![Page 1: Functional Programming - Gasi · Functional Programming Or: How I Learned to Stop Worrying and Love Shipping Haskell Code & for *after accomplishing step 2: ??? Daniel Gąsienica](https://reader034.vdocuments.us/reader034/viewer/2022050609/5fb07a259f1d662eb432a75f/html5/thumbnails/1.jpg)
Fun Profit*
Functional Programming
Or: How I Learned to Stop Worrying and Love Shipping Haskell Code
&for
*after accomplishing step 2: ???Daniel Gąsienica March 17, 2017
![Page 2: Functional Programming - Gasi · Functional Programming Or: How I Learned to Stop Worrying and Love Shipping Haskell Code & for *after accomplishing step 2: ??? Daniel Gąsienica](https://reader034.vdocuments.us/reader034/viewer/2022050609/5fb07a259f1d662eb432a75f/html5/thumbnails/2.jpg)
Amuse-BouchesBackground
Food for Thought*
*Opinions
![Page 3: Functional Programming - Gasi · Functional Programming Or: How I Learned to Stop Worrying and Love Shipping Haskell Code & for *after accomplishing step 2: ??? Daniel Gąsienica](https://reader034.vdocuments.us/reader034/viewer/2022050609/5fb07a259f1d662eb432a75f/html5/thumbnails/3.jpg)
What this talk is about
![Page 4: Functional Programming - Gasi · Functional Programming Or: How I Learned to Stop Worrying and Love Shipping Haskell Code & for *after accomplishing step 2: ??? Daniel Gąsienica](https://reader034.vdocuments.us/reader034/viewer/2022050609/5fb07a259f1d662eb432a75f/html5/thumbnails/4.jpg)
What this talk is not about
![Page 5: Functional Programming - Gasi · Functional Programming Or: How I Learned to Stop Worrying and Love Shipping Haskell Code & for *after accomplishing step 2: ??? Daniel Gąsienica](https://reader034.vdocuments.us/reader034/viewer/2022050609/5fb07a259f1d662eb432a75f/html5/thumbnails/5.jpg)
Background
![Page 6: Functional Programming - Gasi · Functional Programming Or: How I Learned to Stop Worrying and Love Shipping Haskell Code & for *after accomplishing step 2: ??? Daniel Gąsienica](https://reader034.vdocuments.us/reader034/viewer/2022050609/5fb07a259f1d662eb432a75f/html5/thumbnails/6.jpg)
ETH 2011
![Page 7: Functional Programming - Gasi · Functional Programming Or: How I Learned to Stop Worrying and Love Shipping Haskell Code & for *after accomplishing step 2: ??? Daniel Gąsienica](https://reader034.vdocuments.us/reader034/viewer/2022050609/5fb07a259f1d662eb432a75f/html5/thumbnails/7.jpg)
![Page 8: Functional Programming - Gasi · Functional Programming Or: How I Learned to Stop Worrying and Love Shipping Haskell Code & for *after accomplishing step 2: ??? Daniel Gąsienica](https://reader034.vdocuments.us/reader034/viewer/2022050609/5fb07a259f1d662eb432a75f/html5/thumbnails/8.jpg)
![Page 9: Functional Programming - Gasi · Functional Programming Or: How I Learned to Stop Worrying and Love Shipping Haskell Code & for *after accomplishing step 2: ??? Daniel Gąsienica](https://reader034.vdocuments.us/reader034/viewer/2022050609/5fb07a259f1d662eb432a75f/html5/thumbnails/9.jpg)
Thanksgiving 2015
Photo: https://commons.wikimedia.org/wiki/User:Braniff747SP
![Page 10: Functional Programming - Gasi · Functional Programming Or: How I Learned to Stop Worrying and Love Shipping Haskell Code & for *after accomplishing step 2: ??? Daniel Gąsienica](https://reader034.vdocuments.us/reader034/viewer/2022050609/5fb07a259f1d662eb432a75f/html5/thumbnails/10.jpg)
zoomhub
![Page 11: Functional Programming - Gasi · Functional Programming Or: How I Learned to Stop Worrying and Love Shipping Haskell Code & for *after accomplishing step 2: ??? Daniel Gąsienica](https://reader034.vdocuments.us/reader034/viewer/2022050609/5fb07a259f1d662eb432a75f/html5/thumbnails/11.jpg)
ZoomHub
http://zoomhub.net?url=http://www.rhysy.net/Timeline/LargeTimeline.png
Image URL
Zoomable Image
http://zoomhub.net/K4J1
![Page 12: Functional Programming - Gasi · Functional Programming Or: How I Learned to Stop Worrying and Love Shipping Haskell Code & for *after accomplishing step 2: ??? Daniel Gąsienica](https://reader034.vdocuments.us/reader034/viewer/2022050609/5fb07a259f1d662eb432a75f/html5/thumbnails/12.jpg)
Amuse-Bouches
![Page 13: Functional Programming - Gasi · Functional Programming Or: How I Learned to Stop Worrying and Love Shipping Haskell Code & for *after accomplishing step 2: ??? Daniel Gąsienica](https://reader034.vdocuments.us/reader034/viewer/2022050609/5fb07a259f1d662eb432a75f/html5/thumbnails/13.jpg)
Immutability &
The Value of Values
![Page 14: Functional Programming - Gasi · Functional Programming Or: How I Learned to Stop Worrying and Love Shipping Haskell Code & for *after accomplishing step 2: ??? Daniel Gąsienica](https://reader034.vdocuments.us/reader034/viewer/2022050609/5fb07a259f1d662eb432a75f/html5/thumbnails/14.jpg)
The Pain
![Page 15: Functional Programming - Gasi · Functional Programming Or: How I Learned to Stop Worrying and Love Shipping Haskell Code & for *after accomplishing step 2: ??? Daniel Gąsienica](https://reader034.vdocuments.us/reader034/viewer/2022050609/5fb07a259f1d662eb432a75f/html5/thumbnails/15.jpg)
* Fixed in recent versions of WebKit/Chrome
*
![Page 16: Functional Programming - Gasi · Functional Programming Or: How I Learned to Stop Worrying and Love Shipping Haskell Code & for *after accomplishing step 2: ??? Daniel Gąsienica](https://reader034.vdocuments.us/reader034/viewer/2022050609/5fb07a259f1d662eb432a75f/html5/thumbnails/16.jpg)
The Bugs
![Page 17: Functional Programming - Gasi · Functional Programming Or: How I Learned to Stop Worrying and Love Shipping Haskell Code & for *after accomplishing step 2: ??? Daniel Gąsienica](https://reader034.vdocuments.us/reader034/viewer/2022050609/5fb07a259f1d662eb432a75f/html5/thumbnails/17.jpg)
var config = { //... baseURL: 'http://api.zynga.com', //...}
function bar(config) { console.log(config.baseURL.length)}
![Page 18: Functional Programming - Gasi · Functional Programming Or: How I Learned to Stop Worrying and Love Shipping Haskell Code & for *after accomplishing step 2: ??? Daniel Gąsienica](https://reader034.vdocuments.us/reader034/viewer/2022050609/5fb07a259f1d662eb432a75f/html5/thumbnails/18.jpg)
var config = { //... baseURL: 'http://api.zynga.com', //...}
function bar(config) { // NPE console.log(config.baseURL.length)}
![Page 19: Functional Programming - Gasi · Functional Programming Or: How I Learned to Stop Worrying and Love Shipping Haskell Code & for *after accomplishing step 2: ??? Daniel Gąsienica](https://reader034.vdocuments.us/reader034/viewer/2022050609/5fb07a259f1d662eb432a75f/html5/thumbnails/19.jpg)
var config = { //... baseURL: 'http://api.zynga.com', //...}
function foo(config) { // Don’t ask me why but… delete config.baseURL}
function bar(config) { // NPE console.log(config.baseURL.length)}
![Page 20: Functional Programming - Gasi · Functional Programming Or: How I Learned to Stop Worrying and Love Shipping Haskell Code & for *after accomplishing step 2: ??? Daniel Gąsienica](https://reader034.vdocuments.us/reader034/viewer/2022050609/5fb07a259f1d662eb432a75f/html5/thumbnails/20.jpg)
![Page 21: Functional Programming - Gasi · Functional Programming Or: How I Learned to Stop Worrying and Love Shipping Haskell Code & for *after accomplishing step 2: ??? Daniel Gąsienica](https://reader034.vdocuments.us/reader034/viewer/2022050609/5fb07a259f1d662eb432a75f/html5/thumbnails/21.jpg)
The Confusion
![Page 22: Functional Programming - Gasi · Functional Programming Or: How I Learned to Stop Worrying and Love Shipping Haskell Code & for *after accomplishing step 2: ??? Daniel Gąsienica](https://reader034.vdocuments.us/reader034/viewer/2022050609/5fb07a259f1d662eb432a75f/html5/thumbnails/22.jpg)
> 1 === 1true
> true === truetrue
> "hello" === "hello"true
![Page 23: Functional Programming - Gasi · Functional Programming Or: How I Learned to Stop Worrying and Love Shipping Haskell Code & for *after accomplishing step 2: ??? Daniel Gąsienica](https://reader034.vdocuments.us/reader034/viewer/2022050609/5fb07a259f1d662eb432a75f/html5/thumbnails/23.jpg)
> 1 === 1true
> true === truetrue
> "hello" === "hello"true
> [] === []false
> [1, 2] === [1, 2]false
> {} === {}false
> {"a": "b"} === {"a": "b"}false
![Page 24: Functional Programming - Gasi · Functional Programming Or: How I Learned to Stop Worrying and Love Shipping Haskell Code & for *after accomplishing step 2: ??? Daniel Gąsienica](https://reader034.vdocuments.us/reader034/viewer/2022050609/5fb07a259f1d662eb432a75f/html5/thumbnails/24.jpg)
> 1 === 1true
> true === truetrue
> "hello" === "hello"true
> 1 == 1True
> True == TrueTrue
> "hello" == "hello"True
> [] == []True
> [1, 2] == [1, 2]True
> Map.fromList [] == Map.fromList []True
> Map.fromList [("a", "b")] == Map.fromList [("a", "b")]True
> [] === []false
> [1, 2] === [1, 2]false
> {} === {}false
> {"a": "b"} === {"a": "b"}false
![Page 25: Functional Programming - Gasi · Functional Programming Or: How I Learned to Stop Worrying and Love Shipping Haskell Code & for *after accomplishing step 2: ??? Daniel Gąsienica](https://reader034.vdocuments.us/reader034/viewer/2022050609/5fb07a259f1d662eb432a75f/html5/thumbnails/25.jpg)
> let a = [3, 1, 2]
> let b = a.sort()
> b[1, 2, 3]
![Page 26: Functional Programming - Gasi · Functional Programming Or: How I Learned to Stop Worrying and Love Shipping Haskell Code & for *after accomplishing step 2: ??? Daniel Gąsienica](https://reader034.vdocuments.us/reader034/viewer/2022050609/5fb07a259f1d662eb432a75f/html5/thumbnails/26.jpg)
> let a = [3, 1, 2]
> let b = a.sort()
> b[1, 2, 3]
> a[1, 2, 3]
![Page 27: Functional Programming - Gasi · Functional Programming Or: How I Learned to Stop Worrying and Love Shipping Haskell Code & for *after accomplishing step 2: ??? Daniel Gąsienica](https://reader034.vdocuments.us/reader034/viewer/2022050609/5fb07a259f1d662eb432a75f/html5/thumbnails/27.jpg)
> let a = [3, 1, 2]
> let b = sort a
> b[1, 2, 3]
> a[3, 1, 2]
> let a = [3, 1, 2]
> let b = a.sort()
> b[1, 2, 3]
> a[1, 2, 3]
— space = function— application— i.e. JavaScript: sort(a)
![Page 28: Functional Programming - Gasi · Functional Programming Or: How I Learned to Stop Worrying and Love Shipping Haskell Code & for *after accomplishing step 2: ??? Daniel Gąsienica](https://reader034.vdocuments.us/reader034/viewer/2022050609/5fb07a259f1d662eb432a75f/html5/thumbnails/28.jpg)
ConclusionAbandon distinction between
values and references and treat everything as
immutable values.
![Page 30: Functional Programming - Gasi · Functional Programming Or: How I Learned to Stop Worrying and Love Shipping Haskell Code & for *after accomplishing step 2: ??? Daniel Gąsienica](https://reader034.vdocuments.us/reader034/viewer/2022050609/5fb07a259f1d662eb432a75f/html5/thumbnails/30.jpg)
nullThe Billion-Dollar Mistake
![Page 31: Functional Programming - Gasi · Functional Programming Or: How I Learned to Stop Worrying and Love Shipping Haskell Code & for *after accomplishing step 2: ??? Daniel Gąsienica](https://reader034.vdocuments.us/reader034/viewer/2022050609/5fb07a259f1d662eb432a75f/html5/thumbnails/31.jpg)
“I call it my billion-dollar mistake. It was the invention of
the null reference in 1965.”— C. A. R. Hoare
![Page 32: Functional Programming - Gasi · Functional Programming Or: How I Learned to Stop Worrying and Love Shipping Haskell Code & for *after accomplishing step 2: ??? Daniel Gąsienica](https://reader034.vdocuments.us/reader034/viewer/2022050609/5fb07a259f1d662eb432a75f/html5/thumbnails/32.jpg)
boolean string number object
![Page 33: Functional Programming - Gasi · Functional Programming Or: How I Learned to Stop Worrying and Love Shipping Haskell Code & for *after accomplishing step 2: ??? Daniel Gąsienica](https://reader034.vdocuments.us/reader034/viewer/2022050609/5fb07a259f1d662eb432a75f/html5/thumbnails/33.jpg)
boolean string number object
any
![Page 34: Functional Programming - Gasi · Functional Programming Or: How I Learned to Stop Worrying and Love Shipping Haskell Code & for *after accomplishing step 2: ??? Daniel Gąsienica](https://reader034.vdocuments.us/reader034/viewer/2022050609/5fb07a259f1d662eb432a75f/html5/thumbnails/34.jpg)
boolean string number object
any
![Page 35: Functional Programming - Gasi · Functional Programming Or: How I Learned to Stop Worrying and Love Shipping Haskell Code & for *after accomplishing step 2: ??? Daniel Gąsienica](https://reader034.vdocuments.us/reader034/viewer/2022050609/5fb07a259f1d662eb432a75f/html5/thumbnails/35.jpg)
boolean string number object
any
null
![Page 36: Functional Programming - Gasi · Functional Programming Or: How I Learned to Stop Worrying and Love Shipping Haskell Code & for *after accomplishing step 2: ??? Daniel Gąsienica](https://reader034.vdocuments.us/reader034/viewer/2022050609/5fb07a259f1d662eb432a75f/html5/thumbnails/36.jpg)
boolean string number object
any
null
![Page 37: Functional Programming - Gasi · Functional Programming Or: How I Learned to Stop Worrying and Love Shipping Haskell Code & for *after accomplishing step 2: ??? Daniel Gąsienica](https://reader034.vdocuments.us/reader034/viewer/2022050609/5fb07a259f1d662eb432a75f/html5/thumbnails/37.jpg)
let names = ["Aseem", "Matt"]let isCool = x => x.length <= 4let name = names.find(isCool)console.log(name.toUpperCase())// > MATT
![Page 38: Functional Programming - Gasi · Functional Programming Or: How I Learned to Stop Worrying and Love Shipping Haskell Code & for *after accomplishing step 2: ??? Daniel Gąsienica](https://reader034.vdocuments.us/reader034/viewer/2022050609/5fb07a259f1d662eb432a75f/html5/thumbnails/38.jpg)
let names = ["Aseem", "Matt"]let isCool = x => x.length <= 4let name = names.find(isCool)console.log(name.toUpperCase())// > MATT
let names = ["Aseem"]let isCool = x => x.length <= 4let name = names.find(isCool)console.log(name.toUpperCase())
// console.log(name.toUpperCase())// ^//// TypeError: Cannot read property// 'toUpperCase' of undefined
![Page 39: Functional Programming - Gasi · Functional Programming Or: How I Learned to Stop Worrying and Love Shipping Haskell Code & for *after accomplishing step 2: ??? Daniel Gąsienica](https://reader034.vdocuments.us/reader034/viewer/2022050609/5fb07a259f1d662eb432a75f/html5/thumbnails/39.jpg)
main = do let names = ["Aseem", "Matt"] isCool x = length x <= 4 name = find isCool names print (toUpperCase name)
-- null.hs:5:22:-- Coudn't match expected type ‘String’-- with actual type ‘Maybe String’-- In the first argument of ‘toUpperCase’,-- namely ‘name’-- In the first argument of ‘print’,-- namely ‘(toUpperCase name)’
let names = ["Aseem", "Matt"]let isCool = x => x.length <= 4let name = names.find(isCool)console.log(name.toUpperCase())// > MATT
let names = ["Aseem"]let isCool = x => x.length <= 4let name = names.find(isCool)console.log(name.toUpperCase())
// console.log(name.toUpperCase())// ^//// TypeError: Cannot read property// 'toUpperCase' of undefined
![Page 40: Functional Programming - Gasi · Functional Programming Or: How I Learned to Stop Worrying and Love Shipping Haskell Code & for *after accomplishing step 2: ??? Daniel Gąsienica](https://reader034.vdocuments.us/reader034/viewer/2022050609/5fb07a259f1d662eb432a75f/html5/thumbnails/40.jpg)
find :: (a -> Bool) -> [a] -> Maybe aArray<A>.find( predicate: (value: A) => boolean): A | null
![Page 41: Functional Programming - Gasi · Functional Programming Or: How I Learned to Stop Worrying and Love Shipping Haskell Code & for *after accomplishing step 2: ??? Daniel Gąsienica](https://reader034.vdocuments.us/reader034/viewer/2022050609/5fb07a259f1d662eb432a75f/html5/thumbnails/41.jpg)
data Maybe a = Just a | Nothing
![Page 42: Functional Programming - Gasi · Functional Programming Or: How I Learned to Stop Worrying and Love Shipping Haskell Code & for *after accomplishing step 2: ??? Daniel Gąsienica](https://reader034.vdocuments.us/reader034/viewer/2022050609/5fb07a259f1d662eb432a75f/html5/thumbnails/42.jpg)
data Maybe a = Just a | Nothing
foo :: Maybe Intfoo = Just 5orfoo = Nothing
bar :: Maybe Stringbar = Just "Hello"or bar = Nothing
![Page 43: Functional Programming - Gasi · Functional Programming Or: How I Learned to Stop Worrying and Love Shipping Haskell Code & for *after accomplishing step 2: ??? Daniel Gąsienica](https://reader034.vdocuments.us/reader034/viewer/2022050609/5fb07a259f1d662eb432a75f/html5/thumbnails/43.jpg)
let names = ["Aseem"]let isCool = x => x.length <= 4let name = names.find(isCool)console.log(name ? name.toUpperCase() : "nuddin")// nuddin
![Page 44: Functional Programming - Gasi · Functional Programming Or: How I Learned to Stop Worrying and Love Shipping Haskell Code & for *after accomplishing step 2: ??? Daniel Gąsienica](https://reader034.vdocuments.us/reader034/viewer/2022050609/5fb07a259f1d662eb432a75f/html5/thumbnails/44.jpg)
main = do let names = ["Aseem"] isCool x = length x <= 4 name = find isCool names print (case name of Just s -> toUpperCase s Nothing -> "nuddin" )-- nuddin
let names = ["Aseem"]let isCool = x => x.length <= 4let name = names.find(isCool)console.log(name ? name.toUpperCase() : "nuddin")// nuddin
![Page 45: Functional Programming - Gasi · Functional Programming Or: How I Learned to Stop Worrying and Love Shipping Haskell Code & for *after accomplishing step 2: ??? Daniel Gąsienica](https://reader034.vdocuments.us/reader034/viewer/2022050609/5fb07a259f1d662eb432a75f/html5/thumbnails/45.jpg)
ConclusionUnhandled nulls can
cause unexpected runtime errors.
Explicitly model the presence and absence of values and
enforce handling of all cases.
![Page 46: Functional Programming - Gasi · Functional Programming Or: How I Learned to Stop Worrying and Love Shipping Haskell Code & for *after accomplishing step 2: ??? Daniel Gąsienica](https://reader034.vdocuments.us/reader034/viewer/2022050609/5fb07a259f1d662eb432a75f/html5/thumbnails/46.jpg)
Types
![Page 47: Functional Programming - Gasi · Functional Programming Or: How I Learned to Stop Worrying and Love Shipping Haskell Code & for *after accomplishing step 2: ??? Daniel Gąsienica](https://reader034.vdocuments.us/reader034/viewer/2022050609/5fb07a259f1d662eb432a75f/html5/thumbnails/47.jpg)
First-Class Compile-Time
Type Safety
![Page 48: Functional Programming - Gasi · Functional Programming Or: How I Learned to Stop Worrying and Love Shipping Haskell Code & for *after accomplishing step 2: ??? Daniel Gąsienica](https://reader034.vdocuments.us/reader034/viewer/2022050609/5fb07a259f1d662eb432a75f/html5/thumbnails/48.jpg)
data User = User { userId :: UserId , userEmail :: Email } deriving Show
newtype Email = Email String deriving Shownewtype UserId = UserId String deriving Show
createUser :: UserId -> Email -> UsercreateUser userId userEmail = User { userId = userId, userEmail = userEmail }
-- Mainmain = do let email = Email "[email protected]" userId = UserId "3490" print (createUser email userId)
{- types-user.hs:16:21: Couldn't match expected type ‘UserId’ with actual type ‘Email’ In the first argument of ‘createUser’, namely ‘email’ In the first argument of ‘print’, namely ‘(createUser email userId)’
types-user.hs:16:27: Couldn't match expected type ‘Email’ with actual type ‘UserId’ In the second argument of ‘createUser’, namely ‘userId’ In the first argument of ‘print’, namely ‘(createUser email userId)’-}
![Page 49: Functional Programming - Gasi · Functional Programming Or: How I Learned to Stop Worrying and Love Shipping Haskell Code & for *after accomplishing step 2: ??? Daniel Gąsienica](https://reader034.vdocuments.us/reader034/viewer/2022050609/5fb07a259f1d662eb432a75f/html5/thumbnails/49.jpg)
class User { private userId: string private userEmail: string
constructor(userId: string, userEmail: string) { this.userId = userId this.userEmail = userEmail }}
// Mainlet email = '[email protected]'let userId = '3490'
console.log(new User(email, userId))// User { userId: '[email protected]', userEmail: '3490' }
![Page 50: Functional Programming - Gasi · Functional Programming Or: How I Learned to Stop Worrying and Love Shipping Haskell Code & for *after accomplishing step 2: ??? Daniel Gąsienica](https://reader034.vdocuments.us/reader034/viewer/2022050609/5fb07a259f1d662eb432a75f/html5/thumbnails/50.jpg)
data User = User { userId :: UserId , userEmail :: Email } deriving Show
class User { private userId: string private userEmail: string
constructor(userId: string userEmail: string) { this.userId = userId this.userEmail = userEmail }}
// `deriving Show` is explicit generation// of `Object.prototype.toString()`
![Page 51: Functional Programming - Gasi · Functional Programming Or: How I Learned to Stop Worrying and Love Shipping Haskell Code & for *after accomplishing step 2: ??? Daniel Gąsienica](https://reader034.vdocuments.us/reader034/viewer/2022050609/5fb07a259f1d662eb432a75f/html5/thumbnails/51.jpg)
createUser :: UserId -> Email -> UsercreateUser userId userEmail = User { userId = userId , userEmail = userEmail }
class User { private userId: string private userEmail: string
constructor(userId: string, userEmail: string) { this.userId = userId this.userEmail = userEmail }}
// function createUser(// userId: UserId,// userEmail: Email// ): User
![Page 52: Functional Programming - Gasi · Functional Programming Or: How I Learned to Stop Worrying and Love Shipping Haskell Code & for *after accomplishing step 2: ??? Daniel Gąsienica](https://reader034.vdocuments.us/reader034/viewer/2022050609/5fb07a259f1d662eb432a75f/html5/thumbnails/52.jpg)
-- Mainmain = do let email = Email "[email protected]" userId = UserId "3490" print (createUser email userId)
{- types-user.hs:16:21: Couldn't match expected type ‘UserId’ with actual type ‘Email’ In the first argument of ‘createUser’, namely ‘email’ In the first argument of ‘print’, namely ‘(createUser email userId)’
types-user.hs:16:27: Couldn't match expected type ‘Email’ with actual type ‘UserId’ In the second argument of ‘createUser’, namely ‘userId’ In the first argument of ‘print’, namely ‘(createUser email userId)’-}
// Mainlet email = '[email protected]'let userId = '3490'
console.log(new User(email, userId))// User { userId: '[email protected]',// userEmail: '3490' }
![Page 53: Functional Programming - Gasi · Functional Programming Or: How I Learned to Stop Worrying and Love Shipping Haskell Code & for *after accomplishing step 2: ??? Daniel Gąsienica](https://reader034.vdocuments.us/reader034/viewer/2022050609/5fb07a259f1d662eb432a75f/html5/thumbnails/53.jpg)
(Awkward) ‘Solution’
![Page 54: Functional Programming - Gasi · Functional Programming Or: How I Learned to Stop Worrying and Love Shipping Haskell Code & for *after accomplishing step 2: ??? Daniel Gąsienica](https://reader034.vdocuments.us/reader034/viewer/2022050609/5fb07a259f1d662eb432a75f/html5/thumbnails/54.jpg)
class User { private userId: UserId private userEmail: Email
constructor(userId: UserId, userEmail: Email) { this.userId = userId this.userEmail = userEmail }}
type Email = string & {_emailBrand: any}type UserId = string & {_userIdBrand: any}
// Mainlet email = '[email protected]' as Emaillet userId = '3490' as UserId
console.log(new User(email, userId))// Argument of type 'Email' is not assignable to parameter of type 'UserId'.// Type 'Email' is not assignable to type '{ _userIdBrand: any; }'.// Property '_userIdBrand' is missing in type 'Email'.
![Page 55: Functional Programming - Gasi · Functional Programming Or: How I Learned to Stop Worrying and Love Shipping Haskell Code & for *after accomplishing step 2: ??? Daniel Gąsienica](https://reader034.vdocuments.us/reader034/viewer/2022050609/5fb07a259f1d662eb432a75f/html5/thumbnails/55.jpg)
newtype Email = Email String deriving Shownewtype UserId = UserId String deriving Show
-- Mainmain = do let email = Email "[email protected]" userId = UserId "3490" print (createUser email userId)
![Page 56: Functional Programming - Gasi · Functional Programming Or: How I Learned to Stop Worrying and Love Shipping Haskell Code & for *after accomplishing step 2: ??? Daniel Gąsienica](https://reader034.vdocuments.us/reader034/viewer/2022050609/5fb07a259f1d662eb432a75f/html5/thumbnails/56.jpg)
type Email = string & {_emailBrand: any}type UserId = string & {_userIdBrand: any}
// Mainlet email = '[email protected]' as Emaillet userId = '3490' as UserIdconsole.log(new User(email, userId))
newtype Email = Email String deriving Shownewtype UserId = UserId String deriving Show
-- Mainmain = do let email = Email "[email protected]" userId = UserId "3490" print (createUser email userId)
![Page 57: Functional Programming - Gasi · Functional Programming Or: How I Learned to Stop Worrying and Love Shipping Haskell Code & for *after accomplishing step 2: ??? Daniel Gąsienica](https://reader034.vdocuments.us/reader034/viewer/2022050609/5fb07a259f1d662eb432a75f/html5/thumbnails/57.jpg)
type Email = string & {_emailBrand: any}type UserId = string & {_userIdBrand: any}
// Mainlet email = '[email protected]' as Emaillet userId = '3490' as UserIdconsole.log(new User(email, userId))
newtype Email = Email String deriving Shownewtype UserId = UserId String deriving Show
-- Mainmain = do let email = Email "[email protected]" userId = UserId "3490" print (createUser email userId)
Language Feature
![Page 58: Functional Programming - Gasi · Functional Programming Or: How I Learned to Stop Worrying and Love Shipping Haskell Code & for *after accomplishing step 2: ??? Daniel Gąsienica](https://reader034.vdocuments.us/reader034/viewer/2022050609/5fb07a259f1d662eb432a75f/html5/thumbnails/58.jpg)
type Email = string & {_emailBrand: any}type UserId = string & {_userIdBrand: any}
// Mainlet email = '[email protected]' as Emaillet userId = '3490' as UserIdconsole.log(new User(email, userId))
newtype Email = Email String deriving Shownewtype UserId = UserId String deriving Show
-- Mainmain = do let email = Email "[email protected]" userId = UserId "3490" print (createUser email userId)
Language Feature Hack
![Page 59: Functional Programming - Gasi · Functional Programming Or: How I Learned to Stop Worrying and Love Shipping Haskell Code & for *after accomplishing step 2: ??? Daniel Gąsienica](https://reader034.vdocuments.us/reader034/viewer/2022050609/5fb07a259f1d662eb432a75f/html5/thumbnails/59.jpg)
‘Built-in’ Types
![Page 60: Functional Programming - Gasi · Functional Programming Or: How I Learned to Stop Worrying and Love Shipping Haskell Code & for *after accomplishing step 2: ??? Daniel Gąsienica](https://reader034.vdocuments.us/reader034/viewer/2022050609/5fb07a259f1d662eb432a75f/html5/thumbnails/60.jpg)
data Bool = True | False
// function and(a: boolean, b: boolean): booleanand :: Bool -> Bool -> Booland True True = Trueand _ _ = False
// function or(a: boolean, b: boolean): booleanor :: Bool -> Bool -> Boolor False False = Falseor _ _ = True
![Page 61: Functional Programming - Gasi · Functional Programming Or: How I Learned to Stop Worrying and Love Shipping Haskell Code & for *after accomplishing step 2: ??? Daniel Gąsienica](https://reader034.vdocuments.us/reader034/viewer/2022050609/5fb07a259f1d662eb432a75f/html5/thumbnails/61.jpg)
data Bool = True | False
(&&) :: Bool -> Bool -> Bool(&&) True True = True(&&) _ _ = False
(||) :: Bool -> Bool -> Bool(||) False False = False(||) _ _ = True
// Define: (&&)// Use: True && False
![Page 62: Functional Programming - Gasi · Functional Programming Or: How I Learned to Stop Worrying and Love Shipping Haskell Code & for *after accomplishing step 2: ??? Daniel Gąsienica](https://reader034.vdocuments.us/reader034/viewer/2022050609/5fb07a259f1d662eb432a75f/html5/thumbnails/62.jpg)
Security
![Page 63: Functional Programming - Gasi · Functional Programming Or: How I Learned to Stop Worrying and Love Shipping Haskell Code & for *after accomplishing step 2: ??? Daniel Gąsienica](https://reader034.vdocuments.us/reader034/viewer/2022050609/5fb07a259f1d662eb432a75f/html5/thumbnails/63.jpg)
“Make sure we never store plaintext passwords
in our database.”
![Page 64: Functional Programming - Gasi · Functional Programming Or: How I Learned to Stop Worrying and Love Shipping Haskell Code & for *after accomplishing step 2: ??? Daniel Gąsienica](https://reader034.vdocuments.us/reader034/viewer/2022050609/5fb07a259f1d662eb432a75f/html5/thumbnails/64.jpg)
newtype PlainTextPassword = PlainTextPassword String deriving Shownewtype HashedPassword = HashedPassword String deriving Show
getPassword :: IO PlainTextPasswordgetPassword = do s <- getLine return (PlainTextPassword s)
hashPassword :: PlainTextPassword -> HashedPasswordhashPassword (PlainTextPassword s) = HashedPassword ((reverse s) ++ "$SALT$")
storePassword :: HashedPassword -> IO ()storePassword (HashedPassword s) = putStrLn s
-- Mainmain = do putStrLn "Enter password please:" p <- getPassword
putStrLn "\nStored the following hashed password:" storePassword p
-- types-security.hs:21:17:-- Couldn't match expected type ‘HashedPassword’-- with actual type ‘PlainTextPassword’-- In the first argument of ‘storePassword’, namely ‘p’-- In a stmt of a 'do' block: storePassword p
![Page 65: Functional Programming - Gasi · Functional Programming Or: How I Learned to Stop Worrying and Love Shipping Haskell Code & for *after accomplishing step 2: ??? Daniel Gąsienica](https://reader034.vdocuments.us/reader034/viewer/2022050609/5fb07a259f1d662eb432a75f/html5/thumbnails/65.jpg)
newtype PlainTextPassword = PlainTextPassword String deriving Shownewtype HashedPassword = HashedPassword String deriving Show
getPassword :: IO PlainTextPasswordgetPassword = do s <- getLine return (PlainTextPassword s)
hashPassword :: PlainTextPassword -> HashedPasswordhashPassword (PlainTextPassword s) = HashedPassword ((reverse s) ++ "$SALT$")
storePassword :: HashedPassword -> IO ()storePassword (HashedPassword s) = putStrLn s
-- Mainmain = do putStrLn "Enter password please:" p <- getPassword
putStrLn "\nStored the following hashed password:" storePassword (hashPassword p) —- before: `storePassword p`
-- Enter password please:-- passw0rd---- Stored the following hashed password:-- dr0wssap$SALT$
![Page 66: Functional Programming - Gasi · Functional Programming Or: How I Learned to Stop Worrying and Love Shipping Haskell Code & for *after accomplishing step 2: ??? Daniel Gąsienica](https://reader034.vdocuments.us/reader034/viewer/2022050609/5fb07a259f1d662eb432a75f/html5/thumbnails/66.jpg)
ConclusionTypes can help prevent many
errors at compile-time. They are a versatile and powerful
tool to model your domain.
![Page 67: Functional Programming - Gasi · Functional Programming Or: How I Learned to Stop Worrying and Love Shipping Haskell Code & for *after accomplishing step 2: ??? Daniel Gąsienica](https://reader034.vdocuments.us/reader034/viewer/2022050609/5fb07a259f1d662eb432a75f/html5/thumbnails/67.jpg)
Abstraction &
Type Classes
![Page 68: Functional Programming - Gasi · Functional Programming Or: How I Learned to Stop Worrying and Love Shipping Haskell Code & for *after accomplishing step 2: ??? Daniel Gąsienica](https://reader034.vdocuments.us/reader034/viewer/2022050609/5fb07a259f1d662eb432a75f/html5/thumbnails/68.jpg)
map
![Page 69: Functional Programming - Gasi · Functional Programming Or: How I Learned to Stop Worrying and Love Shipping Haskell Code & for *after accomplishing step 2: ??? Daniel Gąsienica](https://reader034.vdocuments.us/reader034/viewer/2022050609/5fb07a259f1d662eb432a75f/html5/thumbnails/69.jpg)
console.log([1, 2, 3].map(x => x * 3))// [3, 6, 9]
![Page 70: Functional Programming - Gasi · Functional Programming Or: How I Learned to Stop Worrying and Love Shipping Haskell Code & for *after accomplishing step 2: ??? Daniel Gąsienica](https://reader034.vdocuments.us/reader034/viewer/2022050609/5fb07a259f1d662eb432a75f/html5/thumbnails/70.jpg)
// Array<A>.map<B>(fn: (value: A) => B): Array<B>console.log([1, 2, 3].map(x => x * 3))// [3, 6, 9]
![Page 71: Functional Programming - Gasi · Functional Programming Or: How I Learned to Stop Worrying and Love Shipping Haskell Code & for *after accomplishing step 2: ??? Daniel Gąsienica](https://reader034.vdocuments.us/reader034/viewer/2022050609/5fb07a259f1d662eb432a75f/html5/thumbnails/71.jpg)
main = do -- map :: (a -> b) -> [a] -> [b] print (map (\x -> x * 3) [1, 2, 3]) -- [3, 6, 9]
![Page 72: Functional Programming - Gasi · Functional Programming Or: How I Learned to Stop Worrying and Love Shipping Haskell Code & for *after accomplishing step 2: ??? Daniel Gąsienica](https://reader034.vdocuments.us/reader034/viewer/2022050609/5fb07a259f1d662eb432a75f/html5/thumbnails/72.jpg)
main = do -- map :: (a -> b) -> [a] -> [b] print (map (3*) [1, 2, 3]) -- [3, 6, 9]
main = do -- map :: (a -> b) -> [a] -> [b] print (map (\x -> x * 3) [1, 2, 3]) -- [3, 6, 9]
![Page 73: Functional Programming - Gasi · Functional Programming Or: How I Learned to Stop Worrying and Love Shipping Haskell Code & for *after accomplishing step 2: ??? Daniel Gąsienica](https://reader034.vdocuments.us/reader034/viewer/2022050609/5fb07a259f1d662eb432a75f/html5/thumbnails/73.jpg)
main = do -- map :: (a -> b) -> [a] -> [b] print (map (3*) [1, 2, 3]) -- [3, 6, 9]
// Array<A>.map<B>(// fn: (value: A) => B// ): Array<B>console.log([1, 2, 3].map(x => x * 3))// [3, 6, 9]
![Page 74: Functional Programming - Gasi · Functional Programming Or: How I Learned to Stop Worrying and Love Shipping Haskell Code & for *after accomplishing step 2: ??? Daniel Gąsienica](https://reader034.vdocuments.us/reader034/viewer/2022050609/5fb07a259f1d662eb432a75f/html5/thumbnails/74.jpg)
Array<A>.map<B>(fn: (value: A) => B): Array<B>
![Page 75: Functional Programming - Gasi · Functional Programming Or: How I Learned to Stop Worrying and Love Shipping Haskell Code & for *after accomplishing step 2: ??? Daniel Gąsienica](https://reader034.vdocuments.us/reader034/viewer/2022050609/5fb07a259f1d662eb432a75f/html5/thumbnails/75.jpg)
F<A>.fmap<B>(fn: (value: A) => B): F<B>
// Container `F`
// `fmap` is generic `map` that// works on any container `F`
![Page 76: Functional Programming - Gasi · Functional Programming Or: How I Learned to Stop Worrying and Love Shipping Haskell Code & for *after accomplishing step 2: ??? Daniel Gąsienica](https://reader034.vdocuments.us/reader034/viewer/2022050609/5fb07a259f1d662eb432a75f/html5/thumbnails/76.jpg)
class Functor f where fmap :: (a -> b) -> f a -> f b
—- Container `f`
—- `fmap` is generic `map` that—- works on any container `f`
![Page 77: Functional Programming - Gasi · Functional Programming Or: How I Learned to Stop Worrying and Love Shipping Haskell Code & for *after accomplishing step 2: ??? Daniel Gąsienica](https://reader034.vdocuments.us/reader034/viewer/2022050609/5fb07a259f1d662eb432a75f/html5/thumbnails/77.jpg)
instance Functor [] where fmap fn [] = [] fmap fn (x:xs) = (fn x) : (fmap fn xs)
—- x = first element of the list —- xs = rest (tail) of the list
—- (:) = prepend list element
![Page 78: Functional Programming - Gasi · Functional Programming Or: How I Learned to Stop Worrying and Love Shipping Haskell Code & for *after accomplishing step 2: ??? Daniel Gąsienica](https://reader034.vdocuments.us/reader034/viewer/2022050609/5fb07a259f1d662eb432a75f/html5/thumbnails/78.jpg)
instance Functor [] where fmap = map
![Page 79: Functional Programming - Gasi · Functional Programming Or: How I Learned to Stop Worrying and Love Shipping Haskell Code & for *after accomplishing step 2: ??? Daniel Gąsienica](https://reader034.vdocuments.us/reader034/viewer/2022050609/5fb07a259f1d662eb432a75f/html5/thumbnails/79.jpg)
instance Functor Maybe where fmap fn Nothing = Nothing fmap fn (Just x) = Just (fn x)
![Page 80: Functional Programming - Gasi · Functional Programming Or: How I Learned to Stop Worrying and Love Shipping Haskell Code & for *after accomplishing step 2: ??? Daniel Gąsienica](https://reader034.vdocuments.us/reader034/viewer/2022050609/5fb07a259f1d662eb432a75f/html5/thumbnails/80.jpg)
main = do -- List print (fmap (3*) [1, 2, 3]) -- > [3, 6, 9]
-- Maybe print (fmap (3*) Nothing) -- > Nothing print (fmap (3*) (Just 2)) -- > Just 6
-- IO -- getLine :: IO String putStrLn "\nWhat is your name?" message <- fmap ("Hello, " ++) getLine putStrLn message -- > What is your name? -- > Daniel -- > "Hello, Daniel"
-- Async putStrLn "\nSay something…" asyncPrompt <- async getLine asyncMessage <- wait (fmap ("Async: " ++) asyncPrompt) putStrLn asyncMessage -- > Say something… -- > Yo yo -- > Async: Yo yo
![Page 81: Functional Programming - Gasi · Functional Programming Or: How I Learned to Stop Worrying and Love Shipping Haskell Code & for *after accomplishing step 2: ??? Daniel Gąsienica](https://reader034.vdocuments.us/reader034/viewer/2022050609/5fb07a259f1d662eb432a75f/html5/thumbnails/81.jpg)
ConclusionExpressive languages allow
developers to describe better abstractions.
Type classes are a mechanism for
abstracting common behaviors between different types.
![Page 82: Functional Programming - Gasi · Functional Programming Or: How I Learned to Stop Worrying and Love Shipping Haskell Code & for *after accomplishing step 2: ??? Daniel Gąsienica](https://reader034.vdocuments.us/reader034/viewer/2022050609/5fb07a259f1d662eb432a75f/html5/thumbnails/82.jpg)
Food for Thought
![Page 83: Functional Programming - Gasi · Functional Programming Or: How I Learned to Stop Worrying and Love Shipping Haskell Code & for *after accomplishing step 2: ??? Daniel Gąsienica](https://reader034.vdocuments.us/reader034/viewer/2022050609/5fb07a259f1d662eb432a75f/html5/thumbnails/83.jpg)
Impure Shell &
Pure Core
![Page 84: Functional Programming - Gasi · Functional Programming Or: How I Learned to Stop Worrying and Love Shipping Haskell Code & for *after accomplishing step 2: ??? Daniel Gąsienica](https://reader034.vdocuments.us/reader034/viewer/2022050609/5fb07a259f1d662eb432a75f/html5/thumbnails/84.jpg)
Pure Core • business logic • data transformation • validation • parsing • encoding / decoding
Impure Shell • user input • networking • file IO • database • randomness • rendering
![Page 85: Functional Programming - Gasi · Functional Programming Or: How I Learned to Stop Worrying and Love Shipping Haskell Code & for *after accomplishing step 2: ??? Daniel Gąsienica](https://reader034.vdocuments.us/reader034/viewer/2022050609/5fb07a259f1d662eb432a75f/html5/thumbnails/85.jpg)
Pure Core • lexical analysis • syntax analysis • type checking • optimize code • generate code
Example: CompilerImpure Shell • read CLI options • read environment
variables • read source files • write binary
![Page 86: Functional Programming - Gasi · Functional Programming Or: How I Learned to Stop Worrying and Love Shipping Haskell Code & for *after accomplishing step 2: ??? Daniel Gąsienica](https://reader034.vdocuments.us/reader034/viewer/2022050609/5fb07a259f1d662eb432a75f/html5/thumbnails/86.jpg)
CONTROVERSIAL CONTENTADVISORYP A R E N T A L
![Page 87: Functional Programming - Gasi · Functional Programming Or: How I Learned to Stop Worrying and Love Shipping Haskell Code & for *after accomplishing step 2: ??? Daniel Gąsienica](https://reader034.vdocuments.us/reader034/viewer/2022050609/5fb07a259f1d662eb432a75f/html5/thumbnails/87.jpg)
Sound Foundation > Weak Ecosystem
![Page 88: Functional Programming - Gasi · Functional Programming Or: How I Learned to Stop Worrying and Love Shipping Haskell Code & for *after accomplishing step 2: ??? Daniel Gąsienica](https://reader034.vdocuments.us/reader034/viewer/2022050609/5fb07a259f1d662eb432a75f/html5/thumbnails/88.jpg)
Stay Hungry
![Page 89: Functional Programming - Gasi · Functional Programming Or: How I Learned to Stop Worrying and Love Shipping Haskell Code & for *after accomplishing step 2: ??? Daniel Gąsienica](https://reader034.vdocuments.us/reader034/viewer/2022050609/5fb07a259f1d662eb432a75f/html5/thumbnails/89.jpg)
Q&A
“The only thing necessary for the triumph of [bad technology] is for
good men to do nothing.”
“All [bad technology] needs to gain a foothold is for people of good conscience
to remain silent.”