F# function parameter datatype - f#

This is the first line of F# that I've tried writing, so apologies because I probably just don't know the right Google keywords to search.
I tried defining a function like so:
let sigmoid x deriv = if deriv then x * (1 - x) else 1 / (1 + System.Math.Exp(-x))
This gives me an error on the System.Math.Exp(-x):
The type 'float' does not match the type 'int'
I guess I was expecting the compiler to do type inference on this function and define x as a float. What am I missing here?
Here is the whole thing that I'm trying to plug in:
let sigmoid x deriv = if deriv then x * (1 - x) else 1 / (1 + System.Math.Exp(-x))
[<EntryPoint>]
let main argv =
sigmoid 1.0 false |> printfn "%A"
0

The compiler infers x as int, because you used it in things like 1 - x. A simple 1 will always be an integer, and you can only use it in arithmetic expressions together with other integers. Your code compiles if you change all your usages of 1 to 1.0, which will make it a float and cause x to be inferred as a float as well.
This is different from C#, for example, which will coerce the types if necessary and thus allow for mixing integers and floating point numbers in the same expressions. That can lead to an accidental loss of precision under certain circumstances, though, while F# always forces you to state any necessary conversions explicitly.

Related

Ocaml "longest match" rule : "minus" operator parsed as binary or unary

The function I have:
let increment n = n+1;;
My call to the function:
let x = increment -5;;
The error I get:
let x = increment -5;;
^^^^^^^^^
Error: This expression has type int -> int
but an expression was expected of type int`
Why doesn't x = -4 after the function call?
I tried finding the answer myself and I ended up here:
http://caml.inria.fr/pub/docs/manual-ocaml-4.00/lex.html#prefix-symbol
The term "longest match rule" is used in the section Ambiguities, I assume that a clarification of that term would solve my issue?
The problem is easy, - is considered here as the binary operator minus so OCaml is reading it as increment minus 5 (increment and 5 are the two operands) when what you'd want is increment the number (minus 5) (increment being a function).
Just write increment (-5) and the job's done.
An alternative to using parentheses, as suggested in the other answer, is to use the ## application operator, e.g.:
let increment n = n + 1
let x = increment ## -5
Briefly, f ## x is the same as f x, but the ## operator has lower precdence than arithmetic operations, while function application has higher precedence. Thus, using the application operator allows you to omit parentheses.
Sometimes, the reverse application operator |> can be more idiomatic; it is typically used to "pipe" an expression through one or more function applications.
Example:
let increment n = n + 1
let x = -5 |> increment
let clamp x low high = x |> min high |> max low

Creating a function that works for all numeric primitives [duplicate]

This question already has answers here:
How to write a function for generic numbers?
(5 answers)
Closed 8 years ago.
I am writing an assembly with some functionality that is intended to work with numeric primitives, i.e. float, int, decimal, etc.
One of the functions takes two sequences and calculates the running average of the two. An implementation for floats may look like this
let average x y = (x+y)/2.
let a = [1..10] |> List.map float
let b = List.rev [1..10] |> List.map float
let result = (a, b) ||> List.map2 average
How can I make this generic for numeric primitives?
F# has so called "static member constraints" that can be used for writing generic numerical code. This is limited to F# (because .NET has no concept like this).
In general, you need to mark the function as inline. This will make the standard operators inside the function behave as generic. In addition, you need to avoid using constants (like 2.0). You can typically replace them with some operation from the LanguagePrimitives module. For example, your average function can be written as generic using:
let inline average x y =
LanguagePrimitives.DivideByInt (x + y) 2
For more information check out this blog post about generic numeric computations in F#.

Mutually recursive definition in OCaml

I know that OCaml provide the let rec ... and ... for definition of mutually recursive function. Why I can't use that expression for define mutually recursive value?
In particular, why I can't do something like let rec x=3 and y=x+5 in x but I can do let rec x=3 and y=[x;4] in y?
For the first case, I've try to give me an answer and I think that is a binding "problem", since the binding of the values should be simultaneous, so y can't know the value of x so I can't add it to the value of the constant 5.
It is true?
Neither of your definitions are mutually recursive. You could just as well write them like this:
let x = 3 in
let y = x + 5 in
x
and
let x = 3 in
let y = [x; 4] in
y
Mutually recursive definitions would look like this:
let rec x = y + 3
and y = x + 5 in
x
and
let rec x = 3 :: y
and y = 4:: x in
x
In the second piece of code x is a cyclic list that contains a 3 followed by a 4 and then loops back to the beginning. However the first piece of code doesn't make any sense. How can x equal y + 3 when y equals x + 5? It can't and therefore recursive values can only be defined using constructors of variant types (because that's the only case where a recursive value would not lead to infinite recursion).
So since recursive values can't be defined without constructors and the let rec ... and syntax is not necessary when the value you're trying to define is not recursive, the syntax simply can not be used with anything but constructor applications.

f# idiomatic type resolution solution for resolving to the wrong type

I'm just getting started with F# but I have some code that is analogous to the following:
let square x = x*x
let result = square 5.1
let result' = square 12
Unfortunately, this results in the following error: This expression was expected to have type float but here has type int
Is there an idiomatic F# solution to this problem, or is my thinking being tainted by my C# experience?
Just write it like that:
let inline square x = x * x
Otherwise, after first time you used that square function, it type was inferred to be float -> float. Hence, and given that F# does not do automatic conversion from int to float, you receive an error.
So, if you don't want to use inline, the simplest solution is to write
let result' = square (float 12)
It is simple and yet readable.
For more advanced solutions please take a look at this: Does F# have generic arithmetic support?
But those solutions are (imho) incomprehensible.
let inline square x = x * x
let result = square 5.1
let result' = square 12
printfn "%f" result
printfn "%d" result'
There's a whole article by Tomas Petricek on this subject:
http://tomasp.net/blog/fsharp-generic-numeric.aspx/

Why isn't it possible to use the same function twice with differently typed arguments?

I played around a little with F# today, wrote this:
let sq x = x * x
let i = sq 3
let d = sq 3.0
It compiles if I remove either the third or the fourth line, but not if both are present.
I get the error This expression should have type 'int', but has type 'float'.
The type inference works so that your function sq has type int -> int, because the first time compiler sees you use that function, you pass it an integer. So it assumes that sq is a function that takes an integer, and by definition of the function (x * x) it also returns an integer.
It is a bit complicated to define a fully generic arithmetic function in F#, but one way to do it is to make the function inline, like so:
let inline sq x = x * x
This way the body of your function will be inlined each time at the call site, so using an inlined sq function will be the same as substituting it's body every time it's used.
This approach has it's drawbacks, and I think it will be interesting for you to see this question.
Let-bound functions cannot be overloaded. In your specific case, you could use inline, which inlines the function body at compile time and can therefore choose an appropriate implementation of *, e.g.
let inline sq x = x * x
The other answers are correct but they leave out an important part of the jigsaw: the fact that in F# there are no implicit conversions between, for example, ints and floats. This is the reason why your second call is in effect calling a different, non existent, overload with a float argument.
The function let sq x = x * x on default has type int -> int.
If you put it in the context of a let d = sq 3.0, F# compiler will infer its type as float -> float.
In any way, this function can have only one type signature, either int->int, or float->float.
This is a limitation in how the bindings are implemented. There are 2 alternatives.
Firstly, add inline to the declaration.
Secondly, use member bindings in a class and override the different types.

Resources