通过动态函数列表传输数据
Piping data through a dynamic list of functions
所以我经常发现自己在设计 'pipeline' 就像数据流一样,
并且通常最终管道本身是动态的。
有没有简单的方法来做这样的事情?
pipe :: [a -> a] -> a -> a
或者我应该用这样的方式达到不同的模式吗?它类似于 State monad,但我不想将函数编辑为 (a -> (), a)
或其他:/
我意识到这是一个幺半群,所以我写了这个,这似乎是一个优雅的解决方案,它存在于某处的库中吗?似乎大多数 Arrow 和 Function Monoids 做不同的事情。
newtype Comp a = Comp {
runComp :: a -> a
}
instance Monoid (Comp a) where
(Comp a) `mappend` (Comp b) = Comp (b . a)
mempty = Comp id
pipe :: [a -> a] -> a -> a
pipe = runComp . foldMap Comp
有人有用于此类事情的模式吗?谢谢!
您正在寻找
之一
foldr (.) id -- right-to-left
或
foldl (flip (.)) id -- left-to-right
取决于您希望函数组成的顺序:
ghci> foldr (.) id [(+1),(*10)] 0
1
ghci> foldl (flip (.)) id [(+1),(*10)] 0
10
所以我经常发现自己在设计 'pipeline' 就像数据流一样, 并且通常最终管道本身是动态的。
有没有简单的方法来做这样的事情?
pipe :: [a -> a] -> a -> a
或者我应该用这样的方式达到不同的模式吗?它类似于 State monad,但我不想将函数编辑为 (a -> (), a)
或其他:/
我意识到这是一个幺半群,所以我写了这个,这似乎是一个优雅的解决方案,它存在于某处的库中吗?似乎大多数 Arrow 和 Function Monoids 做不同的事情。
newtype Comp a = Comp {
runComp :: a -> a
}
instance Monoid (Comp a) where
(Comp a) `mappend` (Comp b) = Comp (b . a)
mempty = Comp id
pipe :: [a -> a] -> a -> a
pipe = runComp . foldMap Comp
有人有用于此类事情的模式吗?谢谢!
您正在寻找
之一foldr (.) id -- right-to-left
或
foldl (flip (.)) id -- left-to-right
取决于您希望函数组成的顺序:
ghci> foldr (.) id [(+1),(*10)] 0
1
ghci> foldl (flip (.)) id [(+1),(*10)] 0
10