SlideShare una empresa de Scribd logo
1 de 30
Descargar para leer sin conexión
Context

           Sebastian Rettig


An applicative value can be seen as aa value with
 An applicative value can be seen as value with
      an added context. - - A fancy value.
        an added context. A fancy value.
Functional Programming
●   No Variables
●   Functions only, eventually stored in
     Modules
       –   Behavior do not change, once defined
       –   → Function called with same parameter
            calculates always the same result
●   Function definitions (Match Cases)
●   Recursion (Memory)
Haskell Features
●   Pure Functional Programming Language
●   Lazy Evaluation
●   Pattern Matching and Guards
●   List Comprehension
●   Type Polymorphism
Nice to remember (1)
    Typeclasses:
●   define properties of the types
●   like an interface
         –   Eq can be compared
         –   Ord can be ordered (>, <, >=, <=) (extending Eq)
         –   Show can be shown as string
         –   Read opposite of Show
         –   Enum sequentially ordered types (can be enumerated
             and usable in List-Ranges ['a'..'e'])
Nice to remember (2)
  Typeclass-Membership:
1. derive from existing Memberships of used types
  data Vector2D = Vector Float Float deriving (Show, Eq)

2. implement Membership by your own
  instance Show Vector2D where
    show Vector a b = “x: ” ++ [a] ++ “ ; y: ” ++ [b]
Nice to remember (3)
    Curried Function:
●   every function in haskell consumes exactly one
      parameter and returns a value
●   PARTIAL APPLICATION
●   so we could write the function header instead of:
    max :: (Ord a) => a -> a -> a
●   also in the following way:
    max :: (Ord a) => a -> (a -> a)
Nice to remember (4)
    Pointless Style:
●   based on partial Application → simpler code
           maxWithFour x = max 4 x
             is the same as
           maxWithFour = max 4
●   use Function Application ($) to avoid Parenthesis on
      function call with parameters
           sqrt $ 3 + 4 + 9
●   use Function Composition (.) to avoid Parenthesis on
      chaining functions
           fn = ceiling . negate . tan . cos . max 50
Type Refresher (1)
    create a Type:
●   data MyVector = Nirvana
                   | Single Int
                   | Tuple Int Int
                   | Triple Int Int Int
●
    MyVector   is the Type
●
    Nirvana, Single, Tuple, Triple   are Type Constructors
●   Type Constructors are normal functions
      :t Single     is   Single :: Int -> MyVector
●   Type Constructors can have Parameters (values)
      Single, Tuple, Triple have 1, 2 and 3
Type Refresher (2)
    create a Type with Record Syntax:
●   data MyVector2 =     Nirvana2
                   |     Single2 {x :: Int}
                   |     Tuple2 {x :: Int, y :: Int}
                   |     Triple2 {x :: Int, y :: Int, z :: Int}
●   Nirvana2, Single2, Tuple2, Triple2 are Type Constructors
●   x, y, z are selectors
           functions who lookup specific fields in the data type → like GET
              functions
              :t x      is    x :: MyVector2 -> Int
●   e.g.: foo = Single2 {x=4}
       x foo returns 4
       :t foo returns foo :: MyVector2
Type Refresher (3)
    to make the Type more generic:
●   data MyVector3 a    = Nirvana3
                   |    Single3 {x' :: a}
                   |    Tuple3 {x' :: a, y' :: a}
                   |    Triple3 {x' :: a, y' :: a, z' :: a}
●
    a   is type parameter and selector x' has the following header
         :t x'     is  x' :: MyVector3 a -> a
●   if we want to use this type, we have to set the Type parameter
        OR let Haskell detect the Type parameter
●   e.g.: foo = Single3 {x'=4}
       :t foo returns foo :: MyVector3 Integer
●   e.g.: foo = Nirvana3
       :t foo returns foo :: MyVector3 a
Type Refresher (4)
    a Type can have more than one Type parameter:
●   data MyVector4 a   b c = Nirvana4
                   |   Single4 {x'' :: a}
                   |   Tuple4 {x'' :: a, y :: b}
                   |   Triple4 {x'' :: a, y'' :: b, z'' :: c}
●
    a, b, c are   type parameter, selector x has header
      :t x''       is   x'' :: MyVector4 a b c -> a
●   e.g.: foo = Single4 {x''=4}
       :t foo returns foo :: MyVector4 Integer b c
●   e.g.: foo = Nirvana4
       :t foo returns foo :: MyVector4 a b c
●   → Partial Application!
Kind
●   explains the steps which are necessary to evaluate the data
      from that type
●   → evaluate = the type is fully applied
●   can be used to find how much parameters a type has
●   GHCi- Command       :k
●   :k MyVector returns MyVector :: *
●   :k MyVector2 returns MyVector2 :: *
●   :k MyVector3 returns MyVector3 :: * -> *
●   :k MyVector4 returns MyVector4 :: * -> * -> * -> *
●   :k MyVector3 Int returns MyVector3 Int :: *
●   :k MyVector4 Int Int returns MyVector4 Int Int :: * -> *
Useful Types
●   Maybe:
    data Maybe a = Nothing | Just a
         –    for operations, which can fail
         –    contains data of type a (Just a) or Nothing
         –    good for handling e.g. Hashmap lookup
●   Either:
    data Either a b = Left a | Right b
      deriving (Eq, Ord, Read, Show)
         –    can contain type a or type b
         –    Left for e.g. Error Messages, Right for value
         –    BUT why is Error Message the first parameter?
Implement Membership (1)
●   Let's refresh again how to implement a Typeclass-
      Membership:
●   first the definition of Typeclass Eq:
    :i Eq
      class Eq a where
      (==) :: a -> a -> Bool
      (/=) :: a -> a -> Bool
      -- Defined in GHC.Classes
●   What is a ? → a is used by (==) and (/=) as parameter
●   → needs to be a fully applied type (concrete type)
●   → :k must return *
Implement Membership (2)
●   But how can we make MyVector3 a member of Eq ?
●   → we have to make MyVector3 fully applied type, e.g.:
    instance Eq (MyVector3 Int) where
      Nirvana3 == Nirvana3 = True
      Single3 {x'=x1} == Single3 {x'=x2} = (x1 == x2)
           ...
●   Or with using generic Type Parameter:
    instance Eq (MyVector3 a) where
      Nirvana3 == Nirvana3 = True
      Single3 {x'=x1} == Single3 {x'=x2} = (x1 == x2)
           ...
●   do a has Type-Class restrictions? If yes, which?
Implement Membership (3)
●   And what about that?
    instance Eq MyVector3 where
      Nirvana3 == Nirvana = True
      Single3 {x'=x1} == Single {x'=x2} = (x1 == x2)
           ...
●   Is this membership correct?
Functor Typeclass (1)
    class Functor f where
      fmap :: (a -> b) -> f a -> f b
●   for things that can be mapped over
●   !!! Functor needs Types with kind * -> * !!!
●   fmap gets a function and a type and maps the function
      over the type variable → the type variable can change!
●   Instance for List:
    instance Functor [] where
      fmap = map
        –   Example: fmap (*2) [2,3,4] returns [4,6,8]
Functor Typeclass (2)
    class Functor f where
      fmap :: (a -> b) -> f a -> f b
●   Instance for Maybe
    instance Functor Maybe where
      fmap g (Just x) = Just (g x)
      fmap g Nothing = Nothing
●   Example:
        –   fmap (+3) Nothing returns Nothing
        –   fmap (+3) (Just 4) returns (Just 7)
        –   fmap (show) (Just 4) returns (Just “4”)
Functor Typeclass (3)
    class Functor f where
      fmap :: (a -> b) -> f a -> f b
●   Instance for Either
    instance Functor (Either a) where
      fmap f (Right x) = Right (f x)
      fmap f (Left x) = Left x
●   Either is a type with kind * -> * -> * !
●   → we have to permanently include the first parameter in the
      instance (partial application)
●   → fmap only maps over the second Type-Parameter!
●   → Left Type-Constructor is often used for Error Messages
Functor Typeclass (4)
    class Functor f where
      fmap :: (a -> b) -> f a -> f b
●   Example:
         –   fmap (+3) (Left 4) returns      (Left 4)
         –   fmap (+3) (Right 4) returns (Right 7)
●   what happens, if we try to do that?
      fmap (+) (Just 4)
●   let's look at the type:
                        :t fmap (+) (Just 4)
      fmap (+) (Just 4) :: Num a => Maybe (a -> a)
●   partial application, BUT we can not use the Functor instance
      on the result Just (4+)
●   → we need an extension → Applicative Functors
Lifting a Function
●   if we partial apply fmap, the header has the following structure
    :t fmap (*2) results in
      fmap (*2) :: (Num a, Functor f) => f a -> f a
    :t fmap (cycle 3) results in
      fmap (cycle 3) :: (Functor f) => f a -> f [a]
●   → this is called lifting a function
●   → we can predefine a normal function which gets a Functor
      and returns a Functor
●   → we move the function inside the Type and operate on type
      variables
●   → we lift the function up to the type → normal function can
      work with complex types
Applicative Functor (1)
    class (Functor f) => Applicative f where
      pure :: a -> f a
      (<*>) :: f (a -> b) -> f a -> f b
●   pure is a function who wraps a normal value into applicative
         –   creates a minimal context
●   (<*>) takes a functor with a function in it and another functor
         –   extracts that function from the first functor
         –   and then maps it over the second one
Applicative Functor (2)
    class (Functor f) => Applicative f where
      pure :: a -> f a
      (<*>) :: f (a -> b) -> f a -> f b
●   Instance for Maybe
    instance Applicative Maybe where
      pure = Just
      Nothing <*> _ = Nothing
      (Just f) <*> something = fmap f something
●   Example:
        –   Just (+3) <*> Just 9   returns Just 12
        –   pure (+3) <*> Just 10 returns Just 13
        –   Just (++"hah") <*> Nothing returns Nothing
Applicative Functor (3)
    class (Functor f) => Applicative f where
      pure :: a -> f a
      (<*>) :: f (a -> b) -> f a -> f b
●   Instance for []
    instance Applicative [] where
      pure x = [x]
      fs <*> xs = [f x | f <- fs, x <- xs]
●   Example:
        –   [(*0),(+100),(^2)] <*> [1,2,3]
              returns [0,0,0,101,102,103,1,4,9]
        –   pure "Hey" :: [String] returns ["Hey"]
        –   [(+),(*)] <*> [1,2] <*> [3,4]
              returns [4,5,5,6,3,4,6,8]
Applicative Functor (4)
●   pure f <*> x equals fmap f x
●   → in Control.Applicative exists a specific function
    (<$>) :: (Functor f) => (a -> b) -> f a -> f b
      f <$> x = fmap f x
●   So we can do the same much prettier:
    (++) <$> Just "johntra" <*> Just "volta"
      returns Just "johntravolta"
    (++) <$> ["ha","heh","hmm"] <*> ["?","!","."]
      returns ["ha?", "ha!", "ha.", "heh?", "heh!",
      "heh.", "hmm?", "hmm!", "hmm."]
Applicative Functor (5)
    class (Functor f) => Applicative f where
      pure :: a -> f a
      (<*>) :: f (a -> b) -> f a -> f b
●   Instance for IO
    instance Applicative IO where
      pure = return
      a <*> b = do
        f <- a
        x <- b
        return (f x)
Applicative Functor (6)
    Example for IO:
●   instead of writing this:
       myAction :: IO String
       myAction = do
         a <- getLine
         b <- getLine
         return $ a ++ b
●   we can write this:
      myAction :: IO String
      myAction = (++) <$> getLine <*> getLine
Applicative Context
●   Applicative Types can bee seen as Types with context:
         –   Maybe, Either for things which can fail
         –   [ ] as non-deterministic result
         –   IO as values send or get from outside
●   Applicative functors allows us to operate in applicative types
      like normal types and provide the context!
●   → We don't need to pattern match against the Context in
      every operation we use in our functions!
Lifting a Function (Applicative)
●   Function lifting in for Applicative:
    liftA :: Applicative f => (a -> b) -> f a -> f b
         –   same as fmap
         –   fmap :: Functor f => (a -> b) -> f a -> f b
    liftA2 :: (Applicative f) => (a -> b -> c) -> f a
      -> f b -> f c
    liftA2 f a b = f <$> a <*> b
         –   gets a function, with 2 parameters
         –   operates on 2 Applicatives
         –   result is also an Applicative
Sources
[1] Haskell-Tutorial: Learn you a Haskell (http://learnyouahaskell.com/,
    2012/03/15)
[2] The Hugs User-Manual (
    http://cvs.haskell.org/Hugs/pages/hugsman/index.html, 2012/03/15)
[3] The Haskellwiki (http://www.haskell.org/haskellwiki, 2012/03/15)

Más contenido relacionado

La actualidad más candente

C# quick ref (bruce 2016)
C# quick ref (bruce 2016)C# quick ref (bruce 2016)
C# quick ref (bruce 2016)Bruce Hantover
 
Monads and friends demystified
Monads and friends demystifiedMonads and friends demystified
Monads and friends demystifiedAlessandro Lacava
 
Java: Introduction to Arrays
Java: Introduction to ArraysJava: Introduction to Arrays
Java: Introduction to ArraysTareq Hasan
 
Extensible Effects in Dotty
Extensible Effects in DottyExtensible Effects in Dotty
Extensible Effects in DottySanshiro Yoshida
 
An introduction to functional programming with Swift
An introduction to functional programming with SwiftAn introduction to functional programming with Swift
An introduction to functional programming with SwiftFatih Nayebi, Ph.D.
 
Passing an Array to a Function (ICT Programming)
Passing an Array to a Function (ICT Programming)Passing an Array to a Function (ICT Programming)
Passing an Array to a Function (ICT Programming)Fatima Kate Tanay
 
Templates presentation
Templates presentationTemplates presentation
Templates presentationmalaybpramanik
 
Functional Programming With Scala
Functional Programming With ScalaFunctional Programming With Scala
Functional Programming With ScalaKnoldus Inc.
 
An Introduction to Part of C++ STL
An Introduction to Part of C++ STLAn Introduction to Part of C++ STL
An Introduction to Part of C++ STL乐群 陈
 
Core csharp and net quick reference
Core csharp and net quick referenceCore csharp and net quick reference
Core csharp and net quick referenceilesh raval
 
Introduction to ad-3.4, an automatic differentiation library in Haskell
Introduction to ad-3.4, an automatic differentiation library in HaskellIntroduction to ad-3.4, an automatic differentiation library in Haskell
Introduction to ad-3.4, an automatic differentiation library in Haskellnebuta
 
C++ Standard Template Library
C++ Standard Template LibraryC++ Standard Template Library
C++ Standard Template LibraryIlio Catallo
 
Parts of python programming language
Parts of python programming languageParts of python programming language
Parts of python programming languageMegha V
 

La actualidad más candente (20)

C# quick ref (bruce 2016)
C# quick ref (bruce 2016)C# quick ref (bruce 2016)
C# quick ref (bruce 2016)
 
Scala Paradigms
Scala ParadigmsScala Paradigms
Scala Paradigms
 
Cats in Scala
Cats in ScalaCats in Scala
Cats in Scala
 
Monads and friends demystified
Monads and friends demystifiedMonads and friends demystified
Monads and friends demystified
 
Templates
TemplatesTemplates
Templates
 
Java: Introduction to Arrays
Java: Introduction to ArraysJava: Introduction to Arrays
Java: Introduction to Arrays
 
Extensible Effects in Dotty
Extensible Effects in DottyExtensible Effects in Dotty
Extensible Effects in Dotty
 
An introduction to functional programming with Swift
An introduction to functional programming with SwiftAn introduction to functional programming with Swift
An introduction to functional programming with Swift
 
Ruby Programming Assignment Help
Ruby Programming Assignment HelpRuby Programming Assignment Help
Ruby Programming Assignment Help
 
Passing an Array to a Function (ICT Programming)
Passing an Array to a Function (ICT Programming)Passing an Array to a Function (ICT Programming)
Passing an Array to a Function (ICT Programming)
 
Templates presentation
Templates presentationTemplates presentation
Templates presentation
 
Functional Programming With Scala
Functional Programming With ScalaFunctional Programming With Scala
Functional Programming With Scala
 
An Introduction to Part of C++ STL
An Introduction to Part of C++ STLAn Introduction to Part of C++ STL
An Introduction to Part of C++ STL
 
Core csharp and net quick reference
Core csharp and net quick referenceCore csharp and net quick reference
Core csharp and net quick reference
 
Introduction to ad-3.4, an automatic differentiation library in Haskell
Introduction to ad-3.4, an automatic differentiation library in HaskellIntroduction to ad-3.4, an automatic differentiation library in Haskell
Introduction to ad-3.4, an automatic differentiation library in Haskell
 
C++ Standard Template Library
C++ Standard Template LibraryC++ Standard Template Library
C++ Standard Template Library
 
Templates
TemplatesTemplates
Templates
 
Lecture 4
Lecture 4Lecture 4
Lecture 4
 
Parts of python programming language
Parts of python programming languageParts of python programming language
Parts of python programming language
 
Arrays
ArraysArrays
Arrays
 

Similar a 09. haskell Context

Functors, applicatives, monads
Functors, applicatives, monadsFunctors, applicatives, monads
Functors, applicatives, monadsrkaippully
 
Functional programming with haskell
Functional programming with haskellFunctional programming with haskell
Functional programming with haskellfaradjpour
 
Humble introduction to category theory in haskell
Humble introduction to category theory in haskellHumble introduction to category theory in haskell
Humble introduction to category theory in haskellJongsoo Lee
 
Bartosz Milewski, “Re-discovering Monads in C++”
Bartosz Milewski, “Re-discovering Monads in C++”Bartosz Milewski, “Re-discovering Monads in C++”
Bartosz Milewski, “Re-discovering Monads in C++”Platonov Sergey
 
Introduction to Functional Programming
Introduction to Functional ProgrammingIntroduction to Functional Programming
Introduction to Functional ProgrammingFrancesco Bruni
 
On fuctional programming, high order functions, ML
On fuctional programming, high order functions, MLOn fuctional programming, high order functions, ML
On fuctional programming, high order functions, MLSimone Di Maulo
 
Python Functions (PyAtl Beginners Night)
Python Functions (PyAtl Beginners Night)Python Functions (PyAtl Beginners Night)
Python Functions (PyAtl Beginners Night)Rick Copeland
 
python ppt.pptx
python ppt.pptxpython ppt.pptx
python ppt.pptxMONAR11
 
Lesson 4A - Inverses of Functions.ppt
Lesson 4A - Inverses of Functions.pptLesson 4A - Inverses of Functions.ppt
Lesson 4A - Inverses of Functions.pptssuser78a386
 
TI1220 Lecture 6: First-class Functions
TI1220 Lecture 6: First-class FunctionsTI1220 Lecture 6: First-class Functions
TI1220 Lecture 6: First-class FunctionsEelco Visser
 

Similar a 09. haskell Context (20)

Functors, applicatives, monads
Functors, applicatives, monadsFunctors, applicatives, monads
Functors, applicatives, monads
 
06. haskell type builder
06. haskell type builder06. haskell type builder
06. haskell type builder
 
Functional programming with haskell
Functional programming with haskellFunctional programming with haskell
Functional programming with haskell
 
Humble introduction to category theory in haskell
Humble introduction to category theory in haskellHumble introduction to category theory in haskell
Humble introduction to category theory in haskell
 
07. haskell Membership
07. haskell Membership07. haskell Membership
07. haskell Membership
 
Practical cats
Practical catsPractical cats
Practical cats
 
Scala qq
Scala qqScala qq
Scala qq
 
Functional programming java
Functional programming javaFunctional programming java
Functional programming java
 
introduction to matlab.pptx
introduction to matlab.pptxintroduction to matlab.pptx
introduction to matlab.pptx
 
Bartosz Milewski, “Re-discovering Monads in C++”
Bartosz Milewski, “Re-discovering Monads in C++”Bartosz Milewski, “Re-discovering Monads in C++”
Bartosz Milewski, “Re-discovering Monads in C++”
 
A taste of Functional Programming
A taste of Functional ProgrammingA taste of Functional Programming
A taste of Functional Programming
 
Introduction to Functional Programming
Introduction to Functional ProgrammingIntroduction to Functional Programming
Introduction to Functional Programming
 
iPython
iPythoniPython
iPython
 
On fuctional programming, high order functions, ML
On fuctional programming, high order functions, MLOn fuctional programming, high order functions, ML
On fuctional programming, high order functions, ML
 
Python Functions (PyAtl Beginners Night)
Python Functions (PyAtl Beginners Night)Python Functions (PyAtl Beginners Night)
Python Functions (PyAtl Beginners Night)
 
python ppt.pptx
python ppt.pptxpython ppt.pptx
python ppt.pptx
 
Lesson 4A - Inverses of Functions.ppt
Lesson 4A - Inverses of Functions.pptLesson 4A - Inverses of Functions.ppt
Lesson 4A - Inverses of Functions.ppt
 
04. haskell handling
04. haskell handling04. haskell handling
04. haskell handling
 
Porting to Python 3
Porting to Python 3Porting to Python 3
Porting to Python 3
 
TI1220 Lecture 6: First-class Functions
TI1220 Lecture 6: First-class FunctionsTI1220 Lecture 6: First-class Functions
TI1220 Lecture 6: First-class Functions
 

09. haskell Context

  • 1. Context Sebastian Rettig An applicative value can be seen as aa value with An applicative value can be seen as value with an added context. - - A fancy value. an added context. A fancy value.
  • 2. Functional Programming ● No Variables ● Functions only, eventually stored in Modules – Behavior do not change, once defined – → Function called with same parameter calculates always the same result ● Function definitions (Match Cases) ● Recursion (Memory)
  • 3. Haskell Features ● Pure Functional Programming Language ● Lazy Evaluation ● Pattern Matching and Guards ● List Comprehension ● Type Polymorphism
  • 4. Nice to remember (1) Typeclasses: ● define properties of the types ● like an interface – Eq can be compared – Ord can be ordered (>, <, >=, <=) (extending Eq) – Show can be shown as string – Read opposite of Show – Enum sequentially ordered types (can be enumerated and usable in List-Ranges ['a'..'e'])
  • 5. Nice to remember (2) Typeclass-Membership: 1. derive from existing Memberships of used types data Vector2D = Vector Float Float deriving (Show, Eq) 2. implement Membership by your own instance Show Vector2D where show Vector a b = “x: ” ++ [a] ++ “ ; y: ” ++ [b]
  • 6. Nice to remember (3) Curried Function: ● every function in haskell consumes exactly one parameter and returns a value ● PARTIAL APPLICATION ● so we could write the function header instead of: max :: (Ord a) => a -> a -> a ● also in the following way: max :: (Ord a) => a -> (a -> a)
  • 7. Nice to remember (4) Pointless Style: ● based on partial Application → simpler code maxWithFour x = max 4 x is the same as maxWithFour = max 4 ● use Function Application ($) to avoid Parenthesis on function call with parameters sqrt $ 3 + 4 + 9 ● use Function Composition (.) to avoid Parenthesis on chaining functions fn = ceiling . negate . tan . cos . max 50
  • 8. Type Refresher (1) create a Type: ● data MyVector = Nirvana | Single Int | Tuple Int Int | Triple Int Int Int ● MyVector is the Type ● Nirvana, Single, Tuple, Triple are Type Constructors ● Type Constructors are normal functions :t Single is Single :: Int -> MyVector ● Type Constructors can have Parameters (values) Single, Tuple, Triple have 1, 2 and 3
  • 9. Type Refresher (2) create a Type with Record Syntax: ● data MyVector2 = Nirvana2 | Single2 {x :: Int} | Tuple2 {x :: Int, y :: Int} | Triple2 {x :: Int, y :: Int, z :: Int} ● Nirvana2, Single2, Tuple2, Triple2 are Type Constructors ● x, y, z are selectors functions who lookup specific fields in the data type → like GET functions :t x is x :: MyVector2 -> Int ● e.g.: foo = Single2 {x=4} x foo returns 4 :t foo returns foo :: MyVector2
  • 10. Type Refresher (3) to make the Type more generic: ● data MyVector3 a = Nirvana3 | Single3 {x' :: a} | Tuple3 {x' :: a, y' :: a} | Triple3 {x' :: a, y' :: a, z' :: a} ● a is type parameter and selector x' has the following header :t x' is x' :: MyVector3 a -> a ● if we want to use this type, we have to set the Type parameter OR let Haskell detect the Type parameter ● e.g.: foo = Single3 {x'=4} :t foo returns foo :: MyVector3 Integer ● e.g.: foo = Nirvana3 :t foo returns foo :: MyVector3 a
  • 11. Type Refresher (4) a Type can have more than one Type parameter: ● data MyVector4 a b c = Nirvana4 | Single4 {x'' :: a} | Tuple4 {x'' :: a, y :: b} | Triple4 {x'' :: a, y'' :: b, z'' :: c} ● a, b, c are type parameter, selector x has header :t x'' is x'' :: MyVector4 a b c -> a ● e.g.: foo = Single4 {x''=4} :t foo returns foo :: MyVector4 Integer b c ● e.g.: foo = Nirvana4 :t foo returns foo :: MyVector4 a b c ● → Partial Application!
  • 12. Kind ● explains the steps which are necessary to evaluate the data from that type ● → evaluate = the type is fully applied ● can be used to find how much parameters a type has ● GHCi- Command :k ● :k MyVector returns MyVector :: * ● :k MyVector2 returns MyVector2 :: * ● :k MyVector3 returns MyVector3 :: * -> * ● :k MyVector4 returns MyVector4 :: * -> * -> * -> * ● :k MyVector3 Int returns MyVector3 Int :: * ● :k MyVector4 Int Int returns MyVector4 Int Int :: * -> *
  • 13. Useful Types ● Maybe: data Maybe a = Nothing | Just a – for operations, which can fail – contains data of type a (Just a) or Nothing – good for handling e.g. Hashmap lookup ● Either: data Either a b = Left a | Right b deriving (Eq, Ord, Read, Show) – can contain type a or type b – Left for e.g. Error Messages, Right for value – BUT why is Error Message the first parameter?
  • 14. Implement Membership (1) ● Let's refresh again how to implement a Typeclass- Membership: ● first the definition of Typeclass Eq: :i Eq class Eq a where (==) :: a -> a -> Bool (/=) :: a -> a -> Bool -- Defined in GHC.Classes ● What is a ? → a is used by (==) and (/=) as parameter ● → needs to be a fully applied type (concrete type) ● → :k must return *
  • 15. Implement Membership (2) ● But how can we make MyVector3 a member of Eq ? ● → we have to make MyVector3 fully applied type, e.g.: instance Eq (MyVector3 Int) where Nirvana3 == Nirvana3 = True Single3 {x'=x1} == Single3 {x'=x2} = (x1 == x2) ... ● Or with using generic Type Parameter: instance Eq (MyVector3 a) where Nirvana3 == Nirvana3 = True Single3 {x'=x1} == Single3 {x'=x2} = (x1 == x2) ... ● do a has Type-Class restrictions? If yes, which?
  • 16. Implement Membership (3) ● And what about that? instance Eq MyVector3 where Nirvana3 == Nirvana = True Single3 {x'=x1} == Single {x'=x2} = (x1 == x2) ... ● Is this membership correct?
  • 17. Functor Typeclass (1) class Functor f where fmap :: (a -> b) -> f a -> f b ● for things that can be mapped over ● !!! Functor needs Types with kind * -> * !!! ● fmap gets a function and a type and maps the function over the type variable → the type variable can change! ● Instance for List: instance Functor [] where fmap = map – Example: fmap (*2) [2,3,4] returns [4,6,8]
  • 18. Functor Typeclass (2) class Functor f where fmap :: (a -> b) -> f a -> f b ● Instance for Maybe instance Functor Maybe where fmap g (Just x) = Just (g x) fmap g Nothing = Nothing ● Example: – fmap (+3) Nothing returns Nothing – fmap (+3) (Just 4) returns (Just 7) – fmap (show) (Just 4) returns (Just “4”)
  • 19. Functor Typeclass (3) class Functor f where fmap :: (a -> b) -> f a -> f b ● Instance for Either instance Functor (Either a) where fmap f (Right x) = Right (f x) fmap f (Left x) = Left x ● Either is a type with kind * -> * -> * ! ● → we have to permanently include the first parameter in the instance (partial application) ● → fmap only maps over the second Type-Parameter! ● → Left Type-Constructor is often used for Error Messages
  • 20. Functor Typeclass (4) class Functor f where fmap :: (a -> b) -> f a -> f b ● Example: – fmap (+3) (Left 4) returns (Left 4) – fmap (+3) (Right 4) returns (Right 7) ● what happens, if we try to do that? fmap (+) (Just 4) ● let's look at the type: :t fmap (+) (Just 4) fmap (+) (Just 4) :: Num a => Maybe (a -> a) ● partial application, BUT we can not use the Functor instance on the result Just (4+) ● → we need an extension → Applicative Functors
  • 21. Lifting a Function ● if we partial apply fmap, the header has the following structure :t fmap (*2) results in fmap (*2) :: (Num a, Functor f) => f a -> f a :t fmap (cycle 3) results in fmap (cycle 3) :: (Functor f) => f a -> f [a] ● → this is called lifting a function ● → we can predefine a normal function which gets a Functor and returns a Functor ● → we move the function inside the Type and operate on type variables ● → we lift the function up to the type → normal function can work with complex types
  • 22. Applicative Functor (1) class (Functor f) => Applicative f where pure :: a -> f a (<*>) :: f (a -> b) -> f a -> f b ● pure is a function who wraps a normal value into applicative – creates a minimal context ● (<*>) takes a functor with a function in it and another functor – extracts that function from the first functor – and then maps it over the second one
  • 23. Applicative Functor (2) class (Functor f) => Applicative f where pure :: a -> f a (<*>) :: f (a -> b) -> f a -> f b ● Instance for Maybe instance Applicative Maybe where pure = Just Nothing <*> _ = Nothing (Just f) <*> something = fmap f something ● Example: – Just (+3) <*> Just 9 returns Just 12 – pure (+3) <*> Just 10 returns Just 13 – Just (++"hah") <*> Nothing returns Nothing
  • 24. Applicative Functor (3) class (Functor f) => Applicative f where pure :: a -> f a (<*>) :: f (a -> b) -> f a -> f b ● Instance for [] instance Applicative [] where pure x = [x] fs <*> xs = [f x | f <- fs, x <- xs] ● Example: – [(*0),(+100),(^2)] <*> [1,2,3] returns [0,0,0,101,102,103,1,4,9] – pure "Hey" :: [String] returns ["Hey"] – [(+),(*)] <*> [1,2] <*> [3,4] returns [4,5,5,6,3,4,6,8]
  • 25. Applicative Functor (4) ● pure f <*> x equals fmap f x ● → in Control.Applicative exists a specific function (<$>) :: (Functor f) => (a -> b) -> f a -> f b f <$> x = fmap f x ● So we can do the same much prettier: (++) <$> Just "johntra" <*> Just "volta" returns Just "johntravolta" (++) <$> ["ha","heh","hmm"] <*> ["?","!","."] returns ["ha?", "ha!", "ha.", "heh?", "heh!", "heh.", "hmm?", "hmm!", "hmm."]
  • 26. Applicative Functor (5) class (Functor f) => Applicative f where pure :: a -> f a (<*>) :: f (a -> b) -> f a -> f b ● Instance for IO instance Applicative IO where pure = return a <*> b = do f <- a x <- b return (f x)
  • 27. Applicative Functor (6) Example for IO: ● instead of writing this: myAction :: IO String myAction = do a <- getLine b <- getLine return $ a ++ b ● we can write this: myAction :: IO String myAction = (++) <$> getLine <*> getLine
  • 28. Applicative Context ● Applicative Types can bee seen as Types with context: – Maybe, Either for things which can fail – [ ] as non-deterministic result – IO as values send or get from outside ● Applicative functors allows us to operate in applicative types like normal types and provide the context! ● → We don't need to pattern match against the Context in every operation we use in our functions!
  • 29. Lifting a Function (Applicative) ● Function lifting in for Applicative: liftA :: Applicative f => (a -> b) -> f a -> f b – same as fmap – fmap :: Functor f => (a -> b) -> f a -> f b liftA2 :: (Applicative f) => (a -> b -> c) -> f a -> f b -> f c liftA2 f a b = f <$> a <*> b – gets a function, with 2 parameters – operates on 2 Applicatives – result is also an Applicative
  • 30. Sources [1] Haskell-Tutorial: Learn you a Haskell (http://learnyouahaskell.com/, 2012/03/15) [2] The Hugs User-Manual ( http://cvs.haskell.org/Hugs/pages/hugsman/index.html, 2012/03/15) [3] The Haskellwiki (http://www.haskell.org/haskellwiki, 2012/03/15)