wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln...
Transcript of wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln...
![Page 1: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz](https://reader035.fdocuments.us/reader035/viewer/2022081522/5fb4cafdabd6f51d5367cfbc/html5/thumbnails/1.jpg)
production haskell
Reid Draper @reiddraper
wrangling the internet of things with haskell
![Page 2: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz](https://reader035.fdocuments.us/reader035/viewer/2022081522/5fb4cafdabd6f51d5367cfbc/html5/thumbnails/2.jpg)
production haskell
Reid Draper @reiddraper
![Page 3: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz](https://reader035.fdocuments.us/reader035/viewer/2022081522/5fb4cafdabd6f51d5367cfbc/html5/thumbnails/3.jpg)
production haskell today
![Page 4: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz](https://reader035.fdocuments.us/reader035/viewer/2022081522/5fb4cafdabd6f51d5367cfbc/html5/thumbnails/4.jpg)
production haskell at helium12 months in
![Page 5: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz](https://reader035.fdocuments.us/reader035/viewer/2022081522/5fb4cafdabd6f51d5367cfbc/html5/thumbnails/5.jpg)
lowest defect rate
![Page 6: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz](https://reader035.fdocuments.us/reader035/viewer/2022081522/5fb4cafdabd6f51d5367cfbc/html5/thumbnails/6.jpg)
easiest to refactorlowest defect rate
![Page 7: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz](https://reader035.fdocuments.us/reader035/viewer/2022081522/5fb4cafdabd6f51d5367cfbc/html5/thumbnails/7.jpg)
OSS libraries for everything*most enjoyable
easiest to refactorlowest defect rate
![Page 8: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz](https://reader035.fdocuments.us/reader035/viewer/2022081522/5fb4cafdabd6f51d5367cfbc/html5/thumbnails/8.jpg)
20k LOC
![Page 9: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz](https://reader035.fdocuments.us/reader035/viewer/2022081522/5fb4cafdabd6f51d5367cfbc/html5/thumbnails/9.jpg)
5 developers20k LOC
![Page 10: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz](https://reader035.fdocuments.us/reader035/viewer/2022081522/5fb4cafdabd6f51d5367cfbc/html5/thumbnails/10.jpg)
6 production services5 developers
20k LOC
![Page 11: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz](https://reader035.fdocuments.us/reader035/viewer/2022081522/5fb4cafdabd6f51d5367cfbc/html5/thumbnails/11.jpg)
build deploy monitor test develop
![Page 12: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz](https://reader035.fdocuments.us/reader035/viewer/2022081522/5fb4cafdabd6f51d5367cfbc/html5/thumbnails/12.jpg)
build deploy monitor test develop
![Page 13: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz](https://reader035.fdocuments.us/reader035/viewer/2022081522/5fb4cafdabd6f51d5367cfbc/html5/thumbnails/13.jpg)
cabal hell
![Page 14: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz](https://reader035.fdocuments.us/reader035/viewer/2022081522/5fb4cafdabd6f51d5367cfbc/html5/thumbnails/14.jpg)
cabal hell
![Page 15: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz](https://reader035.fdocuments.us/reader035/viewer/2022081522/5fb4cafdabd6f51d5367cfbc/html5/thumbnails/15.jpg)
stackhaskellstack.org
![Page 16: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz](https://reader035.fdocuments.us/reader035/viewer/2022081522/5fb4cafdabd6f51d5367cfbc/html5/thumbnails/16.jpg)
![Page 17: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz](https://reader035.fdocuments.us/reader035/viewer/2022081522/5fb4cafdabd6f51d5367cfbc/html5/thumbnails/17.jpg)
project specificsnapshot
ghc packages
![Page 18: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz](https://reader035.fdocuments.us/reader035/viewer/2022081522/5fb4cafdabd6f51d5367cfbc/html5/thumbnails/18.jpg)
![Page 19: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz](https://reader035.fdocuments.us/reader035/viewer/2022081522/5fb4cafdabd6f51d5367cfbc/html5/thumbnails/19.jpg)
2 seconds20k LOC
![Page 20: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz](https://reader035.fdocuments.us/reader035/viewer/2022081522/5fb4cafdabd6f51d5367cfbc/html5/thumbnails/20.jpg)
![Page 21: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz](https://reader035.fdocuments.us/reader035/viewer/2022081522/5fb4cafdabd6f51d5367cfbc/html5/thumbnails/21.jpg)
ordealgithub.com/reiddraper/ordeal
![Page 22: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz](https://reader035.fdocuments.us/reader035/viewer/2022081522/5fb4cafdabd6f51d5367cfbc/html5/thumbnails/22.jpg)
stack build self-contained
executable
![Page 23: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz](https://reader035.fdocuments.us/reader035/viewer/2022081522/5fb4cafdabd6f51d5367cfbc/html5/thumbnails/23.jpg)
build deploy monitor test develop
![Page 24: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz](https://reader035.fdocuments.us/reader035/viewer/2022081522/5fb4cafdabd6f51d5367cfbc/html5/thumbnails/24.jpg)
app!"" assets# !"" images# # %"" favicon.ico# !"" javascript# # %"" site.js# %"" stylesheet# %"" site.css%"" bin %"" app
![Page 25: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz](https://reader035.fdocuments.us/reader035/viewer/2022081522/5fb4cafdabd6f51d5367cfbc/html5/thumbnails/25.jpg)
restart appln -s app-370b347 currenttar -xzf app-370b347.tgz
![Page 26: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz](https://reader035.fdocuments.us/reader035/viewer/2022081522/5fb4cafdabd6f51d5367cfbc/html5/thumbnails/26.jpg)
restart appln -s app-83181ad current
![Page 27: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz](https://reader035.fdocuments.us/reader035/viewer/2022081522/5fb4cafdabd6f51d5367cfbc/html5/thumbnails/27.jpg)
60MB
![Page 28: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz](https://reader035.fdocuments.us/reader035/viewer/2022081522/5fb4cafdabd6f51d5367cfbc/html5/thumbnails/28.jpg)
![Page 29: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz](https://reader035.fdocuments.us/reader035/viewer/2022081522/5fb4cafdabd6f51d5367cfbc/html5/thumbnails/29.jpg)
build deploy monitor test develop
![Page 30: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz](https://reader035.fdocuments.us/reader035/viewer/2022081522/5fb4cafdabd6f51d5367cfbc/html5/thumbnails/30.jpg)
ekg
![Page 31: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz](https://reader035.fdocuments.us/reader035/viewer/2022081522/5fb4cafdabd6f51d5367cfbc/html5/thumbnails/31.jpg)
![Page 32: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz](https://reader035.fdocuments.us/reader035/viewer/2022081522/5fb4cafdabd6f51d5367cfbc/html5/thumbnails/32.jpg)
stdout file syslog
![Page 33: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz](https://reader035.fdocuments.us/reader035/viewer/2022081522/5fb4cafdabd6f51d5367cfbc/html5/thumbnails/33.jpg)
build deploy monitor test develop
![Page 34: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz](https://reader035.fdocuments.us/reader035/viewer/2022081522/5fb4cafdabd6f51d5367cfbc/html5/thumbnails/34.jpg)
QuickCheck
![Page 35: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz](https://reader035.fdocuments.us/reader035/viewer/2022081522/5fb4cafdabd6f51d5367cfbc/html5/thumbnails/35.jpg)
propEvent :: Event -> BoolpropEvent a = Just a == decode (encode a)
![Page 36: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz](https://reader035.fdocuments.us/reader035/viewer/2022081522/5fb4cafdabd6f51d5367cfbc/html5/thumbnails/36.jpg)
Event roundtrips in JSON: FAIL (0.04s) *** Failed! Falsifiable (after 1 test): Event {_severity = Error, _facility = Unspecified, _sampled = 1894-02-22 00:00:04.5986 UTC, _eventDetails = ElementDisconnect {_elementMAC = 8ec52584b2c82424}, _eventMessage = Nothing, _originator = http://www.ietf.org/rfc/rfc2396.txt, _reference = Just http://www.ietf.org/rfc/rfc2396.txt }
![Page 37: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz](https://reader035.fdocuments.us/reader035/viewer/2022081522/5fb4cafdabd6f51d5367cfbc/html5/thumbnails/37.jpg)
Event roundtrips in JSON: FAIL (0.04s) *** Failed! Falsifiable (after 1 test): Event {_severity = Error, _facility = Unspecified, _sampled = 1894-02-22 00:00:04.5986 UTC, _eventDetails = ElementDisconnect {_elementMAC = 8ec52584b2c82424}, _eventMessage = Nothing, _originator = http://www.ietf.org/rfc/rfc2396.txt, _reference = Just http://www.ietf.org/rfc/rfc2396.txt }
![Page 38: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz](https://reader035.fdocuments.us/reader035/viewer/2022081522/5fb4cafdabd6f51d5367cfbc/html5/thumbnails/38.jpg)
ghci> t1894-02-22 00:00:04.5986 UTCghci> Data.Aeson.encode t"\"1894-02-22T00:00:04.598Z\""
![Page 39: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz](https://reader035.fdocuments.us/reader035/viewer/2022081522/5fb4cafdabd6f51d5367cfbc/html5/thumbnails/39.jpg)
build deploy monitor test develop
![Page 40: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz](https://reader035.fdocuments.us/reader035/viewer/2022081522/5fb4cafdabd6f51d5367cfbc/html5/thumbnails/40.jpg)
postgresql-transactionalgithub.com/helium/postgresql-transactional
![Page 41: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz](https://reader035.fdocuments.us/reader035/viewer/2022081522/5fb4cafdabd6f51d5367cfbc/html5/thumbnails/41.jpg)
lookupUser emailAddress = queryFirst [emailAddress] [sql| SELECT id, email, name, timezone FROM user_account WHERE email = ? |]
![Page 42: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz](https://reader035.fdocuments.us/reader035/viewer/2022081522/5fb4cafdabd6f51d5367cfbc/html5/thumbnails/42.jpg)
foo
![Page 43: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz](https://reader035.fdocuments.us/reader035/viewer/2022081522/5fb4cafdabd6f51d5367cfbc/html5/thumbnails/43.jpg)
foo
bar
![Page 44: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz](https://reader035.fdocuments.us/reader035/viewer/2022081522/5fb4cafdabd6f51d5367cfbc/html5/thumbnails/44.jpg)
foo
bar
baz
![Page 45: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz](https://reader035.fdocuments.us/reader035/viewer/2022081522/5fb4cafdabd6f51d5367cfbc/html5/thumbnails/45.jpg)
foo
bar
baz
quz
![Page 46: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz](https://reader035.fdocuments.us/reader035/viewer/2022081522/5fb4cafdabd6f51d5367cfbc/html5/thumbnails/46.jpg)
foo
bar
baz
quz
buz
![Page 47: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz](https://reader035.fdocuments.us/reader035/viewer/2022081522/5fb4cafdabd6f51d5367cfbc/html5/thumbnails/47.jpg)
foo
bar
baz
quz
buz
fiz
![Page 48: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz](https://reader035.fdocuments.us/reader035/viewer/2022081522/5fb4cafdabd6f51d5367cfbc/html5/thumbnails/48.jpg)
BEGINBEGINCOMMITCOMMIT
![Page 49: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz](https://reader035.fdocuments.us/reader035/viewer/2022081522/5fb4cafdabd6f51d5367cfbc/html5/thumbnails/49.jpg)
BEGINBEGINCOMMITCOMMIT
![Page 50: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz](https://reader035.fdocuments.us/reader035/viewer/2022081522/5fb4cafdabd6f51d5367cfbc/html5/thumbnails/50.jpg)
BEGINBEGINCOMMITCOMMIT
![Page 51: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz](https://reader035.fdocuments.us/reader035/viewer/2022081522/5fb4cafdabd6f51d5367cfbc/html5/thumbnails/51.jpg)
WARNING: there is already a transaction in progressWARNING: there is no transaction in progress
![Page 52: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz](https://reader035.fdocuments.us/reader035/viewer/2022081522/5fb4cafdabd6f51d5367cfbc/html5/thumbnails/52.jpg)
foo
bar
baz
quz
buz
fiz
![Page 53: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz](https://reader035.fdocuments.us/reader035/viewer/2022081522/5fb4cafdabd6f51d5367cfbc/html5/thumbnails/53.jpg)
foo
bar
baz
quz
buz
fiz
![Page 54: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz](https://reader035.fdocuments.us/reader035/viewer/2022081522/5fb4cafdabd6f51d5367cfbc/html5/thumbnails/54.jpg)
foo
bar
baz
quz
buz
![Page 55: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz](https://reader035.fdocuments.us/reader035/viewer/2022081522/5fb4cafdabd6f51d5367cfbc/html5/thumbnails/55.jpg)
lookupUser :: Connection -> Text -> IO (Maybe User)lookupUser connection emailAddress = queryFirst [emailAddress] [sql| SELECT id, email, name, timezone FROM user_account WHERE email = ? |] connection
![Page 56: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz](https://reader035.fdocuments.us/reader035/viewer/2022081522/5fb4cafdabd6f51d5367cfbc/html5/thumbnails/56.jpg)
createUser :: Connection -> NewUser -> IO User
createOrganization :: Connection -> NewOrganization -> IO Organization
addUserToOrganization :: Connection -> User -> Organization -> IO ()
![Page 57: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz](https://reader035.fdocuments.us/reader035/viewer/2022081522/5fb4cafdabd6f51d5367cfbc/html5/thumbnails/57.jpg)
createUserAndOrganization :: Connection -> NewUser -> IO ()createUserAndOrganization connection newUser = withTransaction connection $ do let newOrganization = NewOrganization (newUser ^. name) user <- createUser connection newUser org <- createOrganization connection newOrganization addUserToOrganization connection user org
![Page 58: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz](https://reader035.fdocuments.us/reader035/viewer/2022081522/5fb4cafdabd6f51d5367cfbc/html5/thumbnails/58.jpg)
-- NOTE: you MUST wrap this in a transaction!!createUserAndOrganization :: Connection -> NewUser -> IO ()createUserAndOrganization connection newUser = do let newOrganization = NewOrganization (newUser ^. name) user <- createUser connection newUser org <- createOrganization connection newOrganization addUserToOrganization connection user org
![Page 59: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz](https://reader035.fdocuments.us/reader035/viewer/2022081522/5fb4cafdabd6f51d5367cfbc/html5/thumbnails/59.jpg)
withTransaction conn $ do createUserAndOrganization conn newUser somethingElse conn
![Page 60: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz](https://reader035.fdocuments.us/reader035/viewer/2022081522/5fb4cafdabd6f51d5367cfbc/html5/thumbnails/60.jpg)
types to the rescue
![Page 61: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz](https://reader035.fdocuments.us/reader035/viewer/2022081522/5fb4cafdabd6f51d5367cfbc/html5/thumbnails/61.jpg)
lookupUser :: Connection -> Text -> IO (Maybe User)lookupUser :: Text -> PGTransaction (Maybe User)
![Page 62: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz](https://reader035.fdocuments.us/reader035/viewer/2022081522/5fb4cafdabd6f51d5367cfbc/html5/thumbnails/62.jpg)
runPGTransaction :: PGTransaction a -> Postgres.Connection -> IO a
![Page 63: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz](https://reader035.fdocuments.us/reader035/viewer/2022081522/5fb4cafdabd6f51d5367cfbc/html5/thumbnails/63.jpg)
createUserAndOrganization :: NewUser -> PGTransaction ()createUserAndOrganization newUser = let newOrganization = NewOrganization (newUser ^. name) user <- createUser newUser org <- createOrganization newOrganization addUserToOrganization user org
foo = do createUserAndOrganization newUser somethingElse
runPGTransaction foo connection
![Page 64: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz](https://reader035.fdocuments.us/reader035/viewer/2022081522/5fb4cafdabd6f51d5367cfbc/html5/thumbnails/64.jpg)
notAllowed = do user <- createUser newUser someSlowSideEffectingThing return user
![Page 65: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz](https://reader035.fdocuments.us/reader035/viewer/2022081522/5fb4cafdabd6f51d5367cfbc/html5/thumbnails/65.jpg)
notAllowed = do user <- createUser newUser someSlowSideEffectingThing :: IO () return user
![Page 66: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz](https://reader035.fdocuments.us/reader035/viewer/2022081522/5fb4cafdabd6f51d5367cfbc/html5/thumbnails/66.jpg)
postgresql-transactionalgithub.com/helium/postgresql-transactional
![Page 67: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz](https://reader035.fdocuments.us/reader035/viewer/2022081522/5fb4cafdabd6f51d5367cfbc/html5/thumbnails/67.jpg)
build deploy monitor test develop
![Page 68: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz](https://reader035.fdocuments.us/reader035/viewer/2022081522/5fb4cafdabd6f51d5367cfbc/html5/thumbnails/68.jpg)
Reid Draper @reiddrapergithub.com/helium
helium.com