我目前正在尝试学习折叠。
但我不想使用预定义的函数,而是想使用我自己的。
所以我想将字符串中的所有元音加倍。
doubleVowels :: String -> String
我的尝试是(但仅针对“a”,因为我尝试先解决一个字母,然后在运行后对其进行扩展和优化):
doubleVowels :: String -> String
doubleVowels a = foldl (\eachChar -> if eachChar == 'a' then (a ++ "aa") else a) "" a
尝试运行他的代码我得到以下错误:
Experimenting.hs:8:78: error:
* Couldn't match type `[Char]' with `Char -> Char'
Expected type: Char -> Char
Actual type: String
* In the expression: a
In the expression: if eachChar == 'a' then (a ++ "aa") else a
In the first argument of `foldl', namely
`(\ eachChar -> if eachChar == 'a' then (a ++ "aa") else a)'
|
8 | doubleVowels a = foldl (\eachChar -> if eachChar == 'a' then (a ++ "aa") else a) "" a
| ^
Experimenting.hs:8:81: error:
* Couldn't match expected type `Char' with actual type `[Char]'
* In the second argument of `foldl', namely `""'
In the expression:
foldl
(\ eachChar -> if eachChar == 'a' then (a ++ "aa") else a) "" a
In an equation for `doubleVowels':
doubleVowels
= foldl
(\ eachChar -> if eachChar == 'a' then (a ++ "aa") else a) "" a
|
8 | doubleVowels a = foldl (\eachChar -> if eachChar == 'a' then (a ++ "aa") else a) "" a
| ^^
Failed, no modules loaded.
最佳答案
doubleVowels :: String -> String
doubleVowels a = foldr (\eachChar b -> if eachChar == 'a' then ("aa" ++ b) else (eachChar:b)) "" a
在大多数情况下,如果 foldl
没有具体原因,请使用 foldr
而不是 foldl
因为它允许 Haskell 编译器懒惰地评估您的表达式。如果我没记错的话,即使那样,也可以使用 foldl'
,因为 foldl
并不严格并且占用太多内存,而不会为您带来任何懒惰的好处。
除此之外,您还缺少 foldr
s(或 foldl
s)函数的第二个参数。 foldr
有类型:
foldr :: (a -> b -> b) -> b -> t a -> b
foldr
的函数类型为a -> b -> b
,其中第一个参数是折叠结构的当前元素,第二个参数是累加器。您使用的 lambda 只有一个参数。
另外,lambda 函数的主体也没有多大意义。
if eachChar == 'a' then (a ++ "aa") else a)
a
是周围函数doubleVowels
接收的参数。这里需要用到lambda函数的参数。
关于haskell - 使用匿名函数折叠,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70043103/