今日、タイプシグネチャタイプのデータを格納しないようにデータタイプを構築することが可能かどうかを調べたいと思っていましたが、 。ですから、ここにはタイプコンストラクタがa
であるが、タイプがByteString
のデータコンストラクタを持つGADTの試みがあります。タイプ制約を持つGADTのFunctorインスタンス
{-# LANGUAGE GADTs #-}
import Data.ByteString.Char8
import Data.Serialize
data Serialized a where
MkSerialized :: (Serialize a) => ByteString -> Serialized a
今、私は次のようにdecode'
関数を定義することができます
decode' :: (Serialize a) => Serialized a -> a
decode' (MkSerialized bs) = let Right r = (decode bs) in r
そして、それは動作します:
let s = MkSerialized (encode "test") :: Serialized String
print $ decode' s -- prints "test"
私の問題は、私はSerialized
がなりたいということになりましたFunctor
のインスタンス。
しかし、私はエラー(Serialize b)を推測できません。 Functorインスタンスを制約して、Serialize
がfmap
に適用されるようにするにはどうすればよいですか?
できません。 'Functor'では、型パラメータの制約が必要になります。 'rmonad'パッケージ(http://hackage.haskell.org/packages/archive/rmonad/0.8/doc/html/Control-RMonad.html#t:RFunctor)には、制限されたファンクタクラス[' RFunctor']があります。多分あなたはそれを使うことができます。 –
これはあなたの質問には関係ありません。これは 'Functor'では実際には不可能ですが、私は言及する義務があります。デフォルトで' Data.ByteString.Char8'を使用しないでください!これは壊れたコードを奨励する壊れたモジュールです。時にはいくつかの用途がありますが、あなたのコードはUnicodeの誤解を招かない 'Data.ByteString'でも同様に動作します。 – shachaf
これは価値があると思いますが、ByteString - >(x - > a) - > Serialized a'のような 'Coordinated'スタイルのデータ型を' MkSerialized :: Serialize x =>ポスト・デシリアライゼーション機能を持ち、 'Functor'インスタンスを持っています。もちろん、それはここの目的を破るものです。 – shachaf