irriss
irriss

Reputation: 782

Extend type in F#

Let say I have some types

type A = { ... }

type B = { ... }

type AB = A of A | B of B

type Ainfo = { 
    a: A
    ... 
}

type Binfo = { 
    b: B
    ... 
}

type ABinfo = Ainfo of Ainfo | Binfo of Binfo

and I need a collection to store additional information for thes types

something like Dictionary<AB, ABinfo>

the problem with this dictionary is that it will allow to associate key of A with value of Binfo.

Is there a good way to structure code in way that A always extended with Ainfo and B always extended with Binfo? In OOP I would inherit Ainfo from A and Binfo from B, not sure how to do it best way in F#

Upvotes: 0

Views: 93

Answers (1)

Fyodor Soikin
Fyodor Soikin

Reputation: 80744

From your comments, I understand that you really want two properties:

  1. Valid by construction - i.e. impossible to associate an A-value with a B-key
  2. Constant-time lookup (such as Dictionary offers)

To solve for these two properties, you could use two dictionaries behind the scenes instead of one. One dictionary would contain A-values, the other - B-values:

type ABDict = { aDict: Dictionary<A, Ainfo>; bDict: Dictionary<B, Binfo> }

let newABDict () = { aDict = Dictionary(); bDict = Dictionary() }

let insert abinfo dict =
    match abinfo with
    | Ainfo ainfo -> dict.aDict.Add(ainfo.a, ainfo)
    | Binfo binfo -> dict.bDict.Add(binfo.b, binfo)

let lookup ab dict = 
    match ab with
    | A a -> 
        let found, ainfo = dict.aDict.TryGetValue(a)
        if found then Some (Ainfo ainfo) else None
    | B b -> 
        let found, binfo = dict.bDict.TryGetValue(b)
        if found then Some (Binfo binfo) else None

// Usage:
let d = newABDict ()
insert (Ainfo { a = { ... }, ... }) d
insert (Binfo { b = { ... }, ... }) d

let x = lookup (A { ... }) d
let y = lookup (B { ... }) d

Upvotes: 2

Related Questions