Polysemy: NonDet
As seen in a previous log, some effects allow type classes to be supported.
To enable Applicative
, there is the NonDet
effect, which works with Error a
:
failing = do
embed $ putStrLn "failing"
throw @Integer 1
working0 = do
embed $ putStrLn "working0"
return 42
working1 = do
embed $ putStrLn "working1"
return 42
actFailingFirst = failing <|> working0 <|> working1
Some interpreters are provided:
runNonDet
: produces aSem r (f a)
evaluating both branches of a<|>
runNonDetMaybe
: produces aSem r (Maybe a)
evaluating only the necessary branch of a<|>
nonDetToError
: produces aSem r a
relying on aError e
evaluating only the necessary branch of a<|>
Let's make some tests:
putStrLn "# FailingFirst"
putStrLn "nonDetToError"
runM (runError @Integer $ nonDetToError @Integer 2 actFailingFirst) >>= print
putStrLn "## runNonDet"
runM (runError @Integer $ runNonDet @Maybe actFailingFirst) >>= print
putStrLn "## runNonDetMaybe"
runM (runError @Integer $ runNonDetMaybe actFailingFirst) >>= print
putStrLn "# WorkingFirst"
putStrLn "nonDetToError"
runM (runError @Integer $ nonDetToError @Integer 2 actWorkingFirst) >>= print
putStrLn "## runNonDet"
runM (runError @Integer $ runNonDet @Maybe actWorkingFirst) >>= print
putStrLn "## runNonDetMaybe"
runM (runError @Integer $ runNonDetMaybe actWorkingFirst) >>= print
Giving:
# FailingFirst
nonDetToError
failing
working0
Right 42
## runNonDet
failing
Left 1
## runNonDetMaybe
failing
Left 1
# WorkingFirst
nonDetToError
working0
Right 42
## runNonDet
working0
failing
Left 1
## runNonDetMaybe
working0
Right (Just 42)
Let's try to summarize:
With failing
as first element of <|>
:
Eager | Result | |
---|---|---|
nonDetToError | x | Right 42 |
runNonDet | Left 1 | |
runNonDetMaybe | Left 1 |
With working
as first element of <|>
:
Eager | Result | |
---|---|---|
nonDetToError | Right 42 | |
runNonDet | x | Left 1 |
runNonDetMaybe | Right (Just 42) |
See the full the code here.