为什么我不能在Yesod中从Handler返回ByteString?

时间:2017-12-15 18:39:18

标签: haskell yesod bytestring

我试图从Yesod中的ByteString函数返回Handler

getHomeR :: Handler ByteString
getHomeR = return "foo"

但我收到此错误:

/Users/maximiliantagher/Documents/Mercury/hs/mercury-web-backend/src/Application.hs:48:1: error:
    • No instance for (ToTypedContent ByteString)
        arising from a use of ‘yesodRunner’
    • In the expression:
        yesodRunner getHomeR env1404_axwe (Just HomeR) req1404_axwf
      In a case alternative:
          "GET"
            -> yesodRunner getHomeR env1404_axwe (Just HomeR) req1404_axwf
      In the expression:
        case Network.Wai.Internal.requestMethod req1404_axwf of {
          "GET"
            -> yesodRunner getHomeR env1404_axwe (Just HomeR) req1404_axwf
          _ -> yesodRunner
                 (void badMethod) env1404_axwe (Just HomeR) req1404_axwf }

为什么会发生这种情况以及为什么ByteString ToTypedContentToTypedContent个实例?

1 个答案:

答案 0 :(得分:7)

content-type类描述Text对数据的影响。因此,具有关联内容类型的类型(例如ValueToTypedContent(JSON)的UTF 8)可以具有自然的ByteString实例。

ByteString的问题在于它描述了任何二进制数据 - 您的octet-stream可能是PNG,JPEG或其他内容,因此不清楚要提供哪种内容类型。

如果您真的只想返回二进制数据,getHomeR :: Handler TypedContent getHomeR = return $ TypedContent typeOctet $ toContent ("x" :: ByteString) 内容类型是合适的:

image/jpeg

但是如果可能的话,你应该尝试更好的内容类型(例如JPEG {1}}。

在这种情况下,您可以像上面一样手动使用TypedContent,也可以为ToTypedContent以上的新类型编写自己的ByteString实例

newtype Jpeg = Jpeg ByteString deriving (Show, ToContent)

instance ToTypedContent Jpeg where
    toTypedContent h = TypedContent "image/jpeg" (toContent h)