在函数方法中解决继承依赖性

MiP*_*MiP 2 .net oop inheritance f# functional-programming

问题:

继承依赖

  • 类型A在属性中存储类型B的值

  • 类型B继承自类型A.

我们将考虑一个UI控件层次结构,其中每个控件都属于顶级"Form",而Form本身就是一个Control.

作者通过参数化类解决了这个问题:

[<AbstractClass>]
type Control<'Form>(name) = 
    member this.Name = name

    abstract Form : 'Form

type Form(name) = 
    inherit Control<Form>(name)

    override this.Form = this

type Button(name,form) = 
    inherit Control<Form>(name)

    override this.Form = form

let form = new Form("form")       
let button = new Button("button",form)
Run Code Online (Sandbox Code Playgroud)

但是我怎样才能在功能方法中重新设计:"我们根本不会使用继承.相反,我们会将组合与参数化结合使用"?

Tom*_*cek 7

这个问题很难回答,因为问题的提法本质上是面向对象的.当你说"形式是一种控制"时,问题的"一部分"暗示了一种你在函数式编程中通常不会使用的OO建模方式.

严格地说,您的示例代码实际上并没有做任何有用的事情 - 它创建了一堆对象,但不使用它们来呈现任何用户界面或实现任何其他功能.
当然,我怀疑这就是问题所在.如果我想模拟一个包含表单和按钮的非常简单的用户界面,我可能会从这样的事情开始:

type SimpleControl = 
  | Button of string
  | Label of string

type ContainerControl = 
  | Form 

type Control = 
  | Container of ContainerControl * Control list
  | Simple of SimpleControl
Run Code Online (Sandbox Code Playgroud)

这允许您定义容器控件(例如表单),其可以包含其他控件和按钮和标签,这些控件和按钮和标签是简单控件,不能包含其他元素.这只是一个例子 - 根据您实际想要构建的用户界面类型以及您想要用它们做什么,您可以不同地定义类型.

简短的版本是,函数式编程通常需要不同的思维方式,而在面向对象世界中有意义的一些问题在功能世界中没有意义.

  • @ftor我认为用"或"(又名辨别联盟)和"和"(又名记录)来塑造世界是一个非常强大的功能技巧.有时,函数/接口也很有用,但如果我倾向于坚持"或"/"和"尽可能多:-) (2认同)