Сверните список функций в Haskell - PullRequest
2 голосов
/ 07 ноября 2019

Я пытаюсь написать функцию, pipe, которая принимает список математических функций, где pipe [f1,...,fn] x должен возвращать f1(f2(...(fn x))) Я настроил ее так, что:

pipe :: [(a -> a)] -> (a -> a)
pipe fs   = foldLeft f base fs
  where
    f a x =    
    base  = 

-- >>> pipe [] 3
-- 3
--
-- >>> pipe [(\x -> x+x), (\x -> x + 3)] 3
-- 12
--
-- >>> pipe [(\x -> x * 4), (\x -> x + x)] 3
-- 24

Чтолучший способ сделать это с помощью foldl? Спасибо!

Ответы [ 2 ]

2 голосов
/ 07 ноября 2019

при фолде это должно быть:

pipe :: [(a -> a)] -> (a -> a)
pipe fs = foldl (\rs f -> f . rs) id fs 

или с eta:

pipe :: [(a -> a)] -> (a -> a)
pipe = foldl (\rs f -> f . rs) id 

с другим eta:

pipe :: [(a -> a)] -> (a -> a)
pipe = foldl (.) id 

на вашем примере:

pipe [(\x -> x * 4), (\x -> x + x)] 3
=> 24 
0 голосов
/ 07 ноября 2019

pipe на самом деле можно сделать намного проще, чем вы думаете, и нет необходимости использовать довольно неэффективный foldl (вы можете увидеть это даже в ваших собственных скобках - они прямо-ассоциативны): простоflip (foldr id). Шаги, чтобы добраться туда:

pipe [f1,...,fn] x
f1 (f2 (... (fn x)))            -- your definition of pipe
id f1 (id f2 (... (id fn x)))   -- id x = x
foldr id x [f1,...,fn]          -- the definition of foldr
...