.net - Function in Discriminated Union Constraining the Type of a Generic Parameter -


i trying port haskell code f# , getting strange error don't know how around. have discriminated union function defined below:

type othertype =     othertype1 of string     | othertype2 of string type mytype<'a> =      mysub1 of datetime * string * (float -> mytype<'a>)     | mysub2 of 'a     | mysub3 of datetime * string * (bool -> mytype<'a>) 

later have function works on type such

let fun1 date mytype (myfun2: ('b -> mytype<'a>)) =      match mytype     | othertype1(string1) -> mysub1(date, string1, myfun2)     | othertype2(string1) -> mysub3(date, string1, myfun2) 

this constrains myfun2 type (float -> mytype<'a>). there way prevent happening , keep k generic?

the result second pattern match falls.

thank you.

update:

looking @ haskell code trying replicate think issue in haskell version othertype gadt , othertype1 becomes othertype double , othertype2 becomes othertype bool. myfun2 able perform both of functions. here code if interested.

data othertype     othertype1 :: string -> othertype double     othertype2 :: string -> othertype bool   data mytype = mysub1 utctime string (double -> mytype a)     | mysub2     | mysub3 utctime string (bool -> mytype a)  myfun1 :: utctime -> othertype -> mytype myfun1 time o = myfun1' o mysub2             myfun1' :: othertype b-> (b -> mytype a) -> mytype         myfun1' (othertype1 name) k = mysub1 time name k         myfun1' (othertype2 name) k = mysub3 time name k                 

so guess question ask is, can gadts replicated in f#?

as far know, there no faithful way represent arbitrary gadts in f#. however, given structure of gadt , function you're writing, should possible use following (clunky) encoding:

// module witnessing equality of 2 types module eq =     // opaque type equating 'a , 'b     type eq<'a,'b> = private eq of ('a -> 'b) * ('b -> 'a)         member eq.apply(v) = match eq | eq(f,_) -> f v         member eq.unapply(v) = match eq | eq(_,g) -> g v      // constructs eq<'a,'a>     [<generalizablevalue>]     let refl<'a> : eq<'a,'a> = eq(id,id)      // not used, included completeness     let sym (eq(f,g)) = eq(g,f)     let trans (eq(f,g)) (eq(h,i)) = eq(f >> h, >> g)      // ideally, we'd provide way lift eq<'a,'b> eq<f<'a>,f<'b>>, can't expressed f#'s type system  type othertype<'a> = | othertype1 of eq.eq<'a,double> * string | othertype2 of eq.eq<'a,bool> * string  // "smart" constructors let othertype1 s = othertype1(eq.refl, s) let othertype2 s = othertype2(eq.refl, s)  type mytype<'a> = | mysub1 of datetime * string * (float -> mytype<'a>) | mysub2 of 'a | mysub3 of datetime * string * (bool -> mytype<'a>)  let fun1 date mytype myfun2 =      match mytype     | othertype1(eq, string1) -> mysub1(date, string1, eq.unapply >> myfun2)     | othertype2(eq, string1) -> mysub3(date, string1, eq.unapply >> myfun2) 

Comments

Popular posts from this blog

SPSS keyboard combination alters encoding -

Add new record to the table by click on the button in Microsoft Access -

javascript - jQuery .height() return 0 when visible but non-0 when hidden -