I got problems with turning ByteString's into Text and vice versa. Here's the code:
{-# LANGUAGE OverloadedStrings #-}
import Web.Scotty
import Web.ClientSession
import Data.Text.Lazy (Text, toStrict, fromStrict)
import Data.Text.Lazy.Encoding (encodeUtf8, decodeUtf8)
import Data.ByteString (ByteString)
import Data.Monoid ((<>))
initCookies :: IO (Text -> ActionM ())
initCookies = do
key <- getDefaultKey
return $ setCookie key
where
setCookie k id = encryptIO k (encode id)
>>= (\x -> header "Set-Cookie" ("sid=" <> decode x <> ";"))
encode :: Text -> ByteString
encode = encodeUtf8 . toStrict
decode :: ByteString -> Text
decode = fromStrict . decodeUtf8
and error message:
foo.hs:16:35:
Couldn't match expected type `bytestring-0.10.0.2:Data.ByteString.Internal.ByteString'
with actual type `ByteString'
In the return type of a call of `encode'
In the second argument of `encryptIO', namely `(encode id)'
In the first argument of `(>>=)', namely `encryptIO k (encode id)'
foo.hs:17:18:
Couldn't match type `ActionM' with `IO'
Expected type: IO ()
Actual type: ActionM ()
In the return type of a call of `header'
In the expression: header "Set-Cookie" ("sid=" <> decode x <> ";")
In the second argument of `(>>=)', namely
`(\ x -> header "Set-Cookie" ("sid=" <> decode x <> ";"))'
foo.hs:17:56:
Couldn't match expected type `ByteString'
with actual type `bytestring-0.10.0.2:Data.ByteString.Internal.ByteString'
In the first argument of `decode', namely `x'
In the first argument of `(<>)', namely `decode x'
In the second argument of `(<>)', namely `decode x <> ";"'
So, my guess this error has something to do with what ClientSession actually use, in their source code they seem to use normal bytestring which should work with my implementation. Look here:
[..]
import qualified Data.ByteString as S
[..]
encryptIO :: Key -> S.ByteString -> IO S.ByteString
[..]
So why do I get all these errors? Thanks.
You were mixing Data.ByteString.ByteString
and Data.ByteString.Lazy.ByteString
. Because the type names are equal GHC can (and does) produce terrible error messages. I reworked it using explicit imports for ByteString
and Text
, hopefully it's a little more obvious now:
{-# LANGUAGE OverloadedStrings #-}
import Web.Scotty
import Web.ClientSession
import Control.Monad.Trans (liftIO)
import qualified Data.Text as T
import qualified Data.Text.Encoding as T
import qualified Data.Text.Lazy as TL
import qualified Data.Text.Lazy.Encoding as TL
import qualified Data.ByteString as B
import qualified Data.ByteString as BL
import Data.Monoid ((<>))
initCookies :: IO (TL.Text -> ActionM ())
initCookies = do
key <- getDefaultKey
return $ setCookie key
where
setCookie k id = liftIO (encryptIO k (encode id))
>>= (\x -> header "Set-Cookie" ("sid=" <> decode x <> ";"))
encode :: TL.Text -> B.ByteString
encode = T.encodeUtf8 . TL.toStrict
decode :: B.ByteString -> TL.Text
decode = TL.fromStrict . T.decodeUtf8
The Data.String.Conversions
package abstracts that knowledge with a single cs
conversion function, which version is called depending on the context of the call (i.e. input and expected type).
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