2026-09-14
SumTo.hs
sumTo :: Int -> Int
sumTo n = go 1 0
where
go i acc
| i > n = acc
| otherwise =
let acc = acc + i
in go (i + 1) acc
1からnまでの和を求めるつもりですが、print (sumTo 10)は55を出力せず、止まるか<<loop>>で異常終了します。何が問題で、どう直せばよいでしょうか?
Answer
Haskellのletは再帰的で、右辺のaccは引数のaccではなく、いま定義しているacc自身を指します。つまりacc = acc + iは「自分自身にiを足したもの」という終わらない定義で、値が必要になった時点で無限に自分を評価し続けます(GHCはこれを検出すると<<loop>>例外にします)。新しい名前を付ければ直ります:
let acc' = acc + i
in go (i + 1) acc'