Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Functional stuff: GADT, Existential types, Rank-N-Types, ...

Functional stuff: GADT, Existential types, Rank-N-Types, ...

Wrocław, 25.03.2015
"Advanced functional programming" seminar
Institute of Computer Science
University of Wrocław

Rafał Łasocha

March 25, 2015
Tweet

More Decks by Rafał Łasocha

Other Decks in Research

Transcript

  1. Recap
    Existential types
    Rank-N Types
    Examples
    Functional stuff:
    GADT, Existential types, Rank-N-Types, ...
    Rafal Lasocha
    Wroclaw, 25th March 2015
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  2. Recap
    Existential types
    Rank-N Types
    Examples
    Phantom types
    Generalized Algebraic Data Types
    A phantom type is a parametrised type whose parameters do not all
    appear on the right-hand side of its definition
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  3. Recap
    Existential types
    Rank-N Types
    Examples
    Phantom types
    Generalized Algebraic Data Types
    data FormData a = FormData String
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  4. Recap
    Existential types
    Rank-N Types
    Examples
    Phantom types
    Generalized Algebraic Data Types
    data FormData a = FormData String
    data Validated
    data Unvalidated
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  5. Recap
    Existential types
    Rank-N Types
    Examples
    Phantom types
    Generalized Algebraic Data Types
    data FormData a = FormData String
    data Validated
    data Unvalidated
    formData :: String -> FormData Unvalidated
    formData str = FormData str
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  6. Recap
    Existential types
    Rank-N Types
    Examples
    Phantom types
    Generalized Algebraic Data Types
    data FormData a = FormData String
    data Validated
    data Unvalidated
    formData :: String -> FormData Unvalidated
    formData str = FormData str
    validate :: FormData Unvalidated -> Maybe (FormData Validated)
    validate (FormData str) = ...
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  7. Recap
    Existential types
    Rank-N Types
    Examples
    Phantom types
    Generalized Algebraic Data Types
    data FormData a = FormData String
    data Validated
    data Unvalidated
    formData :: String -> FormData Unvalidated
    formData str = FormData str
    validate :: FormData Unvalidated -> Maybe (FormData Validated)
    validate (FormData str) = ...
    useData :: FormData Validated -> IO ()
    useData (FormData str) = ...
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  8. Recap
    Existential types
    Rank-N Types
    Examples
    Phantom types
    Generalized Algebraic Data Types
    data FormData a = FormData String
    data Validated
    data Unvalidated
    formData :: String -> FormData Unvalidated
    formData str = FormData str
    validate :: FormData Unvalidated -> Maybe (FormData Validated)
    validate (FormData str) = ...
    useData :: FormData Validated -> IO ()
    useData (FormData str) = ...
    liftStringFn :: (String -> String) -> FormData a -> FormData a
    liftStringFn fn (FormData str) = FormData (fn str)
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  9. Recap
    Existential types
    Rank-N Types
    Examples
    Phantom types
    Generalized Algebraic Data Types
    data FormData a = FormData String
    data Validated
    data Unvalidated
    formData :: String -> FormData Unvalidated
    formData str = FormData str
    validate :: FormData Unvalidated -> Maybe (FormData Validated)
    validate (FormData str) = ...
    useData :: FormData Validated -> IO ()
    useData (FormData str) = ...
    liftStringFn :: (String -> String) -> FormData a -> FormData a
    liftStringFn fn (FormData str) = FormData (fn str)
    dataToUpper :: FormData a -> FormData a
    dataToUpper = liftStringFn (map toUpper)
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  10. Recap
    Existential types
    Rank-N Types
    Examples
    Phantom types
    Generalized Algebraic Data Types
    Generalised Algebraic Datatypes (GADTs) are datatypes for which a
    constructor has a non standard type.
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  11. Recap
    Existential types
    Rank-N Types
    Examples
    Phantom types
    Generalized Algebraic Data Types
    Generalised Algebraic Datatypes (GADTs) are datatypes for which a
    constructor has a non standard type.
    data Empty
    data NonEmpty
    data List x y where
    Nil :: List a Empty
    Cons:: a -> List a b -> List a NonEmpty
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  12. Recap
    Existential types
    Rank-N Types
    Examples
    Phantom types
    Generalized Algebraic Data Types
    Generalised Algebraic Datatypes (GADTs) are datatypes for which a
    constructor has a non standard type.
    data Empty
    data NonEmpty
    data List x y where
    Nil :: List a Empty
    Cons:: a -> List a b -> List a NonEmpty
    safeHead:: List x NonEmpty -> x
    safeHead (Cons a b) = a
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  13. Recap
    Existential types
    Rank-N Types
    Examples
    Phantom types
    Generalized Algebraic Data Types
    Generalised Algebraic Datatypes (GADTs) are datatypes for which a
    constructor has a non standard type.
    data Empty
    data NonEmpty
    data List x y where
    Nil :: List a Empty
    Cons:: a -> List a b -> List a NonEmpty
    safeHead:: List x NonEmpty -> x
    safeHead (Cons a b) = a
    silly 0 = Nil
    silly 1 = Cons 1 Nil
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  14. Recap
    Existential types
    Rank-N Types
    Examples
    Phantom types
    Generalized Algebraic Data Types
    Generalised Algebraic Datatypes (GADTs) are datatypes for which a
    constructor has a non standard type.
    data Empty
    data NonEmpty
    data List x y where
    Nil :: List a Empty
    Cons:: a -> List a b -> List a NonEmpty
    safeHead:: List x NonEmpty -> x
    safeHead (Cons a b) = a
    silly 0 = Nil
    silly 1 = Cons 1 Nil
    it can’t infer proper type!
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  15. Recap
    Existential types
    Rank-N Types
    Examples
    Definition
    Usage
    An Existential type is a type which is using in constructors parameters
    which are not parameters of this type (they are not declared in left hand
    side of the type’s definition).
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  16. Recap
    Existential types
    Rank-N Types
    Examples
    Definition
    Usage
    An Existential type is a type which is using in constructors parameters
    which are not parameters of this type (they are not declared in left hand
    side of the type’s definition).
    data Worker b x = Worker {buffer :: b, input :: x}
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  17. Recap
    Existential types
    Rank-N Types
    Examples
    Definition
    Usage
    An Existential type is a type which is using in constructors parameters
    which are not parameters of this type (they are not declared in left hand
    side of the type’s definition).
    data Worker b x = Worker {buffer :: b, input :: x}
    data Worker x =
    forall b. Buffer b => Worker {buffer :: b, input :: x}
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  18. Recap
    Existential types
    Rank-N Types
    Examples
    Definition
    Usage
    An Existential type is a type which is using in constructors parameters
    which are not parameters of this type (they are not declared in left hand
    side of the type’s definition).
    data Worker b x = Worker {buffer :: b, input :: x}
    data Worker x =
    forall b. Buffer b => Worker {buffer :: b, input :: x}
    data MemoryBuffer = MemoryBuffer
    memoryWorker = Worker MemoryBuffer (1 :: Int)
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  19. Recap
    Existential types
    Rank-N Types
    Examples
    Definition
    Usage
    An Existential type is a type which is using in constructors parameters
    which are not parameters of this type (they are not declared in left hand
    side of the type’s definition).
    data Worker b x = Worker {buffer :: b, input :: x}
    data Worker x =
    forall b. Buffer b => Worker {buffer :: b, input :: x}
    data MemoryBuffer = MemoryBuffer
    memoryWorker = Worker MemoryBuffer (1 :: Int)
    memoryWorker :: Worker Int
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  20. Recap
    Existential types
    Rank-N Types
    Examples
    Definition
    Usage
    An Existential type is a type which is using in constructors parameters
    which are not parameters of this type (they are not declared in left hand
    side of the type’s definition).
    data Worker b x = Worker {buffer :: b, input :: x}
    data Worker x =
    forall b. Buffer b => Worker {buffer :: b, input :: x}
    data MemoryBuffer = MemoryBuffer
    memoryWorker = Worker MemoryBuffer (1 :: Int)
    memoryWorker :: Worker Int
    it’s impossible for function to demand specific Buffer
    you’re more limited in what you can do with Worker like that
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  21. Recap
    Existential types
    Rank-N Types
    Examples
    Definition
    Usage
    data Worker b x = Worker {buffer :: b, input :: x}
    data Worker x =
    forall b. Buffer b => Worker {buffer :: b, input :: x}
    data MemoryBuffer = MemoryBuffer
    memoryWorker = Worker MemoryBuffer (1 :: Int)
    memoryWorker :: Worker Int
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  22. Recap
    Existential types
    Rank-N Types
    Examples
    Definition
    Usage
    data Worker b x = Worker {buffer :: b, input :: x}
    data Worker x =
    forall b. Buffer b => Worker {buffer :: b, input :: x}
    data MemoryBuffer = MemoryBuffer
    memoryWorker = Worker MemoryBuffer (1 :: Int)
    memoryWorker :: Worker Int
    data NetBuffer = NetBuffer
    netWorker = Worker NetBuffer (2 :: Int)
    netWorker :: Worker Int
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  23. Recap
    Existential types
    Rank-N Types
    Examples
    Definition
    Usage
    data Worker b x = Worker {buffer :: b, input :: x}
    data Worker x =
    forall b. Buffer b => Worker {buffer :: b, input :: x}
    data MemoryBuffer = MemoryBuffer
    memoryWorker = Worker MemoryBuffer (1 :: Int)
    memoryWorker :: Worker Int
    data NetBuffer = NetBuffer
    netWorker = Worker NetBuffer (2 :: Int)
    netWorker :: Worker Int
    workers = [netWorker, memoryWorker]
    workers :: [Worker Int]
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  24. Recap
    Existential types
    Rank-N Types
    Examples
    Definition
    Example
    Rank-N types are types, which are using “forall” keyword in their’s
    definition, and it cannot be moved above (in AST of type sense).
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  25. Recap
    Existential types
    Rank-N Types
    Examples
    Definition
    Example
    Rank-N types are types, which are using “forall” keyword in their’s
    definition, and it cannot be moved above (in AST of type sense).
    ghci> let putInList x = [x]
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  26. Recap
    Existential types
    Rank-N Types
    Examples
    Definition
    Example
    Rank-N types are types, which are using “forall” keyword in their’s
    definition, and it cannot be moved above (in AST of type sense).
    ghci> let putInList x = [x]
    ghci> liftTup putInList (5, ”Blah”) # We want to achieve this!
    ([5], [”Blah”])
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  27. Recap
    Existential types
    Rank-N Types
    Examples
    Definition
    Example
    ghci> liftTup (\x -> [x]) (5, ”Blah”) # We want to achieve this!
    ([5], [”Blah”])
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  28. Recap
    Existential types
    Rank-N Types
    Examples
    Definition
    Example
    ghci> liftTup (\x -> [x]) (5, ”Blah”) # We want to achieve this!
    ([5], [”Blah”])
    −− First try :
    ghci> let liftTup liftFunc (a, b) = (liftFunc a, liftFunc b)
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  29. Recap
    Existential types
    Rank-N Types
    Examples
    Definition
    Example
    ghci> liftTup (\x -> [x]) (5, ”Blah”) # We want to achieve this!
    ([5], [”Blah”])
    −− First try :
    ghci> let liftTup liftFunc (a, b) = (liftFunc a, liftFunc b)
    ghci> liftTup (\x -> [x]) (5, ”Hello”)
    No instance for (Num [Char]) arising from literal ’5’
    ...
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  30. Recap
    Existential types
    Rank-N Types
    Examples
    Definition
    Example
    ghci> liftTup (\x -> [x]) (5, ”Blah”) # We want to achieve this!
    ([5], [”Blah”])
    −− First try :
    ghci> let liftTup liftFunc (a, b) = (liftFunc a, liftFunc b)
    ghci> liftTup (\x -> [x]) (5, ”Hello”)
    No instance for (Num [Char]) arising from literal ’5’
    ...
    ghci> :t liftTup
    liftTup :: (t -> t1) -> (t, t) -> (t1, t1)
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  31. Recap
    Existential types
    Rank-N Types
    Examples
    Definition
    Example
    ghci> liftTup (\x -> [x]) (5, ”Blah”) # We want to achieve this!
    ([5], [”Blah”])
    −− First try :
    ...
    ghci> :t liftTup
    liftTup :: (t -> t1) -> (t, t) -> (t1, t1)
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  32. Recap
    Existential types
    Rank-N Types
    Examples
    Definition
    Example
    ghci> liftTup (\x -> [x]) (5, ”Blah”) # We want to achieve this!
    ([5], [”Blah”])
    −− First try :
    ...
    ghci> :t liftTup
    liftTup :: (t -> t1) -> (t, t) -> (t1, t1)
    −− Second try
    −− test.hs:
    liftTup :: (x -> f x) -> (a, b) -> (f a, f b)
    liftTup liftFunc (t, v) = (liftFunc t, liftFunc v)
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  33. Recap
    Existential types
    Rank-N Types
    Examples
    Definition
    Example
    ghci> liftTup (\x -> [x]) (5, ”Blah”) # We want to achieve this!
    ([5], [”Blah”])
    −− First try :
    ...
    ghci> :t liftTup
    liftTup :: (t -> t1) -> (t, t) -> (t1, t1)
    −− Second try
    −− test.hs:
    liftTup :: (x -> f x) -> (a, b) -> (f a, f b)
    liftTup liftFunc (t, v) = (liftFunc t, liftFunc v)
    ghci> :l test.hs
    Couldnt match expected type ’x’ against inferred type ’a’
    ...
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  34. Recap
    Existential types
    Rank-N Types
    Examples
    Definition
    Example
    ghci> liftTup (\x -> [x]) (5, ”Blah”) # We want to achieve this!
    ([5], [”Blah”])
    −− Second try
    liftTup :: (x -> f x) -> (a, b) -> (f a, f b)
    ...
    −− Third try
    liftTup :: (forall x. x -> f x) -> (a, b) -> (f a, f b)
    ghci> liftTup putInList (5, ”Hello”)
    ([5], [”Hello”])
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  35. Recap
    Existential types
    Rank-N Types
    Examples
    Prompt monad
    Red-Black Trees with types
    Existential types
    It uses RankNTypes and GADTs
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  36. Recap
    Existential types
    Rank-N Types
    Examples
    Prompt monad
    Red-Black Trees with types
    Existential types
    It uses RankNTypes and GADTs
    It adds abstract layer above IO
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  37. Recap
    Existential types
    Rank-N Types
    Examples
    Prompt monad
    Red-Black Trees with types
    Existential types
    It uses RankNTypes and GADTs
    It adds abstract layer above IO
    It describes how our program want to use IO
    ...but it doesn’t show to the user internals of the communication
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  38. Recap
    Existential types
    Rank-N Types
    Examples
    Prompt monad
    Red-Black Trees with types
    Existential types
    It uses RankNTypes and GADTs
    It adds abstract layer above IO
    It describes how our program want to use IO
    ...but it doesn’t show to the user internals of the communication
    It’s pure!
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  39. Recap
    Existential types
    Rank-N Types
    Examples
    Prompt monad
    Red-Black Trees with types
    Existential types
    class Monad m => MonadPrompt p m where
    prompt :: p a -> m a
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  40. Recap
    Existential types
    Rank-N Types
    Examples
    Prompt monad
    Red-Black Trees with types
    Existential types
    class Monad m => MonadPrompt p m where
    prompt :: p a -> m a
    data Prompt p r
    instance MonadPrompt p (Prompt p)
    instance MonadPrompt p (PromptT p m)
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  41. Recap
    Existential types
    Rank-N Types
    Examples
    Prompt monad
    Red-Black Trees with types
    Existential types
    class Monad m => MonadPrompt p m where
    prompt :: p a -> m a
    data Prompt p r
    instance MonadPrompt p (Prompt p)
    instance MonadPrompt p (PromptT p m)
    runPrompt :: (forall a. p a -> a) -> Prompt p r -> r
    runPromptM :: Monad m => (forall a. p a -> m a) -> Prompt p r ->
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  42. Recap
    Existential types
    Rank-N Types
    Examples
    Prompt monad
    Red-Black Trees with types
    Existential types
    data Request a where
    Echo :: String -> Request ()
    GetLine :: Request (Maybe String)
    GetTime :: Request UTCTime
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  43. Recap
    Existential types
    Rank-N Types
    Examples
    Prompt monad
    Red-Black Trees with types
    Existential types
    data Request a where
    Echo :: String -> Request ()
    GetLine :: Request (Maybe String)
    GetTime :: Request UTCTime
    handleIO :: Request a -> IO a
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  44. Recap
    Existential types
    Rank-N Types
    Examples
    Prompt monad
    Red-Black Trees with types
    Existential types
    data Request a where
    Echo :: String -> Request ()
    GetLine :: Request (Maybe String)
    GetTime :: Request UTCTime
    handleIO :: Request a -> IO a
    handleIO (Echo s) = putStrLn s
    handleIO GetLine = catchJust
    (guard . isEOFError)
    (Just <$> getLine)
    (const (return Nothing))
    handleIO GetTime = getCurrentTime
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  45. Recap
    Existential types
    Rank-N Types
    Examples
    Prompt monad
    Red-Black Trees with types
    Existential types
    handleIO :: Request a -> IO a
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  46. Recap
    Existential types
    Rank-N Types
    Examples
    Prompt monad
    Red-Black Trees with types
    Existential types
    handleIO :: Request a -> IO a
    cat :: Prompt Request ()
    cat = do
    line <- prompt GetLine
    maybe (return ()) (\x -> prompt (Echo x) >> cat) line
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  47. Recap
    Existential types
    Rank-N Types
    Examples
    Prompt monad
    Red-Black Trees with types
    Existential types
    handleIO :: Request a -> IO a
    cat :: Prompt Request ()
    cat = do
    line <- prompt GetLine
    maybe (return ()) (\x -> prompt (Echo x) >> cat) line
    runPromptM :: Monad m =>
    (forall a. p a -> m a) ->
    Prompt p r ->
    m r
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  48. Recap
    Existential types
    Rank-N Types
    Examples
    Prompt monad
    Red-Black Trees with types
    Existential types
    handleIO :: Request a -> IO a
    cat :: Prompt Request ()
    cat = do
    line <- prompt GetLine
    maybe (return ()) (\x -> prompt (Echo x) >> cat) line
    runPromptM :: Monad m =>
    (forall a. p a -> m a) ->
    Prompt p r ->
    m r
    runCat :: IO ()
    runCat = runPromptM handleIO cat
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  49. Recap
    Existential types
    Rank-N Types
    Examples
    Prompt monad
    Red-Black Trees with types
    Existential types
    handleIO :: Request a -> IO a
    cat :: Prompt Request ()
    cat = do
    line <- prompt GetLine
    maybe (return ()) (\x -> prompt (Echo x) >> cat) line
    runPromptM :: Monad m =>
    (forall a. p a -> m a) ->
    Prompt p r ->
    m r
    runCat :: IO ()
    runCat = runPromptM handleIO cat
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  50. Recap
    Existential types
    Rank-N Types
    Examples
    Prompt monad
    Red-Black Trees with types
    Existential types
    Why runPromptM needs to be Rank2Type function?
    data Request a where
    Echo :: String -> Request ()
    GetLine :: Request (Maybe String)
    GetTime :: Request UTCTime
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  51. Recap
    Existential types
    Rank-N Types
    Examples
    Prompt monad
    Red-Black Trees with types
    Existential types
    Why runPromptM needs to be Rank2Type function?
    data Request a where
    Echo :: String -> Request ()
    GetLine :: Request (Maybe String)
    GetTime :: Request UTCTime
    handleIO :: Request a -> IO a
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  52. Recap
    Existential types
    Rank-N Types
    Examples
    Prompt monad
    Red-Black Trees with types
    Existential types
    Why runPromptM needs to be Rank2Type function?
    data Request a where
    Echo :: String -> Request ()
    GetLine :: Request (Maybe String)
    GetTime :: Request UTCTime
    handleIO :: Request a -> IO a
    runPromptM :: Monad m =>
    (forall a. p a -> m a) ->
    Prompt p r ->
    m r
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  53. Recap
    Existential types
    Rank-N Types
    Examples
    Prompt monad
    Red-Black Trees with types
    Existential types
    What we achieved?
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  54. Recap
    Existential types
    Rank-N Types
    Examples
    Prompt monad
    Red-Black Trees with types
    Existential types
    What we achieved?
    Why is that cool?
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  55. Recap
    Existential types
    Rank-N Types
    Examples
    Prompt monad
    Red-Black Trees with types
    Existential types
    RWS monad
    RWS (Reader, Writer, State) Monad
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  56. Recap
    Existential types
    Rank-N Types
    Examples
    Prompt monad
    Red-Black Trees with types
    Existential types
    RWS monad
    RWS (Reader, Writer, State) Monad
    Reader: Something, from which we can read data (for example,
    configuration datatype)
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  57. Recap
    Existential types
    Rank-N Types
    Examples
    Prompt monad
    Red-Black Trees with types
    Existential types
    RWS monad
    RWS (Reader, Writer, State) Monad
    Reader: Something, from which we can read data (for example,
    configuration datatype)
    We won’t use Reader monad from RWS.
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  58. Recap
    Existential types
    Rank-N Types
    Examples
    Prompt monad
    Red-Black Trees with types
    Existential types
    RWS monad
    RWS (Reader, Writer, State) Monad
    Reader: Something, from which we can read data (for example,
    configuration datatype)
    We won’t use Reader monad from RWS.
    Writer: Something, to which we can write data (for example, logging to
    file)
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  59. Recap
    Existential types
    Rank-N Types
    Examples
    Prompt monad
    Red-Black Trees with types
    Existential types
    RWS monad
    RWS (Reader, Writer, State) Monad
    Reader: Something, from which we can read data (for example,
    configuration datatype)
    We won’t use Reader monad from RWS.
    Writer: Something, to which we can write data (for example, logging to
    file)
    tell function is writing to the Writer monad
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  60. Recap
    Existential types
    Rank-N Types
    Examples
    Prompt monad
    Red-Black Trees with types
    Existential types
    RWS monad
    RWS (Reader, Writer, State) Monad
    Reader: Something, from which we can read data (for example,
    configuration datatype)
    We won’t use Reader monad from RWS.
    Writer: Something, to which we can write data (for example, logging to
    file)
    tell function is writing to the Writer monad
    State we already know.
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  61. Recap
    Existential types
    Rank-N Types
    Examples
    Prompt monad
    Red-Black Trees with types
    Existential types
    RWS monad
    RWS (Reader, Writer, State) Monad
    Reader: Something, from which we can read data (for example,
    configuration datatype)
    We won’t use Reader monad from RWS.
    Writer: Something, to which we can write data (for example, logging to
    file)
    tell function is writing to the Writer monad
    State we already know.
    get gets the state
    put sets the state
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  62. Recap
    Existential types
    Rank-N Types
    Examples
    Prompt monad
    Red-Black Trees with types
    Existential types
    type Input = [String]
    type Output = [String]
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  63. Recap
    Existential types
    Rank-N Types
    Examples
    Prompt monad
    Red-Black Trees with types
    Existential types
    type Input = [String]
    type Output = [String]
    handleRWS :: Request a -> RWS r Output Input a
    handleRWS (Echo s) = tell (return s)
    handleRWS GetLine = do
    lines <- get
    if null lines
    then return Nothing
    else do
    put (tail lines)
    return (Just (head lines))
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  64. Recap
    Existential types
    Rank-N Types
    Examples
    Prompt monad
    Red-Black Trees with types
    Existential types
    type Input = [String]
    type Output = [String]
    handleRWS :: Request a -> RWS r Output Input a
    handleRWS (Echo s) = tell (return s)
    handleRWS GetLine = do
    lines <- get
    if null lines
    then return Nothing
    else do
    put (tail lines)
    return (Just (head lines))
    rwsCat :: RWS r Output Input ()
    rwsCat = runPromptM handleRWS cat
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  65. Recap
    Existential types
    Rank-N Types
    Examples
    Prompt monad
    Red-Black Trees with types
    Existential types
    type Input = [String]
    type Output = [String]
    handleRWS :: Request a -> RWS r Output Input a
    handleRWS (Echo s) = tell (return s)
    handleRWS GetLine = do
    lines <- get
    if null lines
    then return Nothing
    else do
    put (tail lines)
    return (Just (head lines))
    rwsCat :: RWS r Output Input ()
    rwsCat = runPromptM handleRWS cat
    simulateCat :: Input -> Output
    simulateCat input = snd $ evalRWS rwsCat undefined input
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  66. Recap
    Existential types
    Rank-N Types
    Examples
    Prompt monad
    Red-Black Trees with types
    Existential types
    Red-black trees properties:
    every black node has two black children
    every path from the root to an empty tree passes through the same number
    of black nodes
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  67. Recap
    Existential types
    Rank-N Types
    Examples
    Prompt monad
    Red-Black Trees with types
    Existential types
    type Tr t a b = (t a b,a,t a b)
    data Red t a b = C (t a b) | R (Tr t a b)
    data Black a b = E | B(Tr (Red Black) a [b])
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  68. Recap
    Existential types
    Rank-N Types
    Examples
    Prompt monad
    Red-Black Trees with types
    Existential types
    type Tr t a b = (t a b,a,t a b)
    data Red t a b = C (t a b) | R (Tr t a b)
    data Black a b = E | B(Tr (Red Black) a [b])
    Red is really MaybeRed
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  69. Recap
    Existential types
    Rank-N Types
    Examples
    Prompt monad
    Red-Black Trees with types
    Existential types
    type Tr t a b = (t a b,a,t a b)
    data Red t a b = C (t a b) | R (Tr t a b)
    data Black a b = E | B(Tr (Red Black) a [b])
    Red is really MaybeRed
    C (...) constructor means that there’s Black node inside
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  70. Recap
    Existential types
    Rank-N Types
    Examples
    Prompt monad
    Red-Black Trees with types
    Existential types
    type Tr t a b = (t a b,a,t a b)
    data Red t a b = C (t a b) | R (Tr t a b)
    data Black a b = E | B(Tr (Red Black) a [b])
    Red is really MaybeRed
    C (...) constructor means that there’s Black node inside
    When there’s Red node inside of Red node, we need to do something.
    Thus, type Red (Red Black) a b means dangerous situation.
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  71. Recap
    Existential types
    Rank-N Types
    Examples
    Prompt monad
    Red-Black Trees with types
    Existential types
    type Tr t a b = (t a b,a,t a b)
    data Red t a b = C (t a b) | R (Tr t a b)
    data Black a b = E | B(Tr (Red Black) a [b])
    Red is really MaybeRed
    C (...) constructor means that there’s Black node inside
    When there’s Red node inside of Red node, we need to do something.
    Thus, type Red (Red Black) a b means dangerous situation.
    Note that Black nodes are always increasing their depth, by passing it
    down increased by one (look at [b] at Black constructor)
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  72. Recap
    Existential types
    Rank-N Types
    Examples
    Prompt monad
    Red-Black Trees with types
    Existential types
    type Tr t a b = (t a b,a,t a b)
    data Red t a b = C (t a b) | R (Tr t a b)
    data Black a b = E | B(Tr (Red Black) a [b])
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  73. Recap
    Existential types
    Rank-N Types
    Examples
    Prompt monad
    Red-Black Trees with types
    Existential types
    type Tr t a b = (t a b,a,t a b)
    data Red t a b = C (t a b) | R (Tr t a b)
    data Black a b = E | B(Tr (Red Black) a [b])
    balanceL :: Red (Red Black) a [b] -> a -> Red Black a [b] -> Red Bl
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  74. Recap
    Existential types
    Rank-N Types
    Examples
    Prompt monad
    Red-Black Trees with types
    Existential types
    type Tr t a b = (t a b,a,t a b)
    data Red t a b = C (t a b) | R (Tr t a b)
    data Black a b = E | B(Tr (Red Black) a [b])
    balanceL :: Red (Red Black) a [b] -> a -> Red Black a [b] -> Red Bl
    balanceL (R(R(a,x,b),y,c)) z d = R(B(C a,x,C b),y,B(c,z,d))
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  75. Recap
    Existential types
    Rank-N Types
    Examples
    Prompt monad
    Red-Black Trees with types
    Existential types
    type Tr t a b = (t a b,a,t a b)
    data Red t a b = C (t a b) | R (Tr t a b)
    data Black a b = E | B(Tr (Red Black) a [b])
    balanceL :: Red (Red Black) a [b] -> a -> Red Black a [b] -> Red Bl
    balanceL (R(R(a,x,b),y,c)) z d = R(B(C a,x,C b),y,B(c,z,d))
    balanceL (R(a,x,R(b,y,c))) z d = R(B(a,x,C b),y,B(C c,z,d))
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  76. Recap
    Existential types
    Rank-N Types
    Examples
    Prompt monad
    Red-Black Trees with types
    Existential types
    type Tr t a b = (t a b,a,t a b)
    data Red t a b = C (t a b) | R (Tr t a b)
    data Black a b = E | B(Tr (Red Black) a [b])
    balanceL :: Red (Red Black) a [b] -> a -> Red Black a [b] -> Red Bl
    balanceL (R(R(a,x,b),y,c)) z d = R(B(C a,x,C b),y,B(c,z,d))
    balanceL (R(a,x,R(b,y,c))) z d = R(B(a,x,C b),y,B(C c,z,d))
    balanceL (R(C a,x,C b)) z d = C(B(R(a,x,b),z,d))
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  77. Recap
    Existential types
    Rank-N Types
    Examples
    Prompt monad
    Red-Black Trees with types
    Existential types
    type Tr t a b = (t a b,a,t a b)
    data Red t a b = C (t a b) | R (Tr t a b)
    data Black a b = E | B(Tr (Red Black) a [b])
    balanceL :: Red (Red Black) a [b] -> a -> Red Black a [b] -> Red Bl
    balanceL (R(R(a,x,b),y,c)) z d = R(B(C a,x,C b),y,B(c,z,d))
    balanceL (R(a,x,R(b,y,c))) z d = R(B(a,x,C b),y,B(C c,z,d))
    balanceL (R(C a,x,C b)) z d = C(B(R(a,x,b),z,d))
    balanceL (C a) x b = C(B(a,x,b))
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  78. Recap
    Existential types
    Rank-N Types
    Examples
    Prompt monad
    Red-Black Trees with types
    Existential types
    insB :: Ord a => a -> Black a b -> Red Black a b
    insB x E = R(E,x,E)
    insB x t@(B(a,y,b))
    | x| x>y = balanceR a y (insR x b)
    | otherwise = C t
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  79. Recap
    Existential types
    Rank-N Types
    Examples
    Prompt monad
    Red-Black Trees with types
    Existential types
    insB :: Ord a => a -> Black a b -> Red Black a b
    insB x E = R(E,x,E)
    insB x t@(B(a,y,b))
    | x| x>y = balanceR a y (insR x b)
    | otherwise = C t
    insR :: Ord a => a -> Red Black a b -> RR a b
    insR x (C t) = C(insB x t)
    insR x t@(R(a,y,b))
    | x| x>y = R(C a,y,insB x b)
    | otherwise = C t
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  80. Recap
    Existential types
    Rank-N Types
    Examples
    Prompt monad
    Red-Black Trees with types
    Existential types
    tickB :: Black a b -> Black a c
    tickB E = E
    tickB (B(a,x,b)) = B(tickR a,x,tickR b)
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  81. Recap
    Existential types
    Rank-N Types
    Examples
    Prompt monad
    Red-Black Trees with types
    Existential types
    tickB :: Black a b -> Black a c
    tickB E = E
    tickB (B(a,x,b)) = B(tickR a,x,tickR b)
    tickR :: Red Black a b -> Red Black a c
    tickR (C t) = C(tickB t)
    tickR (R(a,x,b)) = R(tickB a,x,tickB b)
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  82. Recap
    Existential types
    Rank-N Types
    Examples
    Prompt monad
    Red-Black Trees with types
    Existential types
    tickB :: Black a b -> Black a c
    tickB E = E
    tickB (B(a,x,b)) = B(tickR a,x,tickR b)
    tickR :: Red Black a b -> Red Black a c
    tickR (C t) = C(tickB t)
    tickR (R(a,x,b)) = R(tickB a,x,tickB b)
    inc :: Black a b -> Black a [b]
    inc = tickB
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  83. Recap
    Existential types
    Rank-N Types
    Examples
    Prompt monad
    Red-Black Trees with types
    Existential types
    ghci> (E :: Black a [[[b]]])
    E
    it :: Black a [[[b]]]
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  84. Recap
    Existential types
    Rank-N Types
    Examples
    Prompt monad
    Red-Black Trees with types
    Existential types
    ghci> (E :: Black a [[[b]]])
    E
    it :: Black a [[[b]]]
    newtype Tree a = forall b . ENC (Black a b)
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  85. Recap
    Existential types
    Rank-N Types
    Examples
    Prompt monad
    Red-Black Trees with types
    Existential types
    ghci> (E :: Black a [[[b]]])
    E
    it :: Black a [[[b]]]
    newtype Tree a = forall b . ENC (Black a b)
    empty :: Tree a
    empty = ENC E
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  86. Recap
    Existential types
    Rank-N Types
    Examples
    Prompt monad
    Red-Black Trees with types
    Existential types
    ghci> (E :: Black a [[[b]]])
    E
    it :: Black a [[[b]]]
    newtype Tree a = forall b . ENC (Black a b)
    empty :: Tree a
    empty = ENC E
    insert :: Ord a => a -> Tree a -> Tree a
    insert x (ENC t) = ENC(blacken (insB x t))
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  87. Recap
    Existential types
    Rank-N Types
    Examples
    Prompt monad
    Red-Black Trees with types
    Existential types
    ghci> (E :: Black a [[[b]]])
    E
    it :: Black a [[[b]]]
    newtype Tree a = forall b . ENC (Black a b)
    empty :: Tree a
    empty = ENC E
    insert :: Ord a => a -> Tree a -> Tree a
    insert x (ENC t) = ENC(blacken (insB x t))
    blacken :: Red Black a b -> Black a b
    blacken (C u) = u
    blacken (R(a,x,b)) = B(C(inc a),x,C(inc b))
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  88. Recap
    Existential types
    Rank-N Types
    Examples
    Prompt monad
    Red-Black Trees with types
    Existential types
    class Renderable a where
    boundingSphere :: a -> Sphere
    hit :: a -> [Fragment] −− returns the ”fragments” of all hits with ray
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  89. Recap
    Existential types
    Rank-N Types
    Examples
    Prompt monad
    Red-Black Trees with types
    Existential types
    class Renderable a where
    boundingSphere :: a -> Sphere
    hit :: a -> [Fragment] −− returns the ”fragments” of all hits with ray
    hits :: Renderable a => [a] -> [Fragment]
    hits xs = sortByDistance $ concatMap hit xs
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  90. Recap
    Existential types
    Rank-N Types
    Examples
    Prompt monad
    Red-Black Trees with types
    Existential types
    class Renderable a where
    boundingSphere :: a -> Sphere
    hit :: a -> [Fragment] −− returns the ”fragments” of all hits with ray
    hits :: Renderable a => [a] -> [Fragment]
    hits xs = sortByDistance $ concatMap hit xs
    data AnyRenderable = forall a. Renderable a => AnyRenderable a
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  91. Recap
    Existential types
    Rank-N Types
    Examples
    Prompt monad
    Red-Black Trees with types
    Existential types
    class Renderable a where
    boundingSphere :: a -> Sphere
    hit :: a -> [Fragment] −− returns the ”fragments” of all hits with ray
    hits :: Renderable a => [a] -> [Fragment]
    hits xs = sortByDistance $ concatMap hit xs
    data AnyRenderable = forall a. Renderable a => AnyRenderable a
    instance Renderable AnyRenderable where
    boundingSphere (AnyRenderable a) = boundingSphere a
    hit (AnyRenderable a) = hit a
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  92. Recap
    Existential types
    Rank-N Types
    Examples
    Prompt monad
    Red-Black Trees with types
    Existential types
    class Renderable a where
    boundingSphere :: a -> Sphere
    hit :: a -> [Fragment] −− returns the ”fragments” of all hits with ray
    hits :: Renderable a => [a] -> [Fragment]
    hits xs = sortByDistance $ concatMap hit xs
    data AnyRenderable = forall a. Renderable a => AnyRenderable a
    instance Renderable AnyRenderable where
    boundingSphere (AnyRenderable a) = boundingSphere a
    hit (AnyRenderable a) = hit a
    [ AnyRenderable x
    , AnyRenderable y
    , AnyRenderable z ]
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide

  93. Recap
    Existential types
    Rank-N Types
    Examples
    Prompt monad
    Red-Black Trees with types
    Existential types
    References
    https://wiki.haskell.org/Phantom_type
    https://wiki.haskell.org/Generalised_algebraic_datatype
    https://wiki.haskell.org/Existential_type
    http://stackoverflow.com/questions/3071136/
    what-does-the-forall-keyword-in-haskell-ghc-do
    https:
    //themonadreader.files.wordpress.com/2010/01/issue15.pdf
    Red-black trees with types. Stefan Kahrs, 2001.
    “Adventures in Three Monads”, Edward Z. Yang. The Monad Reader,
    issue 15.
    Rafal Lasocha Functional stuff: GADT, Existential types, Rank-N-Types, ...

    View full-size slide