Haskellでいろいろ遊んでみる
初心者向けテーマとして、ブラックジャックが面白い、らしいので、Haskellで作成してみました。
https://qiita.com/KNaito/items/385fb1701f70ffb8ffd4
で、Qiitaの記事には完成したものしか書いてないのですが、そもそも自分が普通のプログラミング(いわゆる手続き指向型プログラミング)思考になっているため、本当に基本的なことでつまづきまくりました。
例えば、整数を2で割った値を返し、1の場合は1を返す次のような関数を定義してみます。
func :: Int -> Int
func 1 = 1
func x = x `div` 2
Haskellに慣れていない人のために、JavaScriptで書くとこれは
function func(x) {
if (x==1) return 1;
return Math.floor(x/2);
}
こんな感じ。
でもって、これを呼び出すときに
main :: IO ()
main = do
let x = 10
let y = func x
print y
と呼び出せば、期待通り10を2で割った5が表示されるのですが、変数の名前を節約したいと思って
main :: IO ()
main = do
let x = 10
let x = func x
print x
としてしまうと、無限ループしてしまいます、、。
理由は多分、print xの段階で遅延評価がはじまり、そこでx = func xの右辺を計算しようと
するのですが、右辺のxは、結局同じ式のx = func xで定義されているので、x = func func x
となっていまい、そのまた右辺のxを計算しようとして、x = func func func x ...と無限ループ
してしまうようです。
数学的には