Skip to content

Instantly share code, notes, and snippets.

@t0yv0
Created June 3, 2014 04:52
Show Gist options
  • Save t0yv0/649a10818119636c0952 to your computer and use it in GitHub Desktop.
Save t0yv0/649a10818119636c0952 to your computer and use it in GitHub Desktop.
Generic clone recipe with Infers.
module Main
open Infers
open Infers.Rep
type SimpleRecord = { Name: string; Age: int }
type LotsOfRecords = { People: SimpleRecord [] }
type Cloneable<'T> =
| C of ('T -> 'T)
[<Sealed>]
[<InferenceRules>]
type CloneRules() =
member r.Int() : Cloneable<int> = C (fun x -> x)
member r.String() : Cloneable<string> = C (fun x -> x)
member r.Array(C f) = C (Array.map f)
member r.And(C cA, C cB) : Cloneable<And<_,_>> =
C (fun ab ->
let mutable r = Unchecked.defaultof<And<_,_>>
r.Elem <- cA ab.Elem
r.Rest <- cB ab.Rest
r)
member c.Record(rep: Rep, reco: Record<'T>, prod: AsProduct<'P,'T>, C cl: Cloneable<'P>) =
C (prod.OfProduct << cl << prod.ToProduct)
[<EntryPoint>]
let Start args =
let sr = { People = [|{Name = "Rick"; Age = 33 }; { Name = "Paul"; Age = 55 }|] }
let func = Infers.Engine.TryGenerate<Cloneable<LotsOfRecords>>(CloneRules())
match func with
| Some (C clone) ->
let src = clone sr
if (sr = src) && not (System.Object.ReferenceEquals(sr, src))
then printfn "OK"
else printfn "FAIL"
| _ ->
printfn "NO MATCH"
0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment