Date: November 3 2021
Summary: My notes on an overview and summary on how to use Haskell
Keywords: #syntax ##summary #haskell #programming #languages #archive
Not Available
Prelude - Haskell's Standard Library Data - Common abstract data type manipulations for use within Haskell
All functions are pure within Haskell. This means that the same result is always produced with no side effects given the same input to a Haskell function.
Haskell functions are lazy. They do not evaluate until needed.
Except only in very seldom cases, type annotations are optional in Haskell.
Bool
A two element set of True
and False
.
Char
A set of all Unicode characters.
String
A synonym for an infinite list of Char
's.
()
A dummy value where there is only one instance of it ever. It is pronounced unit.
-- Unit typing example
-- Function declaration
f44 :: () -> Integer
-- Function definition
f44 () = 44
-- Function invocation
f44 () -- Returns the value 44
Haskell provides unsafeCoerce
to bypass the type system.
Example:
is_zero 0 = True
is_zero _ = False
Loops do not exist in Haskell! Rather, to do looping, one must use recursion. Here is a Haskell example that calculates the factorial of a number:
fac n = do
if n <= 1
then 1
else
n * fac (n - 1)
Requires a boolean expression that determines the definition of a function. Used most often in recursion. Example:
-- Generates a list from a given series of terms
asc :: Int -> Int -> [Int]
asc n m
| m < n = []
| m == n = [m]
| m > n = n : asc (n + 1) m
All concrete types start with a capital letter. Names of type variables start with a lowercase letter.
A function type is created by putting an arrow between two types.
f :: foo -> bar
A function definition uses the name of the function and formal parameters. The body of a function follows an equals sign. Furthermore, the body of a function is always an expression.
One of the strangest quirks about Haskell functions is that arguments are neither surrounded by parentheses nor separated by commas.
ghci
-- Defining a function within ghci
-- Requires the use of multiple lines as denoted
-- by :{ ... :}
« Prelude » λ> :{
Prelude| add :: Integer -> Integer -> Integer -- Function declaration
Prelude| add x y = x + y -- Function definition
Prelude| :}
« Prelude » λ> (add 5 3) -- Compute sum of two numbers
8
-- Creating function declaration
add :: Integer -> Integer -> Integer
-- Creating function definition
add x y = x + y
-- Compute sum of two numbers
add 5 3
Arguments can be discarded with a wildcard by the following notation:
fInt :: Integer -> ()
fInt _ = ()
Functions can be composed by putting a period between them (or a Unicode circle, "â—¦"):
-- Define two functions:
f1 :: A -> B
f2 :: B -> C
-- Compose them together:
f1 . f2
-- Or use alternative composition syntax:
f1 â—¦ f2
In Haskell, a double colon means, "has type of..."
f :: foo -> bar
Any infix operator can be turned into a two-argument function by surrounding them with parentheses:
"Hello " ++ "world!"
Can be rewritten as:
(++) "Hello " "world!"
Haskell enables you to express equality of functions:
mappend = (++)
This is also known as point-free equality as the arguments to these functions are not defined.
Haskell defines extensional equality loosely where
mappend s1 s2 = (++) s1 s2
is saying that the output of the function of the left is equivalent to the output of the function on the right. This is also known as point-wise equality as the arguments (points) are defined.
This goes in a script called hello.hs
main = do
putStrLn "Hello World!"
To load it within ghci
, open ghci
within the same repository that houses the script then run in gchi
:
:load "hello.hs"
:main
And here would be the respective output one should see
λ> :load "hello.hs"
[1 of 1] Compiling Main ( hello.hs, interpreted )
Ok, one module loaded.
λ> :main
Hello World!
To reload a previously loaded file after you make changes to the file, run :reload
.
Zelko, Jacob. Notes on Programming in Haskell. https://jacobzelko.com/11032021155827-haskell-programming. November 3 2021.