假设我有
f :: u -> v -> w
和 g :: x -> y -> z
。 我想要的是h :: (u,x) -> (v,y) -> (w,z)
。
所以我可以手动处理这个问题:
h (u,x) (v,y) = (f u v, g x y)
但是这有什么乐趣呢?
使用
(***)
我可以到达那里:
(f *** g) :: (u,x) -> (v -> w, y -> z)
但我不知道如何走完最后一英里。
(***) :: (Arrow a) => a b c -> a b' c' -> a (b, b') (c, c')
因此将 a 专门化为
->
,我们得到:
(***) :: (Arrow a) => (b -> c) -> (b' -> c') -> (b, b') -> (c, c')
这很好,但无论出于何种原因,我们都想将前两个参数作为一对。但这很简单,我们只需 uncurry 即可。
Prelude Control.Arrow> :t uncurry (***)
uncurry (***) :: (Arrow a) => (a b c, a b' c') -> a (b, b') (c, c')
如果您再次专门化
a
,您应该会看到您正在寻找的类型签名。