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

1 篇文章 0 订阅
1 篇文章 0 订阅


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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值