[英]Define function in Haskell using foldr
我正在嘗試使用foldr函數在Haskell中定義一個函數:
fromDigits :: [Int] -> Int
該函數獲取一個Int列表(每個Int的范圍從0到9)並轉換為單個Int。 例如:
fromDigits [0,1] = 10
fromDigits [4,3,2,1] = 1234
fromDigits [2,3,9] = 932
fromDigits [2,3,9,0,1] = 10932
無論如何,我毫不費力地使用顯式遞歸甚至使用zipWith定義了這一點:
fromDigits n = sum (zipWith (*) n (map ((^)10) [0..]))
但是現在我必須使用文件夾來定義它,但是我不知道如何獲得10的冪。
fromDigits xs = foldr (\x acc -> (x*10^(???)) + acc) 0 xs
如何減少它們? 我知道我可以從(length xs-1)開始,但是那又如何呢?
最好的祝福
約的好處foldr
的是,它是如此extemely容易想象!
foldr f init [a,b, ... z]
≡ foldr f init $ a : b : ... z : []
≡ a`f b`f`... z`f`init
≡ f a (f b ( ... (f z init)...)))
如您所見,第j個列表元素用於f
j個連續調用中。 head元素只傳遞一次到函數的左側。 對於您的應用程序,head元素是最后一位數字。 那應該如何影響結果? 好吧,它只是添加到結果中,不是嗎?
15 = 10 + 5
623987236705839 = 623987236705830 + 9
- 明顯。 然后的問題是,您如何照顧其他數字? 好吧,要使用上述技巧,您首先需要確保在攜帶的子結果的最后一位為0。 來自提供的數字的0! 您如何添加這樣的零?
這實際上應該已經足夠了。
您幾乎在那里:
你的
fromDigits xs =文件夾(\\ x acc->(x * 10 ^(???))+ acc)0 xs
有2個小更改的解決方案:
fromDigits =文件夾(\\ x acc-> acc * 10 + x)0
(順便說一句,我在兩邊都省略了xs
,這不是必需的。
另一種選擇是
fromDigits = foldl(\\ x acc->讀$(顯示x)++(顯示acc))0
訣竅是,您不需要每次都從頭開始計算10的冪,只需要根據以前的10的冪(即乘以10)來計算它。 好吧,假設您可以反轉輸入列表。
(但是您在上面給出的列表已經是相反的順序,因此可以說您應該能夠將它們反向,並且只需說您的函數以正確的順序獲取數字列表即可。如果沒有,則除以10而不是乘以10。)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.