私は、遅延評価を使用して無限シーケンスを処理するライブラリを作成しています。簡潔にするために、シーケンスの各用語のインデックスにOrd
という制約をアサーションするために、一般化された代数データ型(GADT)を使用しています。したがって、次のtypechecks:予想通りGADTを使用して型クラス制約を自動的に派生させる
{-# LANGUAGE GADTs #-}
data Term ix cff where
Term :: (Ord ix) => ix -> cff -> Term ix cff
data Sequence ix cff where
Seq :: [Term ix cff] -> Sequence ix cff
f (Seq (Term i x:_)) (Seq (Term j y:_)) = i < j
{-
add :: Sequence ix cff -> Sequence ix cff -> Sequence ix cff
add (Seq tms1) (Seq tms2) = Seq (addAlong (<) tms1 tms2)
where addAlong :: (ix -> ix -> Bool) ->
[Term ix cff] -> [Term ix cff] -> [Term ix cff]
addAlong ord (Term i x : tms1) (Term j y : tms2) = []
-}
、GHCiのはf :: Sequence t t1 -> Sequence t t2 -> Bool
ことを私に伝えます。比較i < j
を実行するには、Ord
インスタンスが必要ですが、これはの定義でTerm
という制約で処理されます。
ただし、下位ブロックのコメントを外すと、add
関数はエラーNo instance for (Ord ix) arising from the use of ``<''
で型チェックに失敗します。 Sequence
の定義に表示されるTerm ix cff
の(Ord ix)
を把握できませんか?
を最初 'add'では、私は'∀第IX」を考えます。 ix ' - > ix' - > Bool'は '∀ix 'でなければなりません。 Ord ix '=> ix' - > ix ' - > Bool'。さらに、2番目の 'add'は' ScopedTypeVariables'と 'add :: forall ixを必要とします。それ以外の場合、 'addAlong ::(ix - > ...')の 'ix'は同じではありません。 – chi