Haskellは面白いね。
でも難しい。
上手に書かれたコードは唸るほど綺麗なのだけど、
何が出来て何が出来ないのかが判りにくい。
いっぺん真面目に仕様を読んだ方がいいのかね?(コメント希望)
main = putStrLn $ show $ f == f
f = "hello" ++ f
{-無限に長い文字列fを定義して、fとfが同じかどうかを表示する-}
これは帰って来ない。こんぐらい解れよ。と思わんでもないが駄目。
main = putStrLn $ if f == f then g else g
f = "hello" ++ f
g = "bye"
{-無限に長い文字列fと、有限の文字列gを定義して、fとfが同じならg、違ってもgを表示する-}
これも駄目。
main = putStrLn $ h $ if f == f then g else g
f = "hello" ++ f
g = "bye"
h x = "see you"
{-無限に長い文字列fと、関数g、関数hを定義して、fとfが同じならg、違ってもgを引数としてhに与える
hは引数とは無関係に"see you"を返す-}
これは"see you"って出てくる。
もしかして静的にxは「要らない子」だと判断してる?
それとも(if f == f then g else g)がThunkとして与えられてる?
main = putStrLn $ h 0 $ if f == f then g else g
f = "hello" ++ f
g = "bye"
h 0 x = "see you"
h _ x = "see you" ++ x
hの引数を増やしてみた。第一引数が0でなければxの値は必要になる。
これも動くんだ。たぶんThunkなんだな。
main = putStrLn $ h 0 $ (if f == f then g else g) "ok"
f = "hello" ++ f
g x = "bye" ++ x
h 0 x = "see you"
h _ x = "see you" ++ x
gにも引数を付けてみた。ちゃんと帰ってくる。
んじゃ実際には決定不可能な関数に引数を与えることは可能なんだ?
念のため
i x = putStrLn $ h x $ (if f == f then g else g) "ok"
というのを定義してghciから呼ぶと
i 0
は帰ってくるけど
i 1
は止まる。
まとめ:
「型以外は判らない関数」に引数を与えると「型以外は判らない値」が返ってくる。
でも一応返ってくる。何も返ってこないんじゃなくって。
余談:
オフサイドルールはどうも好きじゃない。
「あれ?Hatena::Diaryはタブを表示するんだっけ?まあいいや全部一行にしちゃえ」