In the next chapter (chapter 9) we go on to dene a new version of the Quantum IO Monad in Agda using some of the techniques and constructs we have introduced above. It is useful to note that the notion of Monoids and Monads translate very nicely from their Haskell counterparts. This section shall just give a quick overview of Monads and Monoids in Agda, and shows how despite Agda not having type- classes we are easily able to use Agda's record type to dene them. Agda's record data-type can be thought of a generalisation of the Σ type, as the type of each eld can depend on the types of the previous elds in the record.
record Monoid : Set1 where
eld
carrier : Set
_≈_ : carrier → carrier → Set
_•_ : carrier → carrier → carrier
ǫ : carrier
isMonoid : IsMonoid _≈_ _•_ ǫ
A Monoid in Agda is a record that contains the ve elds given in its denition above. The carrier eld denes the underlying Set or data type over which we would like to dene our monoid. The _≈_ eld must dene an equivalence relation over the carrier set. The _•_ eld denes the binary operation of the monoid, which was denoted by mappend in the Haskell implementation, and the ǫ eld denes the identity element for the given binary operation which corresponds to the mempty element of the Haskell implementation. The last eld, isMonoid, corresponds to a
data-type that encodes the monoid laws using the given equivalence relationship. We can look at this in more detail by giving its denition as another record type.
record IsMonoid {A} (_≈_ : A → A → Set)
(_•_ : A → A → A) (ǫ : A) : Set where eld re : ∀ {x} → x ≈ x sym : ∀ {i j} → i ≈ j → j ≈ i trans : ∀ {i j k} → i ≈ j → j ≈ k → i ≈ k assoc : ∀ x y z → ((x • y) • z) ≈ (x • (y • z)) •-pres-≈ : ∀ {x y u v} → x ≈ y → u ≈ v → x • u ≈ y • v identity : (∀ {x} → (ǫ • x) ≈ x) × (∀ {x} → (x • ǫ) ≈ x)
The rst three elds prove that the given relation is indeed an equivalence relation. re is a proof that ≈ is reexive, sym is a proof that ≈ is symmetric, and trans is a proof that ≈ is transitive. The next two elds prove that the carrier set, along with the • operation form a semi-group. That is, that • is associative, and that • preserves the given equivalence relationship. The nal eld proves that the given element ǫ is indeed a right- and left-identity to the given • operation. In fact, Agda's standard library splits the laws into data-types that prove these sub structures (The IsEquivalence and IsSemigroup data-types respectively). The following section (section 8.4) goes on to look at a reimplementation of our toy language of reversible circuits written in Agda, which uses two instances of a monoid as we have dened. We shall now look at how we can also dene monads in Agda in a similar way as we have dened monoids above.
The standard library of Agda currently only contains an implementation of what it calls raw monads. Raw monads are an implementation of monads that don't contain proofs of the monad laws. It would be possible to dene a type of monad in Agda that encodes the proofs of the monad laws, although in this thesis I shall just be using the raw monads as dened in the standard library. The raw
monad actually makes use of an underlying indexed raw monad, that is indexed by the unit type, which carries no extra information. It useful to give the denition of a raw indexed monad here.
A record type is once again used for the denition of a raw indexed monad. record RawIMonad {I : Set} (M : I → I → Set → Set) : Set1 where
eld
return : ∀ {i A} → A → M i i A
_=_ : ∀ {i j k A B} → M i j A → (A → M j k B) → M i k B The return and _=_ operations are exactly indexed versions of the operators we used in Haskell. Thinking of monads in terms of their abstract behaviour, the indices can be thought of as an index at the beginning of the monadic behaviour, and the index at the end of the monadic behaviour. As such, the return operator doesn't eect the index, and the _=_ operator can only bind together two monadic constructs whose indices match appropriately. We shall actually be using this form of indexed monad later in the denition of QIO, whereby the indices will relate to the set of qubits in a quantum computation. For now, we shall look at the specic instance of a raw indexed monad that relates to a raw monad as we have been using in Haskell. As mentioned previously, this form of raw monad is simply a raw indexed monad whose indices are the unit type (⊤).
RawMonad : (Set → Set) → Set1
RawMonad M = RawIMonad {⊤} (\_ → M)
To nish o this section on monads, I shall give the implementation of a simple Maybe monad dened in Agda. The Maybe data-type must rst be dened, exactly as in the Haskell implementation.
data Maybe (A : Set) : Set where Nothing : Maybe A
To give the denition of Maybe as a monad, we must dene the bind operator, which we can then use in the denition of monadMaybe.
bindMaybe : ∀ {A B} → Maybe A → (A → Maybe B) → Maybe B bindMaybe Nothing f = Nothing
bindMaybe (Just a) f = f a monadMaybe : RawMonad Maybe
monadMaybe = record {return = \a → Just a
;_=_ = bindMaybe
}