Haskell这里的新手--我昨天遇到了这个问题,我就是没法把我的头绕过去。
最小工作实例
它可能不是很小,但它证明了我的问题--下面是:
data VectorFeatureSet feature = VFS [feature]
class FeatureSet fs where
getFeatures :: fs fl -> fl
instance FeatureSet VectorFeatureSet where
getFeatures (VFS fl) = fl -- <- error occurs here
(背景信息:)关于这些类型意味着什么的简短评论:Feature
是一个具有形状和可选属性的地理实体。FeatureSet
只是一组属于一起的Feature
。
编译器在此代码段的最后一行抛出的错误:
Couldn't match expected type `fl' with actual type `[fl]'
`fl' is a rigid type variable bound by
the type signature for getFeatures :: VectorFeatureSet fl -> fl
at (mentioned line)
In the expression: fl
In an equation for `getFeatures': getFeatures (VFS fl) = fl
In the instance declaration for `FeatureSet VectorFeatureSet'
如果我将函数定义更改为
getFeatures (VFS [fl]) = fl
编译器接受它。
(附带说明:我知道,如果我使用命名字段表示法,Haskell可以为我创建选择器函数,但我目前正在学习Haskell,所以我是有意手工编写这些函数的。)
问题
现在,getFeatures
函数应该只用于从FeatureSet中提取特性列表。我对模式的理解是,如果不需要访问/处理列表的内容,则不需要使用列表符号指定模式参数,只需从模式中获取列表并在函数中返回。
但是在这里,Haskell希望我使用像fs -> [fl] -> fl
这样的函数定义来绑定像fs -> fl -> fl
这样的签名(至少我是这么理解的)。
所以,这里我的问题是:为什么模式参数fl
的类型在函数定义方程的左边和右边是不同的?
我觉得我在这里遗漏了一些基本的东西,但我想不出有什么最基本的东西要回去才能弄清楚。
发布于 2014-06-21 01:13:52
给定VectorFeatureSet
的定义,构造函数VFS
具有[fl] -> VectorFeatureSet fl
类型,即它“包含”的值将是fl
的列表。
在FeatureSet
的实例中,getFeatures
应该具有VectorFeatureSet fl -> fl
类型。
因此,在编写getFeatures (VFS fl) = fl
时,您将返回一个特性列表,而不是一个特性,因为变量fl
有类型[fl]
--注意类型和变量位于不同的名称空间中。
这就是类型错误告诉您的--函数应该返回一些类型为fl
的内容,但实际上生成了某种类型的[fl]
。
当您编写getFeatures (VFS [fl]) = fl
时,实际上是单个元素列表的模式匹配,所以如果您尝试使用VectorFeatureSet []
或VectorFeatureSet [x,y]
等调用它,您的函数就会失败。
考虑到getFeatures
的名称和您对它的描述,听起来应该将它定义为
class FeatureSet fs where
getFeatures :: fs fl -> [fl]
https://stackoverflow.com/questions/24339931
复制相似问题