Sou*_*tyr 3 parameters haskell typeclass
我需要创建一个两个参数a Int和a 的函数[Int],它返回一个新[Int]的第一个参数被删除.
我可以很容易地创建函数,包括列表推导和列表递归.但是,我使用这些参数:
deleteAll_list_comp :: Integer -> [Integer] -> [Integer]
deleteAll_list_rec :: (Integer -> Bool) -> [Integer] -> [Integer]
Run Code Online (Sandbox Code Playgroud)
但是,对于我的任务,我所需的参数是
deleteAll_list_comp :: (Eq a) => a -> [a] -> [a]
deleteAll_list_rec :: (Eq a) => a -> [a] -> [a]
Run Code Online (Sandbox Code Playgroud)
我不知道如何阅读这种语法.正如谷歌告诉我的,(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)
Run Code Online (Sandbox Code Playgroud)
这给了我一个" deleteAll_list_rec
缺少伴随绑定的类型签名",这对我来说没有意义,因为我如何正确地绑定了这些要求,不是吗?根据我的小经验,(a:as)在从中提取第一个元素时计为列表.为什么这会产生错误但是
deleteAll_list_comp :: (Eq a) => a -> [a] -> [a]
deleteAll_list_comp toDelete ls = [x | x <- ls, toDelete==x]
Run Code Online (Sandbox Code Playgroud)
才不是?
2/7/13更新:对于所有可能在将来遇到同一问题而偶然发现这篇文章的人,我发现了一些关于Haskell的一般信息,特别是我的问题,在这个链接:http:// learnyouahaskell的.com /类型和-类型类
"有意思.我们在这里看到一个新的东西,=>符号.=>符号之前的所有内容都被称为类约束.我们可以像这样读取前面的类型声明:>相等函数接受任何两个值相同的类型并返回一个Bool.这两个值的> type必须是Eq类的成员(这是类约束).
Eq类型类提供了用于测试相等性的接口.测试该类型的两个值之间的相等性的任何类型都应该是Eq>类的成员.除了IO(处理输入和输出的类型)和函数之外的所有标准Haskell类型都是Eq类型类的一部分."
גלע*_*רקן 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.
Run Code Online (Sandbox Code Playgroud)
(*根据pelotom的评论编辑)
你实现的(相反,你认为你实现的是)是一个仅适用于Integers 列表的函数,作业要求你做的是创建一个适用于所有类型列表的函数,只要它们具有相等的可比性(这样你的函数也适用于布尔值或字符串列表).您可能不需要进行大量更改:尝试从代码中删除显式类型签名,并询问ghci它将从您的代码中推断出的类型(:l yourfile.hs然后:t deleteAll_list_comp).除非您使用算术运算或类似的东西,否则您很可能会发现您的函数已经适用于所有人Eq a.
作为一个更简单的例子,可以解释这个概念:假设我们想编写一个isequal检查相等的函数(稍微没用,但是嘿):
isequal :: Integer -> Integer -> Bool
isequal a b = (a == b)
Run Code Online (Sandbox Code Playgroud)
这是一个非常精细的定义isequal,但我手动设置的类型约束比它们更强.实际上,在没有手动类型签名的情况下,ghci推断:
Prelude> :t isequal
isequal :: Eq a => a -> a -> Bool
Run Code Online (Sandbox Code Playgroud)
它告诉我们该函数将适用于所有输入类型,只要它们是deriving Eq,这仅仅意味着==在它们上定义了适当的关系.
_rec但是你的功能仍然存在问题,因为它应该与你的功能做同样的事情_comp,类型签名应该匹配.