Solve inheritance dependency in a functional appro

2019-05-26 18:58发布

问题:

The problem:

Inheritance dependency

  • Type A stores a value of type B in a property

  • Type B inherits from type A

We'll consider a UI control hierarchy, where every control belongs to a top-level "Form", and the Form itself is a Control.

The author solves this problem by parameterizing classes:

[<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)

But how can I redesign in a functional approach: "We would not be using inheritance at all. Instead, we would use composition in conjunction with parameterization"?

回答1:

This question is hard to answer, because the formulation of the question is inherently object-oriented. When you say "form is a control", the "is a" part of the question hints at an OO way of modelling the world that you would not typically use in functional programming.

Strictly speaking, your sample code does not actually do anything useful - it creates a bunch of objects, but does not use them to render any user interface or implement any other functionality.
Of course, I suspect this is what the question is getting at. If I wanted to model a very simple user interface that includes forms and buttons, I might start with something like this:

type SimpleControl = 
  | Button of string
  | Label of string

type ContainerControl = 
  | Form 

type Control = 
  | Container of ContainerControl * Control list
  | Simple of SimpleControl

This lets you define container controls (such as form) that can contain other controls and buttons and labels, which are simple controls and cannot contain other elements. This is just an example though - depending on what kind of user interfaces you actually want to build and what you want to do with them, you would define the types differently.

The short version is, functional programming often requires a different way of thinking and some of the questions that make sense in object-oriented world do not make sense in the functional world.