SlideShare ist ein Scribd-Unternehmen logo
1 von 156
Metaprogramming
   in Haskell
Table of Contents


Template Haskell

Generic Programming in Haskell

(Type-level Programming)
Table of Contents


Template Haskell

Generic Programming in Haskell

(Type-level Programming)
Template Haskell
Template Haskell

Haskell
Template Haskell

Haskell




C
HOC - Haskell Objective-C binding

   Class/Instance

jmacro

   JavaScript

HAppS



lambdabot

                IRC Bot (IRC        )
TH
TH
TH


     IO
TH


     IO

          ( reify )
TH


       IO

            ( reify )




 DSL
TH
TH

(   )
TH

      (    )

Template Haskell
TH

      (    )

Template Haskell

          Q

          IO
TH

      (    )

Template Haskell

          Q

          IO

     compile-time wxWidgets, Socket, etc...
TH Features

  {-# LANGUAGE TemplateHaskell, QuasiQuotes #-}
  import Language.Haskell.TH

         splice




reify / runIO
DEMO
2   RandomDef.hs
2 RandomDef.hs
{-# LANGUAGE TemplateHaskell #-}
module Main where
import Language.Haskell.TH
import System.Random

$( do rnd ← runIO $ randomRIO (0,1)
    let nm = mkName (["a", "b"] !! rnd)
    m ← [d| main = $(varE $ mkName "a") |]
    t ← valD (varP nm) (normalB [| putStrLn " `) " |]) []
                                         (´
     return (t:m)
 )
(RandomDef.hs)
{-# LANGUAGE TemplateHaskell #-}
module Main where
import Language.Haskell.TH
import System.Random

$( do rnd ← runIO $ randomRIO (0,1)
    let nm = mkName (["a", "b"] !! rnd)
    m ← [d| main = $(varE $ mkName "a") |]
    t ← valD (varP nm) (normalB [| putStrLn " `) " |]) []
                                         (´
     return (t:m)
 )
Template Haskell
Template Haskell

     Exp           Dec   Pat   Type
Template Haskell

     Exp           Dec     Pat   Type




             ……(cf. HOC)
Template Haskell

     Exp           Dec     Pat   Type




             ……(cf. HOC)

Q
putStrLn “Hello!”
  = AppE (VarE ‘putStrLn) (LitE (stringL “Hello!”))

main :: IO ()
main = getLine >>= putStrLn
   [ SigD (mkName "main") (AppT (VarT ''IO) (VarT ''())), FunD (mkName
   "main") [Clause [] (NormalB $ InfixE (Just $ VarE 'getLine) (VarE
   '(>>=)) (Just $ VarE 'putStrLn) ) []]]
lib2 =
     let
           l=LetS[ValD(VarP $ mkName"it")(NormalB(f"be"))[]]
           f=VarE . mkName
     in
           DoE [ l, l, l, NoBindS $ f"oh",l,
           NoBindS $ InfixE(Just$ f"speaking")(f"words")(Just $ f "wisdom"),l]
lib2 =
     let
           l=LetS[ValD(VarP $ mkName"it")(NormalB(f"be"))[]]
           f=VarE . mkName
     in
           DoE [ l, l, l, NoBindS $ f"oh",l,
           NoBindS $ InfixE(Just$ f"speaking")(f"words")(Just $ f "wisdom"),l]

                                           do let it = be
                                             let it = be
                                             let it = be
                                             oh
                                             let it = be
                                             speaking `words` wisdom
                                             let it = be
k



         GHCi
GHCi> runQ [d| data List a = Cons a (List a) | Nil |]
 [DataD [] List [PlainTV a_0] [NormalC Cons [(NotStrict,VarT a_0),
(NotStrict,AppT (ConT List) (VarT a_0))],NormalC Nil []] []]
[k| |]               (“k”               )

Q

     [e| putStrLn “foo” |]                  (e       )

     [d| main = putStrLn “:-)” |]

     [t| Maybe String |]

     [p| Just 2 |]                      (GHC HEAD)

               (                            )

              `a,           ``Maybe (                    )
{-# LANGUAGE TemplateHaskell #-}
module Main where
import Language.Haskell.TH
import System.Random

$( do rnd ← runIO $ randomRIO (0,1)
    let nm = mkName (["a", "b"] !! rnd)
    m ← [d| main = $(varE $ mkName "a") |]
    t ← valD (varP nm) (normalB [| putStrLn " ( ´ `) " |]) []
     return (t:m)
 )
(RandomDef.hs)

{-# LANGUAGE TemplateHaskell #-}
module Main where
import Language.Haskell.TH
import System.Random
                                                                +
$( do rnd ← runIO $ randomRIO (0,1)
    let nm = mkName (["a", "b"] !! rnd)
    m ← [d| main = $(varE $ mkName "a") |]
    t ← valD (varP nm) (normalB [| putStrLn " ( ´ `) " |]) []
     return (t:m)
 )
(Splice)
(Splice)
Q
(Splice)
       Q

$( )
(Splice)
       Q

$( )
(Splice)
       Q

$( )




       main = $(1 + ‘a) :: $(myType)
(Splice)
       Q

$( )




       main = $(1 + ‘a) :: $(myType)

                               $()     (6.12   )
(Splice)
       Q

$( )




       main = $(1 + ‘a) :: $(myType)

                               $()     (6.12   )

        Splice         (6.12 )
(Splice)
           Q

$( )




           main = $(1 + ‘a) :: $(myType)

                                   $()     (6.12   )

            Splice         (6.12 )

       Splice                import
(Splice)
           Q

$( )




           main = $(1 + ‘a) :: $(myType)

                                   $()     (6.12   )

            Splice         (6.12 )

       Splice                import
Q Monad
Q Monad
Q Monad

IO
Q Monad

IO

     runIO $ ...
Q Monad

IO

     runIO $ ...

                         (reify)
Q Monad

IO

     runIO $ ...

                         (reify)

     Q
Q Monad

IO

     runIO $ ...

                                    (reify)

     Q

     GHCi    runQ $ reify ''Maybe
IO

{-# LANGUAGE TemplateHaskell #-}
module Main where
import Language.Haskell.THIO                         Get
import System.Random

$( do rnd ← runIO $ randomRIO (0,1)
    let nm = mkName (["a", "b"] !! rnd)
    m ← [d| main = $(varE $ mkName "a") |]
    t ← valD (varP nm) (normalB [| putStrLn " `) " |]) []
                                         (´
     return (t:m)
 )
{-# LANGUAGE TemplateHaskell #-}
module Main where
import Language.Haskell.TH
import System.Random

$( do rnd ← runIO $ randomRIO (0,1)
    let nm = mkName (["a", "b"] !! rnd)
    m ← [d| main = $(varE $ mkName "a") |]
    t ← valD (varP nm) (normalB [| putStrLn " `) " |]) []
                                         (´
     return (t:m)
 )
reify

compile-time




                 (   )

        derive

DEMO
LISP
LISP

       EDSL
LISP

       EDSL
LISP

         EDSL




   GHC HEAD
LISP

              EDSL




   GHC HEAD

       [$ident| ... |]
LISP

              EDSL




   GHC HEAD

       [$ident| ... |]

   ident                 QuasiQuoter
LISP

              EDSL




   GHC HEAD

       [$ident| ... |]

   ident                 QuasiQuoter

                 String → ExpQ     String → PatQ
LISP

              EDSL




   GHC HEAD

       [$ident| ... |]

   ident                 QuasiQuoter

                 String → ExpQ     String → PatQ

           Graph JSON
mkTweet :: Int → String → JSValue → JSValue
mkTweet tid text = [$json|
 {“status”: {
   “id”: #int<tid>, “text”: #str<text>
 }}
|]

getID :: JSValue → Int
getID [$json| “id”:#Int{var} |] = var
mkTweet :: Int → String → JSValue → JSValue
mkTweet tid text = [$json|
 {“status”: {
   “id”: #int<tid>, “text”: #str<text>
 }}
|]

getID :: JSValue → Int
getID [$json| “id”:#Int{var} |] = var

                                 (            )
mkTweet :: Int → String → JSValue → JSValue
mkTweet tid text = [$json|
 {“status”: {
   “id”: #int<tid>, “text”: #str<text>
 }}
|]

getID :: JSValue → Int
getID [$json| “id”:#Int{var} |] = var

                                 (            )
JSON
data JSON = JSNumber Int | JSString String
            | ...
            | Var String
        deriving (Show, Eq, Ord)

-- QuasiQuoter
json :: QuasiQuoter
json = QuasiQuoter quoteJSONExp quoteJSONPat

quoteJSONExp :: String → ExpQ
quoteJSONPat :: String → PatQ
quoteJSONPat src = ...
quoteJSONExp src = ...
JSON
data JSON = JSNumber Int | JSString String
            | ...
            | Var String
        deriving (Show, Eq, Ord)

-- QuasiQuoter
json :: QuasiQuoter
json = QuasiQuoter quoteJSONExp quoteJSONPat

quoteJSONExp :: String → ExpQ
quoteJSONPat :: String → PatQ
quoteJSONPat src = ...
quoteJSONExp src = ...
JSON
data JSON = JSNumber Int | JSString String
            | ...
            | Var String
        deriving (Show, Eq, Ord)

-- QuasiQuoter
json :: QuasiQuoter
json = QuasiQuoter quoteJSONExp quoteJSONPat

quoteJSONExp :: String → ExpQ
quoteJSONPat :: String → PatQ
quoteJSONPat src = ...
quoteJSONExp src = ...
JSON
data JSON = JSNumber Int | JSString String
            | ...
            | Var String
        deriving (Show, Eq, Ord)

-- QuasiQuoter
json :: QuasiQuoter
json = QuasiQuoter quoteJSONExp quoteJSONPat

quoteJSONExp :: String → ExpQ
quoteJSONPat :: String → PatQ
quoteJSONPat src = ...
quoteJSONExp src = ...
dataToExpQ, dataToPatQ
dataToExpQ, dataToPatQ


jsonPat src= dataToPatQ (const Nothing `extQ` antiQuoteP)
               (parseJSON src)
antiQuoteP (Var a) = Just (varP (mkName a))
antiQuoteP _     = Nothing
dataToExpQ, dataToPatQ


jsonPat src= dataToPatQ (const Nothing `extQ` antiQuoteP)
               (parseJSON src)
antiQuoteP (Var a) = Just (varP (mkName a))
antiQuoteP _     = Nothing
data JSON = JSNumber Int | JSString String
            | ...
            | Var String
        deriving (Show, Eq, Ord, Data, Typeable)

                            ...

parseExpr = ... -- Parser

quoteJSONPat src = do
  let exp = parseExpr src
  dataToPatQ (const Nothing `extQ` antiStrPat) exp

antiStrPat :: Expr → Maybe PatQ
antiStrPat (Var a) = Just $ varP (mkName a)
antiStrPat _     = Nothing
data JSON = JSNumber Int | JSString String
            | ...
            | Var String
        deriving (Show, Eq, Ord, Data, Typeable)

                            ...

parseExpr = ... -- Parser

quoteJSONPat src = do
  let exp = parseExpr src
  dataToPatQ (const Nothing `extQ` antiStrPat) exp

antiStrPat :: Expr → Maybe PatQ
antiStrPat (Var a) = Just $ varP (mkName a)
antiStrPat _     = Nothing
data JSON = JSNumber Int | JSString String
            | ...
            | Var String
        deriving (Show, Eq, Ord, Data, Typeable)

                            ...

parseExpr = ... -- Parser

quoteJSONPat src = do
  let exp = parseExpr src
  dataToPatQ (const Nothing `extQ` antiStrPat) exp

antiStrPat :: Expr → Maybe PatQ
antiStrPat (Var a) = Just $ varP (mkName a)
antiStrPat _     = Nothing

                 Var
……


dataToExpQ   extQ
 …… ……
Generic Programming in Haskell

  Template Haskell

  Generic Programming in Haskell

  (Type-level Programming)
Haskell
Haskell



          ——Wikipedia
Haskell



          ——Wikipedia


 =
Haskell



          ——Wikipedia


 =
Haskell



          ——Wikipedia


 =
Generic Programming
     in Haskell


           (Generics ; GHC     )

SYB (Scrap Your Boilerplate)

Instant Generics
Generic Programming
     in Haskell


           (Generics ; GHC     )

SYB (Scrap Your Boilerplate)

Instant Generics
Sum of Product
Sum of Product


                 (   )
Sum of Product


                 (   )
Sum of Product


                                 (         )



{-# LANGUAGE Generics, TypeOperators #-}
Sum of Product


                                 (         )



{-# LANGUAGE Generics, TypeOperators #-}
 import GHC.Generics
data Bool = False | True

= Unit :+: Unit
data Maybe a = Nothing | Just a

= Unit :+: a
          Just 12 = Inr 12, Nothing = Inl Unit

data List a = Nil | Cons a (List a)

=   Unit :+: (a :*: (List a))

     [1,2,3] = Inr (1 :*: Inr (2 :*:
                Inr (3 :*: Inl Unit)))
Binary Encode
class Bin a where
 toBin :: a → [Int]
 fromBin :: [Int] → (a, [Int])

 toBin {| Unit |} Unit         = [0]
 toBin {| p :*: q |} (a :*: b) = toBin a ++ toBin b
 toBin {| p :+: q |} (Inl a) = 0:toBin a
 toBin {| p :+: q |} (Inr b) = 1:toBin b
 fromBin {| Unit |} (0:xs) = (Unit, xs)
 fromBin {| p :*: q |} bin =
   let (a, bin') = fromBin bin
      (b, bin'') = fromBin bin'

        ...
class Bin a where
 toBin :: a → [Int]
 fromBin :: [Int] → (a, [Int])

 toBin {| Unit |} Unit         = [0]
 toBin {| p :*: q |} (a :*: b) = toBin a ++ toBin b
 toBin {| p :+: q |} (Inl a) = 0:toBin a
 toBin {| p :+: q |} (Inr b) = 1:toBin b
 fromBin {| Unit |} (0:xs) = (Unit, xs)
 fromBin {| p :*: q |} bin =
   let (a, bin') = fromBin bin
      (b, bin'') = fromBin bin'
           in ...
class Bin a where
 toBin :: a → [Int]
 fromBin :: [Int] → (a, [Int])

 toBin {| Unit |} Unit         = [0]
 toBin {| p :*: q |} (a :*: b) = toBin a ++ toBin b
 toBin {| p :+: q |} (Inl a) = 0:toBin a
 toBin {| p :+: q |} (Inr b) = 1:toBin b
 fromBin {| Unit |} (0:xs) = (Unit, xs)
 fromBin {| p :*: q |} bin =
   let (a, bin') = fromBin bin
      (b, bin'') = fromBin bin' in (a :*: b, bin’’)
         ...
(                Int, Char)   instance


instance Bin Int where
  toBin = ....

instance Bin Char where
  toBin = ...


instance Bin a    Bin [a]
instance (Bin a, Bin b)       Bin (a, b)
instance Bin a    Bin (Maybe a)
instance (Bin a, Bin b)       Bin (Either a b)
DEMO
default method




a          [a]   Maybe a
Generic Programming
     in Haskell


           (Generics ; GHC     )

SYB (Scrap Your Boilerplate)

Instant Generics
Scrap Your Boilerplate

                       syb

Haskell




          dataToExpQ
Typeable / Data
Typeable / Data

  Typeable:

     cast (       )
Typeable / Data

  Typeable:

     cast (                  )

  Data:           (gfoldl)




     cast
Typeable / Data

 GHC
 {-# LANGUAGE DeriveDataTypeable #-}
 data Tree a = Leaf a | Branch (Tree a) (Tree a)
          deriving (Data, Typeable)



        Standalone deriving
        {-# LANGUAGE StandaloneDeriving #-}
        deriving instance Typeable1 Tree
        deriving instance Data a  Data (Tree a)
--
data Expr = Num Int
      | Var String
      | Plus Expr Expr
      | Minus Expr Expr
      | Multi Expr Expr
      | Div Expr Expr
        deriving (Show, Eq, Data, Typeable)

normalize :: Expr → Expr
normalize = everywhere (mkT normalize')

normalize'   (Plus (Num n) (Num m)) = Num (n + m)
normalize'   (Multi (Num n) (Num m)) = Num (n * m)
normalize'   (Minus (Num n) (Num m)) = Num (n - m)
normalize'   (Div (Num n) (Num m)) = Num (n `div` m)
normalize'   x               =x
SYB
SYB
SYB
SYB
SYB



mkT :: (b → b) → (a → a)
SYB



mkT :: (b → b) → (a → a)
SYB



mkT :: (b → b) → (a → a)



everywhere :: GenericT → GenericT
SYB



mkT :: (b → b) → (a → a)



everywhere :: GenericT → GenericT

                     bottom-up
SYB



mkT :: (b → b) → (a → a)



everywhere :: GenericT → GenericT

                     bottom-up

   top-down     everywhere'
(1)
GenericT = ∀a. a → a
   Transformer
             mkT fun
                 trans `extT` fun
   GenericM = ∀a. a → m a   :
GenericQ = ∀a. a → r
   Query
             (              ) `mkQ` fun
                 query `extQ` fun
(2)
GenericB = ∀a. a
  Builder


               builder `extB` fun
GenericR = ∀a. m a
  Reader
             mkR fun
               reader `extR` fun
gmapT :: GenericT → a → a



somewhere :: GenericM m → GenecirM m



everything :: (r → r → r) → GenericQ r → GenericQ r



listify :: (r → Bool) → GenericQ [r]




gsize/glength :: GenericQ Int
dataToExpQ

dataToExpQ

:: Data a    GenericQ (Maybe ExpQ)
                  → a → ExpQ



     (const Nohting `ext` anti)
SYB
SYB
SYB




cast
Generic Programming
     in Haskell


           (Generics ; GHC     )

SYB (Scrap Your Boilerplate)

Instant Generics
Instant Generics
Instant Generics

               (Type families)




DPH (Data Parallel Haskell)
Generics
Generics
Generics
Generics
IG
                        Representable a

type Rep a

             data U = U

             data a :+: b = L a | R b (   )

             data a :*: b = a :*: b

             data C con a = C a

             data Var p = Var p

             data Rec p = Rec p
Int, Bool   Int, Bool

data Maybe a = Nothing | Just a

 type Rep (Maybe a)
   = C Maybe_Nothing_ U
  :+: C Maybe_Just_ (Var a)

       Just 12 = R(C(Var 12)), Nothing = L(C U)
Int, Bool   Int, Bool

data Maybe a = Nothing | Just a

 type Rep (Maybe a)
   = C Maybe_Nothing_ U
  :+: C Maybe_Just_ (Var a)

       Just 12 = R(C(Var 12)), Nothing = L(C U)
1           Binary Encode
class Bin a where
   toBin :: a → [Int]
   fromBin :: [Int] → (a, [Int])
                                                  C, Var, Rec
instance Bin U where
   toBin U = []
   fromBin xs = (U, [])

instance (Bin a, Bin b)     Bin (a :+: b) where
  toBin (L a) = 0:toBin a
  toBin (R b) = 1:toBin b
  fromBin (0:bin) = ...
   ...

instance (Bin a, Bin b)     Bin (a :*: b) where
  toBin (a :*: b) = toBin a ++ toBin b
  fromBin bin      = ...

instance Bin Int where
   ...
def_toBin :: (Representable a, Bin (Rep a))
      a → [Int]
def_toBin = toBin . from
...




instance Bin a   Bin [a] where

   toBin = def_toBin; fromBin = def_fromBin
2


!     class Normalize a where

        normalize :: a → a




instance Normalize U
instance Normalize (Var a)
...
instance Normalize a    Normalize (Rec a) where
    normalize (Rec a) = Rec (normalize a)
2


!     class Normalize a where

        normalize :: a → a




instance Normalize U
instance Normalize (Var a)
...
instance Normalize a    Normalize (Rec a) where
    normalize (Rec a) = Rec (normalize a)
2


!     class Normalize a where

        normalize :: a → a




instance Normalize U
instance Normalize (Var a)
...
instance Normalize a    Normalize (Rec a) where
    normalize (Rec a) = Rec (normalize a)
2


!     class Normalize a where

        normalize :: a → a




instance Normalize U
instance Normalize (Var a)
...
instance Normalize a    Normalize (Rec a) where
    normalize (Rec a) = Rec (normalize a)
Expr
dft_normalize
 :: (Representable a, Normalize (Rep a))   a→a
dft_normalize = to . normalize . from

instance Normalize Expr where
  normalize x = case dft_normalize x of
    Plus (Num n) (Num m) → Num (n + m)
    Multi (Num n) (Num m) → Num (n * m)
    Minus (Num n) (Num m) → Num (n - m)
    Div (Num n) (Num m) → Num (n `div` m)
    x              →x


Var                                     Int, Char
Instant Generics
Instant Generics
Instant Generics
100000(ms)

 10000(ms)

  1000(ms)

   100(ms)

    10(ms)

     1(ms)
              geq    rmWeights         selectInt   selectIntAcc
             SYB    Instant Generics
100000(ms)

 10000(ms)

  1000(ms)

   100(ms)

    10(ms)

     1(ms)
              geq    rmWeights         selectInt   selectIntAcc
             SYB    Instant Generics
100000(ms)

 10000(ms)

  1000(ms)

   100(ms)

    10(ms)

     1(ms)
              geq    rmWeights         selectInt   selectIntAcc
             SYB    Instant Generics
100000(ms)

 10000(ms)

  1000(ms)

   100(ms)

    10(ms)

     1(ms)
              geq    rmWeights         selectInt   selectIntAcc
             SYB    Instant Generics
100000(ms)


75000(ms)


50000(ms)


25000(ms)


     0(ms)
              geq    rmWeights         selectInt   selectIntAcc

             SYB    Instant Generics
SYB
Generics

SYB

          IG
GP
SYB with class

    Data




Smash

                 (          )




    SYB

Uniplate




                     MPTC
Questions?
Template Haskell and QuasiQuoters

Weitere ähnliche Inhalte

Was ist angesagt?

Haskell in the Real World
Haskell in the Real WorldHaskell in the Real World
Haskell in the Real Worldosfameron
 
New SPL Features in PHP 5.3
New SPL Features in PHP 5.3New SPL Features in PHP 5.3
New SPL Features in PHP 5.3Matthew Turland
 
PHP data structures (and the impact of php 7 on them), phpDay Verona 2015, Italy
PHP data structures (and the impact of php 7 on them), phpDay Verona 2015, ItalyPHP data structures (and the impact of php 7 on them), phpDay Verona 2015, Italy
PHP data structures (and the impact of php 7 on them), phpDay Verona 2015, ItalyPatrick Allaert
 
Is Haskell an acceptable Perl?
Is Haskell an acceptable Perl?Is Haskell an acceptable Perl?
Is Haskell an acceptable Perl?osfameron
 
PHP 7 – What changed internally? (PHP Barcelona 2015)
PHP 7 – What changed internally? (PHP Barcelona 2015)PHP 7 – What changed internally? (PHP Barcelona 2015)
PHP 7 – What changed internally? (PHP Barcelona 2015)Nikita Popov
 
PHP Language Trivia
PHP Language TriviaPHP Language Trivia
PHP Language TriviaNikita Popov
 
Functional Pe(a)rls - the Purely Functional Datastructures edition
Functional Pe(a)rls - the Purely Functional Datastructures editionFunctional Pe(a)rls - the Purely Functional Datastructures edition
Functional Pe(a)rls - the Purely Functional Datastructures editionosfameron
 
Perl6 a whistle stop tour
Perl6 a whistle stop tourPerl6 a whistle stop tour
Perl6 a whistle stop tourSimon Proctor
 
Perl6 a whistle stop tour
Perl6 a whistle stop tourPerl6 a whistle stop tour
Perl6 a whistle stop tourSimon Proctor
 
Python Performance 101
Python Performance 101Python Performance 101
Python Performance 101Ankur Gupta
 
Fun never stops. introduction to haskell programming language
Fun never stops. introduction to haskell programming languageFun never stops. introduction to haskell programming language
Fun never stops. introduction to haskell programming languagePawel Szulc
 
Scala vs Java 8 in a Java 8 World
Scala vs Java 8 in a Java 8 WorldScala vs Java 8 in a Java 8 World
Scala vs Java 8 in a Java 8 WorldBTI360
 
ITT 2015 - Saul Mora - Object Oriented Function Programming
ITT 2015 - Saul Mora - Object Oriented Function ProgrammingITT 2015 - Saul Mora - Object Oriented Function Programming
ITT 2015 - Saul Mora - Object Oriented Function ProgrammingIstanbul Tech Talks
 
Profiling and optimization
Profiling and optimizationProfiling and optimization
Profiling and optimizationg3_nittala
 
Functional Algebra: Monoids Applied
Functional Algebra: Monoids AppliedFunctional Algebra: Monoids Applied
Functional Algebra: Monoids AppliedSusan Potter
 
What's new in PHP 8.0?
What's new in PHP 8.0?What's new in PHP 8.0?
What's new in PHP 8.0?Nikita Popov
 

Was ist angesagt? (20)

Haskell in the Real World
Haskell in the Real WorldHaskell in the Real World
Haskell in the Real World
 
New SPL Features in PHP 5.3
New SPL Features in PHP 5.3New SPL Features in PHP 5.3
New SPL Features in PHP 5.3
 
PHP data structures (and the impact of php 7 on them), phpDay Verona 2015, Italy
PHP data structures (and the impact of php 7 on them), phpDay Verona 2015, ItalyPHP data structures (and the impact of php 7 on them), phpDay Verona 2015, Italy
PHP data structures (and the impact of php 7 on them), phpDay Verona 2015, Italy
 
Is Haskell an acceptable Perl?
Is Haskell an acceptable Perl?Is Haskell an acceptable Perl?
Is Haskell an acceptable Perl?
 
PHP 7 – What changed internally? (PHP Barcelona 2015)
PHP 7 – What changed internally? (PHP Barcelona 2015)PHP 7 – What changed internally? (PHP Barcelona 2015)
PHP 7 – What changed internally? (PHP Barcelona 2015)
 
Grammarware Memes
Grammarware MemesGrammarware Memes
Grammarware Memes
 
Spl Not A Bridge Too Far phpNW09
Spl Not A Bridge Too Far phpNW09Spl Not A Bridge Too Far phpNW09
Spl Not A Bridge Too Far phpNW09
 
PHP Language Trivia
PHP Language TriviaPHP Language Trivia
PHP Language Trivia
 
Functional Pe(a)rls - the Purely Functional Datastructures edition
Functional Pe(a)rls - the Purely Functional Datastructures editionFunctional Pe(a)rls - the Purely Functional Datastructures edition
Functional Pe(a)rls - the Purely Functional Datastructures edition
 
Perl6 a whistle stop tour
Perl6 a whistle stop tourPerl6 a whistle stop tour
Perl6 a whistle stop tour
 
Perl6 a whistle stop tour
Perl6 a whistle stop tourPerl6 a whistle stop tour
Perl6 a whistle stop tour
 
Hammurabi
HammurabiHammurabi
Hammurabi
 
Python Performance 101
Python Performance 101Python Performance 101
Python Performance 101
 
Fun never stops. introduction to haskell programming language
Fun never stops. introduction to haskell programming languageFun never stops. introduction to haskell programming language
Fun never stops. introduction to haskell programming language
 
Scala vs Java 8 in a Java 8 World
Scala vs Java 8 in a Java 8 WorldScala vs Java 8 in a Java 8 World
Scala vs Java 8 in a Java 8 World
 
ITT 2015 - Saul Mora - Object Oriented Function Programming
ITT 2015 - Saul Mora - Object Oriented Function ProgrammingITT 2015 - Saul Mora - Object Oriented Function Programming
ITT 2015 - Saul Mora - Object Oriented Function Programming
 
Profiling and optimization
Profiling and optimizationProfiling and optimization
Profiling and optimization
 
Functional programming in java
Functional programming in javaFunctional programming in java
Functional programming in java
 
Functional Algebra: Monoids Applied
Functional Algebra: Monoids AppliedFunctional Algebra: Monoids Applied
Functional Algebra: Monoids Applied
 
What's new in PHP 8.0?
What's new in PHP 8.0?What's new in PHP 8.0?
What's new in PHP 8.0?
 

Andere mochten auch

ものまね鳥を愛でる 結合子論理と計算
ものまね鳥を愛でる 結合子論理と計算ものまね鳥を愛でる 結合子論理と計算
ものまね鳥を愛でる 結合子論理と計算Hiromi Ishii
 
Techmix2014 温故知新
Techmix2014 温故知新Techmix2014 温故知新
Techmix2014 温故知新Kazuya Numata
 
Do you trust that certificate?
Do you trust that certificate?Do you trust that certificate?
Do you trust that certificate?zunda
 
The worst Ruby codes I’ve seen in my life - RubyKaigi 2015
The worst Ruby codes I’ve seen in my life - RubyKaigi 2015The worst Ruby codes I’ve seen in my life - RubyKaigi 2015
The worst Ruby codes I’ve seen in my life - RubyKaigi 2015Fernando Hamasaki de Amorim
 
Practical Testing of Ruby Core
Practical Testing of Ruby CorePractical Testing of Ruby Core
Practical Testing of Ruby CoreHiroshi SHIBATA
 
Plugin-based software design with Ruby and RubyGems
Plugin-based software design with Ruby and RubyGemsPlugin-based software design with Ruby and RubyGems
Plugin-based software design with Ruby and RubyGemsSadayuki Furuhashi
 
実践・完全犯罪のつくり方
実践・完全犯罪のつくり方実践・完全犯罪のつくり方
実践・完全犯罪のつくり方Hiromi Ishii
 
(数式の入った)本をつくる
(数式の入った)本をつくる(数式の入った)本をつくる
(数式の入った)本をつくるHiromi Ishii
 
Alloy Analyzer のこと
Alloy Analyzer のことAlloy Analyzer のこと
Alloy Analyzer のことHiromi Ishii
 
Yesodを支える技術
Yesodを支える技術Yesodを支える技術
Yesodを支える技術Hiromi Ishii
 
Rhebok, High Performance Rack Handler / Rubykaigi 2015
Rhebok, High Performance Rack Handler / Rubykaigi 2015Rhebok, High Performance Rack Handler / Rubykaigi 2015
Rhebok, High Performance Rack Handler / Rubykaigi 2015Masahiro Nagano
 
アメブロの大規模システム刷新と それを支えるSpring
アメブロの大規模システム刷新と それを支えるSpringアメブロの大規模システム刷新と それを支えるSpring
アメブロの大規模システム刷新と それを支えるSpringTakuya Hattori
 
TRICK2015 results
TRICK2015 resultsTRICK2015 results
TRICK2015 resultsmametter
 
御清聴ありがとうございました
御清聴ありがとうございました御清聴ありがとうございました
御清聴ありがとうございましたHiromi Ishii
 
EPUBのナビゲーションを理解しよう
EPUBのナビゲーションを理解しようEPUBのナビゲーションを理解しよう
EPUBのナビゲーションを理解しようHiroshi Takase
 

Andere mochten auch (17)

ものまね鳥を愛でる 結合子論理と計算
ものまね鳥を愛でる 結合子論理と計算ものまね鳥を愛でる 結合子論理と計算
ものまね鳥を愛でる 結合子論理と計算
 
Techmix2014 温故知新
Techmix2014 温故知新Techmix2014 温故知新
Techmix2014 温故知新
 
Do you trust that certificate?
Do you trust that certificate?Do you trust that certificate?
Do you trust that certificate?
 
The worst Ruby codes I’ve seen in my life - RubyKaigi 2015
The worst Ruby codes I’ve seen in my life - RubyKaigi 2015The worst Ruby codes I’ve seen in my life - RubyKaigi 2015
The worst Ruby codes I’ve seen in my life - RubyKaigi 2015
 
Practical Testing of Ruby Core
Practical Testing of Ruby CorePractical Testing of Ruby Core
Practical Testing of Ruby Core
 
Ruby meets Go
Ruby meets GoRuby meets Go
Ruby meets Go
 
Plugin-based software design with Ruby and RubyGems
Plugin-based software design with Ruby and RubyGemsPlugin-based software design with Ruby and RubyGems
Plugin-based software design with Ruby and RubyGems
 
実践・完全犯罪のつくり方
実践・完全犯罪のつくり方実践・完全犯罪のつくり方
実践・完全犯罪のつくり方
 
(数式の入った)本をつくる
(数式の入った)本をつくる(数式の入った)本をつくる
(数式の入った)本をつくる
 
Alloy Analyzer のこと
Alloy Analyzer のことAlloy Analyzer のこと
Alloy Analyzer のこと
 
最終発表
最終発表最終発表
最終発表
 
Yesodを支える技術
Yesodを支える技術Yesodを支える技術
Yesodを支える技術
 
Rhebok, High Performance Rack Handler / Rubykaigi 2015
Rhebok, High Performance Rack Handler / Rubykaigi 2015Rhebok, High Performance Rack Handler / Rubykaigi 2015
Rhebok, High Performance Rack Handler / Rubykaigi 2015
 
アメブロの大規模システム刷新と それを支えるSpring
アメブロの大規模システム刷新と それを支えるSpringアメブロの大規模システム刷新と それを支えるSpring
アメブロの大規模システム刷新と それを支えるSpring
 
TRICK2015 results
TRICK2015 resultsTRICK2015 results
TRICK2015 results
 
御清聴ありがとうございました
御清聴ありがとうございました御清聴ありがとうございました
御清聴ありがとうございました
 
EPUBのナビゲーションを理解しよう
EPUBのナビゲーションを理解しようEPUBのナビゲーションを理解しよう
EPUBのナビゲーションを理解しよう
 

Ähnlich wie Template Haskell and QuasiQuoters

Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with ClojureDmitry Buzdin
 
Are we ready to Go?
Are we ready to Go?Are we ready to Go?
Are we ready to Go?Adam Dudczak
 
Beginning Haskell, Dive In, Its Not That Scary!
Beginning Haskell, Dive In, Its Not That Scary!Beginning Haskell, Dive In, Its Not That Scary!
Beginning Haskell, Dive In, Its Not That Scary!priort
 
An Elephant of a Different Colour: Hack
An Elephant of a Different Colour: HackAn Elephant of a Different Colour: Hack
An Elephant of a Different Colour: HackVic Metcalfe
 
Crafting Custom Interfaces with Sub::Exporter
Crafting Custom Interfaces with Sub::ExporterCrafting Custom Interfaces with Sub::Exporter
Crafting Custom Interfaces with Sub::ExporterRicardo Signes
 
Nik Graf - Get started with Reason and ReasonReact
Nik Graf - Get started with Reason and ReasonReactNik Graf - Get started with Reason and ReasonReact
Nik Graf - Get started with Reason and ReasonReactOdessaJS Conf
 
An Intro To ES6
An Intro To ES6An Intro To ES6
An Intro To ES6FITC
 
Tips and Tricks of Developing .NET Application
Tips and Tricks of Developing .NET ApplicationTips and Tricks of Developing .NET Application
Tips and Tricks of Developing .NET ApplicationJoni
 
Rewriting Java In Scala
Rewriting Java In ScalaRewriting Java In Scala
Rewriting Java In ScalaSkills Matter
 
JDays Lviv 2014: Java8 vs Scala: Difference points & innovation stream
JDays Lviv 2014:  Java8 vs Scala:  Difference points & innovation streamJDays Lviv 2014:  Java8 vs Scala:  Difference points & innovation stream
JDays Lviv 2014: Java8 vs Scala: Difference points & innovation streamRuslan Shevchenko
 
여자개발자모임터 6주년 개발 세미나 - Scala Language
여자개발자모임터 6주년 개발 세미나 - Scala Language여자개발자모임터 6주년 개발 세미나 - Scala Language
여자개발자모임터 6주년 개발 세미나 - Scala LanguageAshal aka JOKER
 
Scalding - Hadoop Word Count in LESS than 70 lines of code
Scalding - Hadoop Word Count in LESS than 70 lines of codeScalding - Hadoop Word Count in LESS than 70 lines of code
Scalding - Hadoop Word Count in LESS than 70 lines of codeKonrad Malawski
 
Monadologie
MonadologieMonadologie
Monadologieleague
 
Herding types with Scala macros
Herding types with Scala macrosHerding types with Scala macros
Herding types with Scala macrosMarina Sigaeva
 
Kotlin Basics - Apalon Kotlin Sprint Part 2
Kotlin Basics - Apalon Kotlin Sprint Part 2Kotlin Basics - Apalon Kotlin Sprint Part 2
Kotlin Basics - Apalon Kotlin Sprint Part 2Kirill Rozov
 
Kamil Chmielewski, Jacek Juraszek - "Hadoop. W poszukiwaniu złotego młotka."
Kamil Chmielewski, Jacek Juraszek - "Hadoop. W poszukiwaniu złotego młotka."Kamil Chmielewski, Jacek Juraszek - "Hadoop. W poszukiwaniu złotego młotka."
Kamil Chmielewski, Jacek Juraszek - "Hadoop. W poszukiwaniu złotego młotka."sjabs
 

Ähnlich wie Template Haskell and QuasiQuoters (20)

Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with Clojure
 
Are we ready to Go?
Are we ready to Go?Are we ready to Go?
Are we ready to Go?
 
Beginning Haskell, Dive In, Its Not That Scary!
Beginning Haskell, Dive In, Its Not That Scary!Beginning Haskell, Dive In, Its Not That Scary!
Beginning Haskell, Dive In, Its Not That Scary!
 
An Elephant of a Different Colour: Hack
An Elephant of a Different Colour: HackAn Elephant of a Different Colour: Hack
An Elephant of a Different Colour: Hack
 
Crafting Custom Interfaces with Sub::Exporter
Crafting Custom Interfaces with Sub::ExporterCrafting Custom Interfaces with Sub::Exporter
Crafting Custom Interfaces with Sub::Exporter
 
Nik Graf - Get started with Reason and ReasonReact
Nik Graf - Get started with Reason and ReasonReactNik Graf - Get started with Reason and ReasonReact
Nik Graf - Get started with Reason and ReasonReact
 
An Intro To ES6
An Intro To ES6An Intro To ES6
An Intro To ES6
 
Tips and Tricks of Developing .NET Application
Tips and Tricks of Developing .NET ApplicationTips and Tricks of Developing .NET Application
Tips and Tricks of Developing .NET Application
 
Rewriting Java In Scala
Rewriting Java In ScalaRewriting Java In Scala
Rewriting Java In Scala
 
A bit about Scala
A bit about ScalaA bit about Scala
A bit about Scala
 
JDays Lviv 2014: Java8 vs Scala: Difference points & innovation stream
JDays Lviv 2014:  Java8 vs Scala:  Difference points & innovation streamJDays Lviv 2014:  Java8 vs Scala:  Difference points & innovation stream
JDays Lviv 2014: Java8 vs Scala: Difference points & innovation stream
 
여자개발자모임터 6주년 개발 세미나 - Scala Language
여자개발자모임터 6주년 개발 세미나 - Scala Language여자개발자모임터 6주년 개발 세미나 - Scala Language
여자개발자모임터 6주년 개발 세미나 - Scala Language
 
Introduction to Scala
Introduction to ScalaIntroduction to Scala
Introduction to Scala
 
Scalding - Hadoop Word Count in LESS than 70 lines of code
Scalding - Hadoop Word Count in LESS than 70 lines of codeScalding - Hadoop Word Count in LESS than 70 lines of code
Scalding - Hadoop Word Count in LESS than 70 lines of code
 
Monadologie
MonadologieMonadologie
Monadologie
 
Herding types with Scala macros
Herding types with Scala macrosHerding types with Scala macros
Herding types with Scala macros
 
Kotlin Basics - Apalon Kotlin Sprint Part 2
Kotlin Basics - Apalon Kotlin Sprint Part 2Kotlin Basics - Apalon Kotlin Sprint Part 2
Kotlin Basics - Apalon Kotlin Sprint Part 2
 
Groovy
GroovyGroovy
Groovy
 
Kamil Chmielewski, Jacek Juraszek - "Hadoop. W poszukiwaniu złotego młotka."
Kamil Chmielewski, Jacek Juraszek - "Hadoop. W poszukiwaniu złotego młotka."Kamil Chmielewski, Jacek Juraszek - "Hadoop. W poszukiwaniu złotego młotka."
Kamil Chmielewski, Jacek Juraszek - "Hadoop. W poszukiwaniu złotego młotka."
 
ddd+scala
ddd+scaladdd+scala
ddd+scala
 

Mehr von Hiromi Ishii

Freer Monads, More Extensible Effects
Freer Monads, More Extensible EffectsFreer Monads, More Extensible Effects
Freer Monads, More Extensible EffectsHiromi Ishii
 
Lebesgue可測性に関するSoloayの定理と実数の集合の正則性
Lebesgue可測性に関するSoloayの定理と実数の集合の正則性Lebesgue可測性に関するSoloayの定理と実数の集合の正則性
Lebesgue可測性に関するSoloayの定理と実数の集合の正則性Hiromi Ishii
 
実数の集合はどこまで可測になれるか?
実数の集合はどこまで可測になれるか?実数の集合はどこまで可測になれるか?
実数の集合はどこまで可測になれるか?Hiromi Ishii
 
Lebesgue 可測性に関する Solovay-Shelah の結果に必要な記述集合論のごく基本的な事項
Lebesgue 可測性に関する Solovay-Shelah の結果に必要な記述集合論のごく基本的な事項Lebesgue 可測性に関する Solovay-Shelah の結果に必要な記述集合論のごく基本的な事項
Lebesgue 可測性に関する Solovay-Shelah の結果に必要な記述集合論のごく基本的な事項Hiromi Ishii
 
技術者が知るべき Gröbner 基底
技術者が知るべき Gröbner 基底技術者が知るべき Gröbner 基底
技術者が知るべき Gröbner 基底Hiromi Ishii
 
数学プログラムを Haskell で書くべき 6 の理由
数学プログラムを Haskell で書くべき 6 の理由数学プログラムを Haskell で書くべき 6 の理由
数学プログラムを Haskell で書くべき 6 の理由Hiromi Ishii
 
Algebraic DP: 動的計画法を書きやすく
Algebraic DP: 動的計画法を書きやすくAlgebraic DP: 動的計画法を書きやすく
Algebraic DP: 動的計画法を書きやすくHiromi Ishii
 
Yesod でブログエンジンをつくってみた
Yesod でブログエンジンをつくってみたYesod でブログエンジンをつくってみた
Yesod でブログエンジンをつくってみたHiromi Ishii
 
How wonderful to be (statically) typed 〜型が付くってスバラシイ〜
How wonderful to be (statically) typed 〜型が付くってスバラシイ〜How wonderful to be (statically) typed 〜型が付くってスバラシイ〜
How wonderful to be (statically) typed 〜型が付くってスバラシイ〜Hiromi Ishii
 

Mehr von Hiromi Ishii (9)

Freer Monads, More Extensible Effects
Freer Monads, More Extensible EffectsFreer Monads, More Extensible Effects
Freer Monads, More Extensible Effects
 
Lebesgue可測性に関するSoloayの定理と実数の集合の正則性
Lebesgue可測性に関するSoloayの定理と実数の集合の正則性Lebesgue可測性に関するSoloayの定理と実数の集合の正則性
Lebesgue可測性に関するSoloayの定理と実数の集合の正則性
 
実数の集合はどこまで可測になれるか?
実数の集合はどこまで可測になれるか?実数の集合はどこまで可測になれるか?
実数の集合はどこまで可測になれるか?
 
Lebesgue 可測性に関する Solovay-Shelah の結果に必要な記述集合論のごく基本的な事項
Lebesgue 可測性に関する Solovay-Shelah の結果に必要な記述集合論のごく基本的な事項Lebesgue 可測性に関する Solovay-Shelah の結果に必要な記述集合論のごく基本的な事項
Lebesgue 可測性に関する Solovay-Shelah の結果に必要な記述集合論のごく基本的な事項
 
技術者が知るべき Gröbner 基底
技術者が知るべき Gröbner 基底技術者が知るべき Gröbner 基底
技術者が知るべき Gröbner 基底
 
数学プログラムを Haskell で書くべき 6 の理由
数学プログラムを Haskell で書くべき 6 の理由数学プログラムを Haskell で書くべき 6 の理由
数学プログラムを Haskell で書くべき 6 の理由
 
Algebraic DP: 動的計画法を書きやすく
Algebraic DP: 動的計画法を書きやすくAlgebraic DP: 動的計画法を書きやすく
Algebraic DP: 動的計画法を書きやすく
 
Yesod でブログエンジンをつくってみた
Yesod でブログエンジンをつくってみたYesod でブログエンジンをつくってみた
Yesod でブログエンジンをつくってみた
 
How wonderful to be (statically) typed 〜型が付くってスバラシイ〜
How wonderful to be (statically) typed 〜型が付くってスバラシイ〜How wonderful to be (statically) typed 〜型が付くってスバラシイ〜
How wonderful to be (statically) typed 〜型が付くってスバラシイ〜
 

Template Haskell and QuasiQuoters

  • 1. Metaprogramming in Haskell
  • 2. Table of Contents Template Haskell Generic Programming in Haskell (Type-level Programming)
  • 3. Table of Contents Template Haskell Generic Programming in Haskell (Type-level Programming)
  • 7. HOC - Haskell Objective-C binding Class/Instance jmacro JavaScript HAppS lambdabot IRC Bot (IRC )
  • 8. TH
  • 9. TH
  • 10. TH IO
  • 11. TH IO ( reify )
  • 12. TH IO ( reify ) DSL
  • 13. TH
  • 14. TH ( )
  • 15. TH ( ) Template Haskell
  • 16. TH ( ) Template Haskell Q IO
  • 17. TH ( ) Template Haskell Q IO compile-time wxWidgets, Socket, etc...
  • 18. TH Features {-# LANGUAGE TemplateHaskell, QuasiQuotes #-} import Language.Haskell.TH splice reify / runIO
  • 19. DEMO
  • 20. 2 RandomDef.hs
  • 21. 2 RandomDef.hs {-# LANGUAGE TemplateHaskell #-} module Main where import Language.Haskell.TH import System.Random $( do rnd ← runIO $ randomRIO (0,1) let nm = mkName (["a", "b"] !! rnd) m ← [d| main = $(varE $ mkName "a") |] t ← valD (varP nm) (normalB [| putStrLn " `) " |]) [] (´ return (t:m) )
  • 22. (RandomDef.hs) {-# LANGUAGE TemplateHaskell #-} module Main where import Language.Haskell.TH import System.Random $( do rnd ← runIO $ randomRIO (0,1) let nm = mkName (["a", "b"] !! rnd) m ← [d| main = $(varE $ mkName "a") |] t ← valD (varP nm) (normalB [| putStrLn " `) " |]) [] (´ return (t:m) )
  • 23.
  • 25. Template Haskell Exp Dec Pat Type
  • 26. Template Haskell Exp Dec Pat Type ……(cf. HOC)
  • 27. Template Haskell Exp Dec Pat Type ……(cf. HOC) Q
  • 28. putStrLn “Hello!” = AppE (VarE ‘putStrLn) (LitE (stringL “Hello!”)) main :: IO () main = getLine >>= putStrLn [ SigD (mkName "main") (AppT (VarT ''IO) (VarT ''())), FunD (mkName "main") [Clause [] (NormalB $ InfixE (Just $ VarE 'getLine) (VarE '(>>=)) (Just $ VarE 'putStrLn) ) []]]
  • 29. lib2 = let l=LetS[ValD(VarP $ mkName"it")(NormalB(f"be"))[]] f=VarE . mkName in DoE [ l, l, l, NoBindS $ f"oh",l, NoBindS $ InfixE(Just$ f"speaking")(f"words")(Just $ f "wisdom"),l]
  • 30. lib2 = let l=LetS[ValD(VarP $ mkName"it")(NormalB(f"be"))[]] f=VarE . mkName in DoE [ l, l, l, NoBindS $ f"oh",l, NoBindS $ InfixE(Just$ f"speaking")(f"words")(Just $ f "wisdom"),l] do let it = be let it = be let it = be oh let it = be speaking `words` wisdom let it = be
  • 31. k GHCi GHCi> runQ [d| data List a = Cons a (List a) | Nil |] [DataD [] List [PlainTV a_0] [NormalC Cons [(NotStrict,VarT a_0), (NotStrict,AppT (ConT List) (VarT a_0))],NormalC Nil []] []]
  • 32. [k| |] (“k” ) Q [e| putStrLn “foo” |] (e ) [d| main = putStrLn “:-)” |] [t| Maybe String |] [p| Just 2 |] (GHC HEAD) ( ) `a, ``Maybe ( )
  • 33. {-# LANGUAGE TemplateHaskell #-} module Main where import Language.Haskell.TH import System.Random $( do rnd ← runIO $ randomRIO (0,1) let nm = mkName (["a", "b"] !! rnd) m ← [d| main = $(varE $ mkName "a") |] t ← valD (varP nm) (normalB [| putStrLn " ( ´ `) " |]) [] return (t:m) )
  • 34. (RandomDef.hs) {-# LANGUAGE TemplateHaskell #-} module Main where import Language.Haskell.TH import System.Random + $( do rnd ← runIO $ randomRIO (0,1) let nm = mkName (["a", "b"] !! rnd) m ← [d| main = $(varE $ mkName "a") |] t ← valD (varP nm) (normalB [| putStrLn " ( ´ `) " |]) [] return (t:m) )
  • 37. (Splice) Q $( )
  • 38. (Splice) Q $( )
  • 39. (Splice) Q $( ) main = $(1 + ‘a) :: $(myType)
  • 40. (Splice) Q $( ) main = $(1 + ‘a) :: $(myType) $() (6.12 )
  • 41. (Splice) Q $( ) main = $(1 + ‘a) :: $(myType) $() (6.12 ) Splice (6.12 )
  • 42. (Splice) Q $( ) main = $(1 + ‘a) :: $(myType) $() (6.12 ) Splice (6.12 ) Splice import
  • 43. (Splice) Q $( ) main = $(1 + ‘a) :: $(myType) $() (6.12 ) Splice (6.12 ) Splice import
  • 47. Q Monad IO runIO $ ...
  • 48. Q Monad IO runIO $ ... (reify)
  • 49. Q Monad IO runIO $ ... (reify) Q
  • 50. Q Monad IO runIO $ ... (reify) Q GHCi runQ $ reify ''Maybe
  • 51. IO {-# LANGUAGE TemplateHaskell #-} module Main where import Language.Haskell.THIO Get import System.Random $( do rnd ← runIO $ randomRIO (0,1) let nm = mkName (["a", "b"] !! rnd) m ← [d| main = $(varE $ mkName "a") |] t ← valD (varP nm) (normalB [| putStrLn " `) " |]) [] (´ return (t:m) )
  • 52. {-# LANGUAGE TemplateHaskell #-} module Main where import Language.Haskell.TH import System.Random $( do rnd ← runIO $ randomRIO (0,1) let nm = mkName (["a", "b"] !! rnd) m ← [d| main = $(varE $ mkName "a") |] t ← valD (varP nm) (normalB [| putStrLn " `) " |]) [] (´ return (t:m) )
  • 53. reify compile-time ( ) derive DEMO
  • 54.
  • 55. LISP
  • 56. LISP EDSL
  • 57. LISP EDSL
  • 58. LISP EDSL GHC HEAD
  • 59. LISP EDSL GHC HEAD [$ident| ... |]
  • 60. LISP EDSL GHC HEAD [$ident| ... |] ident QuasiQuoter
  • 61. LISP EDSL GHC HEAD [$ident| ... |] ident QuasiQuoter String → ExpQ String → PatQ
  • 62. LISP EDSL GHC HEAD [$ident| ... |] ident QuasiQuoter String → ExpQ String → PatQ Graph JSON
  • 63. mkTweet :: Int → String → JSValue → JSValue mkTweet tid text = [$json| {“status”: { “id”: #int<tid>, “text”: #str<text> }} |] getID :: JSValue → Int getID [$json| “id”:#Int{var} |] = var
  • 64. mkTweet :: Int → String → JSValue → JSValue mkTweet tid text = [$json| {“status”: { “id”: #int<tid>, “text”: #str<text> }} |] getID :: JSValue → Int getID [$json| “id”:#Int{var} |] = var ( )
  • 65. mkTweet :: Int → String → JSValue → JSValue mkTweet tid text = [$json| {“status”: { “id”: #int<tid>, “text”: #str<text> }} |] getID :: JSValue → Int getID [$json| “id”:#Int{var} |] = var ( )
  • 66. JSON data JSON = JSNumber Int | JSString String | ... | Var String deriving (Show, Eq, Ord) -- QuasiQuoter json :: QuasiQuoter json = QuasiQuoter quoteJSONExp quoteJSONPat quoteJSONExp :: String → ExpQ quoteJSONPat :: String → PatQ quoteJSONPat src = ... quoteJSONExp src = ...
  • 67. JSON data JSON = JSNumber Int | JSString String | ... | Var String deriving (Show, Eq, Ord) -- QuasiQuoter json :: QuasiQuoter json = QuasiQuoter quoteJSONExp quoteJSONPat quoteJSONExp :: String → ExpQ quoteJSONPat :: String → PatQ quoteJSONPat src = ... quoteJSONExp src = ...
  • 68. JSON data JSON = JSNumber Int | JSString String | ... | Var String deriving (Show, Eq, Ord) -- QuasiQuoter json :: QuasiQuoter json = QuasiQuoter quoteJSONExp quoteJSONPat quoteJSONExp :: String → ExpQ quoteJSONPat :: String → PatQ quoteJSONPat src = ... quoteJSONExp src = ...
  • 69. JSON data JSON = JSNumber Int | JSString String | ... | Var String deriving (Show, Eq, Ord) -- QuasiQuoter json :: QuasiQuoter json = QuasiQuoter quoteJSONExp quoteJSONPat quoteJSONExp :: String → ExpQ quoteJSONPat :: String → PatQ quoteJSONPat src = ... quoteJSONExp src = ...
  • 70.
  • 71.
  • 73. dataToExpQ, dataToPatQ jsonPat src= dataToPatQ (const Nothing `extQ` antiQuoteP) (parseJSON src) antiQuoteP (Var a) = Just (varP (mkName a)) antiQuoteP _ = Nothing
  • 74. dataToExpQ, dataToPatQ jsonPat src= dataToPatQ (const Nothing `extQ` antiQuoteP) (parseJSON src) antiQuoteP (Var a) = Just (varP (mkName a)) antiQuoteP _ = Nothing
  • 75. data JSON = JSNumber Int | JSString String | ... | Var String deriving (Show, Eq, Ord, Data, Typeable) ... parseExpr = ... -- Parser quoteJSONPat src = do let exp = parseExpr src dataToPatQ (const Nothing `extQ` antiStrPat) exp antiStrPat :: Expr → Maybe PatQ antiStrPat (Var a) = Just $ varP (mkName a) antiStrPat _ = Nothing
  • 76. data JSON = JSNumber Int | JSString String | ... | Var String deriving (Show, Eq, Ord, Data, Typeable) ... parseExpr = ... -- Parser quoteJSONPat src = do let exp = parseExpr src dataToPatQ (const Nothing `extQ` antiStrPat) exp antiStrPat :: Expr → Maybe PatQ antiStrPat (Var a) = Just $ varP (mkName a) antiStrPat _ = Nothing
  • 77. data JSON = JSNumber Int | JSString String | ... | Var String deriving (Show, Eq, Ord, Data, Typeable) ... parseExpr = ... -- Parser quoteJSONPat src = do let exp = parseExpr src dataToPatQ (const Nothing `extQ` antiStrPat) exp antiStrPat :: Expr → Maybe PatQ antiStrPat (Var a) = Just $ varP (mkName a) antiStrPat _ = Nothing Var
  • 78. …… dataToExpQ extQ …… ……
  • 79. Generic Programming in Haskell Template Haskell Generic Programming in Haskell (Type-level Programming)
  • 81. Haskell ——Wikipedia
  • 82. Haskell ——Wikipedia =
  • 83. Haskell ——Wikipedia =
  • 84. Haskell ——Wikipedia =
  • 85.
  • 86. Generic Programming in Haskell (Generics ; GHC ) SYB (Scrap Your Boilerplate) Instant Generics
  • 87. Generic Programming in Haskell (Generics ; GHC ) SYB (Scrap Your Boilerplate) Instant Generics
  • 88.
  • 89.
  • 93. Sum of Product ( ) {-# LANGUAGE Generics, TypeOperators #-}
  • 94. Sum of Product ( ) {-# LANGUAGE Generics, TypeOperators #-} import GHC.Generics
  • 95. data Bool = False | True = Unit :+: Unit data Maybe a = Nothing | Just a = Unit :+: a Just 12 = Inr 12, Nothing = Inl Unit data List a = Nil | Cons a (List a) = Unit :+: (a :*: (List a)) [1,2,3] = Inr (1 :*: Inr (2 :*: Inr (3 :*: Inl Unit)))
  • 96. Binary Encode class Bin a where toBin :: a → [Int] fromBin :: [Int] → (a, [Int]) toBin {| Unit |} Unit = [0] toBin {| p :*: q |} (a :*: b) = toBin a ++ toBin b toBin {| p :+: q |} (Inl a) = 0:toBin a toBin {| p :+: q |} (Inr b) = 1:toBin b fromBin {| Unit |} (0:xs) = (Unit, xs) fromBin {| p :*: q |} bin = let (a, bin') = fromBin bin (b, bin'') = fromBin bin' ...
  • 97. class Bin a where toBin :: a → [Int] fromBin :: [Int] → (a, [Int]) toBin {| Unit |} Unit = [0] toBin {| p :*: q |} (a :*: b) = toBin a ++ toBin b toBin {| p :+: q |} (Inl a) = 0:toBin a toBin {| p :+: q |} (Inr b) = 1:toBin b fromBin {| Unit |} (0:xs) = (Unit, xs) fromBin {| p :*: q |} bin = let (a, bin') = fromBin bin (b, bin'') = fromBin bin' in ...
  • 98. class Bin a where toBin :: a → [Int] fromBin :: [Int] → (a, [Int]) toBin {| Unit |} Unit = [0] toBin {| p :*: q |} (a :*: b) = toBin a ++ toBin b toBin {| p :+: q |} (Inl a) = 0:toBin a toBin {| p :+: q |} (Inr b) = 1:toBin b fromBin {| Unit |} (0:xs) = (Unit, xs) fromBin {| p :*: q |} bin = let (a, bin') = fromBin bin (b, bin'') = fromBin bin' in (a :*: b, bin’’) ...
  • 99. ( Int, Char) instance instance Bin Int where toBin = .... instance Bin Char where toBin = ... instance Bin a Bin [a] instance (Bin a, Bin b) Bin (a, b) instance Bin a Bin (Maybe a) instance (Bin a, Bin b) Bin (Either a b)
  • 100. DEMO
  • 101. default method a [a] Maybe a
  • 102. Generic Programming in Haskell (Generics ; GHC ) SYB (Scrap Your Boilerplate) Instant Generics
  • 103. Scrap Your Boilerplate syb Haskell dataToExpQ
  • 105. Typeable / Data Typeable: cast ( )
  • 106. Typeable / Data Typeable: cast ( ) Data: (gfoldl) cast
  • 107. Typeable / Data GHC {-# LANGUAGE DeriveDataTypeable #-} data Tree a = Leaf a | Branch (Tree a) (Tree a) deriving (Data, Typeable) Standalone deriving {-# LANGUAGE StandaloneDeriving #-} deriving instance Typeable1 Tree deriving instance Data a Data (Tree a)
  • 108. -- data Expr = Num Int | Var String | Plus Expr Expr | Minus Expr Expr | Multi Expr Expr | Div Expr Expr deriving (Show, Eq, Data, Typeable) normalize :: Expr → Expr normalize = everywhere (mkT normalize') normalize' (Plus (Num n) (Num m)) = Num (n + m) normalize' (Multi (Num n) (Num m)) = Num (n * m) normalize' (Minus (Num n) (Num m)) = Num (n - m) normalize' (Div (Num n) (Num m)) = Num (n `div` m) normalize' x =x
  • 109. SYB
  • 110. SYB
  • 111. SYB
  • 112. SYB
  • 113. SYB mkT :: (b → b) → (a → a)
  • 114. SYB mkT :: (b → b) → (a → a)
  • 115. SYB mkT :: (b → b) → (a → a) everywhere :: GenericT → GenericT
  • 116. SYB mkT :: (b → b) → (a → a) everywhere :: GenericT → GenericT bottom-up
  • 117. SYB mkT :: (b → b) → (a → a) everywhere :: GenericT → GenericT bottom-up top-down everywhere'
  • 118. (1) GenericT = ∀a. a → a Transformer mkT fun trans `extT` fun GenericM = ∀a. a → m a : GenericQ = ∀a. a → r Query ( ) `mkQ` fun query `extQ` fun
  • 119. (2) GenericB = ∀a. a Builder builder `extB` fun GenericR = ∀a. m a Reader mkR fun reader `extR` fun
  • 120. gmapT :: GenericT → a → a somewhere :: GenericM m → GenecirM m everything :: (r → r → r) → GenericQ r → GenericQ r listify :: (r → Bool) → GenericQ [r] gsize/glength :: GenericQ Int
  • 121. dataToExpQ dataToExpQ :: Data a GenericQ (Maybe ExpQ) → a → ExpQ (const Nohting `ext` anti)
  • 122. SYB
  • 123. SYB
  • 125. Generic Programming in Haskell (Generics ; GHC ) SYB (Scrap Your Boilerplate) Instant Generics
  • 127. Instant Generics (Type families) DPH (Data Parallel Haskell)
  • 128.
  • 129.
  • 134. IG Representable a type Rep a data U = U data a :+: b = L a | R b ( ) data a :*: b = a :*: b data C con a = C a data Var p = Var p data Rec p = Rec p
  • 135. Int, Bool Int, Bool data Maybe a = Nothing | Just a type Rep (Maybe a) = C Maybe_Nothing_ U :+: C Maybe_Just_ (Var a) Just 12 = R(C(Var 12)), Nothing = L(C U)
  • 136. Int, Bool Int, Bool data Maybe a = Nothing | Just a type Rep (Maybe a) = C Maybe_Nothing_ U :+: C Maybe_Just_ (Var a) Just 12 = R(C(Var 12)), Nothing = L(C U)
  • 137. 1 Binary Encode class Bin a where toBin :: a → [Int] fromBin :: [Int] → (a, [Int]) C, Var, Rec instance Bin U where toBin U = [] fromBin xs = (U, []) instance (Bin a, Bin b) Bin (a :+: b) where toBin (L a) = 0:toBin a toBin (R b) = 1:toBin b fromBin (0:bin) = ... ... instance (Bin a, Bin b) Bin (a :*: b) where toBin (a :*: b) = toBin a ++ toBin b fromBin bin = ... instance Bin Int where ...
  • 138. def_toBin :: (Representable a, Bin (Rep a)) a → [Int] def_toBin = toBin . from ... instance Bin a Bin [a] where toBin = def_toBin; fromBin = def_fromBin
  • 139. 2 ! class Normalize a where normalize :: a → a instance Normalize U instance Normalize (Var a) ... instance Normalize a Normalize (Rec a) where normalize (Rec a) = Rec (normalize a)
  • 140. 2 ! class Normalize a where normalize :: a → a instance Normalize U instance Normalize (Var a) ... instance Normalize a Normalize (Rec a) where normalize (Rec a) = Rec (normalize a)
  • 141. 2 ! class Normalize a where normalize :: a → a instance Normalize U instance Normalize (Var a) ... instance Normalize a Normalize (Rec a) where normalize (Rec a) = Rec (normalize a)
  • 142. 2 ! class Normalize a where normalize :: a → a instance Normalize U instance Normalize (Var a) ... instance Normalize a Normalize (Rec a) where normalize (Rec a) = Rec (normalize a)
  • 143. Expr dft_normalize :: (Representable a, Normalize (Rep a)) a→a dft_normalize = to . normalize . from instance Normalize Expr where normalize x = case dft_normalize x of Plus (Num n) (Num m) → Num (n + m) Multi (Num n) (Num m) → Num (n * m) Minus (Num n) (Num m) → Num (n - m) Div (Num n) (Num m) → Num (n `div` m) x →x Var Int, Char
  • 147. 100000(ms) 10000(ms) 1000(ms) 100(ms) 10(ms) 1(ms) geq rmWeights selectInt selectIntAcc SYB Instant Generics
  • 148. 100000(ms) 10000(ms) 1000(ms) 100(ms) 10(ms) 1(ms) geq rmWeights selectInt selectIntAcc SYB Instant Generics
  • 149. 100000(ms) 10000(ms) 1000(ms) 100(ms) 10(ms) 1(ms) geq rmWeights selectInt selectIntAcc SYB Instant Generics
  • 150. 100000(ms) 10000(ms) 1000(ms) 100(ms) 10(ms) 1(ms) geq rmWeights selectInt selectIntAcc SYB Instant Generics
  • 151. 100000(ms) 75000(ms) 50000(ms) 25000(ms) 0(ms) geq rmWeights selectInt selectIntAcc SYB Instant Generics
  • 152. SYB
  • 154. GP SYB with class Data Smash ( ) SYB Uniplate MPTC