假设我们有两个(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)
有没有办法以更优雅的方式执行此操作,或将其概括为适用于具有更大优点的函数(例如(a -> b -> c -> d) -> (a -> b -> c -> d) -> (d -> d -> e) -> (a -> b -> c -> e)
)?
答案 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可能是这里的方法,但是有二元f
和g
的替代品。对于一元f
和g
,解决方案是基本的。
combine f g op = liftM2 op f g
对于二进制文件f
和g
,我们可以通过解除它们来使它们成为一元,然后应用相同的解决方案!这使得二进制版本
combine2 f g op = curry $ liftM2 op (uncurry f) (uncurry g)
我只是把它作为替代品。