我拥有的赋值:一个函数numOccurences,它接受一个值和一个列表,返回该值出现在列表中的次数。我正在学习哈斯克尔并且感到沮丧,这是我的代码:
numOccurences:: b -> [a] -> Int
numOccurences n [ls]
|([ls] !! n==True) = (numOccurences(n (tail [ls])))+1
|otherwise = 0
我得到的错误如下: https://imgur.com/a/0lTBn
答案 0 :(得分:2)
一些指示:
首先,在您的类型签名中,使用不同的类型变量(即b
和a
)会创建一种可能性,您可以在另一种类型的列表中查找某种类型的值的出现次数,在这种情况下不是你想要的。因此,您只想使用一个类型变量而不是两个类型变量。
其次,无论列表的具体类型是什么,无论是[Char]
,[Int]
等,它都需要是等同的(即它需要派生Eq
类型类) ,因此在类型签名中使用类约束(Eq a) =>
是有意义的。
第三,既然我们正在遍历一个列表,那么让我们使用pattern matching安全地中断列表的第一个元素进行比较,让我们添加一个基本案例(即我们用空列表做什么)因为我们正在使用递归,所以只要列表中有元素,我们只希望递归模式匹配。
最后,尽量避免使用索引(即!!
),您可以避免使用索引,并使用模式匹配,因为它更安全,更容易推理。
根据上述指示,以下是修改后的函数的外观:
numOccurences :: (Eq a) => a -> [a] -> Int
numOccurences _ [] = 0
numOccurences n (x:xs)
| n == x = 1 + numOccurences n xs
| otherwise = numOccurences n xs