Q:

An issue with type matching (hopefully possible to fix) F#

So i have type Gitem
type Gitem = 
    |Weapon of Weapon
    |Bomb of Bomb
    |Monster of Monster
    |Armour of Armour
    |Potion of Potion
    |None

This is used to store different types of objects within a record, to be clear, the types I'm having issues with look like so:
type Monster={
    name:string;
    dVal:float;
    dType:DamType;
    hVal:float;
    info:string;
    dInfo:string;
    dCry:string;
    Special:bool;
    sItem:obj;
 }        

type Armour={
    name:string;
    aVal:float;
    dType:DamType;
    info:string;
    iSpace:int;
    hidden:bool;
}

type Weapon={
    name:string;
    dVal:float;
    dType:DamType;
    info:string;
    iSpace:int;
    hidden:bool;
}

The problem is, Gitem includes Monster as a potential type, however monsters can have a bomb, weapon or armour as their sItem, i made the type object due to this.
Later in my code i write :
match monster.sItem with  //gives them the item if the monster drops one
                    | Bomb bomb ->
                        procBomb bomb 

                    | Weapon weap -> 
                        procWeap weap

                    | Potion pot ->
                        procPot pot

                    | Armour arm ->
                        procArm arm

I get the error that the expression should be Gitem, not obj, however I cannot make the monster sitem field as Gitem, it is not allowed due to Gitem using monster as a possible type. I tried making another type like Gitem that has all types apart from monster, however this causes problems too.
I'm second year of university, any help would be appreciated

A:

Mutual recursive types can be declared using the and keyword:
type A = { b : B }
and B = { a : A option }

Also, F# 4.1 introduced recursive modules (and namespaces), which allow mutual recursive types at a module (namespace) level. This is useful if you have many lengthy mutually dependent types (note that there’s noand):
module rec RecursiveModule =
    type A = { b : B }
    type B = { a : A option }

