使用匿名函数折叠
Folding with anonymous functions
我正在努力学习折叠。
但我不想使用预定义的函数,而是想使用自己的函数。
所以我想将字符串中的所有元音加倍。
doubleVowels :: String -> String
我的尝试是(但仅针对 'a',因为我尝试先解决一个字母,然后扩展和优化它,一旦它 运行s):
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函数的参数
首先,foldl
中使用的函数应该有两个参数。第一个是accumulated result,另一个是current char。
其次,foldl的求值顺序是从左到右,所以我们要reverse
结果字符串。
比如这里是修改后的版本
doubleVowels :: String -> String
doubleVowels s = reverse $ foldl (\x y -> if y == 'a' then ("aa" ++ x) else (y : x)) "" s
我正在努力学习折叠。
但我不想使用预定义的函数,而是想使用自己的函数。
所以我想将字符串中的所有元音加倍。
doubleVowels :: String -> String
我的尝试是(但仅针对 'a',因为我尝试先解决一个字母,然后扩展和优化它,一旦它 运行s):
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函数的参数
首先,foldl
中使用的函数应该有两个参数。第一个是accumulated result,另一个是current char。
其次,foldl的求值顺序是从左到右,所以我们要reverse
结果字符串。
比如这里是修改后的版本
doubleVowels :: String -> String
doubleVowels s = reverse $ foldl (\x y -> if y == 'a' then ("aa" ++ x) else (y : x)) "" s