2012-10-06 43 views
13

Soy nuevo en Haskell, y me pregunto si hay una mejor manera de averiguar si se duplica la funcionalidad de la biblioteca que Hoogle?Monad m => a -> [a -> m a] -> m a

Caso en cuestión: Tengo una serie de funciones f :: Monad a => a -> m a que quiero encadenar, como

f1234 x = (return x) >>= f1 >>= f2 >>= f3 >>= f4 

Pero Prefiero escribir

chain :: Monad m => a -> [a -> m a] -> m a 
chain = foldl (>>=) <$> return 
f1234 = (flip chain) [f1, f2, f3, f4] 

Parece muy básico, ¿el Base Libary ofrece algo equivalente a chain?

+1

Una alternativa a hoogle es, con un poco de intuición, adivinar el módulo más apropiado y luego examinar su página de documentación. Puede encontrar alguna otra forma de acortar su código, o encontrar alguna otra función muy útil que desee recordar. Esta táctica funciona mejor con el paquete base y luego con los módulos de 'abstracción' (como Monad y Applictive, más adelante, los más avanzados Plegable y Traversable) y los tipos de datos con patrones parametrizados (por ejemplo, Lista). Aunque también podría hacerlo para los tipos de datos más utilizados (para mí, Map/Set y más tarde los Monad Transformers). – Laar

+0

'chain = foldl (>> =). return' es *** mucho más claro ***, en mi humilde opinión. –

Respuesta

17

Hoogle es bueno para esto, y definitivamente la herramienta adecuada para encontrar una función del mismo tipo.

Dado que es sencillo, y no está apareciendo en ninguno de los lugares habituales, también puede escribirlo como importarlo de un módulo oscuro, en parte porque no importará una carga completa de otras cosas.

(Aparte: Algunos paquetes no parecen ser consultada desde Hoogle, por lo que si se conoce la función, módulo o paquete de nombre que está buscando y Hoogle no sabe, el uso hayoo.)

me gustaría conectar

(>=>) :: Monad m => (a -> m b) -> (b -> m c) -> (a -> m c) 

de Control.Monad. Es el operador de composición que siempre quise hasta que lo encontré. Es una forma más natural de trabajar con mónadas que >>= en mi opinión.

Incluso se puede utilizar directamente, es tan claro:

f1234 = f1 >=> f2 >=> f3 >=> f4 

Se muestra si Hoogle para (a -> m a) -> (a -> m a) -> (a -> m a), por lo que una estrategia de futuro si usted está buscando algo que combina una lista de algo es busque una función que combine dos y use una de las funciones fold.

Así

chain' :: Monad m => [a -> m a] -> a -> m a 
chain' = foldr (>=>) return 

f1234 = chain' [f1,f2,f3,f4] 

o

chain'' :: Monad m => a -> [a -> m a] -> m a 
chain'' = flip $ foldr (>=>) return 

si lo prefiere, pero el suyo es bien de todos modos.

+5

Tenga en cuenta que 'f1> => f2> => f3> => f4' es más genérico que' chain '[f1, f2, f3, f4] ', ya que permite componer' a -> mb' y 'b - > mc'. – nponeccop

Cuestiones relacionadas