i trying reinvent list.fold
, list.reduce
, , list.sum
using pointfree inline
functions sake of learning. here had:
let flip f y x = f x y let rec fold folder seed = function | [] -> seed | h :: t -> fold folder (folder seed h) t let inline reduce< ^a when ^a : (static member 0 : ^a) > : (^a -> ^a -> ^a) -> ^a list -> ^a = flip fold languageprimitives.genericzero let inline sum< ^a when ^a : (static member (+) : ^a * ^a -> ^a) , ^a : (static member 0 : ^a)> : ^a list -> ^a = reduce (+) // ^ compile error here
i know such verbose type constraints not used in f# trying learn please bear me.
i got cryptic compile error not understand:
type mismatch. expecting 'a -> 'a -> 'a given 'a -> 'b -> 'c type parameter missing constraint 'when ( ^a or ^?269978) : (static member ( + ) : ^a * ^?269978 -> ^?269979)' type parameter missing constraint 'when ( ^a or ^?269978) : (static member ( + ) : ^a * ^?269978 -> ^?269979)' val ( + ) : x:'t1 -> y:'t2 -> 't3 (requires member ( + )) full name: microsoft.fsharp.core.operators.( + ) overloaded addition operator x: first parameter. y: second parameter.
what should add satisfy compiler?
i don't know way of doing want, because there's no way know of invoke statically constrained static member in pointfree style. note not invoking (+)
of ^a
, compiler not know how figure out... if happy using inner helper function, can do:
let inline sum< ^a when ^a : (static member (+) : ^a -> ^a -> ^a) , ^a : (static member 0 : ^a) > : ^a list -> ^a = let add x y = (^a : (static member (+) : ^a -> ^a -> ^a) (x, y)) reduce add
note warning
warning fs0077: member constraints name 'op_addition' given special status f# compiler .net types implicitly augmented member. may result in runtime failures if attempt invoke member constraint own code.
and indeed:
sum [1; 2; 3]
leads to
system.notsupportedexception: specified method not supported.
at fsi_0005.it@15-1.invoke(int32 x, int32 y) in ...
but if change sum
to:
let inline sum list = reduce (+) list sum [1; 2; 3] // 6
Comments
Post a Comment