I have the following and I need to call the "functiontocall" in another script but need to constrain the inputs to ints. However the maths in the functions it calls all need float types.
let functionone (x: float) (y :float) = x/y
let functiontocall (a: int) (b: int) = functionone a b
|> functiontwo
|> functionthree
What would be the best thing to do to cast these as float?
Casting in F# is just using the type name in an expression:
functionone (float a) (float b)
Related
Is there a quick and simple way to convert an entire list of strings into floats or integers
and add them together similar to this in F#?
foreach(string s in list)
{
sum += int.Parse(s);
}
If you want to aim for minimal number of characters, then you can simplify the solution posted by Ganesh to something like this:
let sum = list |> Seq.sumBy int
This does pretty much the same thing - the int function is a generic conversion that converts anything to an integer (and it works on strings too). The sumBy function is a combination of map and sum that first projects all elements to a numeric value and then sums the results.
Something like this should have the same effect:
let sum = list |> Seq.map System.Int32.Parse |> Seq.sum
F# doesn't seem to support referring to the method on int so I had to use System.Int32 instead.
In F# the type seq is an alias for the .NET IEnumerable, so this code works on arrays, lists etc.
Note the use of Parse in "point-free" style - a function without its argument can be used directly as an argument to another function that expects that type. In this case Seq.map has this type:
('a -> 'b) -> seq<'a> -> seq<'b>
And since System.Int32.Parse has type string -> int, Seq.map System.Int32.Parse has type seq<string> -> seq<int>.
Technically, there are at least 3 different approaches:
1) The Seq.sum or sumBy approach described in the other answers is the canonical way of getting the sum in F#:
let sum = Seq.sumBy int list
2) For instructional purposes, it may be interesting to see how closely one can simulate C# behavior in F#; for instance, using a reference cell type:
let inline (+=) x y = x := !x + y
let sum = ref 0
for s in list do sum += int s
3) Same idea as 2), but using a byref pointer type:
let inline (+=) (x:_ byref) y = x <- x + y
let mutable sum = 0
for s in list do &sum += int s
I have a list of functions in F# which are all of type (float -> float -> float -> float). I want to do some kind of fold on the sequence to get a single function which returns the sum of all of the functions.
For instance, I could pass the values 1.0, 2.0, and 3.0 to every function in the list, and get a return value from each one. Then I could compute the sum of all of these values. However, I want to generalize this.
I know how to do this recursively, but I feel like it should be doable in one line. Is there a concise way to accomplish this task?
The solution by #Lee is a one liner you're looking for. If you wanted to save a few characters, you can use List.sumBy which first applies a given function to an element of the list (similar to List.map) and then sums the result (just like List.sum):
let sumAll (fs:(_ -> _ -> _ -> float) list) a b c =
List.sumBy (fun f -> f a b c) fs
Both this and Lee's version uses type annotations to specify that the functions in the list return float. This is needed, because otherwise the compiler does not know what kind of numbers you want to sum using List.sum (floats, integers, etc.). This ambiguity needs to be resolved to compile the function.
Alternatively, you could mark the function as inline and then it would be inlined when you call it (and it would work for multiple different numeric types). You can also pass the fs parameter as the last one and use partial function application:
let inline sumAll a b c = List.sumBy (fun f -> f a b c)
Now you can call it using pipelining as follows: fs |> sumAll 1 2 3.
let sumAll (fs: (float -> float -> float -> float) list) a b c = List.map (fun f -> f a b c) fs |> Seq.sum
The answers by #Lee and #Tomas are great, but there is a shorter way.
If you can afford passing (a, b, c) as a triple upon invocation:
let inline sumAll() = (|||>) >> List.sumBy
// usage
let predicates =
[
fun a b c -> a
fun a b c -> b * 42.0 - c
]
let ret1 = predicates |> sumAll()(1.0, 2.0, 3.0)
It will be also generic:
let predicates2 =
[
fun a b c -> c - 10
fun a b c -> a + c * 42
]
let ret2 = predicates2 |> sumAll()(1, 2, 3)
A more readable way which supports curried arguments:
let sumAllCurried a b c = (a,b,c) |> (|||>) |> List.sumBy<_, float>
// usage
let ret3 = predicates |> sumAllCurried 1.0 2.0 3.0
Note, I'm using a type parameter on List.sumBy since it looks shorter than typing an entire type specification for f.
I have three functions that ought to be equal:
let add1 x = x + 1
let add2 = (+) 1
let add3 = (fun x -> x + 1)
Why do the types of these methods differ?
add1 and add3 are int -> int, but add2 is (int -> int).
They all work as expected, I am just curious as to why FSI presents them differently?
This is typically an unimportant distinction, but if you're really curious, see the Arity Conformance for Values section of the F# spec.
My quick summary would be that (int -> int) is a superset of int -> int. Since add1 and add3 are syntactic functions, they are inferred to have the more specific type int -> int, while add2 is a function value and is therefore inferred to have the type (int -> int) (and cannot be treated as an int -> int).
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.
this simple function:
let sum a b = a + b
will work only for int types
how to make it so that it would also work for float and long ?
Use inline:
let inline sum a b = a + b
UPDATE:
If you're interested in writing your own polymorphic numerical functions, you should use both inline and LanguagePrimitives module.
Here is a polymorphic cosine function from the thread Converting Haskell Polymorphic Cosine function to F#:
let inline cosine n (x: ^a) =
let one: ^a = LanguagePrimitives.GenericOne
Seq.initInfinite(fun i -> LanguagePrimitives.DivideByInt (- x*x) ((2*i+1)*(2*i+2)))
|> Seq.scan (*) one
|> Seq.take n
|> Seq.sum
The example function you give only works for int types because of type inference; the type inference mechanism will automatically infer int because it sees the addition. If you want to make the same function for float and long, you'd either do inline as Pad has said or you could do this:
let sumFloat (a:float) b = a + b
let sumLong (a:int64) b = a + b
But inline is the right mechanism to get the generic "any type that supports addition" behavior that you're looking for.
let f g x y = g x y
f (+) 0.0 1.0;;
f (=) 0 1;;
I like this solution as well.