I'm trying to return a ByteString
from my Handler
function in Yesod:
getHomeR :: Handler ByteString
getHomeR = return "foo"
but I'm getting this error:
/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 }
Why is this happening and why doesn't ByteString
have a ToTypedContent
instance?
The ToTypedContent
class describes what the content-type
is of the data. So types that have an associated content type (e.g. UTF 8 for Text
or Value
(JSON)) can have a natural ToTypedContent
instance.
The problem with ByteString
is that it describes any binary data—your ByteString
could be a PNG, a JPEG, or anything, so it's unclear what content type to give it.
If you really just want to return binary data, the octet-stream
content type is appropriate:
getHomeR :: Handler TypedContent
getHomeR = return $ TypedContent typeOctet $ toContent ("x" :: ByteString)
But you should try for a better content type if possible (e.g. image/jpeg
for JPEG).
In that case, you can either use the TypedContent
manually as above, or write your own instance of ToTypedContent
for a newtype over ByteString
newtype Jpeg = Jpeg ByteString deriving (Show, ToContent)
instance ToTypedContent Jpeg where
toTypedContent h = TypedContent "image/jpeg" (toContent h)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With