如何解释(Eq a)

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的评论编辑)

  • 我投了这个,因为我认为这是一个很好的简洁分解,但我会改变`(Eq a)=>`片段的描述的措辞.这并不是"该函数将仅作为Eq类成员的参数".而是它说,无论你在签名的其余部分看到类型参数"a",你都可以确定_it_代表一个属于`Eq`成员的类型. (3认同)

us2*_*012 6

你实现的(相反,你认为你实现的是)是一个仅适用于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,类型签名应该匹配.