无法将预期类型“HandlerT ...”与实际类型“IO String”

时间:2017-01-17 01:30:26

标签: haskell yesod

尝试制作一个yesod应用程序(没有堆栈,yesod init),当我编译它时,我遇到了这个monad错误。我知道这些问题很常见,但我从未见过有人用这些特定类型(即HandlerT和IO String)提出这个问题。这是我的所有代码,所以我认为应该很容易让某人测试这个。我也在使用GHC 7.10.3,它有点老了,但我不认为我的问题与编译器版本有任何关系。

$ ghc --version
The Glorious Glasgow Haskell Compilation System, version 7.10.3

这是编译器错误消息:

$ ghc -o yesod_test yesod_monad_test.hs
[1 of 1] Compiling Main             ( yesod_monad_test.hs, yesod_monad_test.o )

yesod_monad_test.hs:25:15:
    Couldn't match expected type `HandlerT HelloWorld IO Text'
                with actual type `IO String'
    In a stmt of a 'do' block: snippet <- readFile temp
    In the expression:
      do { let temp = "posts/" ++ title ++ ".html";
           snippet <- readFile temp;
           defaultLayout
             ((asWidgetT . toWidget) (toHtml (preEscapedText snippet))) }

这是我的代码。

{-# LANGUAGE OverloadedStrings     #-}
{-# LANGUAGE QuasiQuotes           #-}
{-# LANGUAGE TemplateHaskell       #-}
{-# LANGUAGE TypeFamilies          #-}
{-# LANGUAGE ViewPatterns          #-}

import Yesod
import Network.Wai           (pathInfo, rawPathInfo, requestMethod, responseLBS)
import Data.Text             (Text)
import Text.Blaze            (preEscapedText)
import Control.Exception     (IOException, try)
import Control.Monad         (when)

data HelloWorld = HelloWorld

mkYesod "HelloWorld" [parseRoutes|
 /post/#String PostR GET
|]

instance Yesod HelloWorld

getPostR :: String -> Handler Html
getPostR title = do
   let temp = "posts/" ++ title ++ ".html"
   snippet <- readFile temp
   defaultLayout [whamlet|#{preEscapedText snippet}|]

main :: IO ()
main = warp 3000 HelloWorld

我很惊讶这段代码不起作用,因为我相信我正在非常仔细地阅读教程(http://www.yesodweb.com/book/routing-and-handlers#routing-and-handlers_overlap_checking),尽管我在文本类型上使用了字符串。

谢谢。

1 个答案:

答案 0 :(得分:3)

@Alec的答案基本上是正确的。谢谢!

  

基本上,@ amalloy会告诉您将snippet <- readFile temp替换为snippet <- liftIO $ readFile temp