[英]“generalised” scanl
我正在嘗試編寫一種類似於scanl的類型的函數:
general_scanl' :: (a->b->a)->(a->b->[c])->a->[b]->[c]
該函數旨在輸出與以下兩個怪物相同的結果:
general_scanl' f g x y = snd $ foldl' (\(p,q) r -> (f p r,q ++ g p r)) (x,[]) y
要么,
general_scanl' f g x y = concat $ zipWith g (scanl f x y) y
第一個定義的缺點是它包含一個手寫的lambda。
第二個定義的缺點是它會累積不必要的列表列表(scanl fxy)...
我的問題: 有沒有更干凈的方法來定義此功能?
非常感謝,
你有
Prelude> let general_scanl2 f g z xs = concat $ zipWith g (scanl f z xs) xs
-- :: [a]
Prelude> :t general_scanl2
general_scanl2 :: (a -> b -> a) -- f
-> (a -> b -> [c]) -- g
-> a -- z
-> [b] -- xs
-> [c]
Prelude Data.List> :t mapAccumL
mapAccumL :: (a -> b -> (a, y)) -> a -> [b] -> (a, [y])
因此,另一種寫法似乎是
import Data.List
g_scanl3 :: (a -> b -> a) -> (a -> b -> [c]) -> a -> [b] -> [c]
g_scanl3 f g z xs = concat . snd $
mapAccumL (\a b-> (f a b, g a b)) z xs
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.