计算句子haskell中特定单词的出现次数

Syn*_*ity 2 haskell

我是Haskell的新手,我想写一个简单的函数来计算字符串中子字符串的出现次数.

例如:"There is an apple"我想计算"is"句子中的次数,在这种情况下结果应该是1.

这就是我尝试过的:

countOf :: String -> Int
countOf x = length [n | n <- words x, filter "is" x]
Run Code Online (Sandbox Code Playgroud)

根据我所研究的它应该有效,但事实并非如此.我真的不知道如何解决问题,也不知道我得到的错误信息是什么意思:

input:1:41:
     Couldn't match expected type `Bool' with actual type `[a0]'
     In the return type of a call of `filter'
     In the expression: filter "a" x
     In a stmt of a list comprehension: filter "a" x
Run Code Online (Sandbox Code Playgroud)

bhe*_*ilr 8

该函数filter具有类型

filter :: (a -> Bool) -> [a] -> [a]
Run Code Online (Sandbox Code Playgroud)

这意味着它的第一个参数是另一个函数,它接受一个元素并返回一个Bool,并将该函数应用于第二个参数的每个元素.你给的String是第一个参数而不是函数.也许你想要更像的东西

countOf x = length [n | n <- words x, filter (\w -> w == "is") x]
Run Code Online (Sandbox Code Playgroud)

但这也行不通!这是因为列表推导中的任何额外表达必须是a Bool而不是列表. filter返回一个元素列表,而不是一个Bool,这实际上是你的编译器错误的来源,它期望a Bool但是它看到了一个类型列表[a0](它甚至还没有达到足够的意识到它应该是[String]).

相反,你可以做到

countOf x = length [n | n <- words x, n == "is"]
Run Code Online (Sandbox Code Playgroud)

而这相当于

countOf x = length (filter (\w -> w == "is") (words x))
Run Code Online (Sandbox Code Playgroud)

或者$:

countOf x = length $ filter (\w -> w == "is") $ words x
Run Code Online (Sandbox Code Playgroud)

Haskell实际上会让我们进一步简化这一点

countOf x = length $ filter (== "is") $ words x
Run Code Online (Sandbox Code Playgroud)

其中使用了所谓的操作员部分.然后你可以完全免费点

countOf = length . filter (== "is") . words
Run Code Online (Sandbox Code Playgroud)