当我们需要定义一些对应高阶类型进行相互类型转换的操作函数时,我们发现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. 搭建hexo博客

    hexo 是一款快速.简单.并且强大的博客博客模板框架 - 基于nodejs . 特点 基于nodejs 使用Markdown书写文章 无需数据库 可以使用GitHub Pages发布 要用到的模块 ...

  2. Android上dip、dp、px、sp等单位说明

    Android上dip.dp.px.sp等单位说明 dip  device independent pixels(设备独立像素). 不同设备不同的显示效果,这个和设备硬件有关,一般我们为了支持WVGA ...

  3. SQLServer数据库还原提示 数据库正在使用,无法获得独占访问权

    还原数据库的时候提示下图的错误:

  4. cordovas禁止横屏

    cordovas禁止横屏 官网 http://cordova.apache.org/docs/en/latest/config_ref/index.html#preference 配置config.x ...

  5. gulp学习笔记4

    gulp系列学习笔记: 1.gulp学习笔记1 2.gulp学习笔记2 3.gulp学习笔记3 4.gulp学习笔记4 之前的任务都是单个的,比较简单.接下去我们开始引用多个插件,一次性把任务搞定,省 ...

  6. lufylegend游戏引擎

    lufylegend游戏引擎介绍:click 这个链接我觉得已经很详细的介绍了这个引擎. 所以以下我只说说一些简单的游戏代码过程. 首先从canvas做游戏叙述起: 这是一个让人很熟悉的简单小游戏,网 ...

  7. SQL Server 错误日志收缩(ERRORLOG)

    一.基础知识 默认情况下,错误日志位于 : C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\LOG\ERRORLOG 和ERRORLOG.n 文 ...

  8. SSIS Component的ValidateExternalMetadata属性

    ValidateExternalMetadata Property Indicates whether the component validates its column metadata agai ...

  9. Create New Commands in Tcl

    Create New Commands in Tcl eryar@163.com 摘要Abstract:Tcl/Tk脚本可以很容易实现用户自定义的命令,方便的创建图形化的用户界面GUI,所以Tcl和T ...

  10. 使用Nginx配置NodeJs程序(Windows平台)

    简介 Nginx("engine x") 是一个高性能的 HTTP 和 反向代理 服务器,也是一个 IMAP/POP3/SMTP 服务器. Nginx 是由 Igor Sysoev ...