簡體   English   中英

使用文件夾在Haskell中定義函數

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM