generics - Getting or implementing String.Zero and bool.Zero generically for use with monoids -


i trying refactor existing code into more monodic approach. existing code contains interfaces ixinterface , numerics int , bool. numerics have zero default, interfaces have property gettor, bool , string not. 1 way out wrap bool , string in interface, cumbersome.

i figured if f# language manages extend types numerics, perhaps can strings , bools particular situation.

module myzero =     let inline get_zero () : ^a = ((^a) : (static member get_zero : unit -> ^a)())      type system.string         static member get_zero() = system.string.empty  type xr<'t when 't : (static member get_zero : unit -> 't)> =     | expression of (someobj -> 't)     | action of (int -> 't)     | value of 't     | empty      member inline this.execute(x: someobj) : 't =         match         | value(v) -> v         | expression(ex) -> ex x         | action(a) -> x.getlocation         | empty -> get_zero()      static member map f x=         match x         | xr.empty -> xr.empty         | xr.value v -> xr.value <| f v         | xr.action p -> xr.action <| fun v -> f (p v)         | xr.expression e -> xr.expression <| fun x -> f (e x)      // etc 

the above compiles fine, long don't try use strings or bools:

type wihtbool = xr<int>         // succeeds type wihtbool = xr<ixinterface> // succeeds type wihtbool = xr<bool>        // fails  type withstring = xr<string>    // fails 

the error clear , correct (i have extension method, not recognized obvious reasons), don't know non-intrusive way rid of it:

fails "the type bool not support operator 'get_zero'
fails "the type string not support operator 'get_zero'

f# manages extend numeric types using static optimizations feature disabled outside f# core library.

afaik way similar mechanism using overloads , static member constraints.

indeed trying it's implemented in f#+

#nowarn "3186" #r @"fscontrol.core.dll" #r @"fsharpplus.dll"  open fsharpplus  let x:string = mempty() // val x : string = ""  type boo = boo     static member mempty() = boo  let y:boo = mempty() // val y : boo = boo 

it works on same principle f# math operators static constraint can satisfied type of argument.

here's part of source code makes magic.

currently instance bool missing, can add issue suggesting or pull request, one-liner (or two).

anyway if want capture functionality try quick-standalone code:

type mempty =     static member ($) (_:mempty, _:string) = ""     static member ($) (_:mempty, _:bool) = false  let inline mempty() :'t = unchecked.defaultof<mempty> $ unchecked.defaultof<'t>  let x:string = mempty() // val x : string = ""  let y:bool = mempty() // val y : bool = false  type boo = boo      static member ($) (_:mempty, _:boo) = boo  let z:boo = mempty() // val z : boo = boo 

you can rename mempty get_zero think get_zero not best name monoid, remember number 1 under multiplication monoid , get_zero used in f# core libraries generic numbers.

but if going in direction advise consider library since there many issues may find when scaling code resolved there, free other monoid related functions, mconcat , mfold , nicer signatures on types.


Comments

Popular posts from this blog

javascript - Slick Slider width recalculation -

jsf - PrimeFaces Datatable - What is f:facet actually doing? -

angular2 services - Angular 2 RC 4 Http post not firing -