Haskell и ленивая оценка монад

Играя с монадами, я часто сталкиваюсь с проблемами оценки. Сейчас я понимаю основные понятия ленивой оценки, но не понимаю, как монады лениво оцениваются в Haskell.

Рассмотрим следующий код

module Main where
import Control.Monad
import Control.Applicative
import System

main = print <$> head <$> getArgs

В моем понимании функция main должна вывести первый аргумент консоли, но этого не происходит.

Я знаю, что

getArgs :: IO [String]
head <$> getArgs :: IO String
print <$> (head <$> getArgs) :: IO (IO ())
main :: IO (IO ())

так что, очевидно, первый аргумент не выводится на stdout, потому что содержимое первой монады IO не оценивается. Так что если я соединю эти две монады, то все работает.

main = join $ print <$> head <$> getArgs

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

8
задан Jack 17 October 2011 в 12:49
поделиться