Skip to content

Instantly share code, notes, and snippets.

@KoviRobi
Last active August 29, 2015 14:27
Show Gist options
  • Save KoviRobi/6b1c5c85c5458e0baf3d to your computer and use it in GitHub Desktop.
Save KoviRobi/6b1c5c85c5458e0baf3d to your computer and use it in GitHub Desktop.
open System;
(* The type
'a IsoRec record
is the same as
type 'a isorec_record = Roll of { n : int; a : int; b : int; f : 'a isorec_record -> 'a }
but apparenty that way of specifying types is deprecated
*)
type 'a record = { n : int; a : int; b : int; f : 'a }
type 'a IsoRec = Roll of ('a IsoRec record -> 'a)
let unroll (Roll a) = a
let make_rec n =
{ n=n
; a=0
; b=1
; f=Roll
(function tup ->
if tup.n = 0
then tup.a
else unroll tup.f { n=tup.n-1
; a=tup.a+tup.b
; b=tup.a
; f=tup.f})
}
[<EntryPoint>]
let main argv =
printf "Which fibonacci number would you like? "
(* Make the record
The function "(|>)" (parentheses are used to denote that it is infix)
is the application operator with the arguments taken in the other order,
that is
"foo" |> Console.Write
is the same as
Console.Write "foo"
*)
let record = Console.ReadLine () |>
int |>
make_rec
printfn "%d" (unroll record.f record) (* Evaluate the record *)
Console.ReadLine () |> ignore (* Just so that we don't close *)
0 (* Return an integer exit code *)
(* P.S.: One of the cool things about ML (F#) is that comments can be nested
so you can do this: (* *), whereas /* /* */ */ would not work in C, as the first
"*/" would end the comment, not the second one.
*)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment