Быстрый вопрос об операторах стрелок - PullRequest
6 голосов
/ 05 марта 2011

Скажите, у меня есть 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)

Но я не могу понять, как получить эту последнюю милю.

1 Ответ

13 голосов
/ 05 марта 2011
(***) :: (Arrow a) => a b c -> a b' c' -> a (b, b') (c, c')

Так что специализируемся на -> и получаем:

(***) :: (Arrow a) => (b -> c) -> (b' -> c') -> (b, b') -> (c, c')

И это замечательно, за исключением того, что мы хотим по какой-то причине вместо первых двух аргументов принять одну пару. Но это просто, мы просто не торопимся.

Prelude Control.Arrow> :t uncurry (***)
uncurry (***) :: (Arrow a) => (a b c, a b' c') -> a (b, b') (c, c')

И если вы снова специализируете a, вы должны увидеть искомую сигнатуру типа.

...