@lyrical_logical
rpscala 164 回
trait Forall[A] { ... }
// 任意の A について ...
import scala.language.existentials
class Ex(a: A forSome { type A })
// ある A について ...
// ある A の存在を仮定して ...
// これらはできる
T forSome { type T }
T forSome { type T <: Upper }
T forSome { type T >: Lower }
T forSome { type T >: Lower <: Upper }
// こういうのはだめ
T forSome { type T : ContextBound }
data Nanika = forall a. Nanika a
-- Nanika :: forall a. a -> Nanika
-- 擬似コードですが、以下に相当
-- Nanika :: (exists a. a) -> Nanika
sealed trait Foo
case class Bar[T](t: T) extends Foo
foo match {
// t の型がわからず Any になる!
case Bar(t) => ...
}
話を戻す
trait Stream[A, Impl] { ... }
trait Stream[A] {
type Impl
...
}
trait Stream[A] {
type Impl <: Any >: Nothing
def ev: Monoid[Impl]
...
}
sealed trait Exists[F[_]] { type A }
object Exists {
def apply[F[_], A](fa: F[A]): Exists[F] = ExistsImpl(fa)
def run[F[_], R](runner: Rank2[F, R], ex: Exists[F]): R =
ex match { case ExistsImpl(fa) => runner.apply(fa) }
type Rank2[F[_], R] = { def apply[A](fa: F[A]): R }
case class ExistsImpl[F[_], T](fa: F[T]) extends Exists[F] {
type A = T
}
}
type StreamF[A, S] = S => (S, A)
type Stream[A] = Exists[({ type App[S] = StreamF[A, S] })#App]