Agda-2.3.2.2: examples/instance-arguments/11-monads.agda
{-# OPTIONS --universe-polymorphism #-}
-- {-# OPTIONS --verbose tc.constr.findInScope:15 #-}
-- {-# OPTIONS --verbose tc.meta.eta:20 #-}
-- {-# OPTIONS --verbose tc.conv.term:20 #-}
-- {-# OPTIONS --verbose tc.meta.assign:70 #-}
-- {-# OPTIONS --verbose tc.eta.rec:70 #-}
-- {-# OPTIONS --verbose tc.sig.inst:30 #-}
module 11-monads where
open import Category.Monad using (RawMonad; module RawMonad)
open import Category.Monad.Indexed using (RawIMonad; module RawIMonad)
--open import Category.Applicative.Indexed using ()
-- identityMonad often makes monadic code ambiguous.
--open import Category.Monad.Identity using (IdentityMonad)
open import Category.Monad.Partiality using (_⊥; now; isNow; never; run_for_steps) renaming (monad to partialityMonad)
open import Category.Monad.State using (StateMonad)
open import Category.Applicative.Indexed using (IFun)
open import Function using (_$_)
open import Level using (zero; Level)
--open import Data.Unit hiding (_≟_)
open import Data.Bool using (if_then_else_)
open import Data.Nat using (ℕ; _≟_; _+_; suc; _*_)
open import Relation.Nullary.Decidable using (⌊_⌋)
open import Data.List using (List; _∷_; []; [_]; null) renaming (monad to listMonad)
--open import Data.Product
module RawMonadExt {li f} {I : Set li} {M : IFun I f} (m : RawIMonad M) where
bind : ∀ {i j k A B} → M i j A → (A → M j k B) → M i k B
bind {i} {j} {k} {A} {B} = RawIMonad._>>=_ {li} {f} {I} {M} m {i} {j} {k} {A} {B}
syntax bind m (λ x → c) = do x ← m then c
stateMonad = StateMonad ℕ
nToList : ℕ → List ℕ
nToList 0 = [ 0 ]
nToList (suc n) = n ∷ nToList n
test′ : ℕ → (List ℕ) ⊥
test′ k = let open RawMonad partialityMonad
open RawMonadExt partialityMonad
in do x ← return (k ∷ k + 1 ∷ []) then
return x
test2′ : ℕ → (List ℕ) ⊥
test2′ k = let open RawMonad partialityMonad
open RawMonadExt partialityMonad
open RawMonad listMonad using () renaming (_>>=_ to _l>>=_)
in do x ← return [ k ] then
if ⌊ k ≟ 4 ⌋ then return (x l>>= nToList) else never
open RawMonad {{...}}
open RawMonadExt {{...}}
test1 : ℕ → ℕ ⊥
test1 k = do x ← return k then
if ⌊ x ≟ 4 ⌋ then return 10 else never
test2 : ℕ → (List ℕ) ⊥
test2 k = do x ← return [ k ] then
if ⌊ k ≟ 4 ⌋ then return (x >>= nToList) else never
test' : ℕ → (List ℕ) ⊥
test' k = do x ← return (k ∷ k + 1 ∷ []) then
if null x then never else return (x >>= nToList)
test3 : List ℕ
test3 = do x ← 1 ∷ 2 ∷ 3 ∷ [] then
return $ x + 1