Scalaz(30)- Free :Natural Tranformation ~> - map higher kinded types for free

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

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

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

1 hOptFun(None)                                     //> res0: List[Nothing] = List()
2 //hOptFun(Some(10)) //type mismatch;  found   : Int(10)  required: Nothing
3 //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就行了:

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

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

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏程序员的知识天地

Python列表最常见的问题【总结】

列表是Python中使用最多的一种数据结果,如何高效操作列表是提高代码运行效率的关键,本文总结了一些python列表最常见的问题,希望能对大家有帮助。

392
来自专栏武军超python专栏

2018年8月23日python中列表的高级操作:列表推导式,列表生成器,列表迭代器

列表在我们平常的编程中经常会用到,多用于临时存储一些程序需要的数据, 向列表中添加数据时,有多种方式: 1.数据少的话直接定义列表中的数据 my1 = [...

1113
来自专栏null的专栏

python基础知识——内置数据结构(列表)

列表是python中使用较多的一种数据结构,通常是作为函数的返回类型。相比较于元组,列表中的元素是可以修改的,可以实现添加、删除和查找的操作。 1、列表的创建 ...

32710
来自专栏python成长之路

字典常用操作

1674
来自专栏小鹏的专栏

用一个脚本学习 python

# -*- coding: utf-8 -*- # Python 2.7 学习参考脚本 # print 打印函数 print "Hello Worl...

2667
来自专栏C/C++基础

C++11——lambda表达式

定义: C++11新增了很多特性,lambda表达式(lambda expression)就是其中之一,很多语言都提供了 lambda 表达式,如 Pyth...

642
来自专栏蓝天

彻底理解C/C++指针

彻底理解C++指针.pdf 推荐阅读pdf版本,原因是从WPS复制粘贴到ChinaUnix后格式有些丢了。

641
来自专栏cs

python的元组和列表

慕课网 首发了,放在垂直领域吧。简书备份。 在python中,最基本的数据类型就是序列。序列表示一系列有序的元素,列表,元组,字符串是python最常见的序列...

3418
来自专栏静默虚空的博客

[Java 基础]基础语法

Java代码基本规范 大小写敏感:Java是大小写敏感的,这就意味着标识符Hello与hello是不同的。 类名:对于所有的类来说,类名的首字母应该大写。如果类...

1848
来自专栏Crossin的编程教室

python list 排序的两种方法及实例讲解

对 list 进行排序,Python 提供了两个方法: 方法1. 用 list 的内建函数 list.sort 进行排序 list.sort(func=None...

2674

扫码关注云+社区