我是Haskell的新手,我想编写一个简单的函数来计算字符串中子字符串的出现次数。
例如:"There is an apple"
我希望计算句子中"is"
的次数,在这种情况下,结果应为1
。
这是我尝试过的:
countOf :: String -> Int
countOf x = length [n | n <- words x, filter "is" x]
根据我所研究的它应该有效,但它没有。我真的不知道如何解决问题,也不知道我得到的错误信息是什么意思:
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
答案 0 :(得分:9)
函数filter
的类型为
filter :: (a -> Bool) -> [a] -> [a]
这意味着它的第一个参数是另一个函数,它接受一个元素并返回Bool
,并将该函数应用于第二个参数的每个元素。您将String
作为第一个参数而不是函数。也许你想要更像
countOf x = length [n | n <- words x, filter (\w -> w == "is") x]
但这也不会奏效!这是因为列表推导中的任何额外表达必须是Bool
,而不是列表。 filter
返回一个元素列表,而不是Bool
,这实际上是编译器错误的来源,它需要Bool
,但它会看到类型为[a0]
的列表(它甚至还没有达到它应该是[String]
)。
相反,你可以做
countOf x = length [n | n <- words x, n == "is"]
这相当于
countOf x = length (filter (\w -> w == "is") (words x))
或$
:
countOf x = length $ filter (\w -> w == "is") $ words x
Haskell实际上会让我们进一步简化这个
countOf x = length $ filter (== "is") $ words x
使用所谓的操作员部分。然后你可以完全免费点
countOf = length . filter (== "is") . words
答案 1 :(得分:0)
我会这样做:
countOf :: String -> Int
countOf x = length [n | n <- words x, compare "is" n == EQ]
ghci中的演示:
ghci> countOf "There is an apple"
1
答案 2 :(得分:0)
你可以直接理解比较:
countOf x = length [n | n <- words x, n == "is"]
答案 3 :(得分:0)
实际上,您尝试计算字符串中单词的出现次数。如果您要查找子字符串:
import Data.List (inits, tails)
countOf = length . filter (=="is") . conSubsequences
where
conSubsequences = concatMap inits . tails
答案 4 :(得分:0)
还可以尝试折叠:
countOf :: String -> Int
countOf x = foldr count 0 (words x)
where
count x acc = if x == "is" then acc + 1 else acc