简体   繁体   English

确定value是否是Haskell中列表的元素

[英]Determine if value is an element of a list in Haskell

I'm trying to write a function that will determine if an element exists in a list, both of which being provided by the user. 我正在尝试编写一个函数,该函数将确定列表中是否存在元素,这两个元素均由用户提供。 I think a recursive solution is best. 我认为递归解决方案是最好的。 This is what I have: 这就是我所拥有的:

isElement :: a -> [b] -> Bool
isElement a [] = False
isElement a (x:xs) = if a == x then True
                     else isElement a xs

But it can't compile. 但是它不能编译。 The error is "Couldn't match expected type -a' with actual type -b'". 错误为“无法将预期的类型-a'与实际的类型-b'匹配”。 I don't know what this means or how to fix the problem. 我不知道这意味着什么或如何解决该问题。

You code technically works. 您的编码在技术上是可行的。 It's the type signature that's giving you trouble here. 这是类型签名,在这里给您带来麻烦。

First, here's the working code: 首先,这是工作代码:

isElement :: (Eq a) => a -> [a] -> Bool
isElement a [] = False
isElement a (x:xs) = if a == x then True
                     else isElement a xs

I changed two things: 我改变了两件事:

  1. The first thing to keep in mind when working with Haskell's linked lists (the datatype that uses [] ) is that they can only contain elements of the same type. 使用Haskell的链表(使用[]的数据类型)时,要记住的第一件事是它们只能包含相同类型的元素。 However in your type signature, a ➞ [b] you specify that you require your first element to be of type a and the ones in your list of type b , different from a . 但是,在类型签名中, a ➞ [b]指定您要求第一个元素为a类型a而列表b元素则不同于a
  2. The second thing is to "enable" equality checks with generic types a and b , and GHC will give you a warning with the steps to follow in order to fix that: 第二件事是“启用”具有通用类型ab相等性检查,GHC将为您提供警告,并提供以下步骤以解决此问题:

     • No instance for (Eq a) arising from a use of '==' Possible fix: add (Eq a) to the context of the type signature for: isElement :: a -> [a] -> Bool 

    So what it tells us is to specify that the a type can be compared! 因此,它告诉我们的是指定a可以比较a类型!
    And this is fantastic because we can totally do this by giving that clue to the compiler with the (Eq a) => part in our code, that roughly translates to "given this property (Eq) of datatype a , [insert type signature here]". 这太棒了,因为我们可以通过在代码中使用(Eq a) =>部分为编译器提供线索来完全做到这一点,粗略地翻译为“给定数据类型a此属性(Eq),[在此处插入类型签名]”。 (feel free to correct me here, people of StackOverflow!) (请在这里纠正我,StackOverflow的人们!)

Your code works, and reimplementing functions with this kind of explicit recursion is how I learned how it worked in the first place, so don't hesitate to learn by rewriting the stuff you use, then check their sources on Hackage to see how real-world haskellers actually do it. 您的代码可以正常工作,而通过这种显式递归来重新实现功能就是我一开始就了解了它的工作原理,因此不要犹豫,通过重写您使用的内容,然后查看其在Hackage上的源代码,以了解它们的真实性。世界上的散客实际上已经做到了。

Have fun learning! 祝您学习愉快!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM