Pha*_*rae 9 haskell functor type-constraints
今天我想研究是否有可能以这种方式构造数据类型,它不存储其类型签名类型的数据,而是它的另一种表示形式.所以,这是我对GADT的尝试,它具有类型的类型构造函数a,但是类型的数据构造函数ByteString.
{-# 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.
instance Functor Serialized where
    fmap f (MkSerialized bs) = MkSerialized (encode (f (right (decode bs))))
                               where right (Right r) = r
但我得到的错误(序列化b)无法推断.如何约束Functor实例,以便Serialize在fmap?中强制执行?
您可以使用CoYoneda仿函数来完成此操作.
这个想法很简单:有一个额外的功能区域,您可以在其中累积您的fmap功能.解码值时,请应用该函数.
这是代码:
{-# LANGUAGE GADTs #-}
import Data.ByteString.Char8
import Data.Serialize
data Serialized a where
    MkSerialized
      :: (Serialize a)
      => ByteString -> (a -> b) -> Serialized b
decode' :: Serialized a -> a
decode' (MkSerialized bs f) = let Right r = decode bs in f r
instance Functor Serialized where
    fmap f (MkSerialized bs g) = MkSerialized bs (f . g)
这也有利于自动融合多个fmaps而不是重复的解码和编码,就像你的情况一样.
| 归档时间: | 
 | 
| 查看次数: | 1156 次 | 
| 最近记录: |