class: center # The Way to [Simplicity]() ### how Haskell simplifies
code maintenance .me[ Denis Shevchenko @ IOHK ] --- class: middle ## — Simplicity is
the result of [maturity](). .intro-quote-author[ — Friedrich Schiller ] ??? That's why novices tend to create too complex solutions. But when we become more experienced we're looking for a simplicity. --- class: middle .maintainability-is-simplicity[ maintainability [⇔]() simplicity ] --- class: middle .maintainability-is-simplicity[ maintainability [⇔]() simplicity ] .fix[
] .refactoring[
] .improvement[
] ??? How simple the code can be repaired, can be refactored and can be improved. --- class: middle .maintainability-is-simplicity[ maintainability [⇔]() simplicity ] .simplicity[
] --- .computer[
] .to-computer[
] .letter[ [
]() ] .to-human[
] .human[
] --- class: middle ### [
]() Don't forget to encrypt ### [
]() Are you launching missiles? ### [
]() Build a page with types --- class: middle ### [
]() Types ### [
]() Purity ### [
]() Pattern-matching --- class: middle ### Did we encrypt it?! --- class: editor ```cpp class Message { std::string message; public: Message (const std::string& msg); std::string getMessage() const; }; ``` --- class: editor ```haskell data Message = Message Text ``` --- class: editor ```cpp class Message { std::string message; * bool encrypted = false; public: Message (const std::string& msg); std::string getMessage() const; bool isEncrypted() const; void encrypt(); void decrypt(); }; ``` --- class: editor ```haskell data Message = Plain Text | Encrypted Text encrypt :: Message -> Message decrypt :: Message -> Message ``` --- class: editor ```haskell main :: IO () main = send secret "dev@dev.by" where secret = encrypt plain * plain = Plain "Hi Minsk!" ``` --- class: editor ```haskell main :: IO () main = send secret "dev@dev.by" where * secret = Encrypted $ readFile "/tmp/encrypted.msg" ``` --- class: editor ```cpp void send (const Message& msg, const Recipient& recipient) { * if (msg.isEncrypted()) realSending(msg.getMessage(), recipient); else throw SendException ("Unencrypted message!"); } ``` --- class: editor ```haskell send :: Message -> Recipient -> IO () send (Encrypted text) recipient = realSending text recipient send (Plain _) _ = throw SendUnencryptedMessage ``` --- class: editor ```haskell data Message state = Message Text -- States of the message data Plain data Encrypted ``` --- class: editor ```haskell encrypt :: Message Plain -> Message Encrypted decrypt :: Message Encrypted -> Message Plain ``` --- class: editor ```haskell send :: Message Encrypted -> Recipient -> IO () send (Message text) recipient = realSending text recipient ``` --- class: editor ```haskell data Message state = Message Text -- States of the message data Plain data Encrypted ``` --- class: editor ```haskell data Message state = Message Text -- States of the message data Plain data Encrypted *data InBase64 ``` --- class: editor ```haskell messageLength :: Message state -> Int messageLength (Message text) = length text ``` --- class: editor ```haskell messageLength :: Message state -> Int messageLength (Message text) = length text toBase64 :: Message state -> Message InBase64 toBase64 (Message text) = Message $ encode text ``` --- class: middle ### What about missiles? --- class: editor ```cpp std::vector
calculate (const FoodInfo& info, const Food& commonFood); ``` --- class: editor ```cpp std::vector
calculate (const FoodInfo& info, const Food& commonFood); ``` .black-box[
] --- class: editor ```haskell calculate :: FoodInfo -> Food -> [Result] ``` --- class: editor ```haskell calculate :: FoodInfo -> Food -> [Result] ``` .woohoo[
] --- class: editor ```haskell calculate :: FoodInfo -> Food * -> IO [Result] ``` .hmmm[
] --- class: editor ```cpp double calc_sin (double degree) { return sin (degree * PI / 180); } ``` .hmmm[
] --- class: editor ```cpp double calc_sin (double degree) { * launch_missiles(); return sin (degree * PI / 180); } ``` .missiles[
] --- class: editor ```cpp double calc_sin (double degree) { * should_I_launch_missiles = true; return sin (degree * PI / 180); } ``` .missiles[
] --- class: editor ```haskell calculate :: FoodInfo -> Food -> [Result] ``` .woohoo[
] --- class: middle ### Building the page… --- class: editor ```haskell ".buy-form" ? do margin (em 0) auto maxWidth (em 30.0) fontFamily ["Roboto"] [sansSerif] ``` --- class: editor ```haskell body $ div ! class_ "container" $ div ! class_ ".buy-form" ... ``` --- class: editor ```haskell body $ div ! class_ "container" $ * div ! class_ ".buy-form" ... ``` --- class: editor ```haskell data ClassName = LanguageSwitcher | CurrentLanguage | BuyForm ... | Copyright | SocialButtons deriving (Show) ``` --- class: editor ```haskell data ClassName = LanguageSwitcher | CurrentLanguage * | BuyForm ... | Copyright | SocialButtons deriving (Show) ``` --- class: editor ```haskell data ClassName = LanguageSwitcher | CurrentLanguage | BuyForm ... | Copyright | SocialButtons * deriving (Show) ``` --- class: editor ```haskell *cl_ BuyForm ? do margin (em 0) auto maxWidth (em 30.0) fontFamily ["Roboto"] [sansSerif] ``` --- class: editor ```haskell *cl_ BuyForm ? do margin (em 0) auto maxWidth (em 30.0) fontFamily ["Roboto"] [sansSerif] ``` .equal-to[ = ] ```haskell *"." <> "BuyForm" ? do margin (em 0) auto maxWidth (em 30.0) fontFamily ["Roboto"] [sansSerif] ``` --- class: editor ```haskell body $ div ! class_ "container" $ * div ! class_ (toValue BuyForm) ... ``` --- class: editor ```haskell body $ div ! class_ "container" $ * div ! class_ (toValue BuyForm) ... ``` .produces-html[
] ```html
*
... ``` --- class: middle ### [
]() Types ### [
]() Purity ### [
]() Pattern-matching --- class: middle ### Thanks! ## [Your]() questions…