The following gives a duplicate definition error:
let (.*) (m1 : Matrix<float>) (m2 : Matrix<float>) =
m1.Multiply(m2)
let (.*) (v1 : Vector<float>) (v2 : Vector<float>) =
v1.DotProduct(v2)
Is there a way to define an operator overload such that F# recognizes the function I'm trying to call based on the function signature?
For example Julia has this very useful feature:
julia> methods(*)
# 138 methods for generic function "*":
*(x::Bool, y::Bool) at bool.jl:38
*{T<:Unsigned}(x::Bool, y::T<:Unsigned) at bool.jl:53
*(x::Bool, z::Complex{Bool}) at complex.jl:122
*(x::Bool, z::Complex{T<:Real}) at complex.jl:129
...
It would be great if there were a way to replicate something similar in F#.
In this specific case * is already overloaded. For example:
let m = matrix [[ 1.0; 4.0; 7.0 ]
[ 2.0; 5.0; 8.0 ]
[ 3.0; 6.0; 9.0 ]]
let v = vector [ 10.0; 20.0; 30.0 ]
let s = 5.
m * m
//val it : Matrix<float> =
// DenseMatrix 3x3-Double
//30 66 102
//36 81 126
//42 96 150
v * v
//val it : float = 1400.0
With overloading:
type Mult = Mult with
static member inline ( $ ) (Mult, m1:Matrix<float>) = fun (m2:Matrix<float>) -> m1.Multiply(m2)
static member inline ( $ ) (Mult, v1:Vector<float>) = fun (v2:Vector<float>) -> v1.DotProduct(v2)
let inline ( .*. ) v1 v2 = (Mult $ v1) v2
And you can use it like this:
m .*. m
v .*. v
You'll get the same results as above. You can use .*, I just avoided it as not to get confused with the already defined .*. Now this is actually discussed in Global Operator Overloading and Oveload operator in F# but F#'s behavior here is a bit obscure so I re-did the example with the Matrix and Vector types. You can probably make it generic. Maybe someone more familiar with mathdotnet can provide a more idiomatic solution. You should also check if * , .* et al. are already overloaded and function as expected for you since for common operations most of this stuff is already implemented.
Related
let inline (=~) a b = abs (single a - single b) <= 0.001f
type Vector =
{ x : single; y : single; z : single }
static member (=~) (v1, v2) = (v1.x =~ v2.x) && (v1.y =~ v2.y) && (v1.z =~ v2.z)
let v1, v2 =
{ x = 0.1f; y = single Math.PI; z = 0.f },
{ x = 0.1f; y = 3.14159f; z = 0.0001f }
v1 =~ v2
Compiler complains: The type 'Vector' does not support a conversion to the type 'single'
I don't get it. Clearly, the type-specific operator doesn't take precedence over the generic operator, foiling my intuition. What's the trick to making this work?
When you define a custom operator using let, it will always take precedence over type-defined operators. The simple way of dealing with this is to avoid name clashes in local and global operator names, or to keep the scope of the let-bound operators to a minimum. For example, you could put the global =~ operator in a separate module:
module VectorImplementation =
let inline (=~) a b = abs (single a - single b) <= 0.001f
module Vectors =
open VectorImplementation
type Vector =
{ x : single; y : single; z : single }
static member (=~) (v1, v2) =
(v1.x =~ v2.x) && (v1.y =~ v2.y) && (v1.z =~ v2.z)
open System
open Vectors
let v1, v2 =
{ x = 0.1f; y = single Math.PI; z = 0.f },
{ x = 0.1f; y = 3.14159f; z = 0.0001f }
v1 =~ v2
There is also a somewhat strange hack that you can use to define global let-bound operators that are overloaded. There is some debate whether this is a good idea or not - I think it is usually possible to avoid clashes without resorting to this magic trick, but others might disagree.
Page 97 of the F# 4.0 language specification says that:
If the operator does not resolve to a user-defined or library-defined operator, the name resolution rules (§14.1) ensure that the operator resolves to an expression that implicitly uses a static member invocation expression (§0) that involves the types of the operands. This means that the effective behavior of an operator that is not defined in the F# library is to require a static member that has the same name as the operator, on the type of one of the operands of the operator.
As Tomas Petricek has just pointed out in his answer, that means that the =~ operator you defined globally is "hiding" the =~ operator on your Vector type. His answer suggests a good approach for dealing with the problem. Another way would be to simply make both operators different:
let inline (==~) a b = abs (single a - single b) <= 0.001f
type Vector =
{ x : single; y : single; z : single }
static member (=~) (v1, v2) =
(v1.x ==~ v2.x) && (v1.y ==~ v2.y) && (v1.z ==~ v2.z)
You may find this approach simpler than Tomas's approach, or you may find his approach simpler. It's a matter of style preference; either one should work.
when use
let add a b = a + b
it works for int. and
let add2 a b:float = a + b
work for float.
Is it possible to write a function work for int and long (float, byte .etc) in F#?
i need a function whose "a" work for int and long like this:
let f a b = a >>> b
let f (a:int64) b = a >>> b
is it possible in F#?
When you want to write a function that can work with multiple different numeric types, you need to use inline and "static member constraints". The problem is that normal .NET generics cannot capture constraints like "supports the + operator".
To make your sample add function generic, you can use inline:
let inline add x y = x + y
When you look at the inferred type, you'll see something like this:
val inline add :
x: ^a -> y: ^b -> ^c
when ( ^a or ^b) : (static member ( + ) : ^a * ^b -> ^c)
This essentially says that the function can be called on any two arguments that support the + operator. Note that this only works because the function is inline and so the F# compiler does not have to rely on .NET to express the constraints. The same works for the >>> operator:
let inline f a b = a >>> b
The function can now be used with both int64 and int arguments:
f 1024L 2
f 1024 2
I wrote an article about writing generic numeric code in F# some time ago which you may find useful too.
I've been trying to get my head round various bits of F# (I'm coming from more of a C# background), and parsers interest me, so I jumped at this blog post about F# parser combinators:
http://santialbo.com/blog/2013/03/24/introduction-to-parser-combinators
One of the samples here was this:
/// If the stream starts with c, returns Success, otherwise returns Failure
let CharParser (c: char) : Parser<char> =
let p stream =
match stream with
| x::xs when x = c -> Success(x, xs)
| _ -> Failure
in p //what does this mean?
However, one of the things that confused me about this code was the in p statement. I looked up the in keyword in the MSDN docs:
http://msdn.microsoft.com/en-us/library/dd233249.aspx
I also spotted this earlier question:
Meaning of keyword "in" in F#
Neither of those seemed to be the same usage. The only thing that seems to fit is that this is a pipelining construct.
The let x = ... in expr allows you to declare a binding for some variable x which can then be used in expr.
In this case p is a function which takes an argument stream and then returns either Success or Failure depending on the result of the match, and this function is returned by the CharParser function.
The F# light syntax automatically nests let .. in bindings, so for example
let x = 1
let y = x + 2
y * z
is the same as
let x = 1 in
let y = x + 2 in
y * z
Therefore, the in is not needed here and the function could have been written simply as
let CharParser (c: char) : Parser<char> =
let p stream =
match stream with
| x::xs when x = c -> Success(x, xs)
| _ -> Failure
p
The answer from Lee explains the problem. In F#, the in keyword is heritage from earlier functional languages that inspired F# and required it - namely from ML and OCaml.
It might be worth adding that there is just one situation in F# where you still need in - that is, when you want to write let followed by an expression on a single line. For example:
let a = 10
if (let x = a * a in x = 100) then printfn "Ok"
This is a bit funky coding style and I would not normally use it, but you do need in if you want to write it like this. You can always split that to multiple lines though:
let a = 10
if ( let x = a * a
x = 100 ) then printfn "Ok"
I am stuck attempting to overload the (*) operator for a Measure type.
What I would like to see is :
> let x = 1.0<i> * 1.0<i>;;
val x : float = -1.0
The following definition appears to do the trick :
> let inline (*) (v1 : float<i>) (v2 : float<i>) = float(-1) * float(v1) * float(v2);;
val inline ( * ) : float<i> -> float<i> -> float
Note that the product measure in this example correctly resolves to <1> as which happens for example when multiplying the imaginary unit of a complex number. Without this overloading definition the default product resolves to < i^2>.
But the overloading definition above has the nasty side effect that :
> let y = 1.0 * 1.0;;
let y = 1.0 * 1.0;;
--------^^^
stdin(11,9): error FS0001: This expression was expected to have type
float<i>
but here has type
float
Apparently my overloading definition hides the (*) operator for the float type.
What am I doing wrong?
Note that you are redefining the (*) operator rather than overloading it.
The trick to get it working is to write something using an intermediate type, like this:
type Mult = Mult with
static member ($) (Mult, v1: float<i>) = fun (v2: float<i>) ->
float(-1) * float(v1) * float(v2)
static member inline ($) (Mult, v1 ) = fun v2 -> v1 * v2
static member ($) (Mult, v1: Mult) = fun () -> Mult //Dummy overload
let inline (*) v1 v2 = (Mult $ v1) v2
BTW funny way to use units of measure.
I am currently porting some code from Java to F# that deals with multidimensional functions. It supports variable dimension, so in the original implementation each point is represented as an array of doubles. The critical function of the code is an optimisation routine, that basically generates a sequence of points based on some criteria, evaluates a given function at these points and looks for a maximum. This works for any dimension. The operations I need are:
check the dimension of a point
create a new point with the same dimension of a given point
set (in procedural or functional sense) a given coordinate of a point
In F# I could obviously also use arrays in the same way. I was wandering though if there is a better way. If the dimension was fixed in advance, the obvious choice would be to use tuples. Is it possible to use tuples in this dynamic setting though?
No, tuples will be fixed by dimension. Also note that .NET tuples are boxed. If you are operating on large collections of points with small dimension (such as arrays of 2d points), using structs may help.
If you really want to push the F#/.NET advantage over Java, have a look at generics. Writing code with generics allows to write code that works for any dimension, and use different representations for different dimensions (say structs for 1-3 dimensions, and vectors for larger dimensions):
let op<'T where 'T :> IVector> (x: 'T) =
...
This is only relevant though if you are willing to go a long way to get the absolutely best performance and generality. Most projects do not need that, stick with the simplest thing that works.
For the fun of it, here is an extended example of how to utilize generics and F# inlining:
open System.Numerics
type IVector<'T,'V> =
abstract member Item : int -> 'T with get
abstract member Length : int
abstract member Update : int * 'T -> 'V
let lift<'T,'V when 'V :> IVector<'T,'V>> f (v: 'V) : 'V =
if v.Length = 0 then v else
let mutable r = v.Update(0, f v.[0])
for i in 1 .. v.Length - 1 do
r <- r.Update(i, f v.[i])
r
let inline norm (v: IVector<_,_>) =
let sq i =
let x = v.[i]
x * x
Seq.sum (Seq.init v.Length sq)
let inline normalize (v: 'V) : 'V =
let n = norm v
lift (fun x -> x / n) v
[<Struct>]
type Vector2D<'T>(x: 'T, y: 'T) =
member this.X = x
member this.Y = y
interface IVector<'T,Vector2D<'T>> with
member this.Item
with get (i: int) =
match i with
| 0 -> x
| _ -> y
member this.Length = 2
member this.Update(i: int, v: 'T) =
match i with
| 0 -> Vector2D(v, y)
| _ -> Vector2D(x, v)
override this.ToString() =
System.String.Format("{0}, {1}", x, y)
[<Sealed>]
type Vector<'T>(x: 'T []) =
interface IVector<'T,Vector<'T>> with
member this.Item with get (i: int) = x.[i]
member this.Length = x.Length
member this.Update(i: int, v: 'T) =
let a = Array.copy x
a.[i] <- v
Vector(a)
override this.ToString() =
x
|> Seq.map (fun e -> e.ToString())
|> String.concat ", "
[<Struct>]
type C(c: Complex) =
member this.Complex = c
static member Zero = C(Complex(0., 0.))
static member ( + ) (a: C, b: C) = C(a.Complex + b.Complex)
static member ( * ) (a: C, b: C) = C(a.Complex * b.Complex)
static member ( / ) (a: C, b: C) = C(a.Complex / b.Complex)
override this.ToString() = string c
let v1 = Vector2D(10., 30.)
normalize v1
|> printfn "%O"
let v2 = Vector2D(C(Complex(1.25, 0.8)), C(Complex(0.5, -1.)))
normalize v2
|> printfn "%O"
let v3 = Vector([| 10.; 30.; 50.|])
normalize v3
|> printfn "%O"
Note that norm and normalize are fairly general, they cope with specialized 2D vectors and generalized N-dimensional vectors, and with different component types such as complex numbers (you can define your own). The use of generics and F# inlining ensure that while general, these algorithms perform well for the special cases, using compact representations. This is where F# and .NET generics shine compared to Java, where you are obliged to create specialized copies of your code to get decent performance.