Original article
introhaskell

Glossary

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
type variable
    Example:
        Given the type:
            a -> a -> a
        'a' is a type variable.

    ewwlinks +/"Type Variables" "https://cs.lmu.edu/~ray/notes/introhaskell/"

    We know [Char] and [Float] are two
    different types. So how do we speak about,
    or write functions that work on, lists of
    ANY type? Or tuples of any size, or any
    component type?

    Answer: type variables.

    Type variables come in lowercase.

Unit type

ML descendants
OCaml , Standard ML, and F#
lang d
Haskell and Rust the unit type is called () and its only value is also (), reflecting the 0-tuple interpretation.
ML descendants the type is called unit but the value is written as ().
Scala the unit type is called Unit and its only value is written as ().
Common Lisp the type named NULL is a unit type which has one value, namely the symbol NIL. This should not be confused with the NIL type, which is the bottom type.
Python there is a type called NoneType which allows the single value of None.
Swift the unit type is called Void or () and its only value is also (), reflecting the 0-tuple interpretation.
Go the unit type is written struct{} and its value is struct{}{}.
PHP the unit type is called null, which only value is NULL itself.
JavaScript both null and undefined are built-in unit types.
Kotlin Unit is a singleton with only one value: the Unit object.
Ruby nil is the only instance of the NilClass class.
C++ the std::monostate unit type was added in C++17.

https://stackoverflow.com/questions/16892570/what-is-in-haskell-exactly

1
2
-- data () = ()
:t ()
() :: ()

Type variables

1
2
3
4
:t \(x, y) -> y
:t \(x, y) -> head y
:t \x -> \y -> \z -> (x, y)
:t \x -> \y -> \z -> (x, \w -> not y)
\(x, y) -> y :: (a, b) -> b
\(x, y) -> head y :: (a1, [a2]) -> a2
\x -> \y -> \z -> (x, y) :: a -> b -> p -> (a, b)
\x -> \y -> \z -> (x, \w -> not y)
  :: a -> Bool -> p1 -> (a, p2 -> Bool)

An overview of the Haskell Type Classes

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
Bounded
Ord -> Eq
Real -> Ord
Integral -> Real
Integral -> Enum
RealFrac -> Real
RealFrac -> Fractional
RealFloat -> RealFrac
RealFloat -> Floating
Floating -> Fractional
Fractional -> Num
Show
Foldable
Traversable -> Foldable
Traversable -> Functor
Applicative -> Functor
Monad -> Applicative
Monoid -> Semigroup
Read

If it’s Ord, then it is also Eq. If it’s Real, then it is Ord. If it is Integral, then it is Real. If it is Traversable, then it is Foldable. If it is Monad, then it is Applicative. If it is Monoid, then it is Semigroup.

1
:i Semigroup
class Semigroup a where
  (<>) :: a -> a -> a
  GHC.Base.sconcat :: GHC.Base.NonEmpty a -> a
  GHC.Base.stimes :: Integral b => b -> a -> a
  {-# MINIMAL (<>) #-}
  	-- Defined in ‘GHC.Base’
instance Semigroup (Either a b) -- Defined in ‘Data.Either’
instance Semigroup [a] -- Defined in ‘GHC.Base’
instance Semigroup Ordering -- Defined in ‘GHC.Base’
instance Semigroup a => Semigroup (Maybe a)
  -- Defined in ‘GHC.Base’
instance Semigroup a => Semigroup (IO a) -- Defined in ‘GHC.Base’
instance Semigroup b => Semigroup (a -> b) -- Defined in ‘GHC.Base’
instance (Semigroup a, Semigroup b, Semigroup c, Semigroup d,
          Semigroup e) =>
         Semigroup (a, b, c, d, e)
  -- Defined in ‘GHC.Base’
instance (Semigroup a, Semigroup b, Semigroup c, Semigroup d) =>
         Semigroup (a, b, c, d)
  -- Defined in ‘GHC.Base’
instance (Semigroup a, Semigroup b, Semigroup c) =>
         Semigroup (a, b, c)
  -- Defined in ‘GHC.Base’
instance (Semigroup a, Semigroup b) => Semigroup (a, b)
  -- Defined in ‘GHC.Base’
instance Semigroup () -- Defined in ‘GHC.Base’
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
instance of a class
    An instance of a class is an individual
    object which belongs to that class.

    In Haskell, the class system is (roughly
    speaking) a way to group similar types.

    (This is the reason we call them "type
    classes").

    An instance of a class is an individual
    type which belongs to that class.
Type Typeclasses
Bool Eq, Ord, Show, Read, Enum, Bounded
Char Eq, Ord, Show, Read, Enum, Bounded
Int Eq, Ord, Show, Read, Enum, Bounded, Num, Real, Integral
Integer Eq, Ord, Show, Read, Enum, Num, Real, Integral
Float Eq, Ord, Show, Read, Enum, Num, Real, Fractional, RealFrac, Floating, RealFloat
Double Eq, Ord, Show, Read, Enum, Num, Real, Fractional, RealFrac, Floating, RealFloat
Word Eq, Ord, Show, Read, Enum, Bounded, Num, Real, Integral
Ordering Eq, Ord, Show, Read, Enum, Bounded, Semigroup, Monoid
() Eq, Ord, Show, Read, Enum, Bounded, Semigroup, Monoid
Maybe a Eq, Ord, Show, Read, Semigroup, Monoid, Functor, Applicative, Monad, Foldable, Traversable
[a] Eq, Ord, Show, Read, Semigroup, Monoid, Functor, Applicative, Monad, Foldable, Traversable
(a,b) Eq, Ord, Show, Read, Bounded, Semigroup, Monoid, Functor, Applicative, Monad, Foldable, Traversable
a->b Semigroup, Monoid, Functor, Applicative, Monad
IO Semigroup, Monoid, Functor, Applicative, Monad
IOError Eq, Show

You can glean a lot of interesting information based on what typeclasses a type does not implement.

  • Functions and IO objects can NOT be tested for equality, nor can they be compared, printed, or read. (Function equality is undecidable in general, did you know?)

    a->b Semigroup, Monoid, Functor, Applicative, Monad
    IO Semigroup, Monoid, Functor, Applicative, Monad
  • IOErrors can be tested for equality and printed, but not compared or read.

    IOError Eq, Show
  • Bools, Chars, and Ints are bounded (have a minimum value and maxium value), but Integers, Floats, and Doubles, do not.

  • It makes sense to fold and traverse lists and tuples, but not much else (though you can create new types and add them to typeclasses, as we’ll soon see.)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
for l in "Eq"           \
         "Ord"          \
         "Show"         \
         "Read"         \
         "Enum"         \
         "Bounded"      \
         "Num"          \
         "Real"         \
         "Integral"     \
         "Fractional"   \
         "RealFrac"     \
         "Floating"     \
         "RealFloat"    \
         "Semigroup"    \
         "Monoid"       \
         "Functor"      \
         "Applicative"  \
         "Monad"        \
         "Foldable"     \
         "Traversable"; do
    ( set -x; ahoogle --info "$l" | head -n 10; ) 2>&1
done
+ ahoogle --info Eq
+ head -n 10
using alternative /home/shane/.local/bin/hoogle
EQ :: Ordering
base Prelude

+ ahoogle --info Ord
+ head -n 10
using alternative /home/shane/.local/bin/hoogle
class Eq a => Ord a
base Prelude
The Ord class is used for totally ordered datatypes.

Instances of Ord can be derived for any user-defined datatype
whose constituent types are in Ord. The declared order of the
constructors in the data declaration determines the ordering in
derived Ord instances. The Ordering datatype allows a
single comparison to determine the precise ordering of two objects.

+ ahoogle --info Show
+ head -n 10
using alternative /home/shane/.local/bin/hoogle
class Show a
base Prelude
Conversion of values to readable Strings.

Derived instances of Show have the following properties, which
are compatible with derived instances of Read:


The result of show is a syntactically correct Haskell
expression containing only constants, given the fixity declarations in
+ ahoogle --info Read
+ head -n 10
using alternative /home/shane/.local/bin/hoogle
class Read a
base Prelude
Parsing of Strings, producing values.

Derived instances of Read make the following assumptions, which
derived instances of Show obey:


If the constructor is defined to be an infix operator, then the
derived Read instance will parse only infix applications of the
+ ahoogle --info Enum
+ head -n 10
using alternative /home/shane/.local/bin/hoogle
class Enum a
base Prelude
Class Enum defines operations on sequentially ordered types.

The enumFrom... methods are used in Haskell's translation of
arithmetic sequences.

Instances of Enum may be derived for any enumeration type
(types whose constructors have no fields). The nullary constructors
are assumed to be numbered left-to-right by fromEnum from
+ ahoogle --info Bounded
+ head -n 10
using alternative /home/shane/.local/bin/hoogle
class Bounded a
base Prelude
The Bounded class is used to name the upper and lower limits of
a type. Ord is not a superclass of Bounded since types
that are not totally ordered may also have upper and lower bounds.

The Bounded class may be derived for any enumeration type;
minBound is the first constructor listed in the data
declaration and maxBound is the last. Bounded may also
be derived for single-constructor datatypes whose constituent types
+ ahoogle --info Num
+ head -n 10
using alternative /home/shane/.local/bin/hoogle
class Num a
base Prelude
Basic numeric class.

The Haskell Report defines no laws for Num. However, '(+)' and
'(*)' are customarily expected to define a ring and have the following
properties:


Associativity of (+) (x + y) + z = x +
+ ahoogle --info Real
+ head -n 10
using alternative /home/shane/.local/bin/hoogle
class (Num a, Ord a) => Real a
base Prelude

+ ahoogle --info Integral
+ head -n 10
using alternative /home/shane/.local/bin/hoogle
class (Real a, Enum a) => Integral a
base Prelude
Integral numbers, supporting integer division.

The Haskell Report defines no laws for Integral. However,
Integral instances are customarily expected to define a
Euclidean domain and have the following properties for the 'div'/'mod'
and 'quot'/'rem' pairs, given suitable Euclidean functions f
and g:

+ ahoogle --info Fractional
+ head -n 10
using alternative /home/shane/.local/bin/hoogle
class (Num a) => Fractional a
base Prelude
Fractional numbers, supporting real division.

The Haskell Report defines no laws for Fractional. However,
'(+)' and '(*)' are customarily expected to define a division ring and
have the following properties:


recip gives the multiplicative inverse x
+ ahoogle --info RealFrac
+ head -n 10
using alternative /home/shane/.local/bin/hoogle
class (Real a, Fractional a) => RealFrac a
base Prelude
Extracting components of fractions.

+ ahoogle --info Floating
+ head -n 10
using alternative /home/shane/.local/bin/hoogle
class (Fractional a) => Floating a
base Prelude
Trigonometric and hyperbolic functions and related functions.

The Haskell Report defines no laws for Floating. However,
'(+)', '(*)' and exp are customarily expected to define an
exponential field and have the following properties:


exp (a + b) = @exp a * exp b
+ ahoogle --info RealFloat
+ head -n 10
using alternative /home/shane/.local/bin/hoogle
class (RealFrac a, Floating a) => RealFloat a
base Prelude
Efficient, machine-independent access to the components of a
floating-point number.

+ ahoogle --info Semigroup
+ head -n 10
using alternative /home/shane/.local/bin/hoogle
class Semigroup a
base Prelude
The class of semigroups (types with an associative binary operation).

Instances should satisfy the associativity law:


x <> (y <> z) = (x <>
y) <> z

+ ahoogle --info Monoid
+ head -n 10
using alternative /home/shane/.local/bin/hoogle
class Semigroup a => Monoid a
base Prelude
The class of monoids (types with an associative binary operation that
has an identity). Instances should satisfy the following laws:


x <> mempty = x
mempty <> x = x
x <> (y <> z) = (x <>
y) <> z (Semigroup law)
+ ahoogle --info Functor
+ head -n 10
using alternative /home/shane/.local/bin/hoogle
class Functor f
base Prelude
The Functor class is used for types that can be mapped over.
Instances of Functor should satisfy the following laws:


fmap id  ==  id
fmap (f . g)  ==  fmap f . fmap g


+ ahoogle --info Applicative
+ head -n 10
using alternative /home/shane/.local/bin/hoogle
class Functor f => Applicative f
base Prelude
A functor with application, providing operations to


embed pure expressions (pure), and
sequence computations and combine their results (<*>
and liftA2).


+ ahoogle --info Monad
+ head -n 10
using alternative /home/shane/.local/bin/hoogle
class Applicative m => Monad m
base Prelude
The Monad class defines the basic operations over a
monad, a concept from a branch of mathematics known as
category theory. From the perspective of a Haskell programmer,
however, it is best to think of a monad as an abstract datatype
of actions. Haskell's do expressions provide a convenient
syntax for writing monadic expressions.

Instances of Monad should satisfy the following laws:
+ ahoogle --info Foldable
+ head -n 10
using alternative /home/shane/.local/bin/hoogle
class Foldable t
base Prelude
Data structures that can be folded.

For example, given a data type


data Tree a = Empty | Leaf a | Node (Tree a) a (Tree a)


+ ahoogle --info Traversable
+ head -n 10
using alternative /home/shane/.local/bin/hoogle
class (Functor t, Foldable t) => Traversable t
base Prelude
Functors representing data structures that can be traversed from left
to right.

A definition of traverse must satisfy the following laws:


naturality t . traverse f =
traverse (t . f) for every applicative transformation