F# return a specified union type from byte array -
i'm trying write function takes in byte array , converts adt specified parameter. possible in f#? adt:
type dataformat = | alphanumeric of string | angle16 of float | angle32 of float | int16 of int | int32 of int i've tried ten different ways of formatting function specification, can't figure out... read of other posts on this one makes me think more complex think. last 2 attempts don't seem lead anywhere.
// attempt #1 // function require pass in shell // object "format" parameter make work, like: // let converted = frombytes1 myarray angle16(0.0) let frombytes1 (b : byte[]) (format : dataformat) = match format | alphanumeric -> alphanumeric(bitconverter.tostring(b)) | angle16 -> // convert 2-bytes float...omitted | angle32 -> angle32(float (bitconverter.tosingle(b,0))) // attempt #2 // 't seems specify underlying type (float, int) let frombytes2<'t> (b : byte[]) = match 't | alphanumeric -> alphanumeric(bitconverter.tostring(b)) | angle16 -> // convert 2-bytes float...omitted | angle32 -> angle32(float (bitconverter.tosingle(b,0))) i've tried using typeof<> seems return underlying base type.
i think try double-use discriminated union here.
use 1: use tag (or atom in erlang terms) indicate function expect. then, this:
type datatype = | int | bool // without data items associated. let readexpected (valuetype : datatype) (data : byte[] ) = match valuetype | datatype.int -> // parse int data , | datatype.bool -> // parse boolean representation data ... use 2: use union real adt. return value of function:
type adt = | int of int | bool of bool // have data let read (data : byte[]) : adt = let wiretype = data.[0] match wiretype | 2uy -> int(readint data) // return parsed int adt.int | 3uy -> bool(readbool data) // return parsed bool adt.bool | _ -> failwith "unknown wire type in data." you try mix 2 approaches, of course.
type adt = | int of int | bool of bool // have data let readexpected (data : byte[]) (expectedtype : adt) : adt = match expectedtype | int(_) -> int(readint data) | bool(_) -> bool(readbool data) if dislike way write expectedtype explicitely phony data content, opt easy solution this:
type adt = | int of int | bool of bool // have data let inttype = int(0) let booltype = bool(false) let readexpected (data : byte[]) (expectedtype : adt) : adt = match expectedtype | int(_) -> int(readint data) | bool(_) -> bool(readbool data) // caller code: let intvalue = readexpected data inttype let boolvalue = readexpected data booltype maybe make sense here, switch order of 2 parameters.
maybe make sense not pretend dynamic if in fact not. if caller able specify inttype in code above, create 1 function per type.
type adt = | int of int | bool of bool // have data let readint data = int( foo data) // foo data lazy way of saying: parse ;) let readbool data = bool( if data.[0] = 0uy false else true ) // caller code: let intvalue = readint data let boolvalue = readbool data note, readxxx functions have same type: byte[] -> adt. if plan on specifying message types means of composition, can use fact advantage.
Comments
Post a Comment