2014-11-01 1 views
1

Я иду через «узнать тебе Haskell», и я написал после применения:

import System.IO 

main = do 
    filename <- getLine 
    handle <- openFile filename ReadMode 
    content <- hGetContents handle 
    putStr . unlines . (map isLong) . lines $ content 
    hClose handle 

isLong :: String -> String 
isLong x = if length x > 10 then x ++ " long enough" else x ++ " could be better!" 

И это работает, но когда я удалить «$» между строками и содержанием компиляцией терпит неудачу.

Не могли бы вы помочь мне понять, почему это неправильно?

Я думал, что я сочиняю утверждения с точками, и я получаю функцию (String -> IO()), и я применяю ее к «контенту», но зачем нужен «$» здесь?

Спасибо!

ответ

8

Оператор (.) Имеет тип (b -> c) -> (a -> b) -> a -> c .... Его первые два входа должны быть функциями.

lines content, однако, имеет тип [String], а не функцию, следовательно f . lines content не удастся. Компилятор обрабатывает его как

f . (lines content) 

путем добавления ($), изменить приоритет, и он становится

f . lines $ content = (f . lines) $ content 

, который работает, потому что f и lines являются обе функции.

0

Значок доллара в haskell используется для применения функции по значению.

Его окружение - это то, что вам не нужны сложные круглые скобки.