gambler-0.4.1.0: test/Spec/Shortcut.hs
module Spec.Shortcut where
import Fold.Shortcut
import Test.Hspec
import Control.Applicative (pure, (<$>), (<*>), liftA2)
import Data.Bool (Bool (..))
import Data.Function ((&), flip)
import Data.List ((++))
import Data.Maybe (Maybe (Just, Nothing))
import Data.Ord (Ord (..))
import Prelude (Integer, undefined, odd)
import qualified Data.Char as Char
spec :: SpecWith ()
spec = describe "ShortcutFold" do
it "Applicative" do
let x = do
a <- length
b <- find Char.isLetter
c <- elementIndex 'x'
d <- elementIndex 'y'
e <- last
pure (a, b, c, d, e)
run x ("1234xyz" ++ undefined) `shouldBe` (6, Just 'x', Just 4, Just 5, Just 'y')
describe "first" do
it "gets the first item" do
shouldBe @(Maybe Integer) (run first [5, 4, 3]) (Just 5)
it "is lazy" do
shouldBe @(Maybe Integer) (run first (5 : undefined)) (Just 5)
it "returns Nothing for []" do
shouldBe @(Maybe Integer) (run first []) Nothing
it "is tenacious" do
shouldBe ((run ((,) <$> length <*> first)) "abc") (1, Just 'a')
describe "endpoint functions" do
describe "first" do
it "gets the first item" do
run first ([5, 4, 3] :: [Integer]) `shouldBe` Just 5
it "returns Nothing with no input" do
run first ([] :: [Integer]) `shouldBe` Nothing
it "is lazy" do
run first (5 : undefined :: [Integer]) `shouldBe` Just 5
describe "null" do
it "True for []" do
run null ([] :: [Integer]) `shouldBe` True
it "False for anything else" do
run null ([1] :: [Integer]) `shouldBe` False
run null ([1,2] :: [Integer]) `shouldBe` False
run null ([1,2,3] :: [Integer]) `shouldBe` False
describe "and" do
it "True for []" do
run and [] `shouldBe` True
it "True for [True, ...]" do
run and [True] `shouldBe` True
run and [True,True] `shouldBe` True
run and [True,True,True] `shouldBe` True
it "False for anything else" do
run and [False] `shouldBe` False
run and [False,True] `shouldBe` False
run and [True,False] `shouldBe` False
it "is lazy" do
run and (False : undefined) `shouldBe` False
describe "or" do
it "False for []" do
run or [] `shouldBe` False
it "False for [False, ...]" do
run or [False] `shouldBe` False
run or [False,False] `shouldBe` False
run or [False,False,False] `shouldBe` False
it "True for anything else" do
run or [True] `shouldBe` True
run or [False,True] `shouldBe` True
run or [True,False] `shouldBe` True
it "is lazy" do
run or (True : undefined) `shouldBe` True
describe "duplicate" do
it "lets a fold run in two phases" do
let a, b, c :: [Integer]
a = [1,2,3]
b = [4,7,12,15]
c = a ++ b
f = find (>= 10)
(f & duplicate & flip run a & flip run b) `shouldBe` (run f c)
it "preserves laziness" do
let a, b :: [Integer]
a = 1 : 15 : undefined
b = undefined
f = find (>= 10)
(f & duplicate & flip run a & flip run b) `shouldBe` Just 15
describe "repeatedly" do
it "can find an item in a list of lists" do
let a, b, c :: [Integer]
a = [2, 8, 6]
b = [12, 4, 5, 16]
c = [4, 18, 20]
run (repeatedly run (find odd)) [a, b, c]
`shouldBe` Just 5
it "preserves laziness" do
let a, b, c :: [Integer]
a = [2, 8, 6]
b = 12 : 4 : 5 : undefined
c = undefined
run (repeatedly run (find odd)) [a, b, c]
`shouldBe` Just 5
it "works within an Applicative combination with another 'repeatedly'" do
let a, b, c :: [Integer]
a = [2, 8, 6]
b = 12 : 4 : 5 : undefined
c = undefined
f = liftA2 (,) (repeatedly run (find odd)) (repeatedly run (find (> 5)))
run f [a, b, c]
`shouldBe` (Just 5, Just 8)
it "works on an Applicative combination of 'repeatedly's" do
let a, b, c :: [Integer]
a = [2, 8, 6]
b = 12 : 4 : 5 : undefined
c = undefined
f = liftA2 (,) (find odd) (find (> 5))
run (repeatedly run f) [a, b, c]
`shouldBe` (Just 5, Just 8)
it "works within an Applicative combination with something ambivalent" do
let a, b, c :: [Integer]
a = [2, 8, 6]
b = 12 : 4 : 5 : undefined
c = undefined
f = liftA2 (,) (find odd) length
run (repeatedly run f) [a, b, c]
`shouldBe` (Just 5, 6)