summaryh.txt a very compact summary of Haskell functional programming language no where near complete, see http://www.haskell.org for much more Although Haskell is a functional programming language, very different from C, C++, Java, Fortran, Ada, MatLab, Python, Ruby, ... you still must know the basic structure and syntax in order to write programs that compile and run. Haskell literature uses interesting naming, I use programmereze. Thus, this compact summary in plain text. This file is not trying to teach you functional programming. My functional programming experience came from SML, smlnj. Take the Haskell tutorial if you have not learned functional programming. I happened to be using Ubuntu and downloaded and installed the compiler and libraries with the single command: sudo apt-get install ghc6 prepare your program in a file some_name.hs (Yes, there is an interactive version for good typist.) compile your program and execute, I use a Makefile : # Haskell aka ghc aka ghc-6.8.2 GHC=ghc-6.8.2 all: hello_hs.out hello_hs.out : hello.hs $(GHC) -o hello hello.hs ./hello > hello_hs.out ghc has an internal Makefile capability and may output a message about not needing to recompile. My first program was to experiment getting output, hello.hs : {- hello.hs just basic output to screen -} import IO main :: IO () main = do print "Hello from Haskell" print "next line" print 7 print 'A' print 37.235E-7 print [ [1,2], [3,4,5]] print (('a',1), ('c', 2, 123.456)) putStr "Hello " putStr "again" putStr " and again\n" -- new line works putStrLn "more lines" putStrLn ("option "++show(7)++" of show") -- putStrLn show(7) -- does not compile -- putStrLn " "++show(7) -- does not compile putStrLn (" "++show(7)) -- end of hello.hs Produces the output hello_hs.out : "Hello from Haskell" "next line" 7 'A' 3.7235e-6 [[1,2],[3,4,5]] (('a',1),('c',2,123.456)) Hello again and again more lines option 7 of show 7 The structure of a file for a main program is: -- imports -- function definitions main :: IO () -- actually optional, yet a reminder main = do -- lines that produce output, IO, or of type IO xxx -- more lines, same indentation -- extra blank lines and comments allowed anywhere Comments may take either of two forms: multi line comments start {- and end -} comments single line or at end of line -- The language is case sensitive There is a restriction that variables and functions must start with a lower case letter. Types and classes must start with an upper case letter. Names may include upper and lower case letters, digits, underscore _ and apostrophe ' You may notice that some programmers name their version of something that exists by just adding an apostrophe at the end of the name. Underscore or uppercase inside a name with several words is typical. The language, as usually written, is indentation and blank line sensitive. Keep the same indentation for a group of lines. There must be a blank line at the end of a function definition. The backward slash, \ , may be used to continue a line. Other than these restrictions, the language is free form. Standard numbers: Int 0, 1, 2 ... typical 32 bit range Integer 0, 1, 10000000000000000000, ... arbitrary precision Float 0.0, 1.5e-9, 237.29E12 ... Double 0.0, 1.5e-9, 237.29E12 ... Rational 5%37 ... Complex 7.5:+3.25 ... Standard characters and strings: Char 'a', 'Z' ... String "abc", "normal special \n", ... Standard tuples, mixed types, can be nested ('A', 1) ((1,2), (3, 'A', "hello", 37.25e-7, 99), ("key", 7)) () empty tuple, reads like "null" or "void" Standard lists, every item in a list is the same type. List is a type. [1, 2, 3] [2.3, 3.7] ["a", "list", "of", "words"] [[1,2,3], ['A', 'Z'], [7.5, 3.2, 8.9]] [] empty list Parentheses! Many parentheses that other programming languages require are considered bad style in Haskell and other functional programming languages. Unfortunately, there are times when you need parentheses, as I commented in my first program hello.hs Typical installation includes a library of modules. The user may also create modules. Modules are made available to user code with the "import" line. A special module, named Prelude, is automatically imported. My compact summaries include a list of reserved words or key words, type names, functions, etc. Even though you may be able to redefine these, it is better that you do not. as case class data default deriving do else forall foreign hiding if import in infix infixl infixr instance let mdo module newtype of qualified then type where Char Complex Double Float Int Integer IO main String Rational abs cos sqrt sin etc. typical functions There are many many classes defined in the standard and optional libraries. Expect all the common and not so common class names to be used. Functions are the building blocks of the language. Functions are not executed until their output is needed, and only until the required output is available. This is called lazy execution. Three cases first: simple, pattern match, guards Simple function: type declaration input(s) -> output function name, formal parameters, =, expression fct :: Integer -> Integer fct x = if x<=1 then 1 else x * fct(x-1) putStrLn("52!="++show(fct 52)) -- function call Pattern match function: Any number of mutually exclusive argument types may be defined for a function. Only the pattern that matches is executed, when needed. sumAll :: (Num a) => [a] -> a -- sum all numbers in a list sumAll (x:xs) = x + sumAll xs -- the output type is the list element type sumAll [] = 0 -- stop the recursion upon the empty list a :: [Int] a = [1, 2, 3] suma = sumAll a -- type Int result, a constant b :: [Double] b = [1.1, 2.2, 3.3] sumb = sumAll b -- type Double result, a constant "Guards" after the | read like a case statement The "where" makes the function show2 local to showTime showTime :: Int -> Int -> String -- two inputs, one output showTime hours minutes | hours == 0 = "12" ++ ":" ++ show2(minutes) ++ " am" | hours <= 11 = (show2 hours) ++ ":" ++ show2(minutes) ++ " am" | hours == 12 = (show2 hours) ++ ":" ++ show2(minutes) ++ " pm" | otherwise = (show2 (hours-12)) ++ ":" ++ show2(minutes) ++ " pm" where show2 x -- make two digits | x < 10 = "0" ++ show x | otherwise = show x main :: IO () main=do print (showTime 7 9) -- sample use of the function Using many small functions, that can call other functions is considered appropriate style. Note the equal sign, =, is mathematical equality, defining the first, a constant, immutable. Within sequential code, "do", Monad, a <- expression is substitution Operators and punctuation include: + add - subtract * multiply / divide also substitution as in e{f/x} ^ raise to power ^^ raise to power ** raise to power && and || or < less than > greater than == equal /= not equal <= less than or equal >= greater than or equal ++ list concatenation (remember -- is for comments) : append for lists .. specify range for lists \\ list dereference operator <- list compression generator, also assignment operator !! index operator for tuples , separator ; definition separator () empty, null, void ( stuff ) grouping parentheses, tuple constructor, infix to prefix [] empty list [ stuff ] list \ Lambda function operator . function composition, name qualifier | guard and case selector -> function type mapping = type or value, mathematical equality, not substitution :: type specification => context inheritance >> Monad sequencing operator >>= Monad sequencing operator with value passing >@> Monad composition operator " stuff " String constructor 'a' Character constructor ` stuff ` prefix to infix constructor _ wild card operation ~ irrefutable pattern ! force evaluation @ pattern matching :+ constructor for Complex x:+y % constructor for Rational a%b This is just a start. Corrections, additions and comments are welcome. This is meant to be similar to my other compact summaries that exists for C, C++, Fortran90, Ada95, Matlab, VHDL, Python and others I may have forgot about. Jon Squire squire@umbc.edu http://www.csee.umbc.edu/~squire