module stlc.monad.properities.monadIdR where

open import stlc.monad.properities.common

open import stlc.value.properities

monadIdR-nondeterminism :  {A A₁ s s₁ s₂ t t'}   flat {A}  s₂ ⟩= t   fmap  cur {A = A₁} (ret {m = nondeterminism}  p₂) s , s₁ ⟩= s₂  s₁  t'  t  t'
monadIdR-nondeterminism {s₁ = []} ev-flat-nil ev-fmap-nil x₂ = x₂
monadIdR-nondeterminism {s₁ = s₁  s₂} (ev-flat-cons x (ev-concatList-cons-left (ev-it-nil ev-id))) (ev-fmap-cons x₁ (ev-comp ev-p2 (ev-ret ev-ret-nondet))) (cons e₁ e₂) with emonadIdR-nondeterminism (ev-comp (ev-pair ev-unit ev-id) x) x₁ e₂ = cons e₁ e

monadIdR :  {Γ A TA s s₁ t t'} {ma : Monad {A} TA} {saa : SameMonad ma ma}   getBindImpl saa  s₁ , cur {Γ} (ret {m = ma}  p₂) s ⟩= t  s₁  t'  t  t'
monadIdR {saa = exception} (ev-comp (ev-pair ev-p2 ev-p1) (ev-copair1 (ev-app (ev-comp ev-p2 (ev-ret ev-i1))))) e = e
monadIdR {saa = exception} (ev-comp (ev-pair ev-p2 ev-p1) (ev-copair2 (ev-comp ev-p2 ev-i2))) e = e
monadIdR {t' = cur g t} {saa = state} ev-cur (cur e) = cur  { x (ev-bind-state (ev-app x₁) (ev-app (ev-comp ev-p2 (ev-ret ev-cur))) (ev-app ev-swap)) x₂  e x x₁ x₂})
monadIdR {saa = nondeterminism} (ev-comp ev-swap (ev-comp x₁ x₂)) e = monadIdR-nondeterminism x₂ x₁ e
monadIdR {t' = cur g t} {saa = continuation} ev-cur (cur e) = cur  { {cur h s} {cur h' s'} x (ev-bind-cont (ev-app x₁)) x₂  e  { x₃ (ev-comp (ev-pair (ev-comp ev-p2p1p1-p2 (ev-app (ev-comp ev-p2 (ev-ret ev-cur)))) (ev-comp ev-p1 ev-p2)) (ev-app (ev-comp ev-swap (ev-app x₄)))) x₅  x x₃ x₄ x₅}) x₁ x₂ })