Namaran

Code daily. Without assist.

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'