The document discusses types in Haskell, explaining that Haskell is strongly typed and describing basic types like Int, Char, and Bool as well as more complex types like tuples, lists, and functions. It also covers type inference, polymorphism, and how to infer the behavior of functions from their types.
Scala 3 enum for a terser Option Monad Algebraic Data TypePhilip Schwarz
(download for flawless slides)
* Explore a terser definition of the Option Monad that uses a Scala 3 enum as an Algebraic Data Type.
* In the process, have a tiny bit of fun with Scala 3 enums.
* Get a refresher on the Functor and Monad laws.
* See how easy it is to use Scala 3 extension methods, e.g. to add convenience methods and infix operators.
The diagrams for function composition and Kleisli composition were made using https://q.uiver.app/ by https://twitter.com/varkora.
Source code: https://github.com/philipschwarz/scala-3-enum-for-terser-option-monad-algebraic-data-type
Errata:
slide 14 is an unwanted leftover - it is the same as slide 15 minus a diagram.
on slide 19, the colons in the extension method declarations are not needed
N-Queens Combinatorial Problem - Polyglot FP for Fun and Profit - Haskell and...Philip Schwarz
See how feeding FP workhorses map and filter with monadic steroids turns them into the intriguing mapM and filterM.
Graduate to foldM by learning how it behaves with the help of three simple yet instructive examples of its usage.
Use the powers of foldM to generate all permutations of a collection with a simple one-liner.
Exploit what you learned about foldM to solve the N-Queens Combinatorial Problem with an iterative approach rather than a recursive one.
Scala 3 enum for a terser Option Monad Algebraic Data TypePhilip Schwarz
(download for flawless slides)
* Explore a terser definition of the Option Monad that uses a Scala 3 enum as an Algebraic Data Type.
* In the process, have a tiny bit of fun with Scala 3 enums.
* Get a refresher on the Functor and Monad laws.
* See how easy it is to use Scala 3 extension methods, e.g. to add convenience methods and infix operators.
The diagrams for function composition and Kleisli composition were made using https://q.uiver.app/ by https://twitter.com/varkora.
Source code: https://github.com/philipschwarz/scala-3-enum-for-terser-option-monad-algebraic-data-type
Errata:
slide 14 is an unwanted leftover - it is the same as slide 15 minus a diagram.
on slide 19, the colons in the extension method declarations are not needed
N-Queens Combinatorial Problem - Polyglot FP for Fun and Profit - Haskell and...Philip Schwarz
See how feeding FP workhorses map and filter with monadic steroids turns them into the intriguing mapM and filterM.
Graduate to foldM by learning how it behaves with the help of three simple yet instructive examples of its usage.
Use the powers of foldM to generate all permutations of a collection with a simple one-liner.
Exploit what you learned about foldM to solve the N-Queens Combinatorial Problem with an iterative approach rather than a recursive one.
The Functional Programming Triad of Map, Filter and FoldPhilip Schwarz
This slide deck is my homage to SICP, the book which first introduced me to the Functional Programming triad of map, filter and fold.
It was during my Computer Science degree that a fellow student gave me a copy of the first edition, not long after the book came out.
I have not yet come across a better introduction to these three functions.
The upcoming slides are closely based on the second edition of the book, a free online copy of which can be found here:
https://mitpress.mit.edu/sites/default/files/sicp/full-text/book/book.html.
Download for original image quality.
Errata:
slide 20: the Clojure map function is in fact the Scheme one repeated - see code below for correction.
Scheme code: https://github.com/philipschwarz/the-fp-triad-of-map-filter-and-fold-scheme
Clojure code: https://github.com/philipschwarz/the-fp-triad-of-map-filter-and-fold-clojure
Presented online for C++ on Sea (2020-07-17)
Video at https://www.youtube.com/watch?v=Bai1DTcCHVE
Lambdas. All the cool kid languages have them. But does lambda mean what C++ and other languages, from Java to Python, mean by lambda? Where did lambdas come from? What were they originally for? What is their relationship to data abstraction?
In this session we will into the history, the syntax, the uses and abuses of lambdas and the way in which lambda constructs in C++ and other languages do (or do not) match the original construct introduced in lambda calculus.
N-Queens Combinatorial Problem - Polyglot FP for Fun and Profit – Haskell and...Philip Schwarz
See how the guard function has migrated from MonadPlus to Alternative and learn something about the latter.
Learn how to write a Scala program that draws an N-Queens solution board using the Doodle graphics library.
See how to write the equivalent Haskell program using the Gloss graphics library.
Learn how to use Monoid and Foldable to compose images both in Haskell and in Scala.
Link to part 1: https://www.slideshare.net/pjschwarz/nqueens-combinatorial-problem-polyglot-fp-for-fun-and-profit-haskell-and-scala-part-1
Errata:
On slide 22, the last line of the showQueens function should of course be show(solution).draw(frame) rather than show(solution).draw
On slide 43, it would be better if the definitions of the beside, above and on Monoids were also shown.
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - Part ...Philip Schwarz
(download for flawless image quality) Can a left fold ever work over an infinite list? What about a right fold? Find out.
Learn about the other two functions used by functional programmers to implement mathematical induction: iterating and scanning.
Learn about the limitations of the accumulator technique and about tupling, a technique that is the dual of the accumulator trick.
Function Applicative for Great Good of Palindrome Checker Function - Polyglot...Philip Schwarz
Embark on an informative and fun journey through everything you need to know to understand how the Applicative instance for functions makes for a terse palindrome checker function definition in point-free style.
download for better quality - Learn about the sequence and traverse functions
through the work of Runar Bjarnason and Paul Chiusano, authors of Functional Programming in Scala https://www.manning.com/books/functional-programming-in-scala, and others (Martin Odersky, Derek Wyatt, Adelbert Chang)
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - Part 5Philip Schwarz
(download for best quality slides) Gain a deeper understanding of why right folds over very large and infinite lists are sometimes possible in Haskell.
See how lazy evaluation and function strictness affect left and right folds in Haskell.
Learn when an ordinary left fold results in a space leak and how to avoid it using a strict left fold.
Errata:
slide 15: "as sharing is required" should be "as sharing is not required"
slide 43: 𝑠𝑓𝑜𝑙𝑑𝑙 (⊕) 𝑎 should be 𝑠𝑓𝑜𝑙𝑑𝑙 (⊕) 𝑒
The Functional Programming Triad of Folding, Scanning and Iteration - a first...Philip Schwarz
This slide deck can work both as an aide mémoire (memory jogger), or as a first (not completely trivial) example of using left folds, left scans and iteration, to implement mathematical induction.
Errata: on almost half of the slides there is some minor typo or imperfection or in some cases a minor error and in one case, an omission. See a later version for corrections and some improvements.
(for best quality images, either download or view here: https://philipschwarz.dev/fpilluminated/?page_id=455)
Scala code for latest version: https://github.com/philipschwarz/fp-fold-scan-iterate-triad-a-first-example-scala
download for better quality - Learn about the sequence and traverse functions through the work of Runar Bjarnason and Paul Chiusano, authors of Functional Programming in Scala https://www.manning.com/books/functional-programming-in-scala, and Sam Halliday, author of "Functional Programming for Mortals with Scalaz" https://leanpub.com/fpmortals
An overview of the programming techniques available and some of the ongoing research in the Haskell community around concurrent and parallel programming.
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - with ...Philip Schwarz
(download for perfect quality) - See how recursive functions and structural induction relate to recursive datatypes.
Follow along as the fold abstraction is introduced and explained.
Watch as folding is used to simplify the definition of recursive functions over recursive datatypes
Part 1 - through the work of Richard Bird and Graham Hutton.
This version corrects the following issues:
slide 7, 11 fib(0) is 0,rather than 1
slide 23: was supposed to be followed by 2-3 slides recapitulating definitions of factorial and fibonacci with and without foldr, plus translation to scala
slide 36: concat not invoked in concat example
slides 48 and 49: unwanted 'm' in definition of sum
throughout: a couple of typographical errors
throughout: several aesthetic imperfections (wrong font, wrong font colour)
Quicksort - a whistle-stop tour of the algorithm in five languages and four p...Philip Schwarz
Quicksort - a whistle-stop tour of the algorithm in five languages and four paradigms.
Programming Paradigms: Functional, Logic, Imperative, Imperative Functional
Languages: Haskell, Scala, Java, Clojure, Prolog
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - Part 4Philip Schwarz
(download for flawless image quality) Can a left fold ever work over an infinite list? What about a right fold? Find out.
Learn about the other two functions used by functional programmers to implement mathematical induction: iterating and scanning.
Learn about the limitations of the accumulator technique and about tupling, a technique that is the dual of the accumulator trick.
Big picture of category theory in scala with deep dive into contravariant and...Piotr Paradziński
A big picture of category theory in Scala - starting from regular functors with additional structure (Apply, Applicative, Monad) to Comonads. Usually, we think about structures like Monoids in a monoidal category with particular tensor. In here I analyze just signatures of different abstractions.
Exploration of Contravariant functors as a way to model computation "backward" or abstract over input with the ability to prepend operation. Examples for predicates, sorting, show and function input (or any other function parameter except the last one).
Profunctors as abstraction unifying Functors and Contravariant functors to model both input and output. Example for Profunctor - function with one argument.
Relation to Bifunctors, Kan extensions, Adjunctions, and Free constructions.
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - Part 2Philip Schwarz
(download for perfect quality) See aggregation functions defined inductively and implemented using recursion.
Learn how in many cases, tail-recursion and the accumulator trick can be used to avoid stack-overflow errors.
Watch as general aggregation is implemented and see duality theorems capturing the relationship between left folds and right folds.
Through the work of Sergei Winitzki and Richard Bird.
Download for flawless quality (slides viewed online look a bit grainy and out of focus). A monad is an implementation of one of the minimal sets of monadic combinators, satisfying the laws of associativity and identity - see how compositional responsibilities are distributed in each combinator set
Slideshare hasn't imported my notes, so here's the link to the Google Presentation: https://goo.gl/Gl4Vhm
Haskell is a statically typed, non strict, pure functional programming language. It is often talked and blogged about, but rarely used commercially. This talk starts with a brief overview of the language, then explains how Haskell is evaluated and how it deals with non-determinism and side effects using only pure functions. The suitability of Haskell for real world data science is then discussed, along with some examples of its users, a small Haskell-powered visualization, and an overview of useful packages for data science. Finally, Accelerate is introduced, an embedded DSL for array computations on the GPU, and an ongoing attempt to use it as the basis for a deep learning package.
The Functional Programming Triad of Map, Filter and FoldPhilip Schwarz
This slide deck is my homage to SICP, the book which first introduced me to the Functional Programming triad of map, filter and fold.
It was during my Computer Science degree that a fellow student gave me a copy of the first edition, not long after the book came out.
I have not yet come across a better introduction to these three functions.
The upcoming slides are closely based on the second edition of the book, a free online copy of which can be found here:
https://mitpress.mit.edu/sites/default/files/sicp/full-text/book/book.html.
Download for original image quality.
Errata:
slide 20: the Clojure map function is in fact the Scheme one repeated - see code below for correction.
Scheme code: https://github.com/philipschwarz/the-fp-triad-of-map-filter-and-fold-scheme
Clojure code: https://github.com/philipschwarz/the-fp-triad-of-map-filter-and-fold-clojure
Presented online for C++ on Sea (2020-07-17)
Video at https://www.youtube.com/watch?v=Bai1DTcCHVE
Lambdas. All the cool kid languages have them. But does lambda mean what C++ and other languages, from Java to Python, mean by lambda? Where did lambdas come from? What were they originally for? What is their relationship to data abstraction?
In this session we will into the history, the syntax, the uses and abuses of lambdas and the way in which lambda constructs in C++ and other languages do (or do not) match the original construct introduced in lambda calculus.
N-Queens Combinatorial Problem - Polyglot FP for Fun and Profit – Haskell and...Philip Schwarz
See how the guard function has migrated from MonadPlus to Alternative and learn something about the latter.
Learn how to write a Scala program that draws an N-Queens solution board using the Doodle graphics library.
See how to write the equivalent Haskell program using the Gloss graphics library.
Learn how to use Monoid and Foldable to compose images both in Haskell and in Scala.
Link to part 1: https://www.slideshare.net/pjschwarz/nqueens-combinatorial-problem-polyglot-fp-for-fun-and-profit-haskell-and-scala-part-1
Errata:
On slide 22, the last line of the showQueens function should of course be show(solution).draw(frame) rather than show(solution).draw
On slide 43, it would be better if the definitions of the beside, above and on Monoids were also shown.
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - Part ...Philip Schwarz
(download for flawless image quality) Can a left fold ever work over an infinite list? What about a right fold? Find out.
Learn about the other two functions used by functional programmers to implement mathematical induction: iterating and scanning.
Learn about the limitations of the accumulator technique and about tupling, a technique that is the dual of the accumulator trick.
Function Applicative for Great Good of Palindrome Checker Function - Polyglot...Philip Schwarz
Embark on an informative and fun journey through everything you need to know to understand how the Applicative instance for functions makes for a terse palindrome checker function definition in point-free style.
download for better quality - Learn about the sequence and traverse functions
through the work of Runar Bjarnason and Paul Chiusano, authors of Functional Programming in Scala https://www.manning.com/books/functional-programming-in-scala, and others (Martin Odersky, Derek Wyatt, Adelbert Chang)
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - Part 5Philip Schwarz
(download for best quality slides) Gain a deeper understanding of why right folds over very large and infinite lists are sometimes possible in Haskell.
See how lazy evaluation and function strictness affect left and right folds in Haskell.
Learn when an ordinary left fold results in a space leak and how to avoid it using a strict left fold.
Errata:
slide 15: "as sharing is required" should be "as sharing is not required"
slide 43: 𝑠𝑓𝑜𝑙𝑑𝑙 (⊕) 𝑎 should be 𝑠𝑓𝑜𝑙𝑑𝑙 (⊕) 𝑒
The Functional Programming Triad of Folding, Scanning and Iteration - a first...Philip Schwarz
This slide deck can work both as an aide mémoire (memory jogger), or as a first (not completely trivial) example of using left folds, left scans and iteration, to implement mathematical induction.
Errata: on almost half of the slides there is some minor typo or imperfection or in some cases a minor error and in one case, an omission. See a later version for corrections and some improvements.
(for best quality images, either download or view here: https://philipschwarz.dev/fpilluminated/?page_id=455)
Scala code for latest version: https://github.com/philipschwarz/fp-fold-scan-iterate-triad-a-first-example-scala
download for better quality - Learn about the sequence and traverse functions through the work of Runar Bjarnason and Paul Chiusano, authors of Functional Programming in Scala https://www.manning.com/books/functional-programming-in-scala, and Sam Halliday, author of "Functional Programming for Mortals with Scalaz" https://leanpub.com/fpmortals
An overview of the programming techniques available and some of the ongoing research in the Haskell community around concurrent and parallel programming.
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - with ...Philip Schwarz
(download for perfect quality) - See how recursive functions and structural induction relate to recursive datatypes.
Follow along as the fold abstraction is introduced and explained.
Watch as folding is used to simplify the definition of recursive functions over recursive datatypes
Part 1 - through the work of Richard Bird and Graham Hutton.
This version corrects the following issues:
slide 7, 11 fib(0) is 0,rather than 1
slide 23: was supposed to be followed by 2-3 slides recapitulating definitions of factorial and fibonacci with and without foldr, plus translation to scala
slide 36: concat not invoked in concat example
slides 48 and 49: unwanted 'm' in definition of sum
throughout: a couple of typographical errors
throughout: several aesthetic imperfections (wrong font, wrong font colour)
Quicksort - a whistle-stop tour of the algorithm in five languages and four p...Philip Schwarz
Quicksort - a whistle-stop tour of the algorithm in five languages and four paradigms.
Programming Paradigms: Functional, Logic, Imperative, Imperative Functional
Languages: Haskell, Scala, Java, Clojure, Prolog
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - Part 4Philip Schwarz
(download for flawless image quality) Can a left fold ever work over an infinite list? What about a right fold? Find out.
Learn about the other two functions used by functional programmers to implement mathematical induction: iterating and scanning.
Learn about the limitations of the accumulator technique and about tupling, a technique that is the dual of the accumulator trick.
Big picture of category theory in scala with deep dive into contravariant and...Piotr Paradziński
A big picture of category theory in Scala - starting from regular functors with additional structure (Apply, Applicative, Monad) to Comonads. Usually, we think about structures like Monoids in a monoidal category with particular tensor. In here I analyze just signatures of different abstractions.
Exploration of Contravariant functors as a way to model computation "backward" or abstract over input with the ability to prepend operation. Examples for predicates, sorting, show and function input (or any other function parameter except the last one).
Profunctors as abstraction unifying Functors and Contravariant functors to model both input and output. Example for Profunctor - function with one argument.
Relation to Bifunctors, Kan extensions, Adjunctions, and Free constructions.
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - Part 2Philip Schwarz
(download for perfect quality) See aggregation functions defined inductively and implemented using recursion.
Learn how in many cases, tail-recursion and the accumulator trick can be used to avoid stack-overflow errors.
Watch as general aggregation is implemented and see duality theorems capturing the relationship between left folds and right folds.
Through the work of Sergei Winitzki and Richard Bird.
Download for flawless quality (slides viewed online look a bit grainy and out of focus). A monad is an implementation of one of the minimal sets of monadic combinators, satisfying the laws of associativity and identity - see how compositional responsibilities are distributed in each combinator set
Slideshare hasn't imported my notes, so here's the link to the Google Presentation: https://goo.gl/Gl4Vhm
Haskell is a statically typed, non strict, pure functional programming language. It is often talked and blogged about, but rarely used commercially. This talk starts with a brief overview of the language, then explains how Haskell is evaluated and how it deals with non-determinism and side effects using only pure functions. The suitability of Haskell for real world data science is then discussed, along with some examples of its users, a small Haskell-powered visualization, and an overview of useful packages for data science. Finally, Accelerate is introduced, an embedded DSL for array computations on the GPU, and an ongoing attempt to use it as the basis for a deep learning package.
Milano JS Meetup - Gabriele Petronella - Codemotion Milan 2016Codemotion
TypeError: “x" is not a function. Quale sviluppatore JavaScript non ha mai incontrato questo errore, magari su un sito in produzione? Non sarebbe invece fantastico intercettare questi errori durante lo sviluppo? In questo talk presenteremo Flow, uno static typechecker per javascript che ci può aiutare a scrivere codice più affidabile e sicuro. Il talk conterrà esempi concreti e demo. ATTENZIONE: può causare forti sbalzi di JavaScript fatigue!
eg
g
s
s
skfspgkspgkpegkpegkhpehkpweakpwdwacsadsc
eg
g
s
s
skfspgkspgkpegkpegkhpehkpweakpwdwacsadsc
skfspgkspgkpegkpegkhpehkpweakpwdwacsadscskfspgkspgkpegkpegkhpehkpweakpwdwacsadscskfspgkspgkpegkpegkhpehkpweakpwdwacsadscskfspgkspgkpegkpegkhpehkpweakpwdwacsadscskfspgkspgkpegkpegkhpehkpweakpwdwacsadscskfspgkspgkpegkpegkhpehkpweakpwdwacsadscskfspgkspgkpegkpegkhpehkpweakpwdwacsadscskfspgkspgkpegkpegkhpehkpweakpwdwacsadscskfspgkspgkpegkpegkhpehkpweakpwdwacsadscskfspgkspgkpegkpegkhpehkpweakpwdwacsadscskfspgkspgkpegkpegkhpehkpweakpwdwacsadsc
This presentation includes basic of PCOS their pathology and treatment and also Ayurveda correlation of PCOS and Ayurvedic line of treatment mentioned in classics.
Biological screening of herbal drugs: Introduction and Need for
Phyto-Pharmacological Screening, New Strategies for evaluating
Natural Products, In vitro evaluation techniques for Antioxidants, Antimicrobial and Anticancer drugs. In vivo evaluation techniques
for Anti-inflammatory, Antiulcer, Anticancer, Wound healing, Antidiabetic, Hepatoprotective, Cardio protective, Diuretics and
Antifertility, Toxicity studies as per OECD guidelines
it describes the bony anatomy including the femoral head , acetabulum, labrum . also discusses the capsule , ligaments . muscle that act on the hip joint and the range of motion are outlined. factors affecting hip joint stability and weight transmission through the joint are summarized.
Macroeconomics- Movie Location
This will be used as part of your Personal Professional Portfolio once graded.
Objective:
Prepare a presentation or a paper using research, basic comparative analysis, data organization and application of economic information. You will make an informed assessment of an economic climate outside of the United States to accomplish an entertainment industry objective.
A workshop hosted by the South African Journal of Science aimed at postgraduate students and early career researchers with little or no experience in writing and publishing journal articles.
A review of the growth of the Israel Genealogy Research Association Database Collection for the last 12 months. Our collection is now passed the 3 million mark and still growing. See which archives have contributed the most. See the different types of records we have, and which years have had records added. You can also see what we have for the future.
2. Types: what’s the big deal?
If you’ve been following along and trying out homework, you’re
probably intimately familiar with the facts that
Haskell is a statically typed language (it checks types before
we run), and
and it’s quite strict about this (it’s strongly typed).
3. What does “strongly typed” actually mean?
Definition
A strong type system guarantees that a program cannot contain
certain kinds of errors.
Strength and dynamism are more or less independent concepts in a
type system.
There are degrees of both strength and dynamism in type systems,
and often disagreement on both, so the likelihood of confusion
when talking to someone about types is high.
4. Familiar types
Haskell provides a number of types similar to those you’ll have seen
in other languages:
Int is a fixed-width signed integer type, usually the system’s
native word size (32 or 64 bits).
Char is a Unicode character.
Double is the double-precision floating point integer type,
usually 64 bits.
Integer is a signed integer type of unbounded size
(unbounded if you have infinite memory, that is).
Bool is the Boolean type, with possible values True and
False.
5. Expressions and types
Every expression (and hence every value) in Haskell has a type.
The expression ’a’ has the type Char. We can write this as
follows:
a : : Char
a = ’a ’
You can read the syntax “ :: ” as “has the type,” so:
The notation “a :: Char” is called a type signature, and
has the meaning “the expression named a has the type Char.”
6. Type inference
Have you noticed that most of the homework answers submitted so
far contain no type signatures?
This is because the Haskell compiler infers what the type of every
expression and definition is.
When you write a = ’a’, the compiler knows that the expression
’a’ can only have the type Char, so the variable a must have this
type too.
7. Type inference and concision
Unlike other statically typed languages you may be familiar with,
hand-written type annotations are optional1 in Haskell.
This is one of the big factors that lets us write amazingly concise
code:
We don’t need to tell the compiler what our types are when it
can figure this out for itself.
1
Well, they’re almost always optional.
8. Functions have types, too
f a c t : : I n t e g e r −> I n t e g e r
fact n | n < 0 = error ” negative ! ”
| o t h e r w i s e = go n
where go 0 = 1
go i = i ∗ go ( i −1)
A “−>” symbol in a signature denotes the type of a function.
On the left of the −> is the type of the argument.
The type on the right is that of the result.
Read the arrow and its neighbours as “this is a function from the
type Integer to the type Integer.”
9. Functions with multiple arguments
Suppose we have a function with more than one argument. Here’s
how we write its type signature.
c o n s : : Char −> S t r i n g −> S t r i n g
cons x xs = x : xs
Every item in the chain of arrows, except the last, is the type of
the argument at that position. The last item in the chain is the
type of the result.
What is the type of x above?
What is the type of xs?
What is the function’s result type?
10. Tuples
An easy way to create a collection of values is using a tuple.
b l a r g l e : : ( Char , I n t , Bool )
b l a r g l e = ( ’ a ’ , 42 , False )
The type signature (optional, as usual!) indicates what the type of
each element in the tuple is.
A tuple of two elements is usually called a pair.
Tuples with three elements are often called triples.
Larger tuples are 4-tuples, 5-tuples, and in general, n-tuples.
(But 4-tuples and larger are very rare in the wild.)
There is no one-tuple type (it would be redundant).
11. More about tuples
It should be obvious that the following two tuple types can express
different numbers of values:
(Bool, Bool)
(Bool, Bool, Char)
As far as the type checker is concerned, they are indeed completely
distinct types.
This suggests that the following expressions might have different
types:
(True, ’a’)
(’a’, True)
What do you think?
12. Functions on tuples
Pairs are so common in Haskell that there are built-in functions,
fst and snd for accessing the first and second elements of a pair:
fst (1 , ’a ’ )
== 1
>
snd ( 1 , ’ a ’ )
== ’ a ’
>
13. Pattern matching on tuples
For larger tuples, built-in accessor functions are not supplied, since
those types are used much less often.
You can define your own functions using pattern matching, and the
syntax is as you’d expect:
fst3 (a , b , c) = a
snd3 ( a , b , c ) = b
thd3 ( a , b , c ) = c
In practice, it’s more common to pattern-match than to define and
use accessor functions.
14. The list type
The ghci interpreter has a very useful command, :type, for
figuring out what the type of an expression or function is.
Here’s an example:
Prelude> :type lines
lines :: String -> [String]
As this suggests, the notation for “list of String” is [String].
And as the notation suggests, every element in a list must have the
same type.
15. Type synonyms
Recall that a Haskell string is just a list of characters.
The type of a list of characters is [Char], but we often see String
in type signatures.
There is no magic at work here: String is just a synonym for
[Char]. The compiler treats them identically.
In fact, we can introduce our own type synonyms at will:
type S t r e e t N u m b e r = I n t
type StreetName = S t r i n g
type A d d r e s s = ( StreetNumber , StreetName )
(Think typedef, C programmers!)
16. Functions over lists
Type synonyms are only mildly interesting; I mentioned them
mainly to bring the String ≡ [Char] equivalence to the fore.
Here’s why: notice that most functions on lists don’t seem to care
what types the elements of those lists have:
drop 3 [ 0 . . 1 0 ]
== [ 3 , 4 , 5 , 6 , 7 ]
>
drop 5 ” a b a c i n a t e ”
== ” n a t e ”
>
What’s going on here?
17. Polymorphism
Consider the following function definition:
take n | n <= 0 = []
take [] = []
take n ( x : x s ) = x : take ( n−1) x s
The take function never inspects the elements of the list. It
neither knows nor cares what they are.
We call functions like this polymorphic over the list’s elements.
18. Polymorphic type signatures
How do we write the type signature for take?
take : : I n t −> [ a ] −> [ a ]
That name “a” above, inside the list brackets, is a type variable.
A type variable lets us say “I don’t know or care what concrete
type2 will be used in this position, so here’s a placeholder.”
2
“Concrete type”? Think Int, Char, etc.
19. Multiple type variables
We are not limited to a single type variable in a type signature.
triple : : a −> b −> c −> ( a , b , c )
triple x y z = (x , y , z)
This means:
The first argument could have any type a.
The second argument could have any type b. This type could
be the same as, or different to, a.
And the third? You get the idea.
20. Functions as parameters
Suppose we want to inspect every element of a list, and drop those
that do not suit some criterion.
How should we write the type signature of a function that checks
an element of the list?
3
Fancy language for “function returning a Bool.”
21. Functions as parameters
Suppose we want to inspect every element of a list, and drop those
that do not suit some criterion.
How should we write the type signature of a function that checks
an element of the list?
We’re checking some element of type a, and to indicate whether it
passes or fails, we should return a Bool. So our type is:
3
Fancy language for “function returning a Bool.”
22. Functions as parameters
Suppose we want to inspect every element of a list, and drop those
that do not suit some criterion.
How should we write the type signature of a function that checks
an element of the list?
We’re checking some element of type a, and to indicate whether it
passes or fails, we should return a Bool. So our type is:
a −> Bool
How would we pass such a predicate3 as an argument to another
function that will perform the filtering?
3
Fancy language for “function returning a Bool.”
23. The definition of filter
Welcome to the world of higher-order programming!
filter : : ( a −> Bool ) −> [ a ] −> [ a ]
filter [] = []
f i l t e r p ( x : xs )
| p x = x : f i l t e r p xs
| otherwise = f i l t e r p xs
Higher-order programming occurs when we pass around functions
as arguments to other functions. Simple, but amazingly powerful!
24. Turning a polymorphic type into another type
Suppose we want to use the take function on a list of Int values.
How do we figure out what the type of the function will be when
we use it in that context?
Take the type variable a, and substitute our desired type Int
everywhere. So
take : : I n t −> [ a ] −> [ a ]
when applied to a list of Int becomes
take : : I n t −> [ I n t ] −> [ I n t ]
25. Polymorphism and . . . polymorphism
We can do the same rewrite-the-types trick when we want to see
what the type of a polymorphic function would be when used with
another polymorphic type.
What do I mean by this? Consider take for lists-of-lists-of-lists.
Let’s write a polymorphic list as [b], so a polymorphic list of lists
is [[ b ]] .
We’ll thus replace a with [[ b ]] to get this type:
take : : I n t −> [ [ [ b ] ] ] −> [ [ [ b ] ] ]
26. Polymorphism vs type inference (I)
Here’s a definition someone wrote for homework, but they got
confused along the way, since we hadn’t covered types yet:
nth n [] = []
nth n ( x : xs )
| n < 0 = []
| n == 0 = x
| otherwise = n t h ( n−1) x s
Try reasoning about this code.
What was the intended type for the nth function?
What is the type of this version, and why?
27. Polymorphism vs type inference (II)
The original type for nth should have been this:
n t h : : I n t −> [ a ] −> a
But because we didn’t supply a type, and the code wasn’t quite
doing the right thing, the compiler inferred a surprising type:
n t h : : I n t −> [ [ a ] ] −> [ a ]
Notice that its inference was both correct and consistent with what
the code was really doing (but not with what the author initially
thought the code was doing).
28. How does this work in practice?
In real-world code, when you omit type signatures, you place no
constraints on the compiler’s type inference engine.
Therefore, a single type error can lead the inference engine off
in wild logical directions.
If your code passes the typechecker’s scrutiny, you’re not out
of the woods: it may not behave as you expect, since its types
may be different than you thought.
If your code fails to typecheck, the errors are likely to be
confusing, since you gave the compiler no hints about what
you really meant.
29. Polymorphism and type annotations
What does this experience suggest?
Explicit type signatures can actually be useful!
A signature indicates what type we think the code has.
Type inference occurs even when we supply an explicit type.
If our code’s type signature is inconsistent with the type the
compiler infers, we will get a useful compilation error.
30. Real world use of type annotations
Practical coding tips:
Add type signatures to almost all of your top-level definitions.
They’re good for more than the compiler—they’re invaluable
to readers, as documentation of your code’s behaviour!
Let the compiler infer types for almost all local definitions,
i.e. those in let and where clauses.
31. Inferring behaviour from types
In many cases, we can guess what a function probably does, simply
by examining its type (and sometimes its name):
z i p : : [ a ] −> [ b ] −> [ ( a , b ) ]
32. Inferring behaviour from types
In many cases, we can guess what a function probably does, simply
by examining its type (and sometimes its name):
z i p : : [ a ] −> [ b ] −> [ ( a , b ) ]
r e p l i c a t e : : I n t −> a −> [ a ]
33. Inferring behaviour from types
In many cases, we can guess what a function probably does, simply
by examining its type (and sometimes its name):
z i p : : [ a ] −> [ b ] −> [ ( a , b ) ]
r e p l i c a t e : : I n t −> a −> [ a ]
s p l i t A t : : I n t −> [ a ] −> ( [ a ] , [ a ] )
34. What polymorphism tells us
When we see a polymorphic function like this:
myLength : : [ a ] −> I n t
We can make a surprisingly strong statement about its behaviour:
Its behaviour cannot be influenced by either the type or the
values of the elements in the list it receives.
Why is this?
35. What polymorphism tells us
When we see a polymorphic function like this:
myLength : : [ a ] −> I n t
We can make a surprisingly strong statement about its behaviour:
Its behaviour cannot be influenced by either the type or the
values of the elements in the list it receives.
Why is this?
Polymorphism is a way of saying “I cannot know anything
about this type, or inspect or manipulate its values.”
36. What polymorphism tells us
When we see a polymorphic function like this:
myLength : : [ a ] −> I n t
We can make a surprisingly strong statement about its behaviour:
Its behaviour cannot be influenced by either the type or the
values of the elements in the list it receives.
Why is this?
Polymorphism is a way of saying “I cannot know anything
about this type, or inspect or manipulate its values.”
For example, there’s no way to say “myLength should return a
different result for [Char] than for [ Int ].” That’s pretty profound!
37. Homework (I)
Write a function that drops every nth element from a list. It
should return the removed elements in one element of a pair, and
the remainder of the list in another. Provide a type signature for
your function.
every 3 ” abcdefghi ”
== ( ” c f i ” , ” abdegh ” )
>
Write a function that returns the kth least element of a list,
starting from zero as “the least element”.
kminimum 0 [ 3 , 2 , 1 ]
== 1
>
kminimum 2 ” q w e r t y ”
== ’ r ’
>
38. Homework (II)
From inspection of the type and operation of the built-in zipWith
function, write your own implementation.
myZipWith min [ 1 , 2 , 3 ] [ 2 , 2 , 2 , 2 , 2 ]
== [ 1 , 2 , 2 ]
>
Write a function that capitalizes the first letter of every word in a
string. It must preserve whitespace and punctuation.
u c f i r s t ” foo b a r ! ! bAZ”
== ” Foo
> Bar ! ! BAZ”