1

假设我们有两个 type 函数(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))?

4

2 回答 2

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)

对于更多的arities来说看起来并不难看:

combine3 f g op = \a b c -> op (f a b c) (g a b c)
于 2013-09-27T23:25:49.673 回答
3

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

combine f g op = liftM2 op f g

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

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

我只是把它放在那里作为替代品。

于 2013-09-28T07:37:31.403 回答