Recursive ระดับสูงฟังก์ชันพิมพ์ 3 Language

0

คำถาม

ฉันต้องการที่จะกำหนดรูปแบบสำหรับงานนั่นทำอะไรสักอย่างแล้วกลับมาอีกฟังก์ชันของประเภทเดียวกัน[สามารถเป็นตัวมันเองได้]. ที่เห็นได้ชัดคิดไม่ได้ทำงาน("ผิดกฏหมาย cyclic ประเภทการอ้างอิง"เกิดข้อผิดพลาด):

type Behavior[S] = S => Behavior[S]

มีบางอย่างชัดเจนว่าฉันหายตัวไปที่นี่? ก็ฉันไม่เข้าใจว่าต้องแสดงถึงความสนเป็นความคิดของ"ฟังก์ชันกลับมาเอง".

1

คำตอบที่ดีที่สุด

8

คำตอบสั้น

case class Behavior[S](step: S => Behavior[S])

นานคำตอบ(สั้นๆ)

เทอร์มินัล F-Coalgebras เป็นค่อนข้างเจ๋งนะ

นานคำตอบ

คำเตือน:ลายของรั้วลวดหนามสาย&เพื่อนร่วมกล้วยหรืออะไรบางอย่าง...

โอเคงั้นคิดว่าคุณมีคอนเซ็ปต์ของ functor 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 มี mediating morphism A => T (เช่นนั้นทุกอย่าง commutes,ห่ห่):

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)))

สำหรับผลประโยชน์ของคอนกรีตตัวอย่างให้เห็นว่ามัน contraption มันสำหรับงานง่ายสุด imaginable functor 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 ตัวเลข. นี่เป็นเป็นธรรมชาติของตัวเลขบวกกับ countable แม้สถานการณ์จะเปลี่ยนไป. เรื่องพวกนี้เป็นดีๆมที่เหมาะสมสำหรับเป็นตัวแทนให้เดินทางมาไกลของเป็นไปได้ว่าถึงไม่มีที่สิ้นสุดคือ..."การคลิก"โพรเซส.

ปล่อยให้ลองมันเป็น finite พฤติกรรม:

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)

ตอนนี้ที่ด้านบน machinery โดยอัตโนมัติให้เป็นรูปแบบสากลที่จะแปลพวกนั้นนับคำเข้าไปใน 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")

มันแสดงสำหรับภาษาเวลช์ name หวังจะพูดมันออกมายังไง


@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

โอเคนั่นเป็นคนเรียบร้อย ลองคำถาม infinitely การคลิกระบวนการกับแค่หนึ่งของรัฐนั้นคือผู้สืบทอดของตัวเอง:

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(()))}")

2021-11-23 21:59:52

ในภาษาอื่นๆ

หน้านี้อยู่ในภาษาอื่นๆ

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................