{-# OPTIONS --type-in-type
   #-}

open import NeilPrelude

module Maybe where

maybe : {A B : Set}  B  (A  B)  Maybe A  B 
maybe b _ nothing = b
maybe _ f (just a) = f a

fromMaybe : {A : Set}  A  Maybe A  A
fromMaybe a nothing  = a
fromMaybe a (just b) = b

maybeMerge : {A B C : Set}  (A  C)  (B  C)  (A  B  C)  Maybe A  Maybe B  Maybe C
maybeMerge fa fb fab nothing nothing   = nothing
maybeMerge fa fb fab nothing (just b)  = just (fb b)
maybeMerge fa fb fab (just a) nothing  = just (fa a)
maybeMerge fa fb fab (just a) (just b) = just (fab a b)

maybeMergeWith : {A : Set}  (A  A  A)  Maybe A  Maybe A  Maybe A
maybeMergeWith f (just a) (just b) = just (f a b)
maybeMergeWith f nothing mb = mb
maybeMergeWith f ma nothing = ma

maybeMap : {A B : Set}  (A  B)  Maybe A  Maybe B
maybeMap f = maybe nothing (just  f)

maybeMap2 : {A B Z : Set}  (A  B  Z)  Maybe A  Maybe B  Maybe Z
maybeMap2 f nothing   mb  = nothing
maybeMap2 f (just a)  mb  = maybeMap (f a) mb