summaryrefslogtreecommitdiff
path: root/testsuite/tests/generics/GFullyStrict.hs
diff options
context:
space:
mode:
Diffstat (limited to 'testsuite/tests/generics/GFullyStrict.hs')
-rw-r--r--testsuite/tests/generics/GFullyStrict.hs57
1 files changed, 57 insertions, 0 deletions
diff --git a/testsuite/tests/generics/GFullyStrict.hs b/testsuite/tests/generics/GFullyStrict.hs
new file mode 100644
index 0000000000..7c879d9877
--- /dev/null
+++ b/testsuite/tests/generics/GFullyStrict.hs
@@ -0,0 +1,57 @@
+{-# LANGUAGE DefaultSignatures #-}
+{-# LANGUAGE DeriveAnyClass #-}
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeOperators #-}
+module Main where
+
+import Data.Proxy (Proxy(..))
+import GHC.Generics
+
+main :: IO ()
+main = do
+ print (fullyStrict (Proxy :: Proxy (StrictMaybe Bool)))
+ print (fullyStrict (Proxy :: Proxy (Maybe Bool)))
+
+data StrictMaybe a = StrictNothing | StrictJust !a
+ deriving (FullyStrict, Generic)
+
+instance FullyStrict Bool
+instance FullyStrict a => FullyStrict (Maybe a)
+
+class FullyStrict a where
+ fullyStrict :: proxy a -> Bool
+ default fullyStrict :: (GFullyStrict (Rep a)) => proxy a -> Bool
+ fullyStrict _ = gfullyStrict (Proxy :: Proxy (Rep a p))
+
+class GFullyStrict f where
+ gfullyStrict :: proxy (f p) -> Bool
+
+instance GFullyStrict V1 where
+ gfullyStrict _ = True
+
+instance GFullyStrict U1 where
+ gfullyStrict _ = True
+
+instance FullyStrict c => GFullyStrict (Rec0 c) where
+ gfullyStrict _ = fullyStrict (Proxy :: Proxy c)
+
+instance GFullyStrict f => GFullyStrict (D1 c f) where
+ gfullyStrict _ = gfullyStrict (Proxy :: Proxy (f p))
+
+instance GFullyStrict f => GFullyStrict (C1 c f) where
+ gfullyStrict _ = gfullyStrict (Proxy :: Proxy (f p))
+
+instance (GFullyStrict f, Selector c) => GFullyStrict (S1 c f) where
+ gfullyStrict _ = gfullyStrict (Proxy :: Proxy (f p))
+ && selDecidedStrictness (undefined :: S1 c f p) /= DecidedLazy
+
+instance (GFullyStrict f, GFullyStrict g) => GFullyStrict (f :+: g) where
+ gfullyStrict _ =
+ gfullyStrict (Proxy :: Proxy (f p)) && gfullyStrict (Proxy :: Proxy (g p))
+
+instance (GFullyStrict f, GFullyStrict g) => GFullyStrict (f :*: g) where
+ gfullyStrict _ =
+ gfullyStrict (Proxy :: Proxy (f p)) && gfullyStrict (Proxy :: Proxy (g p))