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: Haskell2010
Error: 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 return
import 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` を使うまでもない、ということでしょうか?