我需要创建一个包含Int
和[Int]
两个参数的函数,它会返回一个新的[Int]
,并删除第一个参数的所有出现。
我可以轻松地创建函数,包括列表推导和列表递归。但是,我使用这些参数:
deleteAll_list_comp :: Integer -> [Integer] -> [Integer]
deleteAll_list_rec :: (Integer -> Bool) -> [Integer] -> [Integer]
但是,对于我的作业,我所需的参数是
deleteAll_list_comp :: (Eq a) => a -> [a] -> [a]
deleteAll_list_rec :: (Eq a) => a -> [a] -> [a]
我不知道如何阅读这种语法。正如谷歌告诉我的那样,(Eq a)
只是向Haskell解释a
是一种可比的类型。但是,我不明白这一点,因为所有Int
都是自然可比的。如何使用这些参数解释和实现方法?我的意思是,开始的参数究竟是什么?
@groovy @pelotom
谢谢,这非常清楚。我现在明白,它实际上只需要两个参数而不是三个参数。但是,我仍然遇到此代码的问题。
deleteAll_list_rec :: (Eq a) => a -> [a] -> [a]
delete_list_rec toDelete [] = []
delete_list_rec toDelete (a:as) =
if(toDelete == a) then delete_list_rec toDelete as
else a:(delete_list_rec toDelete as)
这给了我一个“deleteAll_list_rec
的类型签名
缺少一个附带的绑定“这对我来说没有意义,因为我是如何正确地绑定要求的,不是吗?从我的小经验来看,(a:as)
在从中提取第一个元素时计为列表。为什么这会产生错误,但
deleteAll_list_comp :: (Eq a) => a -> [a] -> [a]
deleteAll_list_comp toDelete ls = [x | x <- ls, toDelete==x]
没有?
2/7/13更新:对于今后可能会遇到同样问题的所有人,我总体上找到了一些关于Haskell的好信息,我的问题具体来自这个链接:{{ 3}}
“有趣。我们在这里看到一个新的东西,=&gt;符号。=&gt;符号之前的所有内容都是&gt;称为类约束。我们可以读取前面的类型声明:&gt;相等函数需要任何两个相同类型的值并返回一个Bool。这两个值的&gt;类型必须是Eq类的成员(这是类约束)。
Eq类型类提供了一个用于测试相等性的接口。它使得&gt;感测测试该类型的两个值之间的相等性的任何类型都应该是Eq&gt;类的成员。除IO(处理输入和&gt;输出的类型)和函数之外的所有标准Haskell类型都是Eq类型类的一部分。“
答案 0 :(得分:11)
考虑参数的一种方法可能是:
(Eq a) => a -> [a] -> [a]
(Eq a) => means any a's in the function parameters should be members of the
class Eq, which can be evaluated as equal or unequal.*
a -> [a] means the function will have two parameters: (1) an element of
type a, and (2) a list of elements of the same type a (we know that
type a in this case should be a member of class Eq, such as Num or
String).
-> [a] means the function will return a list of elements of the same
type a; and the assignment states that this returned list should
exclude any elements that equal the first function parameter,
toDelete.
(*根据pelotom的评论编辑)
答案 1 :(得分:6)
你实现了什么(相反,你认为你实现了什么)是一个只适用于Integer
列表的函数,作业要求你做的是创建一个适用于所有类型列表的函数是可比性的(这样你的函数也可以在布尔值或字符串列表上工作)。您可能不需要进行大量更改:尝试从代码中删除显式类型签名,并向ghci
询问它将从您的代码中推断出的类型(:l yourfile.hs
然后:t deleteAll_list_comp
)。除非您使用算术运算或类似的东西,否则您很可能会发现您的函数已经适用于所有Eq a
。
作为一个更简单的例子,可以解释这个概念:假设我们想编写一个检查相等性的函数isequal
(稍微没用,但是嘿):
isequal :: Integer -> Integer -> Bool
isequal a b = (a == b)
这是isequal
的完美定义,但我手动设置的类型约束比它们更强。实际上,在没有手动类型签名的情况下,ghci推断:
Prelude> :t isequal
isequal :: Eq a => a -> a -> Bool
告诉我们该函数适用于所有输入类型,只要它们是deriving Eq
,这意味着只需在它们上定义一个正确的==
关系。
您的_rec
功能仍然存在问题,因为它应该与您的_comp
功能完全相同,因此类型签名应该匹配。