2016-08-20 72 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

相关问题