设为首页 加入收藏

TOP

Scalaz(27)- Inference & Unapply :类型的推导和匹配(四)
2017-10-10 12:13:20 】 浏览:1156
Tags:Scalaz Inference Unapply 类型 推导 匹配
]] = List(\/-(1
3 //| ), \/-(2), \/-(3)) 4 //sequenceList(lether) //....required: List#3051[?G[?A]] 5 sequenceList[({type l[x] = \/[String,x]})#l,Int](lether) 6 //> res8: scalaz#31.\/#32660[String#248,List#3051[Int#1125]] = \/-(List(1, 2, 3 7 //| ))

这样就可以了。那么在Unapply里有没有适合的款式呢?看看:

 

 /**Unpack a value of type `M0[A0, B0]` into types `[a]M0[a, B0]` and `A`, given an instance of `TC` */
  implicit def unapplyMAB1[TC[_[_]], M0[_, _], A0, B0](implicit TC0: TC[({type λ[α] = M0[α, B0]})#λ]): Unapply[TC, M0[A0, B0]] { type M[X] = M0[X, B0] type A = A0 } = new Unapply[TC, M0[A0, B0]] { type M[X] = M0[X, B0] type A = A0 def TC = TC0 def leibniz = refl } /**Unpack a value of type `M0[A0, B0]` into types `[b]M0[A0, b]` and `B`, given an instance of `TC` */
  implicit def unapplyMAB2[TC[_[_]], M0[_, _], A0, B0](implicit TC0: TC[({type λ[α] = M0[A0, α]})#λ]): Unapply[TC, M0[A0, B0]] { type M[X] = M0[A0, X] type A = B0 } = new Unapply[TC, M0[A0, B0]] { type M[X] = M0[A0, X] type A = B0 def TC = TC0 def leibniz = refl }

?好像unapplMFAB1,unapplMFAB2这两个实例都行。试试:

1 //val u1 = Unapply.unapplyMAB1[Applicative, \/, String, Int] //这个不行 2 //could not find implicit value for parameter TC0: scalaz#31.Applicative#28655[[α#75838]scalaz#31.\/#32660[α#75838,Int#1125]]
3 val u2 = Unapply.unapplyMAB2[Applicative, \/, String, Int] //这个可以 4                                                   //> u2 : scalaz#31.Unapply#32894[scalaz#31.Applicative#28655,scalaz#31.\/#3266 5                                                   //| 0[String#17383,Int#1125]]{type M#9842257[X#9842258] = scalaz#31.\/#32660[St 6                                                   //| ring#17383,X#9842258]; type A#9842259 = Int#1125} = scalaz.Unapply_0$$anon$ 7                                                   //| 13@47eaca72
8 sequenceList[u2.M,u2.A](lether)                   //> res9: Exercises#29.unapply#17810.u2#9836539.M#9842257[List#3051[Exercises#2 9                                                   //| 9.unapply#17810.u2#9836539.A#9842259]] = \/-(List(1, 2, 3))

不过需要我们人工判定那个款式才合适。我们可以充分利用Unapply来编写一个更概括的sequenceList函数:

 1 def sequenceListU[GA](lga: List[GA])(implicit U: Unapply[Applicative, GA]): U.M[List[U.A]] =
 2  sequenceList[U.M,U.A](U.leibniz.subst(lga))(U.TC)  3                                                   //> sequenceListU: [GA#10927512](lga#10936796: List#3051[GA#10927512])(implicit  4                                                   //| U#10936797: scalaz#31.Unapply#32894[scalaz#31.Applicative#28655,GA#1092751  5                                                   //| 2])U#10936797.M#65840[List#3051[U#10936797.A#65842]]
 6 sequenceListU(lli)                                //> res10: List#8636[List#8636[Int#1125]] = List(List(1, 2, 4), List(1, 3, 4))
 7 sequenceListU(los)                                //> res11: Option#1959[List#8636[String#248]] = Some(List(a, b, c))
 8 sequenceListU(lether)                             //> res12: scalaz#31.\/#32660[String#248,List#8636[Int#1125]] = \/-(List(1, 2,  9                                                   //| 3))
10 sequenceListU(List(1,2,3))                        //> res13: Int#1125 = 6

这个函数够概括的了。主要是通过leibeniz.subst把List[GA]转换成List[G[A]], 我们看看subst的源代码:

sealed abstract class Leibniz[-L, +H >: L, A >: L <: H, B >: L <: H] { def apply(a: A): B = subst[Id](a) def subst[F[_ >: L <: H]](p: F[A]): F[B] ...

不要慌,注意下面这两段代码:

/** Evidence that MA =:= M[A] */ def leibniz: MA === M[A] implicit def subst[A, B](a: A)(implicit f: A === B): B = f.subst[Id](a)

leibniz返回 MA === M[A],  subst 传入 A 返回 B。A >>>GA, B>>>G[A]。这样上面例子中的U.leibniz.subst(lga)就把List[GA]转换成了List[G[A]]。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

首页 上一页 1 2 3 4 下一页 尾页 4/4/4
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇Scalaz(25)- Monad: Monad Tr.. 下一篇Scala简单计算实例,其在数据分析..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目