尝试制作一个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),尽管我在文本类型上使用了字符串。
谢谢。
答案 0 :(得分:3)
@Alec的答案基本上是正确的。谢谢!
基本上,@ amalloy会告诉您将
snippet <- readFile temp
替换为snippet <- liftIO $ readFile temp
。