Dmitry Volkov
Dmitry Volkov

Reputation: 1337

Generic functions for generic types in F#

I'm learning functional programming with F#, and I want to write a function to raise number to power. I wrote it in the following manner:

let raiseToPower a power = 
    let folding x _ = x * a
    [1..power-1] |> List.fold folding a

let result = raiseToPower 2 5

I did not specify the type of an input variable a, so I can possibly use this function with float or integer number - but not the both

let result = raiseToPower 2.3 5 // OK

// separate program let result = raiseToPower 2 5 // OK

// separate program let result1 = raiseToPower 2.3 5 // OK let result2 = raiseToPower 2 5 // fail

The first question is: Is there a way to make it generic?


The reason I made a function for something F# already has a built-in implementation is that I want to use something like that with custom type - Complex Numbers, for instance.

Consider the following:

type ComplexNumber = {re: double; im: double;}

let (@*) cn1 cn2 = 
    {re = cn1.re * cn2.re - cn1.im * cn2.im; im = cn1.re * cn2.im + cn1.im * cn2.re}

I have a new type ComplexNumber and a new operator for it that multiplies two complex numbers. Now I can write a similar function to raise ComplexNumber to power:

let raiseCnToPower a power = 
    let folding x _ = x @* a
    [1..power-1] |> List.fold folding a

So the second question is: Is there a way to make the initial function to work with custom types and custom operators?


Conclusive question: I'd like to know what you should do here in terms of functional programming. Is this considered to be a problem, or different functions for different types doing almost the same is OK? Is there a way to improve solution in terms of functional programming and F# specifically?

Upvotes: 4

Views: 153

Answers (1)

AMieres
AMieres

Reputation: 5004

An easy way is to declare it inline:

let inline raiseToPower a power = 
    let folding x _ = x * a
    [1..power] |> List.fold folding (a / a) // <- handles power = 0

let result1 = raiseToPower 2 5
let result2 = raiseToPower 2. 5

Upvotes: 4

Related Questions