这是一个功能:
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
....
并且案件不断发生。有没有办法“泛化”这个函数,即抽象所有的情况?
编辑:构造函数使用具体但不同类型进行参数化。我认为这个“设计”可能有问题......如果有的话,请指出来!
答案 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 -> SomeDataType
,put
的类型为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
可以更轻松。