Ankur is correct - you cannot do this (without resorting to hacks that would break units).
Maybe a clearer description of the problem is that the type of pow
function would depend on the value of the argument and F# doesn't allow you to do this. You could imagine this would work if were using just literals as the second argument, but it would become tricky if you used expressions:
pow a 3
pow a n
In the second case the value n
would have to appear in the type!
You can use some nasty tricks (inspired by this Haskell article), but it becomes a bit crazy. Instead of using numeric literals, you'd use something like S(S(S(N)))
to represent the number 3
. This way, you can bring the number into the type. You probably don't want to do this, but here is an example:
[<Measure>] type cm
type Num<[<Measure>] 'M, [<Measure>] 'N> =
| O_ of int * float<'N>
| S_ of int * Num<'M, 'N / 'M>
let O : Num<'M, 'M> = O_ (1, 0.0<_>)
let S n = match n with O_(i, _) | S_(i, _) -> S_(i + 1, n)
let pow (x:float<'M>) ((O_(i, _) | S_(i, _)):Num<'M, 'M 'N>) : float<'M 'N> =
unbox ((float x) ** float i)
let res = pow 2.0<cm> (S (S O))
EDIT: I posted the source code to F# snippets, so that you can see the inferred types: http://fssnip.net/4H
x^(2^y)
, notx^y
. – hammar