Skip to content

Instantly share code, notes, and snippets.

@jki127
Last active September 19, 2019 20:00
Show Gist options
  • Save jki127/fab3b57de935140d2cc126b27478e3f7 to your computer and use it in GitHub Desktop.
Save jki127/fab3b57de935140d2cc126b27478e3f7 to your computer and use it in GitHub Desktop.

Types in Haskell - Programming Languages - Sep 19th, 2019

Basic Types

  • Int
  • Bool
  • Char
  • String
  • []
  • Double
  • Float

Defining Types

data Bool = False | True
data Opinion = Disagree | Neutral | Agree

generateMessage :: Opinion -> String
generateMessage Agree = "It was great."
generateMessages Neutral = "Meh"
generateMessage _ = "Not tolerable."

We don’t always want types that is one of N things like in the above example

Here’s how we make a Person type that has a constructor that takes name and age

data Person = Person String Int

bob :: Person
bob = Person "Bob Smith" 99

isTooOld :: Person -> Bool
isTooOld (Person name age) = age > 65

There’s also another way to make types that looks more like a C++ struct where you can name each attribute

data Person2 = Person2 {
	personName :: String,
	personAge :: Int
}

isTooOld2 :: Person2 -> Bool
isTooOld2 person = personAge person > 65

We can combine the different versions of type declarations as well

data Point = Point Int Int
data Shape = Circle Point Int
				| Rectangle Point Point
				| Polygon [Point]

area :: Shape -> Double
area (Circle center radius) = pi * radius * radius
area (Rectangle (Point left top) (Point right bottom)) =
		(bottom-top) * (right-left)

Let’s try defining the type List for Ints (Linked List)

data IntList = Cons Int IntList
             | Null deriving Show -- deriving makes it easier to print

-- Let's use our new type
mylist :: IntList
mylist = Cons 33 (Cons 12 (Cons 9 Null))

intlistLength :: IntList -> Int
intlistLength Null = 0
intlistLength (Cons _ b) = 1 + intlistLength b

intlistSum :: IntList -> Int
intlistSum Null = 0
intlistSum (Cons a b) = a + intlistSum b

Let’s define a list that works with other types

data List a = Cons a (List a) | Null

listLength :: List a -> Int
listLength Null = 0
listLength (Cons _ b) = 1 + listLength b

-- We can't make listSum take `List a` because it won't know
-- what to do for non-Int types
listSum :: List Int -> Int
listSum Null = 0
listSum (Cons a b) = a + listSum b

mapList :: (a -> b) -> List a -> List b
mapList f Null = Null
mapList f (Cons val next) = Cons (f val) (mapList f next)

REMINDER

++ takes two lists and combines them : takes an items and prepends it to a list

In most languages, there’s a value like null or None to represent a blank value, but these lead to Null Pointer Exceptions.

In Haskell, we have Maybe

-- Maybe is a built-in type
-- data Maybe a = Just a | Nothing

myfirst :: [a] -> Maybe a 
myfirst [] = Nothing
myfirst (h:t) = Just h

Maps

In Haskell, maps are defined as Binary Search Trees.

import qualified Data.Map as Map
let mymap = Map.singleton "giraffe" (4::Int)
let mymap' = Map.insert "centipede" 100 mymap
let j = Map.lookup "giraffe" mymap` -- returns Just 4

Because Maps are BSTs this means that when you use Map.insert , the Map is not copied in memory. Haskell just adds on to the tree and makes it looks like the two maps are different variables. Maps cannot be modified

Exercise: Build a BST in Haskell

data Tree a = Node a (Tree a) (Tree a) | Leaf deriving Show

mytree :: Tree Int
mytree = Node 3 (Node 9 Leaf Leaf) (Node 2 Leaf Leaf)

#proglang-f19

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment