Type level encoding of natural numbers in F# -
i trying encode natural numbers type in f# able check equality @ compile-time instead of run-time. best come was
type nat<'t> =     abstract member asint : int  type z() =      interface nat<z>          member __.asint = 0  type s<'p>(prev : nat<'p>) =     interface nat<s<'p>>          member __.asint = 1 + prev.asint  type tnat =     static member 0 = z() :> nat<z>     static member succ (prev : nat<'p>) = s(prev) :> nat<s<'p>>      static member 1 = tnat.succ(tnat.zero)     static member 2 = tnat.succ(tnat.one)   i'm not sure if i'm happy code. can done in better (or easier) way overlooking?
and can ensure asint calculated @ compile time?
in code, if try:
tnat.two = tnat.succ(tnat.one)   will yield false.
here's alternative implementation without interfaces:
type z = z     static member (!!) z = 0       type s<'a> = s of 'a     static member inline (!!)  (s a) = !!a + 1  let inline asint x = !! x  let 1 = s z let 2 = s 1   by using discriminated unions benefit of structural equality well, in solution have both type (at compile time) , value (at run time) equality.
by using inline, method called resolved @ compile time.
Comments
Post a Comment