name: inverse layout: true class: center, middle, inverse --- #NEW ##DIRECTIONS IN STRING INTERPOLATION --- #TASK --- layout: false # TASK Given the following bindings: ```haskell name :: String name = "Marvin" age :: Int age = 23 profession :: String profession = "λ-scientist" ``` Produce the following output: ``` Marvin is a 23-year-old λ-scientist! ``` --- template: inverse ## Should be easy, right? --- template: inverse #PAINFUL (use [++](https://github.com/sol/interpolate-talk/blob/gh-pages/Painful.hs)) --- template: inverse #
QuasiQuotes
to the rescue! ##QuasiQuotes allow you to
extend the compiler
by parsing a string and create an AST from it! --- layout: false ## Let's give [interpolatedstring-qq](http://hackage.haskell.org/package/interpolatedstring-qq-0.2) a try: ```haskell {-# LANGUAGE QuasiQuotes #-} import Text.InterpolatedString.QQ name :: String name = "Marvin" age :: Int age = 23 profession :: String profession = "λ-scientist" main :: IO () main = do putStrLn [istr|#{name} is a #{age}-year-old #{profession}!|] ``` --- template: inverse #WRONG --- template: inverse ## So what were they actually trying to do? `toString :: a -> String` --- layout: false ## So what were they actually trying to do? The whole problem really boils down to a function that behaves like so: ```haskell ghci> toString "foo" "foo" ghci> toString 23 "23" ``` So if we can solve this, we win! Note: This is different from `show`: ```haskell ghci> show "foo" "\"foo\"" ghci> putStrLn (show "foo") "foo" ``` --- layout: false ## Using a type class ```haskell class ToString a where toString :: a -> String instance ToString String where toString = id instance ToString Int where toString = show ``` Issues: * We can
not easily derive instances
for this class (update: with `-XDefaultSignatures` and GHC 7.10 this will hopefully change) * What if we want to interpolate values of a
type from an other package
? (orphan instances...) --- template: inverse ## BUT: Most values already have a
Show
instance, right? --- template: inverse ##Wouldn't it be cool to just
use show
? (and that is what [they did](http://hackage.haskell.org/package/interpolatedstring-qq-0.2/docs/src/Text-InterpolatedString-QQ.html#istr)) --- template: inverse # WTF ## How could they think that this could possibly work? --- template: inverse #RIGHT --- layout: false #RIGHT Exploit the fact that for strings
`read . show`
is
`id`
! * Use `show` * Try to revert it with `readMaybe :: String -> Maybe String` * If reverting succeeds use that, otherwise use the shown value --- template: inverse #But this is in[efficient](https://github.com/sol/interpolate/blob/9be1f6d15722c58e467e7ebc0cb6dc6fb2c4f5e0/src/Data/String/Interpolate/Internal/Util.hs#L9), right? --- template: inverse #It's on [GitHub](https://github.com/sol/interpolate) and [Hackage](http://hackage.haskell.org/package/interpolate) --- template: inverse # Who am [I](http://typeful.net)? --- template: inverse ## [sol](https://github.com/sol) on GitHub ## [solirc_](https://twitter.com/solirc_) on Twitter ## write [tests](https://github.com/sol/interpolate/blob/9be1f6d15722c58e467e7ebc0cb6dc6fb2c4f5e0/test/Data/String/Interpolate/Internal/UtilSpec.hs#L20) ## current main author of [Hspec](http://hspec.github.io/) ## ported Python's [Doctest](http://hackage.haskell.org/package/doctest) to Haskell ## current maintainer of [Haddock](http://hackage.haskell.org/package/haddock) (also Fuuzetsu is taking over) ## work at
[Wimdu](https://twitter.com/wimdu)
[ZALORA](http://www.zalora.com/)