Skip to content

Instantly share code, notes, and snippets.

@miklund
Created January 12, 2016 13:16
Show Gist options
  • Save miklund/7ed90352f71c4dc7b132 to your computer and use it in GitHub Desktop.
Save miklund/7ed90352f71c4dc7b132 to your computer and use it in GitHub Desktop.
2013-02-07 Immutable Thesaurus
# Title: Immutable Thesaurus
# Author: Mikael Lundin
# Link: http://blog.mikaellundin.name/2013/02/07/immutable-thesaraus.html
// add synonyms to a map
// thesaurus:Map<'a,Set<'a>> -> words:'a [] -> Map<'a,Set<'a>>
// when 'a : comparison
//
// addSynonyms (Map.ofList [("job", set ["work"]); ("work", set ["job"])]) [|"job"; "task"; "work"; "undertaking"|];;
let private addSynonyms thesaurus words =
// cache away set of synonyms
let synonyms = Set.ofArray words
// get existing set for key or empty set
let getExistingSetOrEmpty key map = if map |> Map.containsKey key then map.[key] else Set.empty
// recurse on words
let rec _addSynonyms thesaurus = function
// done recursing, return thesaurus
| [] -> thesaurus
// head :: tail
| hd :: tl ->
let existing = thesaurus |> getExistingSetOrEmpty hd
// add synonyms to map and recurse
_addSynonyms (thesaurus.Add (hd, (synonyms + existing).Remove hd)) tl
// init
_addSynonyms thesaurus (words |> Seq.toList)
// get the value for a key in the map thesaurus
// thesaurus:Map<'a,Set<'b>> -> word:'a -> 'b []
// when 'a : comparison and 'b : comparison
//
// getSynonyms (Map.ofList [("job", set ["work"]); ("work", set ["job"])]) "job";;
let private getSynonyms thesaurus word =
thesaurus |> Map.find word |> Set.toArray
// get all the keys in the map thesaurus
//
// getWords (Map.ofList [("job", set ["work"]); ("work", set ["job"])]);;
let private getWords thesaurus =
thesaurus |> Map.toSeq |> Seq.map fst |> Seq.toArray
// public interface
type Thesaurus(thesaurusData : Map<string, Set<string>>) =
let data = thesaurusData
new () = Thesaurus(Map.empty)
// add synonyms, creates a new Thesaurus and returns it
member this.AddSynonyms words = Thesaurus(addSynonyms data words)
// get all synonyms for a word
member this.GetSynonyms = getSynonyms data
// get all words
member this.GetWords() = getWords data
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment