Haskellでコンパイル時に「(ファイル名):L(現在の行)」を埋め込む
結論
あるファイルでそのコードの場所を文字列として埋め込みたい場合は、このように実現することができます。
{-# LANGUAGE CPP #-}
let here = __FILE__ ++ ":L" ++ show (__LINE__ :: Int)
(コンパイル時と言ったな、あれは嘘だ。これは多分プリプロセス時に解決されます)
起
Haskellでは、関数が単純に例外を出す可能性がある場合はEither e
もしくはMaybe
を使うと思います。
readFooFromSomewhere :: Bar -> Either Text Foo
readFooFromSomewhere bar =
let result = {a result of a some calculation}
case result of
Baz -> Left "残念"
Poi -> Right {some}
これに加えIO
文脈下では関数fail
などによって、Left e
やNothing
でない、マジモンの例外を出すことができます。
(危険、多用厳禁。main
関数以外での使用を推奨しません )
fail
は主に非正常系で使われると思います。
readFooFromSomewhere :: IO ()
readFooFromSomewhere =
result <- {a result of a some calculation}
case result of
Baz -> fail "残念"
Poi -> return {some}
fail
が使われる場所はだいたい非正常系の処理だと思いますので通常は現れないはずですが、
もし現れた場合にissueで報告して欲しい場合はこんな感じにすると思います。
readFooFromSomewhere :: IO ()
readFooFromSomewhere =
result <- {a result of a some calculation}
case result of
-- vvv ここは絶対に通らないよ!もしここを通ったら木の下に埋めてもらっても構わないよ!
Baz -> fail "Main.readFooFromSomewhere: fatal error! sorry, please report an issue if you see this :("
-- ^^^
Poi -> return {some}
承
でもいちいち"Main.readFooFromSomewhere"
とか書くのは面倒なので、どうせならコンパイル時とかプリプロセス時あたりで、自動で埋め込んで欲しいと思うのは自然なことですよね。
それについて選択肢はいくつか考えられます。
- プログラムを
--profile
オプション付きGHCでビルドして、GHC.Stack.HasCallStackとcurrentCallStack
を使う - TemplateHaskellを使う
- CPPを使う
今回はCPPを使ってみます。
しかしながらGCCの__FUNC__
のようなマクロはないようですので、代わりに__FILE__
と__LINE__
で示します。
{-# LANGUAGE CPP #-}
readFooFromSomewhere :: IO ()
readFooFromSomewhere =
result <- {a result of a some calculation}
let here = __FILE__ ++ ":L" ++ show (__LINE__ :: Int)
case result of
Baz -> fail $ here ++ " : fatal error! sorry, please report an issue if you see this :("
Poi -> return {some}
できました。
参考
Author And Source
この問題について(Haskellでコンパイル時に「(ファイル名):L(現在の行)」を埋め込む), 我々は、より多くの情報をここで見つけました https://qiita.com/aiya000/items/7efdfd1102ffd5712422著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .