REVISED: Monday, October 21, 2024
Haskell Beginner Program Skeleton: "Read and Show" Tutorial.
I. EXAMPLE OF READ AND SHOW
A. SKELETON
-- IMPORTS
-- FUNCTIONS
-- MAIN PROGRAM
module ReadAndShow where
B. FLESH ON BONES
1. EXAMPLE
This example is intended to introduce you to input/output (IO).
The example is also a review for using:
if <condition> then <true-value> else <false-value>
Notice the type of the entire if/then/else construction in the example is IO ().
Use your editor to save the following ReadAndShow.hs file:
This example is intended to introduce you to input/output (IO).
The example is also a review for using:
if <condition> then <true-value> else <false-value>
Notice the type of the entire if/then/else construction in the example is IO ().
-- Module declaration.
module ReadAndShow where
-- import (No import required.)
-- Functions (No functions required.)
-- Main program
main :: IO ()
main = do
putStrLn "Please type any number then press Enter or type 0 and press Enter to exit."
inpStr <- getLine
-- Keyed input is stored as a String in inpStr
let inpDouble = (read inpStr) :: Double
-- read changes inpStr type from String to Double.
if inpDouble > 0
then do
putStrLn (show inpDouble ++ " multiplied by " ++ "2.0" ++ " is " ++ show (inpDouble * 2.0))
-- show changes inpDouble type from Double to String.
main
else return ()
2. LOAD EXAMPLE
As shown below, load the above ReadAndShow.hs file into GHCi:
As shown below, load the above ReadAndShow.hs file into GHCi:
PS C:\Users\User> ghci
GHCi, version 9.4.8: https://www.haskell.org/ghc/ :? for help
ghci> :cd C:\Users\User\tinnel\Haskell 2024\newProjects
ghci> :l ReadAndShow.hs
[1 of 1] Compiling ReadAndShow ( ReadAndShow.hs, interpreted )
Ok, one module loaded.
Now that we have loaded Main, we can run functions in GHCi that were defined in Main.
3. RUN EXAMPLE
As shown below, run the function main, in GHCi:
ghci> main
Please type a number then press Enter or type 0 and press Enter to exit.
2.0
2.0 multiplied by 2.0 is 4.0
Please type a number then press Enter or type 0 and press Enter to exit.
0
ghci>
4. COMPILE EXAMPLE
As shown below, compile ReadAndShow.hs in GHC:
Prelude> :! ghc --make "*ReadAndShow"
[1 of 1] Compiling Main ( ReadAndShow.hs, ReadAndShow.o )
Linking ReadAndShow.exe ...
Prelude>
The compile is shown so you know it compiles without error.
C. COMMENTS
Use the program shown above as an example. Rewrite the example and make it your own program.
Repeat 1. thru 3. above until your new program works the way you want it to work. Each time you make changes to your program's editor, save the file and load it in GHCi.
Notice a module begins with the keyword module and is followed by the module name which is followed by the keyword where.
module ReadAndShow where
Also observe that using the arrow instead of the equal sign in the example shown below shows that getLine is not a real function and can return different values. This command means run the action getLine, and store the results we take in inpStr. Understanding the reason behind the choice of the word action instead of function is very important for your understanding of input/output (IO).
Other comments regarding this tutorial are discussed below:
1. Double
Haskell has a static type system. Everything in Haskell has a type. Types are labels, values carry, so we can reason about the values. In GHCi, the :t command, followed by any valid expression, tells us its type. Doing :t on an expression prints out the expression followed by :: and its type. :: is read as "has the type of".
Types have their own labels, called kinds. A kind is the type of a type. We can examine the kind of a type by using the :kind or :k command in GHCi. A * means that the type is a concrete type. A concrete type is a type that does not take any type parameters. Values can only have types that are concrete types. A * is pronounced "star" or "type".
We can see what the instances of a typeclass are, by using the :info command in GHCi.
Double :: *
Prelude>
Prelude> :info Double
data Double = D# Double# -- Defined in `GHC.Types'
instance Enum Double -- Defined in `GHC.Float'
instance Eq Double -- Defined in `GHC.Classes'
instance Floating Double -- Defined in `GHC.Float'
instance Fractional Double -- Defined in `GHC.Float'
instance Num Double -- Defined in `GHC.Float'
instance Ord Double -- Defined in `GHC.Classes'
instance Read Double -- Defined in `GHC.Read'
instance Real Double -- Defined in `GHC.Float'
instance RealFloat Double -- Defined in `GHC.Float'
instance RealFrac Double -- Defined in `GHC.Float'
instance Show Double -- Defined in `GHC.Float'
Prelude>
2. read
Types are written in a capital case, so the a shown in the examples below cannot be a type. Since they are not in capital case they are actually type variables. That means that they can be of any type. Functions that have type variables are called polymorphic functions.
Prelude> :type read
read :: Read a => String -> a
Prelude>
Prelude> :info read
Prelude> :info read
read :: Read a => String -> a -- Defined in `Text.Read'
Prelude>
The function read casts type String to another type.
3. show
Prelude> :type show
show :: Show a => a -> String
Prelude>
Prelude> :info show
Prelude> :info show
class Show a where
...
show :: a -> String
...
-- Defined in `GHC.Show'
Prelude>
The function show casts a type to a readable type String.
Think of read and show as opposites: show lets you convert to String, and read converts from String.
4. :: type annotation
let inpDouble = (read inpStr)::Double
Type annotation is a way of explicitly saying what the type of an expression should be. We do that by adding :: at the end of the expression and then specifying a type.
II. CONCLUSION
In this tutorial, you have received an introduction to the Haskell beginner program skeleton "read and show" module.
III. REFERENCES
Bird, R. (2015). Thinking Functionally with Haskell. Cambridge, England: Cambridge University Press.
Davie, A. (1992). Introduction to Functional Programming Systems Using Haskell. Cambridge, England: Cambridge University Press.
Goerzen, J. & O'Sullivan, B. & Stewart, D. (2008). Real World Haskell. Sebastopol, CA: O'Reilly Media, Inc.
Hutton, G. (2007). Programming in Haskell. New York: Cambridge University Press.
Lipovača, M. (2011). Learn You a Haskell for Great Good!: A Beginner's Guide. San Francisco, CA: No Starch Press, Inc.
Thompson, S. (2011). The Craft of Functional Programming. Edinburgh Gate, Harlow, England: Pearson Education Limited.