Haskell 具有和类型的二进制实例
我正在处理两个不同的协议,并将它们的消息存储在一个通道中。为此,我使用了一个sum类型来捕获这两种类型的消息。现在我在为Haskell 具有和类型的二进制实例,haskell,Haskell,我正在处理两个不同的协议,并将它们的消息存储在一个通道中。为此,我使用了一个sum类型来捕获这两种类型的消息。现在我在为Binary编写解码实例时遇到了困难-我知道要解码哪个协议,但我不知道如何在不使用丑陋的newtype包装器的情况下强制执行它。代码是: -- Supported protocols data ProtoA = ProtoA data ProtoB = ProtoB -- Protocol sum type for storing messag
Binary
编写解码实例时遇到了困难-我知道要解码哪个协议,但我不知道如何在不使用丑陋的newtype包装器的情况下强制执行它。代码是:
-- Supported protocols
data ProtoA = ProtoA
data ProtoB = ProtoB
-- Protocol sum type for storing messages in a channel.
data P = PA ProtoA | PB ProtoB
-- messages stored in a channel that can support either message.
type PChan = TChan P
instance Binary ProtoA where
put ProtoA = return ()
get = return ProtoA
instance Binary ProtoB where
put ProtoB = return ()
get = return ProtoB
instance Binary P where
-- on put, have the constructor available to drive behavior
put (PA ProtoA) = return ()
put (PB ProtoB) = return ()
-- on get, nothing to differentiate behavior
-- don't want alternation
get = undefined
-- Yuck, wrapped newtypes instances...
newtype PA' = PA' P
newtype PB' = PB' P
instance Binary PA' where
put (PA' (PA ProtoA)) = return ()
put (PA' (PB ProtoB)) = fail "shouldn't happen"
get = return (PA' (PA ProtoA))
instance Binary PB' where
put (PB' (PA ProtoA)) = fail "shouldn't happen"
put (PB' (PB ProtoB)) = return ()
get = return (PB' (PB ProtoB))
有没有更好的方法来处理这个问题?也许是幻影类型?在解码时,我知道我在处理哪个协议,但不知道如何强制执行。非常欢迎您的建议和/或建议!谢谢 如果您知道您只有
ProtoA
或ProtoB
消息,请使用get::get ProtoA
或get::get ProtoB
阅读它们。如果您知道这是一个ProtoA
,那么没有理由尝试阅读P
。如果你想要一个P
持有ProtoA
,你可以使用(PA-get)::get P
除非您不知道p
是PA
还是PB
,否则您不会读取p
,因此您的二进制p
实例应该编写一个标记,用于区分PA
s和PB
s
instance Binary P where
put (PA a) = do put (0 :: Word8)
put a
put (PB b) = do put (1 :: Word8)
put b
get = do t <- get :: Get Word8
case t of
0 -> PA <$> get
1 -> PB <$> get
实例二进制P,其中
put(PA a)=do put(0::Word8)
放
put(PB b)=do put(1::Word8)
放b
得到
1->PB获取
如果您要将
p
s写入只应为ProtoA
s或ProtoB
s的某个位置,那么您的工作就是检查并确保这是真的。然后使用put::ProtoA->put
或put::ProtoB->put
如果您知道只有ProtoA
或ProtoB
消息,请使用get::get ProtoA
或get::get ProtoB
阅读它们。如果您知道这是一个ProtoA
,那么没有理由尝试阅读P
。如果你想要一个P
持有ProtoA
,你可以使用(PA-get)::get P
除非您不知道p
是PA
还是PB
,否则您不会读取p
,因此您的二进制p
实例应该编写一个标记,用于区分PA
s和PB
s
instance Binary P where
put (PA a) = do put (0 :: Word8)
put a
put (PB b) = do put (1 :: Word8)
put b
get = do t <- get :: Get Word8
case t of
0 -> PA <$> get
1 -> PB <$> get
实例二进制P,其中
put(PA a)=do put(0::Word8)
放
put(PB b)=do put(1::Word8)
放b
得到
1->PB获取
如果您要将p
s写入只应为ProtoA
s或ProtoB
s的某个位置,那么您的工作就是检查并确保这是真的。然后使用put::ProtoA->put
或put::ProtoB->put