2016-09-15 102 views
1

当我尝试编译代码时,发生两个错误。Haskell错误:无法匹配预期类型'ServerPartT IO a0'与实际类型'[Response]'

第一个是:

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

它提到了码连续3个大块,其中一个

第二个是:

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), 
... 
] 
+0

我只对你的代码做了一个简短的介绍,但是 - 我会怀疑'map'中的一些不正确的父类化尝试使用显式的parens而不是'$',并且看看你是否有进一步的了解。此外,我会说这不是一个最小的“非工作”的例子 - 尝试删除一切不会改变错误信息。 – epsilonhalbe

回答

1

我想这个问题是,在你做块中的第二条语句是msum (...) ++ [...]这是解析为(msum [...]) ++ [...]。所以编译器会看到++,并推断这是列表monad中的一条语句。但根据其余的代码,do块应该使用ServerPartT IO monad。这就是为什么你得到ServerPartT IO a0‘[Response]不匹配的第一个错误信息。

要解决这个问题,尽量把更多的括号:

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

或者其他经营者美元:

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

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

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

+0

非常感谢!有用! –

相关问题