Why I can't bind (**) operator - f#

In f# i can easily bind (+) or (*) operators. Why can't I do the same with (**)?
> let s = (+);;
val s : (int -> int -> int)
> let f = (**);;
let f = (**);;
------------^^
C:\Users\mqrx84\AppData\Local\Temp\stdin(4,13): error FS0010: Incomplete structured construct at or before this point in binding

Because (* *) are used for multi line comments. You need to separate the parentheses from the operator with whitespace e.g. let f = ( ** );;
To define other operators that begin with *, whitespace must follow
the opening parenthesis; otherwise (* is interpreted as the start of a
comment: let ( *+* ) x y = (x + y)
From the spec - http://fsharp.org/specs/language-spec/

Related

F# custom operator with 3 parameters

I found the following piece of code in the fantomas library for F#. I am having a hard time understanding this as an F# noob. From what I understand, it's a custom operator that takes 3 arguments, but why would an operator need 3 arguments? And what exactly is happening here?
/// Function composition operator
let internal (+>) (ctx: Context -> Context) (f: _ -> Context) x =
let y = ctx x
match y.WriterModel.Mode with
| ShortExpression infos when
infos
|> Seq.exists (fun x -> x.ConfirmedMultiline)
->
y
| _ -> f y
Here's an example of how fantomas uses this operator in ther CodePrinter module.
let short =
genExpr astContext e1
+> sepSpace
+> genInfixOperator "=" operatorExpr
+> sepSpace
+> genExpr astContext e2
Operators behave a lot like function names:
let (++) a b c d =
a + b + c + d
(++) 1 2 3 4
One difference is that operators can be used infix. An operator with more than 2 arguments allows infix only for the first 2 arguments:
// the following is equal:
let f = (++) 1 2 // like a function name
let f = 1 ++ 2 // with infix
f 50 60
I did not find how fantomas uses the operator you mention, would be curious, in particular since fantomas is a high profile f# project.
It might be instructive to compare this to the regular function composition operator, >>. The definition for this is:
let (>>) (f : a' -> b') (g : b' -> c') (x : a') =
g ( f x )
Esentially, it applies f to x, and then applies g to the result.
If we have the following functions:
let plusOne i = i + 1
let timesTwo j = j * 2
And apply it the following way:
let plusOneTimesTwo = plusOne >> timesTwo
What we're really doing is something like this:
let plusOneTimesTwo = (>>) plusOne timesTwo
When you don't supply all of the necessary arguments to a function (in this case, x), what you get is a function that takes the remaining arguments and then returns what the original function would return (this is partial application.) In this case, plusOneTimesTwo's function signature is now x : int -> int.
The example you've listed is essentially the same thing, but it's performing additional logic to determine whether it wants to apply the second function to the result y or to return it as-is.

Desugared form of "let in"

What do the let (x = 0) in x * x translate to? A function (fun x -> x * x) 0) ? - This would make sense, as let bindings are expressions - and expressions must return values (just like functions).
Example:
let result1 =
(fun n1 -> (fun n2 ->
(fun n3 -> n1 + n2 + n3 ) 3) 2) 1
let result2 =
let n1 = 1 in
let n2 = 2 in
let n3 = 3 in
n1 + n2 + n3
let result3 =
let n1 = 1
let n2 = 2
let n3 = 3
n1 + n2 + n3
Am I right to assume that result3 is a sugared form of result2, and result2 a sugared form of result1?
Short: Do let in bindings translate to functions?
You can almost see let x = e1 in e2 as a syntactic sugar for (fun x -> e2) e1.
At the basic level, the two expressions mean the same thing - the compiler will probably compile them differently (depending on optimization levels and how it inlines things), but you could often use the second notation instead of the first one.
The one case where they differ is that ML-languages (including F#) only generalize function types written explicitly using the let keyword. This means that if you use fun, the language won't treat it as a generic function. If you want a generic function, you have to use let (and this is not just a compiler artifact, this is actually part of the language).
For example, the following uses let and it works:
let id = (fun x -> x) in ignore(id 1); ignore(id "A")
But the following does not work, because id is not a generic function:
(fun id -> ignore(id 1); ignore(id "A")) (fun x -> x)
The plain old let is just the lightweight syntax form of the verbose let … in.
From MSDN: Verbose Syntax (F#):
nested let bindings:
Lightweight syntax:
let f x =
let a = 1
let b = 2
x + a + b
Verbose syntax:
let f x =
let a = 1 in
let b = 2 in
x + a + b
The let bindings within these function don't translate to functions themselves, however. Both of these translate to identical CIL code:
f:
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldc.i4.1
IL_0003: add
IL_0004: ldc.i4.2
IL_0005: add
IL_0006: ret
Note that the only function here is the outer function f. The variables a and b are evaluated as constants within the scope of f.
let x = <val> in <expr> is functionally equivalent to (fun x -> <expr>) <val>.
<expr> is an expression
<val> is a value
The in keyword is optional.

Alternative approach to avoid "Incomplete pattern match" warning

I have written a function that takes an array as input and returns an array of equal size as output. For example:
myFunc [| "apple"; "orange"; "banana" |]
> val it : (string * string) [] =
[|("red", "sphere"); ("orange", "sphere"); ("yellow", "oblong")|]
Now I want to assign the results via a let binding. For example:
let [|
( appleColor, appleShape );
( orangeColor, orangeShape );
( bananaColor, bananaShape )
|] =
myFunc [| "apple"; "orange"; "banana" |]
Which works great...
> val orangeShape : string = "sphere"
> val orangeColor : string = "orange"
> val bananaShape : string = "oblong"
> val bananaColor : string = "yellow"
> val appleShape : string = "sphere"
> val appleColor : string = "red"
...except it produces a warning:
warning FS0025: Incomplete pattern matches on this expression. For example, the value '[|_; _; _; _|]' may indicate a case not covered by the pattern(s).
The source and reason for the warning has already been covered, I'm just looking for a succinct work-around. This function call occurs near the top of my function, and I don't like the idea of putting the entire function body inside a match:
let otherFunc =
match myFunc [| "apple"; "orange"; "banana" |] with
| [|
( appleColor, appleShape );
( orangeColor, orangeShape );
( bananaColor, bananaShape )
|] ->
// ... the rest of my function logic
| _ -> failwith "Something impossible just happened!"
That just smells bad. I don't like the idea of ignoring the warning either - goes against my better judgment. Are there any other options open to me, or do I just need to find a different approach entirely?
One possibility if you expect this kind of calling pattern to be frequent is to make wrappers that act on the sizes of tuples you expect, e.g.
myFunc3 (in1,in2,in3) =
match myFunc [|in1;in2;in3|] with
[|out1;out2;out3|] -> out1, out2, out3
_ -> failwith "Internal error"
etc. But all it does is move the ugly code to a standard place, and writing out the wrappers will be inconvenient.
I don't think there's any better option with this API, because there's no way to tell the compiler that myFunc always returns the same number of elements it is passed.
Another option might be to replace myFunc with an IDisposable class:
type MyClass() =
let expensiveResource = ...
member this.MyFunc(v) = ...calculate something with v using expensiveResource
interface IDisposable with
override this.Dispose() = // cleanup resource
and then use it in a block like
use myClass = new MyClass()
let appleColor, appleShape = myClass.MyFunc(apple)
...
Adapting #Ganesh's answer, here's a primitive way to approach the problem:
let Tuple2Map f (u, v)
= (f u, f v)
let Tuple3Map f (u, v, w)
= (f u, f v, f w)
let Tuple4Map f (u, v, w, x)
= (f u, f v, f w, f x)
Example:
let Square x = x * x
let (a,b) = Tuple2Map Square (4,6)
// Output:
// val b : int = 36
// val a : int = 16
But I guess something even more primitive would be this:
let Square x = x * x
let (a,b) = (Square 4, Square 6)
And if the function name is too long, e.g.
// Really wordy way to assign to (a,b)
let FunctionWithLotsOfInput w x y z = w * x * y * z
let (a,b) =
(FunctionWithLotsOfInput input1 input2 input3 input4A,
FunctionWithLotsOfInput input1 input2 input3 input4B)
We can define temporary function
let FunctionWithLotsOfInput w x y z = w * x * y * z
// Partially applied function, temporary function
let (a,b) =
let f = (FunctionWithLotsOfInput input1 input2 input3)
(f input4A, f input4B)

How to define x++ (where x: int ref) in F#?

I currently use this function
let inc (i : int ref) =
let res = !i
i := res + 1
res
to write things like
let str = input.[inc index]
How define increment operator ++, so that I could write
let str = input.[index++]
You cannot define postfix operators in F# - see 4.4 Operators and Precedence. If you agree to making it prefix instead, then you can define, for example,
let (++) x = incr x; !x
and use it as below:
let y = ref 1
(++) y;;
val y : int ref = {contents = 2;}
UPDATE: as fpessoa pointed out ++ cannot be used as a genuine prefix operator, indeed (see here and there for the rules upon characters and character sequences comprising valid F# prefix operators).
Interestingly, the unary + can be overloaded for the purpose:
let (~+) x = incr x; !x
allowing
let y = ref 1
+y;;
val y : int ref = {contents = 2;}
Nevertheless, it makes sense to mention that the idea of iterating an array like below
let v = [| 1..5 |]
let i = ref -1
v |> Seq.iter (fun _ -> printfn "%d" v.[+i])
for the sake of "readability" looks at least strange in comparison with the idiomatic functional manner
[|1..5|] |> Seq.iter (printfn "%d")
which some initiated already had expressed in comments to the original question.
I was trying to write it as a prefix operator as suggested, but you can't define (++) as a proper prefix operator, i.e., run things like ++y without the () as you could for example for (!+):
let (!+) (i : int ref) = incr i; !i
let v = [| 1..5 |]
let i = ref -1
[1..5] |> Seq.iter (fun _ -> printfn "%d" v.[!+i])
Sorry, but I guess the answer is that actually you can't do even that.

F# Checked Arithmetics Scope

F# allows to use checked arithmetics by opening Checked module, which redefines standard operators to be checked operators, for example:
open Checked
let x = 1 + System.Int32.MaxValue // overflow
will result arithmetic overflow exception.
But what if I want to use checked arithmetics in some small scope, like C# allows with keyword checked:
int x = 1 + int.MaxValue; // ok
int y = checked { 1 + int.MaxValue }; // overflow
How can I control the scope of operators redefinition by opening Checked module or make it smaller as possible?
You can always define a separate operator, or use shadowing, or use parens to create an inner scope for temporary shadowing:
let f() =
// define a separate operator
let (+.) x y = Checked.(+) x y
try
let x = 1 +. System.Int32.MaxValue
printfn "ran ok"
with e ->
printfn "exception"
try
let x = 1 + System.Int32.MaxValue
printfn "ran ok"
with e ->
printfn "exception"
// shadow (+)
let (+) x y = Checked.(+) x y
try
let x = 1 + System.Int32.MaxValue
printfn "ran ok"
with e ->
printfn "exception"
// shadow it back again
let (+) x y = Operators.(+) x y
try
let x = 1 + System.Int32.MaxValue
printfn "ran ok"
with e ->
printfn "exception"
// use parens to create a scope
(
// shadow inside
let (+) x y = Checked.(+) x y
try
let x = 1 + System.Int32.MaxValue
printfn "ran ok"
with e ->
printfn "exception"
)
// shadowing scope expires
try
let x = 1 + System.Int32.MaxValue
printfn "ran ok"
with e ->
printfn "exception"
f()
// output:
// exception
// ran ok
// exception
// ran ok
// exception
// ran ok
Finally, see also the --checked+ compiler option:
http://msdn.microsoft.com/en-us/library/dd233171(VS.100).aspx
Here is a complicated (but maybe interesting) alternative. If you're writing something serious then you should probably use one of the Brians suggestions, but just out of curiosity, I was wondering if it was possible to write F# computation expression to do this. You can declare a type that represents int which should be used only with checked operations:
type CheckedInt = Ch of int with
static member (+) (Ch a, Ch b) = Checked.(+) a b
static member (*) (Ch a, Ch b) = Checked.(*) a b
static member (+) (Ch a, b) = Checked.(+) a b
static member (*) (Ch a, b) = Checked.(*) a b
Then you can define a computation expression builder (this isn't really a monad at all, because the types of operations are completely non-standard):
type CheckedBuilder() =
member x.Bind(v, f) = f (Ch v)
member x.Return(Ch v) = v
let checked = new CheckedBuilder()
When you call 'bind' it will automatically wrap the given integer value into an integer that should be used with checked operations, so the rest of the code will use checked + and * operators declared as members. You end up with something like this:
checked { let! a = 10000
let! b = a * 10000
let! c = b * 21
let! d = c + 47483648 // !
return d }
This throws an exception because it overflows on the marked line. If you change the number, it will return an int value (because the Return member unwraps the numeric value from the Checked type). This is a bit crazy technique :-) but I thought it may be interesting!
(Note checked is a keyword reserved for future use, so you may prefer choosing another name)

Resources