【发布时间】:2016-02-12 18:27:34
【问题描述】:
我发现我正在编写重复的函数来处理 Data.List 和 Data.Sequence,为了对它们进行概括,我写道:
import qualified Data.Sequence as Seq
class PrependableList pl where
empty :: pl a
first :: pl a -> a
prepend :: a -> pl a -> pl a
len :: pl a -> Int
instance PrependableList [a] where
empty = []
first = head
prepend = (:)
len = length
instance PrependableList (Seq.Seq a) where
empty = Seq.empty
first seq = Seq.index seq 0
prepend = (Seq.<|)
len = Seq.length
上面的实现没有编译,说明 kind 不匹配:
Kind mis-match
The first argument of `PrependableList' should have kind `* -> *',
but `[a]' has kind `*'
In the instance declaration for `PrependableList [a]'
Kind mis-match
The first argument of `PrependableList' should have kind `* -> *',
but `Seq.Seq a' has kind `*'
In the instance declaration for `PrependableList (Seq.Seq a)'
从我在其他条目(例如In Haskell, why isn't there a TypeClass for things that can act like lists?)中看到的情况来看,可能无法完全概括多个类似列表的数据结构。
但是以上 4 个函数至少可以泛化为 Data.List 和 Data.Sequence 吗?
【问题讨论】:
-
只需将
[a]更改为[]。 -
正如错误消息指出的那样,
PrependableList需要一个一元类型构造函数 (* -> *),而不是一个空类型构造函数 (*)。因此,您应该编写instance PrependableList []和实例PrependableList Seq.Seq。此外,除非您使用<|运算符的限定名称,否则您的代码 sn-p 不会编译,即Seq.<|。 -
感谢@MathematicalOrchid,确实克服了编译错误。接下来的问题是如何在函数的类型定义中使用 PrependableList。当我添加“PrependableList a”时,编译器会指出另一种不匹配:“Kind mis-match The first argument of
PrependableList' should have kind* -> ', buta' has kind'”(不能使星号正确显示) -
感谢@Jubobs——修复了序列。
-
@AlbertCardona 你想要
PrependableList pl => pl a这样的东西。
标签: haskell