-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDelay.agda
59 lines (43 loc) · 1.53 KB
/
Delay.agda
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
{-# OPTIONS --copatterns --sized-types #-}
{- This is almost verbatim from J. M. Chapman
https://github.com/jmchapman/Relative-Monads/blob/master/Delay.agda
-}
module Delay where
open import Size
open import Category.Monad
open import Level renaming (zero to lzero; suc to lsuc)
open import Relation.Binary public
import Relation.Binary.PreorderReasoning
module Pre = Relation.Binary.PreorderReasoning
open import Data.Product
mutual
data Delay (A : Set) (i : Size) : Set where
now : A → Delay A i
later : ∞Delay A i → Delay A i
record ∞Delay (A : Set) (i : Size) : Set where
coinductive
constructor delay
field
force : {j : Size< i} → Delay A j
open ∞Delay public
-- Smart constructor.
later! : ∀ {A i} → Delay A i → Delay A (↑ i)
later! x = later (delay x)
module Bind where
mutual
_>>=_ : ∀ {i A B} → Delay A i → (A → Delay B i) → Delay B i
now x >>= f = f x
later x >>= f = later (x ∞>>= f)
_∞>>=_ : ∀ {i A B} → ∞Delay A i → (A → Delay B i) → ∞Delay B i
force (x ∞>>= f) = force x >>= f
delayMonad : ∀ {i} → RawMonad {f = lzero} (λ A → Delay A i)
delayMonad {i} = record
{ return = now
; _>>=_ = _>>=_ {i}
} where open Bind
module _ {i : Size} where
open module DelayMonad = RawMonad (delayMonad {i = i})
public renaming (_⊛_ to _<*>_)
open Bind public using (_∞>>=_)
_∞<$>_ : ∀ {i A B} (f : A → B) (∞a : ∞Delay A i) → ∞Delay B i
f ∞<$> ∞a = ∞a ∞>>= λ a → return (f a)