Scala中的Typeclass模式实例-转载于BitTiger.io

来源:互联网 发布:c语言a =b 编辑:程序博客网 时间:2024/06/11 17:01


Scala中的Typeclass模式实例


Typeclasses,(或者 type classes) 模式源自Haskell, 但是在Scala语言中得到了广泛应用并发扬光大.

What is a type class and why do we need it ?


Type classes are useful to solve several fundamental challenges in software engineering and programming languages. In particular type classes support retroactive extension: the ability to extend existing software modules with new functionality without needing to touch or re-compile the original source. [1]


在Scala 包中已经包含了几个由typeclasses实现的包,这包括scala.math.Numeric 跟 scala.math.Ordering。 但是在ScalaZ的中,所有的library都是基于typeclasses实现的。

Scala中使用traits和 implicits 可以实现typeclasses模式。 与Haskell相比,Scala中typeclasses的实现虽然繁琐一些,但同时也带来了极大的灵活性。在Haskell中只允许单一typeclasses实例化的全局创建,然而在Scala中几乎可以不束缚于创建数量的限制。

此外,在Scala中如果在上下文中找不到合适的typeclasses的实现,也可以指定默认的实现。我们通过下文的例子来看下Scala中如何实现typeclasses的模式。

Show me the Code!


首先我们来定义一个叫Transformer的单例对象,并且给这个Transformer类添加一个T => R的方法叫transform.


其次,我们要实现下transform的具体方法, 例如我们想完成一个从Int => String的转换, 这时我们可以通过implicit关键字来定义隐身转换的方法.

如果你仅仅认为typeclasses模式只能做单一类型的转换那就错了, 我们同样可以做容器类型的转换。举个例子,还是根据上文给的例子我们想做List[T] => String的转换, 为了做这个容器List[T] 到String的转换, 我们还需要一个从T => String的转换。同样,我们可以通过定义我们的隐式转换来实现:


如何理解上文中的代码呢? 首先我们用implicit定义了一个隐式转换的方法叫ListToStringTransformer[T],同时,作为传入参数tToString, 也需要定义一个隐式转换类型Transformer[T, String]。 这样做的好处就是,你的参数可以不用显示的指明来传入,Scala的compiler会去自动搜索你的上下文找到相对应的这个类型的参数。 最后,我们在ListToStringTransformer中需要具体的实例化我们传入的的Tranformer类,并复写transform方法。

接下来,我们要使用下我们之前定义的Transform typeclasses。我们可以通过定义一个Transform trait来实现。trait的命名完全等同于我们之前定义的typeclasses Transform。

上图中的trait的transform方法中,有两个传入参数, 第一个传入参数为t,其类型为T。 可以显示的声明传入; 第二个传入参数是被implicit修饰的transformer,其类型为Transformer[T,R],而这个transformer参数被隐式传入。 当这个方法被调用时, Scala的编译器会根据你第一个传入的数据类型为T的t,结合从上下文找到相应类型为T的transformer来调用, 也就是用来调用相应的transformer.transform(t)方法。


最后我们来调用下我们定义的typeclasses, 通过以下示例:






从Boolean => String的转换,


总结:

我们在定义typeclasses的时候要注意到3部分:

  1. 首先定义type class本身, 是个generic的trait.

  2. 我们需要实例化我们想要实现的具体类型

  3. 我们同时也要定义一个或多个的接口方法来实现(这里的接口方法可以定义到object中)


Reference

  1. "Type Classes as Objects and Implicits"; Bruno C. d. S. Oliveira, Adriaan Moors, Martin Odersky

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 微信限90天提现转帐功能怎么办? 星巴克券过期了怎么办 京东买面膜发个空包怎么办 手机低于4.4版本怎么办才能恢复 263云通信密码忘了怎么办 有信电话拉黑了怎么办 微信手机充值冲错了怎么办 国通石油卡怎么办红卡 善融商城有假货怎么办 中百购物卡丢了怎么办 cncbk被骗25万该怎么办 中银e贷额度冻结怎么办 招行抵押贷循环额度怎么办 小额钱袋被拒了怎么办 银行需要提供消费贷款发票怎么办 中银e贷款逾期怎么办 按揭房不想要了怎么办 房贷不想还了怎么办 融e借没有u盾怎么办 窗式空调声音大怎么办 瑞得卡过期了怎么办 对公账号转错了怎么办 中银e令丢了怎么办 中银e贷到期了怎么办 招行信用卡附属卡怎么办 华普超市购物卡怎么办 公司发超市购物卡怎么办 物美购物卡丢了怎么办 淘宝买肯德基电子券留错号码怎么办 京东e卡过期了怎么办 京东e卡绑定错了怎么办 手机换号京东账号绑的银行卡怎么办 京东金条激活失败怎么办 京东买的k3不能激活怎么办 优购手机光黑屏怎么办 优购手机忘记手势密码怎么办 消费卡过期了钱怎么办 超市卡过期了钱怎么办 宜家购物卡的钱怎么办 武商购物卡过期怎么办 丹尼斯卡过期了怎么办