Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ---------------------------------------------------------------------------------
- -- This is structured to be split into the sections from the description
- -- but be able to compile as well
- ---------------------------------------------------------------------------------
- {-
- NOTEs
- add something on arrays in Haskell
- -}
- ---- Variables and Operations allowed by the language
- -- Variables are declared by using the name = value (unless declared in a function)
- myName = "Aidan" -- String
- myAge = 18 -- Int
- myHeight = 1.7 -- Float
- isMale = True -- Bool
- {-
- To declare the type of the variable, before assignment, add name::type
- This is called a type declaration signature.
- -}
- lastName::String
- lastName = "Pinard"
- seventySevenPointNine::Float
- seventySevenPointNine = 77.9
- {- Variables cannot be reassigned;
- lastName = "Phillip" <<-- error: Multiple declarations of `lastName'
- And they must begin with a lowercase letter.
- Nineteen = 19 <<-- error: Not in scope: data constructor `Nineteen'
- After the first letter they can have numbers, letters,
- underscores (_) and apostrophes ('). using an apostrophe is commonly
- used to indicate a modified version of a value.
- -}
- x' = x + 2 -- x' (x prime, like in math) is 2 larger than x
- a_vAR1A8le_NAmE = "This works"
- -- Math uses the normal operators
- x = 12 + 13 {- Note: x is declared here, is used before in x' = x + 2.
- This is due to the fact that variables cannot change. -}
- y = (10 - 5) * 3
- z::Float
- z = 13/4 {-
- This is normal division and will return a float.
- Adding z::Int before will cause an error.
- The / operator returns a float value
- (specifically a Fractional value, which is not exactly a float).
- -}
- z'::Int
- z' = 13 `div` 4 -- This is integer division
- -- Boolean operations
- notTrue = not True -- False
- notFalse = not False -- True
- probablyTrue = 1 <= 10 && ( 10 > 5 || 'a' /= 'a') && 3.5 == 3.5
- {-
- not -- inverts the Boolean
- <=, < -- less than or equal to, less than,
- >, >= -- greater than, greater than or equal to
- && -- Logical and
- || -- Logical or
- == -- equal to
- /= -- not equal to
- -}
- -- Chars, Strings, Lists
- a = 'a' -- a Char or character
- abc = "abc" -- a String. Double quotes must be used for a string.
- -- to 'add' two strings, use ++. The + operator only works on numbers
- abcdef = abc ++ "def"
- -- Printing strings is done using putStr or putStrLn
- --putStr "Hello\n" -- putStr just prints the characters
- --putStrLn "Hello" -- putStrLn prints the characters and adds a newline
- -- NOTE this must be done within an IO function (see: functions)
- -- Getting input is done using getline
- abcList = ['a', 'b', 'c'] {- A list (formally a linked list).
- All values in a list must have the same type.
- Values are separated by commas.
- -}
- {- Note: A string is a list of characters in Haskell -}
- stringAndCharList = abc == abcList -- True
- anotherName::[Char] -- the [] represent a List.
- anotherName = "Joseph" -- This compiles
- -- the ++ operator concatenates lists (hence it concatenates strings as well)
- oneToSix = [1,2] ++ [3,4,5,6]
- {- Lists can be indexed like an array using the !! operator. Note, when accessing
- a value in a list, the program will iterate through each value before the value
- you are trying to access.
- Lists in Haskell are zero indexed (Like C++ and Java)
- -}
- c = abcList !! 2 -- 'c'
- -- As strings are just Char Arrays, they can be indexed as well
- d = abcdef !! 3 -- 'd'
- -- List functions
- one = head oneToSix -- 1. head gives the first value in a list
- twoToSix = tail oneToSix -- [2,3,4,5,6]. tail returns every value but the first
- six = last oneToSix -- 6. last gives the last value in the list.
- -- Note: as lists are iterated through to get a value, the time for head and tail are constant
- -- but the time for last is dependent on the length of the list.
- zeroToSix = 0:oneToSix -- [0,1,2,3,4,5,6] : adds a value to the front of the list
- oneToTen = [1..10] -- [x..y] creates a list from x to y in increments of 1 given that x < y
- -- emptyList = [10..1]
- -- [] an empty list is returned as Haskell uses positive increments
- -- Haskell gives a warning when it detects an empty List
- evenNumbersUpToTen = [0,2..10] {- [x,y..z] creates a list from x to z.
- y is the second value and y - x is the incrementing value.
- -}
- tenToOne = [10,9..1] -- Using the increment, decreasing lists can be made
- -- Generated lists can be of non-numeric values as well
- aToZ = ['a'..'z']
- {- Haskell also allows for infinite lists. Haskell does not create a variable in
- memory immediately but whenever the value is needed it generates the required
- value. This is called Lazy evaluation. Haskell also has Datatypes which are
- very similar to mathematical concepts and can handle extremely large computations.
- The Integer datatype is one such example. (NOTE: this is not Int. Int is similar to
- int in C++, while Integer is a Haskell expression of the mathematical concept of an
- integer.)
- -}
- oneToInfinity = [1..]
- -- List comprehension
- -- List comprehension is a method of creating lists and modifying them immediately
- squaresToFive = [x*x | x <- [1..5]] {- For the values 1 to 5 ([1..5]),
- save each in x, (x <- ) and apply the operation x*x.
- [operation | temporary_variable <- [list to operate on]]
- a similar c++ equivalent
- int x[5] = {1,2,3,4,5};
- for( int i = 0; i < 5; i++) {
- x[i] = x[i]*x[i];
- }
- // for each value in the array, square it.
- -}
- squaresLessThanTen = [x*x | x <- [1..5], x*x < 10]{- Same as above, except only add
- the squares which are less than 10.
- [operation | temporary_variable <- [list to operate on], condition]
- -}
- -- Tuples
- -- Tuples are a way of quickly grouping together 2 values that may be related
- parse17 = (True, 17) {- A function which parses a string as an integer may return
- a tuple with a Bool indicating whether the parse failed and an Int for a successful
- parse.
- -}
- thingsIKnow = ("math", 13, ['h', 'o', 'u', 's', 'e'], 55.676, ("car", "house"))
- -- Tuples can be of any length, and hold any other datatype, including other tuples.
- -- Tuples with 2 values (pair) are most commonly used, and have functions which
- -- return values in them
- parseSucceeded = fst parse17 -- Gets the first value in a pair
- parseValue = snd parse17 -- Gets the second value in a pair
- -- These functions only work on pairs
- -- fst ("house", "car", 2323) -- gives an error
- -- Tuples can also be "decomposed" immediately upon access, instead of using fst and snd
- -- This can work with tuples of any size
- (parseSucceeded', parseValue') = parse17 -- Splits parse17 into two variables
- -- A _ can be used to ignore values
- (_,_,_,number,_) = thingsIKnow
- {- ignores the first, second, third and fifth values and assigns the
- fourth to number
- -}
- ---- Decision and Conditional Statements
- -- If statements
- hello = if myAge < 18 then "hello small child" else "Hello Adult Person"
- {- The if then else function requires options for all cases.
- As variables cannot be changed, the value of an If then else is
- usually directly assigned to a variable. Haskell does not allow for
- accidental nonexistent values (like some functions returning null
- in C style languages), so each value must exist. For situations where
- a value may or may not exist, Haskell provides the Maybe type.
- -}
- -- Conditionals can also be done on function parameters (see Functions).
- ---- Loops
- {- Since Haskell is a functional language and variables cannot be reassigned,
- if statements are slightly different and normal for/while/dowhile loops do
- not exist, as those constructs are meant for imperative languages. Looping
- is done using recursion. (See Functions)
- Looping over a list or similar can be done using the map function
- -}
- rootsTo100 = map sqrt [1..100] -- apply the function sqrt to each value in the list [1..100]
- -- rootsTo100 is now [1, 1.4142, ...., 10]
- ---- Functions
- {- Functions in Haskell can get very complicated for persons new to functional
- programming, but at a basic level, it is just like math.
- -}
- -- Functions are declared just like variables, with parameters between the name
- -- and the = . Functions parameters in Haskell are simply separated by spaces
- add a b = a + b -- Takes parameters a and b and returns the last operation
- sevenTeen = add 10 7 -- 10 + 7 = seventeen
- -- Functions also have type signatures, and they define the return type and
- -- the types of the parameters
- addThreeInts::Int -> Int -> Int -> Int
- -- The last value is the return value, and the other values show the parameters
- -- the -> shows how the values are separated (They have a specific meaning which comes
- -- from how Haskell works with functions (see partial application))
- addThreeInts a b c = a + b + c
- fifty = addThreeInts 15 18 22 -- Adds the three integers
- -- Functions with multiple lines
- aToBList a b =
- if a < b then
- [a..b]
- else
- [b..a]
- -- Functions which execute differently depending on their
- -- parameters can be expressed using guards
- aToBList' a b
- | a < b = [a..b] -- if a less than b make a list from a to b
- | b < a = [b..a] -- else make a list from b to a
- | otherwise = []
- -- if they cannot be compared then return an empty list.
- -- otherwise is
- -- You can also make infix functions/operators (like for math etc)
- -- A custom math operator to quickly get the hypotenuse from two sides
- (<!>) a b = sqrt $ a^2 + b^2
- five = 3 <!> 4 -- Note, brackets are not used when calling the function
- thirteen = (<!>) 5 12 -- they can also be called like normal functions with brackets
- -- or to do integer division more easily
- (//) a b = a `div` b
- twelve = 150 // 12
- -- normal functions with two parameters can also be called as infix operators
- -- using backticks
- fourteen = 12 `add` 2
- -- tuple pattern matching can also be done with functions to extract values
- sumOfQuintuple (a,b,c,d,e) = a + b + c + d + e
- -- as well as to ignore values
- -- fst and snd are defined as
- fst' (x, _) = x
- snd' (_, y) = y
- -- Functions in Haskell return the last value/line in the function
- -- Sometimes, longer functions may be more difficult to understand what
- -- it returns, so they can be expressed using the where clause
- roots (a,b,c) = (x1, x2) where
- x1 = e + sqrt d / (2 * a)
- x2 = e - sqrt d / (2 * a)
- d = b * b - 4 * a * c
- e = - b / (2 * a)
- -- We define a function called roots, which takes a tuple of 3 values
- -- representing a polynomial (ax^2 + bx + c) and returns the roots of
- -- the function as a tuple (x1, x2). Here we state the return value first
- -- then define what each value represents. Remember, variables in Haskell
- -- can be defined before use, as they are static values (i.e. they will
- -- always be the same, so they can be replaced by their values).
- -- Note this is similar to mathematical equations, where you state the
- -- equation, then state what each value represents
- -- (Area of a square = x^2 *where* x is the length of one side)
- ----------------------------------------------------------
- -- ADD SOMETHING FOR RECURSION
- ----------------------------------------------------------
- (%) = mod
- -- Partial application
- -- Partial application is a large part of functional programming
- -- In imperative languages like c++, all the parameters to a function
- -- must be provided anywhere the function is used
- -- In Haskell, if you do not provide all the arguments to a function,
- -- it simply returns a function which takes the remaining arguments
- -- as parameters. For example:
- add1 = add 1 -- Partially applies the add function from before
- -- Then you can use add1 x in the same way as add 1 x
- fourtyFive = add1 44
- fourtyFive' = add 1 44
- -- These two functions are equivalent
- -- The -> in the type declaration for a function represents the partial
- -- application. E.g. Int -> Int -> Float is a function that takes int,
- -- then returns [a function that then takes int and returns float.]
- -- Partial application is used in situations where a certain
- -- function is repeatedly given the same argument, so it is abridged to
- -- a shorter function call
- aVeryLongVariableNameForAList = [1..100]
- getPosition list index = list !! index
- indexLongList = getPosition aVeryLongVariableNameForAList
- -- Now indexLongList can be used instead of getPosition aVeryLongVariableNameForAList.
- -- There are also functions which can accept functions as parameters
- -- For example, the map function accepts a function and a list or array
- -- and applies the function to each value in the list, and returns a new
- -- list of the new values
- twoToEleven = map add1 [1..10] -- applies add1 to each value in the list
- -- and returns the new values as a list
- -- Sometimes, you may want to apply a onetime function to a list so
- -- you can use an anonymous function, also called a lambda function
- -- with the map.
- oneToHundred = map (\ x -> x*2) [1..10]
- -- lambda functions are declared as
- -- (\ parameters -> processing and return value)
- helloWorld = (\ a b c -> a++b++c) ("Hello") (" ") ("World!")
- -- a function that concatenates the three strings to form the full string
- ----------------
- -- IO Functions
- ----------------
- -- Functions that use any form of IO in Haskell are different to normal
- -- functions. These have side effects (i.e. their output can depend on
- -- things other than just their input). A function has no side effects
- -- if for a given input value, the function will always output the exact
- -- same thing. If a function depends on IO, (i.e. reading input from a
- -- console, or writing to a file[which may or may not fail], etc.) it's
- -- output and the way it processes information can differ. Unlike normal
- -- variables, which are static values for their lifetime, IO variables
- -- are actually functions from which a value can be extracted and stored
- -- as a normal variable.
- -- ------ ------ -- -- - --- ----- --
- -- ADD THE EXAMPLE FROM MONADIC BIND MEDIUM ARTICLE
- {--
- arq a b =
- if myAge < 10 then
- 5
- else
- 6
- a + b
- --}
- sumto10 = foldl (+) 0 [1..10]
- -- The main function
- main = do
- putStrLn myName
- putStrLn aToZ
- putStrLn "Enter something to say: "
- x <- getLine
- putStrLn x
- putStrLn $ aToBList 'a' 'r'
- putStrLn $ aToBList 'a' 'q'
- print sumto10
- putStrLn $ show $ 12 <!> 15
- putStrLn $ addWords "Hello"
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement