내가 원하는 형식을 정의하는 함수에 대한 무언가를 하는 다음 반환 또 다른 기능은 동일한 형식의[할 수 있습 자체가]. 분명한 아이디어 작동하지 않았("불법적 주기적인 유형을 참조"오류가 발생):
type Behavior[S] = S => Behavior[S]
뭔가가 분명하는 내가 누락까요? 또한 내가 이해하지 못하는 방법을 익스프레스는"아이디어를 반환하는 함수 자체는".
내가 원하는 형식을 정의하는 함수에 대한 무언가를 하는 다음 반환 또 다른 기능은 동일한 형식의[할 수 있습 자체가]. 분명한 아이디어 작동하지 않았("불법적 주기적인 유형을 참조"오류가 발생):
type Behavior[S] = S => Behavior[S]
뭔가가 분명하는 내가 누락까요? 또한 내가 이해하지 못하는 방법을 익스프레스는"아이디어를 반환하는 함수 자체는".
case class Behavior[S](step: S => Behavior[S])
F 터미널-Coalgebras 은 정말 멋진 있습니다.
경고:의 많은 철 다음과 같이 구성되어 있습니다.바나나,또는 뭔가...
그래,그래서 가정이 있는 개념의 펑터 F
캡처하는 것이 무엇을 의미하는 행위"는"뭔가를. 대부분의 라이브러리가 무언가 이것을 좋아한다:
trait Functor[F[_]]:
def map[A, B](fa: F[A])(f: A => B): F[B]
인 F
-coalgebra A
은 본질적으로 그 기능에서 A
하기 F[A]
:
trait FCoalg[F[_]: Functor, A]:
def apply(a: A): F[A]
이제, 공항 터미 F
-coalgebra T
가 F
-coalgebra 는 또한 특성을 갖는 다른 모든 F
-coalgebra A
가 중재형 A => T
(이러한 모든 것을 통근,blah blah):
trait TerminalFCoalg[F[_]: Functor, T] extends FCoalg[F, T]:
def mediate[A](coalg: FCoalg[F, A]): A => T
우리는 그것을 구현하는 대한 임의의 F
? 우리는 할 수 있습니다:
case class TerminalFCoalgCarrier[F[_]: Functor](
step: () => F[TerminalFCoalgCarrier[F]]
)
given tfcImpl[F[_]: Functor]: TerminalFCoalg[F, TerminalFCoalgCarrier[F]] with
def apply(a: TerminalFCoalgCarrier[F]): F[TerminalFCoalgCarrier[F]] = a.step()
def mediate[A](coalg: FCoalg[F, A]): A => TerminalFCoalgCarrier[F] = a =>
TerminalFCoalgCarrier(() => summon[Functor[F]].map(coalg(a))(mediate(coalg)))
의 이익을 위해 구체적인 예를 들어,하는 기계는 가장 간단한 상상할 수 있는 펑터 Option
:
given Functor[Option] with
def map[A, B](fa: Option[A])(f: A => B): Option[B] = fa.map(f)
type ConaturalNumber = TerminalFCoalgCarrier[Option]
그것은 터미널 F
-coalgebra 한 Option
소위 conatural 숫자. 이들은 기본적으로 자연의 숫자,플러스 셀 수 있습니다. 이러한 것들은 멋지게 적합한 나타내기 위한 길이의 잠재적으로 무한한""를 클릭하면 프로세스입니다.
자에 그것을 시도 유한 행동:
enum WelshCounting:
case Eeny
case Meeny
case Miny
case Moe
object WelshCountingOptionCoalg extends FCoalg[Option, WelshCounting]:
def apply(w: WelshCounting): Option[WelshCounting] =
import WelshCounting._
w match
case Eeny => None
case Meeny => Some(Eeny)
case Miny => Some(Meeny)
case Moe => Some(Miny)
val welshMediatingMorphism =
summon[TerminalFCoalg[Option, TerminalFCoalgCarrier[Option]]]
.mediate(WelshCountingOptionCoalg)
지금,위의 기계 자동적으로 우리에게 보편적인 방법으로 번역하는 사람들을 믿으로 단어를 conatural 숫자입니다. 추가 할 수 도우미는 방법을 설명하기 위한 conatural 번호(대략적인 금액):
def describe(c: ConaturalNumber): String =
var counter = 0
var curr = c
while true do
curr.step() match
case None => return s"${counter}"
case Some(next) =>
if counter > 42 then
return "probably infinite"
else {
counter += 1
curr = next
}
throw new Error("We have counted to infinity, yay! :D")
그것은 무엇을 보여 웨일스의 세 단어가?
@main def demo(): Unit =
for w <- WelshCounting.values do
val conat = welshMediatingMorphism(w)
println(s"${w} -> ${describe(conat)}")
// Eeny -> 0
// Meeny -> 1
// Miny -> 2
// Moe -> 3
Ok,that's 깔끔합니다. 의도는 무한히 클릭하면 프로세스와 함께 하나의 상태는 후계자의 자체:
object LoopForever extends FCoalg[Option, Unit]:
def apply(u: Unit) = Some(())
val loopForeverMediatingMorphism =
summon[TerminalFCoalg[Option, TerminalFCoalgCarrier[Option]]]
.mediate(LoopForever)
어떻게 그것을 설명 하나의 상태 ()
?
println(s"${()} -> ${describe(loopForeverMediatingMorphism(()))}")
// () -> probably infinite
작동하는 것 같다.
전체 코드:
trait Functor[F[_]]:
def map[A, B](fa: F[A])(f: A => B): F[B]
trait FCoalg[F[_]: Functor, A]:
def apply(a: A): F[A]
trait TerminalFCoalg[F[_]: Functor, T] extends FCoalg[F, T]:
def mediate[A](coalg: FCoalg[F, A]): A => T
case class TerminalFCoalgCarrier[F[_]: Functor](
step: () => F[TerminalFCoalgCarrier[F]]
)
given tfcImpl[F[_]: Functor]: TerminalFCoalg[F, TerminalFCoalgCarrier[F]] with
def apply(a: TerminalFCoalgCarrier[F]): F[TerminalFCoalgCarrier[F]] = a.step()
def mediate[A](coalg: FCoalg[F, A]): A => TerminalFCoalgCarrier[F] = a =>
TerminalFCoalgCarrier(() => summon[Functor[F]].map(coalg(a))(mediate(coalg)))
given Functor[Option] with
def map[A, B](fa: Option[A])(f: A => B): Option[B] = fa.map(f)
type ConaturalNumber = TerminalFCoalgCarrier[Option]
def describe(c: ConaturalNumber): String =
var counter = 0
var curr = c
while true do
curr.step() match
case None => return s"${counter}"
case Some(next) =>
if counter > 42 then
return "probably infinite"
else {
counter += 1
curr = next
}
throw new Error("We cannot count to infinity :(")
enum WelshCounting:
case Eeny
case Meeny
case Miny
case Moe
object WelshCountingOptionCoalg extends FCoalg[Option, WelshCounting]:
def apply(w: WelshCounting): Option[WelshCounting] =
import WelshCounting._
w match
case Eeny => None
case Meeny => Some(Eeny)
case Miny => Some(Meeny)
case Moe => Some(Miny)
val welshMediatingMorphism =
summon[TerminalFCoalg[Option, TerminalFCoalgCarrier[Option]]]
.mediate(WelshCountingOptionCoalg)
object LoopForever extends FCoalg[Option, Unit]:
def apply(u: Unit) = Some(())
val loopForeverMediatingMorphism =
summon[TerminalFCoalg[Option, TerminalFCoalgCarrier[Option]]]
.mediate(LoopForever)
@main def demo(): Unit =
for w <- WelshCounting.values do
val conat = welshMediatingMorphism(w)
println(s"${w} -> ${describe(conat)}")
println(s"${()} -> ${describe(loopForeverMediatingMorphism(()))}")