4

ByteString を Text に、またはその逆に変換する際に問題が発生しました。コードは次のとおりです。

{-# 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

エラーメッセージ:

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 <> ";"'

したがって、このエラーは ClientSession が実際に使用するものと関係があると思います。ソースコードでは、実装で動作するはずの通常のバイト文字列を使用しているようです。ここを見て:

[..]
import qualified Data.ByteString as S
[..]
encryptIO :: Key -> S.ByteString -> IO S.ByteString
[..]

では、なぜこれらすべてのエラーが発生するのでしょうか? ありがとう。

4

2 に答える 2

10

と を混ぜData.ByteString.ByteStringData.ByteString.Lazy.ByteStringいました。型名が同じであるため、GHC はひどいエラー メッセージを生成する可能性があります (実際に生成します)。ByteStringとの明示的なインポートを使用して作り直しましたText。うまくいけば、もう少し明白になりました。

{-# 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
于 2013-09-12T16:16:27.537 に答える
2

Data.String.Conversionsパッケージは、その知識を単一の変換関数で抽象化します。csどのバージョンが呼び出されるかは、呼び出しのコンテキスト (つまり、入力と期待される型) に応じて異なります。

于 2014-12-12T15:35:35.250 に答える