我正在努力学习Haskell。 目前我正在创建一个函数,该函数应该采用[String]和'char'并返回此char所呈现的字符串数。
count [] _ = 0
count (x:xs) v
| elem v x = 1 + count xs
| otherwise = 0 + count xs
如何正确完成?
!修改
我收到此错误::
Occurs check: cannot construct the infinite type: a ~ a1 -> a
Relevant bindings include
v :: a1 (bound at prog.hs:7:14)
xs :: [t a1] (bound at prog.hs:7:10)
x :: t a1 (bound at prog.hs:7:8)
count :: [t a1] -> a1 -> a (bound at prog.hs:6:1)
In the second argument of `(+)', namely `count xs'
In the expression: 1 + count xs
答案 0 :(得分:1)
你有正确的想法。 elem
是一个谓词,用于回答列表是否包含元素。假设String
是char
的列表,那么匹配平等可能会更好。像这样:
count :: String -> Char -> Int
count "" _ = 0
count (x:xs) v
| x == v = 1 + count xs v
| otherwise = count xs v
您的count
函数有两个参数。在你的示例代码中,你错过了第二个(你正在搜索的角色);因此错误。
编辑签名为count :: [String] -> Char -> Int
;我的错。在这种情况下,您应该使用elem
,它可以简化为:
count :: [String] -> Char -> Int
count [] _ = 0
count (x:xs) v = c + count xs v
where c = if elem v x then 1 else 0
...你总是进行count xs v
递归通话,所以你真的不需要警卫。
答案 1 :(得分:1)
count
有两个参数(一个列表和一个字符),但是你在每个警卫中只调用一个(xs
)。您应该将功能更改为:
count [] _ = 0
count (x:xs) v
| elem v x = 1 + count xs v
| otherwise = count xs v
请注意,我删除了零,因为它是多余的,并没有真正使代码更具可读性。
答案 2 :(得分:1)
仅用于展示折叠解决方案:
count :: String -> Char -> Int
count x c = foldr (\x y -> y+1 if x == c else y) s 0
foldr选择每个元素并执行所需的操作,将结果作为下一个项目的输入,因此在这种情况下,我们将其初始化为0,并为每个元素添加1,该元素等于传递给te的char功能
答案 3 :(得分:0)
我建议为计数定义所需的签名,这样你就会得到更好的错误,并且对类型系统有一种良好的感觉(因为你正在学习haskell)
count :: [String] -> Char -> Int
为了使您的代码能够正常运行,我们会想到您需要进行的更改(未经测试)
count [] _ = 0
count (x:xs) v
| elem v x = 1 + count xs v
| otherwise = count xs v
您还可以使用像haskell这样的内置函数来使您的代码更具可读性(更少的警卫和线条),但我认为它会使性能更差一些。