我目前正在嘗試學習折疊。
但是我不想使用預定義的函式,而是想使用我自己的函式。
所以我想將字串中的所有元音加倍。
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.
uj5u.com熱心網友回復:
doubleVowels :: String -> String
doubleVowels a = foldr (\eachChar b -> if eachChar == 'a' then ("aa" b) else (eachChar:b)) "" a
在大多數情況下,如果沒有特定原因foldl,請使用foldr代替,foldl因為它允許 Haskell 編譯器懶惰地評估您的運算式。如果我沒記錯的話,即使那樣使用foldl', 因為foldl它并不嚴格并且占用太多記憶體,同時不會給你帶來任何懶惰的好處。
除此之外,您還缺少foldrs(或foldls)函式的第二個引數。foldr有型別:
foldr :: (a -> b -> b) -> b -> t a -> b
函式 tofoldr具有型別a -> b -> b,其中第一個引數是折疊結構的當前元素,第二個引數是累加器。您使用的 lambda 只有一個引數。
此外,lambda 函式的主體也沒有多大意義。
if eachChar == 'a' then (a "aa") else a)
a是周圍函式doubleVowels接收的引數。這里需要用到 lambda 函式的引數。
uj5u.com熱心網友回復:
首先,使用的函式foldl應該有兩個引數。第一個是累計結果,另一個是當前字符。其次,foldl 的求值順序是從左到右,所以我們要到reverse結果字串。
例如,這里是一個修改版本
doubleVowels :: String -> String
doubleVowels s = reverse $ foldl (\x y -> if y == 'a' then ("aa" x) else (y : x)) "" s
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/363872.html
