Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

operators

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++]
like image 221
bohdan_trotsenko Avatar asked Apr 20 '12 20:04

bohdan_trotsenko


2 Answers

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.

like image 156
Gene Belitski Avatar answered Dec 08 '22 21:12

Gene Belitski


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.

like image 30
fpessoa Avatar answered Dec 08 '22 20:12

fpessoa