{-# OPTIONS_GHC -fplugin=Test.Inspection.Plugin #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE UnboxedTuples #-}
{-# LANGUAGE TemplateHaskell #-}
module Main where
import Data.Elevator.Internal
import Test.Hspec
import Test.Inspection
import Control.Exception (evaluate, SomeException (SomeException))
import GHC.Exts
import GHC.IO
import Data.IORef
import qualified Data.Primitive as P
import qualified Issue4
main :: IO ()
main = hspec $ do
describe "Strict" $ do
it "strict" $ do
evaluate
(let a = Strict (error "boom" :: Int)
konst :: a -> Strict b -> a
konst x y = x
in konst 42 a)
`shouldThrow` \(SomeException e) -> True
describe "Lazy" $ do
it "lazy" $ do
(let a = Lazy (error "boom" :: Array# Int)
konst :: a -> Lazy b -> a
konst x y = x
in konst 42 a)
`shouldBe` 42
describe "levCoerce" $ do
describe "Refl" $ do
it "Int ~ Int" $ do
levCoerce @Int @Int 42 `shouldBe` (42 :: Int)
it "Strict Int ~ Strict Int" $ do
case levCoerce# @_ @_ @(Strict Int) @(Strict Int) (Strict 42) of Strict x -> x `shouldBe` (42 :: Int)
describe "->" $ do
it "even" $ do
levCoerce @(Int -> Bool) @(Strict Int -> Bool) even (Strict 42) `shouldBe` True
it "co,contra: Int -> Strict Int ~ Int -> Strict Int" $ do
levCoerce @(Int -> Strict Int) @(Strict Int -> Int) (\x -> Strict (x+1)) (Strict 42) `shouldBe` (43 :: Int)
it "rank2 co: (Int -> Int) -> Int ~ (Strict Int -> Int) -> Int" $ do
levCoerce @((Strict Int -> Int) -> Int) @((Int -> Strict Int) -> Int) (\f -> f (Strict 42)) (\x -> Strict x) `shouldBe` (42 :: Int)
describe "Issue 4" $ do
it "should not crash" $ do
let arr = P.createArray 5 (even (sum [0..1000]) :: Bool) (\_arr -> return ())
let sarr = Issue4.primArrayToStrictArray arr
Issue4.indexStrictArray sarr 3 `shouldBe` True
from_to_strict :: Bool -> Bool
from_to_strict x = fromStrict# (toStrict# x)
from_to_strict2 :: Bool -> Bool
from_to_strict2 x = case Strict x of Strict x -> x
to_from_lazy :: Lazy a -> Lazy a
to_from_lazy x = toLazy# (fromLazy# x)
to_from_lazy2 :: Lazy a -> Lazy a
to_from_lazy2 (Lazy x) = Lazy x
inspect $ 'from_to_strict `doesNotUse` 'toStrict#
inspect $ ('from_to_strict2 `doesNotUse` 'toStrict#) { expectFail = True } -- https://gitlab.haskell.org/ghc/ghc/-/issues/25261
inspect $ 'to_from_lazy `doesNotUse` 'fromLazy#
inspect $ ('to_from_lazy2 `doesNotUse` 'fromLazy#) { expectFail = True } -- https://gitlab.haskell.org/ghc/ghc/-/issues/25261