Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>First off, <code>Step</code> looks perfect to me. As for <code>Stream</code>, I think you're on the right track with the abstract type. Here's what I came up with (including implementations of the remaining methods in section 2.1 of the Coutts paper):</p> <pre><code>abstract class Stream[A] { protected type S def next: S =&gt; Step[A, S] def state: S def map[B](f: A =&gt; B): Stream[B] = { val next: S =&gt; Step[B, S] = this.next(_) match { case Done =&gt; Done case Skip(s) =&gt; Skip(s) case Yield(a, s) =&gt; Yield(f(a), s) } Stream(next, state) } def unstream: List[A] = { def unfold(s: S): List[A] = next(s) match { case Done =&gt; List.empty case Skip(s) =&gt; unfold(s) case Yield(a, s) =&gt; a :: unfold(s) } unfold(state) } } object Stream { def apply[A, S0](n: S0 =&gt; Step[A, S0], s: S0) = new Stream[A] { type S = S0 val next = n val state = s } def apply[A](as: List[A]): Stream[A] = { val next: List[A] =&gt; Step[A, List[A]] = { case a :: as =&gt; Yield(a, as) case Nil =&gt; Done } Stream(next, as) } def unapply[A](s: Stream[A]): Option[(s.S =&gt; Step[A, s.S], s.S)] = Some((s.next, s.state)) } </code></pre> <p>A couple things to note:</p> <ul> <li>My <code>unapply</code> has a dependent method type: it depends on the <code>s.S</code>. I think that might have been your stumbling block.</li> <li>The <code>unfold</code> method in <code>unstream</code> is not tail-recursive.</li> </ul> <p>The thing I'm still not really clear on myself is why it's important for <code>S</code> to be existential / hidden / whatever. If it's not, you could just write:</p> <pre><code>case class Stream[A, S](next: S =&gt; Step[A, S], state: S) </code></pre> <p>... but I assume there's a reason for it. That being said, I'm also not sure this approach actually hides <code>S</code> the way you want. But this is my story and I'm sticking to it.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload