2009-03-18 2 views
9

Речь идет о синтаксическом сахаре в Хаскелле. Простая программа на Haskell:Как смешать привязку (<-) и присвоить (пусть) в одной строке? (в Haskell)

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

Я использую привязки в первой строке (args <- getArgs) и чистого присвоения в второй (let first = ...). Можно ли объединить их вместе в читаемый однострочный?

Я понимаю, что я могу переписать связывании «де-засахаренные»:

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

Но есть более хороший способ, не загромождая линию (>> =) и вернуться?

ответ

16

liftM и head все очень хорошо, но давайте не будем забывать, соответствие шаблону:

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

или, если вам нравится расположение

main = do 
    arg : _ <- getArgs 
    print arg 

Когда возможно, большинство Haskellers предпочитают сопоставление моделей по head и tail.

+0

Это действительно приятно и доступно для чтения. Благодаря! – sastanin

+0

~ [arg] <- getArgs – Dario

9

Как насчет этого?

import Control.Monad 

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

D'Oh! На 19 секунд быстрее меня. – ephemient

+0

и намного быстрее меня :) – Jonas

+0

Да, это намного приятнее. Спасибо! – sastanin

6

Также можно использовать функцию ap (с типом Monad m => m (a -> b) -> m a -> m b), как это:

import System 
import Control.Monad 

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

Это имеет простое преимущество, что если ваша функция требует несколько аргументов вы можете использовать ap между каждым из их, и вам не нужно использовать liftM2, liftM3 и т.д. для функции f::a -> b -> c -> d вы пишете

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

Спасибо. Я не знал о 'ap'. – sastanin

+0

для тех, у кого аппликативный вкус, 'ap' = <*> и' liftM' = <$> – Eli

1

Как связывают и возвращают беспорядок?

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

или

main = liftM head getArgs >>= print

+2

Обычно я думаю о возврате как «обернуть в монаду» и (>> =) как «развернуть и заменить». Поэтому чтение кода - это что-то вроде «разворачивать и заменять, а также снова обертывать и разворачивать и заменять». Таким образом, liftM более читабельна для меня, потому что это просто «сделать функцию монадической». Итак, мне нравится вариант 2. – sastanin

10

Еще одна возможность:

main = putStr . head =<< getArgs 
+0

Хорошо, это приятно. Я не думал об обратной версии. Спасибо. – sastanin

Смежные вопросы