Search code examples
inheritancef#discriminated-union

Discriminated unions and inheritance


I'm looking to create a scene-graph for my F# project somthing like:

root
->player_bob
-->torch
->enemy_1
-->extravagant_hat
-->enemies_cat_jess 
--->fleas
--->fur_ball
->loot

etc,etc.

Each item needs to hold a collection of game objects to represent it's children.

e.g enemy1's list contains a cat and a hat and the cats list contains fleas and a fur ball

So I plan to make them all inherit from a class that contains a collection that describes that objects children.

Now to my question: Should I down-cast child objects to GameObject's and store them in a list of the "GameObject" base class OR create a discriminating union e.g

type SceneObject = 
        |Character of Character //e.g player, enemy, cat
        |Item of Item //e.g hat, torch, furball

And store objects as a list of "SceneObjects" to avoid any problems/overheads with up-casting them, etc. As well as allowing me to describe special cases where the object isn't rendered and/or not used in collision detection e.g: sound emitters, trap triggers, etc.

The discriminated union + inheritance combo is my initial thought; though, as I'm new to FP, I thought it wise to ask the pro's for the best, functional, way of approaching this.

Thanks,

JD


Solution

  • You can use the discriminated union recursively.

    type SceneObject = 
        | Character of <characterData> * (SceneObject list) 
        | Item      of <itemData>      * (SceneObject list)
    

    And use it like this

    let root = [Character("Bob", [Item("Torch", []); ...]); ...]