Norma Act I - Casta Diva
Vincenzo Bellini
Various Artists
2009-10-15T070000Z
66 Most Beautiful Opera Arias
2009 Menuetto Classics
Rome Lyric Opera Orchestra amp Chorus Alberico Vitalini amp ML Barducci
const sortReleasesOut = (releases) =gt _(releases)groupBy(lsquoid)values()flatten()sortBy((b) =gtbCoreReleasedataValuesreleaseDate)reverse()value()
const dotChainy = str =gt str toLowerCase() split( ) map(c =gt ctrim()) reverse() filter(x =gt xlength gt 3) join()
const doin_Thangs = str =gt _(str) words() groupBy(s =gt slength) orderBy(x =gt xlength) take(2) flatten() value()
const reactiveUpInHere = el =gt fromEvent(el keyup) map(e =gt etargetvalue) filter(text =gt textlength gt 2) throttle(500) distinctUntilChanged()
playerunitWithinRange(2)where(UnitIsEnemy)where(UnitIsTank)DoDamage(5)
const dotChainy = str =gt str toLowerCase() split( ) map(c =gt ctrim()) reverse() filter(x =gt xlength gt 3) join()
const dotChainy = str =gt str toLowerCase() split( ) map(c =gt ctrim()) reverse() filter(x =gt xlength gt 3) join()
const dotChainy = str =gt str toLowerCase() split( ) map(c =gt ctrim()) reverse() filter(x =gt xlength gt 3) join() Chain Dot Com
const dotChainy = str =gt str toLowerCase() split( ) map(c =gt ctrim()) reverse() filter(x =gt xlength gt 3) join() lsquochain dot com
const dotChainy = str =gt str toLowerCase() split( ) map(c =gt ctrim()) reverse() filter(x =gt xlength gt 3) join() [chain dot com ]
const dotChainy = str =gt str toLowerCase() split( ) map(c =gt ctrim()) reverse() filter(x =gt xlength gt 3) join() [chain dot com]
const dotChainy = str =gt str toLowerCase() split( ) map(c =gt ctrim()) reverse() filter(x =gt xlength gt 3) join()
[com dot chain]
const dotChainy = str =gt const lower = strtoLowerCase() const words = lowersplit( )
wordsreverse()
for(let i in words) words[i] = words[i]trim()
let keepers = []
for(let i in words) if(words[i]length gt 3) keeperspush(words[i])
return keepersjoin()
const dotChainy = str =gt const lower = strtoLowerCase() const words = lowersplit( )
wordsreverse()
for(let i in words) words[i] = words[i]trim()
let keepers = []
for(let i in words) if(words[i]length gt 3) keeperspush(words[i])
return keepersjoin()
class AppMailer
constructor() thisemailer = new Emailer()
removeInvalidAddresses() for(let i in thisaddresses) if(thisaddresses[i]match()) thisaddressessplice(i 1)
sendEmail(from to) thisaddresses = to thisemailersetSender(from) thisremoveInvalidAddresses() thisemailersetRecipients(thisaddresses) thisemailersend()
ldquothe major contributor to this complexity in many systems is the handling of state and the burden that this adds when trying to analyse and reason about the systemrdquo
Out of the Tar Pit 2006-Ben Moseley amp Peter Marks
const dotChainy = str =gt str toLowerCase() split( ) map(c =gt ctrim()) reverse() filter(x =gt xlength gt 3) join()
WHAT IF I TOLD YOUhellip
WHAT IF I TOLD YOUhellip
Programming == Math
try return f(x) catch(e) consoleerror(e)
if(x) return f() else return y
for(let thing in things) if(thingamount gt 100) keeperspush(thingname)
for (i = 0 i lt carslength i++) text += cars[i] + ltbrgt
while (i lt 10) text += The number is + i i++
let stuff = [123]
stuff = [12]
stuffsplice(0 2)
stuffpop()
AssignmentLoops
CallbacksSide EffectsBranching
Errors
Programming == Math
Programming = Math
f g
f g
dot
f g = x =gt f(g(x))
strtoUpperCase()trim()
trim(toUpperCase(str))
Category theory
fn fn
fnfn
a bf
cg
ag
cf
a
F(a)
bf
F(f)
cg
F(b) F(g)F(c)
a
F(a)
g
F(gf)
cf
F(c)
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) A
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt parseInt(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) Box(lsquoArsquo)
const Box = x =gt( map f =gt Box(f(x)))
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) Box(lsquoArsquo)
const Box = x =gt( map f =gt Box(f(x)))
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) fold(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) lsquoArsquo
const Box = x =gt( map f =gt Box(f(x)) fold f =gt f(x))
Unified call syntaxMinimized state
Captured AssignmentForced Control Flow
AssignmentLoops
CallbacksSide EffectsBranching
Errors
Loops
mapfilter
reduce
const range = (i count) =gt unfold(x =gt if(x lt= count) [x x+1] i)
range(510) [ 5 6 7 8 9 10 ]
const alphabet = () =gt unfold(x =gt if(x lt 26) [StringfromCharCode(x+65) x+1] 0)
alphabet() [ABCDEFGHIJKLMNOPQRSTUVWXYZ]
AssignmentLoops
CallbacksSide EffectsBranching
Errors
CallbacksSide Effects
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
contrivedEx2()fork(e =gt consoleerror(e) r =gt consolelog(success))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))fork(e =gt consoleerror(e)
r =gt consolelog(r))
AssignmentLoops
CallbacksSide EffectsBranching
Errors
BranchingErrors
EitherOr
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
leftOrRightfold(e =gt `we had an error $e` s =gt stoUpperCase())
Right(hair brown) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Right(five 2))
Right(10)
Left(ignored) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Left(five 2))
Left(ignored)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
Claim
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
AssignmentLoops
CallbacksSide EffectsBranching
Errors
const depObjs = b =gt List(bdeps)flatMap(next =gt findDependencyByProject(nextProjectname bpreviousdeps) fold(x =gt x found =gt makeArgs(next found)))
const mapBuildsAndDepsForDiffQueue = (builds) =gt List(builds) filter(b =gt bprevious) flatMap(b =gt makeArgs(b bprevious)concat(depObjs(b))) filter(b =gt b) toJS()
const filterExistingDiffs = (items) =gt List(items)traverse(Taskof (i) =gt find(Diff BuildId ibuildId DiffId iprevId type imethod ) map(e =gt eswap()getOrElse(null)) map(bs =gt bsfilter(x =gt x)toJS())
const buildProject = (branch sha) =gt queueUnzipWwwOnS3(sha) chain(() =gt isReleaseOrMainBranch(branch)) fold(() =gt _noop () =gt generateReport(sha) chain(queueDiffsForTileBuildsAndDeps) chain(() =gt getHeadCommit(sha) fold(() =gt Taskof(null) head =gt makeVrtDeployment(head sha) chain(() =gt createPrApp(head sha)))) fork(consoleerror
consolelog))
const vrtReport = (sha email platforms) =gt rejectFinishedPlatformOptions(platforms) chain(plats =gt platsmap(gatherScreenshots)) chain(shots =gt fromNullable(sha) fold(() =gt findLastRef() () =gt findBuild(sha)) chain(ref =gt renderReport(shots ref email))) fork(e =gt e r =gt r)
Harder to hack
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
Safer
const ProfileLink = user =gtlta href=`users$
uid`gtunameltagt
const Header = str =gt lth1gtNow Viewing strlth1gt
Component a -gt JSX
a JSXf
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
const sortReleasesOut = (releases) =gt _(releases)groupBy(lsquoid)values()flatten()sortBy((b) =gtbCoreReleasedataValuesreleaseDate)reverse()value()
const dotChainy = str =gt str toLowerCase() split( ) map(c =gt ctrim()) reverse() filter(x =gt xlength gt 3) join()
const doin_Thangs = str =gt _(str) words() groupBy(s =gt slength) orderBy(x =gt xlength) take(2) flatten() value()
const reactiveUpInHere = el =gt fromEvent(el keyup) map(e =gt etargetvalue) filter(text =gt textlength gt 2) throttle(500) distinctUntilChanged()
playerunitWithinRange(2)where(UnitIsEnemy)where(UnitIsTank)DoDamage(5)
const dotChainy = str =gt str toLowerCase() split( ) map(c =gt ctrim()) reverse() filter(x =gt xlength gt 3) join()
const dotChainy = str =gt str toLowerCase() split( ) map(c =gt ctrim()) reverse() filter(x =gt xlength gt 3) join()
const dotChainy = str =gt str toLowerCase() split( ) map(c =gt ctrim()) reverse() filter(x =gt xlength gt 3) join() Chain Dot Com
const dotChainy = str =gt str toLowerCase() split( ) map(c =gt ctrim()) reverse() filter(x =gt xlength gt 3) join() lsquochain dot com
const dotChainy = str =gt str toLowerCase() split( ) map(c =gt ctrim()) reverse() filter(x =gt xlength gt 3) join() [chain dot com ]
const dotChainy = str =gt str toLowerCase() split( ) map(c =gt ctrim()) reverse() filter(x =gt xlength gt 3) join() [chain dot com]
const dotChainy = str =gt str toLowerCase() split( ) map(c =gt ctrim()) reverse() filter(x =gt xlength gt 3) join()
[com dot chain]
const dotChainy = str =gt const lower = strtoLowerCase() const words = lowersplit( )
wordsreverse()
for(let i in words) words[i] = words[i]trim()
let keepers = []
for(let i in words) if(words[i]length gt 3) keeperspush(words[i])
return keepersjoin()
const dotChainy = str =gt const lower = strtoLowerCase() const words = lowersplit( )
wordsreverse()
for(let i in words) words[i] = words[i]trim()
let keepers = []
for(let i in words) if(words[i]length gt 3) keeperspush(words[i])
return keepersjoin()
class AppMailer
constructor() thisemailer = new Emailer()
removeInvalidAddresses() for(let i in thisaddresses) if(thisaddresses[i]match()) thisaddressessplice(i 1)
sendEmail(from to) thisaddresses = to thisemailersetSender(from) thisremoveInvalidAddresses() thisemailersetRecipients(thisaddresses) thisemailersend()
ldquothe major contributor to this complexity in many systems is the handling of state and the burden that this adds when trying to analyse and reason about the systemrdquo
Out of the Tar Pit 2006-Ben Moseley amp Peter Marks
const dotChainy = str =gt str toLowerCase() split( ) map(c =gt ctrim()) reverse() filter(x =gt xlength gt 3) join()
WHAT IF I TOLD YOUhellip
WHAT IF I TOLD YOUhellip
Programming == Math
try return f(x) catch(e) consoleerror(e)
if(x) return f() else return y
for(let thing in things) if(thingamount gt 100) keeperspush(thingname)
for (i = 0 i lt carslength i++) text += cars[i] + ltbrgt
while (i lt 10) text += The number is + i i++
let stuff = [123]
stuff = [12]
stuffsplice(0 2)
stuffpop()
AssignmentLoops
CallbacksSide EffectsBranching
Errors
Programming == Math
Programming = Math
f g
f g
dot
f g = x =gt f(g(x))
strtoUpperCase()trim()
trim(toUpperCase(str))
Category theory
fn fn
fnfn
a bf
cg
ag
cf
a
F(a)
bf
F(f)
cg
F(b) F(g)F(c)
a
F(a)
g
F(gf)
cf
F(c)
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) A
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt parseInt(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) Box(lsquoArsquo)
const Box = x =gt( map f =gt Box(f(x)))
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) Box(lsquoArsquo)
const Box = x =gt( map f =gt Box(f(x)))
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) fold(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) lsquoArsquo
const Box = x =gt( map f =gt Box(f(x)) fold f =gt f(x))
Unified call syntaxMinimized state
Captured AssignmentForced Control Flow
AssignmentLoops
CallbacksSide EffectsBranching
Errors
Loops
mapfilter
reduce
const range = (i count) =gt unfold(x =gt if(x lt= count) [x x+1] i)
range(510) [ 5 6 7 8 9 10 ]
const alphabet = () =gt unfold(x =gt if(x lt 26) [StringfromCharCode(x+65) x+1] 0)
alphabet() [ABCDEFGHIJKLMNOPQRSTUVWXYZ]
AssignmentLoops
CallbacksSide EffectsBranching
Errors
CallbacksSide Effects
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
contrivedEx2()fork(e =gt consoleerror(e) r =gt consolelog(success))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))fork(e =gt consoleerror(e)
r =gt consolelog(r))
AssignmentLoops
CallbacksSide EffectsBranching
Errors
BranchingErrors
EitherOr
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
leftOrRightfold(e =gt `we had an error $e` s =gt stoUpperCase())
Right(hair brown) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Right(five 2))
Right(10)
Left(ignored) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Left(five 2))
Left(ignored)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
Claim
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
AssignmentLoops
CallbacksSide EffectsBranching
Errors
const depObjs = b =gt List(bdeps)flatMap(next =gt findDependencyByProject(nextProjectname bpreviousdeps) fold(x =gt x found =gt makeArgs(next found)))
const mapBuildsAndDepsForDiffQueue = (builds) =gt List(builds) filter(b =gt bprevious) flatMap(b =gt makeArgs(b bprevious)concat(depObjs(b))) filter(b =gt b) toJS()
const filterExistingDiffs = (items) =gt List(items)traverse(Taskof (i) =gt find(Diff BuildId ibuildId DiffId iprevId type imethod ) map(e =gt eswap()getOrElse(null)) map(bs =gt bsfilter(x =gt x)toJS())
const buildProject = (branch sha) =gt queueUnzipWwwOnS3(sha) chain(() =gt isReleaseOrMainBranch(branch)) fold(() =gt _noop () =gt generateReport(sha) chain(queueDiffsForTileBuildsAndDeps) chain(() =gt getHeadCommit(sha) fold(() =gt Taskof(null) head =gt makeVrtDeployment(head sha) chain(() =gt createPrApp(head sha)))) fork(consoleerror
consolelog))
const vrtReport = (sha email platforms) =gt rejectFinishedPlatformOptions(platforms) chain(plats =gt platsmap(gatherScreenshots)) chain(shots =gt fromNullable(sha) fold(() =gt findLastRef() () =gt findBuild(sha)) chain(ref =gt renderReport(shots ref email))) fork(e =gt e r =gt r)
Harder to hack
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
Safer
const ProfileLink = user =gtlta href=`users$
uid`gtunameltagt
const Header = str =gt lth1gtNow Viewing strlth1gt
Component a -gt JSX
a JSXf
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
const dotChainy = str =gt str toLowerCase() split( ) map(c =gt ctrim()) reverse() filter(x =gt xlength gt 3) join()
const doin_Thangs = str =gt _(str) words() groupBy(s =gt slength) orderBy(x =gt xlength) take(2) flatten() value()
const reactiveUpInHere = el =gt fromEvent(el keyup) map(e =gt etargetvalue) filter(text =gt textlength gt 2) throttle(500) distinctUntilChanged()
playerunitWithinRange(2)where(UnitIsEnemy)where(UnitIsTank)DoDamage(5)
const dotChainy = str =gt str toLowerCase() split( ) map(c =gt ctrim()) reverse() filter(x =gt xlength gt 3) join()
const dotChainy = str =gt str toLowerCase() split( ) map(c =gt ctrim()) reverse() filter(x =gt xlength gt 3) join()
const dotChainy = str =gt str toLowerCase() split( ) map(c =gt ctrim()) reverse() filter(x =gt xlength gt 3) join() Chain Dot Com
const dotChainy = str =gt str toLowerCase() split( ) map(c =gt ctrim()) reverse() filter(x =gt xlength gt 3) join() lsquochain dot com
const dotChainy = str =gt str toLowerCase() split( ) map(c =gt ctrim()) reverse() filter(x =gt xlength gt 3) join() [chain dot com ]
const dotChainy = str =gt str toLowerCase() split( ) map(c =gt ctrim()) reverse() filter(x =gt xlength gt 3) join() [chain dot com]
const dotChainy = str =gt str toLowerCase() split( ) map(c =gt ctrim()) reverse() filter(x =gt xlength gt 3) join()
[com dot chain]
const dotChainy = str =gt const lower = strtoLowerCase() const words = lowersplit( )
wordsreverse()
for(let i in words) words[i] = words[i]trim()
let keepers = []
for(let i in words) if(words[i]length gt 3) keeperspush(words[i])
return keepersjoin()
const dotChainy = str =gt const lower = strtoLowerCase() const words = lowersplit( )
wordsreverse()
for(let i in words) words[i] = words[i]trim()
let keepers = []
for(let i in words) if(words[i]length gt 3) keeperspush(words[i])
return keepersjoin()
class AppMailer
constructor() thisemailer = new Emailer()
removeInvalidAddresses() for(let i in thisaddresses) if(thisaddresses[i]match()) thisaddressessplice(i 1)
sendEmail(from to) thisaddresses = to thisemailersetSender(from) thisremoveInvalidAddresses() thisemailersetRecipients(thisaddresses) thisemailersend()
ldquothe major contributor to this complexity in many systems is the handling of state and the burden that this adds when trying to analyse and reason about the systemrdquo
Out of the Tar Pit 2006-Ben Moseley amp Peter Marks
const dotChainy = str =gt str toLowerCase() split( ) map(c =gt ctrim()) reverse() filter(x =gt xlength gt 3) join()
WHAT IF I TOLD YOUhellip
WHAT IF I TOLD YOUhellip
Programming == Math
try return f(x) catch(e) consoleerror(e)
if(x) return f() else return y
for(let thing in things) if(thingamount gt 100) keeperspush(thingname)
for (i = 0 i lt carslength i++) text += cars[i] + ltbrgt
while (i lt 10) text += The number is + i i++
let stuff = [123]
stuff = [12]
stuffsplice(0 2)
stuffpop()
AssignmentLoops
CallbacksSide EffectsBranching
Errors
Programming == Math
Programming = Math
f g
f g
dot
f g = x =gt f(g(x))
strtoUpperCase()trim()
trim(toUpperCase(str))
Category theory
fn fn
fnfn
a bf
cg
ag
cf
a
F(a)
bf
F(f)
cg
F(b) F(g)F(c)
a
F(a)
g
F(gf)
cf
F(c)
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) A
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt parseInt(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) Box(lsquoArsquo)
const Box = x =gt( map f =gt Box(f(x)))
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) Box(lsquoArsquo)
const Box = x =gt( map f =gt Box(f(x)))
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) fold(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) lsquoArsquo
const Box = x =gt( map f =gt Box(f(x)) fold f =gt f(x))
Unified call syntaxMinimized state
Captured AssignmentForced Control Flow
AssignmentLoops
CallbacksSide EffectsBranching
Errors
Loops
mapfilter
reduce
const range = (i count) =gt unfold(x =gt if(x lt= count) [x x+1] i)
range(510) [ 5 6 7 8 9 10 ]
const alphabet = () =gt unfold(x =gt if(x lt 26) [StringfromCharCode(x+65) x+1] 0)
alphabet() [ABCDEFGHIJKLMNOPQRSTUVWXYZ]
AssignmentLoops
CallbacksSide EffectsBranching
Errors
CallbacksSide Effects
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
contrivedEx2()fork(e =gt consoleerror(e) r =gt consolelog(success))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))fork(e =gt consoleerror(e)
r =gt consolelog(r))
AssignmentLoops
CallbacksSide EffectsBranching
Errors
BranchingErrors
EitherOr
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
leftOrRightfold(e =gt `we had an error $e` s =gt stoUpperCase())
Right(hair brown) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Right(five 2))
Right(10)
Left(ignored) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Left(five 2))
Left(ignored)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
Claim
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
AssignmentLoops
CallbacksSide EffectsBranching
Errors
const depObjs = b =gt List(bdeps)flatMap(next =gt findDependencyByProject(nextProjectname bpreviousdeps) fold(x =gt x found =gt makeArgs(next found)))
const mapBuildsAndDepsForDiffQueue = (builds) =gt List(builds) filter(b =gt bprevious) flatMap(b =gt makeArgs(b bprevious)concat(depObjs(b))) filter(b =gt b) toJS()
const filterExistingDiffs = (items) =gt List(items)traverse(Taskof (i) =gt find(Diff BuildId ibuildId DiffId iprevId type imethod ) map(e =gt eswap()getOrElse(null)) map(bs =gt bsfilter(x =gt x)toJS())
const buildProject = (branch sha) =gt queueUnzipWwwOnS3(sha) chain(() =gt isReleaseOrMainBranch(branch)) fold(() =gt _noop () =gt generateReport(sha) chain(queueDiffsForTileBuildsAndDeps) chain(() =gt getHeadCommit(sha) fold(() =gt Taskof(null) head =gt makeVrtDeployment(head sha) chain(() =gt createPrApp(head sha)))) fork(consoleerror
consolelog))
const vrtReport = (sha email platforms) =gt rejectFinishedPlatformOptions(platforms) chain(plats =gt platsmap(gatherScreenshots)) chain(shots =gt fromNullable(sha) fold(() =gt findLastRef() () =gt findBuild(sha)) chain(ref =gt renderReport(shots ref email))) fork(e =gt e r =gt r)
Harder to hack
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
Safer
const ProfileLink = user =gtlta href=`users$
uid`gtunameltagt
const Header = str =gt lth1gtNow Viewing strlth1gt
Component a -gt JSX
a JSXf
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
const doin_Thangs = str =gt _(str) words() groupBy(s =gt slength) orderBy(x =gt xlength) take(2) flatten() value()
const reactiveUpInHere = el =gt fromEvent(el keyup) map(e =gt etargetvalue) filter(text =gt textlength gt 2) throttle(500) distinctUntilChanged()
playerunitWithinRange(2)where(UnitIsEnemy)where(UnitIsTank)DoDamage(5)
const dotChainy = str =gt str toLowerCase() split( ) map(c =gt ctrim()) reverse() filter(x =gt xlength gt 3) join()
const dotChainy = str =gt str toLowerCase() split( ) map(c =gt ctrim()) reverse() filter(x =gt xlength gt 3) join()
const dotChainy = str =gt str toLowerCase() split( ) map(c =gt ctrim()) reverse() filter(x =gt xlength gt 3) join() Chain Dot Com
const dotChainy = str =gt str toLowerCase() split( ) map(c =gt ctrim()) reverse() filter(x =gt xlength gt 3) join() lsquochain dot com
const dotChainy = str =gt str toLowerCase() split( ) map(c =gt ctrim()) reverse() filter(x =gt xlength gt 3) join() [chain dot com ]
const dotChainy = str =gt str toLowerCase() split( ) map(c =gt ctrim()) reverse() filter(x =gt xlength gt 3) join() [chain dot com]
const dotChainy = str =gt str toLowerCase() split( ) map(c =gt ctrim()) reverse() filter(x =gt xlength gt 3) join()
[com dot chain]
const dotChainy = str =gt const lower = strtoLowerCase() const words = lowersplit( )
wordsreverse()
for(let i in words) words[i] = words[i]trim()
let keepers = []
for(let i in words) if(words[i]length gt 3) keeperspush(words[i])
return keepersjoin()
const dotChainy = str =gt const lower = strtoLowerCase() const words = lowersplit( )
wordsreverse()
for(let i in words) words[i] = words[i]trim()
let keepers = []
for(let i in words) if(words[i]length gt 3) keeperspush(words[i])
return keepersjoin()
class AppMailer
constructor() thisemailer = new Emailer()
removeInvalidAddresses() for(let i in thisaddresses) if(thisaddresses[i]match()) thisaddressessplice(i 1)
sendEmail(from to) thisaddresses = to thisemailersetSender(from) thisremoveInvalidAddresses() thisemailersetRecipients(thisaddresses) thisemailersend()
ldquothe major contributor to this complexity in many systems is the handling of state and the burden that this adds when trying to analyse and reason about the systemrdquo
Out of the Tar Pit 2006-Ben Moseley amp Peter Marks
const dotChainy = str =gt str toLowerCase() split( ) map(c =gt ctrim()) reverse() filter(x =gt xlength gt 3) join()
WHAT IF I TOLD YOUhellip
WHAT IF I TOLD YOUhellip
Programming == Math
try return f(x) catch(e) consoleerror(e)
if(x) return f() else return y
for(let thing in things) if(thingamount gt 100) keeperspush(thingname)
for (i = 0 i lt carslength i++) text += cars[i] + ltbrgt
while (i lt 10) text += The number is + i i++
let stuff = [123]
stuff = [12]
stuffsplice(0 2)
stuffpop()
AssignmentLoops
CallbacksSide EffectsBranching
Errors
Programming == Math
Programming = Math
f g
f g
dot
f g = x =gt f(g(x))
strtoUpperCase()trim()
trim(toUpperCase(str))
Category theory
fn fn
fnfn
a bf
cg
ag
cf
a
F(a)
bf
F(f)
cg
F(b) F(g)F(c)
a
F(a)
g
F(gf)
cf
F(c)
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) A
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt parseInt(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) Box(lsquoArsquo)
const Box = x =gt( map f =gt Box(f(x)))
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) Box(lsquoArsquo)
const Box = x =gt( map f =gt Box(f(x)))
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) fold(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) lsquoArsquo
const Box = x =gt( map f =gt Box(f(x)) fold f =gt f(x))
Unified call syntaxMinimized state
Captured AssignmentForced Control Flow
AssignmentLoops
CallbacksSide EffectsBranching
Errors
Loops
mapfilter
reduce
const range = (i count) =gt unfold(x =gt if(x lt= count) [x x+1] i)
range(510) [ 5 6 7 8 9 10 ]
const alphabet = () =gt unfold(x =gt if(x lt 26) [StringfromCharCode(x+65) x+1] 0)
alphabet() [ABCDEFGHIJKLMNOPQRSTUVWXYZ]
AssignmentLoops
CallbacksSide EffectsBranching
Errors
CallbacksSide Effects
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
contrivedEx2()fork(e =gt consoleerror(e) r =gt consolelog(success))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))fork(e =gt consoleerror(e)
r =gt consolelog(r))
AssignmentLoops
CallbacksSide EffectsBranching
Errors
BranchingErrors
EitherOr
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
leftOrRightfold(e =gt `we had an error $e` s =gt stoUpperCase())
Right(hair brown) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Right(five 2))
Right(10)
Left(ignored) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Left(five 2))
Left(ignored)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
Claim
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
AssignmentLoops
CallbacksSide EffectsBranching
Errors
const depObjs = b =gt List(bdeps)flatMap(next =gt findDependencyByProject(nextProjectname bpreviousdeps) fold(x =gt x found =gt makeArgs(next found)))
const mapBuildsAndDepsForDiffQueue = (builds) =gt List(builds) filter(b =gt bprevious) flatMap(b =gt makeArgs(b bprevious)concat(depObjs(b))) filter(b =gt b) toJS()
const filterExistingDiffs = (items) =gt List(items)traverse(Taskof (i) =gt find(Diff BuildId ibuildId DiffId iprevId type imethod ) map(e =gt eswap()getOrElse(null)) map(bs =gt bsfilter(x =gt x)toJS())
const buildProject = (branch sha) =gt queueUnzipWwwOnS3(sha) chain(() =gt isReleaseOrMainBranch(branch)) fold(() =gt _noop () =gt generateReport(sha) chain(queueDiffsForTileBuildsAndDeps) chain(() =gt getHeadCommit(sha) fold(() =gt Taskof(null) head =gt makeVrtDeployment(head sha) chain(() =gt createPrApp(head sha)))) fork(consoleerror
consolelog))
const vrtReport = (sha email platforms) =gt rejectFinishedPlatformOptions(platforms) chain(plats =gt platsmap(gatherScreenshots)) chain(shots =gt fromNullable(sha) fold(() =gt findLastRef() () =gt findBuild(sha)) chain(ref =gt renderReport(shots ref email))) fork(e =gt e r =gt r)
Harder to hack
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
Safer
const ProfileLink = user =gtlta href=`users$
uid`gtunameltagt
const Header = str =gt lth1gtNow Viewing strlth1gt
Component a -gt JSX
a JSXf
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
const reactiveUpInHere = el =gt fromEvent(el keyup) map(e =gt etargetvalue) filter(text =gt textlength gt 2) throttle(500) distinctUntilChanged()
playerunitWithinRange(2)where(UnitIsEnemy)where(UnitIsTank)DoDamage(5)
const dotChainy = str =gt str toLowerCase() split( ) map(c =gt ctrim()) reverse() filter(x =gt xlength gt 3) join()
const dotChainy = str =gt str toLowerCase() split( ) map(c =gt ctrim()) reverse() filter(x =gt xlength gt 3) join()
const dotChainy = str =gt str toLowerCase() split( ) map(c =gt ctrim()) reverse() filter(x =gt xlength gt 3) join() Chain Dot Com
const dotChainy = str =gt str toLowerCase() split( ) map(c =gt ctrim()) reverse() filter(x =gt xlength gt 3) join() lsquochain dot com
const dotChainy = str =gt str toLowerCase() split( ) map(c =gt ctrim()) reverse() filter(x =gt xlength gt 3) join() [chain dot com ]
const dotChainy = str =gt str toLowerCase() split( ) map(c =gt ctrim()) reverse() filter(x =gt xlength gt 3) join() [chain dot com]
const dotChainy = str =gt str toLowerCase() split( ) map(c =gt ctrim()) reverse() filter(x =gt xlength gt 3) join()
[com dot chain]
const dotChainy = str =gt const lower = strtoLowerCase() const words = lowersplit( )
wordsreverse()
for(let i in words) words[i] = words[i]trim()
let keepers = []
for(let i in words) if(words[i]length gt 3) keeperspush(words[i])
return keepersjoin()
const dotChainy = str =gt const lower = strtoLowerCase() const words = lowersplit( )
wordsreverse()
for(let i in words) words[i] = words[i]trim()
let keepers = []
for(let i in words) if(words[i]length gt 3) keeperspush(words[i])
return keepersjoin()
class AppMailer
constructor() thisemailer = new Emailer()
removeInvalidAddresses() for(let i in thisaddresses) if(thisaddresses[i]match()) thisaddressessplice(i 1)
sendEmail(from to) thisaddresses = to thisemailersetSender(from) thisremoveInvalidAddresses() thisemailersetRecipients(thisaddresses) thisemailersend()
ldquothe major contributor to this complexity in many systems is the handling of state and the burden that this adds when trying to analyse and reason about the systemrdquo
Out of the Tar Pit 2006-Ben Moseley amp Peter Marks
const dotChainy = str =gt str toLowerCase() split( ) map(c =gt ctrim()) reverse() filter(x =gt xlength gt 3) join()
WHAT IF I TOLD YOUhellip
WHAT IF I TOLD YOUhellip
Programming == Math
try return f(x) catch(e) consoleerror(e)
if(x) return f() else return y
for(let thing in things) if(thingamount gt 100) keeperspush(thingname)
for (i = 0 i lt carslength i++) text += cars[i] + ltbrgt
while (i lt 10) text += The number is + i i++
let stuff = [123]
stuff = [12]
stuffsplice(0 2)
stuffpop()
AssignmentLoops
CallbacksSide EffectsBranching
Errors
Programming == Math
Programming = Math
f g
f g
dot
f g = x =gt f(g(x))
strtoUpperCase()trim()
trim(toUpperCase(str))
Category theory
fn fn
fnfn
a bf
cg
ag
cf
a
F(a)
bf
F(f)
cg
F(b) F(g)F(c)
a
F(a)
g
F(gf)
cf
F(c)
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) A
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt parseInt(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) Box(lsquoArsquo)
const Box = x =gt( map f =gt Box(f(x)))
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) Box(lsquoArsquo)
const Box = x =gt( map f =gt Box(f(x)))
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) fold(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) lsquoArsquo
const Box = x =gt( map f =gt Box(f(x)) fold f =gt f(x))
Unified call syntaxMinimized state
Captured AssignmentForced Control Flow
AssignmentLoops
CallbacksSide EffectsBranching
Errors
Loops
mapfilter
reduce
const range = (i count) =gt unfold(x =gt if(x lt= count) [x x+1] i)
range(510) [ 5 6 7 8 9 10 ]
const alphabet = () =gt unfold(x =gt if(x lt 26) [StringfromCharCode(x+65) x+1] 0)
alphabet() [ABCDEFGHIJKLMNOPQRSTUVWXYZ]
AssignmentLoops
CallbacksSide EffectsBranching
Errors
CallbacksSide Effects
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
contrivedEx2()fork(e =gt consoleerror(e) r =gt consolelog(success))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))fork(e =gt consoleerror(e)
r =gt consolelog(r))
AssignmentLoops
CallbacksSide EffectsBranching
Errors
BranchingErrors
EitherOr
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
leftOrRightfold(e =gt `we had an error $e` s =gt stoUpperCase())
Right(hair brown) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Right(five 2))
Right(10)
Left(ignored) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Left(five 2))
Left(ignored)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
Claim
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
AssignmentLoops
CallbacksSide EffectsBranching
Errors
const depObjs = b =gt List(bdeps)flatMap(next =gt findDependencyByProject(nextProjectname bpreviousdeps) fold(x =gt x found =gt makeArgs(next found)))
const mapBuildsAndDepsForDiffQueue = (builds) =gt List(builds) filter(b =gt bprevious) flatMap(b =gt makeArgs(b bprevious)concat(depObjs(b))) filter(b =gt b) toJS()
const filterExistingDiffs = (items) =gt List(items)traverse(Taskof (i) =gt find(Diff BuildId ibuildId DiffId iprevId type imethod ) map(e =gt eswap()getOrElse(null)) map(bs =gt bsfilter(x =gt x)toJS())
const buildProject = (branch sha) =gt queueUnzipWwwOnS3(sha) chain(() =gt isReleaseOrMainBranch(branch)) fold(() =gt _noop () =gt generateReport(sha) chain(queueDiffsForTileBuildsAndDeps) chain(() =gt getHeadCommit(sha) fold(() =gt Taskof(null) head =gt makeVrtDeployment(head sha) chain(() =gt createPrApp(head sha)))) fork(consoleerror
consolelog))
const vrtReport = (sha email platforms) =gt rejectFinishedPlatformOptions(platforms) chain(plats =gt platsmap(gatherScreenshots)) chain(shots =gt fromNullable(sha) fold(() =gt findLastRef() () =gt findBuild(sha)) chain(ref =gt renderReport(shots ref email))) fork(e =gt e r =gt r)
Harder to hack
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
Safer
const ProfileLink = user =gtlta href=`users$
uid`gtunameltagt
const Header = str =gt lth1gtNow Viewing strlth1gt
Component a -gt JSX
a JSXf
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
playerunitWithinRange(2)where(UnitIsEnemy)where(UnitIsTank)DoDamage(5)
const dotChainy = str =gt str toLowerCase() split( ) map(c =gt ctrim()) reverse() filter(x =gt xlength gt 3) join()
const dotChainy = str =gt str toLowerCase() split( ) map(c =gt ctrim()) reverse() filter(x =gt xlength gt 3) join()
const dotChainy = str =gt str toLowerCase() split( ) map(c =gt ctrim()) reverse() filter(x =gt xlength gt 3) join() Chain Dot Com
const dotChainy = str =gt str toLowerCase() split( ) map(c =gt ctrim()) reverse() filter(x =gt xlength gt 3) join() lsquochain dot com
const dotChainy = str =gt str toLowerCase() split( ) map(c =gt ctrim()) reverse() filter(x =gt xlength gt 3) join() [chain dot com ]
const dotChainy = str =gt str toLowerCase() split( ) map(c =gt ctrim()) reverse() filter(x =gt xlength gt 3) join() [chain dot com]
const dotChainy = str =gt str toLowerCase() split( ) map(c =gt ctrim()) reverse() filter(x =gt xlength gt 3) join()
[com dot chain]
const dotChainy = str =gt const lower = strtoLowerCase() const words = lowersplit( )
wordsreverse()
for(let i in words) words[i] = words[i]trim()
let keepers = []
for(let i in words) if(words[i]length gt 3) keeperspush(words[i])
return keepersjoin()
const dotChainy = str =gt const lower = strtoLowerCase() const words = lowersplit( )
wordsreverse()
for(let i in words) words[i] = words[i]trim()
let keepers = []
for(let i in words) if(words[i]length gt 3) keeperspush(words[i])
return keepersjoin()
class AppMailer
constructor() thisemailer = new Emailer()
removeInvalidAddresses() for(let i in thisaddresses) if(thisaddresses[i]match()) thisaddressessplice(i 1)
sendEmail(from to) thisaddresses = to thisemailersetSender(from) thisremoveInvalidAddresses() thisemailersetRecipients(thisaddresses) thisemailersend()
ldquothe major contributor to this complexity in many systems is the handling of state and the burden that this adds when trying to analyse and reason about the systemrdquo
Out of the Tar Pit 2006-Ben Moseley amp Peter Marks
const dotChainy = str =gt str toLowerCase() split( ) map(c =gt ctrim()) reverse() filter(x =gt xlength gt 3) join()
WHAT IF I TOLD YOUhellip
WHAT IF I TOLD YOUhellip
Programming == Math
try return f(x) catch(e) consoleerror(e)
if(x) return f() else return y
for(let thing in things) if(thingamount gt 100) keeperspush(thingname)
for (i = 0 i lt carslength i++) text += cars[i] + ltbrgt
while (i lt 10) text += The number is + i i++
let stuff = [123]
stuff = [12]
stuffsplice(0 2)
stuffpop()
AssignmentLoops
CallbacksSide EffectsBranching
Errors
Programming == Math
Programming = Math
f g
f g
dot
f g = x =gt f(g(x))
strtoUpperCase()trim()
trim(toUpperCase(str))
Category theory
fn fn
fnfn
a bf
cg
ag
cf
a
F(a)
bf
F(f)
cg
F(b) F(g)F(c)
a
F(a)
g
F(gf)
cf
F(c)
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) A
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt parseInt(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) Box(lsquoArsquo)
const Box = x =gt( map f =gt Box(f(x)))
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) Box(lsquoArsquo)
const Box = x =gt( map f =gt Box(f(x)))
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) fold(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) lsquoArsquo
const Box = x =gt( map f =gt Box(f(x)) fold f =gt f(x))
Unified call syntaxMinimized state
Captured AssignmentForced Control Flow
AssignmentLoops
CallbacksSide EffectsBranching
Errors
Loops
mapfilter
reduce
const range = (i count) =gt unfold(x =gt if(x lt= count) [x x+1] i)
range(510) [ 5 6 7 8 9 10 ]
const alphabet = () =gt unfold(x =gt if(x lt 26) [StringfromCharCode(x+65) x+1] 0)
alphabet() [ABCDEFGHIJKLMNOPQRSTUVWXYZ]
AssignmentLoops
CallbacksSide EffectsBranching
Errors
CallbacksSide Effects
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
contrivedEx2()fork(e =gt consoleerror(e) r =gt consolelog(success))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))fork(e =gt consoleerror(e)
r =gt consolelog(r))
AssignmentLoops
CallbacksSide EffectsBranching
Errors
BranchingErrors
EitherOr
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
leftOrRightfold(e =gt `we had an error $e` s =gt stoUpperCase())
Right(hair brown) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Right(five 2))
Right(10)
Left(ignored) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Left(five 2))
Left(ignored)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
Claim
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
AssignmentLoops
CallbacksSide EffectsBranching
Errors
const depObjs = b =gt List(bdeps)flatMap(next =gt findDependencyByProject(nextProjectname bpreviousdeps) fold(x =gt x found =gt makeArgs(next found)))
const mapBuildsAndDepsForDiffQueue = (builds) =gt List(builds) filter(b =gt bprevious) flatMap(b =gt makeArgs(b bprevious)concat(depObjs(b))) filter(b =gt b) toJS()
const filterExistingDiffs = (items) =gt List(items)traverse(Taskof (i) =gt find(Diff BuildId ibuildId DiffId iprevId type imethod ) map(e =gt eswap()getOrElse(null)) map(bs =gt bsfilter(x =gt x)toJS())
const buildProject = (branch sha) =gt queueUnzipWwwOnS3(sha) chain(() =gt isReleaseOrMainBranch(branch)) fold(() =gt _noop () =gt generateReport(sha) chain(queueDiffsForTileBuildsAndDeps) chain(() =gt getHeadCommit(sha) fold(() =gt Taskof(null) head =gt makeVrtDeployment(head sha) chain(() =gt createPrApp(head sha)))) fork(consoleerror
consolelog))
const vrtReport = (sha email platforms) =gt rejectFinishedPlatformOptions(platforms) chain(plats =gt platsmap(gatherScreenshots)) chain(shots =gt fromNullable(sha) fold(() =gt findLastRef() () =gt findBuild(sha)) chain(ref =gt renderReport(shots ref email))) fork(e =gt e r =gt r)
Harder to hack
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
Safer
const ProfileLink = user =gtlta href=`users$
uid`gtunameltagt
const Header = str =gt lth1gtNow Viewing strlth1gt
Component a -gt JSX
a JSXf
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
const dotChainy = str =gt str toLowerCase() split( ) map(c =gt ctrim()) reverse() filter(x =gt xlength gt 3) join()
const dotChainy = str =gt str toLowerCase() split( ) map(c =gt ctrim()) reverse() filter(x =gt xlength gt 3) join()
const dotChainy = str =gt str toLowerCase() split( ) map(c =gt ctrim()) reverse() filter(x =gt xlength gt 3) join() Chain Dot Com
const dotChainy = str =gt str toLowerCase() split( ) map(c =gt ctrim()) reverse() filter(x =gt xlength gt 3) join() lsquochain dot com
const dotChainy = str =gt str toLowerCase() split( ) map(c =gt ctrim()) reverse() filter(x =gt xlength gt 3) join() [chain dot com ]
const dotChainy = str =gt str toLowerCase() split( ) map(c =gt ctrim()) reverse() filter(x =gt xlength gt 3) join() [chain dot com]
const dotChainy = str =gt str toLowerCase() split( ) map(c =gt ctrim()) reverse() filter(x =gt xlength gt 3) join()
[com dot chain]
const dotChainy = str =gt const lower = strtoLowerCase() const words = lowersplit( )
wordsreverse()
for(let i in words) words[i] = words[i]trim()
let keepers = []
for(let i in words) if(words[i]length gt 3) keeperspush(words[i])
return keepersjoin()
const dotChainy = str =gt const lower = strtoLowerCase() const words = lowersplit( )
wordsreverse()
for(let i in words) words[i] = words[i]trim()
let keepers = []
for(let i in words) if(words[i]length gt 3) keeperspush(words[i])
return keepersjoin()
class AppMailer
constructor() thisemailer = new Emailer()
removeInvalidAddresses() for(let i in thisaddresses) if(thisaddresses[i]match()) thisaddressessplice(i 1)
sendEmail(from to) thisaddresses = to thisemailersetSender(from) thisremoveInvalidAddresses() thisemailersetRecipients(thisaddresses) thisemailersend()
ldquothe major contributor to this complexity in many systems is the handling of state and the burden that this adds when trying to analyse and reason about the systemrdquo
Out of the Tar Pit 2006-Ben Moseley amp Peter Marks
const dotChainy = str =gt str toLowerCase() split( ) map(c =gt ctrim()) reverse() filter(x =gt xlength gt 3) join()
WHAT IF I TOLD YOUhellip
WHAT IF I TOLD YOUhellip
Programming == Math
try return f(x) catch(e) consoleerror(e)
if(x) return f() else return y
for(let thing in things) if(thingamount gt 100) keeperspush(thingname)
for (i = 0 i lt carslength i++) text += cars[i] + ltbrgt
while (i lt 10) text += The number is + i i++
let stuff = [123]
stuff = [12]
stuffsplice(0 2)
stuffpop()
AssignmentLoops
CallbacksSide EffectsBranching
Errors
Programming == Math
Programming = Math
f g
f g
dot
f g = x =gt f(g(x))
strtoUpperCase()trim()
trim(toUpperCase(str))
Category theory
fn fn
fnfn
a bf
cg
ag
cf
a
F(a)
bf
F(f)
cg
F(b) F(g)F(c)
a
F(a)
g
F(gf)
cf
F(c)
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) A
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt parseInt(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) Box(lsquoArsquo)
const Box = x =gt( map f =gt Box(f(x)))
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) Box(lsquoArsquo)
const Box = x =gt( map f =gt Box(f(x)))
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) fold(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) lsquoArsquo
const Box = x =gt( map f =gt Box(f(x)) fold f =gt f(x))
Unified call syntaxMinimized state
Captured AssignmentForced Control Flow
AssignmentLoops
CallbacksSide EffectsBranching
Errors
Loops
mapfilter
reduce
const range = (i count) =gt unfold(x =gt if(x lt= count) [x x+1] i)
range(510) [ 5 6 7 8 9 10 ]
const alphabet = () =gt unfold(x =gt if(x lt 26) [StringfromCharCode(x+65) x+1] 0)
alphabet() [ABCDEFGHIJKLMNOPQRSTUVWXYZ]
AssignmentLoops
CallbacksSide EffectsBranching
Errors
CallbacksSide Effects
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
contrivedEx2()fork(e =gt consoleerror(e) r =gt consolelog(success))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))fork(e =gt consoleerror(e)
r =gt consolelog(r))
AssignmentLoops
CallbacksSide EffectsBranching
Errors
BranchingErrors
EitherOr
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
leftOrRightfold(e =gt `we had an error $e` s =gt stoUpperCase())
Right(hair brown) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Right(five 2))
Right(10)
Left(ignored) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Left(five 2))
Left(ignored)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
Claim
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
AssignmentLoops
CallbacksSide EffectsBranching
Errors
const depObjs = b =gt List(bdeps)flatMap(next =gt findDependencyByProject(nextProjectname bpreviousdeps) fold(x =gt x found =gt makeArgs(next found)))
const mapBuildsAndDepsForDiffQueue = (builds) =gt List(builds) filter(b =gt bprevious) flatMap(b =gt makeArgs(b bprevious)concat(depObjs(b))) filter(b =gt b) toJS()
const filterExistingDiffs = (items) =gt List(items)traverse(Taskof (i) =gt find(Diff BuildId ibuildId DiffId iprevId type imethod ) map(e =gt eswap()getOrElse(null)) map(bs =gt bsfilter(x =gt x)toJS())
const buildProject = (branch sha) =gt queueUnzipWwwOnS3(sha) chain(() =gt isReleaseOrMainBranch(branch)) fold(() =gt _noop () =gt generateReport(sha) chain(queueDiffsForTileBuildsAndDeps) chain(() =gt getHeadCommit(sha) fold(() =gt Taskof(null) head =gt makeVrtDeployment(head sha) chain(() =gt createPrApp(head sha)))) fork(consoleerror
consolelog))
const vrtReport = (sha email platforms) =gt rejectFinishedPlatformOptions(platforms) chain(plats =gt platsmap(gatherScreenshots)) chain(shots =gt fromNullable(sha) fold(() =gt findLastRef() () =gt findBuild(sha)) chain(ref =gt renderReport(shots ref email))) fork(e =gt e r =gt r)
Harder to hack
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
Safer
const ProfileLink = user =gtlta href=`users$
uid`gtunameltagt
const Header = str =gt lth1gtNow Viewing strlth1gt
Component a -gt JSX
a JSXf
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
const dotChainy = str =gt str toLowerCase() split( ) map(c =gt ctrim()) reverse() filter(x =gt xlength gt 3) join()
const dotChainy = str =gt str toLowerCase() split( ) map(c =gt ctrim()) reverse() filter(x =gt xlength gt 3) join() Chain Dot Com
const dotChainy = str =gt str toLowerCase() split( ) map(c =gt ctrim()) reverse() filter(x =gt xlength gt 3) join() lsquochain dot com
const dotChainy = str =gt str toLowerCase() split( ) map(c =gt ctrim()) reverse() filter(x =gt xlength gt 3) join() [chain dot com ]
const dotChainy = str =gt str toLowerCase() split( ) map(c =gt ctrim()) reverse() filter(x =gt xlength gt 3) join() [chain dot com]
const dotChainy = str =gt str toLowerCase() split( ) map(c =gt ctrim()) reverse() filter(x =gt xlength gt 3) join()
[com dot chain]
const dotChainy = str =gt const lower = strtoLowerCase() const words = lowersplit( )
wordsreverse()
for(let i in words) words[i] = words[i]trim()
let keepers = []
for(let i in words) if(words[i]length gt 3) keeperspush(words[i])
return keepersjoin()
const dotChainy = str =gt const lower = strtoLowerCase() const words = lowersplit( )
wordsreverse()
for(let i in words) words[i] = words[i]trim()
let keepers = []
for(let i in words) if(words[i]length gt 3) keeperspush(words[i])
return keepersjoin()
class AppMailer
constructor() thisemailer = new Emailer()
removeInvalidAddresses() for(let i in thisaddresses) if(thisaddresses[i]match()) thisaddressessplice(i 1)
sendEmail(from to) thisaddresses = to thisemailersetSender(from) thisremoveInvalidAddresses() thisemailersetRecipients(thisaddresses) thisemailersend()
ldquothe major contributor to this complexity in many systems is the handling of state and the burden that this adds when trying to analyse and reason about the systemrdquo
Out of the Tar Pit 2006-Ben Moseley amp Peter Marks
const dotChainy = str =gt str toLowerCase() split( ) map(c =gt ctrim()) reverse() filter(x =gt xlength gt 3) join()
WHAT IF I TOLD YOUhellip
WHAT IF I TOLD YOUhellip
Programming == Math
try return f(x) catch(e) consoleerror(e)
if(x) return f() else return y
for(let thing in things) if(thingamount gt 100) keeperspush(thingname)
for (i = 0 i lt carslength i++) text += cars[i] + ltbrgt
while (i lt 10) text += The number is + i i++
let stuff = [123]
stuff = [12]
stuffsplice(0 2)
stuffpop()
AssignmentLoops
CallbacksSide EffectsBranching
Errors
Programming == Math
Programming = Math
f g
f g
dot
f g = x =gt f(g(x))
strtoUpperCase()trim()
trim(toUpperCase(str))
Category theory
fn fn
fnfn
a bf
cg
ag
cf
a
F(a)
bf
F(f)
cg
F(b) F(g)F(c)
a
F(a)
g
F(gf)
cf
F(c)
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) A
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt parseInt(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) Box(lsquoArsquo)
const Box = x =gt( map f =gt Box(f(x)))
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) Box(lsquoArsquo)
const Box = x =gt( map f =gt Box(f(x)))
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) fold(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) lsquoArsquo
const Box = x =gt( map f =gt Box(f(x)) fold f =gt f(x))
Unified call syntaxMinimized state
Captured AssignmentForced Control Flow
AssignmentLoops
CallbacksSide EffectsBranching
Errors
Loops
mapfilter
reduce
const range = (i count) =gt unfold(x =gt if(x lt= count) [x x+1] i)
range(510) [ 5 6 7 8 9 10 ]
const alphabet = () =gt unfold(x =gt if(x lt 26) [StringfromCharCode(x+65) x+1] 0)
alphabet() [ABCDEFGHIJKLMNOPQRSTUVWXYZ]
AssignmentLoops
CallbacksSide EffectsBranching
Errors
CallbacksSide Effects
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
contrivedEx2()fork(e =gt consoleerror(e) r =gt consolelog(success))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))fork(e =gt consoleerror(e)
r =gt consolelog(r))
AssignmentLoops
CallbacksSide EffectsBranching
Errors
BranchingErrors
EitherOr
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
leftOrRightfold(e =gt `we had an error $e` s =gt stoUpperCase())
Right(hair brown) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Right(five 2))
Right(10)
Left(ignored) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Left(five 2))
Left(ignored)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
Claim
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
AssignmentLoops
CallbacksSide EffectsBranching
Errors
const depObjs = b =gt List(bdeps)flatMap(next =gt findDependencyByProject(nextProjectname bpreviousdeps) fold(x =gt x found =gt makeArgs(next found)))
const mapBuildsAndDepsForDiffQueue = (builds) =gt List(builds) filter(b =gt bprevious) flatMap(b =gt makeArgs(b bprevious)concat(depObjs(b))) filter(b =gt b) toJS()
const filterExistingDiffs = (items) =gt List(items)traverse(Taskof (i) =gt find(Diff BuildId ibuildId DiffId iprevId type imethod ) map(e =gt eswap()getOrElse(null)) map(bs =gt bsfilter(x =gt x)toJS())
const buildProject = (branch sha) =gt queueUnzipWwwOnS3(sha) chain(() =gt isReleaseOrMainBranch(branch)) fold(() =gt _noop () =gt generateReport(sha) chain(queueDiffsForTileBuildsAndDeps) chain(() =gt getHeadCommit(sha) fold(() =gt Taskof(null) head =gt makeVrtDeployment(head sha) chain(() =gt createPrApp(head sha)))) fork(consoleerror
consolelog))
const vrtReport = (sha email platforms) =gt rejectFinishedPlatformOptions(platforms) chain(plats =gt platsmap(gatherScreenshots)) chain(shots =gt fromNullable(sha) fold(() =gt findLastRef() () =gt findBuild(sha)) chain(ref =gt renderReport(shots ref email))) fork(e =gt e r =gt r)
Harder to hack
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
Safer
const ProfileLink = user =gtlta href=`users$
uid`gtunameltagt
const Header = str =gt lth1gtNow Viewing strlth1gt
Component a -gt JSX
a JSXf
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
const dotChainy = str =gt str toLowerCase() split( ) map(c =gt ctrim()) reverse() filter(x =gt xlength gt 3) join() Chain Dot Com
const dotChainy = str =gt str toLowerCase() split( ) map(c =gt ctrim()) reverse() filter(x =gt xlength gt 3) join() lsquochain dot com
const dotChainy = str =gt str toLowerCase() split( ) map(c =gt ctrim()) reverse() filter(x =gt xlength gt 3) join() [chain dot com ]
const dotChainy = str =gt str toLowerCase() split( ) map(c =gt ctrim()) reverse() filter(x =gt xlength gt 3) join() [chain dot com]
const dotChainy = str =gt str toLowerCase() split( ) map(c =gt ctrim()) reverse() filter(x =gt xlength gt 3) join()
[com dot chain]
const dotChainy = str =gt const lower = strtoLowerCase() const words = lowersplit( )
wordsreverse()
for(let i in words) words[i] = words[i]trim()
let keepers = []
for(let i in words) if(words[i]length gt 3) keeperspush(words[i])
return keepersjoin()
const dotChainy = str =gt const lower = strtoLowerCase() const words = lowersplit( )
wordsreverse()
for(let i in words) words[i] = words[i]trim()
let keepers = []
for(let i in words) if(words[i]length gt 3) keeperspush(words[i])
return keepersjoin()
class AppMailer
constructor() thisemailer = new Emailer()
removeInvalidAddresses() for(let i in thisaddresses) if(thisaddresses[i]match()) thisaddressessplice(i 1)
sendEmail(from to) thisaddresses = to thisemailersetSender(from) thisremoveInvalidAddresses() thisemailersetRecipients(thisaddresses) thisemailersend()
ldquothe major contributor to this complexity in many systems is the handling of state and the burden that this adds when trying to analyse and reason about the systemrdquo
Out of the Tar Pit 2006-Ben Moseley amp Peter Marks
const dotChainy = str =gt str toLowerCase() split( ) map(c =gt ctrim()) reverse() filter(x =gt xlength gt 3) join()
WHAT IF I TOLD YOUhellip
WHAT IF I TOLD YOUhellip
Programming == Math
try return f(x) catch(e) consoleerror(e)
if(x) return f() else return y
for(let thing in things) if(thingamount gt 100) keeperspush(thingname)
for (i = 0 i lt carslength i++) text += cars[i] + ltbrgt
while (i lt 10) text += The number is + i i++
let stuff = [123]
stuff = [12]
stuffsplice(0 2)
stuffpop()
AssignmentLoops
CallbacksSide EffectsBranching
Errors
Programming == Math
Programming = Math
f g
f g
dot
f g = x =gt f(g(x))
strtoUpperCase()trim()
trim(toUpperCase(str))
Category theory
fn fn
fnfn
a bf
cg
ag
cf
a
F(a)
bf
F(f)
cg
F(b) F(g)F(c)
a
F(a)
g
F(gf)
cf
F(c)
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) A
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt parseInt(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) Box(lsquoArsquo)
const Box = x =gt( map f =gt Box(f(x)))
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) Box(lsquoArsquo)
const Box = x =gt( map f =gt Box(f(x)))
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) fold(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) lsquoArsquo
const Box = x =gt( map f =gt Box(f(x)) fold f =gt f(x))
Unified call syntaxMinimized state
Captured AssignmentForced Control Flow
AssignmentLoops
CallbacksSide EffectsBranching
Errors
Loops
mapfilter
reduce
const range = (i count) =gt unfold(x =gt if(x lt= count) [x x+1] i)
range(510) [ 5 6 7 8 9 10 ]
const alphabet = () =gt unfold(x =gt if(x lt 26) [StringfromCharCode(x+65) x+1] 0)
alphabet() [ABCDEFGHIJKLMNOPQRSTUVWXYZ]
AssignmentLoops
CallbacksSide EffectsBranching
Errors
CallbacksSide Effects
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
contrivedEx2()fork(e =gt consoleerror(e) r =gt consolelog(success))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))fork(e =gt consoleerror(e)
r =gt consolelog(r))
AssignmentLoops
CallbacksSide EffectsBranching
Errors
BranchingErrors
EitherOr
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
leftOrRightfold(e =gt `we had an error $e` s =gt stoUpperCase())
Right(hair brown) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Right(five 2))
Right(10)
Left(ignored) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Left(five 2))
Left(ignored)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
Claim
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
AssignmentLoops
CallbacksSide EffectsBranching
Errors
const depObjs = b =gt List(bdeps)flatMap(next =gt findDependencyByProject(nextProjectname bpreviousdeps) fold(x =gt x found =gt makeArgs(next found)))
const mapBuildsAndDepsForDiffQueue = (builds) =gt List(builds) filter(b =gt bprevious) flatMap(b =gt makeArgs(b bprevious)concat(depObjs(b))) filter(b =gt b) toJS()
const filterExistingDiffs = (items) =gt List(items)traverse(Taskof (i) =gt find(Diff BuildId ibuildId DiffId iprevId type imethod ) map(e =gt eswap()getOrElse(null)) map(bs =gt bsfilter(x =gt x)toJS())
const buildProject = (branch sha) =gt queueUnzipWwwOnS3(sha) chain(() =gt isReleaseOrMainBranch(branch)) fold(() =gt _noop () =gt generateReport(sha) chain(queueDiffsForTileBuildsAndDeps) chain(() =gt getHeadCommit(sha) fold(() =gt Taskof(null) head =gt makeVrtDeployment(head sha) chain(() =gt createPrApp(head sha)))) fork(consoleerror
consolelog))
const vrtReport = (sha email platforms) =gt rejectFinishedPlatformOptions(platforms) chain(plats =gt platsmap(gatherScreenshots)) chain(shots =gt fromNullable(sha) fold(() =gt findLastRef() () =gt findBuild(sha)) chain(ref =gt renderReport(shots ref email))) fork(e =gt e r =gt r)
Harder to hack
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
Safer
const ProfileLink = user =gtlta href=`users$
uid`gtunameltagt
const Header = str =gt lth1gtNow Viewing strlth1gt
Component a -gt JSX
a JSXf
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
const dotChainy = str =gt str toLowerCase() split( ) map(c =gt ctrim()) reverse() filter(x =gt xlength gt 3) join() lsquochain dot com
const dotChainy = str =gt str toLowerCase() split( ) map(c =gt ctrim()) reverse() filter(x =gt xlength gt 3) join() [chain dot com ]
const dotChainy = str =gt str toLowerCase() split( ) map(c =gt ctrim()) reverse() filter(x =gt xlength gt 3) join() [chain dot com]
const dotChainy = str =gt str toLowerCase() split( ) map(c =gt ctrim()) reverse() filter(x =gt xlength gt 3) join()
[com dot chain]
const dotChainy = str =gt const lower = strtoLowerCase() const words = lowersplit( )
wordsreverse()
for(let i in words) words[i] = words[i]trim()
let keepers = []
for(let i in words) if(words[i]length gt 3) keeperspush(words[i])
return keepersjoin()
const dotChainy = str =gt const lower = strtoLowerCase() const words = lowersplit( )
wordsreverse()
for(let i in words) words[i] = words[i]trim()
let keepers = []
for(let i in words) if(words[i]length gt 3) keeperspush(words[i])
return keepersjoin()
class AppMailer
constructor() thisemailer = new Emailer()
removeInvalidAddresses() for(let i in thisaddresses) if(thisaddresses[i]match()) thisaddressessplice(i 1)
sendEmail(from to) thisaddresses = to thisemailersetSender(from) thisremoveInvalidAddresses() thisemailersetRecipients(thisaddresses) thisemailersend()
ldquothe major contributor to this complexity in many systems is the handling of state and the burden that this adds when trying to analyse and reason about the systemrdquo
Out of the Tar Pit 2006-Ben Moseley amp Peter Marks
const dotChainy = str =gt str toLowerCase() split( ) map(c =gt ctrim()) reverse() filter(x =gt xlength gt 3) join()
WHAT IF I TOLD YOUhellip
WHAT IF I TOLD YOUhellip
Programming == Math
try return f(x) catch(e) consoleerror(e)
if(x) return f() else return y
for(let thing in things) if(thingamount gt 100) keeperspush(thingname)
for (i = 0 i lt carslength i++) text += cars[i] + ltbrgt
while (i lt 10) text += The number is + i i++
let stuff = [123]
stuff = [12]
stuffsplice(0 2)
stuffpop()
AssignmentLoops
CallbacksSide EffectsBranching
Errors
Programming == Math
Programming = Math
f g
f g
dot
f g = x =gt f(g(x))
strtoUpperCase()trim()
trim(toUpperCase(str))
Category theory
fn fn
fnfn
a bf
cg
ag
cf
a
F(a)
bf
F(f)
cg
F(b) F(g)F(c)
a
F(a)
g
F(gf)
cf
F(c)
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) A
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt parseInt(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) Box(lsquoArsquo)
const Box = x =gt( map f =gt Box(f(x)))
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) Box(lsquoArsquo)
const Box = x =gt( map f =gt Box(f(x)))
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) fold(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) lsquoArsquo
const Box = x =gt( map f =gt Box(f(x)) fold f =gt f(x))
Unified call syntaxMinimized state
Captured AssignmentForced Control Flow
AssignmentLoops
CallbacksSide EffectsBranching
Errors
Loops
mapfilter
reduce
const range = (i count) =gt unfold(x =gt if(x lt= count) [x x+1] i)
range(510) [ 5 6 7 8 9 10 ]
const alphabet = () =gt unfold(x =gt if(x lt 26) [StringfromCharCode(x+65) x+1] 0)
alphabet() [ABCDEFGHIJKLMNOPQRSTUVWXYZ]
AssignmentLoops
CallbacksSide EffectsBranching
Errors
CallbacksSide Effects
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
contrivedEx2()fork(e =gt consoleerror(e) r =gt consolelog(success))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))fork(e =gt consoleerror(e)
r =gt consolelog(r))
AssignmentLoops
CallbacksSide EffectsBranching
Errors
BranchingErrors
EitherOr
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
leftOrRightfold(e =gt `we had an error $e` s =gt stoUpperCase())
Right(hair brown) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Right(five 2))
Right(10)
Left(ignored) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Left(five 2))
Left(ignored)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
Claim
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
AssignmentLoops
CallbacksSide EffectsBranching
Errors
const depObjs = b =gt List(bdeps)flatMap(next =gt findDependencyByProject(nextProjectname bpreviousdeps) fold(x =gt x found =gt makeArgs(next found)))
const mapBuildsAndDepsForDiffQueue = (builds) =gt List(builds) filter(b =gt bprevious) flatMap(b =gt makeArgs(b bprevious)concat(depObjs(b))) filter(b =gt b) toJS()
const filterExistingDiffs = (items) =gt List(items)traverse(Taskof (i) =gt find(Diff BuildId ibuildId DiffId iprevId type imethod ) map(e =gt eswap()getOrElse(null)) map(bs =gt bsfilter(x =gt x)toJS())
const buildProject = (branch sha) =gt queueUnzipWwwOnS3(sha) chain(() =gt isReleaseOrMainBranch(branch)) fold(() =gt _noop () =gt generateReport(sha) chain(queueDiffsForTileBuildsAndDeps) chain(() =gt getHeadCommit(sha) fold(() =gt Taskof(null) head =gt makeVrtDeployment(head sha) chain(() =gt createPrApp(head sha)))) fork(consoleerror
consolelog))
const vrtReport = (sha email platforms) =gt rejectFinishedPlatformOptions(platforms) chain(plats =gt platsmap(gatherScreenshots)) chain(shots =gt fromNullable(sha) fold(() =gt findLastRef() () =gt findBuild(sha)) chain(ref =gt renderReport(shots ref email))) fork(e =gt e r =gt r)
Harder to hack
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
Safer
const ProfileLink = user =gtlta href=`users$
uid`gtunameltagt
const Header = str =gt lth1gtNow Viewing strlth1gt
Component a -gt JSX
a JSXf
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
const dotChainy = str =gt str toLowerCase() split( ) map(c =gt ctrim()) reverse() filter(x =gt xlength gt 3) join() [chain dot com ]
const dotChainy = str =gt str toLowerCase() split( ) map(c =gt ctrim()) reverse() filter(x =gt xlength gt 3) join() [chain dot com]
const dotChainy = str =gt str toLowerCase() split( ) map(c =gt ctrim()) reverse() filter(x =gt xlength gt 3) join()
[com dot chain]
const dotChainy = str =gt const lower = strtoLowerCase() const words = lowersplit( )
wordsreverse()
for(let i in words) words[i] = words[i]trim()
let keepers = []
for(let i in words) if(words[i]length gt 3) keeperspush(words[i])
return keepersjoin()
const dotChainy = str =gt const lower = strtoLowerCase() const words = lowersplit( )
wordsreverse()
for(let i in words) words[i] = words[i]trim()
let keepers = []
for(let i in words) if(words[i]length gt 3) keeperspush(words[i])
return keepersjoin()
class AppMailer
constructor() thisemailer = new Emailer()
removeInvalidAddresses() for(let i in thisaddresses) if(thisaddresses[i]match()) thisaddressessplice(i 1)
sendEmail(from to) thisaddresses = to thisemailersetSender(from) thisremoveInvalidAddresses() thisemailersetRecipients(thisaddresses) thisemailersend()
ldquothe major contributor to this complexity in many systems is the handling of state and the burden that this adds when trying to analyse and reason about the systemrdquo
Out of the Tar Pit 2006-Ben Moseley amp Peter Marks
const dotChainy = str =gt str toLowerCase() split( ) map(c =gt ctrim()) reverse() filter(x =gt xlength gt 3) join()
WHAT IF I TOLD YOUhellip
WHAT IF I TOLD YOUhellip
Programming == Math
try return f(x) catch(e) consoleerror(e)
if(x) return f() else return y
for(let thing in things) if(thingamount gt 100) keeperspush(thingname)
for (i = 0 i lt carslength i++) text += cars[i] + ltbrgt
while (i lt 10) text += The number is + i i++
let stuff = [123]
stuff = [12]
stuffsplice(0 2)
stuffpop()
AssignmentLoops
CallbacksSide EffectsBranching
Errors
Programming == Math
Programming = Math
f g
f g
dot
f g = x =gt f(g(x))
strtoUpperCase()trim()
trim(toUpperCase(str))
Category theory
fn fn
fnfn
a bf
cg
ag
cf
a
F(a)
bf
F(f)
cg
F(b) F(g)F(c)
a
F(a)
g
F(gf)
cf
F(c)
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) A
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt parseInt(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) Box(lsquoArsquo)
const Box = x =gt( map f =gt Box(f(x)))
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) Box(lsquoArsquo)
const Box = x =gt( map f =gt Box(f(x)))
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) fold(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) lsquoArsquo
const Box = x =gt( map f =gt Box(f(x)) fold f =gt f(x))
Unified call syntaxMinimized state
Captured AssignmentForced Control Flow
AssignmentLoops
CallbacksSide EffectsBranching
Errors
Loops
mapfilter
reduce
const range = (i count) =gt unfold(x =gt if(x lt= count) [x x+1] i)
range(510) [ 5 6 7 8 9 10 ]
const alphabet = () =gt unfold(x =gt if(x lt 26) [StringfromCharCode(x+65) x+1] 0)
alphabet() [ABCDEFGHIJKLMNOPQRSTUVWXYZ]
AssignmentLoops
CallbacksSide EffectsBranching
Errors
CallbacksSide Effects
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
contrivedEx2()fork(e =gt consoleerror(e) r =gt consolelog(success))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))fork(e =gt consoleerror(e)
r =gt consolelog(r))
AssignmentLoops
CallbacksSide EffectsBranching
Errors
BranchingErrors
EitherOr
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
leftOrRightfold(e =gt `we had an error $e` s =gt stoUpperCase())
Right(hair brown) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Right(five 2))
Right(10)
Left(ignored) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Left(five 2))
Left(ignored)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
Claim
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
AssignmentLoops
CallbacksSide EffectsBranching
Errors
const depObjs = b =gt List(bdeps)flatMap(next =gt findDependencyByProject(nextProjectname bpreviousdeps) fold(x =gt x found =gt makeArgs(next found)))
const mapBuildsAndDepsForDiffQueue = (builds) =gt List(builds) filter(b =gt bprevious) flatMap(b =gt makeArgs(b bprevious)concat(depObjs(b))) filter(b =gt b) toJS()
const filterExistingDiffs = (items) =gt List(items)traverse(Taskof (i) =gt find(Diff BuildId ibuildId DiffId iprevId type imethod ) map(e =gt eswap()getOrElse(null)) map(bs =gt bsfilter(x =gt x)toJS())
const buildProject = (branch sha) =gt queueUnzipWwwOnS3(sha) chain(() =gt isReleaseOrMainBranch(branch)) fold(() =gt _noop () =gt generateReport(sha) chain(queueDiffsForTileBuildsAndDeps) chain(() =gt getHeadCommit(sha) fold(() =gt Taskof(null) head =gt makeVrtDeployment(head sha) chain(() =gt createPrApp(head sha)))) fork(consoleerror
consolelog))
const vrtReport = (sha email platforms) =gt rejectFinishedPlatformOptions(platforms) chain(plats =gt platsmap(gatherScreenshots)) chain(shots =gt fromNullable(sha) fold(() =gt findLastRef() () =gt findBuild(sha)) chain(ref =gt renderReport(shots ref email))) fork(e =gt e r =gt r)
Harder to hack
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
Safer
const ProfileLink = user =gtlta href=`users$
uid`gtunameltagt
const Header = str =gt lth1gtNow Viewing strlth1gt
Component a -gt JSX
a JSXf
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
const dotChainy = str =gt str toLowerCase() split( ) map(c =gt ctrim()) reverse() filter(x =gt xlength gt 3) join() [chain dot com]
const dotChainy = str =gt str toLowerCase() split( ) map(c =gt ctrim()) reverse() filter(x =gt xlength gt 3) join()
[com dot chain]
const dotChainy = str =gt const lower = strtoLowerCase() const words = lowersplit( )
wordsreverse()
for(let i in words) words[i] = words[i]trim()
let keepers = []
for(let i in words) if(words[i]length gt 3) keeperspush(words[i])
return keepersjoin()
const dotChainy = str =gt const lower = strtoLowerCase() const words = lowersplit( )
wordsreverse()
for(let i in words) words[i] = words[i]trim()
let keepers = []
for(let i in words) if(words[i]length gt 3) keeperspush(words[i])
return keepersjoin()
class AppMailer
constructor() thisemailer = new Emailer()
removeInvalidAddresses() for(let i in thisaddresses) if(thisaddresses[i]match()) thisaddressessplice(i 1)
sendEmail(from to) thisaddresses = to thisemailersetSender(from) thisremoveInvalidAddresses() thisemailersetRecipients(thisaddresses) thisemailersend()
ldquothe major contributor to this complexity in many systems is the handling of state and the burden that this adds when trying to analyse and reason about the systemrdquo
Out of the Tar Pit 2006-Ben Moseley amp Peter Marks
const dotChainy = str =gt str toLowerCase() split( ) map(c =gt ctrim()) reverse() filter(x =gt xlength gt 3) join()
WHAT IF I TOLD YOUhellip
WHAT IF I TOLD YOUhellip
Programming == Math
try return f(x) catch(e) consoleerror(e)
if(x) return f() else return y
for(let thing in things) if(thingamount gt 100) keeperspush(thingname)
for (i = 0 i lt carslength i++) text += cars[i] + ltbrgt
while (i lt 10) text += The number is + i i++
let stuff = [123]
stuff = [12]
stuffsplice(0 2)
stuffpop()
AssignmentLoops
CallbacksSide EffectsBranching
Errors
Programming == Math
Programming = Math
f g
f g
dot
f g = x =gt f(g(x))
strtoUpperCase()trim()
trim(toUpperCase(str))
Category theory
fn fn
fnfn
a bf
cg
ag
cf
a
F(a)
bf
F(f)
cg
F(b) F(g)F(c)
a
F(a)
g
F(gf)
cf
F(c)
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) A
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt parseInt(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) Box(lsquoArsquo)
const Box = x =gt( map f =gt Box(f(x)))
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) Box(lsquoArsquo)
const Box = x =gt( map f =gt Box(f(x)))
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) fold(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) lsquoArsquo
const Box = x =gt( map f =gt Box(f(x)) fold f =gt f(x))
Unified call syntaxMinimized state
Captured AssignmentForced Control Flow
AssignmentLoops
CallbacksSide EffectsBranching
Errors
Loops
mapfilter
reduce
const range = (i count) =gt unfold(x =gt if(x lt= count) [x x+1] i)
range(510) [ 5 6 7 8 9 10 ]
const alphabet = () =gt unfold(x =gt if(x lt 26) [StringfromCharCode(x+65) x+1] 0)
alphabet() [ABCDEFGHIJKLMNOPQRSTUVWXYZ]
AssignmentLoops
CallbacksSide EffectsBranching
Errors
CallbacksSide Effects
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
contrivedEx2()fork(e =gt consoleerror(e) r =gt consolelog(success))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))fork(e =gt consoleerror(e)
r =gt consolelog(r))
AssignmentLoops
CallbacksSide EffectsBranching
Errors
BranchingErrors
EitherOr
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
leftOrRightfold(e =gt `we had an error $e` s =gt stoUpperCase())
Right(hair brown) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Right(five 2))
Right(10)
Left(ignored) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Left(five 2))
Left(ignored)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
Claim
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
AssignmentLoops
CallbacksSide EffectsBranching
Errors
const depObjs = b =gt List(bdeps)flatMap(next =gt findDependencyByProject(nextProjectname bpreviousdeps) fold(x =gt x found =gt makeArgs(next found)))
const mapBuildsAndDepsForDiffQueue = (builds) =gt List(builds) filter(b =gt bprevious) flatMap(b =gt makeArgs(b bprevious)concat(depObjs(b))) filter(b =gt b) toJS()
const filterExistingDiffs = (items) =gt List(items)traverse(Taskof (i) =gt find(Diff BuildId ibuildId DiffId iprevId type imethod ) map(e =gt eswap()getOrElse(null)) map(bs =gt bsfilter(x =gt x)toJS())
const buildProject = (branch sha) =gt queueUnzipWwwOnS3(sha) chain(() =gt isReleaseOrMainBranch(branch)) fold(() =gt _noop () =gt generateReport(sha) chain(queueDiffsForTileBuildsAndDeps) chain(() =gt getHeadCommit(sha) fold(() =gt Taskof(null) head =gt makeVrtDeployment(head sha) chain(() =gt createPrApp(head sha)))) fork(consoleerror
consolelog))
const vrtReport = (sha email platforms) =gt rejectFinishedPlatformOptions(platforms) chain(plats =gt platsmap(gatherScreenshots)) chain(shots =gt fromNullable(sha) fold(() =gt findLastRef() () =gt findBuild(sha)) chain(ref =gt renderReport(shots ref email))) fork(e =gt e r =gt r)
Harder to hack
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
Safer
const ProfileLink = user =gtlta href=`users$
uid`gtunameltagt
const Header = str =gt lth1gtNow Viewing strlth1gt
Component a -gt JSX
a JSXf
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
const dotChainy = str =gt str toLowerCase() split( ) map(c =gt ctrim()) reverse() filter(x =gt xlength gt 3) join()
[com dot chain]
const dotChainy = str =gt const lower = strtoLowerCase() const words = lowersplit( )
wordsreverse()
for(let i in words) words[i] = words[i]trim()
let keepers = []
for(let i in words) if(words[i]length gt 3) keeperspush(words[i])
return keepersjoin()
const dotChainy = str =gt const lower = strtoLowerCase() const words = lowersplit( )
wordsreverse()
for(let i in words) words[i] = words[i]trim()
let keepers = []
for(let i in words) if(words[i]length gt 3) keeperspush(words[i])
return keepersjoin()
class AppMailer
constructor() thisemailer = new Emailer()
removeInvalidAddresses() for(let i in thisaddresses) if(thisaddresses[i]match()) thisaddressessplice(i 1)
sendEmail(from to) thisaddresses = to thisemailersetSender(from) thisremoveInvalidAddresses() thisemailersetRecipients(thisaddresses) thisemailersend()
ldquothe major contributor to this complexity in many systems is the handling of state and the burden that this adds when trying to analyse and reason about the systemrdquo
Out of the Tar Pit 2006-Ben Moseley amp Peter Marks
const dotChainy = str =gt str toLowerCase() split( ) map(c =gt ctrim()) reverse() filter(x =gt xlength gt 3) join()
WHAT IF I TOLD YOUhellip
WHAT IF I TOLD YOUhellip
Programming == Math
try return f(x) catch(e) consoleerror(e)
if(x) return f() else return y
for(let thing in things) if(thingamount gt 100) keeperspush(thingname)
for (i = 0 i lt carslength i++) text += cars[i] + ltbrgt
while (i lt 10) text += The number is + i i++
let stuff = [123]
stuff = [12]
stuffsplice(0 2)
stuffpop()
AssignmentLoops
CallbacksSide EffectsBranching
Errors
Programming == Math
Programming = Math
f g
f g
dot
f g = x =gt f(g(x))
strtoUpperCase()trim()
trim(toUpperCase(str))
Category theory
fn fn
fnfn
a bf
cg
ag
cf
a
F(a)
bf
F(f)
cg
F(b) F(g)F(c)
a
F(a)
g
F(gf)
cf
F(c)
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) A
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt parseInt(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) Box(lsquoArsquo)
const Box = x =gt( map f =gt Box(f(x)))
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) Box(lsquoArsquo)
const Box = x =gt( map f =gt Box(f(x)))
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) fold(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) lsquoArsquo
const Box = x =gt( map f =gt Box(f(x)) fold f =gt f(x))
Unified call syntaxMinimized state
Captured AssignmentForced Control Flow
AssignmentLoops
CallbacksSide EffectsBranching
Errors
Loops
mapfilter
reduce
const range = (i count) =gt unfold(x =gt if(x lt= count) [x x+1] i)
range(510) [ 5 6 7 8 9 10 ]
const alphabet = () =gt unfold(x =gt if(x lt 26) [StringfromCharCode(x+65) x+1] 0)
alphabet() [ABCDEFGHIJKLMNOPQRSTUVWXYZ]
AssignmentLoops
CallbacksSide EffectsBranching
Errors
CallbacksSide Effects
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
contrivedEx2()fork(e =gt consoleerror(e) r =gt consolelog(success))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))fork(e =gt consoleerror(e)
r =gt consolelog(r))
AssignmentLoops
CallbacksSide EffectsBranching
Errors
BranchingErrors
EitherOr
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
leftOrRightfold(e =gt `we had an error $e` s =gt stoUpperCase())
Right(hair brown) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Right(five 2))
Right(10)
Left(ignored) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Left(five 2))
Left(ignored)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
Claim
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
AssignmentLoops
CallbacksSide EffectsBranching
Errors
const depObjs = b =gt List(bdeps)flatMap(next =gt findDependencyByProject(nextProjectname bpreviousdeps) fold(x =gt x found =gt makeArgs(next found)))
const mapBuildsAndDepsForDiffQueue = (builds) =gt List(builds) filter(b =gt bprevious) flatMap(b =gt makeArgs(b bprevious)concat(depObjs(b))) filter(b =gt b) toJS()
const filterExistingDiffs = (items) =gt List(items)traverse(Taskof (i) =gt find(Diff BuildId ibuildId DiffId iprevId type imethod ) map(e =gt eswap()getOrElse(null)) map(bs =gt bsfilter(x =gt x)toJS())
const buildProject = (branch sha) =gt queueUnzipWwwOnS3(sha) chain(() =gt isReleaseOrMainBranch(branch)) fold(() =gt _noop () =gt generateReport(sha) chain(queueDiffsForTileBuildsAndDeps) chain(() =gt getHeadCommit(sha) fold(() =gt Taskof(null) head =gt makeVrtDeployment(head sha) chain(() =gt createPrApp(head sha)))) fork(consoleerror
consolelog))
const vrtReport = (sha email platforms) =gt rejectFinishedPlatformOptions(platforms) chain(plats =gt platsmap(gatherScreenshots)) chain(shots =gt fromNullable(sha) fold(() =gt findLastRef() () =gt findBuild(sha)) chain(ref =gt renderReport(shots ref email))) fork(e =gt e r =gt r)
Harder to hack
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
Safer
const ProfileLink = user =gtlta href=`users$
uid`gtunameltagt
const Header = str =gt lth1gtNow Viewing strlth1gt
Component a -gt JSX
a JSXf
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
const dotChainy = str =gt const lower = strtoLowerCase() const words = lowersplit( )
wordsreverse()
for(let i in words) words[i] = words[i]trim()
let keepers = []
for(let i in words) if(words[i]length gt 3) keeperspush(words[i])
return keepersjoin()
const dotChainy = str =gt const lower = strtoLowerCase() const words = lowersplit( )
wordsreverse()
for(let i in words) words[i] = words[i]trim()
let keepers = []
for(let i in words) if(words[i]length gt 3) keeperspush(words[i])
return keepersjoin()
class AppMailer
constructor() thisemailer = new Emailer()
removeInvalidAddresses() for(let i in thisaddresses) if(thisaddresses[i]match()) thisaddressessplice(i 1)
sendEmail(from to) thisaddresses = to thisemailersetSender(from) thisremoveInvalidAddresses() thisemailersetRecipients(thisaddresses) thisemailersend()
ldquothe major contributor to this complexity in many systems is the handling of state and the burden that this adds when trying to analyse and reason about the systemrdquo
Out of the Tar Pit 2006-Ben Moseley amp Peter Marks
const dotChainy = str =gt str toLowerCase() split( ) map(c =gt ctrim()) reverse() filter(x =gt xlength gt 3) join()
WHAT IF I TOLD YOUhellip
WHAT IF I TOLD YOUhellip
Programming == Math
try return f(x) catch(e) consoleerror(e)
if(x) return f() else return y
for(let thing in things) if(thingamount gt 100) keeperspush(thingname)
for (i = 0 i lt carslength i++) text += cars[i] + ltbrgt
while (i lt 10) text += The number is + i i++
let stuff = [123]
stuff = [12]
stuffsplice(0 2)
stuffpop()
AssignmentLoops
CallbacksSide EffectsBranching
Errors
Programming == Math
Programming = Math
f g
f g
dot
f g = x =gt f(g(x))
strtoUpperCase()trim()
trim(toUpperCase(str))
Category theory
fn fn
fnfn
a bf
cg
ag
cf
a
F(a)
bf
F(f)
cg
F(b) F(g)F(c)
a
F(a)
g
F(gf)
cf
F(c)
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) A
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt parseInt(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) Box(lsquoArsquo)
const Box = x =gt( map f =gt Box(f(x)))
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) Box(lsquoArsquo)
const Box = x =gt( map f =gt Box(f(x)))
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) fold(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) lsquoArsquo
const Box = x =gt( map f =gt Box(f(x)) fold f =gt f(x))
Unified call syntaxMinimized state
Captured AssignmentForced Control Flow
AssignmentLoops
CallbacksSide EffectsBranching
Errors
Loops
mapfilter
reduce
const range = (i count) =gt unfold(x =gt if(x lt= count) [x x+1] i)
range(510) [ 5 6 7 8 9 10 ]
const alphabet = () =gt unfold(x =gt if(x lt 26) [StringfromCharCode(x+65) x+1] 0)
alphabet() [ABCDEFGHIJKLMNOPQRSTUVWXYZ]
AssignmentLoops
CallbacksSide EffectsBranching
Errors
CallbacksSide Effects
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
contrivedEx2()fork(e =gt consoleerror(e) r =gt consolelog(success))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))fork(e =gt consoleerror(e)
r =gt consolelog(r))
AssignmentLoops
CallbacksSide EffectsBranching
Errors
BranchingErrors
EitherOr
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
leftOrRightfold(e =gt `we had an error $e` s =gt stoUpperCase())
Right(hair brown) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Right(five 2))
Right(10)
Left(ignored) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Left(five 2))
Left(ignored)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
Claim
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
AssignmentLoops
CallbacksSide EffectsBranching
Errors
const depObjs = b =gt List(bdeps)flatMap(next =gt findDependencyByProject(nextProjectname bpreviousdeps) fold(x =gt x found =gt makeArgs(next found)))
const mapBuildsAndDepsForDiffQueue = (builds) =gt List(builds) filter(b =gt bprevious) flatMap(b =gt makeArgs(b bprevious)concat(depObjs(b))) filter(b =gt b) toJS()
const filterExistingDiffs = (items) =gt List(items)traverse(Taskof (i) =gt find(Diff BuildId ibuildId DiffId iprevId type imethod ) map(e =gt eswap()getOrElse(null)) map(bs =gt bsfilter(x =gt x)toJS())
const buildProject = (branch sha) =gt queueUnzipWwwOnS3(sha) chain(() =gt isReleaseOrMainBranch(branch)) fold(() =gt _noop () =gt generateReport(sha) chain(queueDiffsForTileBuildsAndDeps) chain(() =gt getHeadCommit(sha) fold(() =gt Taskof(null) head =gt makeVrtDeployment(head sha) chain(() =gt createPrApp(head sha)))) fork(consoleerror
consolelog))
const vrtReport = (sha email platforms) =gt rejectFinishedPlatformOptions(platforms) chain(plats =gt platsmap(gatherScreenshots)) chain(shots =gt fromNullable(sha) fold(() =gt findLastRef() () =gt findBuild(sha)) chain(ref =gt renderReport(shots ref email))) fork(e =gt e r =gt r)
Harder to hack
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
Safer
const ProfileLink = user =gtlta href=`users$
uid`gtunameltagt
const Header = str =gt lth1gtNow Viewing strlth1gt
Component a -gt JSX
a JSXf
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
const dotChainy = str =gt const lower = strtoLowerCase() const words = lowersplit( )
wordsreverse()
for(let i in words) words[i] = words[i]trim()
let keepers = []
for(let i in words) if(words[i]length gt 3) keeperspush(words[i])
return keepersjoin()
class AppMailer
constructor() thisemailer = new Emailer()
removeInvalidAddresses() for(let i in thisaddresses) if(thisaddresses[i]match()) thisaddressessplice(i 1)
sendEmail(from to) thisaddresses = to thisemailersetSender(from) thisremoveInvalidAddresses() thisemailersetRecipients(thisaddresses) thisemailersend()
ldquothe major contributor to this complexity in many systems is the handling of state and the burden that this adds when trying to analyse and reason about the systemrdquo
Out of the Tar Pit 2006-Ben Moseley amp Peter Marks
const dotChainy = str =gt str toLowerCase() split( ) map(c =gt ctrim()) reverse() filter(x =gt xlength gt 3) join()
WHAT IF I TOLD YOUhellip
WHAT IF I TOLD YOUhellip
Programming == Math
try return f(x) catch(e) consoleerror(e)
if(x) return f() else return y
for(let thing in things) if(thingamount gt 100) keeperspush(thingname)
for (i = 0 i lt carslength i++) text += cars[i] + ltbrgt
while (i lt 10) text += The number is + i i++
let stuff = [123]
stuff = [12]
stuffsplice(0 2)
stuffpop()
AssignmentLoops
CallbacksSide EffectsBranching
Errors
Programming == Math
Programming = Math
f g
f g
dot
f g = x =gt f(g(x))
strtoUpperCase()trim()
trim(toUpperCase(str))
Category theory
fn fn
fnfn
a bf
cg
ag
cf
a
F(a)
bf
F(f)
cg
F(b) F(g)F(c)
a
F(a)
g
F(gf)
cf
F(c)
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) A
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt parseInt(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) Box(lsquoArsquo)
const Box = x =gt( map f =gt Box(f(x)))
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) Box(lsquoArsquo)
const Box = x =gt( map f =gt Box(f(x)))
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) fold(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) lsquoArsquo
const Box = x =gt( map f =gt Box(f(x)) fold f =gt f(x))
Unified call syntaxMinimized state
Captured AssignmentForced Control Flow
AssignmentLoops
CallbacksSide EffectsBranching
Errors
Loops
mapfilter
reduce
const range = (i count) =gt unfold(x =gt if(x lt= count) [x x+1] i)
range(510) [ 5 6 7 8 9 10 ]
const alphabet = () =gt unfold(x =gt if(x lt 26) [StringfromCharCode(x+65) x+1] 0)
alphabet() [ABCDEFGHIJKLMNOPQRSTUVWXYZ]
AssignmentLoops
CallbacksSide EffectsBranching
Errors
CallbacksSide Effects
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
contrivedEx2()fork(e =gt consoleerror(e) r =gt consolelog(success))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))fork(e =gt consoleerror(e)
r =gt consolelog(r))
AssignmentLoops
CallbacksSide EffectsBranching
Errors
BranchingErrors
EitherOr
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
leftOrRightfold(e =gt `we had an error $e` s =gt stoUpperCase())
Right(hair brown) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Right(five 2))
Right(10)
Left(ignored) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Left(five 2))
Left(ignored)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
Claim
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
AssignmentLoops
CallbacksSide EffectsBranching
Errors
const depObjs = b =gt List(bdeps)flatMap(next =gt findDependencyByProject(nextProjectname bpreviousdeps) fold(x =gt x found =gt makeArgs(next found)))
const mapBuildsAndDepsForDiffQueue = (builds) =gt List(builds) filter(b =gt bprevious) flatMap(b =gt makeArgs(b bprevious)concat(depObjs(b))) filter(b =gt b) toJS()
const filterExistingDiffs = (items) =gt List(items)traverse(Taskof (i) =gt find(Diff BuildId ibuildId DiffId iprevId type imethod ) map(e =gt eswap()getOrElse(null)) map(bs =gt bsfilter(x =gt x)toJS())
const buildProject = (branch sha) =gt queueUnzipWwwOnS3(sha) chain(() =gt isReleaseOrMainBranch(branch)) fold(() =gt _noop () =gt generateReport(sha) chain(queueDiffsForTileBuildsAndDeps) chain(() =gt getHeadCommit(sha) fold(() =gt Taskof(null) head =gt makeVrtDeployment(head sha) chain(() =gt createPrApp(head sha)))) fork(consoleerror
consolelog))
const vrtReport = (sha email platforms) =gt rejectFinishedPlatformOptions(platforms) chain(plats =gt platsmap(gatherScreenshots)) chain(shots =gt fromNullable(sha) fold(() =gt findLastRef() () =gt findBuild(sha)) chain(ref =gt renderReport(shots ref email))) fork(e =gt e r =gt r)
Harder to hack
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
Safer
const ProfileLink = user =gtlta href=`users$
uid`gtunameltagt
const Header = str =gt lth1gtNow Viewing strlth1gt
Component a -gt JSX
a JSXf
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
class AppMailer
constructor() thisemailer = new Emailer()
removeInvalidAddresses() for(let i in thisaddresses) if(thisaddresses[i]match()) thisaddressessplice(i 1)
sendEmail(from to) thisaddresses = to thisemailersetSender(from) thisremoveInvalidAddresses() thisemailersetRecipients(thisaddresses) thisemailersend()
ldquothe major contributor to this complexity in many systems is the handling of state and the burden that this adds when trying to analyse and reason about the systemrdquo
Out of the Tar Pit 2006-Ben Moseley amp Peter Marks
const dotChainy = str =gt str toLowerCase() split( ) map(c =gt ctrim()) reverse() filter(x =gt xlength gt 3) join()
WHAT IF I TOLD YOUhellip
WHAT IF I TOLD YOUhellip
Programming == Math
try return f(x) catch(e) consoleerror(e)
if(x) return f() else return y
for(let thing in things) if(thingamount gt 100) keeperspush(thingname)
for (i = 0 i lt carslength i++) text += cars[i] + ltbrgt
while (i lt 10) text += The number is + i i++
let stuff = [123]
stuff = [12]
stuffsplice(0 2)
stuffpop()
AssignmentLoops
CallbacksSide EffectsBranching
Errors
Programming == Math
Programming = Math
f g
f g
dot
f g = x =gt f(g(x))
strtoUpperCase()trim()
trim(toUpperCase(str))
Category theory
fn fn
fnfn
a bf
cg
ag
cf
a
F(a)
bf
F(f)
cg
F(b) F(g)F(c)
a
F(a)
g
F(gf)
cf
F(c)
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) A
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt parseInt(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) Box(lsquoArsquo)
const Box = x =gt( map f =gt Box(f(x)))
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) Box(lsquoArsquo)
const Box = x =gt( map f =gt Box(f(x)))
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) fold(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) lsquoArsquo
const Box = x =gt( map f =gt Box(f(x)) fold f =gt f(x))
Unified call syntaxMinimized state
Captured AssignmentForced Control Flow
AssignmentLoops
CallbacksSide EffectsBranching
Errors
Loops
mapfilter
reduce
const range = (i count) =gt unfold(x =gt if(x lt= count) [x x+1] i)
range(510) [ 5 6 7 8 9 10 ]
const alphabet = () =gt unfold(x =gt if(x lt 26) [StringfromCharCode(x+65) x+1] 0)
alphabet() [ABCDEFGHIJKLMNOPQRSTUVWXYZ]
AssignmentLoops
CallbacksSide EffectsBranching
Errors
CallbacksSide Effects
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
contrivedEx2()fork(e =gt consoleerror(e) r =gt consolelog(success))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))fork(e =gt consoleerror(e)
r =gt consolelog(r))
AssignmentLoops
CallbacksSide EffectsBranching
Errors
BranchingErrors
EitherOr
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
leftOrRightfold(e =gt `we had an error $e` s =gt stoUpperCase())
Right(hair brown) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Right(five 2))
Right(10)
Left(ignored) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Left(five 2))
Left(ignored)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
Claim
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
AssignmentLoops
CallbacksSide EffectsBranching
Errors
const depObjs = b =gt List(bdeps)flatMap(next =gt findDependencyByProject(nextProjectname bpreviousdeps) fold(x =gt x found =gt makeArgs(next found)))
const mapBuildsAndDepsForDiffQueue = (builds) =gt List(builds) filter(b =gt bprevious) flatMap(b =gt makeArgs(b bprevious)concat(depObjs(b))) filter(b =gt b) toJS()
const filterExistingDiffs = (items) =gt List(items)traverse(Taskof (i) =gt find(Diff BuildId ibuildId DiffId iprevId type imethod ) map(e =gt eswap()getOrElse(null)) map(bs =gt bsfilter(x =gt x)toJS())
const buildProject = (branch sha) =gt queueUnzipWwwOnS3(sha) chain(() =gt isReleaseOrMainBranch(branch)) fold(() =gt _noop () =gt generateReport(sha) chain(queueDiffsForTileBuildsAndDeps) chain(() =gt getHeadCommit(sha) fold(() =gt Taskof(null) head =gt makeVrtDeployment(head sha) chain(() =gt createPrApp(head sha)))) fork(consoleerror
consolelog))
const vrtReport = (sha email platforms) =gt rejectFinishedPlatformOptions(platforms) chain(plats =gt platsmap(gatherScreenshots)) chain(shots =gt fromNullable(sha) fold(() =gt findLastRef() () =gt findBuild(sha)) chain(ref =gt renderReport(shots ref email))) fork(e =gt e r =gt r)
Harder to hack
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
Safer
const ProfileLink = user =gtlta href=`users$
uid`gtunameltagt
const Header = str =gt lth1gtNow Viewing strlth1gt
Component a -gt JSX
a JSXf
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
ldquothe major contributor to this complexity in many systems is the handling of state and the burden that this adds when trying to analyse and reason about the systemrdquo
Out of the Tar Pit 2006-Ben Moseley amp Peter Marks
const dotChainy = str =gt str toLowerCase() split( ) map(c =gt ctrim()) reverse() filter(x =gt xlength gt 3) join()
WHAT IF I TOLD YOUhellip
WHAT IF I TOLD YOUhellip
Programming == Math
try return f(x) catch(e) consoleerror(e)
if(x) return f() else return y
for(let thing in things) if(thingamount gt 100) keeperspush(thingname)
for (i = 0 i lt carslength i++) text += cars[i] + ltbrgt
while (i lt 10) text += The number is + i i++
let stuff = [123]
stuff = [12]
stuffsplice(0 2)
stuffpop()
AssignmentLoops
CallbacksSide EffectsBranching
Errors
Programming == Math
Programming = Math
f g
f g
dot
f g = x =gt f(g(x))
strtoUpperCase()trim()
trim(toUpperCase(str))
Category theory
fn fn
fnfn
a bf
cg
ag
cf
a
F(a)
bf
F(f)
cg
F(b) F(g)F(c)
a
F(a)
g
F(gf)
cf
F(c)
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) A
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt parseInt(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) Box(lsquoArsquo)
const Box = x =gt( map f =gt Box(f(x)))
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) Box(lsquoArsquo)
const Box = x =gt( map f =gt Box(f(x)))
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) fold(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) lsquoArsquo
const Box = x =gt( map f =gt Box(f(x)) fold f =gt f(x))
Unified call syntaxMinimized state
Captured AssignmentForced Control Flow
AssignmentLoops
CallbacksSide EffectsBranching
Errors
Loops
mapfilter
reduce
const range = (i count) =gt unfold(x =gt if(x lt= count) [x x+1] i)
range(510) [ 5 6 7 8 9 10 ]
const alphabet = () =gt unfold(x =gt if(x lt 26) [StringfromCharCode(x+65) x+1] 0)
alphabet() [ABCDEFGHIJKLMNOPQRSTUVWXYZ]
AssignmentLoops
CallbacksSide EffectsBranching
Errors
CallbacksSide Effects
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
contrivedEx2()fork(e =gt consoleerror(e) r =gt consolelog(success))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))fork(e =gt consoleerror(e)
r =gt consolelog(r))
AssignmentLoops
CallbacksSide EffectsBranching
Errors
BranchingErrors
EitherOr
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
leftOrRightfold(e =gt `we had an error $e` s =gt stoUpperCase())
Right(hair brown) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Right(five 2))
Right(10)
Left(ignored) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Left(five 2))
Left(ignored)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
Claim
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
AssignmentLoops
CallbacksSide EffectsBranching
Errors
const depObjs = b =gt List(bdeps)flatMap(next =gt findDependencyByProject(nextProjectname bpreviousdeps) fold(x =gt x found =gt makeArgs(next found)))
const mapBuildsAndDepsForDiffQueue = (builds) =gt List(builds) filter(b =gt bprevious) flatMap(b =gt makeArgs(b bprevious)concat(depObjs(b))) filter(b =gt b) toJS()
const filterExistingDiffs = (items) =gt List(items)traverse(Taskof (i) =gt find(Diff BuildId ibuildId DiffId iprevId type imethod ) map(e =gt eswap()getOrElse(null)) map(bs =gt bsfilter(x =gt x)toJS())
const buildProject = (branch sha) =gt queueUnzipWwwOnS3(sha) chain(() =gt isReleaseOrMainBranch(branch)) fold(() =gt _noop () =gt generateReport(sha) chain(queueDiffsForTileBuildsAndDeps) chain(() =gt getHeadCommit(sha) fold(() =gt Taskof(null) head =gt makeVrtDeployment(head sha) chain(() =gt createPrApp(head sha)))) fork(consoleerror
consolelog))
const vrtReport = (sha email platforms) =gt rejectFinishedPlatformOptions(platforms) chain(plats =gt platsmap(gatherScreenshots)) chain(shots =gt fromNullable(sha) fold(() =gt findLastRef() () =gt findBuild(sha)) chain(ref =gt renderReport(shots ref email))) fork(e =gt e r =gt r)
Harder to hack
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
Safer
const ProfileLink = user =gtlta href=`users$
uid`gtunameltagt
const Header = str =gt lth1gtNow Viewing strlth1gt
Component a -gt JSX
a JSXf
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
const dotChainy = str =gt str toLowerCase() split( ) map(c =gt ctrim()) reverse() filter(x =gt xlength gt 3) join()
WHAT IF I TOLD YOUhellip
WHAT IF I TOLD YOUhellip
Programming == Math
try return f(x) catch(e) consoleerror(e)
if(x) return f() else return y
for(let thing in things) if(thingamount gt 100) keeperspush(thingname)
for (i = 0 i lt carslength i++) text += cars[i] + ltbrgt
while (i lt 10) text += The number is + i i++
let stuff = [123]
stuff = [12]
stuffsplice(0 2)
stuffpop()
AssignmentLoops
CallbacksSide EffectsBranching
Errors
Programming == Math
Programming = Math
f g
f g
dot
f g = x =gt f(g(x))
strtoUpperCase()trim()
trim(toUpperCase(str))
Category theory
fn fn
fnfn
a bf
cg
ag
cf
a
F(a)
bf
F(f)
cg
F(b) F(g)F(c)
a
F(a)
g
F(gf)
cf
F(c)
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) A
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt parseInt(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) Box(lsquoArsquo)
const Box = x =gt( map f =gt Box(f(x)))
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) Box(lsquoArsquo)
const Box = x =gt( map f =gt Box(f(x)))
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) fold(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) lsquoArsquo
const Box = x =gt( map f =gt Box(f(x)) fold f =gt f(x))
Unified call syntaxMinimized state
Captured AssignmentForced Control Flow
AssignmentLoops
CallbacksSide EffectsBranching
Errors
Loops
mapfilter
reduce
const range = (i count) =gt unfold(x =gt if(x lt= count) [x x+1] i)
range(510) [ 5 6 7 8 9 10 ]
const alphabet = () =gt unfold(x =gt if(x lt 26) [StringfromCharCode(x+65) x+1] 0)
alphabet() [ABCDEFGHIJKLMNOPQRSTUVWXYZ]
AssignmentLoops
CallbacksSide EffectsBranching
Errors
CallbacksSide Effects
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
contrivedEx2()fork(e =gt consoleerror(e) r =gt consolelog(success))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))fork(e =gt consoleerror(e)
r =gt consolelog(r))
AssignmentLoops
CallbacksSide EffectsBranching
Errors
BranchingErrors
EitherOr
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
leftOrRightfold(e =gt `we had an error $e` s =gt stoUpperCase())
Right(hair brown) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Right(five 2))
Right(10)
Left(ignored) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Left(five 2))
Left(ignored)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
Claim
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
AssignmentLoops
CallbacksSide EffectsBranching
Errors
const depObjs = b =gt List(bdeps)flatMap(next =gt findDependencyByProject(nextProjectname bpreviousdeps) fold(x =gt x found =gt makeArgs(next found)))
const mapBuildsAndDepsForDiffQueue = (builds) =gt List(builds) filter(b =gt bprevious) flatMap(b =gt makeArgs(b bprevious)concat(depObjs(b))) filter(b =gt b) toJS()
const filterExistingDiffs = (items) =gt List(items)traverse(Taskof (i) =gt find(Diff BuildId ibuildId DiffId iprevId type imethod ) map(e =gt eswap()getOrElse(null)) map(bs =gt bsfilter(x =gt x)toJS())
const buildProject = (branch sha) =gt queueUnzipWwwOnS3(sha) chain(() =gt isReleaseOrMainBranch(branch)) fold(() =gt _noop () =gt generateReport(sha) chain(queueDiffsForTileBuildsAndDeps) chain(() =gt getHeadCommit(sha) fold(() =gt Taskof(null) head =gt makeVrtDeployment(head sha) chain(() =gt createPrApp(head sha)))) fork(consoleerror
consolelog))
const vrtReport = (sha email platforms) =gt rejectFinishedPlatformOptions(platforms) chain(plats =gt platsmap(gatherScreenshots)) chain(shots =gt fromNullable(sha) fold(() =gt findLastRef() () =gt findBuild(sha)) chain(ref =gt renderReport(shots ref email))) fork(e =gt e r =gt r)
Harder to hack
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
Safer
const ProfileLink = user =gtlta href=`users$
uid`gtunameltagt
const Header = str =gt lth1gtNow Viewing strlth1gt
Component a -gt JSX
a JSXf
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
WHAT IF I TOLD YOUhellip
WHAT IF I TOLD YOUhellip
Programming == Math
try return f(x) catch(e) consoleerror(e)
if(x) return f() else return y
for(let thing in things) if(thingamount gt 100) keeperspush(thingname)
for (i = 0 i lt carslength i++) text += cars[i] + ltbrgt
while (i lt 10) text += The number is + i i++
let stuff = [123]
stuff = [12]
stuffsplice(0 2)
stuffpop()
AssignmentLoops
CallbacksSide EffectsBranching
Errors
Programming == Math
Programming = Math
f g
f g
dot
f g = x =gt f(g(x))
strtoUpperCase()trim()
trim(toUpperCase(str))
Category theory
fn fn
fnfn
a bf
cg
ag
cf
a
F(a)
bf
F(f)
cg
F(b) F(g)F(c)
a
F(a)
g
F(gf)
cf
F(c)
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) A
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt parseInt(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) Box(lsquoArsquo)
const Box = x =gt( map f =gt Box(f(x)))
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) Box(lsquoArsquo)
const Box = x =gt( map f =gt Box(f(x)))
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) fold(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) lsquoArsquo
const Box = x =gt( map f =gt Box(f(x)) fold f =gt f(x))
Unified call syntaxMinimized state
Captured AssignmentForced Control Flow
AssignmentLoops
CallbacksSide EffectsBranching
Errors
Loops
mapfilter
reduce
const range = (i count) =gt unfold(x =gt if(x lt= count) [x x+1] i)
range(510) [ 5 6 7 8 9 10 ]
const alphabet = () =gt unfold(x =gt if(x lt 26) [StringfromCharCode(x+65) x+1] 0)
alphabet() [ABCDEFGHIJKLMNOPQRSTUVWXYZ]
AssignmentLoops
CallbacksSide EffectsBranching
Errors
CallbacksSide Effects
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
contrivedEx2()fork(e =gt consoleerror(e) r =gt consolelog(success))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))fork(e =gt consoleerror(e)
r =gt consolelog(r))
AssignmentLoops
CallbacksSide EffectsBranching
Errors
BranchingErrors
EitherOr
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
leftOrRightfold(e =gt `we had an error $e` s =gt stoUpperCase())
Right(hair brown) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Right(five 2))
Right(10)
Left(ignored) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Left(five 2))
Left(ignored)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
Claim
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
AssignmentLoops
CallbacksSide EffectsBranching
Errors
const depObjs = b =gt List(bdeps)flatMap(next =gt findDependencyByProject(nextProjectname bpreviousdeps) fold(x =gt x found =gt makeArgs(next found)))
const mapBuildsAndDepsForDiffQueue = (builds) =gt List(builds) filter(b =gt bprevious) flatMap(b =gt makeArgs(b bprevious)concat(depObjs(b))) filter(b =gt b) toJS()
const filterExistingDiffs = (items) =gt List(items)traverse(Taskof (i) =gt find(Diff BuildId ibuildId DiffId iprevId type imethod ) map(e =gt eswap()getOrElse(null)) map(bs =gt bsfilter(x =gt x)toJS())
const buildProject = (branch sha) =gt queueUnzipWwwOnS3(sha) chain(() =gt isReleaseOrMainBranch(branch)) fold(() =gt _noop () =gt generateReport(sha) chain(queueDiffsForTileBuildsAndDeps) chain(() =gt getHeadCommit(sha) fold(() =gt Taskof(null) head =gt makeVrtDeployment(head sha) chain(() =gt createPrApp(head sha)))) fork(consoleerror
consolelog))
const vrtReport = (sha email platforms) =gt rejectFinishedPlatformOptions(platforms) chain(plats =gt platsmap(gatherScreenshots)) chain(shots =gt fromNullable(sha) fold(() =gt findLastRef() () =gt findBuild(sha)) chain(ref =gt renderReport(shots ref email))) fork(e =gt e r =gt r)
Harder to hack
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
Safer
const ProfileLink = user =gtlta href=`users$
uid`gtunameltagt
const Header = str =gt lth1gtNow Viewing strlth1gt
Component a -gt JSX
a JSXf
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
WHAT IF I TOLD YOUhellip
Programming == Math
try return f(x) catch(e) consoleerror(e)
if(x) return f() else return y
for(let thing in things) if(thingamount gt 100) keeperspush(thingname)
for (i = 0 i lt carslength i++) text += cars[i] + ltbrgt
while (i lt 10) text += The number is + i i++
let stuff = [123]
stuff = [12]
stuffsplice(0 2)
stuffpop()
AssignmentLoops
CallbacksSide EffectsBranching
Errors
Programming == Math
Programming = Math
f g
f g
dot
f g = x =gt f(g(x))
strtoUpperCase()trim()
trim(toUpperCase(str))
Category theory
fn fn
fnfn
a bf
cg
ag
cf
a
F(a)
bf
F(f)
cg
F(b) F(g)F(c)
a
F(a)
g
F(gf)
cf
F(c)
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) A
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt parseInt(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) Box(lsquoArsquo)
const Box = x =gt( map f =gt Box(f(x)))
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) Box(lsquoArsquo)
const Box = x =gt( map f =gt Box(f(x)))
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) fold(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) lsquoArsquo
const Box = x =gt( map f =gt Box(f(x)) fold f =gt f(x))
Unified call syntaxMinimized state
Captured AssignmentForced Control Flow
AssignmentLoops
CallbacksSide EffectsBranching
Errors
Loops
mapfilter
reduce
const range = (i count) =gt unfold(x =gt if(x lt= count) [x x+1] i)
range(510) [ 5 6 7 8 9 10 ]
const alphabet = () =gt unfold(x =gt if(x lt 26) [StringfromCharCode(x+65) x+1] 0)
alphabet() [ABCDEFGHIJKLMNOPQRSTUVWXYZ]
AssignmentLoops
CallbacksSide EffectsBranching
Errors
CallbacksSide Effects
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
contrivedEx2()fork(e =gt consoleerror(e) r =gt consolelog(success))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))fork(e =gt consoleerror(e)
r =gt consolelog(r))
AssignmentLoops
CallbacksSide EffectsBranching
Errors
BranchingErrors
EitherOr
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
leftOrRightfold(e =gt `we had an error $e` s =gt stoUpperCase())
Right(hair brown) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Right(five 2))
Right(10)
Left(ignored) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Left(five 2))
Left(ignored)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
Claim
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
AssignmentLoops
CallbacksSide EffectsBranching
Errors
const depObjs = b =gt List(bdeps)flatMap(next =gt findDependencyByProject(nextProjectname bpreviousdeps) fold(x =gt x found =gt makeArgs(next found)))
const mapBuildsAndDepsForDiffQueue = (builds) =gt List(builds) filter(b =gt bprevious) flatMap(b =gt makeArgs(b bprevious)concat(depObjs(b))) filter(b =gt b) toJS()
const filterExistingDiffs = (items) =gt List(items)traverse(Taskof (i) =gt find(Diff BuildId ibuildId DiffId iprevId type imethod ) map(e =gt eswap()getOrElse(null)) map(bs =gt bsfilter(x =gt x)toJS())
const buildProject = (branch sha) =gt queueUnzipWwwOnS3(sha) chain(() =gt isReleaseOrMainBranch(branch)) fold(() =gt _noop () =gt generateReport(sha) chain(queueDiffsForTileBuildsAndDeps) chain(() =gt getHeadCommit(sha) fold(() =gt Taskof(null) head =gt makeVrtDeployment(head sha) chain(() =gt createPrApp(head sha)))) fork(consoleerror
consolelog))
const vrtReport = (sha email platforms) =gt rejectFinishedPlatformOptions(platforms) chain(plats =gt platsmap(gatherScreenshots)) chain(shots =gt fromNullable(sha) fold(() =gt findLastRef() () =gt findBuild(sha)) chain(ref =gt renderReport(shots ref email))) fork(e =gt e r =gt r)
Harder to hack
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
Safer
const ProfileLink = user =gtlta href=`users$
uid`gtunameltagt
const Header = str =gt lth1gtNow Viewing strlth1gt
Component a -gt JSX
a JSXf
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
Programming == Math
try return f(x) catch(e) consoleerror(e)
if(x) return f() else return y
for(let thing in things) if(thingamount gt 100) keeperspush(thingname)
for (i = 0 i lt carslength i++) text += cars[i] + ltbrgt
while (i lt 10) text += The number is + i i++
let stuff = [123]
stuff = [12]
stuffsplice(0 2)
stuffpop()
AssignmentLoops
CallbacksSide EffectsBranching
Errors
Programming == Math
Programming = Math
f g
f g
dot
f g = x =gt f(g(x))
strtoUpperCase()trim()
trim(toUpperCase(str))
Category theory
fn fn
fnfn
a bf
cg
ag
cf
a
F(a)
bf
F(f)
cg
F(b) F(g)F(c)
a
F(a)
g
F(gf)
cf
F(c)
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) A
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt parseInt(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) Box(lsquoArsquo)
const Box = x =gt( map f =gt Box(f(x)))
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) Box(lsquoArsquo)
const Box = x =gt( map f =gt Box(f(x)))
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) fold(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) lsquoArsquo
const Box = x =gt( map f =gt Box(f(x)) fold f =gt f(x))
Unified call syntaxMinimized state
Captured AssignmentForced Control Flow
AssignmentLoops
CallbacksSide EffectsBranching
Errors
Loops
mapfilter
reduce
const range = (i count) =gt unfold(x =gt if(x lt= count) [x x+1] i)
range(510) [ 5 6 7 8 9 10 ]
const alphabet = () =gt unfold(x =gt if(x lt 26) [StringfromCharCode(x+65) x+1] 0)
alphabet() [ABCDEFGHIJKLMNOPQRSTUVWXYZ]
AssignmentLoops
CallbacksSide EffectsBranching
Errors
CallbacksSide Effects
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
contrivedEx2()fork(e =gt consoleerror(e) r =gt consolelog(success))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))fork(e =gt consoleerror(e)
r =gt consolelog(r))
AssignmentLoops
CallbacksSide EffectsBranching
Errors
BranchingErrors
EitherOr
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
leftOrRightfold(e =gt `we had an error $e` s =gt stoUpperCase())
Right(hair brown) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Right(five 2))
Right(10)
Left(ignored) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Left(five 2))
Left(ignored)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
Claim
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
AssignmentLoops
CallbacksSide EffectsBranching
Errors
const depObjs = b =gt List(bdeps)flatMap(next =gt findDependencyByProject(nextProjectname bpreviousdeps) fold(x =gt x found =gt makeArgs(next found)))
const mapBuildsAndDepsForDiffQueue = (builds) =gt List(builds) filter(b =gt bprevious) flatMap(b =gt makeArgs(b bprevious)concat(depObjs(b))) filter(b =gt b) toJS()
const filterExistingDiffs = (items) =gt List(items)traverse(Taskof (i) =gt find(Diff BuildId ibuildId DiffId iprevId type imethod ) map(e =gt eswap()getOrElse(null)) map(bs =gt bsfilter(x =gt x)toJS())
const buildProject = (branch sha) =gt queueUnzipWwwOnS3(sha) chain(() =gt isReleaseOrMainBranch(branch)) fold(() =gt _noop () =gt generateReport(sha) chain(queueDiffsForTileBuildsAndDeps) chain(() =gt getHeadCommit(sha) fold(() =gt Taskof(null) head =gt makeVrtDeployment(head sha) chain(() =gt createPrApp(head sha)))) fork(consoleerror
consolelog))
const vrtReport = (sha email platforms) =gt rejectFinishedPlatformOptions(platforms) chain(plats =gt platsmap(gatherScreenshots)) chain(shots =gt fromNullable(sha) fold(() =gt findLastRef() () =gt findBuild(sha)) chain(ref =gt renderReport(shots ref email))) fork(e =gt e r =gt r)
Harder to hack
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
Safer
const ProfileLink = user =gtlta href=`users$
uid`gtunameltagt
const Header = str =gt lth1gtNow Viewing strlth1gt
Component a -gt JSX
a JSXf
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
try return f(x) catch(e) consoleerror(e)
if(x) return f() else return y
for(let thing in things) if(thingamount gt 100) keeperspush(thingname)
for (i = 0 i lt carslength i++) text += cars[i] + ltbrgt
while (i lt 10) text += The number is + i i++
let stuff = [123]
stuff = [12]
stuffsplice(0 2)
stuffpop()
AssignmentLoops
CallbacksSide EffectsBranching
Errors
Programming == Math
Programming = Math
f g
f g
dot
f g = x =gt f(g(x))
strtoUpperCase()trim()
trim(toUpperCase(str))
Category theory
fn fn
fnfn
a bf
cg
ag
cf
a
F(a)
bf
F(f)
cg
F(b) F(g)F(c)
a
F(a)
g
F(gf)
cf
F(c)
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) A
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt parseInt(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) Box(lsquoArsquo)
const Box = x =gt( map f =gt Box(f(x)))
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) Box(lsquoArsquo)
const Box = x =gt( map f =gt Box(f(x)))
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) fold(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) lsquoArsquo
const Box = x =gt( map f =gt Box(f(x)) fold f =gt f(x))
Unified call syntaxMinimized state
Captured AssignmentForced Control Flow
AssignmentLoops
CallbacksSide EffectsBranching
Errors
Loops
mapfilter
reduce
const range = (i count) =gt unfold(x =gt if(x lt= count) [x x+1] i)
range(510) [ 5 6 7 8 9 10 ]
const alphabet = () =gt unfold(x =gt if(x lt 26) [StringfromCharCode(x+65) x+1] 0)
alphabet() [ABCDEFGHIJKLMNOPQRSTUVWXYZ]
AssignmentLoops
CallbacksSide EffectsBranching
Errors
CallbacksSide Effects
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
contrivedEx2()fork(e =gt consoleerror(e) r =gt consolelog(success))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))fork(e =gt consoleerror(e)
r =gt consolelog(r))
AssignmentLoops
CallbacksSide EffectsBranching
Errors
BranchingErrors
EitherOr
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
leftOrRightfold(e =gt `we had an error $e` s =gt stoUpperCase())
Right(hair brown) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Right(five 2))
Right(10)
Left(ignored) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Left(five 2))
Left(ignored)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
Claim
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
AssignmentLoops
CallbacksSide EffectsBranching
Errors
const depObjs = b =gt List(bdeps)flatMap(next =gt findDependencyByProject(nextProjectname bpreviousdeps) fold(x =gt x found =gt makeArgs(next found)))
const mapBuildsAndDepsForDiffQueue = (builds) =gt List(builds) filter(b =gt bprevious) flatMap(b =gt makeArgs(b bprevious)concat(depObjs(b))) filter(b =gt b) toJS()
const filterExistingDiffs = (items) =gt List(items)traverse(Taskof (i) =gt find(Diff BuildId ibuildId DiffId iprevId type imethod ) map(e =gt eswap()getOrElse(null)) map(bs =gt bsfilter(x =gt x)toJS())
const buildProject = (branch sha) =gt queueUnzipWwwOnS3(sha) chain(() =gt isReleaseOrMainBranch(branch)) fold(() =gt _noop () =gt generateReport(sha) chain(queueDiffsForTileBuildsAndDeps) chain(() =gt getHeadCommit(sha) fold(() =gt Taskof(null) head =gt makeVrtDeployment(head sha) chain(() =gt createPrApp(head sha)))) fork(consoleerror
consolelog))
const vrtReport = (sha email platforms) =gt rejectFinishedPlatformOptions(platforms) chain(plats =gt platsmap(gatherScreenshots)) chain(shots =gt fromNullable(sha) fold(() =gt findLastRef() () =gt findBuild(sha)) chain(ref =gt renderReport(shots ref email))) fork(e =gt e r =gt r)
Harder to hack
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
Safer
const ProfileLink = user =gtlta href=`users$
uid`gtunameltagt
const Header = str =gt lth1gtNow Viewing strlth1gt
Component a -gt JSX
a JSXf
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
if(x) return f() else return y
for(let thing in things) if(thingamount gt 100) keeperspush(thingname)
for (i = 0 i lt carslength i++) text += cars[i] + ltbrgt
while (i lt 10) text += The number is + i i++
let stuff = [123]
stuff = [12]
stuffsplice(0 2)
stuffpop()
AssignmentLoops
CallbacksSide EffectsBranching
Errors
Programming == Math
Programming = Math
f g
f g
dot
f g = x =gt f(g(x))
strtoUpperCase()trim()
trim(toUpperCase(str))
Category theory
fn fn
fnfn
a bf
cg
ag
cf
a
F(a)
bf
F(f)
cg
F(b) F(g)F(c)
a
F(a)
g
F(gf)
cf
F(c)
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) A
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt parseInt(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) Box(lsquoArsquo)
const Box = x =gt( map f =gt Box(f(x)))
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) Box(lsquoArsquo)
const Box = x =gt( map f =gt Box(f(x)))
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) fold(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) lsquoArsquo
const Box = x =gt( map f =gt Box(f(x)) fold f =gt f(x))
Unified call syntaxMinimized state
Captured AssignmentForced Control Flow
AssignmentLoops
CallbacksSide EffectsBranching
Errors
Loops
mapfilter
reduce
const range = (i count) =gt unfold(x =gt if(x lt= count) [x x+1] i)
range(510) [ 5 6 7 8 9 10 ]
const alphabet = () =gt unfold(x =gt if(x lt 26) [StringfromCharCode(x+65) x+1] 0)
alphabet() [ABCDEFGHIJKLMNOPQRSTUVWXYZ]
AssignmentLoops
CallbacksSide EffectsBranching
Errors
CallbacksSide Effects
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
contrivedEx2()fork(e =gt consoleerror(e) r =gt consolelog(success))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))fork(e =gt consoleerror(e)
r =gt consolelog(r))
AssignmentLoops
CallbacksSide EffectsBranching
Errors
BranchingErrors
EitherOr
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
leftOrRightfold(e =gt `we had an error $e` s =gt stoUpperCase())
Right(hair brown) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Right(five 2))
Right(10)
Left(ignored) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Left(five 2))
Left(ignored)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
Claim
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
AssignmentLoops
CallbacksSide EffectsBranching
Errors
const depObjs = b =gt List(bdeps)flatMap(next =gt findDependencyByProject(nextProjectname bpreviousdeps) fold(x =gt x found =gt makeArgs(next found)))
const mapBuildsAndDepsForDiffQueue = (builds) =gt List(builds) filter(b =gt bprevious) flatMap(b =gt makeArgs(b bprevious)concat(depObjs(b))) filter(b =gt b) toJS()
const filterExistingDiffs = (items) =gt List(items)traverse(Taskof (i) =gt find(Diff BuildId ibuildId DiffId iprevId type imethod ) map(e =gt eswap()getOrElse(null)) map(bs =gt bsfilter(x =gt x)toJS())
const buildProject = (branch sha) =gt queueUnzipWwwOnS3(sha) chain(() =gt isReleaseOrMainBranch(branch)) fold(() =gt _noop () =gt generateReport(sha) chain(queueDiffsForTileBuildsAndDeps) chain(() =gt getHeadCommit(sha) fold(() =gt Taskof(null) head =gt makeVrtDeployment(head sha) chain(() =gt createPrApp(head sha)))) fork(consoleerror
consolelog))
const vrtReport = (sha email platforms) =gt rejectFinishedPlatformOptions(platforms) chain(plats =gt platsmap(gatherScreenshots)) chain(shots =gt fromNullable(sha) fold(() =gt findLastRef() () =gt findBuild(sha)) chain(ref =gt renderReport(shots ref email))) fork(e =gt e r =gt r)
Harder to hack
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
Safer
const ProfileLink = user =gtlta href=`users$
uid`gtunameltagt
const Header = str =gt lth1gtNow Viewing strlth1gt
Component a -gt JSX
a JSXf
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
for(let thing in things) if(thingamount gt 100) keeperspush(thingname)
for (i = 0 i lt carslength i++) text += cars[i] + ltbrgt
while (i lt 10) text += The number is + i i++
let stuff = [123]
stuff = [12]
stuffsplice(0 2)
stuffpop()
AssignmentLoops
CallbacksSide EffectsBranching
Errors
Programming == Math
Programming = Math
f g
f g
dot
f g = x =gt f(g(x))
strtoUpperCase()trim()
trim(toUpperCase(str))
Category theory
fn fn
fnfn
a bf
cg
ag
cf
a
F(a)
bf
F(f)
cg
F(b) F(g)F(c)
a
F(a)
g
F(gf)
cf
F(c)
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) A
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt parseInt(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) Box(lsquoArsquo)
const Box = x =gt( map f =gt Box(f(x)))
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) Box(lsquoArsquo)
const Box = x =gt( map f =gt Box(f(x)))
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) fold(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) lsquoArsquo
const Box = x =gt( map f =gt Box(f(x)) fold f =gt f(x))
Unified call syntaxMinimized state
Captured AssignmentForced Control Flow
AssignmentLoops
CallbacksSide EffectsBranching
Errors
Loops
mapfilter
reduce
const range = (i count) =gt unfold(x =gt if(x lt= count) [x x+1] i)
range(510) [ 5 6 7 8 9 10 ]
const alphabet = () =gt unfold(x =gt if(x lt 26) [StringfromCharCode(x+65) x+1] 0)
alphabet() [ABCDEFGHIJKLMNOPQRSTUVWXYZ]
AssignmentLoops
CallbacksSide EffectsBranching
Errors
CallbacksSide Effects
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
contrivedEx2()fork(e =gt consoleerror(e) r =gt consolelog(success))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))fork(e =gt consoleerror(e)
r =gt consolelog(r))
AssignmentLoops
CallbacksSide EffectsBranching
Errors
BranchingErrors
EitherOr
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
leftOrRightfold(e =gt `we had an error $e` s =gt stoUpperCase())
Right(hair brown) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Right(five 2))
Right(10)
Left(ignored) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Left(five 2))
Left(ignored)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
Claim
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
AssignmentLoops
CallbacksSide EffectsBranching
Errors
const depObjs = b =gt List(bdeps)flatMap(next =gt findDependencyByProject(nextProjectname bpreviousdeps) fold(x =gt x found =gt makeArgs(next found)))
const mapBuildsAndDepsForDiffQueue = (builds) =gt List(builds) filter(b =gt bprevious) flatMap(b =gt makeArgs(b bprevious)concat(depObjs(b))) filter(b =gt b) toJS()
const filterExistingDiffs = (items) =gt List(items)traverse(Taskof (i) =gt find(Diff BuildId ibuildId DiffId iprevId type imethod ) map(e =gt eswap()getOrElse(null)) map(bs =gt bsfilter(x =gt x)toJS())
const buildProject = (branch sha) =gt queueUnzipWwwOnS3(sha) chain(() =gt isReleaseOrMainBranch(branch)) fold(() =gt _noop () =gt generateReport(sha) chain(queueDiffsForTileBuildsAndDeps) chain(() =gt getHeadCommit(sha) fold(() =gt Taskof(null) head =gt makeVrtDeployment(head sha) chain(() =gt createPrApp(head sha)))) fork(consoleerror
consolelog))
const vrtReport = (sha email platforms) =gt rejectFinishedPlatformOptions(platforms) chain(plats =gt platsmap(gatherScreenshots)) chain(shots =gt fromNullable(sha) fold(() =gt findLastRef() () =gt findBuild(sha)) chain(ref =gt renderReport(shots ref email))) fork(e =gt e r =gt r)
Harder to hack
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
Safer
const ProfileLink = user =gtlta href=`users$
uid`gtunameltagt
const Header = str =gt lth1gtNow Viewing strlth1gt
Component a -gt JSX
a JSXf
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
let stuff = [123]
stuff = [12]
stuffsplice(0 2)
stuffpop()
AssignmentLoops
CallbacksSide EffectsBranching
Errors
Programming == Math
Programming = Math
f g
f g
dot
f g = x =gt f(g(x))
strtoUpperCase()trim()
trim(toUpperCase(str))
Category theory
fn fn
fnfn
a bf
cg
ag
cf
a
F(a)
bf
F(f)
cg
F(b) F(g)F(c)
a
F(a)
g
F(gf)
cf
F(c)
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) A
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt parseInt(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) Box(lsquoArsquo)
const Box = x =gt( map f =gt Box(f(x)))
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) Box(lsquoArsquo)
const Box = x =gt( map f =gt Box(f(x)))
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) fold(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) lsquoArsquo
const Box = x =gt( map f =gt Box(f(x)) fold f =gt f(x))
Unified call syntaxMinimized state
Captured AssignmentForced Control Flow
AssignmentLoops
CallbacksSide EffectsBranching
Errors
Loops
mapfilter
reduce
const range = (i count) =gt unfold(x =gt if(x lt= count) [x x+1] i)
range(510) [ 5 6 7 8 9 10 ]
const alphabet = () =gt unfold(x =gt if(x lt 26) [StringfromCharCode(x+65) x+1] 0)
alphabet() [ABCDEFGHIJKLMNOPQRSTUVWXYZ]
AssignmentLoops
CallbacksSide EffectsBranching
Errors
CallbacksSide Effects
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
contrivedEx2()fork(e =gt consoleerror(e) r =gt consolelog(success))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))fork(e =gt consoleerror(e)
r =gt consolelog(r))
AssignmentLoops
CallbacksSide EffectsBranching
Errors
BranchingErrors
EitherOr
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
leftOrRightfold(e =gt `we had an error $e` s =gt stoUpperCase())
Right(hair brown) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Right(five 2))
Right(10)
Left(ignored) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Left(five 2))
Left(ignored)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
Claim
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
AssignmentLoops
CallbacksSide EffectsBranching
Errors
const depObjs = b =gt List(bdeps)flatMap(next =gt findDependencyByProject(nextProjectname bpreviousdeps) fold(x =gt x found =gt makeArgs(next found)))
const mapBuildsAndDepsForDiffQueue = (builds) =gt List(builds) filter(b =gt bprevious) flatMap(b =gt makeArgs(b bprevious)concat(depObjs(b))) filter(b =gt b) toJS()
const filterExistingDiffs = (items) =gt List(items)traverse(Taskof (i) =gt find(Diff BuildId ibuildId DiffId iprevId type imethod ) map(e =gt eswap()getOrElse(null)) map(bs =gt bsfilter(x =gt x)toJS())
const buildProject = (branch sha) =gt queueUnzipWwwOnS3(sha) chain(() =gt isReleaseOrMainBranch(branch)) fold(() =gt _noop () =gt generateReport(sha) chain(queueDiffsForTileBuildsAndDeps) chain(() =gt getHeadCommit(sha) fold(() =gt Taskof(null) head =gt makeVrtDeployment(head sha) chain(() =gt createPrApp(head sha)))) fork(consoleerror
consolelog))
const vrtReport = (sha email platforms) =gt rejectFinishedPlatformOptions(platforms) chain(plats =gt platsmap(gatherScreenshots)) chain(shots =gt fromNullable(sha) fold(() =gt findLastRef() () =gt findBuild(sha)) chain(ref =gt renderReport(shots ref email))) fork(e =gt e r =gt r)
Harder to hack
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
Safer
const ProfileLink = user =gtlta href=`users$
uid`gtunameltagt
const Header = str =gt lth1gtNow Viewing strlth1gt
Component a -gt JSX
a JSXf
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
stuffsplice(0 2)
stuffpop()
AssignmentLoops
CallbacksSide EffectsBranching
Errors
Programming == Math
Programming = Math
f g
f g
dot
f g = x =gt f(g(x))
strtoUpperCase()trim()
trim(toUpperCase(str))
Category theory
fn fn
fnfn
a bf
cg
ag
cf
a
F(a)
bf
F(f)
cg
F(b) F(g)F(c)
a
F(a)
g
F(gf)
cf
F(c)
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) A
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt parseInt(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) Box(lsquoArsquo)
const Box = x =gt( map f =gt Box(f(x)))
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) Box(lsquoArsquo)
const Box = x =gt( map f =gt Box(f(x)))
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) fold(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) lsquoArsquo
const Box = x =gt( map f =gt Box(f(x)) fold f =gt f(x))
Unified call syntaxMinimized state
Captured AssignmentForced Control Flow
AssignmentLoops
CallbacksSide EffectsBranching
Errors
Loops
mapfilter
reduce
const range = (i count) =gt unfold(x =gt if(x lt= count) [x x+1] i)
range(510) [ 5 6 7 8 9 10 ]
const alphabet = () =gt unfold(x =gt if(x lt 26) [StringfromCharCode(x+65) x+1] 0)
alphabet() [ABCDEFGHIJKLMNOPQRSTUVWXYZ]
AssignmentLoops
CallbacksSide EffectsBranching
Errors
CallbacksSide Effects
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
contrivedEx2()fork(e =gt consoleerror(e) r =gt consolelog(success))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))fork(e =gt consoleerror(e)
r =gt consolelog(r))
AssignmentLoops
CallbacksSide EffectsBranching
Errors
BranchingErrors
EitherOr
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
leftOrRightfold(e =gt `we had an error $e` s =gt stoUpperCase())
Right(hair brown) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Right(five 2))
Right(10)
Left(ignored) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Left(five 2))
Left(ignored)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
Claim
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
AssignmentLoops
CallbacksSide EffectsBranching
Errors
const depObjs = b =gt List(bdeps)flatMap(next =gt findDependencyByProject(nextProjectname bpreviousdeps) fold(x =gt x found =gt makeArgs(next found)))
const mapBuildsAndDepsForDiffQueue = (builds) =gt List(builds) filter(b =gt bprevious) flatMap(b =gt makeArgs(b bprevious)concat(depObjs(b))) filter(b =gt b) toJS()
const filterExistingDiffs = (items) =gt List(items)traverse(Taskof (i) =gt find(Diff BuildId ibuildId DiffId iprevId type imethod ) map(e =gt eswap()getOrElse(null)) map(bs =gt bsfilter(x =gt x)toJS())
const buildProject = (branch sha) =gt queueUnzipWwwOnS3(sha) chain(() =gt isReleaseOrMainBranch(branch)) fold(() =gt _noop () =gt generateReport(sha) chain(queueDiffsForTileBuildsAndDeps) chain(() =gt getHeadCommit(sha) fold(() =gt Taskof(null) head =gt makeVrtDeployment(head sha) chain(() =gt createPrApp(head sha)))) fork(consoleerror
consolelog))
const vrtReport = (sha email platforms) =gt rejectFinishedPlatformOptions(platforms) chain(plats =gt platsmap(gatherScreenshots)) chain(shots =gt fromNullable(sha) fold(() =gt findLastRef() () =gt findBuild(sha)) chain(ref =gt renderReport(shots ref email))) fork(e =gt e r =gt r)
Harder to hack
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
Safer
const ProfileLink = user =gtlta href=`users$
uid`gtunameltagt
const Header = str =gt lth1gtNow Viewing strlth1gt
Component a -gt JSX
a JSXf
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
AssignmentLoops
CallbacksSide EffectsBranching
Errors
Programming == Math
Programming = Math
f g
f g
dot
f g = x =gt f(g(x))
strtoUpperCase()trim()
trim(toUpperCase(str))
Category theory
fn fn
fnfn
a bf
cg
ag
cf
a
F(a)
bf
F(f)
cg
F(b) F(g)F(c)
a
F(a)
g
F(gf)
cf
F(c)
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) A
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt parseInt(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) Box(lsquoArsquo)
const Box = x =gt( map f =gt Box(f(x)))
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) Box(lsquoArsquo)
const Box = x =gt( map f =gt Box(f(x)))
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) fold(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) lsquoArsquo
const Box = x =gt( map f =gt Box(f(x)) fold f =gt f(x))
Unified call syntaxMinimized state
Captured AssignmentForced Control Flow
AssignmentLoops
CallbacksSide EffectsBranching
Errors
Loops
mapfilter
reduce
const range = (i count) =gt unfold(x =gt if(x lt= count) [x x+1] i)
range(510) [ 5 6 7 8 9 10 ]
const alphabet = () =gt unfold(x =gt if(x lt 26) [StringfromCharCode(x+65) x+1] 0)
alphabet() [ABCDEFGHIJKLMNOPQRSTUVWXYZ]
AssignmentLoops
CallbacksSide EffectsBranching
Errors
CallbacksSide Effects
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
contrivedEx2()fork(e =gt consoleerror(e) r =gt consolelog(success))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))fork(e =gt consoleerror(e)
r =gt consolelog(r))
AssignmentLoops
CallbacksSide EffectsBranching
Errors
BranchingErrors
EitherOr
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
leftOrRightfold(e =gt `we had an error $e` s =gt stoUpperCase())
Right(hair brown) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Right(five 2))
Right(10)
Left(ignored) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Left(five 2))
Left(ignored)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
Claim
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
AssignmentLoops
CallbacksSide EffectsBranching
Errors
const depObjs = b =gt List(bdeps)flatMap(next =gt findDependencyByProject(nextProjectname bpreviousdeps) fold(x =gt x found =gt makeArgs(next found)))
const mapBuildsAndDepsForDiffQueue = (builds) =gt List(builds) filter(b =gt bprevious) flatMap(b =gt makeArgs(b bprevious)concat(depObjs(b))) filter(b =gt b) toJS()
const filterExistingDiffs = (items) =gt List(items)traverse(Taskof (i) =gt find(Diff BuildId ibuildId DiffId iprevId type imethod ) map(e =gt eswap()getOrElse(null)) map(bs =gt bsfilter(x =gt x)toJS())
const buildProject = (branch sha) =gt queueUnzipWwwOnS3(sha) chain(() =gt isReleaseOrMainBranch(branch)) fold(() =gt _noop () =gt generateReport(sha) chain(queueDiffsForTileBuildsAndDeps) chain(() =gt getHeadCommit(sha) fold(() =gt Taskof(null) head =gt makeVrtDeployment(head sha) chain(() =gt createPrApp(head sha)))) fork(consoleerror
consolelog))
const vrtReport = (sha email platforms) =gt rejectFinishedPlatformOptions(platforms) chain(plats =gt platsmap(gatherScreenshots)) chain(shots =gt fromNullable(sha) fold(() =gt findLastRef() () =gt findBuild(sha)) chain(ref =gt renderReport(shots ref email))) fork(e =gt e r =gt r)
Harder to hack
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
Safer
const ProfileLink = user =gtlta href=`users$
uid`gtunameltagt
const Header = str =gt lth1gtNow Viewing strlth1gt
Component a -gt JSX
a JSXf
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
Programming == Math
Programming = Math
f g
f g
dot
f g = x =gt f(g(x))
strtoUpperCase()trim()
trim(toUpperCase(str))
Category theory
fn fn
fnfn
a bf
cg
ag
cf
a
F(a)
bf
F(f)
cg
F(b) F(g)F(c)
a
F(a)
g
F(gf)
cf
F(c)
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) A
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt parseInt(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) Box(lsquoArsquo)
const Box = x =gt( map f =gt Box(f(x)))
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) Box(lsquoArsquo)
const Box = x =gt( map f =gt Box(f(x)))
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) fold(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) lsquoArsquo
const Box = x =gt( map f =gt Box(f(x)) fold f =gt f(x))
Unified call syntaxMinimized state
Captured AssignmentForced Control Flow
AssignmentLoops
CallbacksSide EffectsBranching
Errors
Loops
mapfilter
reduce
const range = (i count) =gt unfold(x =gt if(x lt= count) [x x+1] i)
range(510) [ 5 6 7 8 9 10 ]
const alphabet = () =gt unfold(x =gt if(x lt 26) [StringfromCharCode(x+65) x+1] 0)
alphabet() [ABCDEFGHIJKLMNOPQRSTUVWXYZ]
AssignmentLoops
CallbacksSide EffectsBranching
Errors
CallbacksSide Effects
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
contrivedEx2()fork(e =gt consoleerror(e) r =gt consolelog(success))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))fork(e =gt consoleerror(e)
r =gt consolelog(r))
AssignmentLoops
CallbacksSide EffectsBranching
Errors
BranchingErrors
EitherOr
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
leftOrRightfold(e =gt `we had an error $e` s =gt stoUpperCase())
Right(hair brown) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Right(five 2))
Right(10)
Left(ignored) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Left(five 2))
Left(ignored)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
Claim
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
AssignmentLoops
CallbacksSide EffectsBranching
Errors
const depObjs = b =gt List(bdeps)flatMap(next =gt findDependencyByProject(nextProjectname bpreviousdeps) fold(x =gt x found =gt makeArgs(next found)))
const mapBuildsAndDepsForDiffQueue = (builds) =gt List(builds) filter(b =gt bprevious) flatMap(b =gt makeArgs(b bprevious)concat(depObjs(b))) filter(b =gt b) toJS()
const filterExistingDiffs = (items) =gt List(items)traverse(Taskof (i) =gt find(Diff BuildId ibuildId DiffId iprevId type imethod ) map(e =gt eswap()getOrElse(null)) map(bs =gt bsfilter(x =gt x)toJS())
const buildProject = (branch sha) =gt queueUnzipWwwOnS3(sha) chain(() =gt isReleaseOrMainBranch(branch)) fold(() =gt _noop () =gt generateReport(sha) chain(queueDiffsForTileBuildsAndDeps) chain(() =gt getHeadCommit(sha) fold(() =gt Taskof(null) head =gt makeVrtDeployment(head sha) chain(() =gt createPrApp(head sha)))) fork(consoleerror
consolelog))
const vrtReport = (sha email platforms) =gt rejectFinishedPlatformOptions(platforms) chain(plats =gt platsmap(gatherScreenshots)) chain(shots =gt fromNullable(sha) fold(() =gt findLastRef() () =gt findBuild(sha)) chain(ref =gt renderReport(shots ref email))) fork(e =gt e r =gt r)
Harder to hack
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
Safer
const ProfileLink = user =gtlta href=`users$
uid`gtunameltagt
const Header = str =gt lth1gtNow Viewing strlth1gt
Component a -gt JSX
a JSXf
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
Programming = Math
f g
f g
dot
f g = x =gt f(g(x))
strtoUpperCase()trim()
trim(toUpperCase(str))
Category theory
fn fn
fnfn
a bf
cg
ag
cf
a
F(a)
bf
F(f)
cg
F(b) F(g)F(c)
a
F(a)
g
F(gf)
cf
F(c)
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) A
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt parseInt(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) Box(lsquoArsquo)
const Box = x =gt( map f =gt Box(f(x)))
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) Box(lsquoArsquo)
const Box = x =gt( map f =gt Box(f(x)))
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) fold(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) lsquoArsquo
const Box = x =gt( map f =gt Box(f(x)) fold f =gt f(x))
Unified call syntaxMinimized state
Captured AssignmentForced Control Flow
AssignmentLoops
CallbacksSide EffectsBranching
Errors
Loops
mapfilter
reduce
const range = (i count) =gt unfold(x =gt if(x lt= count) [x x+1] i)
range(510) [ 5 6 7 8 9 10 ]
const alphabet = () =gt unfold(x =gt if(x lt 26) [StringfromCharCode(x+65) x+1] 0)
alphabet() [ABCDEFGHIJKLMNOPQRSTUVWXYZ]
AssignmentLoops
CallbacksSide EffectsBranching
Errors
CallbacksSide Effects
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
contrivedEx2()fork(e =gt consoleerror(e) r =gt consolelog(success))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))fork(e =gt consoleerror(e)
r =gt consolelog(r))
AssignmentLoops
CallbacksSide EffectsBranching
Errors
BranchingErrors
EitherOr
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
leftOrRightfold(e =gt `we had an error $e` s =gt stoUpperCase())
Right(hair brown) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Right(five 2))
Right(10)
Left(ignored) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Left(five 2))
Left(ignored)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
Claim
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
AssignmentLoops
CallbacksSide EffectsBranching
Errors
const depObjs = b =gt List(bdeps)flatMap(next =gt findDependencyByProject(nextProjectname bpreviousdeps) fold(x =gt x found =gt makeArgs(next found)))
const mapBuildsAndDepsForDiffQueue = (builds) =gt List(builds) filter(b =gt bprevious) flatMap(b =gt makeArgs(b bprevious)concat(depObjs(b))) filter(b =gt b) toJS()
const filterExistingDiffs = (items) =gt List(items)traverse(Taskof (i) =gt find(Diff BuildId ibuildId DiffId iprevId type imethod ) map(e =gt eswap()getOrElse(null)) map(bs =gt bsfilter(x =gt x)toJS())
const buildProject = (branch sha) =gt queueUnzipWwwOnS3(sha) chain(() =gt isReleaseOrMainBranch(branch)) fold(() =gt _noop () =gt generateReport(sha) chain(queueDiffsForTileBuildsAndDeps) chain(() =gt getHeadCommit(sha) fold(() =gt Taskof(null) head =gt makeVrtDeployment(head sha) chain(() =gt createPrApp(head sha)))) fork(consoleerror
consolelog))
const vrtReport = (sha email platforms) =gt rejectFinishedPlatformOptions(platforms) chain(plats =gt platsmap(gatherScreenshots)) chain(shots =gt fromNullable(sha) fold(() =gt findLastRef() () =gt findBuild(sha)) chain(ref =gt renderReport(shots ref email))) fork(e =gt e r =gt r)
Harder to hack
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
Safer
const ProfileLink = user =gtlta href=`users$
uid`gtunameltagt
const Header = str =gt lth1gtNow Viewing strlth1gt
Component a -gt JSX
a JSXf
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
f g
f g
dot
f g = x =gt f(g(x))
strtoUpperCase()trim()
trim(toUpperCase(str))
Category theory
fn fn
fnfn
a bf
cg
ag
cf
a
F(a)
bf
F(f)
cg
F(b) F(g)F(c)
a
F(a)
g
F(gf)
cf
F(c)
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) A
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt parseInt(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) Box(lsquoArsquo)
const Box = x =gt( map f =gt Box(f(x)))
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) Box(lsquoArsquo)
const Box = x =gt( map f =gt Box(f(x)))
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) fold(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) lsquoArsquo
const Box = x =gt( map f =gt Box(f(x)) fold f =gt f(x))
Unified call syntaxMinimized state
Captured AssignmentForced Control Flow
AssignmentLoops
CallbacksSide EffectsBranching
Errors
Loops
mapfilter
reduce
const range = (i count) =gt unfold(x =gt if(x lt= count) [x x+1] i)
range(510) [ 5 6 7 8 9 10 ]
const alphabet = () =gt unfold(x =gt if(x lt 26) [StringfromCharCode(x+65) x+1] 0)
alphabet() [ABCDEFGHIJKLMNOPQRSTUVWXYZ]
AssignmentLoops
CallbacksSide EffectsBranching
Errors
CallbacksSide Effects
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
contrivedEx2()fork(e =gt consoleerror(e) r =gt consolelog(success))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))fork(e =gt consoleerror(e)
r =gt consolelog(r))
AssignmentLoops
CallbacksSide EffectsBranching
Errors
BranchingErrors
EitherOr
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
leftOrRightfold(e =gt `we had an error $e` s =gt stoUpperCase())
Right(hair brown) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Right(five 2))
Right(10)
Left(ignored) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Left(five 2))
Left(ignored)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
Claim
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
AssignmentLoops
CallbacksSide EffectsBranching
Errors
const depObjs = b =gt List(bdeps)flatMap(next =gt findDependencyByProject(nextProjectname bpreviousdeps) fold(x =gt x found =gt makeArgs(next found)))
const mapBuildsAndDepsForDiffQueue = (builds) =gt List(builds) filter(b =gt bprevious) flatMap(b =gt makeArgs(b bprevious)concat(depObjs(b))) filter(b =gt b) toJS()
const filterExistingDiffs = (items) =gt List(items)traverse(Taskof (i) =gt find(Diff BuildId ibuildId DiffId iprevId type imethod ) map(e =gt eswap()getOrElse(null)) map(bs =gt bsfilter(x =gt x)toJS())
const buildProject = (branch sha) =gt queueUnzipWwwOnS3(sha) chain(() =gt isReleaseOrMainBranch(branch)) fold(() =gt _noop () =gt generateReport(sha) chain(queueDiffsForTileBuildsAndDeps) chain(() =gt getHeadCommit(sha) fold(() =gt Taskof(null) head =gt makeVrtDeployment(head sha) chain(() =gt createPrApp(head sha)))) fork(consoleerror
consolelog))
const vrtReport = (sha email platforms) =gt rejectFinishedPlatformOptions(platforms) chain(plats =gt platsmap(gatherScreenshots)) chain(shots =gt fromNullable(sha) fold(() =gt findLastRef() () =gt findBuild(sha)) chain(ref =gt renderReport(shots ref email))) fork(e =gt e r =gt r)
Harder to hack
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
Safer
const ProfileLink = user =gtlta href=`users$
uid`gtunameltagt
const Header = str =gt lth1gtNow Viewing strlth1gt
Component a -gt JSX
a JSXf
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
f g
dot
f g = x =gt f(g(x))
strtoUpperCase()trim()
trim(toUpperCase(str))
Category theory
fn fn
fnfn
a bf
cg
ag
cf
a
F(a)
bf
F(f)
cg
F(b) F(g)F(c)
a
F(a)
g
F(gf)
cf
F(c)
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) A
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt parseInt(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) Box(lsquoArsquo)
const Box = x =gt( map f =gt Box(f(x)))
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) Box(lsquoArsquo)
const Box = x =gt( map f =gt Box(f(x)))
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) fold(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) lsquoArsquo
const Box = x =gt( map f =gt Box(f(x)) fold f =gt f(x))
Unified call syntaxMinimized state
Captured AssignmentForced Control Flow
AssignmentLoops
CallbacksSide EffectsBranching
Errors
Loops
mapfilter
reduce
const range = (i count) =gt unfold(x =gt if(x lt= count) [x x+1] i)
range(510) [ 5 6 7 8 9 10 ]
const alphabet = () =gt unfold(x =gt if(x lt 26) [StringfromCharCode(x+65) x+1] 0)
alphabet() [ABCDEFGHIJKLMNOPQRSTUVWXYZ]
AssignmentLoops
CallbacksSide EffectsBranching
Errors
CallbacksSide Effects
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
contrivedEx2()fork(e =gt consoleerror(e) r =gt consolelog(success))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))fork(e =gt consoleerror(e)
r =gt consolelog(r))
AssignmentLoops
CallbacksSide EffectsBranching
Errors
BranchingErrors
EitherOr
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
leftOrRightfold(e =gt `we had an error $e` s =gt stoUpperCase())
Right(hair brown) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Right(five 2))
Right(10)
Left(ignored) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Left(five 2))
Left(ignored)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
Claim
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
AssignmentLoops
CallbacksSide EffectsBranching
Errors
const depObjs = b =gt List(bdeps)flatMap(next =gt findDependencyByProject(nextProjectname bpreviousdeps) fold(x =gt x found =gt makeArgs(next found)))
const mapBuildsAndDepsForDiffQueue = (builds) =gt List(builds) filter(b =gt bprevious) flatMap(b =gt makeArgs(b bprevious)concat(depObjs(b))) filter(b =gt b) toJS()
const filterExistingDiffs = (items) =gt List(items)traverse(Taskof (i) =gt find(Diff BuildId ibuildId DiffId iprevId type imethod ) map(e =gt eswap()getOrElse(null)) map(bs =gt bsfilter(x =gt x)toJS())
const buildProject = (branch sha) =gt queueUnzipWwwOnS3(sha) chain(() =gt isReleaseOrMainBranch(branch)) fold(() =gt _noop () =gt generateReport(sha) chain(queueDiffsForTileBuildsAndDeps) chain(() =gt getHeadCommit(sha) fold(() =gt Taskof(null) head =gt makeVrtDeployment(head sha) chain(() =gt createPrApp(head sha)))) fork(consoleerror
consolelog))
const vrtReport = (sha email platforms) =gt rejectFinishedPlatformOptions(platforms) chain(plats =gt platsmap(gatherScreenshots)) chain(shots =gt fromNullable(sha) fold(() =gt findLastRef() () =gt findBuild(sha)) chain(ref =gt renderReport(shots ref email))) fork(e =gt e r =gt r)
Harder to hack
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
Safer
const ProfileLink = user =gtlta href=`users$
uid`gtunameltagt
const Header = str =gt lth1gtNow Viewing strlth1gt
Component a -gt JSX
a JSXf
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
f g = x =gt f(g(x))
strtoUpperCase()trim()
trim(toUpperCase(str))
Category theory
fn fn
fnfn
a bf
cg
ag
cf
a
F(a)
bf
F(f)
cg
F(b) F(g)F(c)
a
F(a)
g
F(gf)
cf
F(c)
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) A
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt parseInt(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) Box(lsquoArsquo)
const Box = x =gt( map f =gt Box(f(x)))
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) Box(lsquoArsquo)
const Box = x =gt( map f =gt Box(f(x)))
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) fold(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) lsquoArsquo
const Box = x =gt( map f =gt Box(f(x)) fold f =gt f(x))
Unified call syntaxMinimized state
Captured AssignmentForced Control Flow
AssignmentLoops
CallbacksSide EffectsBranching
Errors
Loops
mapfilter
reduce
const range = (i count) =gt unfold(x =gt if(x lt= count) [x x+1] i)
range(510) [ 5 6 7 8 9 10 ]
const alphabet = () =gt unfold(x =gt if(x lt 26) [StringfromCharCode(x+65) x+1] 0)
alphabet() [ABCDEFGHIJKLMNOPQRSTUVWXYZ]
AssignmentLoops
CallbacksSide EffectsBranching
Errors
CallbacksSide Effects
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
contrivedEx2()fork(e =gt consoleerror(e) r =gt consolelog(success))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))fork(e =gt consoleerror(e)
r =gt consolelog(r))
AssignmentLoops
CallbacksSide EffectsBranching
Errors
BranchingErrors
EitherOr
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
leftOrRightfold(e =gt `we had an error $e` s =gt stoUpperCase())
Right(hair brown) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Right(five 2))
Right(10)
Left(ignored) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Left(five 2))
Left(ignored)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
Claim
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
AssignmentLoops
CallbacksSide EffectsBranching
Errors
const depObjs = b =gt List(bdeps)flatMap(next =gt findDependencyByProject(nextProjectname bpreviousdeps) fold(x =gt x found =gt makeArgs(next found)))
const mapBuildsAndDepsForDiffQueue = (builds) =gt List(builds) filter(b =gt bprevious) flatMap(b =gt makeArgs(b bprevious)concat(depObjs(b))) filter(b =gt b) toJS()
const filterExistingDiffs = (items) =gt List(items)traverse(Taskof (i) =gt find(Diff BuildId ibuildId DiffId iprevId type imethod ) map(e =gt eswap()getOrElse(null)) map(bs =gt bsfilter(x =gt x)toJS())
const buildProject = (branch sha) =gt queueUnzipWwwOnS3(sha) chain(() =gt isReleaseOrMainBranch(branch)) fold(() =gt _noop () =gt generateReport(sha) chain(queueDiffsForTileBuildsAndDeps) chain(() =gt getHeadCommit(sha) fold(() =gt Taskof(null) head =gt makeVrtDeployment(head sha) chain(() =gt createPrApp(head sha)))) fork(consoleerror
consolelog))
const vrtReport = (sha email platforms) =gt rejectFinishedPlatformOptions(platforms) chain(plats =gt platsmap(gatherScreenshots)) chain(shots =gt fromNullable(sha) fold(() =gt findLastRef() () =gt findBuild(sha)) chain(ref =gt renderReport(shots ref email))) fork(e =gt e r =gt r)
Harder to hack
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
Safer
const ProfileLink = user =gtlta href=`users$
uid`gtunameltagt
const Header = str =gt lth1gtNow Viewing strlth1gt
Component a -gt JSX
a JSXf
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
strtoUpperCase()trim()
trim(toUpperCase(str))
Category theory
fn fn
fnfn
a bf
cg
ag
cf
a
F(a)
bf
F(f)
cg
F(b) F(g)F(c)
a
F(a)
g
F(gf)
cf
F(c)
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) A
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt parseInt(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) Box(lsquoArsquo)
const Box = x =gt( map f =gt Box(f(x)))
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) Box(lsquoArsquo)
const Box = x =gt( map f =gt Box(f(x)))
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) fold(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) lsquoArsquo
const Box = x =gt( map f =gt Box(f(x)) fold f =gt f(x))
Unified call syntaxMinimized state
Captured AssignmentForced Control Flow
AssignmentLoops
CallbacksSide EffectsBranching
Errors
Loops
mapfilter
reduce
const range = (i count) =gt unfold(x =gt if(x lt= count) [x x+1] i)
range(510) [ 5 6 7 8 9 10 ]
const alphabet = () =gt unfold(x =gt if(x lt 26) [StringfromCharCode(x+65) x+1] 0)
alphabet() [ABCDEFGHIJKLMNOPQRSTUVWXYZ]
AssignmentLoops
CallbacksSide EffectsBranching
Errors
CallbacksSide Effects
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
contrivedEx2()fork(e =gt consoleerror(e) r =gt consolelog(success))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))fork(e =gt consoleerror(e)
r =gt consolelog(r))
AssignmentLoops
CallbacksSide EffectsBranching
Errors
BranchingErrors
EitherOr
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
leftOrRightfold(e =gt `we had an error $e` s =gt stoUpperCase())
Right(hair brown) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Right(five 2))
Right(10)
Left(ignored) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Left(five 2))
Left(ignored)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
Claim
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
AssignmentLoops
CallbacksSide EffectsBranching
Errors
const depObjs = b =gt List(bdeps)flatMap(next =gt findDependencyByProject(nextProjectname bpreviousdeps) fold(x =gt x found =gt makeArgs(next found)))
const mapBuildsAndDepsForDiffQueue = (builds) =gt List(builds) filter(b =gt bprevious) flatMap(b =gt makeArgs(b bprevious)concat(depObjs(b))) filter(b =gt b) toJS()
const filterExistingDiffs = (items) =gt List(items)traverse(Taskof (i) =gt find(Diff BuildId ibuildId DiffId iprevId type imethod ) map(e =gt eswap()getOrElse(null)) map(bs =gt bsfilter(x =gt x)toJS())
const buildProject = (branch sha) =gt queueUnzipWwwOnS3(sha) chain(() =gt isReleaseOrMainBranch(branch)) fold(() =gt _noop () =gt generateReport(sha) chain(queueDiffsForTileBuildsAndDeps) chain(() =gt getHeadCommit(sha) fold(() =gt Taskof(null) head =gt makeVrtDeployment(head sha) chain(() =gt createPrApp(head sha)))) fork(consoleerror
consolelog))
const vrtReport = (sha email platforms) =gt rejectFinishedPlatformOptions(platforms) chain(plats =gt platsmap(gatherScreenshots)) chain(shots =gt fromNullable(sha) fold(() =gt findLastRef() () =gt findBuild(sha)) chain(ref =gt renderReport(shots ref email))) fork(e =gt e r =gt r)
Harder to hack
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
Safer
const ProfileLink = user =gtlta href=`users$
uid`gtunameltagt
const Header = str =gt lth1gtNow Viewing strlth1gt
Component a -gt JSX
a JSXf
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
Category theory
fn fn
fnfn
a bf
cg
ag
cf
a
F(a)
bf
F(f)
cg
F(b) F(g)F(c)
a
F(a)
g
F(gf)
cf
F(c)
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) A
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt parseInt(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) Box(lsquoArsquo)
const Box = x =gt( map f =gt Box(f(x)))
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) Box(lsquoArsquo)
const Box = x =gt( map f =gt Box(f(x)))
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) fold(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) lsquoArsquo
const Box = x =gt( map f =gt Box(f(x)) fold f =gt f(x))
Unified call syntaxMinimized state
Captured AssignmentForced Control Flow
AssignmentLoops
CallbacksSide EffectsBranching
Errors
Loops
mapfilter
reduce
const range = (i count) =gt unfold(x =gt if(x lt= count) [x x+1] i)
range(510) [ 5 6 7 8 9 10 ]
const alphabet = () =gt unfold(x =gt if(x lt 26) [StringfromCharCode(x+65) x+1] 0)
alphabet() [ABCDEFGHIJKLMNOPQRSTUVWXYZ]
AssignmentLoops
CallbacksSide EffectsBranching
Errors
CallbacksSide Effects
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
contrivedEx2()fork(e =gt consoleerror(e) r =gt consolelog(success))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))fork(e =gt consoleerror(e)
r =gt consolelog(r))
AssignmentLoops
CallbacksSide EffectsBranching
Errors
BranchingErrors
EitherOr
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
leftOrRightfold(e =gt `we had an error $e` s =gt stoUpperCase())
Right(hair brown) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Right(five 2))
Right(10)
Left(ignored) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Left(five 2))
Left(ignored)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
Claim
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
AssignmentLoops
CallbacksSide EffectsBranching
Errors
const depObjs = b =gt List(bdeps)flatMap(next =gt findDependencyByProject(nextProjectname bpreviousdeps) fold(x =gt x found =gt makeArgs(next found)))
const mapBuildsAndDepsForDiffQueue = (builds) =gt List(builds) filter(b =gt bprevious) flatMap(b =gt makeArgs(b bprevious)concat(depObjs(b))) filter(b =gt b) toJS()
const filterExistingDiffs = (items) =gt List(items)traverse(Taskof (i) =gt find(Diff BuildId ibuildId DiffId iprevId type imethod ) map(e =gt eswap()getOrElse(null)) map(bs =gt bsfilter(x =gt x)toJS())
const buildProject = (branch sha) =gt queueUnzipWwwOnS3(sha) chain(() =gt isReleaseOrMainBranch(branch)) fold(() =gt _noop () =gt generateReport(sha) chain(queueDiffsForTileBuildsAndDeps) chain(() =gt getHeadCommit(sha) fold(() =gt Taskof(null) head =gt makeVrtDeployment(head sha) chain(() =gt createPrApp(head sha)))) fork(consoleerror
consolelog))
const vrtReport = (sha email platforms) =gt rejectFinishedPlatformOptions(platforms) chain(plats =gt platsmap(gatherScreenshots)) chain(shots =gt fromNullable(sha) fold(() =gt findLastRef() () =gt findBuild(sha)) chain(ref =gt renderReport(shots ref email))) fork(e =gt e r =gt r)
Harder to hack
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
Safer
const ProfileLink = user =gtlta href=`users$
uid`gtunameltagt
const Header = str =gt lth1gtNow Viewing strlth1gt
Component a -gt JSX
a JSXf
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
fn fn
fnfn
a bf
cg
ag
cf
a
F(a)
bf
F(f)
cg
F(b) F(g)F(c)
a
F(a)
g
F(gf)
cf
F(c)
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) A
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt parseInt(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) Box(lsquoArsquo)
const Box = x =gt( map f =gt Box(f(x)))
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) Box(lsquoArsquo)
const Box = x =gt( map f =gt Box(f(x)))
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) fold(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) lsquoArsquo
const Box = x =gt( map f =gt Box(f(x)) fold f =gt f(x))
Unified call syntaxMinimized state
Captured AssignmentForced Control Flow
AssignmentLoops
CallbacksSide EffectsBranching
Errors
Loops
mapfilter
reduce
const range = (i count) =gt unfold(x =gt if(x lt= count) [x x+1] i)
range(510) [ 5 6 7 8 9 10 ]
const alphabet = () =gt unfold(x =gt if(x lt 26) [StringfromCharCode(x+65) x+1] 0)
alphabet() [ABCDEFGHIJKLMNOPQRSTUVWXYZ]
AssignmentLoops
CallbacksSide EffectsBranching
Errors
CallbacksSide Effects
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
contrivedEx2()fork(e =gt consoleerror(e) r =gt consolelog(success))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))fork(e =gt consoleerror(e)
r =gt consolelog(r))
AssignmentLoops
CallbacksSide EffectsBranching
Errors
BranchingErrors
EitherOr
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
leftOrRightfold(e =gt `we had an error $e` s =gt stoUpperCase())
Right(hair brown) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Right(five 2))
Right(10)
Left(ignored) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Left(five 2))
Left(ignored)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
Claim
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
AssignmentLoops
CallbacksSide EffectsBranching
Errors
const depObjs = b =gt List(bdeps)flatMap(next =gt findDependencyByProject(nextProjectname bpreviousdeps) fold(x =gt x found =gt makeArgs(next found)))
const mapBuildsAndDepsForDiffQueue = (builds) =gt List(builds) filter(b =gt bprevious) flatMap(b =gt makeArgs(b bprevious)concat(depObjs(b))) filter(b =gt b) toJS()
const filterExistingDiffs = (items) =gt List(items)traverse(Taskof (i) =gt find(Diff BuildId ibuildId DiffId iprevId type imethod ) map(e =gt eswap()getOrElse(null)) map(bs =gt bsfilter(x =gt x)toJS())
const buildProject = (branch sha) =gt queueUnzipWwwOnS3(sha) chain(() =gt isReleaseOrMainBranch(branch)) fold(() =gt _noop () =gt generateReport(sha) chain(queueDiffsForTileBuildsAndDeps) chain(() =gt getHeadCommit(sha) fold(() =gt Taskof(null) head =gt makeVrtDeployment(head sha) chain(() =gt createPrApp(head sha)))) fork(consoleerror
consolelog))
const vrtReport = (sha email platforms) =gt rejectFinishedPlatformOptions(platforms) chain(plats =gt platsmap(gatherScreenshots)) chain(shots =gt fromNullable(sha) fold(() =gt findLastRef() () =gt findBuild(sha)) chain(ref =gt renderReport(shots ref email))) fork(e =gt e r =gt r)
Harder to hack
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
Safer
const ProfileLink = user =gtlta href=`users$
uid`gtunameltagt
const Header = str =gt lth1gtNow Viewing strlth1gt
Component a -gt JSX
a JSXf
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
fnfn
a bf
cg
ag
cf
a
F(a)
bf
F(f)
cg
F(b) F(g)F(c)
a
F(a)
g
F(gf)
cf
F(c)
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) A
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt parseInt(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) Box(lsquoArsquo)
const Box = x =gt( map f =gt Box(f(x)))
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) Box(lsquoArsquo)
const Box = x =gt( map f =gt Box(f(x)))
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) fold(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) lsquoArsquo
const Box = x =gt( map f =gt Box(f(x)) fold f =gt f(x))
Unified call syntaxMinimized state
Captured AssignmentForced Control Flow
AssignmentLoops
CallbacksSide EffectsBranching
Errors
Loops
mapfilter
reduce
const range = (i count) =gt unfold(x =gt if(x lt= count) [x x+1] i)
range(510) [ 5 6 7 8 9 10 ]
const alphabet = () =gt unfold(x =gt if(x lt 26) [StringfromCharCode(x+65) x+1] 0)
alphabet() [ABCDEFGHIJKLMNOPQRSTUVWXYZ]
AssignmentLoops
CallbacksSide EffectsBranching
Errors
CallbacksSide Effects
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
contrivedEx2()fork(e =gt consoleerror(e) r =gt consolelog(success))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))fork(e =gt consoleerror(e)
r =gt consolelog(r))
AssignmentLoops
CallbacksSide EffectsBranching
Errors
BranchingErrors
EitherOr
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
leftOrRightfold(e =gt `we had an error $e` s =gt stoUpperCase())
Right(hair brown) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Right(five 2))
Right(10)
Left(ignored) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Left(five 2))
Left(ignored)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
Claim
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
AssignmentLoops
CallbacksSide EffectsBranching
Errors
const depObjs = b =gt List(bdeps)flatMap(next =gt findDependencyByProject(nextProjectname bpreviousdeps) fold(x =gt x found =gt makeArgs(next found)))
const mapBuildsAndDepsForDiffQueue = (builds) =gt List(builds) filter(b =gt bprevious) flatMap(b =gt makeArgs(b bprevious)concat(depObjs(b))) filter(b =gt b) toJS()
const filterExistingDiffs = (items) =gt List(items)traverse(Taskof (i) =gt find(Diff BuildId ibuildId DiffId iprevId type imethod ) map(e =gt eswap()getOrElse(null)) map(bs =gt bsfilter(x =gt x)toJS())
const buildProject = (branch sha) =gt queueUnzipWwwOnS3(sha) chain(() =gt isReleaseOrMainBranch(branch)) fold(() =gt _noop () =gt generateReport(sha) chain(queueDiffsForTileBuildsAndDeps) chain(() =gt getHeadCommit(sha) fold(() =gt Taskof(null) head =gt makeVrtDeployment(head sha) chain(() =gt createPrApp(head sha)))) fork(consoleerror
consolelog))
const vrtReport = (sha email platforms) =gt rejectFinishedPlatformOptions(platforms) chain(plats =gt platsmap(gatherScreenshots)) chain(shots =gt fromNullable(sha) fold(() =gt findLastRef() () =gt findBuild(sha)) chain(ref =gt renderReport(shots ref email))) fork(e =gt e r =gt r)
Harder to hack
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
Safer
const ProfileLink = user =gtlta href=`users$
uid`gtunameltagt
const Header = str =gt lth1gtNow Viewing strlth1gt
Component a -gt JSX
a JSXf
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
a bf
cg
ag
cf
a
F(a)
bf
F(f)
cg
F(b) F(g)F(c)
a
F(a)
g
F(gf)
cf
F(c)
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) A
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt parseInt(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) Box(lsquoArsquo)
const Box = x =gt( map f =gt Box(f(x)))
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) Box(lsquoArsquo)
const Box = x =gt( map f =gt Box(f(x)))
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) fold(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) lsquoArsquo
const Box = x =gt( map f =gt Box(f(x)) fold f =gt f(x))
Unified call syntaxMinimized state
Captured AssignmentForced Control Flow
AssignmentLoops
CallbacksSide EffectsBranching
Errors
Loops
mapfilter
reduce
const range = (i count) =gt unfold(x =gt if(x lt= count) [x x+1] i)
range(510) [ 5 6 7 8 9 10 ]
const alphabet = () =gt unfold(x =gt if(x lt 26) [StringfromCharCode(x+65) x+1] 0)
alphabet() [ABCDEFGHIJKLMNOPQRSTUVWXYZ]
AssignmentLoops
CallbacksSide EffectsBranching
Errors
CallbacksSide Effects
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
contrivedEx2()fork(e =gt consoleerror(e) r =gt consolelog(success))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))fork(e =gt consoleerror(e)
r =gt consolelog(r))
AssignmentLoops
CallbacksSide EffectsBranching
Errors
BranchingErrors
EitherOr
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
leftOrRightfold(e =gt `we had an error $e` s =gt stoUpperCase())
Right(hair brown) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Right(five 2))
Right(10)
Left(ignored) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Left(five 2))
Left(ignored)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
Claim
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
AssignmentLoops
CallbacksSide EffectsBranching
Errors
const depObjs = b =gt List(bdeps)flatMap(next =gt findDependencyByProject(nextProjectname bpreviousdeps) fold(x =gt x found =gt makeArgs(next found)))
const mapBuildsAndDepsForDiffQueue = (builds) =gt List(builds) filter(b =gt bprevious) flatMap(b =gt makeArgs(b bprevious)concat(depObjs(b))) filter(b =gt b) toJS()
const filterExistingDiffs = (items) =gt List(items)traverse(Taskof (i) =gt find(Diff BuildId ibuildId DiffId iprevId type imethod ) map(e =gt eswap()getOrElse(null)) map(bs =gt bsfilter(x =gt x)toJS())
const buildProject = (branch sha) =gt queueUnzipWwwOnS3(sha) chain(() =gt isReleaseOrMainBranch(branch)) fold(() =gt _noop () =gt generateReport(sha) chain(queueDiffsForTileBuildsAndDeps) chain(() =gt getHeadCommit(sha) fold(() =gt Taskof(null) head =gt makeVrtDeployment(head sha) chain(() =gt createPrApp(head sha)))) fork(consoleerror
consolelog))
const vrtReport = (sha email platforms) =gt rejectFinishedPlatformOptions(platforms) chain(plats =gt platsmap(gatherScreenshots)) chain(shots =gt fromNullable(sha) fold(() =gt findLastRef() () =gt findBuild(sha)) chain(ref =gt renderReport(shots ref email))) fork(e =gt e r =gt r)
Harder to hack
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
Safer
const ProfileLink = user =gtlta href=`users$
uid`gtunameltagt
const Header = str =gt lth1gtNow Viewing strlth1gt
Component a -gt JSX
a JSXf
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
ag
cf
a
F(a)
bf
F(f)
cg
F(b) F(g)F(c)
a
F(a)
g
F(gf)
cf
F(c)
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) A
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt parseInt(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) Box(lsquoArsquo)
const Box = x =gt( map f =gt Box(f(x)))
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) Box(lsquoArsquo)
const Box = x =gt( map f =gt Box(f(x)))
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) fold(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) lsquoArsquo
const Box = x =gt( map f =gt Box(f(x)) fold f =gt f(x))
Unified call syntaxMinimized state
Captured AssignmentForced Control Flow
AssignmentLoops
CallbacksSide EffectsBranching
Errors
Loops
mapfilter
reduce
const range = (i count) =gt unfold(x =gt if(x lt= count) [x x+1] i)
range(510) [ 5 6 7 8 9 10 ]
const alphabet = () =gt unfold(x =gt if(x lt 26) [StringfromCharCode(x+65) x+1] 0)
alphabet() [ABCDEFGHIJKLMNOPQRSTUVWXYZ]
AssignmentLoops
CallbacksSide EffectsBranching
Errors
CallbacksSide Effects
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
contrivedEx2()fork(e =gt consoleerror(e) r =gt consolelog(success))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))fork(e =gt consoleerror(e)
r =gt consolelog(r))
AssignmentLoops
CallbacksSide EffectsBranching
Errors
BranchingErrors
EitherOr
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
leftOrRightfold(e =gt `we had an error $e` s =gt stoUpperCase())
Right(hair brown) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Right(five 2))
Right(10)
Left(ignored) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Left(five 2))
Left(ignored)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
Claim
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
AssignmentLoops
CallbacksSide EffectsBranching
Errors
const depObjs = b =gt List(bdeps)flatMap(next =gt findDependencyByProject(nextProjectname bpreviousdeps) fold(x =gt x found =gt makeArgs(next found)))
const mapBuildsAndDepsForDiffQueue = (builds) =gt List(builds) filter(b =gt bprevious) flatMap(b =gt makeArgs(b bprevious)concat(depObjs(b))) filter(b =gt b) toJS()
const filterExistingDiffs = (items) =gt List(items)traverse(Taskof (i) =gt find(Diff BuildId ibuildId DiffId iprevId type imethod ) map(e =gt eswap()getOrElse(null)) map(bs =gt bsfilter(x =gt x)toJS())
const buildProject = (branch sha) =gt queueUnzipWwwOnS3(sha) chain(() =gt isReleaseOrMainBranch(branch)) fold(() =gt _noop () =gt generateReport(sha) chain(queueDiffsForTileBuildsAndDeps) chain(() =gt getHeadCommit(sha) fold(() =gt Taskof(null) head =gt makeVrtDeployment(head sha) chain(() =gt createPrApp(head sha)))) fork(consoleerror
consolelog))
const vrtReport = (sha email platforms) =gt rejectFinishedPlatformOptions(platforms) chain(plats =gt platsmap(gatherScreenshots)) chain(shots =gt fromNullable(sha) fold(() =gt findLastRef() () =gt findBuild(sha)) chain(ref =gt renderReport(shots ref email))) fork(e =gt e r =gt r)
Harder to hack
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
Safer
const ProfileLink = user =gtlta href=`users$
uid`gtunameltagt
const Header = str =gt lth1gtNow Viewing strlth1gt
Component a -gt JSX
a JSXf
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
a
F(a)
bf
F(f)
cg
F(b) F(g)F(c)
a
F(a)
g
F(gf)
cf
F(c)
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) A
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt parseInt(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) Box(lsquoArsquo)
const Box = x =gt( map f =gt Box(f(x)))
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) Box(lsquoArsquo)
const Box = x =gt( map f =gt Box(f(x)))
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) fold(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) lsquoArsquo
const Box = x =gt( map f =gt Box(f(x)) fold f =gt f(x))
Unified call syntaxMinimized state
Captured AssignmentForced Control Flow
AssignmentLoops
CallbacksSide EffectsBranching
Errors
Loops
mapfilter
reduce
const range = (i count) =gt unfold(x =gt if(x lt= count) [x x+1] i)
range(510) [ 5 6 7 8 9 10 ]
const alphabet = () =gt unfold(x =gt if(x lt 26) [StringfromCharCode(x+65) x+1] 0)
alphabet() [ABCDEFGHIJKLMNOPQRSTUVWXYZ]
AssignmentLoops
CallbacksSide EffectsBranching
Errors
CallbacksSide Effects
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
contrivedEx2()fork(e =gt consoleerror(e) r =gt consolelog(success))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))fork(e =gt consoleerror(e)
r =gt consolelog(r))
AssignmentLoops
CallbacksSide EffectsBranching
Errors
BranchingErrors
EitherOr
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
leftOrRightfold(e =gt `we had an error $e` s =gt stoUpperCase())
Right(hair brown) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Right(five 2))
Right(10)
Left(ignored) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Left(five 2))
Left(ignored)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
Claim
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
AssignmentLoops
CallbacksSide EffectsBranching
Errors
const depObjs = b =gt List(bdeps)flatMap(next =gt findDependencyByProject(nextProjectname bpreviousdeps) fold(x =gt x found =gt makeArgs(next found)))
const mapBuildsAndDepsForDiffQueue = (builds) =gt List(builds) filter(b =gt bprevious) flatMap(b =gt makeArgs(b bprevious)concat(depObjs(b))) filter(b =gt b) toJS()
const filterExistingDiffs = (items) =gt List(items)traverse(Taskof (i) =gt find(Diff BuildId ibuildId DiffId iprevId type imethod ) map(e =gt eswap()getOrElse(null)) map(bs =gt bsfilter(x =gt x)toJS())
const buildProject = (branch sha) =gt queueUnzipWwwOnS3(sha) chain(() =gt isReleaseOrMainBranch(branch)) fold(() =gt _noop () =gt generateReport(sha) chain(queueDiffsForTileBuildsAndDeps) chain(() =gt getHeadCommit(sha) fold(() =gt Taskof(null) head =gt makeVrtDeployment(head sha) chain(() =gt createPrApp(head sha)))) fork(consoleerror
consolelog))
const vrtReport = (sha email platforms) =gt rejectFinishedPlatformOptions(platforms) chain(plats =gt platsmap(gatherScreenshots)) chain(shots =gt fromNullable(sha) fold(() =gt findLastRef() () =gt findBuild(sha)) chain(ref =gt renderReport(shots ref email))) fork(e =gt e r =gt r)
Harder to hack
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
Safer
const ProfileLink = user =gtlta href=`users$
uid`gtunameltagt
const Header = str =gt lth1gtNow Viewing strlth1gt
Component a -gt JSX
a JSXf
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
a
F(a)
g
F(gf)
cf
F(c)
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) A
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt parseInt(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) Box(lsquoArsquo)
const Box = x =gt( map f =gt Box(f(x)))
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) Box(lsquoArsquo)
const Box = x =gt( map f =gt Box(f(x)))
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) fold(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) lsquoArsquo
const Box = x =gt( map f =gt Box(f(x)) fold f =gt f(x))
Unified call syntaxMinimized state
Captured AssignmentForced Control Flow
AssignmentLoops
CallbacksSide EffectsBranching
Errors
Loops
mapfilter
reduce
const range = (i count) =gt unfold(x =gt if(x lt= count) [x x+1] i)
range(510) [ 5 6 7 8 9 10 ]
const alphabet = () =gt unfold(x =gt if(x lt 26) [StringfromCharCode(x+65) x+1] 0)
alphabet() [ABCDEFGHIJKLMNOPQRSTUVWXYZ]
AssignmentLoops
CallbacksSide EffectsBranching
Errors
CallbacksSide Effects
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
contrivedEx2()fork(e =gt consoleerror(e) r =gt consolelog(success))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))fork(e =gt consoleerror(e)
r =gt consolelog(r))
AssignmentLoops
CallbacksSide EffectsBranching
Errors
BranchingErrors
EitherOr
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
leftOrRightfold(e =gt `we had an error $e` s =gt stoUpperCase())
Right(hair brown) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Right(five 2))
Right(10)
Left(ignored) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Left(five 2))
Left(ignored)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
Claim
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
AssignmentLoops
CallbacksSide EffectsBranching
Errors
const depObjs = b =gt List(bdeps)flatMap(next =gt findDependencyByProject(nextProjectname bpreviousdeps) fold(x =gt x found =gt makeArgs(next found)))
const mapBuildsAndDepsForDiffQueue = (builds) =gt List(builds) filter(b =gt bprevious) flatMap(b =gt makeArgs(b bprevious)concat(depObjs(b))) filter(b =gt b) toJS()
const filterExistingDiffs = (items) =gt List(items)traverse(Taskof (i) =gt find(Diff BuildId ibuildId DiffId iprevId type imethod ) map(e =gt eswap()getOrElse(null)) map(bs =gt bsfilter(x =gt x)toJS())
const buildProject = (branch sha) =gt queueUnzipWwwOnS3(sha) chain(() =gt isReleaseOrMainBranch(branch)) fold(() =gt _noop () =gt generateReport(sha) chain(queueDiffsForTileBuildsAndDeps) chain(() =gt getHeadCommit(sha) fold(() =gt Taskof(null) head =gt makeVrtDeployment(head sha) chain(() =gt createPrApp(head sha)))) fork(consoleerror
consolelog))
const vrtReport = (sha email platforms) =gt rejectFinishedPlatformOptions(platforms) chain(plats =gt platsmap(gatherScreenshots)) chain(shots =gt fromNullable(sha) fold(() =gt findLastRef() () =gt findBuild(sha)) chain(ref =gt renderReport(shots ref email))) fork(e =gt e r =gt r)
Harder to hack
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
Safer
const ProfileLink = user =gtlta href=`users$
uid`gtunameltagt
const Header = str =gt lth1gtNow Viewing strlth1gt
Component a -gt JSX
a JSXf
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) A
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt parseInt(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) Box(lsquoArsquo)
const Box = x =gt( map f =gt Box(f(x)))
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) Box(lsquoArsquo)
const Box = x =gt( map f =gt Box(f(x)))
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) fold(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) lsquoArsquo
const Box = x =gt( map f =gt Box(f(x)) fold f =gt f(x))
Unified call syntaxMinimized state
Captured AssignmentForced Control Flow
AssignmentLoops
CallbacksSide EffectsBranching
Errors
Loops
mapfilter
reduce
const range = (i count) =gt unfold(x =gt if(x lt= count) [x x+1] i)
range(510) [ 5 6 7 8 9 10 ]
const alphabet = () =gt unfold(x =gt if(x lt 26) [StringfromCharCode(x+65) x+1] 0)
alphabet() [ABCDEFGHIJKLMNOPQRSTUVWXYZ]
AssignmentLoops
CallbacksSide EffectsBranching
Errors
CallbacksSide Effects
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
contrivedEx2()fork(e =gt consoleerror(e) r =gt consolelog(success))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))fork(e =gt consoleerror(e)
r =gt consolelog(r))
AssignmentLoops
CallbacksSide EffectsBranching
Errors
BranchingErrors
EitherOr
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
leftOrRightfold(e =gt `we had an error $e` s =gt stoUpperCase())
Right(hair brown) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Right(five 2))
Right(10)
Left(ignored) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Left(five 2))
Left(ignored)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
Claim
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
AssignmentLoops
CallbacksSide EffectsBranching
Errors
const depObjs = b =gt List(bdeps)flatMap(next =gt findDependencyByProject(nextProjectname bpreviousdeps) fold(x =gt x found =gt makeArgs(next found)))
const mapBuildsAndDepsForDiffQueue = (builds) =gt List(builds) filter(b =gt bprevious) flatMap(b =gt makeArgs(b bprevious)concat(depObjs(b))) filter(b =gt b) toJS()
const filterExistingDiffs = (items) =gt List(items)traverse(Taskof (i) =gt find(Diff BuildId ibuildId DiffId iprevId type imethod ) map(e =gt eswap()getOrElse(null)) map(bs =gt bsfilter(x =gt x)toJS())
const buildProject = (branch sha) =gt queueUnzipWwwOnS3(sha) chain(() =gt isReleaseOrMainBranch(branch)) fold(() =gt _noop () =gt generateReport(sha) chain(queueDiffsForTileBuildsAndDeps) chain(() =gt getHeadCommit(sha) fold(() =gt Taskof(null) head =gt makeVrtDeployment(head sha) chain(() =gt createPrApp(head sha)))) fork(consoleerror
consolelog))
const vrtReport = (sha email platforms) =gt rejectFinishedPlatformOptions(platforms) chain(plats =gt platsmap(gatherScreenshots)) chain(shots =gt fromNullable(sha) fold(() =gt findLastRef() () =gt findBuild(sha)) chain(ref =gt renderReport(shots ref email))) fork(e =gt e r =gt r)
Harder to hack
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
Safer
const ProfileLink = user =gtlta href=`users$
uid`gtunameltagt
const Header = str =gt lth1gtNow Viewing strlth1gt
Component a -gt JSX
a JSXf
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt parseInt(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) Box(lsquoArsquo)
const Box = x =gt( map f =gt Box(f(x)))
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) Box(lsquoArsquo)
const Box = x =gt( map f =gt Box(f(x)))
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) fold(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) lsquoArsquo
const Box = x =gt( map f =gt Box(f(x)) fold f =gt f(x))
Unified call syntaxMinimized state
Captured AssignmentForced Control Flow
AssignmentLoops
CallbacksSide EffectsBranching
Errors
Loops
mapfilter
reduce
const range = (i count) =gt unfold(x =gt if(x lt= count) [x x+1] i)
range(510) [ 5 6 7 8 9 10 ]
const alphabet = () =gt unfold(x =gt if(x lt 26) [StringfromCharCode(x+65) x+1] 0)
alphabet() [ABCDEFGHIJKLMNOPQRSTUVWXYZ]
AssignmentLoops
CallbacksSide EffectsBranching
Errors
CallbacksSide Effects
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
contrivedEx2()fork(e =gt consoleerror(e) r =gt consolelog(success))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))fork(e =gt consoleerror(e)
r =gt consolelog(r))
AssignmentLoops
CallbacksSide EffectsBranching
Errors
BranchingErrors
EitherOr
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
leftOrRightfold(e =gt `we had an error $e` s =gt stoUpperCase())
Right(hair brown) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Right(five 2))
Right(10)
Left(ignored) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Left(five 2))
Left(ignored)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
Claim
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
AssignmentLoops
CallbacksSide EffectsBranching
Errors
const depObjs = b =gt List(bdeps)flatMap(next =gt findDependencyByProject(nextProjectname bpreviousdeps) fold(x =gt x found =gt makeArgs(next found)))
const mapBuildsAndDepsForDiffQueue = (builds) =gt List(builds) filter(b =gt bprevious) flatMap(b =gt makeArgs(b bprevious)concat(depObjs(b))) filter(b =gt b) toJS()
const filterExistingDiffs = (items) =gt List(items)traverse(Taskof (i) =gt find(Diff BuildId ibuildId DiffId iprevId type imethod ) map(e =gt eswap()getOrElse(null)) map(bs =gt bsfilter(x =gt x)toJS())
const buildProject = (branch sha) =gt queueUnzipWwwOnS3(sha) chain(() =gt isReleaseOrMainBranch(branch)) fold(() =gt _noop () =gt generateReport(sha) chain(queueDiffsForTileBuildsAndDeps) chain(() =gt getHeadCommit(sha) fold(() =gt Taskof(null) head =gt makeVrtDeployment(head sha) chain(() =gt createPrApp(head sha)))) fork(consoleerror
consolelog))
const vrtReport = (sha email platforms) =gt rejectFinishedPlatformOptions(platforms) chain(plats =gt platsmap(gatherScreenshots)) chain(shots =gt fromNullable(sha) fold(() =gt findLastRef() () =gt findBuild(sha)) chain(ref =gt renderReport(shots ref email))) fork(e =gt e r =gt r)
Harder to hack
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
Safer
const ProfileLink = user =gtlta href=`users$
uid`gtunameltagt
const Header = str =gt lth1gtNow Viewing strlth1gt
Component a -gt JSX
a JSXf
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) Box(lsquoArsquo)
const Box = x =gt( map f =gt Box(f(x)))
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) Box(lsquoArsquo)
const Box = x =gt( map f =gt Box(f(x)))
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) fold(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) lsquoArsquo
const Box = x =gt( map f =gt Box(f(x)) fold f =gt f(x))
Unified call syntaxMinimized state
Captured AssignmentForced Control Flow
AssignmentLoops
CallbacksSide EffectsBranching
Errors
Loops
mapfilter
reduce
const range = (i count) =gt unfold(x =gt if(x lt= count) [x x+1] i)
range(510) [ 5 6 7 8 9 10 ]
const alphabet = () =gt unfold(x =gt if(x lt 26) [StringfromCharCode(x+65) x+1] 0)
alphabet() [ABCDEFGHIJKLMNOPQRSTUVWXYZ]
AssignmentLoops
CallbacksSide EffectsBranching
Errors
CallbacksSide Effects
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
contrivedEx2()fork(e =gt consoleerror(e) r =gt consolelog(success))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))fork(e =gt consoleerror(e)
r =gt consolelog(r))
AssignmentLoops
CallbacksSide EffectsBranching
Errors
BranchingErrors
EitherOr
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
leftOrRightfold(e =gt `we had an error $e` s =gt stoUpperCase())
Right(hair brown) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Right(five 2))
Right(10)
Left(ignored) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Left(five 2))
Left(ignored)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
Claim
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
AssignmentLoops
CallbacksSide EffectsBranching
Errors
const depObjs = b =gt List(bdeps)flatMap(next =gt findDependencyByProject(nextProjectname bpreviousdeps) fold(x =gt x found =gt makeArgs(next found)))
const mapBuildsAndDepsForDiffQueue = (builds) =gt List(builds) filter(b =gt bprevious) flatMap(b =gt makeArgs(b bprevious)concat(depObjs(b))) filter(b =gt b) toJS()
const filterExistingDiffs = (items) =gt List(items)traverse(Taskof (i) =gt find(Diff BuildId ibuildId DiffId iprevId type imethod ) map(e =gt eswap()getOrElse(null)) map(bs =gt bsfilter(x =gt x)toJS())
const buildProject = (branch sha) =gt queueUnzipWwwOnS3(sha) chain(() =gt isReleaseOrMainBranch(branch)) fold(() =gt _noop () =gt generateReport(sha) chain(queueDiffsForTileBuildsAndDeps) chain(() =gt getHeadCommit(sha) fold(() =gt Taskof(null) head =gt makeVrtDeployment(head sha) chain(() =gt createPrApp(head sha)))) fork(consoleerror
consolelog))
const vrtReport = (sha email platforms) =gt rejectFinishedPlatformOptions(platforms) chain(plats =gt platsmap(gatherScreenshots)) chain(shots =gt fromNullable(sha) fold(() =gt findLastRef() () =gt findBuild(sha)) chain(ref =gt renderReport(shots ref email))) fork(e =gt e r =gt r)
Harder to hack
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
Safer
const ProfileLink = user =gtlta href=`users$
uid`gtunameltagt
const Header = str =gt lth1gtNow Viewing strlth1gt
Component a -gt JSX
a JSXf
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
const contrivedEx1 = str =gt [strtrim()] map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
const contrivedEx1 = str =gt const trimmed = strtrim() const number = parseInt(trimmed) const nextNumber = number + 1 return StringfromCharCode(nextNumber)
contrivedEx1( 64 ) [lsquoArsquo]
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) Box(lsquoArsquo)
const Box = x =gt( map f =gt Box(f(x)))
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) Box(lsquoArsquo)
const Box = x =gt( map f =gt Box(f(x)))
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) fold(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) lsquoArsquo
const Box = x =gt( map f =gt Box(f(x)) fold f =gt f(x))
Unified call syntaxMinimized state
Captured AssignmentForced Control Flow
AssignmentLoops
CallbacksSide EffectsBranching
Errors
Loops
mapfilter
reduce
const range = (i count) =gt unfold(x =gt if(x lt= count) [x x+1] i)
range(510) [ 5 6 7 8 9 10 ]
const alphabet = () =gt unfold(x =gt if(x lt 26) [StringfromCharCode(x+65) x+1] 0)
alphabet() [ABCDEFGHIJKLMNOPQRSTUVWXYZ]
AssignmentLoops
CallbacksSide EffectsBranching
Errors
CallbacksSide Effects
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
contrivedEx2()fork(e =gt consoleerror(e) r =gt consolelog(success))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))fork(e =gt consoleerror(e)
r =gt consolelog(r))
AssignmentLoops
CallbacksSide EffectsBranching
Errors
BranchingErrors
EitherOr
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
leftOrRightfold(e =gt `we had an error $e` s =gt stoUpperCase())
Right(hair brown) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Right(five 2))
Right(10)
Left(ignored) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Left(five 2))
Left(ignored)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
Claim
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
AssignmentLoops
CallbacksSide EffectsBranching
Errors
const depObjs = b =gt List(bdeps)flatMap(next =gt findDependencyByProject(nextProjectname bpreviousdeps) fold(x =gt x found =gt makeArgs(next found)))
const mapBuildsAndDepsForDiffQueue = (builds) =gt List(builds) filter(b =gt bprevious) flatMap(b =gt makeArgs(b bprevious)concat(depObjs(b))) filter(b =gt b) toJS()
const filterExistingDiffs = (items) =gt List(items)traverse(Taskof (i) =gt find(Diff BuildId ibuildId DiffId iprevId type imethod ) map(e =gt eswap()getOrElse(null)) map(bs =gt bsfilter(x =gt x)toJS())
const buildProject = (branch sha) =gt queueUnzipWwwOnS3(sha) chain(() =gt isReleaseOrMainBranch(branch)) fold(() =gt _noop () =gt generateReport(sha) chain(queueDiffsForTileBuildsAndDeps) chain(() =gt getHeadCommit(sha) fold(() =gt Taskof(null) head =gt makeVrtDeployment(head sha) chain(() =gt createPrApp(head sha)))) fork(consoleerror
consolelog))
const vrtReport = (sha email platforms) =gt rejectFinishedPlatformOptions(platforms) chain(plats =gt platsmap(gatherScreenshots)) chain(shots =gt fromNullable(sha) fold(() =gt findLastRef() () =gt findBuild(sha)) chain(ref =gt renderReport(shots ref email))) fork(e =gt e r =gt r)
Harder to hack
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
Safer
const ProfileLink = user =gtlta href=`users$
uid`gtunameltagt
const Header = str =gt lth1gtNow Viewing strlth1gt
Component a -gt JSX
a JSXf
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) Box(lsquoArsquo)
const Box = x =gt( map f =gt Box(f(x)))
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) Box(lsquoArsquo)
const Box = x =gt( map f =gt Box(f(x)))
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) fold(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) lsquoArsquo
const Box = x =gt( map f =gt Box(f(x)) fold f =gt f(x))
Unified call syntaxMinimized state
Captured AssignmentForced Control Flow
AssignmentLoops
CallbacksSide EffectsBranching
Errors
Loops
mapfilter
reduce
const range = (i count) =gt unfold(x =gt if(x lt= count) [x x+1] i)
range(510) [ 5 6 7 8 9 10 ]
const alphabet = () =gt unfold(x =gt if(x lt 26) [StringfromCharCode(x+65) x+1] 0)
alphabet() [ABCDEFGHIJKLMNOPQRSTUVWXYZ]
AssignmentLoops
CallbacksSide EffectsBranching
Errors
CallbacksSide Effects
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
contrivedEx2()fork(e =gt consoleerror(e) r =gt consolelog(success))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))fork(e =gt consoleerror(e)
r =gt consolelog(r))
AssignmentLoops
CallbacksSide EffectsBranching
Errors
BranchingErrors
EitherOr
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
leftOrRightfold(e =gt `we had an error $e` s =gt stoUpperCase())
Right(hair brown) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Right(five 2))
Right(10)
Left(ignored) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Left(five 2))
Left(ignored)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
Claim
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
AssignmentLoops
CallbacksSide EffectsBranching
Errors
const depObjs = b =gt List(bdeps)flatMap(next =gt findDependencyByProject(nextProjectname bpreviousdeps) fold(x =gt x found =gt makeArgs(next found)))
const mapBuildsAndDepsForDiffQueue = (builds) =gt List(builds) filter(b =gt bprevious) flatMap(b =gt makeArgs(b bprevious)concat(depObjs(b))) filter(b =gt b) toJS()
const filterExistingDiffs = (items) =gt List(items)traverse(Taskof (i) =gt find(Diff BuildId ibuildId DiffId iprevId type imethod ) map(e =gt eswap()getOrElse(null)) map(bs =gt bsfilter(x =gt x)toJS())
const buildProject = (branch sha) =gt queueUnzipWwwOnS3(sha) chain(() =gt isReleaseOrMainBranch(branch)) fold(() =gt _noop () =gt generateReport(sha) chain(queueDiffsForTileBuildsAndDeps) chain(() =gt getHeadCommit(sha) fold(() =gt Taskof(null) head =gt makeVrtDeployment(head sha) chain(() =gt createPrApp(head sha)))) fork(consoleerror
consolelog))
const vrtReport = (sha email platforms) =gt rejectFinishedPlatformOptions(platforms) chain(plats =gt platsmap(gatherScreenshots)) chain(shots =gt fromNullable(sha) fold(() =gt findLastRef() () =gt findBuild(sha)) chain(ref =gt renderReport(shots ref email))) fork(e =gt e r =gt r)
Harder to hack
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
Safer
const ProfileLink = user =gtlta href=`users$
uid`gtunameltagt
const Header = str =gt lth1gtNow Viewing strlth1gt
Component a -gt JSX
a JSXf
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) map(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) Box(lsquoArsquo)
const Box = x =gt( map f =gt Box(f(x)))
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) fold(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) lsquoArsquo
const Box = x =gt( map f =gt Box(f(x)) fold f =gt f(x))
Unified call syntaxMinimized state
Captured AssignmentForced Control Flow
AssignmentLoops
CallbacksSide EffectsBranching
Errors
Loops
mapfilter
reduce
const range = (i count) =gt unfold(x =gt if(x lt= count) [x x+1] i)
range(510) [ 5 6 7 8 9 10 ]
const alphabet = () =gt unfold(x =gt if(x lt 26) [StringfromCharCode(x+65) x+1] 0)
alphabet() [ABCDEFGHIJKLMNOPQRSTUVWXYZ]
AssignmentLoops
CallbacksSide EffectsBranching
Errors
CallbacksSide Effects
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
contrivedEx2()fork(e =gt consoleerror(e) r =gt consolelog(success))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))fork(e =gt consoleerror(e)
r =gt consolelog(r))
AssignmentLoops
CallbacksSide EffectsBranching
Errors
BranchingErrors
EitherOr
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
leftOrRightfold(e =gt `we had an error $e` s =gt stoUpperCase())
Right(hair brown) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Right(five 2))
Right(10)
Left(ignored) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Left(five 2))
Left(ignored)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
Claim
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
AssignmentLoops
CallbacksSide EffectsBranching
Errors
const depObjs = b =gt List(bdeps)flatMap(next =gt findDependencyByProject(nextProjectname bpreviousdeps) fold(x =gt x found =gt makeArgs(next found)))
const mapBuildsAndDepsForDiffQueue = (builds) =gt List(builds) filter(b =gt bprevious) flatMap(b =gt makeArgs(b bprevious)concat(depObjs(b))) filter(b =gt b) toJS()
const filterExistingDiffs = (items) =gt List(items)traverse(Taskof (i) =gt find(Diff BuildId ibuildId DiffId iprevId type imethod ) map(e =gt eswap()getOrElse(null)) map(bs =gt bsfilter(x =gt x)toJS())
const buildProject = (branch sha) =gt queueUnzipWwwOnS3(sha) chain(() =gt isReleaseOrMainBranch(branch)) fold(() =gt _noop () =gt generateReport(sha) chain(queueDiffsForTileBuildsAndDeps) chain(() =gt getHeadCommit(sha) fold(() =gt Taskof(null) head =gt makeVrtDeployment(head sha) chain(() =gt createPrApp(head sha)))) fork(consoleerror
consolelog))
const vrtReport = (sha email platforms) =gt rejectFinishedPlatformOptions(platforms) chain(plats =gt platsmap(gatherScreenshots)) chain(shots =gt fromNullable(sha) fold(() =gt findLastRef() () =gt findBuild(sha)) chain(ref =gt renderReport(shots ref email))) fork(e =gt e r =gt r)
Harder to hack
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
Safer
const ProfileLink = user =gtlta href=`users$
uid`gtunameltagt
const Header = str =gt lth1gtNow Viewing strlth1gt
Component a -gt JSX
a JSXf
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
const contrivedEx1 = str =gt Box(strtrim()) map(trimmed =gt new Number(trimmed)) map(number =gt number + 1) fold(nextNumber =gt StringfromCharCode(nextNumber))
contrivedEx1( 64 ) lsquoArsquo
const Box = x =gt( map f =gt Box(f(x)) fold f =gt f(x))
Unified call syntaxMinimized state
Captured AssignmentForced Control Flow
AssignmentLoops
CallbacksSide EffectsBranching
Errors
Loops
mapfilter
reduce
const range = (i count) =gt unfold(x =gt if(x lt= count) [x x+1] i)
range(510) [ 5 6 7 8 9 10 ]
const alphabet = () =gt unfold(x =gt if(x lt 26) [StringfromCharCode(x+65) x+1] 0)
alphabet() [ABCDEFGHIJKLMNOPQRSTUVWXYZ]
AssignmentLoops
CallbacksSide EffectsBranching
Errors
CallbacksSide Effects
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
contrivedEx2()fork(e =gt consoleerror(e) r =gt consolelog(success))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))fork(e =gt consoleerror(e)
r =gt consolelog(r))
AssignmentLoops
CallbacksSide EffectsBranching
Errors
BranchingErrors
EitherOr
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
leftOrRightfold(e =gt `we had an error $e` s =gt stoUpperCase())
Right(hair brown) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Right(five 2))
Right(10)
Left(ignored) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Left(five 2))
Left(ignored)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
Claim
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
AssignmentLoops
CallbacksSide EffectsBranching
Errors
const depObjs = b =gt List(bdeps)flatMap(next =gt findDependencyByProject(nextProjectname bpreviousdeps) fold(x =gt x found =gt makeArgs(next found)))
const mapBuildsAndDepsForDiffQueue = (builds) =gt List(builds) filter(b =gt bprevious) flatMap(b =gt makeArgs(b bprevious)concat(depObjs(b))) filter(b =gt b) toJS()
const filterExistingDiffs = (items) =gt List(items)traverse(Taskof (i) =gt find(Diff BuildId ibuildId DiffId iprevId type imethod ) map(e =gt eswap()getOrElse(null)) map(bs =gt bsfilter(x =gt x)toJS())
const buildProject = (branch sha) =gt queueUnzipWwwOnS3(sha) chain(() =gt isReleaseOrMainBranch(branch)) fold(() =gt _noop () =gt generateReport(sha) chain(queueDiffsForTileBuildsAndDeps) chain(() =gt getHeadCommit(sha) fold(() =gt Taskof(null) head =gt makeVrtDeployment(head sha) chain(() =gt createPrApp(head sha)))) fork(consoleerror
consolelog))
const vrtReport = (sha email platforms) =gt rejectFinishedPlatformOptions(platforms) chain(plats =gt platsmap(gatherScreenshots)) chain(shots =gt fromNullable(sha) fold(() =gt findLastRef() () =gt findBuild(sha)) chain(ref =gt renderReport(shots ref email))) fork(e =gt e r =gt r)
Harder to hack
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
Safer
const ProfileLink = user =gtlta href=`users$
uid`gtunameltagt
const Header = str =gt lth1gtNow Viewing strlth1gt
Component a -gt JSX
a JSXf
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
Unified call syntaxMinimized state
Captured AssignmentForced Control Flow
AssignmentLoops
CallbacksSide EffectsBranching
Errors
Loops
mapfilter
reduce
const range = (i count) =gt unfold(x =gt if(x lt= count) [x x+1] i)
range(510) [ 5 6 7 8 9 10 ]
const alphabet = () =gt unfold(x =gt if(x lt 26) [StringfromCharCode(x+65) x+1] 0)
alphabet() [ABCDEFGHIJKLMNOPQRSTUVWXYZ]
AssignmentLoops
CallbacksSide EffectsBranching
Errors
CallbacksSide Effects
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
contrivedEx2()fork(e =gt consoleerror(e) r =gt consolelog(success))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))fork(e =gt consoleerror(e)
r =gt consolelog(r))
AssignmentLoops
CallbacksSide EffectsBranching
Errors
BranchingErrors
EitherOr
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
leftOrRightfold(e =gt `we had an error $e` s =gt stoUpperCase())
Right(hair brown) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Right(five 2))
Right(10)
Left(ignored) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Left(five 2))
Left(ignored)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
Claim
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
AssignmentLoops
CallbacksSide EffectsBranching
Errors
const depObjs = b =gt List(bdeps)flatMap(next =gt findDependencyByProject(nextProjectname bpreviousdeps) fold(x =gt x found =gt makeArgs(next found)))
const mapBuildsAndDepsForDiffQueue = (builds) =gt List(builds) filter(b =gt bprevious) flatMap(b =gt makeArgs(b bprevious)concat(depObjs(b))) filter(b =gt b) toJS()
const filterExistingDiffs = (items) =gt List(items)traverse(Taskof (i) =gt find(Diff BuildId ibuildId DiffId iprevId type imethod ) map(e =gt eswap()getOrElse(null)) map(bs =gt bsfilter(x =gt x)toJS())
const buildProject = (branch sha) =gt queueUnzipWwwOnS3(sha) chain(() =gt isReleaseOrMainBranch(branch)) fold(() =gt _noop () =gt generateReport(sha) chain(queueDiffsForTileBuildsAndDeps) chain(() =gt getHeadCommit(sha) fold(() =gt Taskof(null) head =gt makeVrtDeployment(head sha) chain(() =gt createPrApp(head sha)))) fork(consoleerror
consolelog))
const vrtReport = (sha email platforms) =gt rejectFinishedPlatformOptions(platforms) chain(plats =gt platsmap(gatherScreenshots)) chain(shots =gt fromNullable(sha) fold(() =gt findLastRef() () =gt findBuild(sha)) chain(ref =gt renderReport(shots ref email))) fork(e =gt e r =gt r)
Harder to hack
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
Safer
const ProfileLink = user =gtlta href=`users$
uid`gtunameltagt
const Header = str =gt lth1gtNow Viewing strlth1gt
Component a -gt JSX
a JSXf
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
AssignmentLoops
CallbacksSide EffectsBranching
Errors
Loops
mapfilter
reduce
const range = (i count) =gt unfold(x =gt if(x lt= count) [x x+1] i)
range(510) [ 5 6 7 8 9 10 ]
const alphabet = () =gt unfold(x =gt if(x lt 26) [StringfromCharCode(x+65) x+1] 0)
alphabet() [ABCDEFGHIJKLMNOPQRSTUVWXYZ]
AssignmentLoops
CallbacksSide EffectsBranching
Errors
CallbacksSide Effects
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
contrivedEx2()fork(e =gt consoleerror(e) r =gt consolelog(success))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))fork(e =gt consoleerror(e)
r =gt consolelog(r))
AssignmentLoops
CallbacksSide EffectsBranching
Errors
BranchingErrors
EitherOr
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
leftOrRightfold(e =gt `we had an error $e` s =gt stoUpperCase())
Right(hair brown) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Right(five 2))
Right(10)
Left(ignored) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Left(five 2))
Left(ignored)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
Claim
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
AssignmentLoops
CallbacksSide EffectsBranching
Errors
const depObjs = b =gt List(bdeps)flatMap(next =gt findDependencyByProject(nextProjectname bpreviousdeps) fold(x =gt x found =gt makeArgs(next found)))
const mapBuildsAndDepsForDiffQueue = (builds) =gt List(builds) filter(b =gt bprevious) flatMap(b =gt makeArgs(b bprevious)concat(depObjs(b))) filter(b =gt b) toJS()
const filterExistingDiffs = (items) =gt List(items)traverse(Taskof (i) =gt find(Diff BuildId ibuildId DiffId iprevId type imethod ) map(e =gt eswap()getOrElse(null)) map(bs =gt bsfilter(x =gt x)toJS())
const buildProject = (branch sha) =gt queueUnzipWwwOnS3(sha) chain(() =gt isReleaseOrMainBranch(branch)) fold(() =gt _noop () =gt generateReport(sha) chain(queueDiffsForTileBuildsAndDeps) chain(() =gt getHeadCommit(sha) fold(() =gt Taskof(null) head =gt makeVrtDeployment(head sha) chain(() =gt createPrApp(head sha)))) fork(consoleerror
consolelog))
const vrtReport = (sha email platforms) =gt rejectFinishedPlatformOptions(platforms) chain(plats =gt platsmap(gatherScreenshots)) chain(shots =gt fromNullable(sha) fold(() =gt findLastRef() () =gt findBuild(sha)) chain(ref =gt renderReport(shots ref email))) fork(e =gt e r =gt r)
Harder to hack
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
Safer
const ProfileLink = user =gtlta href=`users$
uid`gtunameltagt
const Header = str =gt lth1gtNow Viewing strlth1gt
Component a -gt JSX
a JSXf
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
Loops
mapfilter
reduce
const range = (i count) =gt unfold(x =gt if(x lt= count) [x x+1] i)
range(510) [ 5 6 7 8 9 10 ]
const alphabet = () =gt unfold(x =gt if(x lt 26) [StringfromCharCode(x+65) x+1] 0)
alphabet() [ABCDEFGHIJKLMNOPQRSTUVWXYZ]
AssignmentLoops
CallbacksSide EffectsBranching
Errors
CallbacksSide Effects
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
contrivedEx2()fork(e =gt consoleerror(e) r =gt consolelog(success))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))fork(e =gt consoleerror(e)
r =gt consolelog(r))
AssignmentLoops
CallbacksSide EffectsBranching
Errors
BranchingErrors
EitherOr
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
leftOrRightfold(e =gt `we had an error $e` s =gt stoUpperCase())
Right(hair brown) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Right(five 2))
Right(10)
Left(ignored) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Left(five 2))
Left(ignored)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
Claim
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
AssignmentLoops
CallbacksSide EffectsBranching
Errors
const depObjs = b =gt List(bdeps)flatMap(next =gt findDependencyByProject(nextProjectname bpreviousdeps) fold(x =gt x found =gt makeArgs(next found)))
const mapBuildsAndDepsForDiffQueue = (builds) =gt List(builds) filter(b =gt bprevious) flatMap(b =gt makeArgs(b bprevious)concat(depObjs(b))) filter(b =gt b) toJS()
const filterExistingDiffs = (items) =gt List(items)traverse(Taskof (i) =gt find(Diff BuildId ibuildId DiffId iprevId type imethod ) map(e =gt eswap()getOrElse(null)) map(bs =gt bsfilter(x =gt x)toJS())
const buildProject = (branch sha) =gt queueUnzipWwwOnS3(sha) chain(() =gt isReleaseOrMainBranch(branch)) fold(() =gt _noop () =gt generateReport(sha) chain(queueDiffsForTileBuildsAndDeps) chain(() =gt getHeadCommit(sha) fold(() =gt Taskof(null) head =gt makeVrtDeployment(head sha) chain(() =gt createPrApp(head sha)))) fork(consoleerror
consolelog))
const vrtReport = (sha email platforms) =gt rejectFinishedPlatformOptions(platforms) chain(plats =gt platsmap(gatherScreenshots)) chain(shots =gt fromNullable(sha) fold(() =gt findLastRef() () =gt findBuild(sha)) chain(ref =gt renderReport(shots ref email))) fork(e =gt e r =gt r)
Harder to hack
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
Safer
const ProfileLink = user =gtlta href=`users$
uid`gtunameltagt
const Header = str =gt lth1gtNow Viewing strlth1gt
Component a -gt JSX
a JSXf
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
mapfilter
reduce
const range = (i count) =gt unfold(x =gt if(x lt= count) [x x+1] i)
range(510) [ 5 6 7 8 9 10 ]
const alphabet = () =gt unfold(x =gt if(x lt 26) [StringfromCharCode(x+65) x+1] 0)
alphabet() [ABCDEFGHIJKLMNOPQRSTUVWXYZ]
AssignmentLoops
CallbacksSide EffectsBranching
Errors
CallbacksSide Effects
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
contrivedEx2()fork(e =gt consoleerror(e) r =gt consolelog(success))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))fork(e =gt consoleerror(e)
r =gt consolelog(r))
AssignmentLoops
CallbacksSide EffectsBranching
Errors
BranchingErrors
EitherOr
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
leftOrRightfold(e =gt `we had an error $e` s =gt stoUpperCase())
Right(hair brown) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Right(five 2))
Right(10)
Left(ignored) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Left(five 2))
Left(ignored)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
Claim
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
AssignmentLoops
CallbacksSide EffectsBranching
Errors
const depObjs = b =gt List(bdeps)flatMap(next =gt findDependencyByProject(nextProjectname bpreviousdeps) fold(x =gt x found =gt makeArgs(next found)))
const mapBuildsAndDepsForDiffQueue = (builds) =gt List(builds) filter(b =gt bprevious) flatMap(b =gt makeArgs(b bprevious)concat(depObjs(b))) filter(b =gt b) toJS()
const filterExistingDiffs = (items) =gt List(items)traverse(Taskof (i) =gt find(Diff BuildId ibuildId DiffId iprevId type imethod ) map(e =gt eswap()getOrElse(null)) map(bs =gt bsfilter(x =gt x)toJS())
const buildProject = (branch sha) =gt queueUnzipWwwOnS3(sha) chain(() =gt isReleaseOrMainBranch(branch)) fold(() =gt _noop () =gt generateReport(sha) chain(queueDiffsForTileBuildsAndDeps) chain(() =gt getHeadCommit(sha) fold(() =gt Taskof(null) head =gt makeVrtDeployment(head sha) chain(() =gt createPrApp(head sha)))) fork(consoleerror
consolelog))
const vrtReport = (sha email platforms) =gt rejectFinishedPlatformOptions(platforms) chain(plats =gt platsmap(gatherScreenshots)) chain(shots =gt fromNullable(sha) fold(() =gt findLastRef() () =gt findBuild(sha)) chain(ref =gt renderReport(shots ref email))) fork(e =gt e r =gt r)
Harder to hack
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
Safer
const ProfileLink = user =gtlta href=`users$
uid`gtunameltagt
const Header = str =gt lth1gtNow Viewing strlth1gt
Component a -gt JSX
a JSXf
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
const range = (i count) =gt unfold(x =gt if(x lt= count) [x x+1] i)
range(510) [ 5 6 7 8 9 10 ]
const alphabet = () =gt unfold(x =gt if(x lt 26) [StringfromCharCode(x+65) x+1] 0)
alphabet() [ABCDEFGHIJKLMNOPQRSTUVWXYZ]
AssignmentLoops
CallbacksSide EffectsBranching
Errors
CallbacksSide Effects
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
contrivedEx2()fork(e =gt consoleerror(e) r =gt consolelog(success))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))fork(e =gt consoleerror(e)
r =gt consolelog(r))
AssignmentLoops
CallbacksSide EffectsBranching
Errors
BranchingErrors
EitherOr
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
leftOrRightfold(e =gt `we had an error $e` s =gt stoUpperCase())
Right(hair brown) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Right(five 2))
Right(10)
Left(ignored) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Left(five 2))
Left(ignored)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
Claim
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
AssignmentLoops
CallbacksSide EffectsBranching
Errors
const depObjs = b =gt List(bdeps)flatMap(next =gt findDependencyByProject(nextProjectname bpreviousdeps) fold(x =gt x found =gt makeArgs(next found)))
const mapBuildsAndDepsForDiffQueue = (builds) =gt List(builds) filter(b =gt bprevious) flatMap(b =gt makeArgs(b bprevious)concat(depObjs(b))) filter(b =gt b) toJS()
const filterExistingDiffs = (items) =gt List(items)traverse(Taskof (i) =gt find(Diff BuildId ibuildId DiffId iprevId type imethod ) map(e =gt eswap()getOrElse(null)) map(bs =gt bsfilter(x =gt x)toJS())
const buildProject = (branch sha) =gt queueUnzipWwwOnS3(sha) chain(() =gt isReleaseOrMainBranch(branch)) fold(() =gt _noop () =gt generateReport(sha) chain(queueDiffsForTileBuildsAndDeps) chain(() =gt getHeadCommit(sha) fold(() =gt Taskof(null) head =gt makeVrtDeployment(head sha) chain(() =gt createPrApp(head sha)))) fork(consoleerror
consolelog))
const vrtReport = (sha email platforms) =gt rejectFinishedPlatformOptions(platforms) chain(plats =gt platsmap(gatherScreenshots)) chain(shots =gt fromNullable(sha) fold(() =gt findLastRef() () =gt findBuild(sha)) chain(ref =gt renderReport(shots ref email))) fork(e =gt e r =gt r)
Harder to hack
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
Safer
const ProfileLink = user =gtlta href=`users$
uid`gtunameltagt
const Header = str =gt lth1gtNow Viewing strlth1gt
Component a -gt JSX
a JSXf
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
const alphabet = () =gt unfold(x =gt if(x lt 26) [StringfromCharCode(x+65) x+1] 0)
alphabet() [ABCDEFGHIJKLMNOPQRSTUVWXYZ]
AssignmentLoops
CallbacksSide EffectsBranching
Errors
CallbacksSide Effects
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
contrivedEx2()fork(e =gt consoleerror(e) r =gt consolelog(success))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))fork(e =gt consoleerror(e)
r =gt consolelog(r))
AssignmentLoops
CallbacksSide EffectsBranching
Errors
BranchingErrors
EitherOr
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
leftOrRightfold(e =gt `we had an error $e` s =gt stoUpperCase())
Right(hair brown) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Right(five 2))
Right(10)
Left(ignored) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Left(five 2))
Left(ignored)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
Claim
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
AssignmentLoops
CallbacksSide EffectsBranching
Errors
const depObjs = b =gt List(bdeps)flatMap(next =gt findDependencyByProject(nextProjectname bpreviousdeps) fold(x =gt x found =gt makeArgs(next found)))
const mapBuildsAndDepsForDiffQueue = (builds) =gt List(builds) filter(b =gt bprevious) flatMap(b =gt makeArgs(b bprevious)concat(depObjs(b))) filter(b =gt b) toJS()
const filterExistingDiffs = (items) =gt List(items)traverse(Taskof (i) =gt find(Diff BuildId ibuildId DiffId iprevId type imethod ) map(e =gt eswap()getOrElse(null)) map(bs =gt bsfilter(x =gt x)toJS())
const buildProject = (branch sha) =gt queueUnzipWwwOnS3(sha) chain(() =gt isReleaseOrMainBranch(branch)) fold(() =gt _noop () =gt generateReport(sha) chain(queueDiffsForTileBuildsAndDeps) chain(() =gt getHeadCommit(sha) fold(() =gt Taskof(null) head =gt makeVrtDeployment(head sha) chain(() =gt createPrApp(head sha)))) fork(consoleerror
consolelog))
const vrtReport = (sha email platforms) =gt rejectFinishedPlatformOptions(platforms) chain(plats =gt platsmap(gatherScreenshots)) chain(shots =gt fromNullable(sha) fold(() =gt findLastRef() () =gt findBuild(sha)) chain(ref =gt renderReport(shots ref email))) fork(e =gt e r =gt r)
Harder to hack
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
Safer
const ProfileLink = user =gtlta href=`users$
uid`gtunameltagt
const Header = str =gt lth1gtNow Viewing strlth1gt
Component a -gt JSX
a JSXf
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
AssignmentLoops
CallbacksSide EffectsBranching
Errors
CallbacksSide Effects
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
contrivedEx2()fork(e =gt consoleerror(e) r =gt consolelog(success))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))fork(e =gt consoleerror(e)
r =gt consolelog(r))
AssignmentLoops
CallbacksSide EffectsBranching
Errors
BranchingErrors
EitherOr
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
leftOrRightfold(e =gt `we had an error $e` s =gt stoUpperCase())
Right(hair brown) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Right(five 2))
Right(10)
Left(ignored) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Left(five 2))
Left(ignored)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
Claim
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
AssignmentLoops
CallbacksSide EffectsBranching
Errors
const depObjs = b =gt List(bdeps)flatMap(next =gt findDependencyByProject(nextProjectname bpreviousdeps) fold(x =gt x found =gt makeArgs(next found)))
const mapBuildsAndDepsForDiffQueue = (builds) =gt List(builds) filter(b =gt bprevious) flatMap(b =gt makeArgs(b bprevious)concat(depObjs(b))) filter(b =gt b) toJS()
const filterExistingDiffs = (items) =gt List(items)traverse(Taskof (i) =gt find(Diff BuildId ibuildId DiffId iprevId type imethod ) map(e =gt eswap()getOrElse(null)) map(bs =gt bsfilter(x =gt x)toJS())
const buildProject = (branch sha) =gt queueUnzipWwwOnS3(sha) chain(() =gt isReleaseOrMainBranch(branch)) fold(() =gt _noop () =gt generateReport(sha) chain(queueDiffsForTileBuildsAndDeps) chain(() =gt getHeadCommit(sha) fold(() =gt Taskof(null) head =gt makeVrtDeployment(head sha) chain(() =gt createPrApp(head sha)))) fork(consoleerror
consolelog))
const vrtReport = (sha email platforms) =gt rejectFinishedPlatformOptions(platforms) chain(plats =gt platsmap(gatherScreenshots)) chain(shots =gt fromNullable(sha) fold(() =gt findLastRef() () =gt findBuild(sha)) chain(ref =gt renderReport(shots ref email))) fork(e =gt e r =gt r)
Harder to hack
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
Safer
const ProfileLink = user =gtlta href=`users$
uid`gtunameltagt
const Header = str =gt lth1gtNow Viewing strlth1gt
Component a -gt JSX
a JSXf
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
CallbacksSide Effects
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
contrivedEx2()fork(e =gt consoleerror(e) r =gt consolelog(success))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))fork(e =gt consoleerror(e)
r =gt consolelog(r))
AssignmentLoops
CallbacksSide EffectsBranching
Errors
BranchingErrors
EitherOr
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
leftOrRightfold(e =gt `we had an error $e` s =gt stoUpperCase())
Right(hair brown) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Right(five 2))
Right(10)
Left(ignored) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Left(five 2))
Left(ignored)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
Claim
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
AssignmentLoops
CallbacksSide EffectsBranching
Errors
const depObjs = b =gt List(bdeps)flatMap(next =gt findDependencyByProject(nextProjectname bpreviousdeps) fold(x =gt x found =gt makeArgs(next found)))
const mapBuildsAndDepsForDiffQueue = (builds) =gt List(builds) filter(b =gt bprevious) flatMap(b =gt makeArgs(b bprevious)concat(depObjs(b))) filter(b =gt b) toJS()
const filterExistingDiffs = (items) =gt List(items)traverse(Taskof (i) =gt find(Diff BuildId ibuildId DiffId iprevId type imethod ) map(e =gt eswap()getOrElse(null)) map(bs =gt bsfilter(x =gt x)toJS())
const buildProject = (branch sha) =gt queueUnzipWwwOnS3(sha) chain(() =gt isReleaseOrMainBranch(branch)) fold(() =gt _noop () =gt generateReport(sha) chain(queueDiffsForTileBuildsAndDeps) chain(() =gt getHeadCommit(sha) fold(() =gt Taskof(null) head =gt makeVrtDeployment(head sha) chain(() =gt createPrApp(head sha)))) fork(consoleerror
consolelog))
const vrtReport = (sha email platforms) =gt rejectFinishedPlatformOptions(platforms) chain(plats =gt platsmap(gatherScreenshots)) chain(shots =gt fromNullable(sha) fold(() =gt findLastRef() () =gt findBuild(sha)) chain(ref =gt renderReport(shots ref email))) fork(e =gt e r =gt r)
Harder to hack
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
Safer
const ProfileLink = user =gtlta href=`users$
uid`gtunameltagt
const Header = str =gt lth1gtNow Viewing strlth1gt
Component a -gt JSX
a JSXf
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
contrivedEx2()fork(e =gt consoleerror(e) r =gt consolelog(success))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))fork(e =gt consoleerror(e)
r =gt consolelog(r))
AssignmentLoops
CallbacksSide EffectsBranching
Errors
BranchingErrors
EitherOr
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
leftOrRightfold(e =gt `we had an error $e` s =gt stoUpperCase())
Right(hair brown) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Right(five 2))
Right(10)
Left(ignored) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Left(five 2))
Left(ignored)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
Claim
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
AssignmentLoops
CallbacksSide EffectsBranching
Errors
const depObjs = b =gt List(bdeps)flatMap(next =gt findDependencyByProject(nextProjectname bpreviousdeps) fold(x =gt x found =gt makeArgs(next found)))
const mapBuildsAndDepsForDiffQueue = (builds) =gt List(builds) filter(b =gt bprevious) flatMap(b =gt makeArgs(b bprevious)concat(depObjs(b))) filter(b =gt b) toJS()
const filterExistingDiffs = (items) =gt List(items)traverse(Taskof (i) =gt find(Diff BuildId ibuildId DiffId iprevId type imethod ) map(e =gt eswap()getOrElse(null)) map(bs =gt bsfilter(x =gt x)toJS())
const buildProject = (branch sha) =gt queueUnzipWwwOnS3(sha) chain(() =gt isReleaseOrMainBranch(branch)) fold(() =gt _noop () =gt generateReport(sha) chain(queueDiffsForTileBuildsAndDeps) chain(() =gt getHeadCommit(sha) fold(() =gt Taskof(null) head =gt makeVrtDeployment(head sha) chain(() =gt createPrApp(head sha)))) fork(consoleerror
consolelog))
const vrtReport = (sha email platforms) =gt rejectFinishedPlatformOptions(platforms) chain(plats =gt platsmap(gatherScreenshots)) chain(shots =gt fromNullable(sha) fold(() =gt findLastRef() () =gt findBuild(sha)) chain(ref =gt renderReport(shots ref email))) fork(e =gt e r =gt r)
Harder to hack
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
Safer
const ProfileLink = user =gtlta href=`users$
uid`gtunameltagt
const Header = str =gt lth1gtNow Viewing strlth1gt
Component a -gt JSX
a JSXf
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
contrivedEx2()fork(e =gt consoleerror(e) r =gt consolelog(success))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))fork(e =gt consoleerror(e)
r =gt consolelog(r))
AssignmentLoops
CallbacksSide EffectsBranching
Errors
BranchingErrors
EitherOr
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
leftOrRightfold(e =gt `we had an error $e` s =gt stoUpperCase())
Right(hair brown) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Right(five 2))
Right(10)
Left(ignored) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Left(five 2))
Left(ignored)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
Claim
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
AssignmentLoops
CallbacksSide EffectsBranching
Errors
const depObjs = b =gt List(bdeps)flatMap(next =gt findDependencyByProject(nextProjectname bpreviousdeps) fold(x =gt x found =gt makeArgs(next found)))
const mapBuildsAndDepsForDiffQueue = (builds) =gt List(builds) filter(b =gt bprevious) flatMap(b =gt makeArgs(b bprevious)concat(depObjs(b))) filter(b =gt b) toJS()
const filterExistingDiffs = (items) =gt List(items)traverse(Taskof (i) =gt find(Diff BuildId ibuildId DiffId iprevId type imethod ) map(e =gt eswap()getOrElse(null)) map(bs =gt bsfilter(x =gt x)toJS())
const buildProject = (branch sha) =gt queueUnzipWwwOnS3(sha) chain(() =gt isReleaseOrMainBranch(branch)) fold(() =gt _noop () =gt generateReport(sha) chain(queueDiffsForTileBuildsAndDeps) chain(() =gt getHeadCommit(sha) fold(() =gt Taskof(null) head =gt makeVrtDeployment(head sha) chain(() =gt createPrApp(head sha)))) fork(consoleerror
consolelog))
const vrtReport = (sha email platforms) =gt rejectFinishedPlatformOptions(platforms) chain(plats =gt platsmap(gatherScreenshots)) chain(shots =gt fromNullable(sha) fold(() =gt findLastRef() () =gt findBuild(sha)) chain(ref =gt renderReport(shots ref email))) fork(e =gt e r =gt r)
Harder to hack
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
Safer
const ProfileLink = user =gtlta href=`users$
uid`gtunameltagt
const Header = str =gt lth1gtNow Viewing strlth1gt
Component a -gt JSX
a JSXf
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
Promise(6)then(six =gt six 2) Promise(3)
Promise(6)then(six =gt Promise(six 2)) Promise(3)
Promise(6)map(six =gt six 2) Promise(3)
Promise(6)chain(six =gt Promise(six 2)) Promise(3)
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
contrivedEx2()fork(e =gt consoleerror(e) r =gt consolelog(success))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))fork(e =gt consoleerror(e)
r =gt consolelog(r))
AssignmentLoops
CallbacksSide EffectsBranching
Errors
BranchingErrors
EitherOr
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
leftOrRightfold(e =gt `we had an error $e` s =gt stoUpperCase())
Right(hair brown) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Right(five 2))
Right(10)
Left(ignored) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Left(five 2))
Left(ignored)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
Claim
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
AssignmentLoops
CallbacksSide EffectsBranching
Errors
const depObjs = b =gt List(bdeps)flatMap(next =gt findDependencyByProject(nextProjectname bpreviousdeps) fold(x =gt x found =gt makeArgs(next found)))
const mapBuildsAndDepsForDiffQueue = (builds) =gt List(builds) filter(b =gt bprevious) flatMap(b =gt makeArgs(b bprevious)concat(depObjs(b))) filter(b =gt b) toJS()
const filterExistingDiffs = (items) =gt List(items)traverse(Taskof (i) =gt find(Diff BuildId ibuildId DiffId iprevId type imethod ) map(e =gt eswap()getOrElse(null)) map(bs =gt bsfilter(x =gt x)toJS())
const buildProject = (branch sha) =gt queueUnzipWwwOnS3(sha) chain(() =gt isReleaseOrMainBranch(branch)) fold(() =gt _noop () =gt generateReport(sha) chain(queueDiffsForTileBuildsAndDeps) chain(() =gt getHeadCommit(sha) fold(() =gt Taskof(null) head =gt makeVrtDeployment(head sha) chain(() =gt createPrApp(head sha)))) fork(consoleerror
consolelog))
const vrtReport = (sha email platforms) =gt rejectFinishedPlatformOptions(platforms) chain(plats =gt platsmap(gatherScreenshots)) chain(shots =gt fromNullable(sha) fold(() =gt findLastRef() () =gt findBuild(sha)) chain(ref =gt renderReport(shots ref email))) fork(e =gt e r =gt r)
Harder to hack
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
Safer
const ProfileLink = user =gtlta href=`users$
uid`gtunameltagt
const Header = str =gt lth1gtNow Viewing strlth1gt
Component a -gt JSX
a JSXf
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
contrivedEx2()fork(e =gt consoleerror(e) r =gt consolelog(success))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))fork(e =gt consoleerror(e)
r =gt consolelog(r))
AssignmentLoops
CallbacksSide EffectsBranching
Errors
BranchingErrors
EitherOr
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
leftOrRightfold(e =gt `we had an error $e` s =gt stoUpperCase())
Right(hair brown) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Right(five 2))
Right(10)
Left(ignored) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Left(five 2))
Left(ignored)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
Claim
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
AssignmentLoops
CallbacksSide EffectsBranching
Errors
const depObjs = b =gt List(bdeps)flatMap(next =gt findDependencyByProject(nextProjectname bpreviousdeps) fold(x =gt x found =gt makeArgs(next found)))
const mapBuildsAndDepsForDiffQueue = (builds) =gt List(builds) filter(b =gt bprevious) flatMap(b =gt makeArgs(b bprevious)concat(depObjs(b))) filter(b =gt b) toJS()
const filterExistingDiffs = (items) =gt List(items)traverse(Taskof (i) =gt find(Diff BuildId ibuildId DiffId iprevId type imethod ) map(e =gt eswap()getOrElse(null)) map(bs =gt bsfilter(x =gt x)toJS())
const buildProject = (branch sha) =gt queueUnzipWwwOnS3(sha) chain(() =gt isReleaseOrMainBranch(branch)) fold(() =gt _noop () =gt generateReport(sha) chain(queueDiffsForTileBuildsAndDeps) chain(() =gt getHeadCommit(sha) fold(() =gt Taskof(null) head =gt makeVrtDeployment(head sha) chain(() =gt createPrApp(head sha)))) fork(consoleerror
consolelog))
const vrtReport = (sha email platforms) =gt rejectFinishedPlatformOptions(platforms) chain(plats =gt platsmap(gatherScreenshots)) chain(shots =gt fromNullable(sha) fold(() =gt findLastRef() () =gt findBuild(sha)) chain(ref =gt renderReport(shots ref email))) fork(e =gt e r =gt r)
Harder to hack
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
Safer
const ProfileLink = user =gtlta href=`users$
uid`gtunameltagt
const Header = str =gt lth1gtNow Viewing strlth1gt
Component a -gt JSX
a JSXf
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
contrivedEx2()fork(e =gt consoleerror(e) r =gt consolelog(success))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))fork(e =gt consoleerror(e)
r =gt consolelog(r))
AssignmentLoops
CallbacksSide EffectsBranching
Errors
BranchingErrors
EitherOr
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
leftOrRightfold(e =gt `we had an error $e` s =gt stoUpperCase())
Right(hair brown) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Right(five 2))
Right(10)
Left(ignored) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Left(five 2))
Left(ignored)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
Claim
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
AssignmentLoops
CallbacksSide EffectsBranching
Errors
const depObjs = b =gt List(bdeps)flatMap(next =gt findDependencyByProject(nextProjectname bpreviousdeps) fold(x =gt x found =gt makeArgs(next found)))
const mapBuildsAndDepsForDiffQueue = (builds) =gt List(builds) filter(b =gt bprevious) flatMap(b =gt makeArgs(b bprevious)concat(depObjs(b))) filter(b =gt b) toJS()
const filterExistingDiffs = (items) =gt List(items)traverse(Taskof (i) =gt find(Diff BuildId ibuildId DiffId iprevId type imethod ) map(e =gt eswap()getOrElse(null)) map(bs =gt bsfilter(x =gt x)toJS())
const buildProject = (branch sha) =gt queueUnzipWwwOnS3(sha) chain(() =gt isReleaseOrMainBranch(branch)) fold(() =gt _noop () =gt generateReport(sha) chain(queueDiffsForTileBuildsAndDeps) chain(() =gt getHeadCommit(sha) fold(() =gt Taskof(null) head =gt makeVrtDeployment(head sha) chain(() =gt createPrApp(head sha)))) fork(consoleerror
consolelog))
const vrtReport = (sha email platforms) =gt rejectFinishedPlatformOptions(platforms) chain(plats =gt platsmap(gatherScreenshots)) chain(shots =gt fromNullable(sha) fold(() =gt findLastRef() () =gt findBuild(sha)) chain(ref =gt renderReport(shots ref email))) fork(e =gt e r =gt r)
Harder to hack
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
Safer
const ProfileLink = user =gtlta href=`users$
uid`gtunameltagt
const Header = str =gt lth1gtNow Viewing strlth1gt
Component a -gt JSX
a JSXf
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
const contrivedEx2 = () =gt fsreadFile(cfgjson utf-8 (err contents) =gt if(err) throw err const newContents = contentsreplace(8g 6) fswriteFile(cfg1json newContents (err _) =gt if(err) throw err consolelog(success) ) )
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
contrivedEx2()fork(e =gt consoleerror(e) r =gt consolelog(success))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))fork(e =gt consoleerror(e)
r =gt consolelog(r))
AssignmentLoops
CallbacksSide EffectsBranching
Errors
BranchingErrors
EitherOr
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
leftOrRightfold(e =gt `we had an error $e` s =gt stoUpperCase())
Right(hair brown) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Right(five 2))
Right(10)
Left(ignored) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Left(five 2))
Left(ignored)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
Claim
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
AssignmentLoops
CallbacksSide EffectsBranching
Errors
const depObjs = b =gt List(bdeps)flatMap(next =gt findDependencyByProject(nextProjectname bpreviousdeps) fold(x =gt x found =gt makeArgs(next found)))
const mapBuildsAndDepsForDiffQueue = (builds) =gt List(builds) filter(b =gt bprevious) flatMap(b =gt makeArgs(b bprevious)concat(depObjs(b))) filter(b =gt b) toJS()
const filterExistingDiffs = (items) =gt List(items)traverse(Taskof (i) =gt find(Diff BuildId ibuildId DiffId iprevId type imethod ) map(e =gt eswap()getOrElse(null)) map(bs =gt bsfilter(x =gt x)toJS())
const buildProject = (branch sha) =gt queueUnzipWwwOnS3(sha) chain(() =gt isReleaseOrMainBranch(branch)) fold(() =gt _noop () =gt generateReport(sha) chain(queueDiffsForTileBuildsAndDeps) chain(() =gt getHeadCommit(sha) fold(() =gt Taskof(null) head =gt makeVrtDeployment(head sha) chain(() =gt createPrApp(head sha)))) fork(consoleerror
consolelog))
const vrtReport = (sha email platforms) =gt rejectFinishedPlatformOptions(platforms) chain(plats =gt platsmap(gatherScreenshots)) chain(shots =gt fromNullable(sha) fold(() =gt findLastRef() () =gt findBuild(sha)) chain(ref =gt renderReport(shots ref email))) fork(e =gt e r =gt r)
Harder to hack
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
Safer
const ProfileLink = user =gtlta href=`users$
uid`gtunameltagt
const Header = str =gt lth1gtNow Viewing strlth1gt
Component a -gt JSX
a JSXf
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
const readFile = futurize(fsreadFile)const writeFile = futurize(fswriteFile)
const contrivedEx2 = () =gt readFile(cfgjson utf-8) map(contents =gt contentsreplace(8g 6)) chain(replaced =gt writeFile(cfg1json replaced))
contrivedEx2()fork(e =gt consoleerror(e) r =gt consolelog(success))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))fork(e =gt consoleerror(e)
r =gt consolelog(r))
AssignmentLoops
CallbacksSide EffectsBranching
Errors
BranchingErrors
EitherOr
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
leftOrRightfold(e =gt `we had an error $e` s =gt stoUpperCase())
Right(hair brown) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Right(five 2))
Right(10)
Left(ignored) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Left(five 2))
Left(ignored)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
Claim
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
AssignmentLoops
CallbacksSide EffectsBranching
Errors
const depObjs = b =gt List(bdeps)flatMap(next =gt findDependencyByProject(nextProjectname bpreviousdeps) fold(x =gt x found =gt makeArgs(next found)))
const mapBuildsAndDepsForDiffQueue = (builds) =gt List(builds) filter(b =gt bprevious) flatMap(b =gt makeArgs(b bprevious)concat(depObjs(b))) filter(b =gt b) toJS()
const filterExistingDiffs = (items) =gt List(items)traverse(Taskof (i) =gt find(Diff BuildId ibuildId DiffId iprevId type imethod ) map(e =gt eswap()getOrElse(null)) map(bs =gt bsfilter(x =gt x)toJS())
const buildProject = (branch sha) =gt queueUnzipWwwOnS3(sha) chain(() =gt isReleaseOrMainBranch(branch)) fold(() =gt _noop () =gt generateReport(sha) chain(queueDiffsForTileBuildsAndDeps) chain(() =gt getHeadCommit(sha) fold(() =gt Taskof(null) head =gt makeVrtDeployment(head sha) chain(() =gt createPrApp(head sha)))) fork(consoleerror
consolelog))
const vrtReport = (sha email platforms) =gt rejectFinishedPlatformOptions(platforms) chain(plats =gt platsmap(gatherScreenshots)) chain(shots =gt fromNullable(sha) fold(() =gt findLastRef() () =gt findBuild(sha)) chain(ref =gt renderReport(shots ref email))) fork(e =gt e r =gt r)
Harder to hack
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
Safer
const ProfileLink = user =gtlta href=`users$
uid`gtunameltagt
const Header = str =gt lth1gtNow Viewing strlth1gt
Component a -gt JSX
a JSXf
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))fork(e =gt consoleerror(e)
r =gt consolelog(r))
AssignmentLoops
CallbacksSide EffectsBranching
Errors
BranchingErrors
EitherOr
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
leftOrRightfold(e =gt `we had an error $e` s =gt stoUpperCase())
Right(hair brown) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Right(five 2))
Right(10)
Left(ignored) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Left(five 2))
Left(ignored)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
Claim
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
AssignmentLoops
CallbacksSide EffectsBranching
Errors
const depObjs = b =gt List(bdeps)flatMap(next =gt findDependencyByProject(nextProjectname bpreviousdeps) fold(x =gt x found =gt makeArgs(next found)))
const mapBuildsAndDepsForDiffQueue = (builds) =gt List(builds) filter(b =gt bprevious) flatMap(b =gt makeArgs(b bprevious)concat(depObjs(b))) filter(b =gt b) toJS()
const filterExistingDiffs = (items) =gt List(items)traverse(Taskof (i) =gt find(Diff BuildId ibuildId DiffId iprevId type imethod ) map(e =gt eswap()getOrElse(null)) map(bs =gt bsfilter(x =gt x)toJS())
const buildProject = (branch sha) =gt queueUnzipWwwOnS3(sha) chain(() =gt isReleaseOrMainBranch(branch)) fold(() =gt _noop () =gt generateReport(sha) chain(queueDiffsForTileBuildsAndDeps) chain(() =gt getHeadCommit(sha) fold(() =gt Taskof(null) head =gt makeVrtDeployment(head sha) chain(() =gt createPrApp(head sha)))) fork(consoleerror
consolelog))
const vrtReport = (sha email platforms) =gt rejectFinishedPlatformOptions(platforms) chain(plats =gt platsmap(gatherScreenshots)) chain(shots =gt fromNullable(sha) fold(() =gt findLastRef() () =gt findBuild(sha)) chain(ref =gt renderReport(shots ref email))) fork(e =gt e r =gt r)
Harder to hack
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
Safer
const ProfileLink = user =gtlta href=`users$
uid`gtunameltagt
const Header = str =gt lth1gtNow Viewing strlth1gt
Component a -gt JSX
a JSXf
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))fork(e =gt consoleerror(e)
r =gt consolelog(r))
AssignmentLoops
CallbacksSide EffectsBranching
Errors
BranchingErrors
EitherOr
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
leftOrRightfold(e =gt `we had an error $e` s =gt stoUpperCase())
Right(hair brown) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Right(five 2))
Right(10)
Left(ignored) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Left(five 2))
Left(ignored)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
Claim
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
AssignmentLoops
CallbacksSide EffectsBranching
Errors
const depObjs = b =gt List(bdeps)flatMap(next =gt findDependencyByProject(nextProjectname bpreviousdeps) fold(x =gt x found =gt makeArgs(next found)))
const mapBuildsAndDepsForDiffQueue = (builds) =gt List(builds) filter(b =gt bprevious) flatMap(b =gt makeArgs(b bprevious)concat(depObjs(b))) filter(b =gt b) toJS()
const filterExistingDiffs = (items) =gt List(items)traverse(Taskof (i) =gt find(Diff BuildId ibuildId DiffId iprevId type imethod ) map(e =gt eswap()getOrElse(null)) map(bs =gt bsfilter(x =gt x)toJS())
const buildProject = (branch sha) =gt queueUnzipWwwOnS3(sha) chain(() =gt isReleaseOrMainBranch(branch)) fold(() =gt _noop () =gt generateReport(sha) chain(queueDiffsForTileBuildsAndDeps) chain(() =gt getHeadCommit(sha) fold(() =gt Taskof(null) head =gt makeVrtDeployment(head sha) chain(() =gt createPrApp(head sha)))) fork(consoleerror
consolelog))
const vrtReport = (sha email platforms) =gt rejectFinishedPlatformOptions(platforms) chain(plats =gt platsmap(gatherScreenshots)) chain(shots =gt fromNullable(sha) fold(() =gt findLastRef() () =gt findBuild(sha)) chain(ref =gt renderReport(shots ref email))) fork(e =gt e r =gt r)
Harder to hack
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
Safer
const ProfileLink = user =gtlta href=`users$
uid`gtunameltagt
const Header = str =gt lth1gtNow Viewing strlth1gt
Component a -gt JSX
a JSXf
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
const lib = username =gt getTweets(username) map(ts =gt truncateTo130(ts)) chain(ts =gt writeFile(tweetsjson ts))
lib(lsquodrbooleanrsquo)chain(f =gt saveToS3(f))fork(e =gt consoleerror(e)
r =gt consolelog(r))
AssignmentLoops
CallbacksSide EffectsBranching
Errors
BranchingErrors
EitherOr
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
leftOrRightfold(e =gt `we had an error $e` s =gt stoUpperCase())
Right(hair brown) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Right(five 2))
Right(10)
Left(ignored) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Left(five 2))
Left(ignored)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
Claim
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
AssignmentLoops
CallbacksSide EffectsBranching
Errors
const depObjs = b =gt List(bdeps)flatMap(next =gt findDependencyByProject(nextProjectname bpreviousdeps) fold(x =gt x found =gt makeArgs(next found)))
const mapBuildsAndDepsForDiffQueue = (builds) =gt List(builds) filter(b =gt bprevious) flatMap(b =gt makeArgs(b bprevious)concat(depObjs(b))) filter(b =gt b) toJS()
const filterExistingDiffs = (items) =gt List(items)traverse(Taskof (i) =gt find(Diff BuildId ibuildId DiffId iprevId type imethod ) map(e =gt eswap()getOrElse(null)) map(bs =gt bsfilter(x =gt x)toJS())
const buildProject = (branch sha) =gt queueUnzipWwwOnS3(sha) chain(() =gt isReleaseOrMainBranch(branch)) fold(() =gt _noop () =gt generateReport(sha) chain(queueDiffsForTileBuildsAndDeps) chain(() =gt getHeadCommit(sha) fold(() =gt Taskof(null) head =gt makeVrtDeployment(head sha) chain(() =gt createPrApp(head sha)))) fork(consoleerror
consolelog))
const vrtReport = (sha email platforms) =gt rejectFinishedPlatformOptions(platforms) chain(plats =gt platsmap(gatherScreenshots)) chain(shots =gt fromNullable(sha) fold(() =gt findLastRef() () =gt findBuild(sha)) chain(ref =gt renderReport(shots ref email))) fork(e =gt e r =gt r)
Harder to hack
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
Safer
const ProfileLink = user =gtlta href=`users$
uid`gtunameltagt
const Header = str =gt lth1gtNow Viewing strlth1gt
Component a -gt JSX
a JSXf
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
AssignmentLoops
CallbacksSide EffectsBranching
Errors
BranchingErrors
EitherOr
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
leftOrRightfold(e =gt `we had an error $e` s =gt stoUpperCase())
Right(hair brown) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Right(five 2))
Right(10)
Left(ignored) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Left(five 2))
Left(ignored)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
Claim
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
AssignmentLoops
CallbacksSide EffectsBranching
Errors
const depObjs = b =gt List(bdeps)flatMap(next =gt findDependencyByProject(nextProjectname bpreviousdeps) fold(x =gt x found =gt makeArgs(next found)))
const mapBuildsAndDepsForDiffQueue = (builds) =gt List(builds) filter(b =gt bprevious) flatMap(b =gt makeArgs(b bprevious)concat(depObjs(b))) filter(b =gt b) toJS()
const filterExistingDiffs = (items) =gt List(items)traverse(Taskof (i) =gt find(Diff BuildId ibuildId DiffId iprevId type imethod ) map(e =gt eswap()getOrElse(null)) map(bs =gt bsfilter(x =gt x)toJS())
const buildProject = (branch sha) =gt queueUnzipWwwOnS3(sha) chain(() =gt isReleaseOrMainBranch(branch)) fold(() =gt _noop () =gt generateReport(sha) chain(queueDiffsForTileBuildsAndDeps) chain(() =gt getHeadCommit(sha) fold(() =gt Taskof(null) head =gt makeVrtDeployment(head sha) chain(() =gt createPrApp(head sha)))) fork(consoleerror
consolelog))
const vrtReport = (sha email platforms) =gt rejectFinishedPlatformOptions(platforms) chain(plats =gt platsmap(gatherScreenshots)) chain(shots =gt fromNullable(sha) fold(() =gt findLastRef() () =gt findBuild(sha)) chain(ref =gt renderReport(shots ref email))) fork(e =gt e r =gt r)
Harder to hack
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
Safer
const ProfileLink = user =gtlta href=`users$
uid`gtunameltagt
const Header = str =gt lth1gtNow Viewing strlth1gt
Component a -gt JSX
a JSXf
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
BranchingErrors
EitherOr
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
leftOrRightfold(e =gt `we had an error $e` s =gt stoUpperCase())
Right(hair brown) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Right(five 2))
Right(10)
Left(ignored) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Left(five 2))
Left(ignored)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
Claim
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
AssignmentLoops
CallbacksSide EffectsBranching
Errors
const depObjs = b =gt List(bdeps)flatMap(next =gt findDependencyByProject(nextProjectname bpreviousdeps) fold(x =gt x found =gt makeArgs(next found)))
const mapBuildsAndDepsForDiffQueue = (builds) =gt List(builds) filter(b =gt bprevious) flatMap(b =gt makeArgs(b bprevious)concat(depObjs(b))) filter(b =gt b) toJS()
const filterExistingDiffs = (items) =gt List(items)traverse(Taskof (i) =gt find(Diff BuildId ibuildId DiffId iprevId type imethod ) map(e =gt eswap()getOrElse(null)) map(bs =gt bsfilter(x =gt x)toJS())
const buildProject = (branch sha) =gt queueUnzipWwwOnS3(sha) chain(() =gt isReleaseOrMainBranch(branch)) fold(() =gt _noop () =gt generateReport(sha) chain(queueDiffsForTileBuildsAndDeps) chain(() =gt getHeadCommit(sha) fold(() =gt Taskof(null) head =gt makeVrtDeployment(head sha) chain(() =gt createPrApp(head sha)))) fork(consoleerror
consolelog))
const vrtReport = (sha email platforms) =gt rejectFinishedPlatformOptions(platforms) chain(plats =gt platsmap(gatherScreenshots)) chain(shots =gt fromNullable(sha) fold(() =gt findLastRef() () =gt findBuild(sha)) chain(ref =gt renderReport(shots ref email))) fork(e =gt e r =gt r)
Harder to hack
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
Safer
const ProfileLink = user =gtlta href=`users$
uid`gtunameltagt
const Header = str =gt lth1gtNow Viewing strlth1gt
Component a -gt JSX
a JSXf
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
EitherOr
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
leftOrRightfold(e =gt `we had an error $e` s =gt stoUpperCase())
Right(hair brown) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Right(five 2))
Right(10)
Left(ignored) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Left(five 2))
Left(ignored)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
Claim
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
AssignmentLoops
CallbacksSide EffectsBranching
Errors
const depObjs = b =gt List(bdeps)flatMap(next =gt findDependencyByProject(nextProjectname bpreviousdeps) fold(x =gt x found =gt makeArgs(next found)))
const mapBuildsAndDepsForDiffQueue = (builds) =gt List(builds) filter(b =gt bprevious) flatMap(b =gt makeArgs(b bprevious)concat(depObjs(b))) filter(b =gt b) toJS()
const filterExistingDiffs = (items) =gt List(items)traverse(Taskof (i) =gt find(Diff BuildId ibuildId DiffId iprevId type imethod ) map(e =gt eswap()getOrElse(null)) map(bs =gt bsfilter(x =gt x)toJS())
const buildProject = (branch sha) =gt queueUnzipWwwOnS3(sha) chain(() =gt isReleaseOrMainBranch(branch)) fold(() =gt _noop () =gt generateReport(sha) chain(queueDiffsForTileBuildsAndDeps) chain(() =gt getHeadCommit(sha) fold(() =gt Taskof(null) head =gt makeVrtDeployment(head sha) chain(() =gt createPrApp(head sha)))) fork(consoleerror
consolelog))
const vrtReport = (sha email platforms) =gt rejectFinishedPlatformOptions(platforms) chain(plats =gt platsmap(gatherScreenshots)) chain(shots =gt fromNullable(sha) fold(() =gt findLastRef() () =gt findBuild(sha)) chain(ref =gt renderReport(shots ref email))) fork(e =gt e r =gt r)
Harder to hack
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
Safer
const ProfileLink = user =gtlta href=`users$
uid`gtunameltagt
const Header = str =gt lth1gtNow Viewing strlth1gt
Component a -gt JSX
a JSXf
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
leftOrRightfold(e =gt `we had an error $e` s =gt stoUpperCase())
Right(hair brown) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Right(five 2))
Right(10)
Left(ignored) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Left(five 2))
Left(ignored)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
Claim
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
AssignmentLoops
CallbacksSide EffectsBranching
Errors
const depObjs = b =gt List(bdeps)flatMap(next =gt findDependencyByProject(nextProjectname bpreviousdeps) fold(x =gt x found =gt makeArgs(next found)))
const mapBuildsAndDepsForDiffQueue = (builds) =gt List(builds) filter(b =gt bprevious) flatMap(b =gt makeArgs(b bprevious)concat(depObjs(b))) filter(b =gt b) toJS()
const filterExistingDiffs = (items) =gt List(items)traverse(Taskof (i) =gt find(Diff BuildId ibuildId DiffId iprevId type imethod ) map(e =gt eswap()getOrElse(null)) map(bs =gt bsfilter(x =gt x)toJS())
const buildProject = (branch sha) =gt queueUnzipWwwOnS3(sha) chain(() =gt isReleaseOrMainBranch(branch)) fold(() =gt _noop () =gt generateReport(sha) chain(queueDiffsForTileBuildsAndDeps) chain(() =gt getHeadCommit(sha) fold(() =gt Taskof(null) head =gt makeVrtDeployment(head sha) chain(() =gt createPrApp(head sha)))) fork(consoleerror
consolelog))
const vrtReport = (sha email platforms) =gt rejectFinishedPlatformOptions(platforms) chain(plats =gt platsmap(gatherScreenshots)) chain(shots =gt fromNullable(sha) fold(() =gt findLastRef() () =gt findBuild(sha)) chain(ref =gt renderReport(shots ref email))) fork(e =gt e r =gt r)
Harder to hack
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
Safer
const ProfileLink = user =gtlta href=`users$
uid`gtunameltagt
const Header = str =gt lth1gtNow Viewing strlth1gt
Component a -gt JSX
a JSXf
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
leftOrRightfold(e =gt `we had an error $e` s =gt stoUpperCase())
Right(hair brown) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Right(five 2))
Right(10)
Left(ignored) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Left(five 2))
Left(ignored)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
Claim
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
AssignmentLoops
CallbacksSide EffectsBranching
Errors
const depObjs = b =gt List(bdeps)flatMap(next =gt findDependencyByProject(nextProjectname bpreviousdeps) fold(x =gt x found =gt makeArgs(next found)))
const mapBuildsAndDepsForDiffQueue = (builds) =gt List(builds) filter(b =gt bprevious) flatMap(b =gt makeArgs(b bprevious)concat(depObjs(b))) filter(b =gt b) toJS()
const filterExistingDiffs = (items) =gt List(items)traverse(Taskof (i) =gt find(Diff BuildId ibuildId DiffId iprevId type imethod ) map(e =gt eswap()getOrElse(null)) map(bs =gt bsfilter(x =gt x)toJS())
const buildProject = (branch sha) =gt queueUnzipWwwOnS3(sha) chain(() =gt isReleaseOrMainBranch(branch)) fold(() =gt _noop () =gt generateReport(sha) chain(queueDiffsForTileBuildsAndDeps) chain(() =gt getHeadCommit(sha) fold(() =gt Taskof(null) head =gt makeVrtDeployment(head sha) chain(() =gt createPrApp(head sha)))) fork(consoleerror
consolelog))
const vrtReport = (sha email platforms) =gt rejectFinishedPlatformOptions(platforms) chain(plats =gt platsmap(gatherScreenshots)) chain(shots =gt fromNullable(sha) fold(() =gt findLastRef() () =gt findBuild(sha)) chain(ref =gt renderReport(shots ref email))) fork(e =gt e r =gt r)
Harder to hack
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
Safer
const ProfileLink = user =gtlta href=`users$
uid`gtunameltagt
const Header = str =gt lth1gtNow Viewing strlth1gt
Component a -gt JSX
a JSXf
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
Left(no ducks ()fold(e =gt `we had an error $e` s =gt stoUpperCase()) we had an error no ducks (
Right(ducks)fold(e =gt `we had an error $e` s =gt stoUpperCase())DUCKS
leftOrRightfold(e =gt `we had an error $e` s =gt stoUpperCase())
Right(hair brown) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Right(five 2))
Right(10)
Left(ignored) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Left(five 2))
Left(ignored)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
Claim
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
AssignmentLoops
CallbacksSide EffectsBranching
Errors
const depObjs = b =gt List(bdeps)flatMap(next =gt findDependencyByProject(nextProjectname bpreviousdeps) fold(x =gt x found =gt makeArgs(next found)))
const mapBuildsAndDepsForDiffQueue = (builds) =gt List(builds) filter(b =gt bprevious) flatMap(b =gt makeArgs(b bprevious)concat(depObjs(b))) filter(b =gt b) toJS()
const filterExistingDiffs = (items) =gt List(items)traverse(Taskof (i) =gt find(Diff BuildId ibuildId DiffId iprevId type imethod ) map(e =gt eswap()getOrElse(null)) map(bs =gt bsfilter(x =gt x)toJS())
const buildProject = (branch sha) =gt queueUnzipWwwOnS3(sha) chain(() =gt isReleaseOrMainBranch(branch)) fold(() =gt _noop () =gt generateReport(sha) chain(queueDiffsForTileBuildsAndDeps) chain(() =gt getHeadCommit(sha) fold(() =gt Taskof(null) head =gt makeVrtDeployment(head sha) chain(() =gt createPrApp(head sha)))) fork(consoleerror
consolelog))
const vrtReport = (sha email platforms) =gt rejectFinishedPlatformOptions(platforms) chain(plats =gt platsmap(gatherScreenshots)) chain(shots =gt fromNullable(sha) fold(() =gt findLastRef() () =gt findBuild(sha)) chain(ref =gt renderReport(shots ref email))) fork(e =gt e r =gt r)
Harder to hack
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
Safer
const ProfileLink = user =gtlta href=`users$
uid`gtunameltagt
const Header = str =gt lth1gtNow Viewing strlth1gt
Component a -gt JSX
a JSXf
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
leftOrRightfold(e =gt `we had an error $e` s =gt stoUpperCase())
Right(hair brown) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Right(five 2))
Right(10)
Left(ignored) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Left(five 2))
Left(ignored)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
Claim
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
AssignmentLoops
CallbacksSide EffectsBranching
Errors
const depObjs = b =gt List(bdeps)flatMap(next =gt findDependencyByProject(nextProjectname bpreviousdeps) fold(x =gt x found =gt makeArgs(next found)))
const mapBuildsAndDepsForDiffQueue = (builds) =gt List(builds) filter(b =gt bprevious) flatMap(b =gt makeArgs(b bprevious)concat(depObjs(b))) filter(b =gt b) toJS()
const filterExistingDiffs = (items) =gt List(items)traverse(Taskof (i) =gt find(Diff BuildId ibuildId DiffId iprevId type imethod ) map(e =gt eswap()getOrElse(null)) map(bs =gt bsfilter(x =gt x)toJS())
const buildProject = (branch sha) =gt queueUnzipWwwOnS3(sha) chain(() =gt isReleaseOrMainBranch(branch)) fold(() =gt _noop () =gt generateReport(sha) chain(queueDiffsForTileBuildsAndDeps) chain(() =gt getHeadCommit(sha) fold(() =gt Taskof(null) head =gt makeVrtDeployment(head sha) chain(() =gt createPrApp(head sha)))) fork(consoleerror
consolelog))
const vrtReport = (sha email platforms) =gt rejectFinishedPlatformOptions(platforms) chain(plats =gt platsmap(gatherScreenshots)) chain(shots =gt fromNullable(sha) fold(() =gt findLastRef() () =gt findBuild(sha)) chain(ref =gt renderReport(shots ref email))) fork(e =gt e r =gt r)
Harder to hack
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
Safer
const ProfileLink = user =gtlta href=`users$
uid`gtunameltagt
const Header = str =gt lth1gtNow Viewing strlth1gt
Component a -gt JSX
a JSXf
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
Right(hair brown) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Right(five 2))
Right(10)
Left(ignored) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Left(five 2))
Left(ignored)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
Claim
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
AssignmentLoops
CallbacksSide EffectsBranching
Errors
const depObjs = b =gt List(bdeps)flatMap(next =gt findDependencyByProject(nextProjectname bpreviousdeps) fold(x =gt x found =gt makeArgs(next found)))
const mapBuildsAndDepsForDiffQueue = (builds) =gt List(builds) filter(b =gt bprevious) flatMap(b =gt makeArgs(b bprevious)concat(depObjs(b))) filter(b =gt b) toJS()
const filterExistingDiffs = (items) =gt List(items)traverse(Taskof (i) =gt find(Diff BuildId ibuildId DiffId iprevId type imethod ) map(e =gt eswap()getOrElse(null)) map(bs =gt bsfilter(x =gt x)toJS())
const buildProject = (branch sha) =gt queueUnzipWwwOnS3(sha) chain(() =gt isReleaseOrMainBranch(branch)) fold(() =gt _noop () =gt generateReport(sha) chain(queueDiffsForTileBuildsAndDeps) chain(() =gt getHeadCommit(sha) fold(() =gt Taskof(null) head =gt makeVrtDeployment(head sha) chain(() =gt createPrApp(head sha)))) fork(consoleerror
consolelog))
const vrtReport = (sha email platforms) =gt rejectFinishedPlatformOptions(platforms) chain(plats =gt platsmap(gatherScreenshots)) chain(shots =gt fromNullable(sha) fold(() =gt findLastRef() () =gt findBuild(sha)) chain(ref =gt renderReport(shots ref email))) fork(e =gt e r =gt r)
Harder to hack
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
Safer
const ProfileLink = user =gtlta href=`users$
uid`gtunameltagt
const Header = str =gt lth1gtNow Viewing strlth1gt
Component a -gt JSX
a JSXf
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
Left(ignored) map(obj =gt objhair) map(brown =gt brownlength) chain(five =gt Left(five 2))
Left(ignored)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
Claim
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
AssignmentLoops
CallbacksSide EffectsBranching
Errors
const depObjs = b =gt List(bdeps)flatMap(next =gt findDependencyByProject(nextProjectname bpreviousdeps) fold(x =gt x found =gt makeArgs(next found)))
const mapBuildsAndDepsForDiffQueue = (builds) =gt List(builds) filter(b =gt bprevious) flatMap(b =gt makeArgs(b bprevious)concat(depObjs(b))) filter(b =gt b) toJS()
const filterExistingDiffs = (items) =gt List(items)traverse(Taskof (i) =gt find(Diff BuildId ibuildId DiffId iprevId type imethod ) map(e =gt eswap()getOrElse(null)) map(bs =gt bsfilter(x =gt x)toJS())
const buildProject = (branch sha) =gt queueUnzipWwwOnS3(sha) chain(() =gt isReleaseOrMainBranch(branch)) fold(() =gt _noop () =gt generateReport(sha) chain(queueDiffsForTileBuildsAndDeps) chain(() =gt getHeadCommit(sha) fold(() =gt Taskof(null) head =gt makeVrtDeployment(head sha) chain(() =gt createPrApp(head sha)))) fork(consoleerror
consolelog))
const vrtReport = (sha email platforms) =gt rejectFinishedPlatformOptions(platforms) chain(plats =gt platsmap(gatherScreenshots)) chain(shots =gt fromNullable(sha) fold(() =gt findLastRef() () =gt findBuild(sha)) chain(ref =gt renderReport(shots ref email))) fork(e =gt e r =gt r)
Harder to hack
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
Safer
const ProfileLink = user =gtlta href=`users$
uid`gtunameltagt
const Header = str =gt lth1gtNow Viewing strlth1gt
Component a -gt JSX
a JSXf
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
Claim
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
AssignmentLoops
CallbacksSide EffectsBranching
Errors
const depObjs = b =gt List(bdeps)flatMap(next =gt findDependencyByProject(nextProjectname bpreviousdeps) fold(x =gt x found =gt makeArgs(next found)))
const mapBuildsAndDepsForDiffQueue = (builds) =gt List(builds) filter(b =gt bprevious) flatMap(b =gt makeArgs(b bprevious)concat(depObjs(b))) filter(b =gt b) toJS()
const filterExistingDiffs = (items) =gt List(items)traverse(Taskof (i) =gt find(Diff BuildId ibuildId DiffId iprevId type imethod ) map(e =gt eswap()getOrElse(null)) map(bs =gt bsfilter(x =gt x)toJS())
const buildProject = (branch sha) =gt queueUnzipWwwOnS3(sha) chain(() =gt isReleaseOrMainBranch(branch)) fold(() =gt _noop () =gt generateReport(sha) chain(queueDiffsForTileBuildsAndDeps) chain(() =gt getHeadCommit(sha) fold(() =gt Taskof(null) head =gt makeVrtDeployment(head sha) chain(() =gt createPrApp(head sha)))) fork(consoleerror
consolelog))
const vrtReport = (sha email platforms) =gt rejectFinishedPlatformOptions(platforms) chain(plats =gt platsmap(gatherScreenshots)) chain(shots =gt fromNullable(sha) fold(() =gt findLastRef() () =gt findBuild(sha)) chain(ref =gt renderReport(shots ref email))) fork(e =gt e r =gt r)
Harder to hack
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
Safer
const ProfileLink = user =gtlta href=`users$
uid`gtunameltagt
const Header = str =gt lth1gtNow Viewing strlth1gt
Component a -gt JSX
a JSXf
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
Claim
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
AssignmentLoops
CallbacksSide EffectsBranching
Errors
const depObjs = b =gt List(bdeps)flatMap(next =gt findDependencyByProject(nextProjectname bpreviousdeps) fold(x =gt x found =gt makeArgs(next found)))
const mapBuildsAndDepsForDiffQueue = (builds) =gt List(builds) filter(b =gt bprevious) flatMap(b =gt makeArgs(b bprevious)concat(depObjs(b))) filter(b =gt b) toJS()
const filterExistingDiffs = (items) =gt List(items)traverse(Taskof (i) =gt find(Diff BuildId ibuildId DiffId iprevId type imethod ) map(e =gt eswap()getOrElse(null)) map(bs =gt bsfilter(x =gt x)toJS())
const buildProject = (branch sha) =gt queueUnzipWwwOnS3(sha) chain(() =gt isReleaseOrMainBranch(branch)) fold(() =gt _noop () =gt generateReport(sha) chain(queueDiffsForTileBuildsAndDeps) chain(() =gt getHeadCommit(sha) fold(() =gt Taskof(null) head =gt makeVrtDeployment(head sha) chain(() =gt createPrApp(head sha)))) fork(consoleerror
consolelog))
const vrtReport = (sha email platforms) =gt rejectFinishedPlatformOptions(platforms) chain(plats =gt platsmap(gatherScreenshots)) chain(shots =gt fromNullable(sha) fold(() =gt findLastRef() () =gt findBuild(sha)) chain(ref =gt renderReport(shots ref email))) fork(e =gt e r =gt r)
Harder to hack
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
Safer
const ProfileLink = user =gtlta href=`users$
uid`gtunameltagt
const Header = str =gt lth1gtNow Viewing strlth1gt
Component a -gt JSX
a JSXf
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
const getConfig = () =gt try return fsreadFileSync(cfgjson) catch(e) return null const contrivedEx3 = () =gt const cfg = getConfig() if(cfg) const parsed = JSONparse(cfg) return parsedport else return 3000
Claim
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
AssignmentLoops
CallbacksSide EffectsBranching
Errors
const depObjs = b =gt List(bdeps)flatMap(next =gt findDependencyByProject(nextProjectname bpreviousdeps) fold(x =gt x found =gt makeArgs(next found)))
const mapBuildsAndDepsForDiffQueue = (builds) =gt List(builds) filter(b =gt bprevious) flatMap(b =gt makeArgs(b bprevious)concat(depObjs(b))) filter(b =gt b) toJS()
const filterExistingDiffs = (items) =gt List(items)traverse(Taskof (i) =gt find(Diff BuildId ibuildId DiffId iprevId type imethod ) map(e =gt eswap()getOrElse(null)) map(bs =gt bsfilter(x =gt x)toJS())
const buildProject = (branch sha) =gt queueUnzipWwwOnS3(sha) chain(() =gt isReleaseOrMainBranch(branch)) fold(() =gt _noop () =gt generateReport(sha) chain(queueDiffsForTileBuildsAndDeps) chain(() =gt getHeadCommit(sha) fold(() =gt Taskof(null) head =gt makeVrtDeployment(head sha) chain(() =gt createPrApp(head sha)))) fork(consoleerror
consolelog))
const vrtReport = (sha email platforms) =gt rejectFinishedPlatformOptions(platforms) chain(plats =gt platsmap(gatherScreenshots)) chain(shots =gt fromNullable(sha) fold(() =gt findLastRef() () =gt findBuild(sha)) chain(ref =gt renderReport(shots ref email))) fork(e =gt e r =gt r)
Harder to hack
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
Safer
const ProfileLink = user =gtlta href=`users$
uid`gtunameltagt
const Header = str =gt lth1gtNow Viewing strlth1gt
Component a -gt JSX
a JSXf
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
Claim
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
AssignmentLoops
CallbacksSide EffectsBranching
Errors
const depObjs = b =gt List(bdeps)flatMap(next =gt findDependencyByProject(nextProjectname bpreviousdeps) fold(x =gt x found =gt makeArgs(next found)))
const mapBuildsAndDepsForDiffQueue = (builds) =gt List(builds) filter(b =gt bprevious) flatMap(b =gt makeArgs(b bprevious)concat(depObjs(b))) filter(b =gt b) toJS()
const filterExistingDiffs = (items) =gt List(items)traverse(Taskof (i) =gt find(Diff BuildId ibuildId DiffId iprevId type imethod ) map(e =gt eswap()getOrElse(null)) map(bs =gt bsfilter(x =gt x)toJS())
const buildProject = (branch sha) =gt queueUnzipWwwOnS3(sha) chain(() =gt isReleaseOrMainBranch(branch)) fold(() =gt _noop () =gt generateReport(sha) chain(queueDiffsForTileBuildsAndDeps) chain(() =gt getHeadCommit(sha) fold(() =gt Taskof(null) head =gt makeVrtDeployment(head sha) chain(() =gt createPrApp(head sha)))) fork(consoleerror
consolelog))
const vrtReport = (sha email platforms) =gt rejectFinishedPlatformOptions(platforms) chain(plats =gt platsmap(gatherScreenshots)) chain(shots =gt fromNullable(sha) fold(() =gt findLastRef() () =gt findBuild(sha)) chain(ref =gt renderReport(shots ref email))) fork(e =gt e r =gt r)
Harder to hack
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
Safer
const ProfileLink = user =gtlta href=`users$
uid`gtunameltagt
const Header = str =gt lth1gtNow Viewing strlth1gt
Component a -gt JSX
a JSXf
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
AssignmentLoops
CallbacksSide EffectsBranching
Errors
const depObjs = b =gt List(bdeps)flatMap(next =gt findDependencyByProject(nextProjectname bpreviousdeps) fold(x =gt x found =gt makeArgs(next found)))
const mapBuildsAndDepsForDiffQueue = (builds) =gt List(builds) filter(b =gt bprevious) flatMap(b =gt makeArgs(b bprevious)concat(depObjs(b))) filter(b =gt b) toJS()
const filterExistingDiffs = (items) =gt List(items)traverse(Taskof (i) =gt find(Diff BuildId ibuildId DiffId iprevId type imethod ) map(e =gt eswap()getOrElse(null)) map(bs =gt bsfilter(x =gt x)toJS())
const buildProject = (branch sha) =gt queueUnzipWwwOnS3(sha) chain(() =gt isReleaseOrMainBranch(branch)) fold(() =gt _noop () =gt generateReport(sha) chain(queueDiffsForTileBuildsAndDeps) chain(() =gt getHeadCommit(sha) fold(() =gt Taskof(null) head =gt makeVrtDeployment(head sha) chain(() =gt createPrApp(head sha)))) fork(consoleerror
consolelog))
const vrtReport = (sha email platforms) =gt rejectFinishedPlatformOptions(platforms) chain(plats =gt platsmap(gatherScreenshots)) chain(shots =gt fromNullable(sha) fold(() =gt findLastRef() () =gt findBuild(sha)) chain(ref =gt renderReport(shots ref email))) fork(e =gt e r =gt r)
Harder to hack
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
Safer
const ProfileLink = user =gtlta href=`users$
uid`gtunameltagt
const Header = str =gt lth1gtNow Viewing strlth1gt
Component a -gt JSX
a JSXf
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
AssignmentLoops
CallbacksSide EffectsBranching
Errors
const depObjs = b =gt List(bdeps)flatMap(next =gt findDependencyByProject(nextProjectname bpreviousdeps) fold(x =gt x found =gt makeArgs(next found)))
const mapBuildsAndDepsForDiffQueue = (builds) =gt List(builds) filter(b =gt bprevious) flatMap(b =gt makeArgs(b bprevious)concat(depObjs(b))) filter(b =gt b) toJS()
const filterExistingDiffs = (items) =gt List(items)traverse(Taskof (i) =gt find(Diff BuildId ibuildId DiffId iprevId type imethod ) map(e =gt eswap()getOrElse(null)) map(bs =gt bsfilter(x =gt x)toJS())
const buildProject = (branch sha) =gt queueUnzipWwwOnS3(sha) chain(() =gt isReleaseOrMainBranch(branch)) fold(() =gt _noop () =gt generateReport(sha) chain(queueDiffsForTileBuildsAndDeps) chain(() =gt getHeadCommit(sha) fold(() =gt Taskof(null) head =gt makeVrtDeployment(head sha) chain(() =gt createPrApp(head sha)))) fork(consoleerror
consolelog))
const vrtReport = (sha email platforms) =gt rejectFinishedPlatformOptions(platforms) chain(plats =gt platsmap(gatherScreenshots)) chain(shots =gt fromNullable(sha) fold(() =gt findLastRef() () =gt findBuild(sha)) chain(ref =gt renderReport(shots ref email))) fork(e =gt e r =gt r)
Harder to hack
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
Safer
const ProfileLink = user =gtlta href=`users$
uid`gtunameltagt
const Header = str =gt lth1gtNow Viewing strlth1gt
Component a -gt JSX
a JSXf
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
const contrivedEx4 = user =gt const address = useraddress if(address) const zip = addressmatch((d5)$i) if(zip) const city = cityByZip(zip)
if(city) return city else return cant find city return cant find city
const contrivedEx4 = user =gt fromNullable(useraddress) chain(a =gt fromNullable(amatch((d5)$i))) chain(zip =gt fromNullable(cityByZip(zip))) fold(() =gt cant find city city =gt city)
AssignmentLoops
CallbacksSide EffectsBranching
Errors
const depObjs = b =gt List(bdeps)flatMap(next =gt findDependencyByProject(nextProjectname bpreviousdeps) fold(x =gt x found =gt makeArgs(next found)))
const mapBuildsAndDepsForDiffQueue = (builds) =gt List(builds) filter(b =gt bprevious) flatMap(b =gt makeArgs(b bprevious)concat(depObjs(b))) filter(b =gt b) toJS()
const filterExistingDiffs = (items) =gt List(items)traverse(Taskof (i) =gt find(Diff BuildId ibuildId DiffId iprevId type imethod ) map(e =gt eswap()getOrElse(null)) map(bs =gt bsfilter(x =gt x)toJS())
const buildProject = (branch sha) =gt queueUnzipWwwOnS3(sha) chain(() =gt isReleaseOrMainBranch(branch)) fold(() =gt _noop () =gt generateReport(sha) chain(queueDiffsForTileBuildsAndDeps) chain(() =gt getHeadCommit(sha) fold(() =gt Taskof(null) head =gt makeVrtDeployment(head sha) chain(() =gt createPrApp(head sha)))) fork(consoleerror
consolelog))
const vrtReport = (sha email platforms) =gt rejectFinishedPlatformOptions(platforms) chain(plats =gt platsmap(gatherScreenshots)) chain(shots =gt fromNullable(sha) fold(() =gt findLastRef() () =gt findBuild(sha)) chain(ref =gt renderReport(shots ref email))) fork(e =gt e r =gt r)
Harder to hack
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
Safer
const ProfileLink = user =gtlta href=`users$
uid`gtunameltagt
const Header = str =gt lth1gtNow Viewing strlth1gt
Component a -gt JSX
a JSXf
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
AssignmentLoops
CallbacksSide EffectsBranching
Errors
const depObjs = b =gt List(bdeps)flatMap(next =gt findDependencyByProject(nextProjectname bpreviousdeps) fold(x =gt x found =gt makeArgs(next found)))
const mapBuildsAndDepsForDiffQueue = (builds) =gt List(builds) filter(b =gt bprevious) flatMap(b =gt makeArgs(b bprevious)concat(depObjs(b))) filter(b =gt b) toJS()
const filterExistingDiffs = (items) =gt List(items)traverse(Taskof (i) =gt find(Diff BuildId ibuildId DiffId iprevId type imethod ) map(e =gt eswap()getOrElse(null)) map(bs =gt bsfilter(x =gt x)toJS())
const buildProject = (branch sha) =gt queueUnzipWwwOnS3(sha) chain(() =gt isReleaseOrMainBranch(branch)) fold(() =gt _noop () =gt generateReport(sha) chain(queueDiffsForTileBuildsAndDeps) chain(() =gt getHeadCommit(sha) fold(() =gt Taskof(null) head =gt makeVrtDeployment(head sha) chain(() =gt createPrApp(head sha)))) fork(consoleerror
consolelog))
const vrtReport = (sha email platforms) =gt rejectFinishedPlatformOptions(platforms) chain(plats =gt platsmap(gatherScreenshots)) chain(shots =gt fromNullable(sha) fold(() =gt findLastRef() () =gt findBuild(sha)) chain(ref =gt renderReport(shots ref email))) fork(e =gt e r =gt r)
Harder to hack
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
Safer
const ProfileLink = user =gtlta href=`users$
uid`gtunameltagt
const Header = str =gt lth1gtNow Viewing strlth1gt
Component a -gt JSX
a JSXf
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
const depObjs = b =gt List(bdeps)flatMap(next =gt findDependencyByProject(nextProjectname bpreviousdeps) fold(x =gt x found =gt makeArgs(next found)))
const mapBuildsAndDepsForDiffQueue = (builds) =gt List(builds) filter(b =gt bprevious) flatMap(b =gt makeArgs(b bprevious)concat(depObjs(b))) filter(b =gt b) toJS()
const filterExistingDiffs = (items) =gt List(items)traverse(Taskof (i) =gt find(Diff BuildId ibuildId DiffId iprevId type imethod ) map(e =gt eswap()getOrElse(null)) map(bs =gt bsfilter(x =gt x)toJS())
const buildProject = (branch sha) =gt queueUnzipWwwOnS3(sha) chain(() =gt isReleaseOrMainBranch(branch)) fold(() =gt _noop () =gt generateReport(sha) chain(queueDiffsForTileBuildsAndDeps) chain(() =gt getHeadCommit(sha) fold(() =gt Taskof(null) head =gt makeVrtDeployment(head sha) chain(() =gt createPrApp(head sha)))) fork(consoleerror
consolelog))
const vrtReport = (sha email platforms) =gt rejectFinishedPlatformOptions(platforms) chain(plats =gt platsmap(gatherScreenshots)) chain(shots =gt fromNullable(sha) fold(() =gt findLastRef() () =gt findBuild(sha)) chain(ref =gt renderReport(shots ref email))) fork(e =gt e r =gt r)
Harder to hack
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
Safer
const ProfileLink = user =gtlta href=`users$
uid`gtunameltagt
const Header = str =gt lth1gtNow Viewing strlth1gt
Component a -gt JSX
a JSXf
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
const buildProject = (branch sha) =gt queueUnzipWwwOnS3(sha) chain(() =gt isReleaseOrMainBranch(branch)) fold(() =gt _noop () =gt generateReport(sha) chain(queueDiffsForTileBuildsAndDeps) chain(() =gt getHeadCommit(sha) fold(() =gt Taskof(null) head =gt makeVrtDeployment(head sha) chain(() =gt createPrApp(head sha)))) fork(consoleerror
consolelog))
const vrtReport = (sha email platforms) =gt rejectFinishedPlatformOptions(platforms) chain(plats =gt platsmap(gatherScreenshots)) chain(shots =gt fromNullable(sha) fold(() =gt findLastRef() () =gt findBuild(sha)) chain(ref =gt renderReport(shots ref email))) fork(e =gt e r =gt r)
Harder to hack
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
Safer
const ProfileLink = user =gtlta href=`users$
uid`gtunameltagt
const Header = str =gt lth1gtNow Viewing strlth1gt
Component a -gt JSX
a JSXf
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
const vrtReport = (sha email platforms) =gt rejectFinishedPlatformOptions(platforms) chain(plats =gt platsmap(gatherScreenshots)) chain(shots =gt fromNullable(sha) fold(() =gt findLastRef() () =gt findBuild(sha)) chain(ref =gt renderReport(shots ref email))) fork(e =gt e r =gt r)
Harder to hack
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
Safer
const ProfileLink = user =gtlta href=`users$
uid`gtunameltagt
const Header = str =gt lth1gtNow Viewing strlth1gt
Component a -gt JSX
a JSXf
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
Harder to hack
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
Safer
const ProfileLink = user =gtlta href=`users$
uid`gtunameltagt
const Header = str =gt lth1gtNow Viewing strlth1gt
Component a -gt JSX
a JSXf
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
const getConfig = () =gt Eithertry(fsreadFileSync)(cfgjson)
const contrivedEx3 = () =gt getConfig() map(JSONparse) fold(e =gt 3000 c =gt cport)
Safer
const ProfileLink = user =gtlta href=`users$
uid`gtunameltagt
const Header = str =gt lth1gtNow Viewing strlth1gt
Component a -gt JSX
a JSXf
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
Safer
const ProfileLink = user =gtlta href=`users$
uid`gtunameltagt
const Header = str =gt lth1gtNow Viewing strlth1gt
Component a -gt JSX
a JSXf
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
const ProfileLink = user =gtlta href=`users$
uid`gtunameltagt
const Header = str =gt lth1gtNow Viewing strlth1gt
Component a -gt JSX
a JSXf
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
Component a -gt JSX
a JSXf
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
a JSXf
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
a JSXf
bg
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
a JSXf
bg
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
a JSXf
bg
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Title = Comp(Heading)contramap(s =gt spageName)
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
const Title = Comp(Heading)contramap(s =gt spageName)
Titlefold( pageName lsquoHome currentUser id 2 name Chris Harrisonrsquo )
lth1gtNow Viewing Homelth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))))
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
const Comp = g =gt( fold g contramap f =gt Comp(x =gt g(f(x))) concat other =gt Comp(x =gt ltdivgtg(x) otherfold(x)ltdivgt))
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName)
const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
const ProfileLink = user =gtlta href=`users$uid`gtunameltagt)
const Heading = str =gt lth1gtNow Viewing strlth1gt
const Heading = Comp(Title)contramap(s =gt spageName) const Link = Comp(ProfileLink)contramap(s =gt scurrentUser)
const App = Headingconcat(Link)
Appfold( pageName lsquoHome currentUser name Chris Harrisonrsquo ) ltdivgt lth1gtNow Viewing Homelth1gt lta href=users22gtChris Harrisonltagt ltdivgt
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
Reducer (a b) -gt a
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
const r = Reducer((acc x) =gt accconcat(x)) contramap(x =gt `The number is $x`) map(x =gt x + )
[123]reduce(rfold ) The number is 1 The number is 2 The number is 3
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))))
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
const Reducer = g =gt( fold g contramap f =gt Reducer((acc x) =gt g(acc f(x))) map f =gt Reducer((acc x) =gt f(g(acc x))) concat o =gt Reducer((acc x) =gt ofold(g(acc x) x)))
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
const appReducer = Reducer((state action) =gt switch (actiontype) case set_visibility_filter return Objectassign( state visibilityFilter actionfilter ) default return state )
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
const todoReducer = Reducer((state action) =gt switch (actiontype) case new_todo const t = id 0 title actionpayloadtitle return Objectassign( state todos statetodosconcat(t) ) default return state )
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all
action))map(s =gt Objectassign( s lastUpdated Date()))
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
const todoApp =appReducerconcat(todoReducer)contramap(action =gt Objectassign(filter all action))map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
const todoApp =appReducercontramap(action =gt Objectassign(filter all action))concat(todoReducer)map(s =gt Objectassign( s lastUpdated Date()))
todoAppfold(visibilityFilter lsquocomplete type lsquoset_visibility_filter)
visibilityFilter all lastUpdated Sun Aug 21 2016 110448 GMT-0700 (PDT)
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
Hoc Component -gt Component
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
const Hoc = g =gt( fold g concat other =gt Hoc(x =gt g(otherfold(x))))
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
const hoc = Hoc(withReducer(lsquostate dispatch todoAppfold todos []))
const Todos = hocfold(( state dispatch ) =gt ltdivgt ltspangtFilter statevisibilityFilterltspangt ltulgt statetodosmap(t =gt ltligtttitleltligt) ltulgt ltbutton onClick=() =gt dispatch( type new_todo payload title New todo)gt Add Todo ltbuttongt ltbutton onClick=() =gt dispatch( type set_visibility_filter )gt Set Visibility ltbuttongt ltdivgt)
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
const App = Headingcontramap(s =gt spageName) concat(TodoComp) concat(Linkcontramap(s =gt scurrentUser)) fold( pageName Home currentUser id 2 name Boris )
ReactDOMrender(App documentgetElementById(body))
const TodoComp = Component(classToFn(Todos))
const Heading = Component(s =gt lth1gtNow Viewing slth1gt)
const Link = Component(u =gt lta href=`users$uid`gtunameltagt)
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
httpsjsfiddlenetcnsn8yk29
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
map =compose =
program construction
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
FunctorBoxof(20)map(x =gt x 2) Box(10)
Monad Boxof(true)chain(x =gt Boxof(x)) Box(false) Monoid Boxof(small)concat(Boxof(pox)) Box(smallpox)
Applicative Boxof(x =gt x + 1)ap(2) Box(3)
Traversable Boxof(3)traverse(Eitherof x =gt fromNullable(x)) Right(Box(3))
Natural transformation eitherToBox(fromNullable(null)) Box(null)
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
Professor Frisbyrsquos Composable JavaScript
drboolean
drboolean
drboolean
drboolean
drboolean