gksato
あ、なるほど。
sqlite-simple というライブラリを使おうと,`stack.yaml` の extra-devs と プロジェクトのcabalファイルに以下のように追加しました.# stack.yaml # コメント行は省略します resolver: lts-16.2 packages: - . extra-deps: - sqlite-simple-0.4.16.0@sha256:aeb9502c0004054846829766a08d856122a7e7386077b95048e60edaf9f46b88,2947
# cabalファイル(一部)
library
hs-source-dirs: src
exposed-modules: Lexer, Writer
build-depends: base >= 4.7 && < 5
, text
, sqlite-simple # この行を追加しました
default-language: Haskell2010Error: While constructing the build plan, the following exceptions were encountered:
In the dependencies for sqlite-simple-0.4.16.0:
base-4.13.0.0 from stack configuration does not match <4.13 (latest matching version
is 4.12.0.0)
direct-sqlite must match >=2.3.13 && <2.4, but the stack configuration has no specified
version (latest matching version is 2.3.26)
semigroups-0.19.1 from stack configuration does not match ==0.18.* (latest matching version
is 0.18.5)
needed due to AIQRating-0.1.0.0 -> sqlite-simple-0.4.16.0
Some different approaches to resolving this:
* Build requires unattainable version of base. Since base is a part of GHC, you most likely
need to use a different GHC version with the matching base.
Plan construction failed.dependencies 等々書いてあったため,baseのバージョンが新しすぎて対応していないのかな?などと思い,cabalファイルの build-depends をいじったりしていたのですが,エラーが全く解決できず困っています.resolver を lts-15 系を使う)extra-deps の sqlite-simple-0.4.16.0@... を sqlite-simple-0.4.18.0 とかにする)chcp 65001
他のプロジェクトへの影響など
allow-newer を true にしてもとくに他のプロジェクトへの影響はありません。allow-newer する以外の方法はないでしょう。either (putStrLn . show) return =<< ...case 式をなくせます。either throwIO returnimport Control.Exception した上でMyException を instance Exception MyException にする必要があるのでお忘れなく。ExceptT IO や IO (Either ..) を使うのに適切な場面ではないように感じます。ExceptT IO や IO (Either ...) は、 either throwIO return などのイディオムで簡単にただの IO に変換できるものの、関数の利用者に「この例外は必ず処理しろよ!」という強い義務を与えるものであり、今回 liveinwoodさんが検討しているような小さなツールでは、扱いが煩雑になりがちです。IO (Either ...) などはアンチパターンだと考える人も多くいます(私はこの点については同意してませんが)。IO にしておいて throwIO すれば case式はいらなくなるし、それで十分じゃないでしょうか?fail で十分だとも考えられます。: とは何のことですか。ExceptT IO や `IO (Either ...)` は、 `either throwIO return` などのイディオムで簡単にただの `IO` に変換できるものの、関数の利用者に「この例外は必ず処理しろよ!」という強い義務を与えるものであり、ExceptT IO にそのような意味があるとこは全く意識していませんでした。`IO` の中で`Either` を使いたいって理由だけで使っていました。`Either` を使いたい理由は、最初のチェックがエラーなら次のチェックは実行したくなかったからです。もっと言えば、発生した例外によって結果を分ける、ということをしない限り自前の例外を定義する必要すらなく、 `fail` で十分だとも考えられます。
ExceptT IO には検査例外の意味があるのに、私のコードでは発生した例外を無視して標準出力に出力しているだけであり、規模からしても`ExceptT IO` を使うまでもない、ということでしょうか?