Как смешать привязку (<-) и присваивание (let) в одну строку? (в Хаскеле) - PullRequest
9 голосов
/ 18 марта 2009

Это о синтаксическом сахаре в Хаскеле. Простая программа на Haskell:

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

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

Я понимаю, что могу переписать переплет "de-sugared":

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

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

Ответы [ 5 ]

16 голосов
/ 20 марта 2009

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

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

или, если вам нравится макет

main = do
    arg : _ <- getArgs
    print arg

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

10 голосов
/ 20 марта 2009

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

main = putStr . head =<< getArgs
9 голосов
/ 18 марта 2009

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

import Control.Monad

main = do
   first <- liftM head getArgs
   print first
6 голосов
/ 18 марта 2009

Также возможно использовать функцию 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
1 голос
/ 20 марта 2009

Как связать и вернуть беспорядок?

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

или

main = liftM head getArgs >>= print

...