2

この回答の推奨事項に従ってHaskellの学習を開始しました。だから私は簡単なリスト関数を実装しているだけで、自分では説明できないコンパイラの動作の違いに出くわしました:

-- Impl 1
elementAt :: (Integral b) => [a] -> b -> a
elementAt xs id = xs !! (fromIntegral(id-1))

-- Impl 2
elementAt' :: (Num b) => [a] -> b -> a
elementAt' xs id = xs !! (id-1)

次の署名付き:

fromIntegral :: (Integral a, Num b) => a -> b
(!!) :: [a] -> Int -> a

2 番目の実装でのみエラーが発生しますelementAt'

Could not deduce (b ~ Int)
from the context (Num b)

私の理解が正しければ、演算子 (!!) が2 番目の引数としてIntインスタンスを期待していることを意味しますが (署名からわかるように)、提供されたパラメーターがNum型クラスに準拠していることのみを保証します(署名から推測elemenAt') 、これはIntよりも広いです。

それを念頭に置いて、最初の実装が実際に機能する理由がわかりません。これもNumfromIntegral型クラスにのみ準拠する値を返すことを知っています。

4

1 に答える 1