Scalaz (31) - Free: 자유 데이터 구조 - 산식 과 알고리즘 에 대한 관심 분리
간단 한 표현 식 1 + 2 + 3 을 사용 합 니 다. 이 표현 식 은 산식 과 알고리즘 을 동시에 포함 합 니 다. 연산 식 은 a Op b Op c 이 고 알고리즘 은 Int 덧셈, a, b, c 는 Int 이 며 oP 는 Int + 입 니 다.그러면 우 리 는 그것 을 산식 과 산법 으로 분해 해 서 는 안 됩 니까?우 리 는 먼저 산식 을 유도 할 수 있다. Op (a, Op (b, c)).우 리 는 알고리즘 에서 Op 즉 a, b, c 에 대해 여러 가지 정 의 를 내 릴 수 있다. 즉, 이러한 정 의 를 통 해 우 리 는 산식 이 다른 의 미 를 부여 할 수 있다.이 예 는 산식, 알고리즘 이 분 리 된 전 과정 에 관심 을 가 질 수 있다. 우리 가 연산 하고 자 하 는 프로그램 을 추상 적 으로 묘사 하고 구체 적 인 연산 방식 을 정의 하면 분리 해서 진행 할 수 있다.
실제로 1 + 2 + 3 은 일종 의 모 노 이 드 조작 이 라 고 할 수 있다.그 중에서 Free Monoid 를 유도 할 수 있 는 지, 하나의 Monoid 자유 데이터 구조 가 Monoidal 작업 을 실현 하 는 산식, 알고리즘 분리 에 관심 을 가 질 수 있 는 지 살 펴 보 자.임의의 기본 형식 A 에 대한 Monoid 정 의 는 다음 과 같 습 니 다.
1. 이원 함수 append: (A, A) = > A
2. A 형식의 초기 값 (0 값) zero
Monoid 는 다음 과 같은 법칙 을 따라 야 합 니 다.
1. append 함수 의 연관 성 associativity: 임의의 A 유형의 x, y, z - append (x, append (y, z) = = append (x, y), z)
2. zero 의 동일 한 idenity law: 임의의 유형의 x - append (zero, x) = = append (x, zero)
위의 법칙 에 따 르 면 위의 표현 식 1 + 2 + 3 = = 1 + (2 + (3 + 0).그것 의 산식 은 다음 과 같다. append (x, append (y, append (z, zero))).그러면 우 리 는 이러한 Free Monoid 자유 데이터 구 조 를 얻 을 수 있 을 것 이다.
1 sealed trait FreeMonoid[+A] 2 final case object Zero extends FreeMonoid[Nothing] 3 final case class Append[A](l: A, r: FreeMonoid[A]) extends FreeMonoid[A]
1:: 2: 3: Nil > > List (1, 2, 3), A 가 Monoid 라면 List [A] 도 Monoid 이 고 List [A] 는 Free Monoid 자유 데이터 구조 입 니 다. 다음 시범 을 보 겠 습 니 다.
1 def listOp[A](l: List[A]): FreeMonoid[A] = l match { 2 case Nil => Zero 3 case h :: t => Append(h,listOp(t)) 4 } //> listOp: [A](l: List[A])Exercises.freestruct.FreeMonoid[A]
5 listOp(List(1,2,3)) //> res0: Exercises.freestruct.FreeMonoid[Int] = Append(1,Append(2,Append(3,Zero 6 //| )))
List 는 Free 입 니 다. Monoid, 그것 의 Nil = = Zero, a ++ b === Append(a,b)。
마찬가지 로 우 리 는 Monad 의 특성 조작 함수 에서 Free Monad 의 자유 데이터 구 조 를 유도 할 수 있다.우 리 는 다음 조작 함수 로 Monad M [] 을 구축 할 수 있다.
1、point: A => M[A]
2、join: M[M[A]] => M[A]
3、map: (M[A], A => B) => M[B]
(point + flatMap 조합 역시 Monad 를 구축 할 수 있 습 니 다)
Free Monad 는 형식 구축 기 Functor F [] 를 기반 으로 하 는 Free Monoid 이기 때문에 Free Monad 의 정 의 는 다음 과 같 아야 합 니 다.
sealed trait Free[F[_],A]
우 리 는 직접 point 를 case class 로 바 꿀 수 있다.
final case class Return[F[_],A](a: A) extends Free[F,A]
join 의 입력 유형 은 F [F [A] 입 니 다. 우 리 는 free [F, A] 를 안에 넣 어야 합 니 다.
final case class Suspend[F[_],A](ffa: F[Free[F,A]) extends Free[F,A]
우 리 는 이제 Free Monad 의 자유 데이터 구조 정 의 를 다음 과 같이 추측 할 수 있다.
1 sealed trait Free[F[_], A] 2 final case class Return[F[_],A](a: A) extends Free[F,A] 3 final case class Suspend[F[_],A](ffa: F[Free[F,A]]) extends Free[F,A]
우 리 는 상기 구조 로 Monad 의 모든 특성 조작 함 수 를 실현 할 수 있다 는 것 을 증명 해 야 한다. 그러면 이 Free 는 Functor F 로 Monad 를 만 드 는 Monad 구조 기 이 고 가장 간단 한 구조의 Monad 구조 기, 즉 Free Monad 이다.
1 import scalaz.Functor 2 final case class Return[F[_],A](a: A) extends Free[F,A] 3 final case class Suspend[F[_],A](ffa: F[Free[F,A]]) extends Free[F,A] 4 sealed trait Free[F[_],A] { 5 def point(a: A) = Return[F,A](a) 6 def flatMap[B](f: A => Free[F,B])(implicit F: Functor[F]): Free[F,B] =
7 this match { 8 case Return(a) => f(a) 9 case Suspend(ffa) => Suspend[F,B](F.map(ffa)(fa => fa flatMap f)) 10 } 11 def map[B](f: A => B): Free[F,B] = flatMap(a => Return[F,B](f(a))) 12 def join(ffa: F[Free[F,A]]): Free[F,A] = Suspend[F,A](ffa) 13
14 }
이 무료 자유 데이터 구 조 는 우리 가 point, flatMap, map, join 이라는 몇 개의 Monad 특성 조작 함 수 를 실현 하 는 것 을 충분히 지원 하기 때문에 무료 Monad 입 니 다.
Free 가 Free Monad 라면 Free [F, A] 의 F [A] 를 Program [Commands] 로 사용 할 수 있 습 니 다. 명령 집합 Commands 로 프로그램 을 독립 적 으로 설명 할 수 있 습 니 다. 최종 프로그램 프로그램 은 부작용 이 없 기 때문에 최대한 의 함수 조합 (function composition) 을 허용 합 니 다.. Program 에 대한 구체 적 인 연산 방법 은 독립 적 으로 분리 하여 실현 할 수 있 습 니 다. 우 리 는 다음 토론 에서 Free Monad 의 실제 응용 방식 인 AST 와 Interpreter 의 실현 과정 을 중점적으로 소개 할 것 입 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.