4 people like it.

Bi directional map

Bi directional map to implement toString and fromString function for descriminated unions.

The implementation of Bi directional map

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
/// Bi directional map.
/// It stores correspondences of two values.
/// It yields correspond value from another value of the pair.
type BiMap<'a,'b when 'a : comparison and 'b : comparison>(item1s:'a list, item2s:'b list) =
  // reusing standard F# library's map to implement find functions
  let item1IsKey = List.zip item1s item2s |> Map.ofList
  let item2IsKey = List.zip item2s item1s |> Map.ofList
  
  member __.findBy1    key = Map.find    key item1IsKey
  member __.tryFindBy1 key = Map.tryFind key item1IsKey 
  // Ctrl + H. then replace 1 to 2 the above two lines of code
  member __.findBy2    key = Map.find    key item2IsKey 
  member __.tryFindBy2 key = Map.tryFind key item2IsKey 

The implementation of toString and fromString function for a descreminated union

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
type Week = 
  | Sunday 
  | Monday 
  | Tuesday 
  | Wednesday 
  | Tursday 
  | Friday 
  | Saturday

let weekBiMap = 
  BiMap (
    [ Sunday ; Monday ; Tuesday ; Wednesday ; Tursday ; Friday ; Saturday ],
    ["Sunday";"Monday";"Tuesday";"Wednesday";"Tursday";"Friday";"Saturday"]
  )

type Week with
  member this.ToStr           = this  |> weekBiMap.findBy1
  static member FromStr sWeek = sWeek |> weekBiMap.tryFindBy2

usage

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
Sunday.ToStr // val it : string = "Sunday"

Week.FromStr "Tuesday" // val it : Week option = Some Tuesday
Week.FromStr "Tuesady" // val it : Week option = None

// In this snippet I use a class instance as a reusable factory which
// removes trivial function implementation.
// It seems that OOP class features eliminated boilerplates from the FP code.
// And this OOP class is easily implemented by using FP features.
// It's an interesting result isn't it?
// (I know there are already many examples that shows the multi-paradimn language really shine)
Multiple items
type BiMap<'a,'b (requires comparison and comparison)> =
  new : item1s:'a list * item2s:'b list -> BiMap<'a,'b>
  member findBy1 : key:'a -> 'b
  member findBy2 : key:'b -> 'a
  member tryFindBy1 : key:'a -> 'b option
  member tryFindBy2 : key:'b -> 'a option

Full name: Script.BiMap<_,_>


 Bi directional map.
 It stores correspondences of two values.
 It yields correspond value from another value of the pair.


--------------------
new : item1s:'a list * item2s:'b list -> BiMap<'a,'b>
val item1s : 'a list (requires comparison)
type 'T list = List<'T>

Full name: Microsoft.FSharp.Collections.list<_>
val item2s : 'b list (requires comparison)
val item1IsKey : Map<'a,'b> (requires comparison and comparison)
Multiple items
module List

from Microsoft.FSharp.Collections

--------------------
type List<'T> =
  | ( [] )
  | ( :: ) of Head: 'T * Tail: 'T list
  interface IEnumerable
  interface IEnumerable<'T>
  member Head : 'T
  member IsEmpty : bool
  member Item : index:int -> 'T with get
  member Length : int
  member Tail : 'T list
  static member Cons : head:'T * tail:'T list -> 'T list
  static member Empty : 'T list

Full name: Microsoft.FSharp.Collections.List<_>
val zip : list1:'T1 list -> list2:'T2 list -> ('T1 * 'T2) list

Full name: Microsoft.FSharp.Collections.List.zip
Multiple items
module Map

from Microsoft.FSharp.Collections

--------------------
type Map<'Key,'Value (requires comparison)> =
  interface IEnumerable
  interface IComparable
  interface IEnumerable<KeyValuePair<'Key,'Value>>
  interface ICollection<KeyValuePair<'Key,'Value>>
  interface IDictionary<'Key,'Value>
  new : elements:seq<'Key * 'Value> -> Map<'Key,'Value>
  member Add : key:'Key * value:'Value -> Map<'Key,'Value>
  member ContainsKey : key:'Key -> bool
  override Equals : obj -> bool
  member Remove : key:'Key -> Map<'Key,'Value>
  ...

Full name: Microsoft.FSharp.Collections.Map<_,_>

--------------------
new : elements:seq<'Key * 'Value> -> Map<'Key,'Value>
val ofList : elements:('Key * 'T) list -> Map<'Key,'T> (requires comparison)

Full name: Microsoft.FSharp.Collections.Map.ofList
val item2IsKey : Map<'b,'a> (requires comparison and comparison)
member BiMap.findBy1 : key:'a -> 'b

Full name: Script.BiMap`2.findBy1
val key : 'a (requires comparison)
val find : key:'Key -> table:Map<'Key,'T> -> 'T (requires comparison)

Full name: Microsoft.FSharp.Collections.Map.find
val __ : BiMap<'a,'b> (requires comparison and comparison)
member BiMap.tryFindBy1 : key:'a -> 'b option

Full name: Script.BiMap`2.tryFindBy1
val tryFind : key:'Key -> table:Map<'Key,'T> -> 'T option (requires comparison)

Full name: Microsoft.FSharp.Collections.Map.tryFind
member BiMap.findBy2 : key:'b -> 'a

Full name: Script.BiMap`2.findBy2
val key : 'b (requires comparison)
member BiMap.tryFindBy2 : key:'b -> 'a option

Full name: Script.BiMap`2.tryFindBy2
type Week =
  | Sunday
  | Monday
  | Tuesday
  | Wednesday
  | Tursday
  | Friday
  | Saturday
  member ToStr : string
  static member FromStr : sWeek:string -> Week option

Full name: Script.Week
union case Week.Sunday: Week
union case Week.Monday: Week
union case Week.Tuesday: Week
union case Week.Wednesday: Week
union case Week.Tursday: Week
union case Week.Friday: Week
union case Week.Saturday: Week
val weekBiMap : BiMap<Week,string>

Full name: Script.weekBiMap
val this : Week
member Week.ToStr : string

Full name: Script.Week.ToStr
member BiMap.findBy1 : key:'a -> 'b
static member Week.FromStr : sWeek:string -> Week option

Full name: Script.Week.FromStr
val sWeek : string
member BiMap.tryFindBy2 : key:'b -> 'a option
static member Week.FromStr : sWeek:string -> Week option
Raw view Test code New version

More information

Link:http://fssnip.net/9h
Posted:13 years ago
Author:nagat01
Tags: maps