Scalaz는 "거대한"모나드에 대해 ItateeT와 일치하도록 "리프팅"`EnumeratorT`를 반복합니다.


445

내가 EnumeratorT있고 해당하는 경우 IterateeT함께 실행할 수 있습니다.

val en: EnumeratorT[String, Task] = EnumeratorT.enumList(List("a", "b", "c"))
val it: IterateeT[String, Task, Int] = IterateeT.length

(it &= en).run : Task[Int]

열거 자 모나드가 iteratee 모나드보다 "더 큰"경우 up, 더 일반적으로 Hoist다음과 같이 일치자를 "리프팅" 할 수 있습니다 .

val en: EnumeratorT[String, Task] = ...
val it: IterateeT[String, Id, Int] = ...

val liftedIt = IterateeT.IterateeTMonadTrans[String].hoist(
  implicitly[Task |>=| Id]).apply(it)
(liftedIt &= en).run: Task[Int]

그러나 iteratee 모나드가 열거 자 모나드보다 "더 큰"경우 어떻게해야합니까?

val en: EnumeratorT[String, Id] = ...
val it: IterateeT[String, Task, Int] = ...

it &= ???

에 대한 Hoist인스턴스 EnumeratorT나 명백한 "리프트"방법 이없는 것 같습니다 .


59
깔끔한 질문에 대한 +1,하지만 이후 최고 떨어져 나는 확실하지이 일반적인 경우에 가능하다는 것을 내 머리 야 Enumerator정말 주위에 단지 래퍼 StepT => IterateeT는 "스텝 다운"을해야합니다 제안, A로부터 StepT[E, BigMonad, A].
트래비스 브라운

12
예, 직접 구현하려고 할 때 발견되었습니다. 그러나 논리적으로 Enumerator효과적인 소스 일뿐입니다. 내가 제공 할 수있는 일이 사용할 수있을 것 같은이 느낌 A공급을 Task[A].
lmm

8
스칼라에 대한 답변을 제공 할만큼 충분히 알지 못하지만 자신의 유형정의하고 리프팅 메커니즘을 제공 할 수 없습니까?
Rob

8
아니, 그것은 전혀 같은 것이 아니며, 다른 종류의 "리프팅"입니다.
lmm

2
@TravisBrown 당신이 그것을 쓰고 싶다면 지금 이것에 현상금이 있습니다.
Aaron Hall

답변:


4

일반적인 인코딩에서 열거자는 본질적으로 StepT[E, F, ?] ~> F[StepT[E, F, ?]]입니다. 이 형식을 Step[E, G, ?] ~> G[Step[E, G, ?]]지정된 형식으로 변환하는 일반 메서드를 작성하려고 F ~> G하면 문제가 발생합니다. 원래 열거자를 적용하려면 a Step[E, G, A]를 "낮게"해야합니다 Step[E, F, A].

Scalaz는 다음과 같은 대체 열거 형 인코딩 도 제공 합니다 .

trait EnumeratorP[E, F[_]] {
  def apply[G[_]: Monad](f: F ~> G): EnumeratorT[E, G]
}

이 접근 방식을 사용하면 필요한 효과에 대해 구체적인 열거자를 정의 할 수 있지만 더 풍부한 컨텍스트가 필요한 소비자와 함께 작업하기 위해 "리프팅"할 수 있습니다. 우리는 사용하기 위해 당신의 예제를 수정할 수 있습니다 EnumeratorP(그리고 오래된 모나드 부분 순서가 아닌 새로운 자연 변환 접근법).

import scalaz._, Scalaz._, iteratee._, concurrent.Task

def enum: EnumeratorP[String, Id] = ???
def iter: IterateeT[String, Task, Int] = ???

val toTask = new (Id ~> Task) { def apply[A](a: A): Task[A] = Task(a) }

이제 다음과 같이 두 가지를 구성 할 수 있습니다.

scala> def result = (iter &= enum(toTask)).run
result: scalaz.concurrent.Task[Int]

EnumeratorP합니다 (이 경우 모나드이다 F실용적이다), 그리고 EnumeratorP동반자 개체에있는 것과 같은 많은 모양 열거 정의하는 데 도움이되는 몇 가지 기능을 제공 EnumeratorT저기의를 empty, perform, enumPStream, 등 내가 거기 추측해야 EnumeratorT사용하여 구현 할 수없는 경우 EnumeratorP인코딩,하지만 내 머리 위로 떨어져 나는 확실히 그들이 어떻게 보이는지 모르겠어요.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.