2009-03-18 6 views
9

Se trata del azúcar sintáctico en Haskell. Un simple programa Haskell:¿Cómo mezclar binding (<-) y asignación (let) en una línea? (en Haskell)

main = do 
    args <- getArgs 
    let first = head args 
    print first 

I Uso de unión en la primera línea (args <- getArgs) y una asignación puro en la segunda (let first = ...). ¿Es posible fusionarlos en un solo trazo legible?

entiendo que puedo reescribir la unión “de-azucarada”:

main = do 
    first <- getArgs >>= (return . head) 
    print first 

Pero hay una manera más agradable, sin estorbar la línea con (>> =) y regresar?

Respuesta

16

liftM y head son todos muy bien, pero no olvidemos la coincidencia de modelos:

main = do { arg:_ <- getArgs; print arg } 

o si te gusta el diseño

main = do 
    arg : _ <- getArgs 
    print arg 

Cuando sea posible, la mayoría de los Haskellers prefieren patrones coincidentes sobre head y tail.

+0

Esto es realmente agradable y legible. ¡Gracias! – sastanin

+0

~ [arg] <- getArgs – Dario

9

¿Qué le parece esto?

import Control.Monad 

main = do 
    first <- liftM head getArgs 
    print first 
+0

D'oh! 19 segundos más rápido que yo. – ephemient

+0

y mucho más rápido que yo :) – Jonas

+0

Sí, esto es mucho más agradable. ¡Gracias! – sastanin

6

También es posible utilizar la función ap (con el tipo Monad m => m (a -> b) -> m a -> m b) así:

import System 
import Control.Monad 

main :: IO() 
main = do line <- return head `ap` getArgs 
      putStrLn line 

Esto tiene la sencilla ventaja de que si su función requiere varios argumentos que puede utilizar ap entre cada una de ellos y que no necesitan utilizar liftM2, liftM3 etc. para una función f::a -> b -> c -> d se escribe

return f `ap` arg1 `ap` arg2 `ap` arg3 
+0

Gracias. No sabía sobre 'ap'. – sastanin

+0

para aquellos con un gusto aplicativo, 'ap' = <*> y' liftM' = <$> – Eli

1

¿Cómo se enredan y vuelven?

main = getArgs >>= (return.head) >>= print

o

main = liftM head getArgs >>= print

+2

Normalmente pienso en return como "envolver en mónada", y (>> =) como "desenvolver y sustituir". Entonces, leer el código es algo así como "desenvolver y sustituir, y envolver nuevamente, desenvolver y sustituir". Entonces, liftM es más legible para mí, porque es simplemente "make function monadic". Entonces, me gusta la opción 2. – sastanin

10

Sin embargo, otra posibilidad:

main = putStr . head =<< getArgs 
+0

Bueno, es bueno. No pensé en la versión invertida. Gracias. – sastanin

Cuestiones relacionadas