Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

F# and modeling of the inheritance

my question relates to a way how to deal with the inheritance in functional way in F#. To describe it a little, I give a simple example. Suppose we want to model a world consisting of various kinds of animals. Each animal kind shares some attributes with other kinds (e.g. name, size etc.). In addition, each kind may have other, which are not shared by others (e.g. number of children is relevant for dogs and cats, however not for spiders for instance). Also, there might be methods or functions associated with each animal kind which may or may not be same for two animal kinds, i.e. there is default implementation which may be overiden for a particular kind. Each animal kind may have method(s) which is only defined for that kind.

Now, in OOP world, this would probably lead to an abstract class having the common attributes and abstract methods followed by the classes derived for each animal kind. What I am not sure is how to specify the domain model functionally in F#. Here: Which to use , abstract class or interface in F#? is claimed that "idiomatic F# code uses different extensibility points than C# (e.g. taking function/interface as an argument), so you don't really need abstract classes".

If this is a the way that should be adopted, would it be possible to provide some elementary example of this?

As for my further thinking on this, I suppose that the attributes should be encapsulated in some structure. Then, most idiomatic structure in this respect in F# is record. Would that mean that there is to be a parent record, which shall be included in other records corresponding to particular "children", i.e. composition instead of inheritance. This however seems to me as a workaround which is neither idiomatic nor particularly elegant.

I think the preferred way how to model inheritance in F# are discriminated unions. However, this does not solve the problem of shared attributes and methods.

The models similar to the one mentioned above, are quite frequent in my view, since are implicitly included in most enterprise applications. Thus, is there any suggestion how this can be handled in functional way (en example to the way suggested under the link above or any other suggestion)? Or shall we say that this is not a domain which can be easily modeled using the functional approach?

Thank you.

like image 657
user2039784 Avatar asked Jun 13 '13 10:06

user2039784


1 Answers

Your description of the example already presupposes the object-oriented programming model. You are describing the problem in object-oriented terms such as overriding and methods defined for certain types of animals. This makes it difficult to give you a sensible alternative functional representation, because your question already assumes object-oriented concepts in the answer.

First, it is perfectly fine to use object-oriented constructs in F# when they make sense (the example in your question is just a toy sample, so this may or may not be the case). The key idea is that F# prefers composition over inheritance and so you would probably try to avoid inheritance (which can lead to complex object hierarchies) and instead compose animals from different aspects.

Second, if you explained your problem in a different way, then there might be perfectly fine functional representation using discriminated unions. For example:

type MammalKind = Cat | Dog
type MammalInfo = { Legs : int; Children : int }

type Animal = 
  | Mammal of MammalKind * MammalInfo
  | Spider of (...)

The idea would be to structure the type so that different kinds of animals (that you can process in a different way) have their own type. For example, you could write a function that takes MammalInfo and performs some computation that only makes sense for dogs and cats (but not for spiders). But as I mentioned earlier, your description of the problem is inherently object-oriented, so it might be difficult to see how this would be done.

like image 117
Tomas Petricek Avatar answered Oct 17 '22 00:10

Tomas Petricek