简体   繁体   中英

Haskell error: couldn't match expected type ‘ServerPartT IO a0’ with actual type '[Response]'

When I tried to compile the code, two errors occur.

the first one is:

Couldn't match expected type ‘ServerPartT IO a0’
            with actual type ‘[Response]’
In a stmt of a 'do' block:
  msum
    (map (\ (a, b) -> dir a b)
     $ routes
         staticDir
         redirectUrlGraphEmail
         redirectUrlGraphPost
         aboutContents
         privacyContents)
  ++
    [do { nullDir;
          seeOther "graph" (toResponse "Redirecting to /graph") },
     notFoundResponse]
In the second argument of ‘($)’, namely
  ‘do { decodeBody (defaultBodyPolicy "/tmp/" 4096 4096 4096);
        msum
          (map (\ (a, b) -> dir a b)
           $ routes
               staticDir
               redirectUrlGraphEmail
               redirectUrlGraphPost
               aboutContents
               privacyContents)
        ++
          [do { nullDir;
                .... },
           notFoundResponse] }’
In a stmt of a 'do' block:
  simpleHTTP serverConf
  $ do { decodeBody (defaultBodyPolicy "/tmp/" 4096 4096 4096);
         msum
           (map (\ (a, b) -> dir a b)
            $ routes
                staticDir
                redirectUrlGraphEmail
                redirectUrlGraphPost
                aboutContents
                privacyContents)
         ++
           [do { nullDir;
                 .... },
            notFoundResponse] }

It mentioned three chunks of code, which one

the second one is:

    Couldn't match type ‘ServerPartT IO’ with ‘[]’
Expected type: [[Response]]
  Actual type: [ServerPartT IO Response]
In the first argument of ‘msum’, namely
  ‘(map (\ (a, b) -> dir a b)
    $ routes
        staticDir
        redirectUrlGraphEmail
        redirectUrlGraphPost
        aboutContents
        privacyContents)’
In the first argument of ‘(++)’, namely
  ‘msum
     (map (\ (a, b) -> dir a b)
      $ routes
          staticDir
          redirectUrlGraphEmail
          redirectUrlGraphPost
          aboutContents
          privacyContents)’
In a stmt of a 'do' block:
  msum
    (map (\ (a, b) -> dir a b)
     $ routes
         staticDir
         redirectUrlGraphEmail
         redirectUrlGraphPost
         aboutContents
         privacyContents)
  ++
    [do { nullDir;
          seeOther "graph" (toResponse "Redirecting to /graph") },
     notFoundResponse]

I am also not quite sure about the location of the error.

It seems like these two errors have totally opposite meanings. I am confused now. Can anyone help to explain this? Thanks!

The original code is here:

runServer :: IO ()
runServer = do
configureLogger
staticDir <- getStaticDir
redirectUrlGraphEmail <- retrieveAuthURL testUrl
redirectUrlGraphPost <- retrieveAuthURL testPostUrl
aboutContents <- LazyIO.readFile $ markdownPath ++ "README.md" 
privacyContents <- LazyIO.readFile $ markdownPath ++ "PRIVACY.md"

-- Start the HTTP server
simpleHTTP serverConf $ do
  decodeBody (defaultBodyPolicy "/tmp/" 4096 4096 4096)
  msum  
       (map (\ (a, b) -> dir a b) $ routes staticDir redirectUrlGraphEmail redirectUrlGraphPost aboutContents privacyContents ) ++  
       [ do
          nullDir
          seeOther "graph" (toResponse "Redirecting to /graph"),    
          notFoundResponse
    ]

where routes is in another module:

routes :: [Char] -> T.Text -> T.Text -> Text -> Text -> [ (String, ServerPart Response)]
routes staticDir redirectUrlGraphEmail redirectUrlGraphPost aboutContents privacyContents = [
("grid", gridResponse),
("graph", graphResponse),
("image", graphImageResponse),
...
]

I guess the problem is that the second statement in your do block is msum (...) ++ [...] which is parsed as (msum [...]) ++ [...] . So the the compiler sees the ++ and infers that this is a statement in the list monad. But based on the rest of the code, the do block should use the ServerPartT IO monad. That's why you get the first error message that ServerPartT IO a0 and '[Response] don't match.

To fix this , try putting more parentheses:

msum ((...) ++ [...])

Or another dollar operator:

msum $ (...) ++ [...]

The second error message is another result of the same problem. Since the compiler infers that the statement is in the list monad, it assumes that the msum belongs to the list monad, too. So the argument of msum should be a list of actions in the list monad (= a list of lists), but it is a list of actions in the ServerPartT IO monad. I expect that this error goes away when you add the missing parentheses and the compiler sees that the msum should be from the ServerPartT IO monad.

The error location should be provided in the compiler output above the part you copied. There should be a filename, then a colon, then a line number. The compiler also reports the pieces of source code that are relevant to the error. Note that, for example, the first error message doesn't have three unrelated pieces of source code, but that the first piece is a part of the second piece, and the second piece is a part of the third piece. So the compiler starts by showing you the piece with the error, and then larger and larger pieces to provide more context.

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