You are on page 1of 5

-- Don't worry about this line until we get to

-- module.hs
module Baby where
-- The base library. Make sure to include this in everything!
-- You won't have much of anything without this
-- By the way this is a comment.
import Prelude
multiply :: Integer -> Integer -> Integer
multiply x y = x * y
doubleMe :: Integer -> Integer
doubleMe x = multiply x 2
doubleUs :: Integer -> Integer -> Integer
doubleUs x y = doubleMe x + doubleMe y
-- The else is MADATORY, because we need
-- referential transparency
doubleSmallNumber :: Integer -> Integer
doubleSmallNumber x =
if x > 100
then x
else doubleMe x
-- Functions can contain '
doubleSmallNumber' :: Integer -> Integer
doubleSmallNumber' x =
1 + doubleSmallNumber x
{-- This is still a function by the way
But because it returns a constant, it can be
treated as a variable in your head
Having it as a function can give some
interesting properties to it as you can imagine.
In particular, it allows Haskell's lazy evaluation to work
in very intersting ways. --}
-- By the way that was a multiline comment
conanO'Brien :: String
conanO'Brien = "It's a-me, Conan O' Brien!"
-- Lists (basically arrays)
lostNumbers :: [Integer]
lostNumbers = [4, 8, 15, 16, 23, 42]
-- Use the ++ operator to concat lists
giveMeAllTheNumbers :: [Integer]
giveMeAllTheNumbers = [1, 2, 3, 4, 5] ++ [6, 7 , 8, 9, 10]
helloWorld :: [Char] -- also known as a String!
helloWorld = "Hello" ++ " " ++ "World"
-- Anything that can be performed on a list
-- can be performed on a String
-- because a "string" is just syntatic sugar for a
-- ['s', 't', 'r', 'i', 'n', 'g']
-- ... which is in itself syntatic sugar for
thisListIsVerbose :: String
thisListIsVerbose = 's' : 't' : 'r' : 'i' : 'n' : 'g' : []

-- : is the prepend operator. It adds something to the


-- front of a list. In addition, the fact that this compiles
-- proves that String is a [Char]
-- To access a list index, use !!
-- It's pretty weird, I know
accessingListIndexes :: Char
accessingListIndexes = helloWorld !! 5
-- You can also go crazy with this thing
inception :: [[[Integer]]]
inception = [[[1, 2, 3], [4, 5, 6]]]
-- Lists can be compared if the things in them
-- can be compared. All of these return True
-- Haskell compares the first element, if they're equal,
-- it compares the next and so on
comparingLists :: [Bool]
comparingLists =
([3, 2, 1] > [1, 2, 3]) : ([3, 2, 1] > [2, 10, 100]) :
([3, 4, 2] > [3, 4]) : ([3, 4, 2] < [3, 4, 5]) :
([3, 4, 2] == [3, 4, 2]) : ([3, 4, 2] /= [3, 4, 5]) : []
numbers :: [Integer]
numbers = [1, 2, 3, 4, 5]
-- Basic list functions
headOfNumbers :: Integer
headOfNumbers = head numbers -- => 1
-- Will throw!
headOfEmptyList :: Integer
headOfEmptyList = head []
tailOfNumbers :: [Integer]
tailOfNumbers = tail numbers -- => [2, 3, 4, 5]
lastOfNumbers :: Integer
lastOfNumbers = last numbers -- => 5
initOfNumbers :: [Integer]
initOfNumbers = init numbers -- => [1, 2, 3, 4]
{-- Why we need to use toInteger here is a bit
complicated, and we'll not really get into it.
Later we'll also use fromIntegral. These will come a lot
later, for now you just understand that they convert the
two different basic number types, Int and Integer. --}
lengthOfNumbers :: Integer
lengthOfNumbers = toInteger (length numbers) -- => 5
nullOfNumbers :: Bool
nullOfNumbers = null numbers -- => False
nullOfEmptyList :: Bool
nullOfEmptyList = null [] -- => True
reverseOfNumbers :: [Integer]
reverseOfNumbers = reverse numbers -- => [5, 4, 3, 2, 1]

takeFromNumbers :: Integer -> [Integer]


takeFromNumbers numItems =
take (fromIntegral numItems :: Int) numbers
-- takeFromNumbers 3 => [1, 2, 3]
dropFromNumbers :: Integer -> [Integer]
dropFromNumbers numItems =
drop (fromIntegral numItems :: Int) numbers
-- dropFromNumbers 3 => [4, 5, 6]
maxOfNumbers :: Integer
maxOfNumbers = maximum numbers -- => 6
minOfNumbers :: Integer
minOfNumbers = minimum numbers -- => 1
sumOfNumbers :: Integer
sumOfNumbers = sum numbers -- => 15
isElemOfNumbers :: Integer -> Bool
isElemOfNumbers num = num `elem` numbers
numbersUsingRanges :: [Integer]
numbersUsingRanges = [1..5] -- => [1, 2, 3, 4, 5]
lettersUsingRanges :: String
lettersUsingRanges = ['a'..'z'] -- => You know this one.
-- You can even specify steps
rangeSteps :: [Integer]
rangeSteps = [2, 4..20] -- => [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
-- Be careful when using fractional ranges!
rangeFractional :: [Double]
rangeFractional = [0.1, 0.3..1]
-- => [0.1, 0.3, 0.5, 0.7, 0.8999999999999999, 1.0999999999999999]
cycleListINF :: [Integer]
cycleListINF = cycle [1, 2, 3]
-- => [1, 2, 3, 1, 2, 3] forever and ever
-- Use Ctrl-C to stop!
repeatNumberINF :: [Integer]
repeatNumberINF = repeat 42
-- => 42 forever and ever
-- Use Ctrl-C to stop!
replicateNumber :: Integer -> Integer -> [Integer]
replicateNumber numTimes number =
replicate (fromIntegral numTimes :: Int) number
-- replicateNumber 3 10 => [10, 10, 10]
{-- List comprehesions are a way to make specific lists
out of more general lists. --}
evenNumbersListCompre :: [Integer]
evenNumbersListCompre = [x * 2 | x <- [1..10]]
-- Multiply x by 2 for every x in [1..10]
advancedListCompre :: [Integer]

advancedListCompre = [x | x <- [50..100], x `mod` 7 == 3]


-- Take every x from [50..100] where x % 7 is 3
boomBangs :: [Int] -> [String]
boomBangs list = [if x > 10 then "BOOM!" else "BANG!" |
x <- list, odd x]
-- Filters out even numbers, and then replaces them with
-- either BOOM! or BANG!
veryArbritaryListCompre :: [Integer]
veryArbritaryListCompre = [x | x <- [10..20], x /= 13, x /= 15, x /= 19]
-- [10..20] except 13, 15, and 19. Because we don't like them.
multipleListsListCompre :: [Integer]
multipleListsListCompre = [x * y | x <- [2, 5, 10], y <- [8, 10, 11]]
-- Multiplies everything in x with everything in y
lengthWithListCompre :: [a] -> Integer
lengthWithListCompre list = sum [1 | _ <- list]
-- Map every element in the list to 1. Then sum the list.
-- Generally we use _ when we don't care what the variable is
-- Strings are lists, remember!
removeNonUppercase :: String -> String
removeNonUppercase string = [c | c <- string, c `elem` ['A'..'Z']]
-- Comprehensions of lists of lists!
-- Not recommended for readability reasons.
inceptionListCompre :: [[Integer]] -> [[Integer]]
inceptionListCompre twoDimenList =
[ [x | x <- list, even x] | list <- twoDimenList ]
-- Tuples are sort of like lists, but they can
-- contain arbritary values of arbritary types.
basicTuple :: (String, Integer)
basicTuple = ("Eshan", 42)
-- Tuples have fst (first) and snd (second) methods.
-- However, note that they only work on pair tuples.
firstOfBasicTuple :: String
firstOfBasicTuple = fst basicTuple -- => "Eshan"
secondOfBasicTuple :: Integer
secondOfBasicTuple = snd basicTuple -- => 42
numberToName :: [(Integer, String)]
numberToName = zip [1..5] ["one", "two", "three", "four", "five"]
-- => [(1, "one"), (2, "two"), (3, "three"), (4, "four"), (5, "five")]
-- Haskell is lazy! [1..] is infinite. No problemo!
infiniteZip :: [(Integer, String)]
infiniteZip = zip [1..] ["apple", "orange", "cherry", "mango"]
-- => [(1,"apple"),(2,"orange"),(3,"cherry"),(4,"mango")]
thePerfectTriangle :: [(Integer, Integer, Integer)]
thePerfectTriangle =
[(a, b, c) | c <- [1..10], b <- [1..c], a <- [1..b], a^2 + b^2 == c^2, a + b +
c == 24]

-- All possible right triangles with side lengths <= 10 with


-- perimeter 24. There's actually only one, (6, 8, 10).

You might also like