通常写一个函数的案例

时间:2015-01-15 09:54:01

标签: haskell

这是一个功能:

data AnyControlFrame =
   PingFrame_ACF PingFrame
   |SynStream_ACF SynStreamFrame
   |RstStreamFrame_ACF RstStreamFrame
   |SettingsFrame_ACF SettingsFrame
   |WindowUpdateFrame_ACF WindowUpdateFrame
   |Ignored_ACF LB.ByteString


writeControlFrame :: AnyControlFrame -> Put 
writeControlFrame (PingFrame_ACF a)         = put a
writeControlFrame (RstStreamFrame_ACF a)    = put a
writeControlFrame (SettingsFrame_ACF a)     = put a
writeControlFrame (WindowUpdateFrame_ACF a) = put a
....

并且案件不断发生。有没有办法“泛化”这个函数,即抽象所有的情况?

编辑:构造函数使用具体但不同类型进行参数化。我认为这个“设计”可能有问题......如果有的话,请指出来!

1 个答案:

答案 0 :(得分:2)

您自己定义AnyControlFrame吗?如果是这样,那么你可以这样做:

data AnyControlFrame = PingFrame_ACF         { someValue :: SomeDataType }
                     | RstStreamFrame_ACF    { someValue :: SomeDataType }
                     | SettingsFrame_ACF     { someValue :: SomeDataType }
                     | WindowUpdateFrame_ACF { someValue :: SomeDataType }
                     | ....

writeControlFrame :: AnyControlFrame -> Put
writeControlFrame = put . someValue

这是有效的,因为someValue的类型为AnyControlFrame -> SomeDataTypeput的类型为SomeDataType -> Put。因此,你可以撰写它们。

如果您没有自己定义AnyControlFrame,那么(我相信)您可以做的唯一其他事情就是自己定义someValue

someValue :: AnyControlFrame -> SomeDataType
writeControlFrame (PingFrame_ACF a)         = a
writeControlFrame (RstStreamFrame_ACF a)    = a
writeControlFrame (SettingsFrame_ACF a)     = a
writeControlFrame (WindowUpdateFrame_ACF a) = a
....

writeControlFrame :: AnyControlFrame -> Put
writeControlFrame = put . someValue

无论哪种方式,使用someValue :: AnyControlFrame -> SomeDataType都会使您的代码更“通用”(尽管这不是我用来描述它的词)。如果您想编写多个函数,例如writeControlFrame,那么使用someValue可以更轻松。