Friday, August 24, 2012

Prelude: Creating The Logic Engine

Gathering the Resources



    Despite the complete absence of Logic in modern Socio-Political rhetoric, there are no shortages of resources about the Categorical Syllogisms on which the Logic Engine is to be based. This is not due to any particular quality of greatness in our current world-society at all. This is entirely the legacy of the better men and women of the classical, renaissance, and enlightenment eras who toiled tirelessly to ensure that the resources for this critical tool be available for all generations to come. 

    The feckless university systems of this world have almost completely eliminated it from nearly all courses of study and thus condensed it to one specific type of 'humanities' class which is entirely optional and which glosses over the subject of logic to make room for the impossibly mammoth amount of corollary subjects and personalities which must be covered in order to justify a course named "Introduction to Philosophy and Ethics".

    Here's a list of resources which you can use to educate yourself on the forum for logical debate known as the Syllogism or (more specifically) the Categorical Proposition:

    The last one is a list of all of the 256 possible combinations of Categorical syllogism. Once you learn how to read that last page, you can merely 'plug-in' the form of any argument and determine whether-or-not a syllogistic argument is invalid. This is important, because an Invalid argument can never be True; it can only ever be 'undetermined' at best. 

    If an arguer cannot phrase his argument in a Valid form, the argument is worthless as far as decision-making is concerned. This is what the Logic-Engine is all about. Here's an example, if you are going to send a county to war and kill hundreds of thousands of people in the process, you must make that decision based upon an argument which is, at the very least, valid in form. The argument may turn out to be False. However that is not the fault of the arguer per se, rather, that is the fault of the premises used to make the argument. In the world of decision making, the entity or process which determines the truth-value of a premise is completely separate from the entity which makes the decision. This is incontrovertibly True in the world of Executive Government. The President does not go into Iran personally and collect intel about Iran's theoretical quest to declare a nuclear war on America. In fact, the President will likely never even meet any of the people who did. 

    The executor must trust the efforts of the information gatherers she uses first, then trust the sources the information-gatherers cite indirectly. This can never occur in any other fashion lest the gatherer and source be one in the same person; in this case organizational association through the likes of research institutes and corporations are completely irrelevant due to distortions in interpretation and observer-bias which is introduced, willingly or not, by each agent in turn -- remember the telephone game?

    Once you separate the scientific process of premise-proving from the Syllogistic process of decision-making, you are halfway to the point of creating an entirely new form of human governance: the reign of the categorical syllogism. This is because one can take any form of argument and evaluate it using the categorical syllogism. We can trust the categorical syllogism because it is one of the founding structures used to create of all modern mathematics. Every modern structure, tool, or organization has been influenced or completely sired by mathematics and the scientific method. If you refute the consistency of the categorical syllogism, you might as well refute all science. Give-up the computer you are reading this on, the phone, camera, television, gaming set, car, watch, air-conditioning unit, building-you-live-in, justice system which protects you, and government whose freedoms you enjoy. If you don't trust the categorical syllogism you can't explain the presence of any (and much much more) of these things in your life; because they were all founded upon it.

    Simply put: the categorical syllogism and it's children: mathematics, philosophy and science are the foundation of civilization as we know it. To reject it is to return to the bronze-age. 

    The task before us is simply to take the tools before us and formalize them into a public forum and private decision-making system which will be understandable to all members of society and with which we can build a new more logical form of governance.

   The way I will contribute to this is to create a computer program which allows us to feed arguments into it and make determinations of validity or invalidity. 

    I would also like to create a public forum and invite pundits to participate. We can then use logic to determine the course of human activity. 

    In short, if we had used the Logic Engine when Bush Jr. was proposing a war in Iraq, hundreds of thousands of lives would have been saved. The Logic Engine is no mere curiosity of classical pre-science, it is the structure around which most or all of the world's greatest problems can be solved. However, the rule of might will forever dominate human affairs: The strongest entities will make the rules and write the histories. It is thus our charge to ensure that the strongest entities use the categorical syllogism as the basis for decision-making. It is thus our charge to ensure that the majority of human-beings use it. 

    Our work is cut-out for us and will not be completed in any living-persons lifetime. However, by merely pooling our resources and popularizing our efforts, we can and will succeed. The power of the syllogism is readily-apparent to all thinking-persons who use it. For now, we need only concern-ourselves with demonstrating that power for the world to see. 

Look for my breakdown of the Logic-Engine in the posts to come.
    


Friday, August 17, 2012

Haskell Chapter 2

Program Flow


    Once you have learned how to create functions and manipulate standard IO in a programming language, you quickly begin to run-in to situations where you need your module to make decisions. Around this time you also discover the need to save large amounts of data and then cycle through that data one-at-a-time in order to pick-out items on which you must perform some sort of work. This really has nothing to do with computer programming per se, this is just how the civilized human world works. At the end of the day, a computer program is just a way to mechanically perform human activities. The need for artificial intelligence arises from the need to perform human activities. Human activities are long, complex, and usually involve large amounts of data (whether computerized or not). Just imagine the huge amount of data and diagnostic metrics which would be required to maintain a healthy large farm or a prosperous township during the bronze-age. If all we ever did was hunt and gather, there would be no need for computers. Indeed, computers (in the form of counting machines like the abacus) started popping-up around the same time as organized agriculture and thus civilization itself.

    All counting machines and computers (whether primitive or advanced) utilize the concept of leverage in order to perform their feats of prodigy. The idea is that a symbol (like a bead in the tenths-position on an abacus) can represent a whole-other set of ideas and values. Then by merely manipulating the list of symbols, you can manipulate all of the other values and thus perform calculations which would be daunting or impossible to primitive man and woman-kind (more daunting for man-kind). This is called symbolic leveraging and it's the foundation of civilization as we know it.

    The programming paradigm that represents this is sometimes called program-flow or workflow. The tools we use to control the flow of work being performed in Haskell are: conditional statements, lists and list operations, recursion, counters, and list comprehensions. Ultimately, the mentality behind these sorts of programs can be boiled-down to this: Test every element of a list for some arbitrary condition. If the condition is True, perform a function on the element. If not, move on to the next element.

    If we begin by examining conditional-statements, we can illustrate the process with a minimum amount of prerequisite knowledge and give you real-world skills which you can use to create all sorts of useful modules.  Yes, conditional statements are based on boolean operations. However, most high-school graduates already know everything they need to know about booleans in order to create expert conditional statements. There's no point beating you over the head with abstruse knowledge which you will not be using anytime soon. Most of what you need to know about bools will be instantly apparent upon viewing the code. 

    Conditional statements lead directly to counting. Conditional statements are the fun and easy part of programming in Haskell. However, you will eventually find yourself needing to count the amount of items in a list which meet a specific boolean condition, or to look for an item in a specific index of a list (which also requires counting and a subsequent condition-test). The act of counting is where Haskell starts to get advanced. This is because Haskell does not have a feature which other programming languages have built empires upon: mutable-state variables. This is not a shortcoming either. The designers created Haskell that way on purpose. You're probably thinking: Wait, go back a sentence. What the hell is a mutable-state variable? Here's the long and the short of mutable-state variables:
    
    When you write-down a number or value on a notepad, you can go back and erase it or add to it or subtract from it; whatever you want. Once you lift your pencil from the page, the data is saved exactly as you left it. Haskell doesn't allow this. When you give a variable some value in Haskell, Haskell takes that value and locks it away in a safe-deposit box. If you try to modify the value in any way, Haskell will force you to save the new value to yet another deposit box or risk losing it forever. In short, the original value can never be changed or mutated. The only thing you can do to it is to delete it and start over again. This is true for every data-type in Haskell. You can only ever do three things to a variable in Haskell:
  1. Create a new variable (Num, Char, List, etc.).
  2. Read the value of a variable you already created.
  3. Destroy a variable you previously created.
    This makes counting extremely challenging. However, once you master counting in Haskell, you will have officially become a Functional Programmer. If I could send you a badge for that accomplishment, I would because it is mind-expanding and will probably change the way you think about computer programs. But right now I can't afford it. Anyways, don't worry too much about that. Counting Happens in the next Chapter . For now we get to concentrate on something far less challenging yet still pretty rewarding. Conditional Statements.


Conditional Statements


    Bools are the main unit of conditional statements. As mentioned before, they are also the main unit of formal logic; which is a system of making decisions based on truth values. Haskell has a very rich feature-set to deal with truth values; and they come in the form of conditional statements known as 'guards'. So, in this text, conditional statements will be your intro into logic. Anyways, conditional statements are where things start to get really interesting in Computer Science. They allow you to begin designing artificial intelligence modules, instead of mere calculators. 

    Many of the functions you write in Haskell won't ever use Bools like True and False directly. Instead, they use conditional statements. Haskell will check whether a condition is True or False for you, without you even needing to see the words 'True' and 'False'. This is immensely convenient and makes your code both easier to read and write. In the 'Bools' section of the appendix, we will show you how to manipulate Bools discretely using logic statements like not-and and not-or etc. But for now, we will focus on how to create conditional statements because they are easier to understand, more powerful to use, and more fun to write than Bools. 

    There are different ways to create a conditional statement in Haskell. You can use 'if-then statements' like this: 'if x is higher than 100 then putStrLn ("Too high!") else function x.' However, 'if-then' statements are rather rigid and require special indentations and other syntax. It is much easier to create conditional statements using Haskell's dedicated tool for logic: 'Guards'.

    Guards look a little funny, but they are really quite easy to understand. A guard in plain-English could be written like this : 

'If this condition is True (list condition here), then do this: (insert activity here).'

In Haskell's guard syntax, we would write the above line like this:

  | x = y        = function x
  | otherwise    = x

    Notice that there is the traditional 2-space indent. That's because guards are only-ever used inside of function definitions. Also, you will notice that the second line says 'otherwise'. This means that, if x is NOT equal to y, return x unchanged. 'otherwise' is required to compile the function. After all, Haskell needs to know what to do when the first-line is NOT True. Haskell calls this an 'exhaustive pattern'. An 'exhaustive pattern' is one which covers or exhausts all of the possibilities in a conditional statement. As a general rule of thumb, conditional statements need at least two lines: one line to cover what to do when the condition is met, and one line to cover what should be done otherwise.
  • ' | ' is the same as 'If the following condition is True...'
  • 'x = y' is the same as ' the condition is 'x = y'. Of course, you can make any logically-consistent condition you want.
  • '=' means 'then do the following...'
  • 'function x' is the activity you would like to have done. It doesn't have to be a function. However, any activity which requires a definition or statement of equality must be defined separately. As a result, the activity in question usually ends-up being a function of some sort.
    There is one final ingredient to a guard, and that's called a 'where cluase'. A 'where clause' is not strictly necessary. However, it is necessary when the activity you wish-to-be done is so complicated that it needs further definition in its own right. 

Consider the following scenario:

    Imagine you purchased a new HDTV which you connect to the PC in your dorm-room. The sound it produces is wonderfully lush and dynamic in an almost 3-dimensional way. However, it tends to go from a whisper to a cacophony without warning; anytime there is an action scene. Your neighbor is ready to call the cops on you over the noise it creates. The problem is that whenever you turn it down for an action scene, you can't hear the dialogue during the normal scenes! Arggg! What to do? The bass-player in your band explains that you should create a 'software limiter' for your PC which will turn the volume down automatically, whenever the levels go above -5 dbv. That way, the dialogue will be louder and the action will be quiter. 

    This is a perfect job for a guard. All you need to do is setup a function which tests the input level. If the input level is greater than -5, the function will return an output of -5. If the function is less than -5, the output level will remain the same.  We'll call that volume-level 'x'.This is such a simple function that you shouldn't even need a where clause. Here's what it would look like in Haskell. 

limiter x 
  | x > -5    = -5
  | otherwise = x

  Notice that the first line does not have an equals-sign ('='). For some reason, functions that use guards don't use equals-signs before the definition. I suppose the Haskell folks just decided that guards have enough equals-signs in them as it is. This can be a little strange at first. It's another one of those Haskell idiosyncrasies you need to get used to.
      
   Because Haskell is designed to emulate formal mathematical notation, we must always be aware of order-of-operations. This means we need to be aware of when and when not to use parens. 'limiter x' is designed to use negative numbers. However, if we input a negative number into Haskell WITHOUT parens, Haskell thinks you want it to perform a subtraction operation on x while simultaneously inserting x into the function 'limiter'. This creates a conflict in the order-of-operations. You can resolve this the same way you did in your high-school algebra class: put the negative-number inside parens, like this: 

'Prelude> limiter (-7)'

In other words, 'If in doubt, use parens!'

    Now, let's say you've used your limiter module for a few weeks now and you are starting to become dissatisfied with the results. There seems to be no urgency or suspense in the audio; and this is one of the things that made you choose that model of HDTV in the first place! Once the volume hits -5, it sort of falls flat. Once again, the bass-player comes to the rescue. He immediately diagnoses the problem and suggests that the solution here is to make a compressor instead of a limiter. An audio compressor takes every output and modifies it according to some middle-value. That is, it takes the quiet parts and makes them all louder, yet simultaneously takes the loud parts and makes them all quieter. In a way, it compresses the dynamics into a smaller-range while still preserving the roller coaster-like ups and downs which make a movie soundtrack so exciting.

    To do this, we use guards in conjunction with 'where-clauses' as well as the Float data-type. The guards will be setup around an adjustable middle volume which we will call 'center'. When you run the program yourself, try inputting a center value of (-5). I also hate variable-names like 'x' because they tell us nothing about what value x is supposed to be. It only takes a second to find and apply a more descriptive name than 'x'. In this case, I will call the input value 'volumeLevel' because that is what we are modifying with this module; the volume level.Then we will use the 'where-clauses' to define mini-functions which raise and lower the input volume by some percentage. Since we are using a percentage to modify the volume, we need to output 'volumeLevel' in the form of a Float; which is the only way to achieve an accurate output value. Here's what our compressor looks like:

compressor volumeLevel center
  | volumeLevel > center = cut volumeLevel
  | volumeLevel < center = boost volumeLevel
  where
    boost volumeLevel = volumeLevel - (volumeLevel * 0.25)
    cut   volumeLevel = volumeLevel + (volumeLevel * 0.25)

    Notice that 'where' lines up exactly with the guard-symbol (' | '). This is crucial syntax if you want your module to compile properly. Also, notice that there is no equals-sign after where. However, the following lines are indented two-spaces in from 'where'. Again, the two-space indent is a common pattern you will see in Haskell syntax. Make sure you check your first several functions to see that they maintain this unique spacing. If you haven't already, take a minute to try-out both functions on your own.

    The next section will consist of exercises which concentrate on using guards to modify the previous modules you created in the last section. Once you master guards, you will have all of the required skills to start writing programs which are both fun and useful. Of course, some of you may not remember much about Bools. We'll review Boolean operations and offer a complete treatment of classical logic in the appendix at a later date. Simple Boolean operations like and (&&) and or (||) will be covered whenever it applies to an exercise. They are so simple to use, that they don't warrant a dedicated section for most students. What matters is that you get a good grasp of conditional statements and functions. After that, the bulk of the hard-stuff will be behind-you!


Thursday, August 16, 2012

Haskell 1.2.4

Basic IO Exercises


    Before we start on the exercises, I'll quickly recap the workflow concerning the two applications we use to write Haskell modules: the text-editor and ghci. All of the exercises below should be written-out in your text-editor first. Use the comment operator '--' at the beginning of lines containing notes to yourself on what each part of the program does. Ghci will automatically skip over commented notes. Make sure to start your code in the upper-leftmost corner of the text-editor to eliminate the possibility of weird compile-time errors. When you are ready to save the file, save it within your 'haskellPrograms' folder under a name that has no spaces, punctuation-marks, or other uncommon characters. For the interest of consistency, I urge you to use the Haskell naming-convention; something like this: 'exerciseChp1.hs'. Remember that '.hs' is the required suffix, and 'haskellPrograms' is the required folder. 
    Now navigate to 'haskellPrograms' within your terminal application. Once there, type 'ghci' in the terminal. Now you are ready to load your programs! Remember, to load a program you type ':l programName' into ghci.

Exercise 1.1

    This is a basic exercise to help you get a feel for how to use 'putStrLn'. Create a short IO script using the 10 IO Rules of Haskell which apply. First, create a script that takes a number from the user, multiplies it by two, and prints the results onscreen. The idea with this first script is to collect a number from the user into a variable, use that variable as an argument in a separate arithmetic function, pipe the output of the arithmetic function back into a variable within main, and finish by printing the last variable along with some message like 'Two times the number you entered is:' followed by the correct answer. The main tools you need will be:

  • *
  • <-
  • let
  • putStrLn 
  • ++
  • Parens and Double-Quotes 

    You will need to use every rule here except rule #8. If you don't remember, go back and carefully read the special rules for using 'let','read', '++',  and 'putStrLn' which are listed and highlighted in Chapter 1.2.

Exercise 1.2

    Now modify the successful script you created for the last exercise. Try using the arithmetic function as an argument for putStrLn. Now read the compiler-errors. Can you see how the compiler-error messages reflect which specific rule have been broken? Modify the arithmetic function so that it uses 'read' in the argument. Check the error-messages for clues to what is happening. Although the error-messages are difficult to understand, they do give you hints when things go wrong.
    
Exercise 1.3
    
    In this exercise, you must create a simple program which asks for the user's first and last name separately, then displays a message welcoming them to Haskell by their full-name. You must then load the program module (module for short) into ghci and run it. Shown below is the logical breakdown of each step within the program. For starters, it's always good to create a vision of how you think the program should ideally function, despite the fact that you may not know how to accomplish it.  
    Here's how I imagine the program to work. Notice the term 'main>'. This is the ghci 'prompt' which (as you might expect) prompts the user to action. As such, it is not part of our program's design. Likewise, the red-colored text represents data typed by the user, and is also not part of the code we expect to write.

main>Please enter your first name below:
Ryan
main>Now enter your last name below:
Johnson
main>Haskell officially welcomes Ryan Johnson to the world of code!

    To accomplish this simple program you will need to do four things:
  1. Create a 'main=do' function since this is an IO program.
  2. Create two separate functions which display a unique message and retrieve the first and last names of the user.
  3. Combine the first and last name into one unit, as shown above, which features correct spacing*.
  4. Display a greeting which 'pastes' the first and last name of the user into the middle of a pre-written phrase, thus creating a customized greeting message.
    To do this you will need these operators, covered in section 1.2:
  • putStrLn
  • getLine
  • <-
  • ++
  • Parens and Double-Quotes
    You must carefully apply these rules of Haskell IO:
  • Rule #1
  • Rule #2
  • Rule #3
  • Rule #4
  • Rule #6
  • Rule #7
    Ok, now start writing and trying out your creations. You will know you have succeeded when you get the same results as those listed in our creative vision above.

*HINT: Did you know that a space is also a Character in Haskell? You can even make a String of spaces using double-quotations like this: "          ". 








Wednesday, August 15, 2012

Haskell Chapter 1.2.3

Your first assignment pt2: Program your Wizard


Warning: This may turn out to be the hardest chapter in the entire online book! It's filled with rules upon rules; which nobody likes to read. However, once you are through with Chapter 1, you will have a strong working-knowledge of practical Haskell. Stick with it and I'll keep looking for better ways to rewrite the following article!

    One if the best things about functional programming is that it forces you to separate your code into logical chunks. This is great because you can look at the code and immediately tell what each chunk does. It's also frustrating because Haskell enforces this mentality rather strictly; you must undergo a few disheartening failures before you get to experience success. Here's the code I used for this simple little wizard:

main = do
  age <- askUser
  prediction age

askUser = do  
  putStrLn "Tell me your age and I'll magically predict your mother's age: "  
  getLine

addToAge x = read x + 25

prediction z = do 
  putStrLn "Your mom's current age is: "
  print $ addToAge z


    If you come from a dynamic programming background, you will already see that it takes a LOT more code to implement this program in Haskell than it does in a good dynamic language; Haskell isn't always more elegant

    What you see above are four discreet functions. The overall program is referred to in Haskell as a module. So, here we have four functions which work together to create one module. 

    The first function is the 'main = do' module. This is the spine. Notice how each line after 'do' is indented. Also notice that each of the four functions are composed mostly of IO actions like 'putStrLn'. The indentation is very important in 'do' functions. Make sure you always check it before you try to compile your finished program.

    So, logically you can break this whole 'momsAge' module down into two core activities:
  1. Ask your classmate how old she is and write that number down.
  2. Enter your classmate's age into a function and speak the results to her.
    Likewise, 'main' is broken into two functions that reflect this: 'age <- askUser' takes care of activity number one. 'prediction age' takes care of activity number two.

    If you look closely at both activities above, you will see they each consist of two more separate sub-activities. So, following these two logical core activites as they break down into two more subserviant activities we can directly construct the code above. Of course, it's not that easy. Haskell has all those rules we talked about earlier. Here's the break down of the 'momsAge' code using each of the 10 IO Rules of Haskell that apply; starting with the 'main=do' chunk:


main = do
  age <- askUser
  prediction age


Rule #1: Gotta have a 'main=do' function.
Rule #2: Make sure you indent each line in the function's definition by exactly two spaces.
Rule #3: Separate your input function from 'main'. For now, we can call the input function: 'askUser' because it asks the user for her age.
Rule #4: Bind the output of 'askUser' to a variable within 'main' -- in this case we call the variable 'age' because terse variable names like 'x' are practically useless. Otherwise, Haskell will not save the results of 'askUser'; and you won't be able to use it for our second 'core activity'.
Rule #7: The last line of a 'main=do' function needs to return some kind of value. The 'prediction' function prints out the results along with a message to the user. This qualifies as a 'return value'.

     Whew! See what I mean about rules on top of rules! All of the rules above and reasoning we made earlier about the logical structure of the program come together to make this little function.

    If you have read the other non-CS sections of this blog, you'll know that this is a prime example of symbolic leveraging gone wrong. Anyways, we're still not done. We need to define 'askUser' and 'prediction'; right now they're just meaningless placeholders. We'll start with 'askUser' because it's first in the logical order. Here's the rules that govern 'askUser':


askUser = do  
  putStrLn "Tell me your age and I'll magically predict your mother's age: "  
  getLine


Rule #2: Make sure you indent each line by exactly two spaces.
Rule #3: Separate your input function from 'main'. We can call the overall input function: 'askUser' because it asks the user for her age. However, the input 'action' which retrieves the user-data is 'getLine'.
Rule #6: 'askUser' has an IO action inside of it. In fact, it is basically nothing-but IO actions. That means we need to employ the magic 'do' word.
Rule #7: The last line of a 'do' function needs to return some kind of value. 'getLine' takes the user's keyboard input and immediately returns it to whoever invoked it (in this case 'askUser'). If you run 'askUser' from a ghci interactive session (whose parent function is 'std IO'), it will return the output value on screen (which is also 'std IO'). Likewise, if you run 'askUser' from inside of another function, it will return the output value to that other function (in this case 'main=do'). This is why Rule #4 works!

And now the rules that govern the next chunk of code called 'addToAge':

addToAge x = read x + 25

Rule #5: 'addToAge' has no IO actions. 'read' sure seems like an IO action, but Haskell doesn't require 'do' notation for read. Since 'read' is not an IO action, we must follow rule number five and separate the whole operation off to it's own function. This is nice, if the median age of new motherhood increases, or if we want to give the result as a range instead of one answer (which is bound to be wrong) all we have to do is change 'addToAge'. The rest of the 'momsAge' module remains intact and bug free! This is what functional programming is all about!
Rule #9: We know that 'addToAge' is going to receive a variable which has been bound to the output of 'askUser'. We also know that 'askUser' uses 'getLine' which only delivers strings for outputs; regardless of what kind of input you give it. Since Haskell is statically-typed, we know that it will refuse to perform arithmetic operations on strings -- even if they look like numbers to you and me. What we need then is some way to convert our variable (age) into a number long enough to perform arithmetic on it.
Rule #10: 'read' is a way to convert a string to a number and back again. It doesn't work for a string of letters like 'bananas', but it works great for a string of numbers like '20'. So, using rule #9, we anticipated that 'age' would be a string. Now we apply 'read' to age, and continue to operate on it using arithmetic. The output of 'addToAge' will still be a string, but 'read' allows us to calculate it as if it were a number. 

And finally (make it stop please!), the rules that govern 'prediction':


prediction z = do 
  putStrLn "Your mom's current age is: "
  print $ addToAge z


Rule #2: Make sure you indent each line by exactly two spaces.
Rule #6: 'putStrLn' is an IO action, so it means that 'prediction' requires 'do' notation.
Rule #7: We need to finish with an output function. The logical choice is to finish with 'addToAge' because we know it outputs a concrete value (x + 25).
Rule #8: We also need a way to print the output of 'addToAge'. We know 'addToAge' is not a 'do' function; and thus it has no IO capabilities of it's own. However, 'print $' gives us a tool to print the output of any function onscreen AND it satisfies rule #7 at the same time!

Wrapping it all up: Save, Compile and Load your Module


Whew! All done! Now all we need to do is save the code to a '.hs' file and load it into ghci. Here's how: 

Copy the text above to a good text-editor (I use KATE). Make sure that there are no empty lines or spaces before 'main=do'; remember Haskell is very sensitive to spacing and indents.

Next, save the file as 'momsAge.hs' within the haskellPrograms folder we created earlier. Open a terminal, navigate to /haskellPrograms and type 'ghci'. When  you see the 'Prelude>' prompt, type: 

':l momsAge'

As long as there are no weird empty lines or spacing issues, the program will compile and you will be greeted with this prompt:

*Main>

This means that ghci has loaded-up 'momsAge'. 'Main>' is sort of a generic-prompt which Haskell uses for user-created functions. To run your module, you need to 'call' the main=do function by typing 'main' (lowercase m). Of course, you can call other functions in 'momsAge' too (if you feel like testing them out) by simply typing the name of the function and pressing enter. From there, it's pretty self-explanatory.

Prologue 


    Wow, that was a helluva lot of rules to remember. I agree. Way too many in fact. But, once you master this section, we can go on and practice writing programs instead of spending the entire book ONLY talking about theory (like in Learn You a Haskell and Haskell:TCoFP 1st Ed). Its a pain and you will probably need to re-read this section several times. However, there really is no other way to do this. This leads to the last rule (for now), but don't worry; it's easy to remember:

The Golden Rule of Coding: The only way to learn how to code is to code, code, code!

In the next section we will concentrate only on practical IO excercises until (hopefully) it becomes natural for you. In section 1.3 we will introduce Bools briefly, and then finish with some more exercises. All that theory and verbose explanation is great -- to a point. But you need to practice until your fingers 'just know what to do' without even thinking about rules.

Tuesday, August 14, 2012

Haskell Chapter 1.2.2

Your first assignment pt1: Create a Wizard


    When you install a piece of software for the first time, it will proceed to ask you some basic questions about you so that it can set the software up correctly. As you probably already know, that sequence of questions is called a wizard.
 
     Wizards are an excellent example of precisely what it is that software really does. A wizard asks you for information, takes that information and processes it. Then, the wizard spits out a result. All the while, the inner-workings of the wizard are invisible to the user. Anyone can use a wizard because a wizard uses natural language; in our case English. This allows the programmer to create algorithms of infinite complexity which are, all the while, still accessible to anyone with basic communications skills and perhaps some arithmetic. This is what all software should ideally be: an intuitive user interface that gathers data, invisibly executes it with unfettered complexity, and returns the data in terms that the user can understand without knowing how the program works.

    This is not so easy to do in Haskell; a weakness if ever there was one. Still, Haskell can do so many other things, so well and with so little effort, that we just have to bite the bullet here! 

    The perfect analogy for the wizard is the algebraic function. If you don't remember this, or never learned it, you need to stop here and seek out a good introductory Algebra textbook. In several years from now I may have one written for you (eh just go check one out from the library)!

    OK, now that you're back, let's continue with the algebraic function. A function is the first program anyone learns how to write. Long before learning to code, we learn to write functions and they work like 50% of the wizard which we are attempting to write. In this section, we will create a function along with a set of instructions and save them as a '.hs' file. We call this file a 'script' because it contains not only functions, but a general order in which the functions are-to-be performed. Whereas a module can be a very short '.hs' file consisting of only one line, a script is a collection of functions and instructions; a collection of multiple-lines of code. Here's the real-world scenario which we want to model as a mathematical function: 
  1. Start by finding a classmate who is either an only child or a firstborn child.
  2. Ask the user (your classmate) how old she is. For demonstration purposes, we'll say that she says 20 and you write that down in your notes. 
  3. Let x = your classmate's age. Now, let x = 20.
  4. Next, you tell her that you will guess her mom's age within +/- 5 years. 
  5. In america, the average new mother is about 25 years old. So, we can extrapolate that your classmate's mother was probably close to that age when she gave birth. On your notepad, add the classmate's age (x) plus 25. 
  6. Finally, perform the calculation (x + 25) and speak the results to your classmate: "Your mother is most likely 45 plus or minus 5 years"
     There's a pretty good chance you'll be right. Maybe not. The point is, you just made a function which (if you  remember algebra class) can be written like this:

function(x) = x + 25

The anatomy of a function can be divided into five parts:

  • First we have the name of the function: 'function' -- a rather boring name.
  • Second we have the input of the function: '(x)'
  • Next we have the declaration of equality, which signals the end of the arguments section: '='
  • Then we have the definition, which explains how the function works: 'x + 25' -- this can consist of nearly an infinite number of lines.
  • Lastly we have the return value. It is not usually listed in the function itself, but rather it is inferred from the definition. In non-conditional functions, the return value is usually the product of the last line of the function
    In Haskell we don't use parenthesis (parens) for function input; in this case 'x'. Haskell automatically infers that the data following a function-call is the input (also called the argument). We also don't need to actually use the word 'function'. This is a relief. It allows us to give the function a name which helps us separate one function from the countless others your programs may have. Using Haskell notation, we'll give it a nice descriptive title: 'momsAge'. In Haskell-eese we write the above function like this:

momsAge x = x + 25

Not much of a difference there, so we'll move on.

     OK, but wait, where's all the stuff where I asked her how old she was and took the notes and then spoke the answer to her? That's all IO. You will no doubt remember that none of your math classes covered anything like that. As it turns out, simple stuff like asking a chick in your class a question is really hard to describe in mathematical terms. The only way to do it is to use an abstract tool called a monad, which we won't talk about for awhile. All that matters is that monads are what allow IO in Haskell and, more succinctly, monads are what allow Haskell to exist in the first place! No monad, no Haskell. By learning Haskell IO from the start, you are learning a little about monads from the get go; for now you don't need to know much more than that; other than to say: monads are nothing to be afraid of.

     Forget about monads for now. Haskell IO is really composed of a mix of tools and structure. The tools consist of a set of built-in operations which Haskell calls 'IO Actions' or just 'actions' for short. In any other language these actions would be just another primitive operation like plus, minus  or divide. But in Haskell, they are quarantined from the rest of the language under the rubric: 'actions'.

    Common actions are: 'print', 'getLine', and 'putStrLn'. Of course, there are many others. Then there is the IO structure which is really what makes IO on Haskell so confusing for the unitiated. 

    The Haskell IO structure is dominated by rules on top of rules. In good dynamic languages, IO is so easy that the pupil learns it instinctively with only a few syntactic definitions from the author. With Haskell, you need to make sure that your code is laid-out according to a merciless set of rules. The rules are extensive and they don't come naturally. There are aspects that don't really make sense at first. As I gain insight, I will add posts to the subject of Haskell IO in order to create a methodical approach. The idea being that once you understand the rules, you should be able to synthesize your own code with impunity. 'Showing you how' just does not work with Haskell IO. Now, if I haven't scared you away yet, here's the core set of rules:

Haskell IO Rules of the Road


1. All IO scripts require a "main = do" function which acts as a spine around which the other functions of the script are attached. Think C/C++. This makes for easier-to-read code, but Haskell also requires it. In this way, main becomes the entry point for the program but also becomes the 'director' of the other functions. In other words: always start your IO script with 'main = do'. 

2. Remember to give each separate step in your function it's own carefully indented line. The exception here is 'do'. Put 'do' on the same line as 'main' without any particular indents.

3. Create seperate functions for standard input (outside of 'main'), then bind them to a variable within main using '<-' . Avoid putting any standard input commands directly within "main = do". Haskell has no problems with you putting specific output commands like ' putStrLn "Hello World" ' directly into main. But, it prevents input actions altogether. Thankfully, you can bind the output of a seperate input function within main for usage with later functions. This means that you will have multiple separate functions for even the simplest of IO scripts; weaving in and out of 'main' continuously.

4. Use '<-' only for binding IO functions. Any other (non-IO) binding can (and should) be performed with 'let x = n' syntax. This is also true when piping the output of a (non IO) function to a local variable. Like 'let a = momsAge 9'. Just remember that functions can be renamed in the same way. 'let a = momsAge'. You will find that a large portion of your compiler-errors come from missing arguments!

5. Separate non-IO functions from all other 'do' functions. Any mathematical operation or algorithm should be separated from IO functions like 'main'. You can still call those functions from within 'main'. This makes your programs easier to read and maintain but it also keeps your code from crashing during compile-time!

6. Use ' function = do' (do notation) for all functions that have IO actions in them. Get used to the fact that you will see many many instances of 'do' in large programs!

7. All 'do' functions must end with some sort of return value; even if that return value is only a print statement or onscreen command. This is especially true with 'main' statements.

8. Use 'print $ function x' to print the output value of a function (which itself has no IO actions) onscreen. You'll learn what the $ sign means later. For now, just think of it as the second part of this command with 'print' being the first.

9. Always be aware of the type of data you pass to an operator. Haskell is statically typed, unlike most other popular languages. This takes a lot of getting used to. 90% of the mistakes newbies make when writing their first IO programs come from type conflicts. If Haskell catches you trying to use an Integer operation (like multiplication) on a piece of data that was input as a String, it will refuse to compile the program! This happens all the time with numbers (numbers can be both integers and strings). The getLine function only outputs Strings, regardless of the input you give it; which leads us to rule #10.

10. The read command is your best friend! If you bring in a variable (a number) with getLine, and you need to perform an arithmetical operation on it, use read to convert it (temporarily) into a Number just long enough to perform the operation. Remember that the variable will revert to its original type once the operation is finished.

     In part 2, we'll look at the actual Haskell code used to automate the momsAge function from beginning to end. In every section where one of the 10 IO rules is implemented, I will mark the applied rule and how it interacts with the structure of the overall module.


Monday, August 13, 2012

Haskell Chapter 1.2

"I'm the operator with my pocket calculator!" -- Kraftwerk


On Basic Operators and Calculators

    Most first-semester programming students know enough about computer-languages to understand that each language has operators -- which are miniature programs that are 'built-in' to the language. There are, of course, a whole library of operators around which the programming language is built. In many ways, the process of learning to program revolves around learning to expertly use the most crucial operators of the given language. 

    In this text I will attempt to explain operators and basic data-types that apply specifically to the lessons at hand. However, since this text is also an attempt to implement scaffolding in literary form, those operators and data-types should provide the student with a well-rounded set of tools which can be used to explore their own extra-curricular questions and experiments.

Basic Data-Types

Numbers
    The Number or 'Num' is the most basic data-type. There are different types of Num: Integers, Floats, Ints, Doubles and variables as well as a few less common types. We will mainly use three types: Integers, Floats and variables. Variables are a 'universal type' in that they are merely memory slots with no type of their own; that leaves us to Integers and Floats. You should already know what an Integer is. A float is just a decimal of some sort; called Float because that decimal can 'float' around depending on the accuracy specified by the programmer. The important characteristic of numbers or Nums, is that you can perform all sorts of mathematical operations on them. However, you cannot do this with Strings or Chars. This is an important distinction because a Char can be ANY symbol at all; including a number. 

Characters
    The Character type is any symbol you can find on your keyboard. These symbols are standardized by an organization called ASCII. They have a binary value, which you can manipulate to create some interesting text-processing modules. However, they are mostly meaningless to Haskell. Characters are there for the reader to read. In order to perform arithmetic on a Char, you need to convert it to a number first using an operator like 'read' -- which we will read about later.

Strings
    Strings are lists of Characters. As such, they are the first lists you will use in this text. There are different types of lists. Lists have there own large set of operators; and all of those operators work on Strings in the same way. Lists are complicated enough that they need their own Chapter to do them justice. However, for now just remember that Strings are really just special lists which consist of 2 or more Chars. Instead of the brackets used in other types of lists, Strings are enclosed by double-quotation marks. 

Variables
    Variables are different from Chars because they don't use quotation marks or any special IO operators. A variable is just a label for a memory slot in which you can deposit values for later use. Other than that, they are identical to variables in algebra and thus take on the characteristics of whatever data you put into them. Variables should always be given descriptive names. Avoid variable-names like x or y. In real-world scripts, terse variable names will drive you crazy and significantly reduce your productivity.

Literals
    Literals are anything other than a String or Char. Numbers and Bools are literals. Literals are what we use in the language of mathematics. Strings and Chars are what we use in human languages like English.

Bools
    Bools consist of two symbols: True and False. Written just like that, always with the first letter capitalized. As you probably already know, Bools are the core units of Logic. Either a statement is True or False. Bools are also great for running tests: 'if x is higher than 100, return True'.

GHCI the Calculator

    One of the best things about having an interactive programming environment, like GHCI, is that it allows you to utilize the power of the language on-the-fly. You can perform complex algebraic calculations on Nums that would put a top-of-the-line graphing calculator to shame. You can also test out and casually use a whole library of interactive modules by simply loading the necessary module. As a result, the environment itself becomes a tool for learning and troubleshooting. 

    Below is an explanation of some of the most common operators and the syntax required to use them. Open up your favorite text editor and give them a try as you read. If you have a Linux OS, you can right-click on the terminal and select 'Always On Top'. This will allow you to view and scroll the background blog-text while working within the terminal. If you have an Ubuntu variant of some sort, you can probably  set the transparency of the terminal window too. This allows you to see any text which runs behind the terminal window -- very handy.

    Before we get to the good stuff, there is one final concept behind operators which we must explain. There are three types of basic operators: Inline, Infix, and Modified. 
  • Infix Operators are the most familiar type of operator. Examples include most of the common arithmetic operators like add ('+'), multiply ('*'), and exponentiate ('^'). If you want to find the square of two you type '2^2' at the GHCI prompt ('Prelude>'). Infix operators go between the values you are calculating: 'Prelude> 2 * 2'
  • Inline Operators are a little less common. These work much the same as an algebraic function. Inline operators always come at the beginning of the operation. The values which you plug in to an operator are called 'arguments'. Those arguments come after the inline operator you are using. A good example is the modulo or remainder operator. This nifty tool allows you to find only the remainder produced by dividing two numbers. It is used like this: ' mod 4 2 '. Here we are trying to find out if there is any remainder left after we divide four by two. The answer is, of course, zero. 'Prelude> mod 4 2
  • Modified Operators can be either Infix or Inline. This is helpful when you want to make a piece of code more readable. You can modify any operator by placing the modifier symbol ( ` ) directly before and after the operation you are trying to modify. Notice that this is NOT the same symbol as the single-quote, which looks like this: ( ' ). You could modify the modulo operation so that the dividend comes first, the modulo operator comes second, and the divisor comes last; just like you would do in formal mathematical notation: 'Prelude> 4 `mod` 2'  
     We won't waste time specifically stating whether something is Infix or Inline, unless it is not immediately apparent or it needs to be modified to facilitate the flow of the code. Usually you can tell by looking at the example.

    We'll start with: 

    Arithmetic Operators
  • Add: +
  • Subtract: -
  • Multiply: *
  • Divide: div x y 
  • Exponentiate: ^
  • Square-Root: sqrt x
  • Modulo: mod x y
  • Associate: ( )
    OK, so there's not much in arithmetic which is different than what you or any grade-school student are already used to. Of course, there are others not listed here. For example, '/' can be used to divide literals (Nums that are not in variable-form). However, 'div' is more versatile. Checkout www.Haskell.org for complete lists of 'Prelude' operators.

Basic IO Operators

    Now we will move on to IO operators because you will need them in the next section. IO operators just send an output (whatever you decide) to the screen. In this case, they send it to the onscreen display of the terminal. 
    Most IO operators deal with 'Strings'. Strings are just groups composed of Characters or Chars. Haskell has no ability to find meaning in Strings unless you write a program telling it how. So, to Haskell the Char '2' has the same meaning as the Char 'P'. This is important to remember. In later exercises, this knowledge is crucial. We'll start with the two most basic IO operators: 'getLine' and 'putStrLn':

IO Operators for Strings and Chars
  • getLine This is an input command -- as opposed to an operator. This command has no arguments. If you put getLine into a module, Haskell will stop what it is doing, record any keyboard input until the user presses enter, and immediately spit-out that input in the form of a String. If you enter a number into getLine, it will spit it out as a String, so Haskell won't know that it is actually a number.
  • putStrLn This is an output operator. It takes only one argument which must be enclosed in double-quotations. I find it is best to use putStrLn with parens like this: ' putStrLn ("Hello World!")'. putStrLn automatically displays the argument you give it in the terminal screen; without displaying the double-quotes or parens. One crucial rule to remember when using putStrLn is that it only accepts two kinds of argument: Strings and literals. If you try to sneak a function into the output of putStrLn, your module will fail to load!
  • <- This is the IO-Bind operator. This is a special operator which is mostly used with IO operations. It takes the output of any IO function, IO command, or IO operator and saves it to a variable-name of your choosing. So, if you write 'name <- getLine' in a script, it will run getLine and pipe the output into the variable 'name'. This is how you save important IO values for future use.
  • ++ This is the join or Concatenate Operator. This allows you to join two strings together. This is usually used in an instance of 'putStrLn'; inside the parens but outside of double-quotations. Remember that last sentence. This is crucial when you are using Concatenate: ++ Goes inside of parens but outside of quotes.
  • read This is not really an IO operator at all. However, you almost always use read in conjunction with some previous IO operation. So I include it here. 'read' converts a Character into a number. This is a vital operator. If you use getLine to retrieve a number from the user, getLine will save that number as a  Char or String of Chars. The problem is that arithmetic operators do not work on Chars! They only work on Numbers! So, use read (inline) in order to convert a Char into a Number just long enough to perform an operation on it. Once the operation is done, the variable containing the Char will revert to it's original state. There's one more rule about 'read' which you must understand in order to use it correctly: you must avoid using read in the argument of a function. This is because read changes the type of the argument and, as we have already learned, Haskell is based on a static (unchanging) type system. It is better to use read inside the definition of a function; where the rule is generally 'anything goes'.
  • let This is also not exactly an IO operator. However, you do use it to input and save data to a variable within ghci or within a function. It is a Bind Operator like the arrow ( <- ). Try this: 'Prelude> let x = 9'. Now you can add x, multiply, subtract or use any other one of the arithmetic operators on x. In this way we have 'declared the variable x'. That is, we declared that x is the name of a memory slot which we want to save data in. The stupid thing about 'let' is that we can't always use it in scripts (modules). For instance, for variable declarations which occur outside of a function and within a script, you simply type 'x = whatever'. This is also the case with 'Where' clauses, which we will learn about later. Because of this confusing inconsistency, I sincerely hope that the Glasgow Haskell folks will eliminate 'let' in the future. For now, we just need to remember that 'let' is only used within ghci and the body of functions. 'let' is only designed for non-IO applications like arithmetic functions and variable declarations.
    For the moment, don't worry too much about IO operations. Instead, try using ghci as a simple calculator. Open up an old algebra book and try out some problems which use variables and parens. Use the 'let' operator to deposit values into variables and test the results. You will find that parentheses (parens) work the same in Haskell as they do in your algebra textbook. Haskell is designed to use as much mathematical notation as possible. This makes it familiar and easy to use for anyone with secondary-school education under their belt.

Warm-Up Exercises
  • Use ghci as a basic calculator using the arithmetic operators above.
  • Use 'let' to declare a variable. Try performing different arithmetic operations on the variable.
  • Try-out some basic problems from an old algebra text which make use of variables and parens.
  • Find the most difficult order of operations problem you can and calculate it in ghci. Check the results.
  • Use 'putStrLn' using the rules listed above in order to display 'Hello World' within ghci.
  • Use 'getLine', '<-' and the variable 'n'  to save your numeric keyboard input.
  • Use 'read n' with the arithmetic operators listed above. Use parens to insert 'read n' into the arguments of Inline operators -- just as you would in formal mathematical notation.

Sunday, August 12, 2012

Haskell Chapter 1: Getting Started

     If you're not using Linux (or Unix) already, you should be. Sure, you can install Haskell on just about any kind of pc, but the Linux OS was designed by coders for coders. Trying to learn programming on Windows or Mac is a bit like trying to become a gourmet chef by getting a job at McDonald's. Why would you do that? Linux is Le Cordon Bleu and everything else is McDonald's. Besides, modern Linux distros cost nothing and are actually easier to install and setup then their corporate counterparts. If you're worried about transitioning to a new OS, don't be. You'll find modern versions of Linux work in virtually the same way as the OS you are used to. Particularly if you stick to the Ubuntu-family; you'll quickly see that there really is no learning curve to speak of. I'll even pick a distro for you, click here: Mint 13 MATE
   
      In Linux, you automatically get an unfathomably large library of free applications which usually work better than the paid kind, have better support (strange but true), and are open-source; so they are constantly being debugged, improved and upgraded. To get the software resources that automatically come with a good Linux distribution on an OS like Windows, you would need to pay tens-of-thousands of dollars in licensing fees. Then there's the fact that Linux is the most reliable OS ever made. The reduction in frustration-level alone makes it worthwhile. There's no reason to put it off, make the switch now! If you still insist on spending money on crappy ripoffs of programs that were originally written for either Linux or Unix, then you can go here and find an installer: the Haskell Wiki.

     Now, if you have Ubuntu or Mint you can just open Synaptic Package Manager and search for 'ghci'. Install the latest version. See how much easier that is? Regardless of your system, the next steps are relatively the same. 

     One final note before we begin: You will see a lot of quotations in any text dealing with programming. This is a little confusing when you are starting out. When I tell you to type something a certain exact way, I will use single quotations to separate that code from the rest of the neighboring sentences. 

     I don't want you to actually type the single quotation marks themselves. Instead, type what's in-between the single quotation marks. Like, if I say type 'ghci', you type this: ghci . On the other-hand, if you see double quotation marks ("), go ahead and type those. Haskell uses double quotation marks to process certain types of data. If there are no surrounding lines of text (see step 7 below), I will omit the single quotes for simplicity's sake. Likewise, Haskell will present a 'prompt' which prompts you to type something. It usually takes the form of some library (like Prelude) followed by ' > '. I don't won't you to type 'Prelude>'. I do want you to type the text that occurs after it -- like 'Prelude> let x = 9'.

OK, let's Haskell!


1. Create a folder for your Haskell programs. This is a good time to start using the Haskell naming convention. In Haskell, we never capitalize the first word in a name. However we always capitalize the subsequent words -- all the while leaving out any spaces because Operating Systems don't like spaces (go-figure). So my Haskell program folder is called haskellPrograms. If you prefer, HaskellPrograms and Haskell_Programs will work for file names too.
2. Open up your terminal application and navigate to /haskellPrograms. This is important. Once you run the haskell interactive environment (ghci) in the next step, you will eventually need to load-up the programs you write. In order to do this, ghci needs to 'know' what programs you are referring to. It will automatically look in whatever folder you were in when you called ghci. In this case, that folder will be haskellPrograms.
3. Open your favorite text-editor (I use KATE). If you are using Linux or a Linux ripoff (Mac), you can just switch to another empty workspace with the click of a button. If you are still using windows, you must minimize your current screen etc, open the Programs menu, then open up some text editor and finally maximize the browser window every time you need to see this blog. Oh wait, you also have to do all that stuff with your terminal application too. Why are you still using Windows?
4. Go to the Edit>Preferences section of your text-editor. Now, locate the 'tabs' settings and change it to this: Tabs>Use Spaces>Number of Spaces = 8. Next, set the indent to Use Spaces>Number of Spaces = 2. This is crucial. Haskell is very sensitive to tab spacing. There is still no standard for tab spacing; some companies use 3 spaces, some use a fixed pixel width. If your text-editor doesn't use the exact settings above, you are in for a world of frustration! However, if you are using KATE, you can skip this step: KATE comes with the correct spacing out-of-the-box.
5. Open a new file in your text editor. Save the blank file as test.hs within your /haskellPrograms file. Dot hs is the suffix for Haskell source-code. Later when you compile your first program, the suffix will change. But, the suffix you will work with the most is ' .hs '. Now, you are ready to enter code into test.hs and load it into ghci.
6. Go back to your terminal and type 'ghci '. This will launch the ghci interactive environment. This is a program that lets you experiment with the Haskell language without compiling a program. Using ghci is a little bit different from writing an actual Haskell script, so I will try to concentrate on scripts instead -- that way you don't get too confused.
7. Go back to your text-editor and write this all the way on the top-left corner (do NOT skip a line) of the 'test.hs' file, which you should already have open:


main = do
    putStrLn "Hello World!"

8. Now save test.hs. Go back to ghci (in the terminal) and type this ':l test.hs'. Colon l is the command for "load the following file", in this case the file we want to load is test.hs.
9. Now type 'main' and observe! If everything was entered into your text editor as described above, you should now see 'Hello World' on the line below, like this:

*Main>main
Hello World!
*Main>

     Ya, I know what your thinking: that's a pretty lame program dude. Just bear with me here, it will get better real soon. For now, you have accomplished that famously devilish programming task: Haskell IO! Take a short break, drink some water, have a cookie. Next I'll explain the basic Haskell operations like arithmetic and IO. Using these, you can start experimenting with ghci and get a feel for what it's like to program in Haskell. But before we do that, you'll want to know how to leave your current ghci session and possibly load up another one: type ' :quit '. Be careful however, this doesn't always work! Some programs will endlessly read your keyboard input; even reserved commands like :quit.

    One final word about the 'Prelude>' prompt. In Haskell, whenever you load a program module or library of program modules, Haskell conveniently displays the module or library that you have successfully loaded at the prompt. When you first start-up 'ghci', it automatically loads the standard-library known as 'Prelude'. Prelude is a collection of modules which the Glasgow Haskell folks believe to be vital to daily usage. It is a large library and it changes from time to time as the Haskell committee vote to insert or remove modules. There are other libraries which are just as crucial. In fact, I am often perplexed to find that basic common-sense modules are missing from Prelude but available in other places like Data.Char.