模式匹配设计

M.K*_*.K. 0 functional-programming scala

我最近编写了一些代码,如下面的块,它让我想到如果我对函数式编程抽象更有知识,可以改进设计.

sealed trait Foo
case object A extends Foo
case object B extends Foo
case object C extends Foo
.
.
.

object Foo {
  private def someFunctionSemanticallyRelatedToA() = { // do stuff }
  private def someFunctionSemanticallyRelatedToB() = { // do stuff }
  private def someFunctionSemanticallyRelatedToC() = { // do stuff }
  .   
  .   
  .   

  def somePublicFunction(x : Foo)  = x match {
    case A => someFunctionSemanticallyRelatedToA()
    case B => someFunctionSemanticallyRelatedToB()
    case C => someFunctionSemanticallyRelatedToC()
    .
    .
    .
  }
}
Run Code Online (Sandbox Code Playgroud)

我的问题是:

  1. somePublicFunction()是否遭受代码嗅觉甚至整个设计?我担心的是,价值构建者的名单可能会变得非常大.
  2. 是否有更好的FP抽象来更优雅甚至简洁地处理这种类型的设计?

Yaw*_*war 5

你刚刚遇到了表达问题.在您的代码示例中,问题是每次从Foo代数数据类型添加或删除案例时,您都需要修改每个匹配(如in somePublicFunction)的值Foo.在Nimrand的回答中,问题出现在频谱的另一端:您可以Foo轻松添加或删除案例,但每次要添加或删除行为(方法)时,您都需要修改每个子类Foo.

解决表达式问题有各种各样的建议,但有一个有趣的功能方法是Oleg Kiselyov的Typed Tagless Final Interpreters,它用一个返回一些被认为等同于该情况的抽象值的函数替换代数数据类型的每个情况.使用泛型(即类型参数),这些函数都可以具有兼容的类型,并且无论何时实现它们都可以相互协作.例如,我已经实现了使用TTFI构建和评估算术表达式树的示例:https://github.com/yawaramin/scala-ttfi