Added explanation of guess number
This commit is contained in:
parent
ec443f0b85
commit
7f58cb3285
2 changed files with 83 additions and 3 deletions
|
@ -550,10 +550,50 @@ guessNum nbTry nbToFound = do
|
|||
guessNum (nbTry + 1) nbToFound
|
||||
#+END_SRC
|
||||
|
||||
#+BEGIN_COMMENT
|
||||
****** TODO Let's explain each line of the that function.
|
||||
#+END_COMMENT
|
||||
Let's read the program line by line:
|
||||
|
||||
- ~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:
|
||||
|
||||
|
@ -718,6 +758,28 @@ to use a library to parse options.
|
|||
|
||||
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 Daemons & Logging
|
||||
** TODO Intermediate
|
||||
|
|
18
code/optparse_1.hs
Executable file
18
code/optparse_1.hs
Executable 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"
|
Loading…
Reference in a new issue