Showing posts with label GHCi. Show all posts
Showing posts with label GHCi. Show all posts

Thursday, January 19, 2017

HASKELL AND YOUR AGE BY CHOCOLATE

HASKELL AND YOUR AGE BY CHOCOLATE

REVISED: Saturday, October 5, 2024


1. INTRODUCTION

This tutorial is for having fun with Haskell.

2. HASKELL PROGRAM

The Haskell program is as follows:

-- C:\Users\Tinnel\Haskell2024\age.hs

import Data.List
import System.IO

main :: IO ()  -- Has type I/O action.
main = do {  putStrLn ""  -- putStrLn Has type I/O action.
           ; putStrLn "=========================================================="
           ; putStrLn ""
           ; putStrLn "CALCULATING YOUR AGE BY CHOCOLATE!"
           ; putStrLn ""
           ; putStrLn "First, type a positive integer from 1 to 10 indicating how"
           ; putStrLn "often you crave chocolate each week, then press Enter."
           ; cewS <- getLine -- getLine is a function, getLine :: IO String
           ; putStrLn ""
           ; let runTot1I = (read cewS)::Integer
           ; let runTot1S = show runTot1I
           ; putStrLn ("Running Total: " ++ runTot1S)
           ; putStrLn ""
           ; putStrLn "=========================================================="
           ; putStrLn ""
           ; let cewI = (read cewS)::Integer
           ; let cewIx2I = cewI * 2
           ; let cewIx2S = show cewIx2I
           ; putStrLn ("Second, we multiply " ++ cewS ++ " by 2 which equals " ++ cewIx2S ++ ".")
           ; putStrLn ""
           ; let runTot2I = runTot1I * 2
           ; let runTot2S = show runTot2I
           ; putStrLn ("Running Total: " ++ runTot2S)
           ; putStrLn ""
           ; putStrLn "=========================================================="
           ; putStrLn ""
           ; let cewIp5I = cewIx2I + 5
           ; let cewIp5S = show cewIp5I
           ; putStrLn ("Third, we add 5 to our running total which equals " ++ cewIp5S ++ ".")
           ; putStrLn ""
           ; let runTot3I = runTot2I + 5
           ; let runTot3S = show runTot3I
           ; putStrLn ("Running Total: " ++ runTot3S)
           ; putStrLn ""
           ; putStrLn "=========================================================="
           ; putStrLn ""
           ; let cewIp5x50I = cewIp5I * 50
           ; let cewIp5x50S = show cewIp5x50I
           ; putStrLn ("Fourth, we multiply our running total by 50 which equals " ++ cewIp5x50S ++ ".")
           ; putStrLn ""
           ; let runTot4I = runTot3I * 50
           ; let runTot4S = show runTot4I
           ; putStrLn ("Running Total: " ++ runTot4S)
           ; putStrLn ""
           ; putStrLn "=========================================================="
           ; putStrLn ""
           ; putStrLn "Fifth, type the current year date as a positive integer; e.g., 2017"
           ; putStrLn "then press Enter."
           ; yearS <- getLine -- getLine is a function, getLine :: IO String
           ; putStrLn ""
           ; putStrLn ("Running Total: " ++ runTot4S)
           ; putStrLn ""
           ; putStrLn "=========================================================="
           ; putStrLn ""
           ; let yearI = (read yearS)::Integer
           ; let runTotI = cewIp5x50I + (yearI - 250)
           ; let runTotS = show runTotI
           ; putStrLn "Sixth, we subtract 250 from the current year; e.g., 2017 - 250 = 1767"
           ; putStrLn ("and add the result to our running total which equals " ++ runTotS ++ ".")
           ; putStrLn ""
           ; let runTot6I = runTot4I + (yearI - 250)
           ; let runTot6S = show runTot6I
           ; putStrLn ("Running Total: " ++ runTot6S)
           ; putStrLn ""
           ; putStrLn "=========================================================="
           ; putStrLn ""
           ; putStrLn "Seventh, if you have not had your birthday this year type the integer 1."
           ; putStrLn "If you have had your birthday this year type zero; e.g., 0."
           ; putStrLn "Then press Enter."
           ; birthdayS <- getLine -- getLine is a function, getLine :: IO String
           ; putStrLn ""
           ; putStrLn ("Running Total: " ++ runTot6S)
           ; putStrLn ""
           ; putStrLn "=========================================================="
           ; putStrLn ""
           ; let birthdayI = (read birthdayS)::Integer
           ; let runTotMI = (runTotI - birthdayI)
           ; let runTotMS = show runTotMI
           ; putStrLn "Eighth, we subtract 1 or 0 from the running total."
           ; putStrLn ""
           ; putStrLn ("Now our running total equals " ++ runTotMS ++ ".")
           ; putStrLn ""
           ; let runTot8I = (runTot6I - birthdayI)
           ; let runTot8S = show runTot8I
           ; putStrLn ("Running Total: " ++ runTot8S)
           ; putStrLn ""
           ; putStrLn "=========================================================="
           ; putStrLn ""
           ; putStrLn "Ninth, type the year of your birth; e.g., 1992"
           ; putStrLn "then press Enter."
           ; birthYearS <- getLine -- getLine is a function, getLine :: IO String
           ; putStrLn ""
           ; putStrLn ("Running Total: " ++ runTot8S)
           ; putStrLn ""
           ; putStrLn "=========================================================="
           ; putStrLn ""
           ; let birthYearI = (read birthYearS)::Integer
           ; let runTotBYI = (runTotMI - birthYearI)
           ; let runTotBYS = show runTotBYI
           ; putStrLn "Tenth, we subtract the year you were born from the running total."
           ; putStrLn ""
           ; putStrLn ("Now our running total equals " ++ runTotBYS ++ ".")
           ; putStrLn ""
           ; let runTot10I = (runTot8I - birthYearI)
           ; let runTot10S = show runTot10I
           ; putStrLn ("Running Total: " ++ runTot10S)
           ; putStrLn ""
           ; putStrLn "=========================================================="
           ; putStrLn ""
           ; putStrLn "The running total's first two digits are how often you crave chocolate each week."
           ; putStrLn ""
           ; putStrLn "The last two digits of the running total are your Age By Chocolate."
           ; putStrLn ""
           ; putStrLn ("Running Total: " ++ runTot10S)
           ; putStrLn ""
           ; putStrLn "=========================================================="
           ; putStrLn ""
          }
--

3. GHCi RUN

GHCi, version 9.8.1: http://www.haskell.org/ghc/  :? for help
Prelude> :l age
[1 of 1] Compiling Main             ( age.hs, interpreted )
Ok, modules loaded: Main.

*Main> main
==========================================================

CALCULATING YOUR AGE BY CHOCOLATE!

First, type a positive integer from 1 to 10 indicating how
often you crave chocolate each week, then press Enter.
10

Running Total: 10

==========================================================

Second, we multiply 10 by 2 which equals 20.

Running Total: 20

==========================================================

Third, we add 5 to our running total which equals 25.

Running Total: 25

==========================================================

Fourth, we multiply our running total by 50 which equals 1250.

Running Total: 1250

==========================================================

Fifth, type the current year date as a positive integer; e.g., 2017
then press Enter.
2017

Running Total: 1250

==========================================================

Sixth, we subtract 250 from the current year; e.g., 2017 - 250 = 1767
and add the result to our running total which equals 3017.

Running Total: 3017

==========================================================

Seventh, if you have not had your birthday this year type the integer 1.
If you have had your birthday this year type zero; e.g., 0.
Then press Enter.
0

Running Total: 3017

==========================================================

Eighth, we subtract 1 or 0 from the running total.
Now our running total equals 3017.

Running Total: 3017

==========================================================

Ninth, type the year of your birth; e.g., 1992
then press Enter.
1992

Running Total: 3017

==========================================================

Tenth, we subtract the year you were born from the running total.
Now our running total equals 1025.

Running Total: 1025

==========================================================

The first two digits of the running total are how often you crave chocolate each week.
The last two digits of the running total are your Age By Chocolate.

Running Total: 1025

==========================================================
*Main>

4. CONCLUSION

You can have fun with Haskell.

5. 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.



Saturday, May 9, 2015

THERE ARE MANY WAYS TO WRITE HASKELL PROGRAMS

THERE ARE MANY WAYS TO WRITE HASKELL PROGRAMS

REVISED: Tuesday, February 13, 2024




1. INTRODUCTION

There are many ways to write Haskell programs. The following are just a few of the many ways you can use Haskell to solve problems and present information with batch and interactive programs.

2. BATCH PROGRAMS

Firstly, you can write Haskell pure functions also called batch programs that have no side effects. Batch programs are programs that do not need to interact with the user while they are running. Batch programs take all their inputs at the start of the program and give all their outputs at the end of the program. Batch programs are written with functions that do not interact with their environment.

When programming first started many programs were batch programs which were run in computer centers far removed from the users who would use the output. Batch programming was well suited for payroll, inventory, accounts receivable, accounts payable, personnel, and in general most business applications. Many batch programs are still used today because they lend themselves to time cut offs such as the end of the month, the end of a payroll period, or the end of any accounting period of time.

3. INTERACTIVE PROGRAMS

Secondly, you can write Haskell impure functions also called interactive programs that do have IO side effects. Interactive programs are programs that do need to interact with the user while they are running. Interactive programs read from the keyboard and write to the screen as the program is running allowing the user to control input and output. These programs are normally run at the users location instead of an off site computer center. Interactive Haskell programs can be written in many ways including stream-based interaction, the interact function, and monads.

3.1. STREAM-BASED

Early versions of Haskell used stream-based interaction as the main method of interacting with the outside world. You can think of a stream as a continuing sequence of elements bundled in chunks. Stream processing applications are very important in our society. We want to know information the instant information is created. News of world events, changes in the stock market, political decisions which could start or stop a war are all things we want to know the moment they occur. 

3.2. INTERACT FUNCTION

The interact function signature is:

interact :: (String -> String) -> IO ()

The following module uses the interact function which is a function that passes the entire input as a giant string to a function of your choice, then prints the returned string to standard output.

module InteractHaskell where

import Data.Char (toUpper)

main :: IO ()
main = interact upperCase

upperCase :: String -> String
upperCase = map toUpper

The output from GHCi is as follows:

Prelude>  :load InteractHaskell
[1 of 1] Compiling InteractHaskell ( InteractHaskell.hs, interpreted )
Ok, modules loaded: InteractHaskell.
Prelude>

Prelude>  upperCase "summer in the sun is lots of fun."
"SUMMER IN THE SUN IS LOTS OF FUN."
Prelude>  

3.3. IO ACTION MONADS

IO action monads have evolved into being the currently most often choice for writing Haskell programs. Three IO action primitives are getChar, putChar, and return. Some very basic IO action monad examples are shown below.

3.3.1. INPUT:

getChar :: IO Char           -- IO action primitive that reads a single Char from the terminal.
getLine :: IO String          -- IO action that reads a single String from the terminal.

3.3.2. OUTPUT:

putChar :: Char -> IO ()   -- IO action primitive that prints a single Char to the terminal.
putStr :: String -> IO ()    -- IO action that prints a single String to the terminal.

print :: Show a => a -> IO ()
putStrLn :: String -> IO ()
return :: Monad m => a -> m a  -- Monad is an IO action primitive that returns any type.

3.3.3. IO ACTION MONAD EXAMPLES

A sequence of actions can be combined as a single composite action using the keyword do.

Four examples of the above IO action monads using do are as follows:

3.3.3.1. Example 1

Module:

module ExOne where

ex1a :: IO ()
ex1a = do putStr "Type a Char then press Enter to echo the Char:\n"
                 x <- getChar
                 putChar x
                 putStr "\n"

ex1b :: IO ()
ex1b = do putStr "Type a String then press Enter to echo the String: \CR"
                 y <- getLine
                 putStr y
                 putStr "\CR"
                 putStr ""

ex1c :: IO (Char, Char)
ex1c = do putStr "At each blinking cursor type a Char then press Enter to echo two Char:\n"
                getChar >>= \x ->
                    getChar >>= \_ ->
                        getChar >>= \y ->
                            return (x,y)       
GHCi:

Prelude>  :load ExOne
[1 of 1] Compiling ExOne ( ExOne.hs, interpreted )
Ok, modules loaded: ExOne.
Prelude>

Prelude>  ex1a
Type a Char then press Enter to echo the Char: 
a
a
Prelude>

Prelude>  ex1b
Type a String then press Enter to echo the String: 
Hello World!
Hello World!
Prelude>  

Prelude>  ex1c
At each blinking cursor type a Char then press Enter to echo two Char:
a
b
('a','b')
Prelude>

Prelude>  :type (>>=)
(>>=) :: Monad m => m a -> (a -> m b) -> m b  -- Takes something of IO a, and a function of (a to IO b), and returns IO b.
Prelude>

3.3.3.2. Example 2

GHCi:

Prelude>  let main = putStrLn "Hello, world!"
Prelude>

Prelude>  main
Hello, world!
Prelude>

3.3.3.3. Example 3

Module:

module ExThree where

main = do putStrLn "Type a line of text and then press Enter to echo the line of text: "
                 line <- getLine
                 print line

GHCi:

Prelude>  :load ExThree
[1 of 1] Compiling ExThree ( ExThree.hs, interpreted )
Ok, modules loaded: ExThree.
Prelude>

Prelude>  main
Type a line of text and then press Enter to echo the line of text: 
Hello, world!
"Hello, world!"
Prelude> 

3.3.3.4. Example 4

Module:

module ExFour where

-- GetChar :: IO Char
-- PutChar :: Char -> IO ()

-- Reading a string from the keyboard.

myGetLine :: IO [Char]
myGetLine = do x <- getChar
                           if x == '\n' then  -- '\n' is escape sequence for new line.
                              return []
                           else
                              do xs <- myGetLine
                                   return (x:xs)  

-- Writing a string to the screen:

myPutStr            :: String -> IO ()
myPutStr []        = return ()
myPutStr (x:xs) = do putChar x
                                   myPutStr xs
  
-- Writing a string and moving to a new line:

myPutStrLn      :: String -> IO ()
myPutStrLn xs = do myPutStr xs
                                 putChar '\n'
 
main  = do myPutStr "Enter a string then press Enter: "
                   xs <- myGetLine
                   myPutStr "The string has "
                   myPutStr (show (length xs))
                   myPutStrLn " characters counting punctuation and white-space."

GHCi:

Prelude>  :load ExFour
[1 of 1] Compiling ExFour         ( ExFour.hs, interpreted )
Ok, modules loaded: ExFour.
Prelude>

Prelude>  main
Enter a string then press Enter: Hello, world!
The string has 13 characters counting punctuation and white-space.
Prelude>

4. CONCLUSION

There are many ways to write Haskell programs. The number of ways will change as time goes by because our needs as a society will change. Haskell must evolve to meet those needs or Haskell will be replaced by other languages. such as Python.

5. 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.




Saturday, February 9, 2013

HASKELL SOURCE CODE EXAMPLE: WRITING TO A FILE

HASKELL SOURCE CODE EXAMPLE: WRITING TO A FILE



REVISED: Saturday, February 10, 2024




Haskell SOURCE CODE EXAMPLE: Writing To A File.

I.  HASKELL SOURCE CODE EXAMPLE OF WRITING TO A FILE

When we execute a Haskell program, the "main function" of the "Main module" gets called.

A. WRITE HASKELL PROGRAM

For example; "Copy Paste" the following Haskell program into your text editor:

module Main where  -- Capital M
main :: IO ()               -- Lowercase m
main = writeFile "C:/Users/Tinnel/Haskell2024/txtFileOut.txt" oops
oops = "A hearse. A hearse. My kingdom for a hearse."

From your text editor select "FileSave As", and save the file as: 

Main.hs   -- Capital M

Notice for Windows you have to use forward slashes / and not backward slashes \ for the file path. And you can use any file path you want as long as you have system privileges for writing to files at that path location.

Both readFile and writeFile operate in text mode.

B. LOAD HASKELL PROGRAM INTO GHCi INTERPRETER

After the GHCi  Prelude> prompt type :load Main as shown below, then press Enter:

Prelude> :load Main
[1 of 1] Compiling Main             ( Main.hs, interpreted )
Ok, modules loaded: Main.
Prelude>

C. COMPILE HASKELL PROGRAM

After the GHCi  Prelude> prompt type :! ghc --make "*Main" as shown below, then press Enter to compile the program:

Prelude> :! ghc --make "*Main"
[1 of 1] Compiling Main             ( Main.hs, Main.o )
Linking Main.exe ...
Prelude>

D. EXECUTE COMPILED HASKELL PROGRAM

Navigate to your working directory. C:/Users/Tinnel/Haskell2024/ is my working directory. From your working directory, hold down the Shift key and right mouse click in any open area of the window. Select the "Open command window here" option. The following path will be filled in for you:

C:/Users/Tinnel/Haskell2024>

NOTE: You must have sufficient operating system privilege in the directory and folder you want to use to perform this operation! On my computer I used the path C:/Users/Tinnel/Haskell2024/ which is where I have system privilege to write to files.

On Windows 8, from the desktop, hover your mouse over the lower left corner until the start box appears and right click. Select “Command Prompt (Admin)”.

As shown below, after the > prompt type Main.exe and press Enter and the compiled program will be executed:

C:/Users/Tinnel/Haskell2024>Main.exe  -- Writes to file not the screen!

C:/Users/Tinnel/Haskell2024>

E. READ FILE

From your text editor, open  C:/Users/Tinnel/Haskell2024/txtFileOut.txt and you will see the following:

A hearse. A hearse. My kingdom for a hearse.

Congratulations! You have written to a file!

II. CONCLUSION

In this tutorial, you have received an introduction to writing to a file.

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.