我试图从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
ToTypedContent
有ToTypedContent
个实例?
答案 0 :(得分:7)
content-type
类描述Text
对数据的影响。因此,具有关联内容类型的类型(例如Value
或ToTypedContent
(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)