Through the lens of Haskell Exploring new ideas for library design - - PowerPoint PPT Presentation

through the lens of haskell
SMART_READER_LITE
LIVE PREVIEW

Through the lens of Haskell Exploring new ideas for library design - - PowerPoint PPT Presentation

Through the lens of Haskell Exploring new ideas for library design @georgesdubus Haskell, the language Haskell, the ecosystem Design space There should be one and preferably only one obvious way to do it. (Python) There should be


slide-1
SLIDE 1

Through the lens of Haskell

Exploring new ideas for library design

slide-2
SLIDE 2

@georgesdubus

slide-3
SLIDE 3

Haskell, the language

slide-4
SLIDE 4

Haskell, the ecosystem

slide-5
SLIDE 5

Design space

slide-6
SLIDE 6

There should be one — and preferably only one —

  • bvious way to do it.

(Python)

slide-7
SLIDE 7

There should be one — and preferably only one —

  • bvious way to do it.

Let’s keep looking for it!

(Python) (Haskell)

slide-8
SLIDE 8
slide-9
SLIDE 9

Some Haskell libraries

slide-10
SLIDE 10

JSON Packaging HTTP

slide-11
SLIDE 11

JSON Packaging HTTP ??? ??? ???

slide-12
SLIDE 12

Some Haskell libraries

Part 1: attoparsec

slide-13
SLIDE 13

“Real life” use case :

A slack bot that answers movie quotes

slide-14
SLIDE 14

subtitleParser Full package definition

Name Type

slide-15
SLIDE 15

subtitleParser All I need

slide-16
SLIDE 16

attoparsec

All I need to know :

parseOnly :: Parser Subtitles -> ByteString -> Either ErrorMessage Subtitles

slide-17
SLIDE 17

attoparsec

All I need to know :

parseOnly :: Parser Subtitles -> ByteString -> Either ErrorMessage Subtitles parseOnly :: Parser a -> ByteString -> Either ErrorMessage a

slide-18
SLIDE 18

attoparsec

Or : incremental parsing

parse :: Parser a -> ByteString -> Result a feed :: Result a -> ByteString -> Result a

(Result can be Partial, Failed or Done)

slide-19
SLIDE 19

attoparsec

Part of a bigger parser

many :: Parser a -> Parser [a]

  • r :: Parser a -> Parser b -> Parser (Either a b)
slide-20
SLIDE 20

Parsers everywhere

parseCSV :: Parser CSV in attoparsec-csv json :: Parser JSONValue in aeson crontab :: Parser Crontab in cron emailAddress :: Parser String in email-header toml :: Parser TOMLValue in toml ...

slide-21
SLIDE 21

A good library simplifies the implementation

slide-22
SLIDE 22

A good library simplifies the interface

slide-23
SLIDE 23

General solution Specific building blocks

slide-24
SLIDE 24

General solution Specific building blocks

attoparsec all parsers

slide-25
SLIDE 25

Some Haskell libraries

Part 2: conduit

slide-26
SLIDE 26

Conduit

Streaming library Producers Consumers Conduits that both consume and produce

slide-27
SLIDE 27

Lot of libraries

sourceSocket socket =$= ungzip =$= sinkFile "/tmp/output" producer from Data.Conduit.Network conduit from Data.Conduit.Zlib consumer from Data.Conduit.Binary

slide-28
SLIDE 28

conduit + attoparsec =

High-performance subtitles streaming for free !

sourceFile “something.srt” =$= conduitParser parseSubtitleLine =$= ircConsumer

Parser of Subtitle Lines Parser ➡ Conduit

slide-29
SLIDE 29

General solution Specific building blocks

conduit all conduits

slide-30
SLIDE 30

Some Haskell libraries

Part 3: lens

slide-31
SLIDE 31

BlogPost { title = “Made-up examples considered harmful” , author = Person {name=“Alice”} , comments = [ Comment { author = “Bob” , content = “Great insight!” } , Comment { author = “Carol” , content = “I completely disagree” } ] }

Data manipulation

slide-32
SLIDE 32

>>> view title blogpost “Made-up examples considered harmful”

Getters

Lens

slide-33
SLIDE 33

>>> view title blogpost “Made-up examples considered harmful” >>> view (author . name) blogpost "Alice"

Getters

Lens Lens Lens

slide-34
SLIDE 34

>>> view title blogpost “Made-up examples considered harmful” >>> view (author . name) blogpost "Alice" >>> set (speaker . name) “Alicia” blogpost BlogPost { title = “Made-up examples considered harmful” , author = “Alicia” , ... }

Getters Setters

Lens Lens Lens

slide-35
SLIDE 35

>>> toListOf (comments . each . author) blogpost [“Bob”, “Carol”]

Getters/setters with multiple values ?!?

Lens Lens Traversal

slide-36
SLIDE 36

>>> let commentContents = comments . each . content >>> toListOf commentContents blogpost [“Great insight!”, “I completely disagree”] >>> set commentContents “Blah blah blah” blogpost BlogPost { comments = [ Comment { author = “Bob” , content = “Blah blah blah” } , Comment { author = “Carol” , content = “Blah blah blah” } ] , ... }

Getter / setter pairs are values

slide-37
SLIDE 37

[{“id”: “1”, “name”: “georges”}, {“id”: “2”, “name”: “lucie”}] >>> input & (values . key “name”) %~ capitalize [{“id”: “1”, “name”: “Georges”}, {“id”: “2”, “name”: “Lucie”}]

Libraries provide lenses: JSON

slide-38
SLIDE 38

titles = allNamed (only "h2") . contents

Libraries provide lenses: HTML

Traversal into all tags with a given name Their content

slide-39
SLIDE 39

General solution Specific building blocks

lens all lenses

slide-40
SLIDE 40

“Borrowing” ideas

slide-41
SLIDE 41

Python ➡ Haskell wreq = requests + lens

slide-42
SLIDE 42

Haskell ➡ Python hypothesis

slide-43
SLIDE 43

Conclusion

slide-44
SLIDE 44

Explore the design space

slide-45
SLIDE 45

Explore the design space Factorize library interfaces

slide-46
SLIDE 46

Explore the design space Factorize library interfaces Bonus : DIY conclusion