Haskell のスコープの仕様でハマる

by syoyo

久しぶりに MUDA を更新していて、
以下のようなコードでハマりました.


test n = muda n

  where

  muda 0 = show 0
  muda n = concat
    [ muda (n-1)
    , ","
    , show bora
    ]

  bora = n

main = putStrLn $ test 3

これを実行すると、 “0, 1, 2, 3” を期待していたのですが、


0,3,3,3

となってしまいます.

C とかと違って、Haskell は関数型だから関数単位でのスコープなので(の解釈で合っているはず)、
bora が参照している n は muda の中の n ではなくて test の n だったのです.

以下のようにして、where でもうひとつ節を作れば期待通りになります.


test n = muda n

  where

  muda 0 = show 0
  muda n = concat
    [ muda (n-1)
    , ","
    , show bora
    ]

    where

      bora = n

main = putStrLn $ test 3

$ runhaskell test.hs
0,1,2,3

じつはこれ、JavaScript を書いているときも同じように変数のスコープでハマりました…
(JavaScript も関数型なスコープ体系なので)

Advertisements