我很想知道是否有一个标准库函数可以做到这一点,而我只是找不到。
由于类型类,很容易错过,但看看Control.Arrow. Plain Arrows 不能被Arrow柯里化或应用,因此组合子必然是无点的。如果你专门研究它们(->),你会发现你想要的是这样的:
(&&&) :: (Arrow a) => a b c -> a b c' -> a b (c, c')
还有其他类似的函数,例如 for 的等效操作Either,它专门为(->)如下所示:
(|||) :: (a -> c) -> (b -> c) -> Either a b -> c
这与either.
出于好奇,我想以无点风格重写此功能,但我遇到了很多麻烦。
由于您要复制输入,因此您需要某种方式来实现这一点——最常见的方式是通过Applicative或的Monad实例(->),例如. 这本质上是一个隐式的内联monad,被拆分的参数是“环境”值。使用这种方法,成为,或成为,成为,并成为S 组合子。\f g -> (,) <$> f <*> gReaderjoin f xf x xpurereturnconstfmap(.)(<*>) \f g x -> f x (g x)