Simple Haskell program not behaving correct -


i'm new haskell , trying write simple program find maximal element , it's index intput. receive values compare 1 one. maximal element i'm holding in maxi variable, it's index - in maxidx. here's program:

loop =     let maxi = 0     let maxidx = 0     let idx = 0     let idxn = 0     replicatem 5 $         input_line <- getline         let element = read input_line :: int          if maxi < element                      let maxi = element             let maxidx = idx             hputstrln stderr "inner check"         else             hputstrln stderr "outer check"          let idx = idxn + 1         let idxn = idx          print maxidx      loop 

even though know elements coming starting bigger smaller (5, 4, 3, 2, 1) program enters inner check time (it should happen first element!) , maxidx 0. doing wrong? in advance.

anyway, let's have fun.

loop =     let maxi = 0     let maxidx = 0     let idx = 0     let idxn = 0     replicatem 5 $         input_line <- getline         let element = read input_line :: int          if maxi < element                      let maxi = element             let maxidx = idx             hputstrln stderr "inner check"         else             hputstrln stderr "outer check"          let idx = idxn + 1         let idxn = idx          print maxidx      loop 

is not particularly haskelly code (and know not particularly correct).

let's make if haskellier.

what here? we've infinite loop, reading line 5 times, it, , calls again no particular reason.

let's split it:

import control.monad  readfivelines :: io [int] readfivelines = replicatem 5 readln  addindex :: [int] -> [(int, int)] addindex xs = zip xs [0..]  findmaxindex :: [int] -> int findmaxindex xs = snd (maximum (addindex xs))  loop :: () loop = loop  main :: io () main = xs <- readfivelines           putstrln (show (findmaxindex xs)) 

snd returns second element tuple; readln read . getline; zip takes 2 lists , returns list of pairs; maximum finds maximum value.

i left loop intact in original beauty.

you can haskellier if remember something (huge expression) can replaced something $ huge expression ($ applies left operand right operand), , functions can combined .: f (g x) same (f . g) x, or f . g $ x (see? it's working left side well!). additionally, zip x y can rewritten x `zip` y

import control.monad  readfivelines :: io [int] readfivelines = replicatem 5 readln  addindex :: [int] -> [(int, int)] addindex = (`zip` [0..])  findmaxindex :: [int] -> int findmaxindex = snd . maximum . addindex  main :: io () main = xs <- readfivelines           putstrln . show . findmaxindex $ xs 

as debug print, there's package called debug.trace , function traceshow prints first argument (formatted show, hence name) stderr, , returns second argument:

findmaxindex :: [int] -> int findmaxindex = snd . (\xs -> traceshow xs (maximum xs)) . addindex 

that allows tap onto expression , see what's coming in (and values around — can show tuples, lists, etc.)


Popular posts from this blog

php - How should I create my API for mobile applications (Needs Authentication) -

5 Reasons to Blog Anonymously (and 5 Reasons Not To)

Google AdWords and AdSense - A Dynamic Small Business Marketing Duo