Added explanation of guess number

This commit is contained in:
Yann Esposito (Yogsototh) 2018-06-29 09:46:07 +02:00
parent ec443f0b85
commit 7f58cb3285
Signed by untrusted user who does not match committer: yogsototh
GPG key ID: 7B19A4C650D59646
2 changed files with 83 additions and 3 deletions

View file

@ -550,10 +550,50 @@ guessNum nbTry nbToFound = do
guessNum (nbTry + 1) nbToFound guessNum (nbTry + 1) nbToFound
#+END_SRC #+END_SRC
#+BEGIN_COMMENT Let's read the program line by line:
****** TODO Let's explain each line of the that function.
#+END_COMMENT
- ~putText "What is your guess?"~ should be straightforward.
- ~answer <- getLine~ So the ~getLine~ read from standard input and returns the
line entered by the user. The line will be put in the ~answer~ variable.
- ~let guessedNumber = readMaybe (toS answer)~: there are a few things to tell about this line.
If you open GHCI and ask the type for each interresting symbol here is what you get:
#+BEGIN_SRC
λ :t getLine
getLine :: IO Text
λ :t toS
toS :: StringConv a b => a -> b
λ :t readMaybe
readMaybe :: Read a => GHC.Base.String -> Maybe a
#+END_SRC
- ~answer~ comes from ~getLine :: IO Text~ so ~answer~ should have the type ~Text~.
- Now we want to read this ~Text~ and see if this is a number and compare it to another ~Int~.
- To transform the number we don't use a function ~textToInt~ we simply use a
quite generic function ~readMaybe~ that take some ~String~ and try to
transform that to some type. For our specific case, the compiler is able to
figure out the type we want to transform the text into is ~Int~. Take the
time to digest that: ~Int~ is specified in the type signature of the
~guessNum~ function so the compiler could discover that ~readMaybe~ should
return a ~Maybe Int~. How does he do that? Let's follow:
1. see a ~n == nbToFound~ so we can deduce ~n~ and ~nbToFound~ have the same type.
2. Reading the type signature of the function it is clear ~nbToFound~ is of
type ~Int~ (it's the second argument of a function with type ~Int -> Int -> IO ()~)
3. Then ~n~ is generated from a pattern matching; the case ~Just n~ which
could be the the result of the ~readMaybe~ function. So we can deduce
that the ~a~ in the type signature of ~readMaybe~ is ~Int~ for this specific case.
- so ~guessedNumber :: Maybe Int~, if the user enter something that cannot be
transformed in number from a string then ~guessedNumber~ would be equal
to ~Nothing~ and we ask the user to enter a number. If the user entered a
number the type will be ~Just n~ were ~n~ will be an ~Int~.
- We compare the ~guessedNumber~ to the number to found ~nbToFound~.
- If the user found the right number we stop here by displaying the number of try.
- If the user hasn't found the number, depending on its value we tell the user
it's either too low or too high and we call the same function, this time, we
increment the number of try.
The full program is then: The full program is then:
@ -718,6 +758,28 @@ to use a library to parse options.
For that we will use the =optparse-generic= package. For that we will use the =optparse-generic= package.
#+BEGIN_SRC haskell :tangle code/optparse_1.hs
#!/usr/bin/env stack
{- stack script
--resolver lts-11.6
--install-ghc
--package protolude
--package optparse-generic
-}
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE OverloadedStrings #-}
import Protolude
import System.Environment (getArgs)
main :: IO ()
main = do
arguments <- getArgs
case head arguments of
Just filename -> die ("The first argument is: " <> toS filename)
Nothing -> die "Please enter a filename"
#+END_SRC
*** TODO File Access *** TODO File Access
*** TODO Daemons & Logging *** TODO Daemons & Logging
** TODO Intermediate ** TODO Intermediate

18
code/optparse_1.hs Executable file
View file

@ -0,0 +1,18 @@
#!/usr/bin/env stack
{- stack script
--resolver lts-11.6
--install-ghc
--package protolude
--package optparse-generic
-}
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE OverloadedStrings #-}
import Protolude
import System.Environment (getArgs)
main :: IO ()
main = do
arguments <- getArgs
case head arguments of
Just filename -> die ("The first argument is: " <> toS filename)
Nothing -> die "Please enter a filename"