私は、値としてサポートできる型では固定されていないDSLを設計しようとしています。値の型が固定されていないScala DSL
以下、これを達成するために、Value
typeclassを使用しています。意図されたアプリケーションでは動作しますが、動作はありません。
trait Value[T]
object Value {
implicit object IntIsValue extends Value[Int]
implicit object StringIsValue extends Value[String]
}
DSLは、金額ベースおよびアプリケーション用語で構成されています。私は、コンパイルの問題を持っているところ
abstract class Term[T: Value]
case class ValueTerm[T: Value](x: T) extends Term[T]
case class AppTerm[Arg: Value, T: Value](fun: Arg => T, arg: Term[Arg]) extends Term[T]
評価関数は次のとおりです。
:def eval[T: Value](term: Term[T]): T = {
term match {
case ValueTerm(x) => x
case AppTerm(fun, arg) => fun(eval(arg)) // doesn't compile
}
}
ここで私が得る代表コンパイルエラーです
Error:(14, 40) could not find implicit value for evidence parameter of type A$A354.this.Value[Any]
case AppTerm(fun, arg) => fun(eval(arg))
^
コンパイラはarg
がTerm[Any]
と考えており、それがValue
のインスタンスであることはわかりません。
Value
の制約をeval
から削除することで回避できます。しかし、その後、私はValue
の行動を失い、私はeval
に使用する場合があります:
def eval[T](term: Term[T]): T -- loses behaviour of Value typeclass
これは、コンパイル、そしてどのよう
- だろうこのようなものを達成するために
はここにDSLのいくつかの使い方です:
val i41: Term[Int] = ValueTerm(41)
val i42: Term[Int] = AppTerm(fun = (_: Int) + 1, arg = i41)
val theAnswer: Term[String] = AppTerm(fun = "The answer is " ++ (_: Int).toString, arg = i42)
eval(i41)
eval(i42)
eval(theAnswer)
'Any'で示されているように、型情報を失うので、パス依存型がここでの答えだと思います。 – Reactormonk