Haskell错误:无法将预期类型'ServerPartT IO a0'与实际类型'[Response]'匹配

时间:2016-09-15 13:25:52

标签: haskell happstack

当我尝试编译代码时,会发生两个错误。

第一个是:

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] }

它提到了三个代码块,其中一个

第二个是:

    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]

我也不太确定错误的位置。

似乎这两个错误具有完全相反的含义。我现在很困惑。任何人都可以帮忙解释一下吗?谢谢!

原始代码在这里:

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
    ]

其中routes位于另一个模块中:

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

1 个答案:

答案 0 :(得分:2)

我想问题是你的do块中的第二个语句是msum (...) ++ [...],它被解析为(msum [...]) ++ [...]。因此编译器会看到++,并推断这是列表monad中的一个语句。但是基于其余的代码,do块应该使用ServerPartT IO monad。这就是您收到ServerPartT IO a0‘[Response]不匹配的第一条错误消息的原因。

要解决此问题,请尝试添加更多括号:

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

或另一位美元运营商:

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

第二条错误消息是同一问题的另一个结果。由于编译器推断该语句在列表monad中,因此它假定msum也属于列表monad。因此,msum的参数应该是列表monad(=列表列表)中的操作列表,但它是ServerPartT IO monad中的操作列表。我希望当您添加缺少的括号时,此错误消失,并且编译器发现msum应该来自ServerPartT IO monad。

错误位置应在您复制的部件上方的编译器输出中提供。应该有文件名,然后是冒号,然后是行号。编译器还报告与错误相关的源代码片段。请注意,例如,第一个错误消息没有三个不相关的源代码片段,但第一个片段是第二个片段的一部分,第二个片段是第三个片段的一部分。因此,编译器首先向您展示带有错误的部分,然后通过显示更大和更大的部分来提供更多上下文。