Scalaz(29)- Free :Coyoneda - Functor for free
很多时候我们会遇到一些高阶类型F[_],但又无法实现它的map函数,也就是虽然形似但F不可能成为Functor。看看下面的例子:
trait Interact[A]
case class Ask(prompt: String) extends Interact[String]
case class Tell(msg: String) extends Interact[Unit]
Interact类型只容许两种实例:Ask继承了Interact[String], Tell继承Interact[Unit]。我们无法获取map[A,B]函数的B值,因而无法实现map函数了。但是,往往在一些场合里我们需要把F当做Functor来使用,如用Free Structure把F升格成Monad。也就是说我们需要把Interact当做Functor才能构建一个基于Interact的Free Monad。Scalaz里的Coyoneda与任何F[_]类型成同构(互等),而Coyoneda是个Functor,这样我们可以用Coyoneda来替代F。在上面的例子里我们只要得出F的Coyoneda,然后我们就可以用这个Coyoneda来替代F,因为它们是同构的。我们来看看Coyoneda的定义:scalaz/Coyoneda.scala
sealed abstract class Coyoneda[F[_], A] { coyo =>
/** The pivot between `fi` and `k`, usually existential. */
type I /** The underlying value. */
val fi: F[I] /** The transformer function, to be lifted into `F` by `run`. */
val k: I => A
...
/** Like `lift(fa).map(_k)`. */
def apply[F[_], A, B](fa: F[A])(_k: A => B): Aux[F, B, A] =
new Coyoneda[F, B]{
type I = A
val k = _k
val fi = fa
}
...
type Aux[F[_], A, B] = Coyoneda[F, A] {type I = B} /** `F[A]` converts to `Coyoneda[F,A]` for any `F` */
def lift[F[_],A](fa: F[A]): Coyoneda[F, A] = apply(fa)(identity[A])
即使F不是Functor,我们还是可以把F[A]拆成Coyoneda[F,A]。而Coyoneda和F同构,看下面scalaz里的代码:
type CoyonedaF[F[_]] = ({type A[α] = Coyoneda[F, α]}) import Isomorphism._ def iso[F[_]: Functor]: CoyonedaF[F]#A <~> F =
new IsoFunctorTemplate[CoyonedaF[F]#A, F] {
def from[A](fa: F[A]) = lift(fa)
def to[A](fa: Coyoneda[F, A]) = fa.run
}
我们自己同样可以用更简单的方法来证明:
object proof_coyo {
trait _Coyoneda[F[_],A] {
type I
def k: I => A
def fi: F[I]
} def toCoyo[F[_],A](fa: F[A]) =
new _Coyoneda[F, A] {
type I = A
val k = (a: A) => a
val fi = fa
}
def fromCoyo[F[_]: Functor,A](coyo: _Coyoneda[F,A]): F[A] =
Functor[F].map(coyo.fi)(coyo.k) }
对于任何类型F及A, 我们通过toCoyo, fromCoyo可以证明_Coyoneda和F[A]同构。 既然Coyoneda和F[A]同构,那么我们可以这样表述:F[A] >>> Coyoneda[F,A]。也就是说我们可以在任何地方用Coyoneda[F,A]替代F[A]。上面例子中的Interact也可以用Coyoneda替代:
trait Interact[A]
case class Ask(prompt: String) extends Interact[String]
case class Tell(msg: String) extends Interact[Unit] type coyoInteract[A] = Coyoneda[Interact,A]
Scalaz(29)- Free :Coyoneda - Functor for free的更多相关文章
- Scalaz(25)- Monad: Monad Transformer-叠加Monad效果
中间插播了几篇scalaz数据类型,现在又要回到Monad专题.因为FP的特征就是Monad式编程(Monadic programming),所以必须充分理解认识Monad.熟练掌握Monad运用.曾 ...
- Scalaz(40)- Free :versioned up,再回顾
在上一篇讨论里我在设计示范例子时遇到了一些麻烦.由于Free Monad可能是一种主流的FP编程规范,所以在进入实质编程之前必须把所有东西都搞清楚.前面遇到的问题主要与scalaz Free的Free ...
- Scalaz(39)- Free :a real monadic program
一直感觉FP比较虚,可能太多学术性的东西,不知道如何把这些由数学理论在背后支持的一套全新数据类型和数据结构在现实开发中加以使用.直到Free Monad,才真正感觉能用FP方式进行编程了.在前面我们已 ...
- Scalaz(34)- Free :算法-Interpretation
我们说过自由数据结构(free structures)是表达数据类型的最简单结构.List[A]是个数据结构,它是生成A类型Monoid的最简单结构,因为我们可以用List的状态cons和Nil来分别 ...
- Scalaz(33)- Free :算式-Monadic Programming
在任何模式的编程过程中都无法避免副作用的产生.我们可以用F[A]这种类型模拟FP的运算指令:A是可能产生副作用的运算,F[_]是个代数数据类型ADT(Algebraic Data Type),可以实现 ...
- Scalaz(9)- typeclass:checking instance abiding the laws
在前几篇关于Functor和Applilcative typeclass的讨论中我们自定义了一个类型Configure,Configure类型的定义是这样的: case class Configure ...
- Scalaz(44)- concurrency :scalaz Future,尚不完整的多线程类型
scala已经配备了自身的Future类.我们先举个例子来了解scala Future的具体操作: import scala.concurrent._ import ExecutionContext. ...
- Scalaz(43)- 总结 :FP就是实用的编程模式
完成了对Free Monad这部分内容的学习了解后,心头豁然开朗,存在心里对FP的疑虑也一扫而光.之前也抱着跟大多数人一样的主观概念,认为FP只适合学术性探讨.缺乏实际应用.运行效率低,很难发展成现实 ...
- Scalaz(41)- Free :IO Monad-Free特定版本的FP语法
我们不断地重申FP强调代码无副作用,这样才能实现编程纯代码.像通过键盘显示器进行交流.读写文件.数据库等这些IO操作都会产生副作用.那么我们是不是为了实现纯代码而放弃IO操作呢?没有IO的程序就是一段 ...
随机推荐
- Java final修饰符
final的定义: 在英文层面上,final的意思是"最后的","最终的"意思,在Java中也同样表示出此种含义. final的运用对象: final适用于修饰 ...
- react3 组件
<body><!-- React 真实 DOM 将会插入到这里 --><div id="example"></div> <!- ...
- SoapUI测试WS接口实战
引文: 本文讨论以下问题: 视频播放功能如何进行压力测试? 进行webservices接口测试时,用LR和soapui哪个工具更好? 1 测试需求 前几天接到一项压力测试的任务:视频播放功能的并发压力 ...
- IOS开发之控件篇UICollectionViewControllor第一章 - 普通介绍
1.介绍 UICollectionView和UICollectionViewControllor是IOS6.0后引入的新控件 使用UICollectionView必须实现三个接口: UICollect ...
- Linux常用命令03
上篇我们写到,如何编辑文件,我们有时候,在编辑的时候,有可能会异常的退出,这样的话, linux会针对这个文件生成一个swp文件,当你下次进入vi模式时,就会提示你一个错误 这样,即使你按enter键 ...
- static、const和static const
http://blog.csdn.net/rainkin1993/article/details/8068558 #include<iostream> using namespace st ...
- 去除IE6浏览器下获得焦点的元素的虚线框的两个小办法
[1]onfocus = "this.blur()"//得到焦点时,失去焦点 e.g. <a href="#" onfocus = "this. ...
- javase基础复习攻略《二》
今天就开始的真正走进JAVASE的世界,本篇介绍的是:JAVASE基础语法,大家如果有C语言的基础,对于本节内容一定感觉非常轻松,编程语言之间的都是相通的,只不过C语言属于面向过程编程,而JAVA语言 ...
- LeetCode:Move Zeroes
LeetCode:Move Zeroes [问题再现] Given an array nums, write a function to move all 0's to the end of it w ...
- js断点调试心得
虽然网上已经有多的数不清的调试教程了,但仍然没有发现哪篇文章写的通俗易懂,索性自己尝试写写自己的一些使用习惯或者说是心得,希望对那些还不是很懂得使用断点调试的孩子有一些帮助(大神请无视~). 1.断点 ...