Created
December 31, 2011 13:02
-
-
Save linqing/1543950 to your computer and use it in GitHub Desktop.
category theory and scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
object Test { | |
/* 简介 */ | |
type A = Double // 一组对象A | |
type B = Long // 一组对象B | |
type C = String // 一组对象C | |
val f: A => B = // 一组态射f | |
(a: Double) => a.round | |
val g: B => C = // 另外一组态射g | |
(b: B) => b.toString() | |
val h: A => C = // 态射组合 | |
f andThen g | |
} | |
object Test2 { | |
/* 公理 */ | |
type A = Double // 一组对象A | |
type B = Long // 一组对象B | |
type C = String // 一组对象C | |
type D = List[Char] // 一组对象D | |
val f: A => B = // 一组态射f | |
_.round | |
val g: B => C = // 另外一组态射g | |
_.toString() | |
val h: C => D = // 又一组态射h | |
_.toCharArray.toList | |
/** | |
* 公理一:态射的组合操作要满足结合律 | |
* f . (g . h) = (f . g) . h | |
*/ | |
assert { | |
(f andThen (g andThen h)) == ((f andThen g) andThen h) | |
} | |
/** | |
* 公理二:态射在组合操作下是闭合的。 | |
* 所以如果存在态射f:A->B和g:B-C ,那么范畴中必定存在态射hh: A->C使得 | |
* hh = f . g | |
*/ | |
val hh: A => C = | |
(a: A) => a.round.toString() | |
assert { | |
hh == (f andThen g) | |
} | |
/** | |
* 公理三:对任何一个范畴 C ,其中任何一个对象 A 一定存在一个单位态射idA:A->A 。 | |
* 这个态射是组合操作的单位元。 | |
* f . idA = idA . f = f | |
*/ | |
val idA: A => A = | |
(a) => a | |
val idB: B => B = | |
(b) => b | |
assert { | |
(idA andThen f) == (f andThen idB) && | |
(idA andThen f) == f && | |
(f andThen idB) == f | |
} | |
} | |
object Test3 { | |
/* 函子Functor | |
* 函子本质上说其实就是范畴之间的转换。 | |
* 比如对于范畴 CategoryC 和 CategoryD ,函子F: CategoryC -> CategoryD能够: | |
* 1. 将 CategoryC 中任意对象 a 转换为 CategoryD 中的 F(A) | |
* 2. 将 CategoryC 中的态射f: A->B转换为 CategoryD 中的 F(f): F(A) -> F(B) | |
*/ | |
/* CategoryC */ | |
type A = Double // 范畴CategoryC中的一组对象A | |
type B = Long // 范畴CategoryC中的一组对象B | |
type C = String // 范畴CategoryC中的一组对象C | |
val f: A => B = | |
// 范畴CategoryC中的一组态射f | |
_.round | |
val g: B => C = | |
_.toString | |
/* Functor定义 */ | |
class Box[A](val theValue: A) | |
/* CategoryD */ | |
type FA = Box[A] | |
type FB = Box[B] | |
type FC = Box[C] | |
type FF = (A => B) => (FA => FB) | |
/* functor */ | |
object Functor { | |
val amap: A => FA = | |
(a) => new FA(a) | |
val bmap: B => FB = | |
(b) => new FB(b) | |
val fmap: (A => B) => (FA => FB) = | |
(f: A => B) => | |
(fa) => new FB(f(fa.theValue)) | |
} | |
// | |
val a: A = 1.11 | |
val b: B = f(a) | |
val fa: FA = Functor.amap(a) | |
val fb: FB = Functor.bmap(b) | |
val ff: FA => FB = Functor.fmap(f) | |
} | |
object MonadTest { | |
/** | |
* Monad是一个函子 ,并且对于 C 中每一个对象 x 都存在如下两个态射: | |
* unitX: X->M(x) | |
* joinX: M(M(X))->M(X) | |
*/ | |
/* CategoryC */ | |
type A = Double // 范畴CategoryC中的一组对象A | |
type B = Long // 范畴CategoryC中的一组对象B | |
type C = String // 范畴CategoryC中的一组对象C | |
val f: A => B = // 范畴CategoryC中的一组态射f | |
_.round | |
/* Functor定义 */ | |
class Maybe[T](val theValue: T) { | |
def map: (T => B) => Maybe[B] = | |
(f) => new Maybe(f(theValue)) | |
} | |
def fmap[T, P](f: T => P): Maybe[T] => Maybe[P] = | |
(fa: Maybe[T]) => new Maybe(f(fa.theValue)) | |
def unit[A](a: A): Maybe[A] = | |
new Maybe(a) | |
def join[T]: Maybe[Maybe[T]] => Maybe[T] = | |
(f: Maybe[Maybe[T]]) => f.theValue | |
/** | |
* 公理一: 给定一个monad 和态射 其中 ,有公理如下 | |
*/ | |
assert { | |
(join andThen fmap(join)) == (join andThen join) | |
} | |
val f1: A => A = (x: A) => x + 1 | |
val l = List(1, 2,3) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment