当我们需要定义一些对应高阶类型进行相互类型转换的操作函数时,我们发现scala语言并不提供能定义这种函数的支持。举例来说:如果我们希望定义一个函数把对于任何T值的Option[T]转换成List[T]的话,我们可能这样定义:

 def toList[T](opt: Option[T]): List[T] = opt.toList
//> toList: [T](opt: Option[T])List[T]
val hOptFun = toList _ //> hOptFun : Option[Nothing] => List[Nothing] = <function1>

看看hOptFun的类型:Option[Nothing] => List[Nothing], 即我们无法对T的类型进行限定。如果我们使用hOptFun:

 hOptFun(None)                                     //> res0: List[Nothing] = List()
//hOptFun(Some(10)) //type mismatch; found : Int(10) required: Nothing
//hOptFun(Some("hi")) //type mismatch; found : String("hi") required: Nothing

结果是无法正常使用hOptFun。这就证明了scala是不支持高阶类型转换函数的。一个可行的方法是通过一个特殊类来实现高阶类型转换,这就是scalaz的NaturalTransformation类型的主要功能。scalaz的NaturalTransformation类型是这样定义的:scalaz/NaturalTransformation.scala

/** A universally quantified function, usually written as `F ~> G`,
* for symmetry with `A => B`.
*
* Can be used to encode first-class functor transformations in the
* same way functions encode first-class concrete value morphisms;
* for example, `sequence` from [[scalaz.Traverse]] and `cosequence`
* from [[scalaz.Distributive]] give rise to `([a]T[A[a]]) ~>
* ([a]A[T[a]])`, for varying `A` and `T` constraints.
*/
trait NaturalTransformation[-F[_], +G[_]] {
self =>
def apply[A](fa: F[A]): G[A]
...

我们只需要实现apply就行了:

 val optionToListTrans = new (Option ~> List) {
def apply[T](opt: Option[T]): List[T] = opt.toList
} //> optionToListTrans : scalaz.~>[Option,List] = Exercises.naturaltransform$$an
//| onfun$main$1$$anon$1@2d554825
optionToListTrans(None) //> res1: List[Nothing] = List()
optionToListTrans(Some("hi")) //> res2: List[String] = List(hi)
optionToListTrans.apply(.some) //> res3: List[Int] = List(3)

从optiontoListTrans.apply可以看出我们实际上直接调用了那个按我们要求实现的apply方法。换句话说:如果我们需要把F[A]与G[A]对应,我们可以通过实现apply的方式来表达它们具体的对应方式,这个apply方法就可以实现高阶类型的相互转换。

Scalaz(30)- Free :Natural Tranformation ~> - map higher kinded types for free的更多相关文章

  1. Scalaz(25)- Monad: Monad Transformer-叠加Monad效果

    中间插播了几篇scalaz数据类型,现在又要回到Monad专题.因为FP的特征就是Monad式编程(Monadic programming),所以必须充分理解认识Monad.熟练掌握Monad运用.曾 ...

  2. Scalaz(39)- Free :a real monadic program

    一直感觉FP比较虚,可能太多学术性的东西,不知道如何把这些由数学理论在背后支持的一套全新数据类型和数据结构在现实开发中加以使用.直到Free Monad,才真正感觉能用FP方式进行编程了.在前面我们已 ...

  3. Scalaz(37)- Free :实践-DB Transaction free style

    我一直在不断的提示大家:FP就是Monadic Programming,是一种特殊的编程风格.在我们熟悉的数据库编程领域能不能实现FP风格呢?我们先设计一些示范例子来分析一下惯用的数据库编程过程: i ...

  4. Scalaz(36)- Free :实践-Free In Action - 实用体验

    在上面几期讨论中我们连续介绍了Free Monad.因为FP是纯函数编程,也既是纯函数的组合集成,要求把纯代码和副作用代码可以分离开来.Free Monad的程序描述(AST)和程序实现(Interp ...

  5. Scalaz(34)- Free :算法-Interpretation

    我们说过自由数据结构(free structures)是表达数据类型的最简单结构.List[A]是个数据结构,它是生成A类型Monoid的最简单结构,因为我们可以用List的状态cons和Nil来分别 ...

  6. Scalaz(26)- Lens: 函数式不可变对象数据操作方式

    scala中的case class是一种特殊的对象:由编译器(compiler)自动生成字段的getter和setter.如下面的例子: case class City(name:String, pr ...

  7. Scalaz(44)- concurrency :scalaz Future,尚不完整的多线程类型

    scala已经配备了自身的Future类.我们先举个例子来了解scala Future的具体操作: import scala.concurrent._ import ExecutionContext. ...

  8. Scalaz(43)- 总结 :FP就是实用的编程模式

    完成了对Free Monad这部分内容的学习了解后,心头豁然开朗,存在心里对FP的疑虑也一扫而光.之前也抱着跟大多数人一样的主观概念,认为FP只适合学术性探讨.缺乏实际应用.运行效率低,很难发展成现实 ...

  9. Scalaz(42)- Free :FreeAp-Applicative Style Programming Language

    我们在前面花了几期时间讨论Free Monad,那是因为FP既是Monadic programming,Free Monad是FP模式编程的主要方式.对我们来说,Free Monad代表着fp从学术探 ...

随机推荐

  1. Atitit 知识图谱的数据来源

    Atitit 知识图谱的数据来源   2. 知识图谱的数据来源1 a) 百科类数据2 b) 结构化数据3 c) 半结构化数据挖掘AVP (垂直站点爬虫)3 d) 通过搜索日志(query record ...

  2. 大数据时代的IT架构设计

    大数据时代的IT架构设计(来自互联网.银行等领域的一线架构师先进经验分享) IT架构设计研究组 编著   ISBN 978-7-121-22605-2 2014年4月出版 定价:49.00元 208页 ...

  3. Java 线程 — ConcurrentLinkedQueue

    ConcurrentLinkedQueue 在考虑并发的时候可以先考虑单线程的情况,然后再将并发的情况考虑进来. 比如ConcurrentLinkedQueue: 先考虑单线的offer 再考虑多线程 ...

  4. IDEA开发多项目的示例

    前言:慢慢习惯用IDEA了,觉得用起来确实还不错,有VS的感觉,但是缺点就是每次启动慢,如果修改以后反应也需要好久,这方面做得不好.但是职能提示个人觉得要比Eclipse好太多.好了现在我用IDEA来 ...

  5. HDU 1024Max Sum Plus Plus(最大m字段和)

    /* 动态转移方程:dp[i][j]=max(dp[i-1]+a[i], max(dp[t][j-1])+a[i]) (j-1<=t<i) 表示的是前i个数j个字段和的最大值是多少! */ ...

  6. 你用过这种奇葩的C#注释吗?如何看待

    本人虽然不是专业开发人员,也非专业出身,但一直使用C#堆码,解决自己日常的小问题.包括自己的研究,也是用C#来实现和测试.对C#是情有独钟.虽然C#的很多高级技术不会用,也不太懂,但总归是知道,耳闻目 ...

  7. IIS 6中mimemap属性的默认设置

    Collapse this tableExpand this table Extension MIME type .ra audio/x-pn-realaudio .sv4crc applicatio ...

  8. HTML5的学习--performance

    HTML5提供的performance接口精确的告诉我们当访问一个网站页面时当前网页每个处理阶段的精确时间(timestamp),以方便我们进行前端分析. 它是浏览器的直接实现,比在网页中用js设置D ...

  9. (高德地图)marker定位 bug 解决总结

    项目背景: 一个项目bug,项目中用到高德地图,默认打开页面会生成一个marker(下图红色icon),然后用户拖动marker到想要的位置,并且保存. 用户反映定位不准确,在当前页面编辑的位置,到后 ...

  10. Windows Azure Virtual Machine (26) 使用高级存储(SSD)和DS系列VM

    <Windows Azure Platform 系列文章目录> Update: 2016-11-3,如果大家在使用Linux VM,使用FIO进行IOPS测试的时候,请使用以下命令: su ...