简体   繁体   中英

Couldn't match expected type ‘IO a0’ with actual type ‘a1 -> IO ()’

Works:

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

Doesn't work:

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

As far as I can undestand, >>= passes on the variable, which is then ignored in the subsequent lambda (\\_ -> ...) . However, when I transform that to using >> and have function composition, it doesn't appear to work.

What is the difference between the two that causes the second not to compile? It'd be great to know why those two expressions aren't equivalent.

/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’

This will work:

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

Note that f . g . map h xs f . g . map h xs f . g . map h xs implies that map h xs is a function you are composing with g and then f . But map transform todos is a list, and you are really composing the function putStrLn , unlines and map transform and then applying the composition to the list todos .

In general:

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

so your working expression:

putStrLn $ unlines $ map transform todos

is the same as:

( putStrLn . unlines . map transform ) todos

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM