1

我想使用haskell中的yesod框架在html页面中发布curl命令的结果。这是我到目前为止的代码:

{-# LANGUAGE TypeFamilies, QuasiQuotes, MultiParamTypeClasses,
         TemplateHaskell, OverloadedStrings #-}
import Yesod
import Network.Curl
import Text.Blaze hiding (toMarkup)

data HelloWorld = HelloWorld

mkYesod "HelloWorld" [parseRoutes|
/ HomeR GET
|]

url = "http://www.google.com/"
opts = [CurlFollowLocation True]

res=withCurlDo $ do
            curlGet url opts
            return ()

instance ToMarkup (IO a) where
toMarkup a = a

instance Yesod HelloWorld

getHomeR :: Handler RepHtml
getHomeR = defaultLayout [whamlet|#{toMarkup res}|]

main :: IO ()
main = warpDebug 3000 HelloWorld

此代码启动带有警告的服务器

Warning: No explicit method nor default method for `Text.Blaze.toMarkup'
In the instance declaration for `ToMarkup (IO a)'

并将网络浏览器指向

http://localhost:3000

它在上述警告消息中以 HTML 页面的形式给出“内部服务器错误”。

我对 Haskell 和 Yesod 还很陌生……有人可以帮忙吗?

4

1 回答 1

1

您的缩进是错误的toMarkup(应该缩进)。但是类型仍然是错误的。toMarkup应该返回一个Markup实例并将curlGet输出转储到标准输出,而您想要捕获它并重新渲染它。

尝试这样的事情:

{-# LANGUAGE TypeFamilies, QuasiQuotes, MultiParamTypeClasses, TemplateHaskell, OverloadedStrings #-}
import Yesod
import Network.Curl

data HelloWorld = HelloWorld

mkYesod "HelloWorld" [parseRoutes|
      / HomeR GET
    |]

url = "http://www.google.com/"
opts = [CurlFollowLocation True]

instance Yesod HelloWorld

getHomeR = do
    (code, res) <- liftIO $ curlGetString url opts        
    -- This doesn't work since Yesod HTML-escapes the content in the template
    -- defaultLayout [whamlet|#{res}|]
    return $ RepHtml $ toContent res

main :: IO ()
main = warpDebug 3000 HelloWorld

作为 curl 的替代方案,您还可以使用http-conduit。导入Net.HTTP.Conduit,你可以写成getHomeR

getHomeR = fmap (RepHtml . toContent) . liftIO $ simpleHttp "http://www.google.com"
于 2013-03-12T15:53:21.887 回答