[英]Do native Haskell lists have a “real” type name? Or… what am I doing wrong here?
跟随有关Haskell类型族的文章之后,我发现了自己尝试这一点的勇气。 知道列表已经是可应用的,什么都没有,只是为了看看我是否正确,我尝试执行以下操作:
{-# LANGUAGE TypeFamilies #-}
class Iterable c where
data Iterator c :: * -> *
current :: Iterator c a -> Maybe a
next :: Iterator c a -> Maybe (Iterator c a)
instance Iterable [] where
data Iterator [] a = ListIterator [a] -- Problem in this line!
current (ListIterator []) = Nothing
current (ListIterator (x:xs)) = Just x
next (ListIterator []) = Nothing
next (ListIterator (x:xs)) = Just (ListIterator xs)
这类似于上述haskell教程中给出的示例代码。 这应该做的是一般地为本地Haskell列表实现类型为Iterable
的系列。
我也尝试编写data Iterator [a] = ListIterator [a]
但这会产生与我在此处显示的代码相同的错误消息:
temp.hs:8:19: error:
* Expecting one more argument to `[]'
Expected a type, but `[]' has kind `* -> *'
* In the first argument of `Iterable', namely `[]'
In the instance declaration for `Iterable []'
因此,我的问题是,如果我可以选择对列表使用实型名称而不是[]
,我怀疑这就是我的(语法上的)问题的出处。
请注意,该类实际上根本没有以任何方式使用其参数,它仅使用Iterator c
,而不使用c
本身。 原则上没关系– c
基本上像标签一样工作,以选择其他类型–尽管您应该问自己,这是否真的是您想要的,以及更直接的方法是否会更好。
唯一真正的问题:由于c
自身未使用,因此编译器无法知道c
应该具有哪种类型 。 即,基本上,您的类是多态的 ,Haskell98不允许这样做...因此它默认为最简单的类型,即*
。 GHCi可以告诉您以下内容:
*Main> :k Iterable
Iterable :: * -> Constraint
这样就可以用于例如instance Iterable Int
,因为Int
具有*
。 但是[]
没有,它具有种类* -> *
。 因此,该错误消息。
您可以启用GHC的PolyKinds
扩展来避免此默认设置:
{-# LANGUAGE PolyKinds #-}
class Iterable c where
data Iterator c :: * -> *
current :: Iterator c a -> Maybe a
next :: Iterator c a -> Maybe (Iterator c a)
现在它是
*Main> :k Iterable
Iterable :: k -> Constraint
因此, instance Iterable Int
(也可以使用instance Iterable []
k ~ *
)和instance Iterable []
(也可以使用k ~ (* -> *)
)都可以使用。
另外,您可以手动声明c
应该始终为kind * -> *
:
{-# LANGUAGE KindSignatures #-}
class Iterable (c :: * -> *) where
data Iterator c :: * -> *
current :: Iterator c a -> Maybe a
next :: Iterator c a -> Maybe (Iterator c a)
现在, instance Iterable []
将起作用,但instance Iterable Int
将不起作用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.