2011-03-04 12 views
6

Digamos que tengo f :: u -> v -> w y g :: x -> y -> z. Lo que quiero es h :: (u,x) -> (v,y) -> (w,z).Pregunta rápida sobre los operadores de flecha

Así que podría ir sobre esto de forma manual:

h (u,x) (v,y) = (f u v, g x y) 

Pero ¿dónde está la diversión en eso?

Usando (***) puedo llegar hasta cierto punto existe:

(f *** g) :: (u,x) -> (v -> w, y -> z) 

Pero no puedo encontrar la manera de conseguir que la última milla.

Respuesta

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

Así especializar a un -> y obtenemos:

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

Y eso es genial, excepto que queremos, por cualquier motivo, dar los primeros dos argumentos como un solo par en su lugar. Pero eso es fácil, solo corremos.

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

Y si usted se especializa la a de nuevo, debería ver la firma de tipo estabas buscando.

+0

gracias! gist'd para referencia futura: https://gist.github.com/856956 – rampion