结合两个curried函数

时间:2013-09-27 23:20:01

标签: haskell higher-order-functions

假设我们有两个(a -> b -> c)类型的函数。我想要一个单独的函数,当应用于ab时,将dc合并一个指定的函数(c -> c -> d)。我用箭头提出了这个解决方案:

combine :: (a -> b -> c) -> (a -> b -> c) -> (c -> c -> d) -> (a -> b -> d)
combine f g op = ((uncurry op) .) . (uncurry (&&&)) . (f &&& g)

有没有办法以更优雅的方式执行此操作,或将其概括为适用于具有更大优点的函数(例如(a -> b -> c -> d) -> (a -> b -> c -> d) -> (d -> d -> e) -> (a -> b -> c -> e))?

2 个答案:

答案 0 :(得分:7)

不要害怕明白。对我来说,这更容易阅读:

combine :: (a -> b -> c) -> (a -> b -> c) -> (c -> c -> d) -> (a -> b -> d)
combine f g op = \a b -> op (f a b) (g a b)

对于更多的人来说,看起来不是更丑陋:

combine3 f g op = \a b c -> op (f a b c) (g a b c)

答案 1 :(得分:3)

虽然我同意显式lambda可能是这里的方法,但是有二元fg的替代品。对于一元fg,解决方案是基本的。

combine f g op = liftM2 op f g

对于二进制文件fg,我们可以通过解除它们来使它们成为一元,然后应用相同的解决方案!这使得二进制版本

combine2 f g op = curry $ liftM2 op (uncurry f) (uncurry g)

我只是把它作为替代品。