1.
上篇文章我们讲解了Functor,下面我们有必要对类型和种类做一个详细的讲解,这里我们需要理解两个知识点
(1).first-order-kinded type
(2).higher-kinded type
因为我们需要进入抽象性的编程,所以对数据类型要有一个理性的认识,我们先打个比方
函数与高级函数,这里我姑且认为你已经知道什么事高级函数了,同样的,类型也有高低之分,这里我们对数据类型进行二次的抽象,一次抽象比较简单我不讲解(就是我们Java经常使用的泛态)
二次抽象
(1).F[_] 对应first-order-kinded type,接受一个类型从而创建一个新的类型
(2)X[F[_]] 对应higher-kinded type,接受一个(1)的类型创建一个新的类型
我们上一集讲解的Functor就是X[F[_]]类型的
2.
同样scala也是提供了k命令来查看(这里后人追加的,并非官方提供的)
scala> :k List
scala.collection.immutable.List's kind is F[+A]
scala> :k Functor
scalaz.Functor's kind is X[F[A]]
scala>
这里X[F[A]]是A没有下界限制的!
3.
(1).first-order-kinded type
(2).higher-kinded type
两者的联系,这里不好做解析,这里看看leaning scalaz 的作者的阐述
For example, the data structure List forms a functor, in the sense that an instance Functor[List] can be derived for List. Since there should be only one instance for List, we can say that List is a functor.
这里看大家的领悟了,不过这里作者的补充
To add to the confusion, the fact that Scala can treat type constructor as a first class variable was novel enough
所以我们在lift函数时必须知道他的Functor[F]
scala> Functor[List].lift((_: Int) + 2)
res38: List[Int] => List[Int] = <function1>
scala> res38(List(1,2,3))
res39: List[Int] = List(3, 4, 5)
4.
补充scala无法使用newtype,我们可以创建我们需要的类型,例如
3$
如果我们可以类型的$(3)
type Tagged[U] = { type Tag = U }
type @@[T, U] = T with Tagged[U]
scala> sealed trait Axe
scala> def Axe[A](a: A): A @@ Axe = Tag[A, Axe](a)
Axe: [A](a: A)scalaz.@@[A,Axe]
使用新类型
scala> Axe(2)
res45: scalaz.@@[Int,Axe] = 2
获取里面的值
scala> scalaz.Tag.unsubst[Int, Id, Axe](res45)
res47: scalaz.Scalaz.Id[Int] = 2