Scalaz(5)- typeclass:my typeclass scalaz style-demo
2015-09-19 17:13
585 查看
我们在上一篇讨论中介绍了一些基本的由scalaz提供的typeclass。这些基本typeclass主要的作用是通过操作符来保证类型安全,也就是在前期编译时就由compiler来发现错误。在这篇讨论中我希望能按照scalaz的格式设计自己的typeclass并能使之融入scalaz库结构里去。
我们来设计一个NoneZero typeclass。这个NoneZero typeclass能确定目标类型值是否为空,如:
0.nonZero = false
3.nonZero = true
"".nonZero = false
"value".nonZero = true
List().nonZero = false
List(1,2,3).nonZero = true
首先是trait: (定义typeclass行为)
现在NonZero typeclass只有一项功能或行为,就是这个抽象函数NonZero:对任何类型A值a,返回Boolean结果。
为了方便使用NoneZero typeclass,我们在伴生对象里定义NonZero[A]的构建函数:
只要我们提供一个f: A => Boolean函数就能用create来构建一个NonZero[A]实例。实际上这个f函数定义了类型A在NonZero tyoeclass中的具体行为。
下一步是注入操作方法:
我们注入了一个操作方法isNonZero。注意:注入方法是针对所有类型A的,所以需要NonZero[A]作为参数。
跟着就是隐式作用域解析了(implicit resolution):
这是一个隐式视域(implicit view):从类型A转换到NonZeroOps[A]。这样类型A就具备isNonZero这个操作方法了。
我们按scalaz惯例在object NonZero放一个默认隐式转换:
注意我们在create参数里使用了partial function。
然后试试在Int类型上使用:
不错,已经可以使用了。再试试其它即兴类型:
我把完整的代码贴在下面吧,供大家练习参考:
我们来设计一个NoneZero typeclass。这个NoneZero typeclass能确定目标类型值是否为空,如:
0.nonZero = false
3.nonZero = true
"".nonZero = false
"value".nonZero = true
List().nonZero = false
List(1,2,3).nonZero = true
首先是trait: (定义typeclass行为)
trait NonZero[A] { def nonZero(a: A): Boolean }
现在NonZero typeclass只有一项功能或行为,就是这个抽象函数NonZero:对任何类型A值a,返回Boolean结果。
为了方便使用NoneZero typeclass,我们在伴生对象里定义NonZero[A]的构建函数:
object NonZero { def create[A](f: A => Boolean): NonZero[A] = new NonZero[A] { def nonZero(a: A): Boolean = f(a) } }
只要我们提供一个f: A => Boolean函数就能用create来构建一个NonZero[A]实例。实际上这个f函数定义了类型A在NonZero tyoeclass中的具体行为。
下一步是注入操作方法:
class NonZeroOps[A](a: A)(implicit ev: NonZero[A]) { def isNonZero: Boolean = ev.nonZero(a) }
我们注入了一个操作方法isNonZero。注意:注入方法是针对所有类型A的,所以需要NonZero[A]作为参数。
跟着就是隐式作用域解析了(implicit resolution):
object ToNonZeroOps { implicit def toNonZeroOps[A](a: A)(implicit ev: NonZero[A]) = new NonZeroOps[A](a) }
这是一个隐式视域(implicit view):从类型A转换到NonZeroOps[A]。这样类型A就具备isNonZero这个操作方法了。
我们按scalaz惯例在object NonZero放一个默认隐式转换:
object NonZero { def create[A](f: A => Boolean): NonZero[A] = new NonZero[A] { def nonZero(a: A): Boolean = f(a) } implicit val intNZInstance: NonZero[Int] = create { case 0 => false case _ => true } }
注意我们在create参数里使用了partial function。
然后试试在Int类型上使用:
import ToNonZeroOps._ 10.isNonZero //> res0: Boolean = true 0.isNonZero //> res1: Boolean = false 2.isNonZero //> res2: Boolean = true
不错,已经可以使用了。再试试其它即兴类型:
import ToNonZeroOps._ implicit val stringNZInstance: NonZero[String] = NonZero.create { case "" => false case _ => true } //> stringNZInstance : scalaz.ex5.NonZero[String] = scalaz.ex5$NonZero$$anon$1@ //| 1c655221 implicit val booleanNZInstance: NonZero[Boolean] = NonZero.create { b => b } //> booleanNZInstance : scalaz.ex5.NonZero[Boolean] = scalaz.ex5$NonZero$$anon$ //| 1@6aaa5eb0 implicit def listNZInstance[A]: NonZero[List[A]] = NonZero.create { case Nil => false case _ => true } //> listNZInstance: [A]=> scalaz.ex5.NonZero[List[A]] "".isNonZero //> res0: Boolean = false "not empty".isNonZero //> res1: Boolean = true true.isNonZero //> res2: Boolean = true false.isNonZero //> res3: Boolean = false List(1,2,3).isNonZero //> res4: Boolean = true List("a","b").isNonZero //> res5: Boolean = true List().isNonZero //> res6: Boolean = false 10.isNonZero //> res7: Boolean = true 0.isNonZero //> res8: Boolean = false 2.isNonZero //> res9: Boolean = true
我把完整的代码贴在下面吧,供大家练习参考:
trait NonZero[A] { def nonZero(a: A): Boolean }
object NonZero { def create[A](f: A => Boolean): NonZero[A] = new NonZero[A] { def nonZero(a: A): Boolean = f(a) } implicit val intNZInstance: NonZero[Int] = create { case 0 => false case _ => true } }class NonZeroOps[A](a: A)(implicit ev: NonZero[A]) { def isNonZero: Boolean = ev.nonZero(a) }
object ToNonZeroOps { implicit def toNonZeroOps[A](a: A)(implicit ev: NonZero[A]) = new NonZeroOps[A](a) }
import ToNonZeroOps._ implicit val stringNZInstance: NonZero[String] = NonZero.create { case "" => false case _ => true } //> stringNZInstance : scalaz.ex5.NonZero[String] = scalaz.ex5$NonZero$$anon$1@ //| 1c655221 implicit val booleanNZInstance: NonZero[Boolean] = NonZero.create { b => b } //> booleanNZInstance : scalaz.ex5.NonZero[Boolean] = scalaz.ex5$NonZero$$anon$ //| 1@6aaa5eb0 implicit def listNZInstance[A]: NonZero[List[A]] = NonZero.create { case Nil => false case _ => true } //> listNZInstance: [A]=> scalaz.ex5.NonZero[List[A]] "".isNonZero //> res0: Boolean = false "not empty".isNonZero //> res1: Boolean = true true.isNonZero //> res2: Boolean = true false.isNonZero //> res3: Boolean = false List(1,2,3).isNonZero //> res4: Boolean = true List("a","b").isNonZero //> res5: Boolean = true List().isNonZero //> res6: Boolean = false 10.isNonZero //> res7: Boolean = true 0.isNonZero //> res8: Boolean = false 2.isNonZero //> res9: Boolean = true
相关文章推荐
- Scalaz(5)- typeclass:my typeclass scalaz style-demo
- php多维数组的去重(针对任意的键值进行去重)--二维数组的唯一--时间复杂度~O(n)
- Thinkphp学习笔记
- thinkphp 数据库设置前缀问题 联合查询
- php 出现 500 Internal Server Error错误问题解决
- PHP 基础
- E9天嵌i.mx6q的nfs和tftp环境搭建
- windows下安装php性能分析工具XHProf
- 解决phpcms 后台更新提交更新目录出现PHP has encountered a Stack overflow错误
- Yii的where方法使用大全
- getAttribute()和getParameter()方法区别
- php设置时区和获取当前时间
- Php防跨站分析
- php获取客户端真实IP 防止代理和作弊
- php获得ip地址
- Ubuntu 上安装ftp服务器 vsftpd
- EditPlus常用快捷键
- Yii Framework2.0开发教程(5)数据库mysql性能
- getAttribute 和 getParameter的区别
- php基础------SESSION