Examples-0.1.0: Haskell code examples
Copyright© Frank Jung 2023
LicenseGPL-3.0-only
Safe HaskellSafe-Inferred
LanguageHaskell2010

RankNTypes

Description

Based on Haskell Design Patterns by Ryan Lemmer, Chapter 5, Abstracting function types: RankNTypes, page 88..

The applyToFive example is from Thinking In Types by Sandy Maguire.

The rank of a function is the "depth" of its polymorphism. Most of typical polymorphic functions in Haskell are of rank 1. e.g.:

const :: a -> b -> a
head :: [a] -> a

Using -XRankNTypes extension makes polymorphism first-class. This allows us to introduce polymorphism anywhere a type is allowed. The comprimise is that type inference becomes harder.

See also PolyList for other examples of RankNTypes.

Synopsis

Types

data ShowBox Source #

This is an existential type that allows you to construct heterogenous lists of underlying different types (wrapped by the ShowBox type).

For example:

heteroList :: [ShowBox]
heteroList = [SB (), SB 5, SB "hello"]

See also PolyList for an example of a polymorphic list.

Constructors

forall s.Show s => SB s 

Instances

Instances details
Show ShowBox Source #

Show instance for ShowBox.

Instance details

Defined in RankNTypes

data HasShow where Source #

HasShow type example.

See Thinking with Types, Section 7.1 Existential Types and Eliminators

Constructors

HasShow :: Show a => a -> HasShow 

Instances

Instances details
Show HasShow Source #

Show instance for HasShow.

Same as:

instance Show HasShow where
  show (HasShow a) = show a
Instance details

Defined in RankNTypes

Functions

applyToFive :: (forall a. a -> a) -> Int Source #

Due to Haskell's implicit quantification of type variables, the forall a. part needs to be inside the parentheses. This requires the -XRankNTypes extension.

This function is of rank 2 as it receives a function of rank 1 as an argument and runs it on the integer value 5.

elimHasShow :: (forall a. Show a => a -> r) -> HasShow -> r Source #

Eliminator for HasShow.

Reads value of HasShow type.

processTuple :: (Integral a1, Integral a2) => (forall a. Integral a => a -> Bool) -> (a1, a2) -> (Bool, Bool) Source #

Process tuple with polymorphic function for Integral types.