一般写一个函数的例子 [英] Generically write cases of a function

查看:118
本文介绍了一般写一个函数的例子的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是一个函数:

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


writeControlFrame :: AnyControlFrame - >把
writeControlFrame(A)写入一个
writeControlFrame(RstStreamFrame_ACF a)=放一个
writeControlFrame(SettingsFrame_ACF a)=放一个
writeControlFrame(WindowUpdateFrame_ACF a)=放一个
....

以及案例不断涌现。有没有一种方法可以泛泛地写出这个函数,即抽象出所有的情况?

编辑:构造函数是用具体但不同类型参数化的。我认为,我可能有这个设计的错误....如果是这样,请指出! 解决方案

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


$ b

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

writeControlFrame :: AnyControlFrame - >把
writeControlFrame = put。 someValue

这是因为 someValue AnyControlFrame - > SomeDataType put的类型 SomeDataType - >把。因此你可以编写它们。



如果你自己没有定义 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 - >把
writeControlFrame = put。 someValue

使用 someValue :: AnyControlFrame - > SomeDataType 使你的代码更加通用 (尽管这不是我用来描述它的词)。如果你想编写几个函数,比如 writeControlFrame ,那么使用 someValue 可以简单得多。


Here is a function:

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
....

and the cases keep coming. Is there a way to write this function "generically", that is, to abstract over all the cases?

EDIT: The constructors are parametrized with concrete, but different types. I reckon that I may have got something wrong with this "design".... if so, please point it out!

解决方案

Are you defining AnyControlFrame yourself? If so then you can do this:

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

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

This works because the type of someValue is AnyControlFrame -> SomeDataType and the type of put is SomeDataType -> Put. Hence you can compose them.

If you are not defining AnyControlFrame yourself then the only other thing that (I believe) you can do is define someValue yourself:

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

Either way, using someValue :: AnyControlFrame -> SomeDataType makes your code more “generic” (although that's not the word I would use to describe it). If you want to write several functions like writeControlFrame then using someValue makes it much easier.

这篇关于一般写一个函数的例子的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆