Skip to content

Instantly share code, notes, and snippets.

@pocketberserker
Created May 31, 2015 20:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pocketberserker/2d8cad2448fc4dc1bb25 to your computer and use it in GitHub Desktop.
Save pocketberserker/2d8cad2448fc4dc1bb25 to your computer and use it in GitHub Desktop.
Pure F# で HList を実装しようとしたが…型推論に阻まれる
[<AbstractClass>]
type HList<'A when 'A :> HList<'A>>() =
abstract member Extend<'E> : 'E -> HCons<'E, 'A>
abstract member Extender<'E> : unit -> Apply<unit, 'E * 'A, HCons<'E, 'A>>
and HList private () =
static member Cons<'E, 'L when 'L :> HList<'L>>(e, l) = HCons<'E, 'L>(e, l)
and HCons<'E, 'L when 'L :> HList<'L>>(e: 'E, l: 'L) =
inherit HList<HCons<'E, 'L>>()
override __.Extender<'X>() = Apply.Cons<'X, HCons<'E, 'L>>()
override this.Extend<'X>(e: 'X) = HList.Cons<'X, HCons<'E, 'L>>(e, this)
member __.Head = e
member __.tail = l
and [<AbstractClass>] Apply<'F, 'A, 'R>() =
abstract member Apply: 'F * 'A -> 'R
and Apply private () =
static member F() = { new Apply<'X -> 'Y, 'X, 'Y>() with
member __.Apply(f, x) = f x }
static member Id() = { new Apply<unit, _, _>() with
member __.Apply((), x) = x }
static member Cons<'E, 'L when 'L :> HList<'L>>() =
{ new Apply<unit, 'E * 'L, HCons<'E, 'L>>() with
member __.Apply((), (p1, p2)) = HList.Cons<'E, 'L>(p1, p2) }
type HNil private () =
inherit HList<HNil>()
override this.Extend<'E>(e: 'E) = HList.Cons<'E, HNil>(e, this)
override __.Extender<'E>() = Apply.Cons<'E, HNil>()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment