Scala 中的无标记最终示例需要多余的第二个 interp arg
Tagless final example in Scala requires superfluous second interp arg
我正在尝试在 Scala 中实现无标记的最终 DSL 和解释器,基于 this 博客 post 写在 Haskell.
我可以得到一个示例 运行 - 请参阅下面的代码,但我不太明白为什么我需要 testVal(Interp)(Interp)
。如果我只提供一个 Interp
参数,那么我会得到以下编译错误:
Error:(29, 24) could not find implicit value for evidence parameter of type Test.Expr[Test.Id]
val x = testVal(Interp)
Error:(29, 24) not enough arguments for method testVal: (implicit evidence: Test.Expr[Test.Id])Test.Id[Int].
Unspecified value parameter evidence.
val x = testVal(Interp)
有没有一种简单的方法可以消除 Interp
个论点之一?
object Test {
trait Expr[F[_]] {
def const(i: Int): F[Int]
def lam[A, B](f: F[A] => F[B]): F[A => B]
def app[A, B](f: F[A => B], a: F[A]): F[B]
def add(x: F[Int], y: F[Int]): F[Int]
}
type Id[A] = A
object Interp extends Expr[Id] {
override def const(i: Int): Id[Int] = i
override def lam[A, B](f: Id[A] => Id[B]): Id[A => B] = f
override def app[A, B](f: Id[A => B], a: Id[A]): Id[B] = f(a)
override def add(x: Id[Int], y: Id[Int]): Id[Int] = x + y
}
def testVal[F[_]: Expr](f: Expr[F]): F[Int] =
f.app(
f.lam[Int, Int](
x => f.add(x, f.const(1))),
f.const(10)
)
def main(args: Array[String]): Unit = {
// val x = testVal(Interp) -- won't compile
val x = testVal(Interp)(Interp)
println(x)
}
}
语法
def f[X: Y](args: Types): Res = { ... }
是
的快捷方式
def f[X](args: Types)(implicit yx: Y[X]): Res = { ... }
所以如果你写
def testVal[F[_]: Expr](f: Expr[F]): F[Int] = { ... }
那就和你写的一样
def testVal[F[_]](f: Expr[F])(implicit redundant: Expr[F]): F[Int] = { ... }
但你显然不需要相同的 Expr[F]
两次。
签名应该是
def testVal[F[_]: Expr]: F[Int]
或
def testVal[F[_]](implicit f: Expr[F]): F[Int]
但不能同时进行。
这是一个完整的示例,它还展示了在您决定使用 F: Expr
变体(不分配隐式参数的名称):
import scala.language.higherKinds
object Test {
trait Expr[F[_]] {
def const(i: Int): F[Int]
def lam[A, B](f: F[A] => F[B]): F[A => B]
def app[A, B](f: F[A => B], a: F[A]): F[B]
def add(x: F[Int], y: F[Int]): F[Int]
}
type Id[A] = A
object Interp extends Expr[Id] {
override def const(i: Int): Id[Int] = i
override def lam[A, B](f: Id[A] => Id[B]): Id[A => B] = f
override def app[A, B](f: Id[A => B], a: Id[A]): Id[B] = f(a)
override def add(x: Id[Int], y: Id[Int]): Id[Int] = x + y
}
def testVal[F[_]: Expr]: F[Int] = {
implicit val f = implicitly[Expr[F]]
f.app(
f.lam[Int, Int](
x => f.add(x, f.const(1))),
f.const(10)
)
}
def main(args: Array[String]): Unit = {
val x = testVal(Interp)
println(x)
}
}
此外,如果你使 Interp
本身隐含,那么你可以在调用 testVal
时省略所有参数列表,而只写
val x = testVal // no arguments at all.
我正在尝试在 Scala 中实现无标记的最终 DSL 和解释器,基于 this 博客 post 写在 Haskell.
我可以得到一个示例 运行 - 请参阅下面的代码,但我不太明白为什么我需要 testVal(Interp)(Interp)
。如果我只提供一个 Interp
参数,那么我会得到以下编译错误:
Error:(29, 24) could not find implicit value for evidence parameter of type Test.Expr[Test.Id]
val x = testVal(Interp)
Error:(29, 24) not enough arguments for method testVal: (implicit evidence: Test.Expr[Test.Id])Test.Id[Int].
Unspecified value parameter evidence.
val x = testVal(Interp)
有没有一种简单的方法可以消除 Interp
个论点之一?
object Test {
trait Expr[F[_]] {
def const(i: Int): F[Int]
def lam[A, B](f: F[A] => F[B]): F[A => B]
def app[A, B](f: F[A => B], a: F[A]): F[B]
def add(x: F[Int], y: F[Int]): F[Int]
}
type Id[A] = A
object Interp extends Expr[Id] {
override def const(i: Int): Id[Int] = i
override def lam[A, B](f: Id[A] => Id[B]): Id[A => B] = f
override def app[A, B](f: Id[A => B], a: Id[A]): Id[B] = f(a)
override def add(x: Id[Int], y: Id[Int]): Id[Int] = x + y
}
def testVal[F[_]: Expr](f: Expr[F]): F[Int] =
f.app(
f.lam[Int, Int](
x => f.add(x, f.const(1))),
f.const(10)
)
def main(args: Array[String]): Unit = {
// val x = testVal(Interp) -- won't compile
val x = testVal(Interp)(Interp)
println(x)
}
}
语法
def f[X: Y](args: Types): Res = { ... }
是
的快捷方式def f[X](args: Types)(implicit yx: Y[X]): Res = { ... }
所以如果你写
def testVal[F[_]: Expr](f: Expr[F]): F[Int] = { ... }
那就和你写的一样
def testVal[F[_]](f: Expr[F])(implicit redundant: Expr[F]): F[Int] = { ... }
但你显然不需要相同的 Expr[F]
两次。
签名应该是
def testVal[F[_]: Expr]: F[Int]
或
def testVal[F[_]](implicit f: Expr[F]): F[Int]
但不能同时进行。
这是一个完整的示例,它还展示了在您决定使用 F: Expr
变体(不分配隐式参数的名称):
import scala.language.higherKinds
object Test {
trait Expr[F[_]] {
def const(i: Int): F[Int]
def lam[A, B](f: F[A] => F[B]): F[A => B]
def app[A, B](f: F[A => B], a: F[A]): F[B]
def add(x: F[Int], y: F[Int]): F[Int]
}
type Id[A] = A
object Interp extends Expr[Id] {
override def const(i: Int): Id[Int] = i
override def lam[A, B](f: Id[A] => Id[B]): Id[A => B] = f
override def app[A, B](f: Id[A => B], a: Id[A]): Id[B] = f(a)
override def add(x: Id[Int], y: Id[Int]): Id[Int] = x + y
}
def testVal[F[_]: Expr]: F[Int] = {
implicit val f = implicitly[Expr[F]]
f.app(
f.lam[Int, Int](
x => f.add(x, f.const(1))),
f.const(10)
)
}
def main(args: Array[String]): Unit = {
val x = testVal(Interp)
println(x)
}
}
此外,如果你使 Interp
本身隐含,那么你可以在调用 testVal
时省略所有参数列表,而只写
val x = testVal // no arguments at all.