9
votes

Object Oriented programming paradigm uses inheritance to model relationships between entities that follow Generalization-Specialization relationship. Here, a Base class is used to encapsulate the common (General) attributes and behavior of a set of entities and the Derived Classes extend the base class by adding additional attributes and/or adding/modifying existing behavior.

As someone new to Functional Programming, I need guidance on modeling such relationships in functional languages like F#.

e.g. what would be the best approach to model a simple situation like the following:

abstract class Tutorial { 
  private String topic;
  abstract public void learn();
}

class VideoTutorial extends Tutorial {
  private float duration;
  public void learn () {
    System.out.println ("Watch Video");
  }
}

class PDFTutorial extends Tutorial {
  private int pageCount;
  public void learn () {
    System.out.println ("Read PDF");
  }
}

and then later use a collection of Tutorials and call learn to observe polymorphic behavior.

1

1 Answers

17
votes

In the functional design, you think about things a bit differently, so the ideas will not map perfectly. Typically, functional design focuses more on data types that express the entities you are working with. In your case, you could define TutorialKind which is either video or PDF using a discriminated union and Tutorial would then be a record that consits of a kind and its topic:

type TutorialKind = 
  | VideoTutorial of duration:float
  | PDFTutorial of pageCount:int

type Tutorial = 
  { Kind : TutorialKind
    Topic : string }

Note that this keeps just the data about tutorials. Any functionality can be implemented in functions that pattern match on the kind of the tutorial:

let learn tutorial = 
  match tutorial.Kind with
  | VideoTutorial _ -> printfn "Watch video"
  | PDFTutorial _ -> printfn "Read PDF"

Note that this is extensible in a different direction than the OO version. In OO, you can easily add new subclasses; here you can easily add new functions. In practice, functional people are usually happy with this change, but F# is a mixed language and if you need "OO-style extensibility", you can easily use interfaces.