Identification Scheme

RecursiveEnigma
TechDev Mix
Published in
3 min readMar 22, 2015

An entity must have a unique identity, so that other objects can uniquely identify it. In an application with one object store, this is not a problem, because the identity usually takes the form of the auto generated identity value assigned to the object when gets persisted. A good example of this is something like a simple web application, that keeps all it’s objects in a single SQL database. When new objects are persisted to the database, the primary key is automatically incremented, and this becomes the identity of the new entity.

However, when an entity is referred to differently by more than one context, the situation becomes slightly more complicated. In this scenario an entity will actually have multiple identities, depending on which object or system is referring to it. The solution to this problem is to use an Identification Scheme, where each identity has a type associated with it:

type PersonIdScheme = 
| Passport
| National
| DriversLicense
type PersonIdentifier (scheme, value) =
member me.scheme = scheme
member me.value = value
type PersonIdComparer() =
interface IComparer<PersonIdentifier> with
member me.Compare(a, b) =
if a.scheme = b.scheme && a.value = b.value
then 0
else -1
type Person (id: Set<PersonIdentifier>) =
let mutable id' = id

member me.id
with get () = id'
and set (value) = id' <- value

The above example demonstrates how you can design an Object Oriented Identification Scheme, in F#, to identify a person. Two things stand out, one is the enumeration PersonIdScheme, that specifies the different ways in which a person can be uniquely identified.

The second is the property Person.id, that’s a Set of PersonIdentifiers. Because an object now has a collection of identities, it’s necessary for the Identification Scheme to enforce a unique identity value per Scheme.

Now, let’s implement a functional Identification Scheme in OCaml. Imagine an application that stores discount sales deals in different databases, either relational as Identity.t.Common, or something like Amazon S3 as Identity.t.ObjStore:

common.ml

module rec Identity : 
sig
type t =
| Id of IdSet.t
| Common of string
| ObjStore of string
val scheme : t list -> IdSet.t
end =
struct
type
t =
| Id of IdSet.t
| Common of string
| ObjStore of string
let scheme lst =
List.fold_right
(fun item set -> IdSet.add item set) lst IdSet.empty
end
and IdSetItem : Set.OrderedType =
struct
type t = Identity.t
let compare = Pervasives.compare
end
and IdSet : (Set.S with type elt = Identity.t) =
Set.Make(IdSetItem)

deals.ml

open Core.Std 
open Common
open Common.Identity
type deal = {
id: Identity.t;
title: string;
description: string;
expiry_date: Time.t;
}

deal_repository.ml

open Core.Std 
open Common
open Common.Identity
open Deals
let save deal =
(* In a real app, the deal will be saved here.
For the example just return the passed in deal. *)

deal
let get_by_id deal_id =
(* In a real app, the database will be queried here.
For the example just return a fake deal. *)

{ id = Id (scheme [Common "1"; ObjStore "2"]);
title = "?";
description = "?";
expiry_date = Time.now ();
}

The most interesting piece of code from the above example is the Identity.t recursive variant. The Id tag is a Set of recursive Identity.t tags. The function scheme converts a list of Identity.t tags to a Set. The “module rec” statement, declares the modules mutually recursive, so that the Identity.t variant and IdSet Set can refer to each other. The end result is a self explaining statement like “Id (scheme [Common “1”; ObjStore “2”])” to create a new collection of Identity.t values.

It’s an interesting comparison between OCaml and F#, and Object Oriented and functional. The F# code looks more succinct, and in the OO code we have to deal with mutable state. For the F# code I chose to use an Enumeration, but I could’ve used a Discriminated Union to make it the same as the Variant in OCaml

--

--