SlideShare una empresa de Scribd logo
1 de 251
Descargar para leer sin conexión
Haskell
A Whirlwind Tour
     William Taysom
           2011
Haskell
Haskell

Who?

What?

When?

Where?

Why?

How?
Haskell

Who?

What?

When?

Where?

Why?

How?
Why?




       Aesthetics
Why? Aesthetics
“We provided DARPA with a copy of our prototype
implemented in Haskell without explaining that it was
a program, and based on preconceptions from their
past experience, they had studied the program under
the assumption that it was a mixture of requirements
specification and top level design. They were
convinced it was incomplete because it did not address
issues such as data structure design and execution
order.”
                                          — Paul Hudak
Why? Aesthetics



“Take Lisp: you know it's the most beautiful language
in the world. At least up until Haskell came along.”

                                         — Larry Wall
Why? Aesthetics



“Reading Haskell is like reading poetry.
Writing Haskell is like writing poetry.”

                                           — Oliver Steele
Why? Aesthetics


“I also have interest in Haskell, but my brain just
explodes every time I read a Haskell program bigger
than ten lines.”

                                             — Matz
Why? Aesthetics



“The biggest advantage of Haskell to me is that it helps
me write better programs in other languages.”

                                — Tenerife Skunkworks
Why? Aesthetics


.NET       LINQ

Python     List Comprehensions

Java       Generics

JavaScript jQuery
Why?




       Pragmatics
Why? Pragmatics


Platform    Compiler   Debugger     Profiler Testing

Libraries   Network      Graphics            Hackage

Community Books        Documentation         Hoogle
Why? Pragmatics


Platform    Compiler   Debugger     Profiler Testing

Libraries   Network      Graphics            Hackage

Community Books        Documentation         Hoogle
Why? Pragmatics
        Hoogle
Why? Pragmatics
        Hoogle
Why? Pragmatics


Platform    Compiler   Debugger     Profiler Testing

Libraries   Network      Graphics            Hackage

Community Books        Documentation         Hoogle
Why? Pragmatics


Platform    Compiler   Debugger     Profiler Testing

Libraries   Network      Graphics            Hackage

Community Books        Documentation         Hoogle
How?

       GHC
   Documentation
     Libraries
       Cabal
      Hackage
Why? Pragmatics


Platform    Compiler   Debugger     Profiler Testing

Libraries   Network      Graphics            Hackage

Community Books        Documentation         Hoogle
Why? Pragmatics
Why? Pragmatics
Why? Pragmatics

“A programming language must be considered in the
context of its community, and Haskell has an
exemplary one. I have come to believe, however, that
this polite exterior conceals a deep and consuming
madness.”

                                       — Avdi Grimm
Why?




       Performance
Why? Performance
The Computer Language Benchmarks Game
Why? Performance



             Web Server
   Pong benchmark, extra large instance, requests/second
Why? Performance



             Web Server
   Pong benchmark, extra large instance, requests/second
Why?


        Aesthetics
        Pragmatics
       Performance
Haskell

Who?

What?

When?

Where?

Why?     Aesthetics   Pragmatics   Performance

How?
Haskell

Who?

What?

When?

Where?

Why?     Aesthetics   Pragmatics   Performance

How?
Who? When? Where?




    September 1987
Who? When? Where?

   Portland, Oregon
Who? When? Where?



Functional Programming
Languages and Computer
Architecture Conference
Who? When? Where?


   A Dozen Purely
 Functional Languages
Who? When? Where?




     All Similar
Who? When? Where?
     Committee Formed
Who? When? Where?
     Committee Formed
Provide faster communication of new
ideas.

Stable foundation for real application
development.

Vehicle through which others would be
encouraged to use functional languages.
Who? When? Where?

Haskell Report
April 1st 1990

“You know, Haskell
actually never liked the
name Haskell.”

            — Mary Curry
Who? When? Where?


          2002

Revised Haskell 98 Report
Who? When? Where?


       2010

      Haskell'
Haskell

Who?    Research     Wadler   Hudak   Peyton-Jones

What?

When?   1987         1990     2002    Now

Where? Portland        Glasgow        Microsoft

Why?    Aesthetics     Pragmatics     Performance

How?
Haskell

Who?    Research     Wadler   Hudak   Peyton-Jones

What?

When?   1987         1990     2002    Now

Where? Portland        Glasgow        Microsoft

Why?    Aesthetics     Pragmatics     Performance

How?
What?


A non-strict, purely
functional programming
language with strong,
static type inference.
What?


A non-strict, purely
functional programming
language with strong,
static type inference.
What? Programming

Source Code

Formal, Textural Syntax

Static & Runtime Semantics

Data, Variables, Lexical Scope

Interpreter, Compiler
What?


A non-strict, purely
functional programming
language with strong,
static type inference.
What?


A non-strict, purely
functional programming
language with strong,
static type inference.
What? Functional




    (Not Imperative)
What? Functional

Imperative   Statements Executed Step-by-step
What? Functional

Imperative   Statements Executed Step-by-step
             Modifying State
What? Functional

Imperative   Statements Executed Step-by-step
             Modifying State
             Turing Machine
What? Functional

Imperative   Statements Executed Step-by-step
             Modifying State
             Von Neumann Architecture
What? Functional

Imperative   Statements Executed Step-by-step
             Modifying State
             Von Neumann Architecture


Functional   Expressions Recursively Simplified
What? Functional

Imperative   Statements Executed Step-by-step
             Modifying State
             Von Neumann Architecture


Functional   Expressions Recursively Simplified
             Reduced Value
What? Functional

Imperative   Statements Executed Step-by-step
             Modifying State
             Von Neumann Architecture


Functional   Expressions Recursively Simplified
             Reduced Value
             Lambda Calculus
What? Functional

Imperative   Statements Executed Step-by-step
             Modifying State
             Von Neumann Architecture


Functional   Expressions Recursively Simplified
             Reduced Value
             Lambda Calculus
What? Functional

Imperative   Statements Executed Step-by-step
             Modifying State
             Von Neumann Architecture


Functional   Expressions Recursively Simplified
             Reduced Value
             Lambda Calculus
What?


A non-strict, purely
functional programming
language with strong,
static type inference.
What?


A non-strict, purely
functional programming
language with strong,
static type inference.
What? Pure




    (No Side Effects)
What? Pure


    Immutable Only
What? Pure




Referential Transparency
What? Pure


    Functions always
  return the same value.

     If v = f x, then you can
    always replace f x with v.
What? Pure


    Functions always
  return the same value.

   If v equals f x, then you can
    always replace f x with v.
What?


A non-strict, purely
functional programming
language with strong,
static type inference.
What?


A non-strict, purely
functional programming
language with strong,
static type inference.
What? Non-strict


        Be lazy.
What? Non-strict


         Be lazy.

 Ignore evaluation order.
Wait...
if everything is
immutable and there
 are no side effects
and evaluation is lazy,
then how the hell do
  you do anything?
MONADS
 Bring your own Semicolon
What? Monads
What? Monads
What? Monads
What? Monads
What? Monads
What? Monads



“Haskell is the world's finest
imperative programming language.”

                            — Simon Peyton-Jones
What? Monads



“Haskell is the only language I know with
first-class support for imperative programming.”

                                             — SamB
What? Monads


“Haskell has no preferred imperative semantics, and
the monad just lets you swap out the semantics
according to your needs.”

                                     — Jared Updike
What?


A non-strict, purely
functional programming
language with strong,
static type inference.
What?


A non-strict, purely
functional programming
language with strong,
static type inference.
What? Types


       Strong
        Static
      Inference
What? Types


       Strong
        Static
      Inference
What? Strong Types

    Runtime values
      have types.
What? Strong Types

    Runtime values
      have types.
      like Java and Ruby
     unlike C and Assembly
          (Not Weak)
What? Types


       Strong
        Static
      Inference
What? Types


       Strong
        Static
      Inference
What? Static Types

 Source code expressions
       have types.
What? Static Types

 Source code expressions
       have types.
         like C and Java
   unlike Ruby and JavaScript
         (Not Dynamic)
What? Types


       Strong
        Static
      Inference
What? Types


       Strong
        Static
      Inference
What? Type Inference

Automatically determines
   types of variables.
What? Type Inference

Automatically determines
   types of variables.
       like C# and Go
      unlike C and Java
       (Not Manifest)
You don’t need to
 type the type!
SYNERGY
 Purity means types tell you a lot.
What? Type Purity

     No side effects
         mean,
What? Type Purity

     No side effects
         mean,
  argument and return
    types limit what
   a function can do.
What? Type Purity


“Haskell is so strict about type safety that randomly
generated snippets of code that successfully type check
are likely to do something useful, even if you've no idea
what that useful thing is.”

                                                — sigfpe
What? Type Purity


“Since when does "it compiles" equate to "it will run
(correctly)"? We're talking about C, after all, not
Haskell.”

                                         — Sean Russell
What? Types


       Strong
        Static
      Inference
What?


A non-strict, purely
functional programming
language with strong,
static type inference.
What?


A non-strict, purely
functional programming
language with strong,
static type inference.
Haskell

Who?    Research     Wadler   Hudak    Peyton-Jones

What?   Non-strict   Purely Functional Static Types

When?   1987         1990     2002     Now

Where? Portland         Glasgow        Microsoft

Why?    Aesthetics      Pragmatics     Performance

How?
Haskell

Who?    Research     Wadler   Hudak    Peyton-Jones

What?   Non-strict   Purely Functional Static Types

When?   1987         1990     2002     Now

Where? Portland         Glasgow        Microsoft

Why?    Aesthetics      Pragmatics     Performance

How?
How?


       Just Download
         and Install
        the Platform
How?


       Just Download
         and Install
        the Platform
Glorious Glasgow
Haskell Compilation
      System
GHC


Compiler      ghc

Interactive   ghci

Scripts       runghc
GHC


Compiler      ghc

Interactive   ghci

Scripts       runghc
Haskell

Who?    Research     Wadler   Hudak    Peyton-Jones

What?   Non-strict   Purely Functional Static Types

When?   1987         1990     2002     Now

Where? Portland         Glasgow        Microsoft

Why?    Aesthetics      Pragmatics     Performance

How?    Platform        Hoogle         Hackage
Haskell

Who?    Research     Wadler   Hudak    Peyton-Jones

What?   Non-strict   Purely Functional Static Types

When?   1987         1990     2002     Now

Where? Portland         Glasgow        Microsoft

Why?    Aesthetics      Pragmatics     Performance

How?    Platform        Hoogle         Hackage
Example
┼ $




      Example
$ ghci
$ ghci
GHCi, version 7.0.2: http://
www.haskell.org/ghc/ :? for help
Loading package ghc-prim ... linking ...
done.
Loading package integer-gmp ...
linking ... done.
Loading package base ... linking ...
done.
Loading package ffi-1.0 ... linking ...
done.
ghci>
$ ghci
GHCi, version 7.0.2: http://
www.haskell.org/ghc/ :? for help
Loading package ghc-prim ... linking ...
done.
Loading package integer-gmp ...
linking ... done.
Loading package base ... linking ...
done.
Loading package ffi-1.0 ... linking ...
done.
ghci> "hello, world"
$ ghci
GHCi, version 7.0.2: http://
www.haskell.org/ghc/ :? for help
Loading package ghc-prim ... linking ...
done.
Loading package integer-gmp ...
linking ... done.
Loading package base ... linking ...
done.
Loading package ffi-1.0 ... linking ...
done.
ghci> "hello, world"
"hello, world"
ghci>
"hello, world"
ghci>
"hello, world"
ghci> 6 * 9
"hello, world"
ghci> 6 * 9
42
ghci>
"hello, world"
ghci> 6 * 9
42
ghci> [1, 2, 3]
"hello, world"
ghci> 6 * 9
42
ghci> [1, 2, 3]
[1,2,3]
ghci>
"hello, world"
ghci> 6 * 9
42
ghci> [1, 2, 3]
[1,2,3]
ghci> it
"hello, world"
ghci> 6 * 9
42
ghci> [1, 2, 3]
[1,2,3]
ghci> it
[1,2,3]
ghci>
"hello, world"
ghci> 6 * 9
42
ghci> [1, 2, 3]
[1,2,3] application is so important in Haskell that
 “Function
ghci> it it using the quietest possible syntax:
 we denote
[1,2,3]at all.”
 nothing
ghci> reverse it
                               — Simon Peyton-Jones
“Function application is so important in Haskell that
we denote it using the quietest possible syntax:
nothing at all.”

                                — Simon Peyton-Jones
"hello, world"
ghci> 6 * 9
42
ghci> [1, 2, 3]
[1,2,3] application is so important in Haskell that
 “Function
ghci> it it using the quietest possible syntax:
 we denote
[1,2,3]at all.”
 nothing
ghci> reverse it
                               — Simon Peyton-Jones
"hello, world"
ghci> 6 * 9
42
ghci> [1, 2, 3]
[1,2,3]
ghci> it
[1,2,3]
ghci> reverse it
[3,2,1]
ghci>
[3,2,1]
ghci>
[3,2,1]
ghci> let xs = [1..100]
[3,2,1]
ghci> let xs = [1..100]
ghci>
[3,2,1]
ghci> let xs = [1..100]
ghci> xs
[3,2,1]
ghci> let xs = [1..100]
ghci> xs
[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,1
7,18,19,20,21,22,23,24,25,26,27,28,29,30,
31,32,33,34,35,36,37,38,39,40,41,42,43,44
,45,46,47,48,49,50,51,52,53,54,55,56,57,5
8,59,60,61,62,63,64,65,66,67,68,69,70,71,
72,73,74,75,76,77,78,79,80,81,82,83,84,85
,86,87,88,89,90,91,92,93,94,95,96,97,98,9
9,100]
ghci>
[3,2,1]
ghci> let xs = [1..100]
ghci> xs
[1,2,⋯,99,100]
ghci>
[3,2,1]
ghci> let xs = [1..100]
ghci> xs
[1,2,⋯,99,100]
ghci> [x | x <- xs, x > 21]
[3,2,1]
ghci> let xs = [1..100]
ghci> xs
[1,2,⋯,99,100]
ghci> [x | x <- xs, x > 21]
[22,23,24,25,26,27,28,29,30,31,32,33,34,3
5,36,37,38,39,40,41,42,43,44,45,46,47,48,
49,50,51,52,53,54,55,56,57,58,59,60,61,62
,63,64,65,66,67,68,69,70,71,72,73,74,75,7
6,77,78,79,80,81,82,83,84,85,86,87,88,89,
90,91,92,93,94,95,96,97,98,99,100]
ghci>
[3,2,1]
ghci> let xs = [1..100]
ghci> xs
[1,2,⋯,99,100]
ghci> [x | x <- xs, x > 21]
[22,23,⋯,99,100]
ghci>
[3,2,1]
ghci> let xs = [1..100]
ghci> xs
[1,2,⋯,99,100]
ghci> [x | x <- xs, x > 21]
[22,23,⋯,99,100]
ghci> filter (> 21) xs
[3,2,1]
ghci> let xs = [1..100]
ghci> xs
[1,2,⋯,99,100]
ghci> [x | x <- xs, x > 21]
[22,23,⋯,99,100]
ghci> filter (> 21) xs
[22,23,⋯,99,100]
ghci>
[3,2,1]
ghci> let xs = [1..100]
ghci> xs
[1,2,⋯,99,100]
ghci> [x | x <- xs, x > 21]
[22,23,⋯,99,100]
ghci> filter (> 21) xs
[22,23,⋯,99,100]
ghci> filter (x -> x > 21) xs
[3,2,1]
ghci> let xs = [1..100]
ghci> xs
[1,2,⋯,99,100]
ghci> [x | x <- xs, x > 21]
[22,23,⋯,99,100]

           TMTOWTDI
ghci> filter (> 21) xs
[22,23,⋯,99,100]
ghci> filter (x -> x > 21) xs
[22,23,⋯,99,100]
ghci>
TMTOWTDI
The Evolution of a
Haskell Programmer
1.    Freshman                13. Continuation-passing
2.    Sophomore               14. Boy Scout
3.    Junior (Peano)          15. Combinatory
4.    Junior (Ban n+k)        16. List-encoding
5.    Senior (Leans Right)    17. Interpretive
6.    Senior (Leans Left)     18. Static
7.    Senior (Leans Around)   19. Beginning Graduate
8.    Memoizing               20. Origamist
9.    Points-free             21. Cartesianally-inclined
10.   Iterative               22. Ph.D.
11.   Iterative one-liner     23. Post-doc
12.   Accumulating            24. Tenured Professor
TMTOWTDI
[3,2,1]
ghci> let xs = [1..100]
ghci> xs
[1,2,⋯,99,100]
ghci> [x | x <- xs, x > 21]
[22,23,⋯,99,100]

          TMTOWTDI
ghci> filter (> 21) xs
[22,23,⋯,99,100]
ghci> filter (x -> x > 21) xs
[22,23,⋯,99,100]
ghci>
[22,23,⋯,99,100]
ghci>
[22,23,⋯,99,100]
ghci> let divides = x y -> rem y x == 0
[22,23,⋯,99,100]
ghci> let divides = x y -> rem y x == 0
ghci>
[22,23,⋯,99,100]
ghci> let divides = x y -> rem y x == 0
ghci> let divides x y = rem y x == 0
[22,23,⋯,99,100]
ghci> let divides = x y -> rem y x == 0
ghci> let divides x y = rem y x == 0
ghci>
[22,23,⋯,99,100]
ghci> let divides = x y -> rem y x == 0
ghci> let divides x y = rem y x == 0
ghci> divides 3 12
[22,23,⋯,99,100]
ghci> let divides = x y -> rem y x == 0
ghci> let divides x y = rem y x == 0
ghci> divides 3 12
True
ghci>
[22,23,⋯,99,100]
ghci> let divides = x y -> rem y x == 0
ghci> let divides x y = rem y x == 0
ghci> divides 3 12
True
ghci> 3 `divides` 12
[22,23,⋯,99,100]
ghci> let divides = x y -> rem y x == 0
ghci> let divides x y = rem y x == 0
ghci> divides 3 12
True
ghci> 3 `divides` 12
True
ghci>
[22,23,⋯,99,100]
ghci> let divides = x y -> rem y x == 0
ghci> let divides x y = rem y x == 0
ghci> divides 3 12
True
ghci> 3 `divides` 12
True
ghci> let divisors x = [d | d <- [1..x],
d `divides` x]
[22,23,⋯,99,100]
ghci> let divides = x y -> rem y x == 0
ghci> let divides x y = rem y x == 0
ghci> divides 3 12
True
ghci> 3 `divides` 12
True
ghci> let divisors x = [d | d <- [1..x],
d `divides` x]
ghci>
[22,23,⋯,99,100]
ghci> let divides = x y -> rem y x == 0
ghci> let divides x y = rem y x == 0
ghci> divides 3 12
True
ghci> 3 `divides` 12
True
ghci> let divisors x = [d | d <- [1..x],
d `divides` x]
ghci> divisors 100
[22,23,⋯,99,100]
ghci> let divides = x y -> rem y x == 0
ghci> let divides x y = rem y x == 0
ghci> divides 3 12
True
ghci> 3 `divides` 12
True
         Fundamentals
ghci> let divisors x = [d | d <- [1..x],
d `divides` x]
ghci> divisors 100
[1,2,4,5,10,20,25,50,100]
ghci>
Fundamentals
Data Declaration

data Color = Red | Green | Blue
Variables

red = Red
-- Lower case for variable and upper case for
constructor.

nan = 0 / 0
-- Variables stand for values. They do not label
locations.
-- Don't need let because we aren't at GHCi.
-- Declarations go at top-level, not expressions.
(Like Java, unlike Ruby.)
Functions

hue Red = 0
hue Green = 120
hue Blue = 240
Lambda & Case

hue = c -> case c of
 Red    -> 0
 Green -> 120
 Blue -> 240
Pattern Wildcard

isRed Red = True
isRed _ = False
Boolean Data

data Bool = True | False
Boolean Functions

otherwise = True

not True = False
not False = True
Boolean Operators

True && x = x
False && _ = False

(||) True _ = True
(||) False x = x
-- Parenthesis let us use operators prefix.
Operator Precedence

infixr 3 &&
infixr 2 ||

-- Ten precedence levels: 0 binds least tightly, 9
(default) binds most tightly.

-- Three associativities: infixl (default), infixr,
infix (non-associative).
Types


“Types in Haskell express high-level design in the same
way that UML diagrams do in Object Oriented
languages.”

                                — Simon Peyton-Jones
Types
ghci> :l example




“Types in Haskell express high-level design in the same
way that UML diagrams do in Object Oriented
languages.”

                                — Simon Peyton-Jones
ghci> :l example
[1 of 1] Compiling Main
( example.hs, interpreted )
Ok, modules loaded: Main.
ghci>
ghci> :l example
[1 of 1] Compiling Main
( example.hs, interpreted )
Ok, modules loaded: Main.
ghci> :r
ghci> :l example
[1 of 1] Compiling Main
( example.hs, interpreted )
Ok, modules loaded: Main.
ghci> :r
Ok, modules loaded: Main.
ghci>
ghci> :l example
[1 of 1] Compiling Main
( example.hs, interpreted )
Ok, modules loaded: Main.
ghci> :r
Ok, modules loaded: Main.
ghci> :type red
ghci> :l example
[1 of 1] Compiling Main
( example.hs, interpreted )
Ok, modules loaded: Main.
ghci> :r
Ok, modules loaded: Main.
ghci> :type red
Red :: Color
ghci>
ghci> :l example
[1 of 1] Compiling Main
( example.hs, interpreted )
Ok, modules loaded: Main.
ghci> :r
Ok, modules loaded: Main.
ghci> :type red
Red :: Color
ghci> :t isRed
Types
ghci> :l example
[1 of 1] Compiling Main
( example.hs, interpreted )
Ok, :: Color loaded: Main.
 red modules
ghci> Double
 nan :: :r
Ok, modules loaded: Main.
ghci> Color -> Double
 hue :: :type red
Red :: Color
 otherwise :: Bool
ghci> :t isRed
isRed Bool -> Bool Bool
 not :: :: Color ->
ghci> (||) :: Bool -> Bool -> Bool
 (&&),
Types

red :: Color
nan :: Double

hue :: Color -> Double

otherwise :: Bool
not :: Bool -> Bool
(&&), (||) :: Bool -> Bool -> Bool
Recursive Data

data Color = Red | Green | Blue
           | Mix Color Color
Recursive Data

data Color = Red | Green | Blue
           | Mix Color Color

mix :: Color -> Color -> Color
mix = Mix
-- Mix is a type constructor function.
Recursive Data

yellow, cyan, magenta :: Color
yellow = Mix Red Green

Mix cyan magenta =
            Mix (Mix Green Blue) (Mix Red Blue)
-- Constructor functions can be used for pattern
matching, but variables bind.
Recursive Functions

isRed   :: Color -> Bool
isRed   Red        = True
isRed   (Mix c c') = isRed c && isRed c'
isRed   _          = False
Recursive Functions

hue   :: Color -> Double
hue   Red     =0
hue   Green = 120
hue   Blue    = 240
Recursive Functions

hue   :: Color -> Double
hue   Red     =0
hue   Green = 120
hue   Blue    = 240

hue (Mix c c') = ???
hue (Mix c c') = ???
hue (Mix c c') = ???


                       h
hue (Mix c c') = let
    h = hue c
    ???
                       h
h'
hue (Mix c c') = let
    h = hue c
    ???
                            h
h'
hue (Mix c c') = let
    h = hue c
    h' = hue c'
    ???                     h
h'   m
hue (Mix c c') = let
    h = hue c
    h' = hue c'
    ???                         h
h'   m
hue (Mix c c') = let
    h = hue c
    h' = hue c'
    m = average h h'            h
   ???
h'   m
hue (Mix c c') = let
    h = hue c
    h' = hue c'
    m = average h h'                    h

   average x y = abs (x + y) / 2
   ???
h'   m
hue (Mix c c') = let
    h = hue c
    h' = hue c'
    m = average h h'                     h

    average x y = abs (x + y) / 2
  in m
h'   m
hue (Mix c c') = let
    h = hue c
    h' = hue c'
    m = average h h'                     h

    average x y = abs (x + y) / 2
  in ??!
m
hue (Mix c c') = let
    h = hue c
    h' = hue c'
    m = average h h'                 h

    average x y = abs (x + y) / 2
  in ??!

                                h'
m
hue (Mix c c') = let
    h = hue c
    h' = hue c'
    m = average h h'                      h

    average x y = abs (x + y) / 2
  in ??!

                                h'   m'
m
hue (Mix c c') = let
    h = hue c
    h' = hue c'
    m = average h h'                      h
    m' = m + 180

    average x y = abs (x + y) / 2
  in ??!
                                h'   m'
m    d
hue (Mix c c') = let
    h = hue c
    h' = hue c'
    m = average h h'                      h
    m' = m + 180

    average x y = abs (x + y) / 2
  in ??!
                                h'   m'
m    d
hue (Mix c c') = let
    h = hue c
    h' = hue c'
    m = average h h'                      h
    m' = m + 180
    d = distance h m

    average x y = abs (x + y) / 2
  in ??!                        h'   m'
m    d
hue (Mix c c') = let
    h = hue c
    h' = hue c'
    m = average h h'                     h
    m' = m + 180
    d = distance h m

    average x y = abs (x + y) / 2
    distance x y = abs (x - y) h'   m'
  in ??!
m    d
hue (Mix c c') = let
    h = hue c
    h' = hue c'
    m = average h h'                     h
    m' = m + 180
    d = distance h m

    average x y = abs (x + y) / 2
    distance x y = abs (x - y) h'   m'
  in case compare d 90 of
    LT -> m
    EQ -> ??!
    GT -> m'
m    d
hue (Mix c c') = let
    h = hue c
    h' = hue c'
    m = average h h'                     h
    m' = m + 180
    d = distance h m

    average x y = abs (x + y) / 2
    distance x y = abs (x - y) h'   m'
  in case compare d 90 of
    LT -> m
    EQ -> nan
    GT -> m'
m    d
hue (Mix c c') = r where
  r = case compare d 90 of
    LT -> m
    EQ -> nan                             h
    GT -> m'
  h = hue c
  h' = hue c'
  m = average h h'
  m' = m + 180                  h'   m'
  d = distance h m

average x y = abs (x + y) / 2
distance x y = abs (x - y)
Testing


test-framework   organize tests

HUnit            what you’re used to

QuickCheck       test properties with

                 automatically generated data
QuickCheck

prop_hue_bounds c = let h = hue c in
  isNaN h || 0 <= h && h < 360
QuickCheck

prop_hue_bounds c = let h = hue c in
  isNaN h || 0 <= h && h < 360

prop_hue_mix_reflexivity c = let h = hue c in
  isNaN h || hue (Mix c c) == h
QuickCheck

prop_hue_bounds c = let h = hue c in
  isNaN h || 0 <= h && h < 360

prop_hue_mix_reflexivity c = let h = hue c in
  isNaN h || hue (Mix c c) == h

prop_hue_mix_commutativity c c' =
  let h = hue (Mix c c') in
    isNaN h || hue (Mix c' c) == h
QuickCheck
ghci> quickCheck prop_hue_mix_commutativi
ty


prop_hue_bounds c = let h = hue c in
  isNaN h || 0 <= h && h < 360

prop_hue_mix_reflexivity c = let h = hue c in
  isNaN h || hue (Mix c c) == h

prop_hue_mix_commutativity c c' =
  let h = hue (Mix c c') in
    isNaN h || hue (Mix c' c) == h
ghci> quickCheck prop_hue_mix_commutativi
ty
+++ OK, passed 100 tests.
ghci>
ghci> quickCheck prop_hue_mix_commutativi
ty
+++ OK, passed 100 tests.
ghci> quickCheck prop_hue_mix_reflexivity
ghci> quickCheck prop_hue_mix_commutativi
ty
+++ OK, passed 100 tests.
ghci> quickCheck prop_hue_mix_reflexivity
+++ OK, passed 100 tests.
ghci>
ghci> quickCheck prop_hue_mix_commutativi
ty
+++ OK, passed 100 tests.
ghci> quickCheck prop_hue_mix_reflexivity
+++ OK, passed 100 tests.
ghci> quickCheck prop_hue_bounds
ghci> quickCheck prop_hue_mix_commutativi
ty
+++ OK, passed 100 tests.
ghci> quickCheck prop_hue_mix_reflexivity
+++ OK, passed 100 tests.
ghci> quickCheck prop_hue_bounds
*** Failed! Falsifiable (after 3 tests):
Mix (Mix Red Blue) (Mix Green Red)
ghci>
ghci> quickCheck prop_hue_mix_commutativi
ty
+++ OK, passed 100 tests.
ghci> quickCheck prop_hue_mix_reflexivity
+++ OK, passed 100 tests.
ghci> quickCheck prop_hue_bounds
*** Failed! Falsifiable (after 3 tests):
Mix (Mix Red Blue) (Mix Green Red)
ghci> hue (Mix magenta yellow)
ghci> quickCheck prop_hue_mix_commutativi
ty
+++ OK, passed 100 tests.
ghci> quickCheck prop_hue_mix_reflexivity
+++ OK, passed 100 tests.
ghci> quickCheck prop_hue_bounds
*** Failed! Falsifiable (after 3 tests):
Mix (Mix Red Blue) (Mix Green Red)
ghci> hue (Mix magenta yellow)
360.0
ghci>
h'
hue (Mix c c') = r where
  r = case compare d 90 of
    LT -> m
    EQ -> nan              m          m'
    GT -> m'
  h = hue c
  h' = hue c'
  m = average h h'
                             d   h
  m' = m + 180
  d = distance h m
h'
hue (Mix c c') = r where
  r = case compare d 90 of
    LT -> m
    EQ -> nan              m          m'
    GT -> m'
  h = hue c
  h' = hue c'
  m = average h h'
                             d   h
  m' = normalize (m + 180)
  d = distance h m
h'
hue (Mix c c') = r where
  r = case compare d 90 of
    LT -> m
    EQ -> nan              m             m'
    GT -> m'
  h = hue c
  h' = hue c'
  m = average h h'
                             d      h
  m' = normalize (m + 180)
  d = distance h m

normalize h | h < 360 = h
            | otherwise = h - 360
h'
hue (Mix c c') = r where
  r = case compare d 90 of
    LT -> m
    EQ -> nan              m                    m'
    GT -> m'
  h = hue c
  h' = hue c'
  m = average h h'
                             d            h
  m' = normalize (m + 180)
  d = distance h m

normalize h | h < 360 = h
            | otherwise = normalize (h - 360)
ghci>                                      h'
 hue (Mix c c') = r where
   r = case compare d 90 of
     LT -> m
     EQ -> nan              m                   m'
     GT -> m'
   h = hue c
   h' = hue c'
   m = average h h'
                              d           h
   m' = normalize (m + 180)
   d = distance h m

normalize h | h < 360 = h
            | otherwise = normalize (h - 360)
ghci> quickCheck prop_hue_bounds



                                   m'
ghci> quickCheck prop_hue_bounds
+++ OK, passed 100 tests.
ghci>
                                   m'
QuickCheck

prop_hue_mix_nothing c c' =
 distance (hue c) (hue c') == 180 ==>
   isNaN (hue (Mix c c'))
QuickCheck
ghci> quickCheck prop_hue_mix_nothing



prop_hue_mix_nothing c c' =
 distance (hue c) (hue c') == 180 ==>
   isNaN (hue (Mix c c'))
QuickCheck
ghci> quickCheck prop_hue_mix_nothing
*** Gave up! Passed only 23 tests.
ghci>
prop_hue_mix_nothing c c' =
 distance (hue c) (hue c') == 180 ==>
   isNaN (hue (Mix c c'))
QuickCheck

prop_hue_mix_nothing c c' =
 distance (hue c) (hue c') == 180 ==>
   isNaN (hue (Mix c c'))
QuickCheck

prop_hue_mix_nothing c c' =
 distance (hue c) (hue c') == 180 ==>
   isNaN (hue (Mix c c'))

-- Can we easily find the complement of a color?
complement   Red        =   ???
complement   Green      =   ???
complement   Blue       =   ???
complement   (Mix c c') =   ???
complement   Red        =   cyan
complement   Green      =   ???
complement   Blue       =   ???
complement   (Mix c c') =   ???
complement   Red        =   cyan
complement   Green      =   magenta
complement   Blue       =   ???
complement   (Mix c c') =   ???
complement   Red        =   cyan
complement   Green      =   magenta
complement   Blue       =   yellow
complement   (Mix c c') =   ???
complement   Red        =   cyan
complement   Green      =   magenta
complement   Blue       =   yellow
complement   (Mix c c') =   Mix ???
                                 ???
complement   Red        =   cyan
complement   Green      =   magenta
complement   Blue       =   yellow
complement   (Mix c c') =   Mix (complement c )
                                 (complement c' )
QuickCheck

prop_complement c = let h = hue c in
  not (isNaN h) ==>
    distance h (hue (complement c)) == 180
QuickCheck

prop_complement c = let h = hue c in
  not (isNaN h) ==>
    distance h (hue (complement c)) == 180

prop_hue_mix_complement c =
 isNaN (hue (Mix c (complement c)))
QuickCheck
ghci> quickCheck prop_complement



prop_complement c = let h = hue c in
  not (isNaN h) ==>
    distance h (hue (complement c)) == 180

prop_hue_mix_complement c =
 isNaN (hue (Mix c (complement c)))
ghci> quickCheck prop_complement
+++ OK, passed 100 tests.
ghci>
ghci> quickCheck prop_complement
+++ OK, passed 100 tests.
ghci> quickCheck prop_hue_mix_complement
ghci> quickCheck prop_complement
+++ OK, passed 100 tests.
ghci> quickCheck prop_hue_mix_complement
+++ OK, passed 100 tests.
ghci>
To be continued...
Summary


Haskell is functional.

Haskell has types.

QuickCheck is cool.
Preview: Infinite Lists

primes = sieve [2..] where
  sieve (p:xs) =
    p : sieve [x | x <- xs, rem x p /= 0]
Preview: IO (echo.hs)

import System.Environment (getArgs)
import Data.List (intercalate)

main = do
  args <- getArgs
  putStrLn (intercalate " " args)
Preview: Parsers
Preview: Parse JSON

data Value =   String   String
           |   Number   Double
           |   Object   [(String, Value)]
           |   Array    [Value]
           |   Bool     Bool
           |   Null
Preview: Parse JSON

value = String     <$>jsstring
    <|> Number <$>number
    <|> Object     <$>commaGroup '{' pair '}'
    <|> Array      <$>commaGroup '[' value ']'
    <|> Bool True <$ string "true"
    <|> Bool False <$ string "false"
    <|> Null       <$ string "null"
Preview: Parse JSON

pair :: Parser (String, Value)
pair = do
  s <- jsstring
  sp_char_sp ':'
  v <- value
  spaces
  return (s, v)
To be continued...

Más contenido relacionado

La actualidad más candente

Break Free with Managed Functional Programming: An Introduction to F#
Break Free with Managed Functional Programming: An Introduction to F#Break Free with Managed Functional Programming: An Introduction to F#
Break Free with Managed Functional Programming: An Introduction to F#IndyMobileNetDev
 
Break Free with Managed Functional Programming: An Introduction to F#
Break Free with Managed Functional Programming: An Introduction to F#Break Free with Managed Functional Programming: An Introduction to F#
Break Free with Managed Functional Programming: An Introduction to F#Dave Fancher
 
Introduction to Hanjp-IM Project (DebConf18 - Hsinchu, Taiwan)
Introduction to Hanjp-IM Project (DebConf18 - Hsinchu, Taiwan)Introduction to Hanjp-IM Project (DebConf18 - Hsinchu, Taiwan)
Introduction to Hanjp-IM Project (DebConf18 - Hsinchu, Taiwan)Youngbin Han
 
Ruby and Rails short motivation
Ruby and Rails short motivationRuby and Rails short motivation
Ruby and Rails short motivationjistr
 
2012-02-15 jfokus2012 - regex applied
2012-02-15 jfokus2012 - regex applied2012-02-15 jfokus2012 - regex applied
2012-02-15 jfokus2012 - regex appliedStaffan Nöteberg
 
Beam me up, scotty (PUG Roma)
Beam me up, scotty (PUG Roma)Beam me up, scotty (PUG Roma)
Beam me up, scotty (PUG Roma)Gianluca Padovani
 
NLP using JavaScript Natural Library
NLP using JavaScript Natural LibraryNLP using JavaScript Natural Library
NLP using JavaScript Natural LibraryAniruddha Chakrabarti
 
Julia language: inside the corporation
Julia language: inside the corporationJulia language: inside the corporation
Julia language: inside the corporationAndre Pemmelaar
 
Intelligent System Scripting Language - Conceptual Presentation
Intelligent System Scripting Language - Conceptual PresentationIntelligent System Scripting Language - Conceptual Presentation
Intelligent System Scripting Language - Conceptual PresentationCédric Poottaren
 
Meta Programming in Ruby - Code Camp 2010
Meta Programming in Ruby - Code Camp 2010Meta Programming in Ruby - Code Camp 2010
Meta Programming in Ruby - Code Camp 2010ssoroka
 
GraphQL in Ruby on Rails - basics
GraphQL in Ruby on Rails - basicsGraphQL in Ruby on Rails - basics
GraphQL in Ruby on Rails - basicsVisuality
 
Automating boring and repetitive UbuCon Asia video and subtitle stuffs
Automating boring and repetitive UbuCon Asia video and subtitle stuffsAutomating boring and repetitive UbuCon Asia video and subtitle stuffs
Automating boring and repetitive UbuCon Asia video and subtitle stuffsYoungbin Han
 
Functions, anonymous functions and the function type
Functions, anonymous functions and the function typeFunctions, anonymous functions and the function type
Functions, anonymous functions and the function typeChang John
 
Dart: A Replacement for JavaScript and Why You Should Care
Dart: A Replacement for JavaScript and Why You Should CareDart: A Replacement for JavaScript and Why You Should Care
Dart: A Replacement for JavaScript and Why You Should CareKevin Gisi
 
PHP Reactive Programming at Medan Tech Day 2018
PHP Reactive Programming at Medan Tech Day 2018PHP Reactive Programming at Medan Tech Day 2018
PHP Reactive Programming at Medan Tech Day 2018Dolly Aswin Harahap
 
How I Learned to Stop Worrying and Love Legacy Code.....
How I Learned to Stop Worrying and Love Legacy Code.....How I Learned to Stop Worrying and Love Legacy Code.....
How I Learned to Stop Worrying and Love Legacy Code.....Mike Harris
 
Build software like a bag of marbles, not a castle of LEGO®
Build software like a bag of marbles, not a castle of LEGO®Build software like a bag of marbles, not a castle of LEGO®
Build software like a bag of marbles, not a castle of LEGO®Hannes Lowette
 

La actualidad más candente (19)

Break Free with Managed Functional Programming: An Introduction to F#
Break Free with Managed Functional Programming: An Introduction to F#Break Free with Managed Functional Programming: An Introduction to F#
Break Free with Managed Functional Programming: An Introduction to F#
 
Break Free with Managed Functional Programming: An Introduction to F#
Break Free with Managed Functional Programming: An Introduction to F#Break Free with Managed Functional Programming: An Introduction to F#
Break Free with Managed Functional Programming: An Introduction to F#
 
Introduction to Hanjp-IM Project (DebConf18 - Hsinchu, Taiwan)
Introduction to Hanjp-IM Project (DebConf18 - Hsinchu, Taiwan)Introduction to Hanjp-IM Project (DebConf18 - Hsinchu, Taiwan)
Introduction to Hanjp-IM Project (DebConf18 - Hsinchu, Taiwan)
 
Stay fresh
Stay freshStay fresh
Stay fresh
 
Ruby and Rails short motivation
Ruby and Rails short motivationRuby and Rails short motivation
Ruby and Rails short motivation
 
2012-02-15 jfokus2012 - regex applied
2012-02-15 jfokus2012 - regex applied2012-02-15 jfokus2012 - regex applied
2012-02-15 jfokus2012 - regex applied
 
Beam me up, scotty (PUG Roma)
Beam me up, scotty (PUG Roma)Beam me up, scotty (PUG Roma)
Beam me up, scotty (PUG Roma)
 
NLP using JavaScript Natural Library
NLP using JavaScript Natural LibraryNLP using JavaScript Natural Library
NLP using JavaScript Natural Library
 
Julia language: inside the corporation
Julia language: inside the corporationJulia language: inside the corporation
Julia language: inside the corporation
 
Why Scala?
Why Scala?Why Scala?
Why Scala?
 
Intelligent System Scripting Language - Conceptual Presentation
Intelligent System Scripting Language - Conceptual PresentationIntelligent System Scripting Language - Conceptual Presentation
Intelligent System Scripting Language - Conceptual Presentation
 
Meta Programming in Ruby - Code Camp 2010
Meta Programming in Ruby - Code Camp 2010Meta Programming in Ruby - Code Camp 2010
Meta Programming in Ruby - Code Camp 2010
 
GraphQL in Ruby on Rails - basics
GraphQL in Ruby on Rails - basicsGraphQL in Ruby on Rails - basics
GraphQL in Ruby on Rails - basics
 
Automating boring and repetitive UbuCon Asia video and subtitle stuffs
Automating boring and repetitive UbuCon Asia video and subtitle stuffsAutomating boring and repetitive UbuCon Asia video and subtitle stuffs
Automating boring and repetitive UbuCon Asia video and subtitle stuffs
 
Functions, anonymous functions and the function type
Functions, anonymous functions and the function typeFunctions, anonymous functions and the function type
Functions, anonymous functions and the function type
 
Dart: A Replacement for JavaScript and Why You Should Care
Dart: A Replacement for JavaScript and Why You Should CareDart: A Replacement for JavaScript and Why You Should Care
Dart: A Replacement for JavaScript and Why You Should Care
 
PHP Reactive Programming at Medan Tech Day 2018
PHP Reactive Programming at Medan Tech Day 2018PHP Reactive Programming at Medan Tech Day 2018
PHP Reactive Programming at Medan Tech Day 2018
 
How I Learned to Stop Worrying and Love Legacy Code.....
How I Learned to Stop Worrying and Love Legacy Code.....How I Learned to Stop Worrying and Love Legacy Code.....
How I Learned to Stop Worrying and Love Legacy Code.....
 
Build software like a bag of marbles, not a castle of LEGO®
Build software like a bag of marbles, not a castle of LEGO®Build software like a bag of marbles, not a castle of LEGO®
Build software like a bag of marbles, not a castle of LEGO®
 

Similar a Haskell Tour (Part 1)

Functional programming with Xtend
Functional programming with XtendFunctional programming with Xtend
Functional programming with XtendSven Efftinge
 
Programming Paradigms
Programming ParadigmsProgramming Paradigms
Programming ParadigmsJaneve George
 
Os Keysholistic
Os KeysholisticOs Keysholistic
Os Keysholisticoscon2007
 
Elasticsearch Basics
Elasticsearch BasicsElasticsearch Basics
Elasticsearch BasicsShifa Khan
 
Scala: functional programming for the imperative mind
Scala: functional programming for the imperative mindScala: functional programming for the imperative mind
Scala: functional programming for the imperative mindSander Mak (@Sander_Mak)
 
Programming Paradigms
Programming ParadigmsProgramming Paradigms
Programming ParadigmsDirecti Group
 
Introduction to Scala
Introduction to ScalaIntroduction to Scala
Introduction to ScalaJohan Andrén
 
sete linguagens em sete semanas
sete linguagens em sete semanassete linguagens em sete semanas
sete linguagens em sete semanastdc-globalcode
 
Александр Ломов: "Reactjs + Haskell + Cloud Foundry = Love"
Александр Ломов: "Reactjs + Haskell + Cloud Foundry = Love"Александр Ломов: "Reactjs + Haskell + Cloud Foundry = Love"
Александр Ломов: "Reactjs + Haskell + Cloud Foundry = Love"Olga Lavrentieva
 
[WebCamp2014] Towards functional web
[WebCamp2014] Towards functional web[WebCamp2014] Towards functional web
[WebCamp2014] Towards functional webBlaž Repas
 
PL Lecture 01 - preliminaries
PL Lecture 01 - preliminariesPL Lecture 01 - preliminaries
PL Lecture 01 - preliminariesSchwannden Kuo
 
The Holistic Programmer
The Holistic ProgrammerThe Holistic Programmer
The Holistic ProgrammerAdam Keys
 
BayFP: Concurrent and Multicore Haskell
BayFP: Concurrent and Multicore HaskellBayFP: Concurrent and Multicore Haskell
BayFP: Concurrent and Multicore HaskellBryan O'Sullivan
 
Little words of wisdom for the developer - Guillaume Laforge (Pivotal)
Little words of wisdom for the developer - Guillaume Laforge (Pivotal)Little words of wisdom for the developer - Guillaume Laforge (Pivotal)
Little words of wisdom for the developer - Guillaume Laforge (Pivotal)jaxLondonConference
 

Similar a Haskell Tour (Part 1) (20)

Functional programming with Xtend
Functional programming with XtendFunctional programming with Xtend
Functional programming with Xtend
 
TypeScript
TypeScriptTypeScript
TypeScript
 
Programming Paradigms
Programming ParadigmsProgramming Paradigms
Programming Paradigms
 
Os Keysholistic
Os KeysholisticOs Keysholistic
Os Keysholistic
 
Elasticsearch Basics
Elasticsearch BasicsElasticsearch Basics
Elasticsearch Basics
 
Presentation
PresentationPresentation
Presentation
 
Scala: functional programming for the imperative mind
Scala: functional programming for the imperative mindScala: functional programming for the imperative mind
Scala: functional programming for the imperative mind
 
Programming Paradigms
Programming ParadigmsProgramming Paradigms
Programming Paradigms
 
Swift vs. Language X
Swift vs. Language XSwift vs. Language X
Swift vs. Language X
 
Introduction to Scala
Introduction to ScalaIntroduction to Scala
Introduction to Scala
 
sete linguagens em sete semanas
sete linguagens em sete semanassete linguagens em sete semanas
sete linguagens em sete semanas
 
Александр Ломов: "Reactjs + Haskell + Cloud Foundry = Love"
Александр Ломов: "Reactjs + Haskell + Cloud Foundry = Love"Александр Ломов: "Reactjs + Haskell + Cloud Foundry = Love"
Александр Ломов: "Reactjs + Haskell + Cloud Foundry = Love"
 
Jax keynote
Jax keynoteJax keynote
Jax keynote
 
[WebCamp2014] Towards functional web
[WebCamp2014] Towards functional web[WebCamp2014] Towards functional web
[WebCamp2014] Towards functional web
 
PL Lecture 01 - preliminaries
PL Lecture 01 - preliminariesPL Lecture 01 - preliminaries
PL Lecture 01 - preliminaries
 
The Holistic Programmer
The Holistic ProgrammerThe Holistic Programmer
The Holistic Programmer
 
BayFP: Concurrent and Multicore Haskell
BayFP: Concurrent and Multicore HaskellBayFP: Concurrent and Multicore Haskell
BayFP: Concurrent and Multicore Haskell
 
Introduction to Scala
Introduction to ScalaIntroduction to Scala
Introduction to Scala
 
Scala: An OO Surprise
Scala: An OO SurpriseScala: An OO Surprise
Scala: An OO Surprise
 
Little words of wisdom for the developer - Guillaume Laforge (Pivotal)
Little words of wisdom for the developer - Guillaume Laforge (Pivotal)Little words of wisdom for the developer - Guillaume Laforge (Pivotal)
Little words of wisdom for the developer - Guillaume Laforge (Pivotal)
 

Último

Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)wesley chun
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobeapidays
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingEdi Saputra
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...apidays
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...Martijn de Jong
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityPrincipled Technologies
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...apidays
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century educationjfdjdjcjdnsjd
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfsudhanshuwaghmare1
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...DianaGray10
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsJoaquim Jorge
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Drew Madelung
 

Último (20)

Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 

Haskell Tour (Part 1)