F# Immutability, pure function and side effect -
i'm new f# , i'm coding little challenges learn nitty-gritty details language. think have problem because of immutability.
scenario: have read height lines in console, each line contains 1 integer. integer represent size of mountain. after reading input need write line number of highest mountains. if index given highest mountain size set 0 else loose. repeat scenario until mountains have size set zero.
here code wrote:
open system type mountain = {id:int; height:int} let readlineint() = int(console.in.readline()) let readmountaindata id = {id = id; height = readlineint()} let readallmountainsdata = [ in 0 .. 7 yield readmountaindata ] let rec mainloop () = let mountains = readallmountainsdata let highestmountain = mountains |> list.maxby (fun x -> x.height) printfn "%i" highestmountain.id mainloop() mainloop()
this code going infinite loop, believe it's because
let readlineint() = int(console.in.readline())
is immutable, value set once , after it's never stop again read line. try put 'mutable' keyword
let mutable readallmountainsdata = [ in 0 .. 7 yield readmountaindata ]
but didn't change thing. have idea?
edit: know code going infinite loop because after adding logging main loop follow:
let rec mainloop () = let mountains = readallmountainsdata console.error.writeline("mountain count:{0} ", mountains.length) mountains |> list.iter (fun x -> console.error.writeline("mountain id:{0} height:{1}", x.id, x.height)) let highestmountain = mountains |> list.maxby (fun x -> x.height) printfn "%i" highestmountain.id mainloop()
then have in output:
standard error stream: mountain count:8 mountain id:0 height:9 mountain id:1 height:8 mountain id:2 height:7 mountain id:3 height:6 mountain id:4 height:5 mountain id:5 height:4 mountain id:6 height:3 mountain id:7 height:2 mountain count:8 mountain id:0 height:9 mountain id:1 height:8 mountain id:2 height:7 mountain id:3 height:6 mountain id:4 height:5 mountain id:5 height:4 mountain id:6 height:3 mountain id:7 height:2 mountain count:8 mountain id:0 height:9 mountain id:1 height:8 mountain id:2 height:7 etc...
why want reread value? because values provided external source. workflow follow:
loop one: read 8 values height of mountains in console output value of highest mountain loop two: read 8 values height of mountains in console output value of highest mountain loop three: read 8 values height of mountains in console output value of highest mountain etc
let readlineint () = ...
defines function. it's body executed every time call it. , in case body has side-effect , side-effect (reading stdin) executed every time body executed. that's not problem.
readallmountainsdata
defined list containing data of 7 mountains. each of mountains have own height (because readlineint()
called once each mountain). list calculated once , not change after that. not re-calculated every time use readallmountainsdata
variable, not function (even though name might suggest otherwise). seems sensible re-reading mountain data every time make no sense.
adding mutable
keyword definition allows re-assign variable. is, allows write readallmountainsdata <- somenewvalue
later in program change variable's value. since never that, nothing changes.
the reason program loops infinitely mainloop
calls again. has no exit condition. fix should decide how want loop / under condition want exit, , implement logic accordingly.
in edit clarified, want re-read values, need make readallmountainsdata
function giving parameter list (let readallmountainsdata () = ...
) , call function. way you'll new data on each iteration, loop still infinite unless add exit condition.
Comments
Post a Comment