Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Functions with generic parameter types

I am trying to figure out how to define a function that works on multiple types of parameters (e.g. int and int64). As I understand it, function overloading is not possible in F# (certainly the compiler complains). Take for example the following function.

let sqrt_int = function     | n:int   -> int (sqrt (float n))     | n:int64 -> int64 (sqrt (float n)) 

The compiler of course complains that the syntax is invalid (type constraints in pattern matching are not supported it seems), though I think this illustrates what I would like to achieve: a function that operates on several parameter types and returns a value of the according type. I have a feeling that this is possible in F# using some combination of generic types/type inference/pattern matching, but the syntax has eluded me. I've also tried using the :? operator (dynamic type tests) and when clauses in the pattern matching block, but this still produces all sorts errors.

As I am rather new to the language, I may very well be trying to do something impossible here, so please let me know if there is alternative solution.

like image 440
Noldorin Avatar asked Feb 01 '09 16:02

Noldorin


People also ask

What is a generic type parameter?

Generic Methods A type parameter, also known as a type variable, is an identifier that specifies a generic type name. The type parameters can be used to declare the return type and act as placeholders for the types of the arguments passed to the generic method, which are known as actual type arguments.

How do you provide a generic parameterized type?

In order to use a generic type we must provide one type argument per type parameter that was declared for the generic type. The type argument list is a comma separated list that is delimited by angle brackets and follows the type name. The result is a so-called parameterized type.

What are the function of generic types in TypeScript?

Generics allow creating 'type variables' which can be used to create classes, functions & type aliases that don't need to explicitly define the types that they use. Generics makes it easier to write reusable code.

How do you pass a generic type as parameter TypeScript?

Assigning Generic ParametersBy passing in the type with the <number> code, you are explicitly letting TypeScript know that you want the generic type parameter T of the identity function to be of type number . This will enforce the number type as the argument and the return value.


1 Answers

Overloading is typically the bugaboo of type-inferenced languages (at least when, like F#, the type system isn't powerful enough to contain type-classes). There are a number of choices you have in F#:

  • Use overloading on methods (members of a type), in which case overloading works much like as in other .Net languages (you can ad-hoc overload members, provided calls can be distinguished by the number/type of parameters)
  • Use "inline", "^", and static member constraints for ad-hoc overloading on functions (this is what most of the various math operators that need to work on int/float/etc.; the syntax here is weird, this is little-used apart from the F# library)
  • Simulate type classes by passing an extra dictionary-of-operations parameter (this is what INumeric does in one of the F# PowerPack libraries to generalize various Math algorithms for arbitrary user-defined types)
  • Fall back to dynamic typing (pass in an 'obj' parameter, do a dynamic type test, throw a runtime exception for bad type)

For your particular example, I would probably just use method overloading:

type MathOps =     static member sqrt_int(x:int) = x |> float |> sqrt |> int     static member sqrt_int(x:int64) = x |> float |> sqrt |> int64  let x = MathOps.sqrt_int 9 let y = MathOps.sqrt_int 100L 
like image 120
Brian Avatar answered Sep 29 '22 23:09

Brian