我是Haskell的新手,我需要定义这种数据类型:
data Restaurant = Restaurant [(String, String, Int)] deriving (Eq,Show)
这是餐厅员工的名单:(每个员工的姓名,地址,工资) .
现在,我正在尝试定义这个 numberOfEmployees 函数:
numberOfEmployees :: Restaurant -> Int
numberOfEmployees rest = length rest
但是我得到了这个编译错误:无法将预期类型't2 a0'与实际类型'Restaurant'匹配
如果我使用 type 而不是 data ,它为什么有效? (我可以't use the '键入' declaration in my code because it'关于'data'的练习的一部分)
type Restaurant = [(String, String, Int)]
3 回答
因为
type
是一个弱别名 . 在代码中,它等同于RHS上的类型 .另一方面,
data
(和newtype
,或许更是如此)会创建一个"strong"别名,这意味着您需要先解压缩它:如果要限制对数据的操作,这一点尤为重要 . 如果内部模块不导出构造函数,则用户只能使用智能构造函数和其他运算符,并且无法直接访问或修改包装数据(实际上使其不透明) .
函数
length
的类型为[a] -> Int
. 那就是它需要一个列表作为参数 . 但是你试图将Restaurant
传递给它 .您应该使用模式匹配来获取列表并将其传递给
length
.length
的类型是但是没有类型
t
和a
这样Restaurant
类型等于t a
. 正如其他人所解释的那样,你需要拉出列表并找到列表的长度 -Restaurant
永远不会有length
.Nitpick
你可以写
以便
每个
a
. 但是,Foo
将只是类型同义词/系列,而不是正确的第一类类型 . 只有使用data
或newtype
声明的真正类型,内置的()
,列表和元组类型,奇怪的->
以及这些类型的应用程序才真正算在内 .