Играя с монадами, я часто сталкиваюсь с проблемами оценки. Сейчас я понимаю основные понятия ленивой оценки, но не понимаю, как монады лениво оцениваются в 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
Не мог бы кто-нибудь, пожалуйста, прояснить это для меня? (или дайте мне указатель)