代码之家  ›  专栏  ›  技术社区  ›  Dmitry Polyanitsa

组合两个curried函数

  •  1
  • Dmitry Polyanitsa  · 技术社区  · 12 年前

    假设我们有两个类型的函数 (a -> b -> c) 。我想要一个函数,当应用于 a b 将给予 d ,合并自 c 通过指定的函数 (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)
    

    有没有一种方法可以用更优雅的方式来做到这一点,或者将其推广到适用于具有更大arity的函数(例如。 (a -> b -> c -> d) -> (a -> b -> c -> d) -> (d -> d -> e) -> (a -> b -> c -> e) )?

    2 回复  |  直到 12 年前
        1
  •  7
  •   Claudiu    12 年前

    不要害怕直言不讳。对我来说,这更容易阅读:

    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)
    

    更多的arities看起来并不难看:

    combine3 f g op = \a b c -> op (f a b c) (g a b c)
    
        2
  •  3
  •   kqr    12 年前

    虽然我同意显式lambda可能是实现这一目标的方法,但二进制也有其他选择 f g .对于一元 f ,解决方案是初等的。

    combine f g op = liftM2 op f g
    

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

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

    我只是把它作为一种替代品。

    推荐文章