Skip to content

Instantly share code, notes, and snippets.

@fpawel
Created May 25, 2017 08:53
Show Gist options
  • Save fpawel/1b6c32d6ab51a33f715f2484352cef3f to your computer and use it in GitHub Desktop.
Save fpawel/1b6c32d6ab51a33f715f2484352cef3f to your computer and use it in GitHub Desktop.
[<AutoOpen>]
module private Helpers1 =
let rec generateFsharpObject (t:Type) : obj =
let fail() = failwithf "generateFsharpObject %A " t
if t.IsValueType then Activator.CreateInstance(t)
elif t = typeof<string> then box ""
elif isEnumerable t then
if t.IsArray then
let valueType = t.GetElementType()
let result = Array.CreateInstance( valueType, 0 )
box result
elif t.IsGenericType then
let deft = t.GetGenericTypeDefinition()
if deft = typedefof<list<_>> then
let valueType = t.GetGenericArguments().[0]
makeListOf valueType []
elif deft = typedefof<Set<_>> then
let valueType = t.GetGenericArguments().[0]
Activator.CreateInstance( t, makeListOf valueType [] )
elif deft = typedefof<Map<_,_>> then
let keyValuePairType = typedefof<System.Tuple<_,_>>.MakeGenericType( t.GetGenericArguments() )
Activator.CreateInstance( t, makeListOf keyValuePairType [] )
else
let valueType = t.GetGenericArguments().[0]
Activator.CreateInstance( t, makeListOf valueType [] )
else fail()
elif FSharpType.IsTuple t then
FSharpValue.MakeTuple( FSharpType.GetTupleElements(t) |> Array.map generateFsharpObject, t)
elif FSharpType.IsUnion t then
let cases = FSharpType.GetUnionCases t
let tag = 0
let case = cases |> Array.find( fun x -> x.Tag=tag)
let values = case.GetFields() |> Array.map (fun px -> generateFsharpObject px.PropertyType )
FSharpValue.MakeUnion(case, values)
elif FSharpType.IsRecord t then
let values =
FSharpType.GetRecordFields(t)
|> Array.map ( fun px -> generateFsharpObject px.PropertyType)
FSharpValue.MakeRecord( t, values)
else fail()
let generateFsharpObject<'a>() =
generateFsharpObject (typeof<'a>)
:?> 'a
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment