-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/
-- | Informative annotations which don't change equality
--
-- This package introduces a type Ann a to annotate data types
-- with information which doesn't influence the behaviour of your
-- program. These annotations can then be displayed, as assistance to the
-- user.
@package ann
@version 1.0.0
-- | This module introduces a type Ann a to annotate data
-- types with information which doesn't influence the behaviour of your
-- program. These annotations can then be displayed, as assistance to the
-- user.
--
--
Examples
--
-- Variable names
--
-- You are writing a programing language, and representing binder as
-- de Bruijn indices. Nevertheless you want to keep the variable
-- names written by the user, to be able to interact with them on these
-- terms (e.g. in error messages). With Ann it would look
-- like this:
--
--
-- data Term
-- = Var Int
-- | App Term Term
-- | Lam (Ann String) Term
-- deriving (Eq)
--
--
-- Thanks to the Ann type, you can derive the intended equality:
-- the user's choice of variable doesn't change the term (this is called
-- α-equivalence).
--
-- Validation monad
--
-- The Validation applicative can be made into a monad.
-- Specifically Validation (Ann e) is a monad, as I explained
-- in a Twitter thread.
--
-- Theoretical considerations
--
-- Ann a is the quotient of a by the
-- total relation.
--
-- What's so special about the total relation?
--
-- There are only two relations which can be defined generically on all
-- sets: the empty relation and the total relation (this can be proved by
-- parametricity). The quotient by the empty relation is Identity.
-- So the only interesting generic quotient is Ann.
--
-- Strictly speaking, sets are also equipped with the equality relation
-- (and you can derive the disequality relation from it). But quotienting
-- by the equality relation is the same as quotienting by the empty
-- relation; and quotienting by the disequality relation is the same as
-- quotienting by the total relation.
--
-- Other quotients can be defined on individual sets using abstract
-- types.
--
-- A consequence of defining Ann generically on types is that it
-- turns Ann into a functor. The functor structure is not
-- particularly intersting. But Ann is also a monad.
--
--
-- (>>=) :: Ann a -> (a -> Ann b) -> Ann b
--
--
-- That is: you are allowed to “look inside” an Ann a
-- only if you you are producing an Ann b to begin with.
-- The program is not allowed to depend on the choice of representative,
-- yet (>>=) gives the representative for us to play with.
-- But it's alright: it's only going to affect the representative in
-- Ann b, on which the program cannot depend either.
--
-- Something that I'd like to point out is that you really need the
-- a in the (a -> Ann b) argument. The reason is
-- that Ann is not isomorphic to Const (): Ann
-- b is isomorphic to () if and only if b is
-- inhabited. Ann Void, on the other hand, is isomorphic
-- to Void. There is a sense in which all that's interesting
-- about Ann stems from this fact.
--
-- The monadic (>>=) is more or less explicitly in use in
-- many dependently typed theories (it is pretty hidden, but there in the
-- typing rules for Prop in Coq). For further reading see
-- [Propositions as [Types]
-- ](https:/ieeexplore.ieee.orgabstractdocument8133549) and
-- Implicit and noncomputational arguments using monads.
--
-- Algebras of Ann
--
-- I haven't talked about return yet
--
--
-- 'return' :: a -> Ann a
--
--
-- It is the canonical projection to Ann a. It's exported
-- as project as well.
--
-- This is really not relevant for the design or usage of the library,
-- but it's a natural question to ask: the algebras of Ann (as a
-- monad) are sets with at most 1 element. Let α :: Ann A ->
-- A be such an algebra. Since Ann A has at most one
-- element, α is constant. But, by the laws of algebra, we also
-- have α ∘ return = id, in particular id :: A -> A
-- is constant, therefore A has at most 1 element.
--
-- Conversely, if A has at most 1 element, then Ann
-- A is isomorphic to A, in particular A is an
-- algebra.
--
-- Is there an equivalent for subsets?
--
-- Frankly at this point, this is just me rambling about stuff that I
-- find interesting. I'll get back to relevant stuff in the next section.
--
-- Subsets are the dual of quotients (in category-theory terms, quotients
-- are co-equalisers while subsets are equalisers). However, the category
-- of set is not its own dual, so that there is an interesting phenomenon
-- for one doesn't imply that there is to the other.
--
-- In the case at hand, there are two generically definable predicates as
-- well. The empty predicate and the full predicate. They both define
-- boring subset (the empty set, and the identity functor, respectively).
-- So really, Ann is the only interesting case of the bunch.
--
-- Extracting and IO
--
-- The type of extract is
--
--
-- extract :: Ann a -> IO a
--
--
-- There can't be a function `Ann a -> a` as this violates the
-- quotient condition (concretely that the program isn't affected by the
-- choice of representative of 'Ann a'). Well, more precisely, if such a
-- function exists, it must be constant. The existence of such a function
-- is a form of choice (of the axiom of choice fame). It's a very
-- powerful principle, and probably not desirable. I should give a
-- citation here, but no source comes to mind at the moment. You will
-- have to trust me that in dependently typed language, this is
-- equivalent to choice (in particular it implies the excluded middle, if
-- 'Ann a' is used to represent propositions).
--
-- Ok, back to IO. We don't want the choice of representative to
-- affect the semantics of the program, but we still want to print it
-- out, so that the user get their debug message or whatnot. IO is
-- our solution because it is allowed to do non-deterministic actions in
-- IO (and printing usually involves IO, so it doesn't cost
-- much). So the semantics of extract is “choose an arbitrary
-- representative“; this representative need not be the same each time.
-- Of course we don't actually want an arbitrary representative to be
-- printed out: we want the one we put in. It would be difficult to give
-- a different implementation anyway. So we know, that, really, we will
-- get the representative we put in. But, strictly speaking, this is not,
-- strictly speaking, part of the semantics of the function (at least I
-- don't know how to make it so; it would be really nice to be able to).
--
-- This same trick is used in Tackling the awkward squad.
--
-- Quotients and equivalence relations
--
-- This is even less related to the core of the package than the rest of
-- this section, but while we are on the subject of quotients, I'd like
-- to address a point.
--
-- You may have noticed that I repeatedly spoke of quotienting by “a
-- relation” throughout this document. If you are like me, though, you
-- may have been taught that a set is quotiented by an equivalence
-- relation. It's because equivalence classes form an equivalence
-- relation. But it isn't essential to the definition of quotient.
--
-- A quotient <math> of a set <math> is defined by its
-- universal property. Namely that a function <math>` is the same
-- thing as a function <math> such that <math>. That
-- <math> is an equivalence relation doesn't play a role in this
-- definition. It turns out, however, that quotienting by <math> or
-- by its reflexive, symmetric and transitive closure yields the same
-- set.
module Data.Ann
-- | Ann a is the type of annotations of type a.
-- It is such, in particular that, for all x :: Ann a and
-- y :: Ann a, x == y.
data Ann a
-- | Create an annotation. See also extract.
project :: a -> Ann a
-- | Extract the underlying value of an annotation. We have that
-- extract . project = return. But do keep in mind that valid
-- refactoring can change the underlying value of the annotation. As
-- such, extract is a non-deterministic operation.
extract :: Ann a -> IO a
-- | When all else fails – if neither the Monad instance nor
-- extract fit your need – you can use unsafeExtract to
-- observe the underlying value of an annotation.
--
-- ⚠️ You must prove that you are not using 'unsafeExtract
-- ann in a way where changing the value of ann would
-- change the behaviour of your program.
unsafeExtract :: Ann a -> a
instance GHC.Show.Show a => GHC.Show.Show (Data.Ann.Ann a)
instance GHC.Read.Read a => GHC.Read.Read (Data.Ann.Ann a)
instance GHC.Base.Monoid a => GHC.Base.Monoid (Data.Ann.Ann a)
instance GHC.Base.Semigroup a => GHC.Base.Semigroup (Data.Ann.Ann a)
instance GHC.Base.Functor Data.Ann.Ann
instance GHC.Base.Applicative Data.Ann.Ann
instance GHC.Base.Monad Data.Ann.Ann
instance GHC.Classes.Eq (Data.Ann.Ann a)
instance GHC.Classes.Ord (Data.Ann.Ann a)