mirror of
https://github.com/polysemy-research/polysemy.git
synced 2024-11-30 07:13:55 +03:00
93f8054e05
* Revert functorial state of runNonDet to [] * Added a shouldNotBe
58 lines
2.0 KiB
Haskell
58 lines
2.0 KiB
Haskell
module AlternativeSpec where
|
|
|
|
import Polysemy
|
|
import Polysemy.NonDet
|
|
import Test.Hspec
|
|
import Control.Applicative
|
|
import Polysemy.Trace
|
|
import Polysemy.Reader
|
|
|
|
runAlt :: Alternative f => Sem '[NonDet] a -> f a
|
|
runAlt = run . runNonDet
|
|
|
|
failtrace :: (Member NonDet r, Member Trace r)
|
|
=> Sem r ()
|
|
failtrace = pure () <|> trace "trace"
|
|
|
|
failtrace' :: (Member NonDet r, Member Trace r)
|
|
=> Sem r ()
|
|
failtrace' = trace "sim" *> empty <|> trace "salabim"
|
|
|
|
inHigherOrder :: Members '[NonDet, Trace, Reader ()] r
|
|
=> Sem r ()
|
|
inHigherOrder = do
|
|
local (\_ -> ()) $ trace "1" <|> trace "2"
|
|
trace "3"
|
|
|
|
spec :: Spec
|
|
spec = parallel $ do
|
|
describe "Alternative instance" $ do
|
|
it "should choose the first branch" $ do
|
|
runAlt (pure '1' <|> pure '2') `shouldBe` (Just '1')
|
|
it "should failover" $ do
|
|
runAlt (empty <|> pure '2') `shouldBe` (Just '2')
|
|
runAlt (pure '1' <|> empty) `shouldBe` (Just '1')
|
|
|
|
describe "runNonDetMaybe" $ do
|
|
it "should skip second branch if the first branch succeeds" $ do
|
|
(run . runNonDetMaybe . runTraceList) failtrace
|
|
`shouldBe` Just ([], ())
|
|
(run . runTraceList . runNonDetMaybe) failtrace
|
|
`shouldBe` ([], Just ())
|
|
|
|
it "should respect local/global state semantics" $ do
|
|
(run . runNonDetMaybe . runTraceList) failtrace'
|
|
`shouldBe` Just (["salabim"], ())
|
|
(run . runTraceList . runNonDetMaybe) failtrace'
|
|
`shouldBe` (["sim", "salabim"], Just ())
|
|
|
|
describe "runNonDet" $ do
|
|
it "should have terrible semantics when <|> is used within\
|
|
\ a higher-order action of a later effect (See Issue #246.)" $ do
|
|
(fst . run . runTraceList . runReader () . runNonDet @[]) inHigherOrder
|
|
`shouldBe` ["1","2","3","3"]
|
|
(fst . run . runTraceList . runReader () . runNonDet @[]) inHigherOrder
|
|
`shouldNotBe` ["1","3","2","3"] -- This is what we actually WANT it to be.
|
|
(fst . run . runTraceList . runNonDet @[] . runReader ()) inHigherOrder
|
|
`shouldBe` ["1","3","2","3"]
|