【问题标题】:Convert expression to polish notation in Scala在 Scala 中将表达式转换为波兰符号
【发布时间】:2014-10-13 14:44:57
【问题描述】:

我想将a.meth(b) 之类的表达式转换为执行该精确计算的(A, B) => C 类型的函数。

到目前为止,我最好的尝试是沿着这些思路:

def polish[A, B, C](symb: String): (A, B) => C = { (a, b) =>
// reflectively check if "symb" is a method defined on a
// if so, reflectively call symb, passing b
}

然后像这样使用它:

def flip[A, B, C](f : (A, B) => C): (B, A) => C = {(b, a) => f(a,b)}
val op = flip(polish("::"))
def reverse[A](l: List[A]): List[A] = l reduceLeft op

正如您所见,它非常丑陋,您必须“手动”进行大量类型检查。

还有其他选择吗?

【问题讨论】:

  • 我不太明白如何使用polish 方法。你能展示一个示例用例吗?
  • symb 是定义为值
  • 我真的明白了。类似polish("charAt")("quux", 2)
  • 我会这样使用它:l.foldLeft(Nil)(polish("::"))
  • @IonuțG.Stan 是的,它会避免使用经典的:.meth(),这会导致这些函数无法重用。

标签: scala functional-programming polish-notation


【解决方案1】:

您可以使用普通的旧子类型多态性轻松实现它。只需声明接口

trait Iface[B, C] {
    def meth(b: B): C
}

那么你就可以轻松实现polish

def polish[B, C](f: (Iface[B, C], B) => C): (Iface[B, C], B) => C = { (a, b) =>
    f(a, b)
}

使用它是完全类型安全的

object IfaceImpl extends Iface[String, String] {
    override def meth(b: String): String = b.reverse
}

polish((a: Iface[String, String], b: String) => a meth b)(IfaceImpl, "hello")

更新:

实际上,你可以只使用闭包来实现它

def polish[A, B, C](f: (A, B) => C): (A, B) => C = f

class Foo {
  def meth(b: String): String = b.reverse
}

polish((_: Foo) meth (_: String))(new Foo, "hello")

或者根本没有辅助函数:)

val polish = identity _ // Magic at work

((_: Foo) meth (_: String))(new Foo, "hello")

【讨论】:

  • 这不是我想的。请参阅我添加的示例以获得更清晰的信息。
猜你喜欢
  • 1970-01-01
  • 2019-11-23
  • 1970-01-01
  • 2018-05-31
  • 1970-01-01
  • 2016-12-09
  • 2018-05-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多