aern2-mp-0.2.15.0: src/AERN2/Select.hs
{-|
Module : AERN2.Select
Description : multivalued select operation
Copyright : (c) Michal Konecny
License : BSD3
Maintainer : mikkonecny@gmail.com
Stability : experimental
Portability : portable
Generic multivalued select operation
-}
module AERN2.Select where
import MixedTypesNumPrelude
import qualified Numeric.CollectErrors as CN
import AERN2.Kleenean
class (IsBool (SelectType k)) => CanSelect k where
{-| Must be Bool or similar -}
type SelectType k
{-|
Execute two lazy computations "in parallel" until one of them succeeds.
-}
select :: k -> k -> (SelectType k) {-^ True means that the first computation succeeded. -}
type CanSelectBool k = (CanSelect k, SelectType k ~ Bool)
type CanSelectCNBool k = (CanSelect k, SelectType k ~ CN Bool)
instance CanSelect Kleenean where
type SelectType Kleenean = CN Bool
select CertainTrue _ = cn True
select _ CertainTrue = cn False
select CertainFalse CertainFalse =
CN.noValueNumErrorPotential $
CN.NumError "select (Kleenean): Both branches failed!"
select _ _ =
CN.noValueNumErrorPotential $
CN.NumError "select (Kleenean): Insufficient information to determine selection."
instance CanSelect (CN Kleenean) where
type SelectType (CN Kleenean) = CN Bool
select cnk1 cnk2 =
do
k1 <- cnk1
k2 <- cnk2
select k1 k2
class CanSelectCountable k where
{-| Must be Integer or similar -}
type SelectCountableType k
{-|
Execute a sequence of lazy computations "in parallel" until one of them succeeds
and return the index of a succeeding computation.
-}
selectCountable :: (Integer -> k) -> SelectCountableType k
type CanSelectCountableInteger k = (CanSelectCountable k, SelectCountableType k ~ Integer)
type CanSelectCountableCNInteger k = (CanSelectCountable k, SelectCountableType k ~ CN Integer)
instance CanSelectCountable Kleenean where
type SelectCountableType Kleenean = Integer
selectCountable kleeneans = aux 0
where
aux i = case kleeneans i of
CertainTrue -> i
_ -> aux (i + 1)
instance CanSelectCountable (CN Kleenean) where
type SelectCountableType (CN Kleenean) = CN Integer
selectCountable cnkleeneans = aux 0
where
aux i = do
ki <- cnkleeneans i
case ki of
CertainTrue -> cn i
_ -> aux (i + 1)