재귀적이 높은 순서 함수에 입력 Scala3

0

질문

내가 원하는 형식을 정의하는 함수에 대한 무언가를 하는 다음 반환 또 다른 기능은 동일한 형식의[할 수 있습 자체가]. 분명한 아이디어 작동하지 않았("불법적 주기적인 유형을 참조"오류가 발생):

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

뭔가가 분명하는 내가 누락까요? 또한 내가 이해하지 못하는 방법을 익스프레스는"아이디어를 반환하는 함수 자체는".

1

최고의 응답

8

짧은 대답

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

2021-11-23 21:59:52

다른 언어로

이 페이지는 다른 언어로되어 있습니다

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