Program layout
For output, use printf
and printfn
.
If you don't need to read input, you can just write top-level statements:
for i=1 to 10 do printfn"Hello, world! %i"i
Otherwise, you have to (quite vexingly) annotate a Array<string> -> int
function definition with [<EntryPoint>]
.
// This is almost the shortest…
[<EntryPoint>]let m a=
for x in a do printfn"%s"x
0
// This saves a byte! But you can't use "let" as easily in a one-liner like this.
[<EntryPoint>]let m a=[for x in a->printfn"%s"x];0
Printing a bunch of hardcoded small numbers
Try some variation on this:
Seq.iter(printfn"%i")"data_here_123"B
"..."B
is a byte[] literal. You can actually put Unicode up to U+00FF in there.
Conditional output
if x<5 then printfn"%i"x
x<5&&()=printfn"%i"x // compare the `unit` result of printfn to `() : unit` to make a `bool`!
x<5&()=printfn"%i"x // honestly no idea why this works (causes a warning)
Defining operators
As in Haskell, this is often shorter than giving helper functions alphabetic names.
You can overwrite any operator and steal its precedence! Pick one that saves parens. You can even redefine unary plus (~+)
etc.
let(%)=max
printfn"%A"((3+4)%5)
let(-)=max
printfn"%A"(3+4-5)
Mutation
Either use ref
or let mutable
:
Operation |
ref |
let mutable |
Creation |
let x=ref 1 |
let mutable x=1 |
Multiple creation |
let x,y=ref 1,ref 2 |
let mutable x,y=1,2 |
Type |
int ref |
int |
Access |
!x |
x |
Modification |
x:=2 |
x<-2 |
Arrays are always mutable, so let x=[|1|]
followed by x.[0]<-2
also works.
Of course, also consider the more "FP golf" tricks making your state variable the accumulator of a Seq.fold
or an argument of let rec(%)
, which is often shorter.
let mutable a=1for i in 1..5 do printfn"hey %i"a;a<-a*2
let a=ref 1for i in 1..5 do printfn"hey %i"!a;a:=!a*2
let rec(=)a i=printfn"hey %i"a;i<5&a*2=i+11=1
Seq.fold(fun a _->printfn"hey %i"a;a*2)1[1..5]