-- This module provides the familiar reader effect. module Control.Effects.Search where import Control.Effects.Eff import Control.Monad -- |A proxy for passing type to functions. Example -- > foo data T a = T asT :: a -> T a -> a asT a T = a -- |The functor representing the effect. You shouldn't need -- to create this manually, just use `choose` or `searchFail`. data Search w a = SChoose [w] (w -> a) deriving (Functor, Typeable) -- |Nondeterministicaly choose an element from a list choose :: (Member (Search w) r, Typeable w) => [w] -> Eff r w choose ws = effect $ \k -> inj $ SChoose ws k -- |Fail a search. Equal to choosing from an empty list. searchFail :: (Member (Search w) r, Typeable w) => T w -> Eff r () searchFail t = do x <- choose [] let _ = x `asT` t return () -- |Use a strict depth first search. Equal to using `ListT` handleDFS :: Handler (Search w) r a [a] handleDFS (Value a) = return [a] handleDFS (Comp (SChoose ws k)) = f $ map k ws where f = foldr (liftM2 (++)) $ return [] -- |Lazy depth first search with backtracking. handleBacktrackMaybe :: Handler (Search w) r a (Maybe a) handleBacktrackMaybe (Value a) = return $ Just a handleBacktrackMaybe (Comp (SChoose ws k)) = step ws where step [] = return Nothing step (w:ws') = k w >>= \r -> case r of m@(Just x) -> return m Nothing -> step ws'