本文的写做的灵感主要是看了这个视频 : Tutorial: Typeclasses in Scala with Dan Rosen html
加上查阅了相关的资料,以为能够写一篇博客,再加上也好久没写博客了。本文的主要内容是根据参考资料express
对typeclass的解释再加上本身的一点点理解,代码会借(cao)鉴(xi)资料中的例子(不过代码会稍做修改)。json
首先简单看看维基上对于typeclass的定义:"In computer science, a type class is a type system ide
construct that supports ad hoc polymorphism." 这个“ad hoc polymorphism”(特质多态)其实也被函数
称做函数重载或运算符重载。测试
在scala中采用typeclass模式有什么有优势呢?总的来讲就是:代码易扩展;代码写得好看。
ui
如下用到的代码均借鉴自[2] 。spa
首先咱们来看看两个 ADT 的定义:scala
就是定义了一个表达式ADT,还有Json ADT。
视频
而后还有给表达式赋值的和输出Json的两个object :
简单测试一下:
而后如今想添加一个功能,就是给定某个类型的对象,得到该对象的json字符串。面向对象的作法是
声明一个JsonConvertible接口,而后让有须要类型去继承该接口,实现 convertToJson 方法。
如今想让Expression类型的对象都能转成Json类型,那么就是每一个Expression类型都要去实现
converToJson方法。
而后咱们能够简单测试一下:
而后如今问题来了,咱们想保持Expression接口尽可能的轻量,不想有太多的依赖,并且若是如今又要增长
一个新的trait那么Number、Multiply和Divide三个类又要去实现这个接口的方法。或者若是Expression是属于
第三方的库,没法修改来继承JsonConvertible怎么办?
这时候继承多态不适用了,咱们要用特质多态来解决这个问题。
咱们先来看看新的write函数定义,如今咱们新加了一个helper类JsonConverter,这个类实现了
把value转化为Json类型的方法。而后咱们来看看如今这么作的好处:
咱们能够看到,如今Expression能够保持原来的样子,而且把Expression转化为Json的逻辑与
Expression的实现分开了。简单测试一下:
so far so good。可是如今想再进一步使实现更简洁一些,这个JsonConverter其实并不必定要
显式的传入,咱们能够借助scala的implicit来实现。
就是在原来的基础上做些小修改,把expressionJsonConverter改成implicit,还有write函数
改成curry,conv参数改成implicit。简单测试一下:
更进一步咱们能够用scala中的context bound来改写代码。
context bound 的表达形式是 A : B,意思是在上下文中存在隐式的 B[A] 类型的对象。刚开始
接触的时候我以为context bound 和 view bound很像, A <% B,view bound的意思你能够把
A看成B来用,上下文中须要存在一个A到B的隐式转换。
ok,到此就是scala type class的简单介绍,视频中后面还有关于Expression和Json的重构并扩展到
Int和Tuple上,有兴趣的能够看看。
相关资料
[1] What are type classes in Scala useful for?
[2] Tutorial: Typeclasses in Scala with Dan Rosen
[3] The Neophyte's Guide to Scala Part 12: Type Classes
[4] Type class