Your example contains a few things that would work differently in a functional language:
- The class is mutable - in functional languages, you would use an immutable type
- You're using
current_time
to get the current time, but this is not a pure function (it depends on some global changing state). In pure functional languages (Haskell), this is not allowed (and you have to use monads), but most of the impure functional languages (F#, OCaml) allow this.
- Your
main
function uses a loop - loops are generally discouraged in functional languages (although some support them).
The idiomatic F# solution would deal with the first and the last point like this:
let currentTime() =
System.DateTime.Now
type State(startTime) =
static member Start() =
State(currentTime())
member x.IsCompleted =
(currentTime() - startTime).TotalSeconds > 30.0
member x.Progress =
(currentTime() - startTime).TotalSeconds / 30.0
let main() =
let s = State.Start()
let rec loop () =
if not s.IsCompleted then
printf "%A" s.Progress
loop ()
loop ()
printf "finished"
The type State
is immutable in the sense that it never changes the value of its local field. It is not purely functional, because it depends on the (changing) current time, but that's not a problem in F# (you just have to be aware of that). If you needed some method that modifies the state (which you don't) then the method would return a new instance of State
(just like .NET string
).
The main
function is written using recursion instead of a loop - in this case, it doesn't really matter (loop would be fine in F# too). The point of using a recursion is that you could pass the current state as an argument and use a new instance when making a recursive call (which essentially changes the current state during the computation).