module Ivory.Stdlib.Maybe
(
MaybeType(..)
, initJust, initNothing
, getMaybe
, setJust, setNothing
, setDefault, setDefault_
, mapMaybe
, mapMaybeM, mapMaybeM_
, forMaybeM, forMaybeM_
) where
import GHC.TypeLits
import Ivory.Language
class (IvoryStruct sym, IvoryExpr t, IvoryStore t, IvoryInit t) =>
MaybeType (sym :: Symbol) t | sym -> t where
maybeValidLabel :: Label sym (Stored IBool)
maybeValueLabel :: Label sym (Stored t)
initJust :: MaybeType sym a => a -> Init (Struct sym)
initJust x =
istruct
[ maybeValidLabel .= ival true
, maybeValueLabel .= ival x
]
initNothing :: MaybeType sym a => Init (Struct sym)
initNothing =
istruct
[ maybeValidLabel .= ival false
]
getMaybe :: MaybeType sym a
=> ConstRef s1 (Struct sym)
-> a
-> Ivory eff a
getMaybe ref def = do
valid <- deref (ref ~> maybeValidLabel)
value <- deref (ref ~> maybeValueLabel)
assign (valid ? (value, def))
setDefault :: MaybeType sym a
=> Ref s1 (Struct sym)
-> a
-> Ivory eff a
setDefault ref def = do
setDefault_ ref def
deref (ref ~> maybeValueLabel)
setDefault_ :: MaybeType sym a
=> Ref s1 (Struct sym)
-> a
-> Ivory eff ()
setDefault_ ref def = do
valid <- deref (ref ~> maybeValidLabel)
ifte_ (iNot valid)
(do store (ref ~> maybeValidLabel) true
store (ref ~> maybeValueLabel) def)
(return ())
mapMaybe :: MaybeType sym a
=> (a -> a)
-> Ref s1 (Struct sym)
-> Ivory eff ()
mapMaybe f ref = mapMaybeM (return . f) ref
mapMaybeM :: MaybeType sym a
=> (a -> Ivory eff a)
-> Ref s1 (Struct sym)
-> Ivory eff ()
mapMaybeM f ref = do
valid <- deref (ref ~> maybeValidLabel)
ifte_ valid
(do value <- deref (ref ~> maybeValueLabel)
value' <- f value
store (ref ~> maybeValueLabel) value')
(return ())
forMaybeM :: MaybeType sym a
=> Ref s1 (Struct sym)
-> (a -> Ivory eff a)
-> Ivory eff ()
forMaybeM = flip mapMaybeM
mapMaybeM_ :: MaybeType sym a
=> (a -> Ivory eff ())
-> Ref s1 (Struct sym)
-> Ivory eff ()
mapMaybeM_ f ref = do
valid <- deref (ref ~> maybeValidLabel)
ifte_ valid
(do value <- deref (ref ~> maybeValueLabel)
f value)
(return ())
forMaybeM_ :: MaybeType sym a
=> Ref s1 (Struct sym)
-> (a -> Ivory eff ())
-> Ivory eff ()
forMaybeM_ = flip mapMaybeM_
setJust :: MaybeType sym a
=> Ref s1 (Struct sym)
-> a
-> Ivory eff ()
setJust ref x = do
store (ref ~> maybeValidLabel) true
store (ref ~> maybeValueLabel) x
setNothing :: MaybeType sym a
=> Ref s1 (Struct sym)
-> Ivory eff ()
setNothing ref = store (ref ~> maybeValidLabel) false