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