2016-08-20 73 views
0

作品: 無法比擬預期的類型 'IO A0' 與實際類型 'A1 - > IO()'

enumerate = \todos -> 
    setSGR [SetColor Foreground Vivid Red] >>= 
    (\_ -> putStrLn $ unlines $ map transform todos) >> 
    setSGR [Reset] 

不起作用:

enumerate = \todos -> 
    setSGR [SetColor Foreground Vivid Red] >> 
    putStrLn . unlines . map transform todos >> 
    setSGR [Reset] 

至於我可以undestand,>>=傳遞變量,然後在隨後的lambda (\_ -> ...)中被忽略。但是,當我將其轉換爲使用>>並且具有函數組合時,它似乎不起作用。

導致第二個不能編譯的兩者之間的區別是什麼?很高興知道爲什麼這兩個表達式不相同。

/Users/atimberlake/Webroot/HTodo/htodo/app/Main.hs:18:25: 
    Couldn't match expected type ‘IO a0’ with actual type ‘a1 -> IO()’ 
    In the second argument of ‘(>>)’, namely 
     ‘putStrLn . unlines . map transform todos’ 
    In the first argument of ‘(>>)’, namely 
     ‘setSGR [SetColor Foreground Vivid Red] 
     >> putStrLn . unlines . map transform todos’ 
    In the expression: 
     setSGR [SetColor Foreground Vivid Red] 
     >> putStrLn . unlines . map transform todos 
     >> setSGR [Reset] 

/Users/atimberlake/Webroot/HTodo/htodo/app/Main.hs:18:46: 
    Couldn't match expected type ‘a1 -> [String]’ 
       with actual type ‘[[Char]]’ 
    Possible cause: ‘map’ is applied to too many arguments 
    In the second argument of ‘(.)’, namely ‘map transform todos’ 
    In the second argument of ‘(.)’, namely 
     ‘unlines . map transform todos’ 
+0

不同意接近的選票。這不是一個印刷錯誤,而是對'.'和'$'如何工作的誤解。 – amalloy

+0

同意......認爲這對Haskell的其他出發點很有用。事實上,我應該已經意識到,但是在處理Haskell的複雜性時,通常會犯這些愚蠢的錯誤。 – Wildhoney

回答

2

這將工作:

enumerate = \todos -> 
    setSGR [] >> 
    (putStrLn . unlines . map transform) todos >> 
    setSGR [] 

注意f . g . map h xs意味着map h xs是你與g然後f合成的功能。但map transform todos是一個列表,並且 您確實正在編寫功能putStrLn,unlinesmap transform,然後將組合應用於列表todos

一般:

f $ g $ h x = (f . g . h) x 

所以你的工作表現:

putStrLn $ unlines $ map transform todos 

是一樣的:

(putStrLn . unlines . map transform) todos 
+0

現在非常有意義。謝謝! – Wildhoney

相關問題