无法将预期类型'IO a0'与实际类型'a1 - >匹配IO()'

时间:2016-08-20 14:18:11

标签: haskell

使用:

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]

据我所知,>>=传递变量,然后在随后的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’

1 个答案:

答案 0 :(得分:2)

这将有效:

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

请注意,f . g . map h xs表示map h xs是您使用g然后f撰写的函数。但是map transform todos是一个列表,而且 您实际上正在编写函数putStrLnunlinesmap transform,然后将合成应用于列表todos

一般来说:

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

所以你的工作表达:

putStrLn $ unlines $ map transform todos

与:

相同
( putStrLn . unlines . map transform ) todos