私はHaskellの素晴らしい世界への第一歩を踏み出しました。演習として、リストの最大要素とそのインデックスを見つけるメソッドを実装したいと思います。この関数を「マキシ」と呼びましょう。リストでmaxiを呼び出すと、次の結果が返されます。
ghci> maxi [1, 3, 4, 1, 2, 3]
(4, 2)
4はこのリストで最大のintであり、インデックス2にあります。
私はこの関数を次のように実装しようとしました:
maxim :: (Ord a) => [a] -> (a, Int)
maxim l =
let pmaxim :: (Ord a) => [a] -> Int -> (a, Int) -- Internal function to do the work
pmaxim [] _ = error "Empty list" -- List is empty, error
pmaxim [x] xi = (x, xi) -- List has one item, return it and the index
pmaxim (x:xs) xi -- More than one item, break list apart
| x > t = (x, xi) -- If current item is bigger, return it and its index
| otherwise = (t, ti) -- If list tail has a bigger item, return that
where (t, ti) = pmaxim xs (ti + 1) -- Get max of tail of the list
in pmaxim l 0 -- Call internal function with start index
これを呼び出すと、本当に奇妙なことが起こります。最大要素の値を返した後、ghciがハングしているようです。
ghci> maxi [1, 3, 4, 1, 2, 3]
(4,
これはHaskellの遅延評価の性質と関係があると思いますが、ここで実際に何が起こっているのか、そしてそれを修正する方法を理解するのは難しいと感じています。また、Haskellでデバッグする方法について誰かが持っているかもしれないヒントにも本当に感謝しています。動作に影響を与えることなく、実行中に値を出力する簡単な方法はありますか?
組み込みのHaskell関数を使用してこの動作を実現するためのより良い方法がいくつかあることを認識していることを指摘したいと思います。Haskellを学ぶために、これを最初から実装しています。
ありがとうございました