我很想知道是否有一个标准库函数可以做到这一点,而我只是找不到。
由于类型类,很容易错过,但看看Control.Arrow
. Plain Arrow
s 不能被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 <*> g
Reader
join f x
f x x
pure
return
const
fmap
(.)
(<*>)
\f g x -> f x (g x)