撰寫一個doItX :: (a -> a -> a) -> a -> Int -> a函式,將第一個引數f x時間應用于第二個引數。
doItX (*) 2 1 == 2
doItX ( ) "a" 6 == "aaaaaa"
doItX (*) 2 3 == 8
我有以下代碼:
doItX f a x
| x==1 = a
| x>1 = doItX f (f a a) (x-1)
如果x為 2 或更少,則效果很好,但對于第三個示例,它回傳16而不是8.
uj5u.com熱心網友回復:
可能最“慣用”的解決方案是基于庫的解決方案:
doItX1 :: (a -> a -> a) -> a -> Int -> a
doItX1 f a x = foldr1 f (replicate x a)
與前奏功能foldr1記錄在這里。
但是,如果出于某種原因,您堅持使用手動遞回,那么您的代碼幾乎就在那里。您只需要修復遞回呼叫:
doItX :: (a -> a -> a) -> a -> Int -> a
doItX f a x
| (x > 1) = ----Was: doItX f (f a a) (x-1)
f a (doItX f a (x-1))
| (x == 1) = a
| otherwise = error ("doItX called with x set to " (show x))
uj5u.com熱心網友回復:
讓我們考慮一下doItX (*) 2 3。
doItX (*) 2 3
-- doItX f a x
-- f = (*)
-- a = 2
-- x = 3
-- doItX f (f a a) (x-1)
doItX (*) ((*) 2 2) 2
doItX (*) 4 2
doItX (*) ((*) 4 4) 1 -- ups, you wanted `2 * 4` but got `4 * 4`.
-- You probably should always pass 2 for a.
16
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/386988.html
