我正在写一个库来处理使用懒惰评估的无限序列。为简洁起见,我使用广义代数数据类型(GADT)来声明序列中每个项的索引的Ord
约束。因此,以下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
的定义中的约束(Ord ix)
来处理。
但是,当下块没有注释时,add
函数无法检测到错误No instance for (Ord ix) arising from the use of ``<''
。它不应该能够从Term ix cff
中找出出现在Sequence
的定义中的(Ord ix)
吗?
在第一'add',我想'∀九”。 ix' - > ix' - > Bool'应该是'∀ix'。 Ord ix'=> ix' - > ix' - > Bool'。此外,第二个'add'应该要求'ScopedTypeVariables'和'add :: forall ix。 ...'否则'addAlong ::(ix - > ...'中的'ix'不一样。 – chi