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)'

Web ブラウザで

http://localhost:3000

上記の警告メッセージに沿って「Internal Server Error」が HTML ページとして表示されます。

私はHaskellとYesodにかなり慣れていません...誰か助けてもらえますか?

4

1 に答える 1

1

インデントが間違っていtoMarkupます(インデントする必要があります)。ただし、型はまだ間違っています。インスタンスをtoMarkup返し、出力を stdout にダンプする必要がありますが、それをキャプチャして再レンダリングする必要があります。MarkupcurlGet

次のようなことを試してください:

{-# 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 に答える