# Scala 3 Kan Extensions

All concepts are Kan extensions. The notion of Kan extensions subsumes all the other fundamental concepts of category theory. – Categories for the Working Mathematician

## 左看

``````data Lan g h a where
Lan :: (g b -> a) -> h b -> Lan g h a
``````

``````enum Lan[G[?], H[?], A] {
case LeftKan[G[?], H[?], A, B](f: (G[B] => A), v: H[B]) extends Lan[G, H, A]
}
``````

``````given [G[?],H[?]] as Functor[Lan[G, H, *]] {
def [A, B](r: Lan[G, H, A]).map(f: A => B):Lan[G,H,B] = r match {
case Lan.LeftKan(g, v) => Lan.LeftKan(f compose g, v)
}
}
``````

``````type CoYoneda[F[?], A] = Lan[Id, F, A]
``````

• `*`kind projector 表示 kind， Scala 3 不再需要编译器插件，只需要打开toggle `-Ykind-projector` 即可。
• `given` 是新的表示 typeclass instance 的 implicit。

## 右看

``````newtype Ran g h a = Ran { runRan :: forall b. (a -> g b) -> h b }
``````

``````case class Ran[G[?], H[?], A](run: [B] => (A => G[B]) => H[B])
``````

``````given [G[?],H[?]] as Functor[Ran[G, H, *]] {
def [A, B](r: Ran[G, H, A]).map(f: A => B):Ran[G,H,B] =
Ran([C] => (k:B=>G[C]) => r.run(k.compose(f)))
}
``````

``````type Yoneda[F[?], A] = Ran[Id, F, A]
``````

``````given [G[?]](using Functor[Ran[G, G, *]]) as Monad[Ran[G, G, *]] {
def pure[A](a: A): Ran[G, G, A] = Ran([C]=>(k:A=>G[C]) => k(a))
def [A, B](r: Ran[G, G, A]).map(f: A => B):Ran[G,G,B] = r.map(f)
def [A, B](ran: Ran[G, G, A]) >>= (f: A => Ran[G,G,B]):Ran[G,G,B] =
Ran([C] => (k: B => G[C]) => ran.run((a)=> f(a).run(k)))
}
``````

• `using` 是新的 implicit 参数写法, 而且还可以匿名。