2011-08-24 8 views
6

Quiero componer funciones de la siguiente manera:funciones horquilla FMAP

compose :: (a->b->c) -> (d->a) -> (d->b) -> d -> c 
compose f g h x = f (g x) (h x) 

Para que podamos usarlo de la manera siguiente:

compose (==) (myReverse . myReverse) id [1..100] 

Creo que podría simplificarse con algo como 'fmap', por lo que no necesita definir 'componer' en absoluto. Pero no pude encontrar la manera de hacerlo.

+0

Lo que ha proporcionado es la solución más simple y más fácil de leer. Puede haber otra solución de código llamada "densa" para esto, pero prefiero el código simple y legible :) – Ankur

Respuesta

11

Si importa Control.Applicative, entonces

compose f g h = f <$> g <*> h 

Por lo tanto, puede escribir (==) <$> (myReverse . myReverse) <*> id $ [1..100]

<*> especializado para funciones es equivalente a la S-combinator:

s f g x = f x (g x) 

Probablemente puede utilizar Control.Arrow demasiado :

compose f g h = g &&& h >>> uncurry f 
test = uncurry (==) <<< (myReverse <<< myReverse) &&& id $ [1..100] 

actualización

le he pedido al lambdabot#haskell la misma pregunta y él respondió simplemente liftM2. : D

+0

+1, buena respuesta. Como semi novato, traté de llegar a ambas soluciones, me acerqué mucho pero no lo logré (me perdí el '<<<' por componer con 'uncurry'). –

+0

En realidad '<<<' es equivalente a '.'. Es el '&&&' que hace el trabajo (divide el argumento) aquí. – Rotsor

+1

Sé que '<<<' es composición, pero me quedé atrapado con 'uncurry (==) ((reverse reverse) &&& id) $ [1..100]', lo que en retrospectiva es bastante estúpido. –

Cuestiones relacionadas