packages feed

deepseq-bounded 0.6.2.0 → 0.7.0.0

raw patch · 28 files changed

+9005/−16693 lines, 28 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

- Control.DeepSeq.Bounded: deepseq_bounded_flag__new_improved_pattern_grammar :: Bool
+ Control.DeepSeq.Bounded.NFDataP: instance (Integral a, NFDataP a) => NFDataP (Ratio a)
+ Control.DeepSeq.Bounded.NFDataP: instance (Ix a, NFDataP a, NFDataP b) => NFDataP (Array a b)
+ Control.DeepSeq.Bounded.NFDataP: instance (NFDataP a, NFDataP b) => NFDataP (Either a b)
+ Control.DeepSeq.Bounded.NFDataP: instance (RealFloat a, NFDataP a) => NFDataP (Complex a)
+ Control.DeepSeq.Bounded.NFDataP: instance (Typeable a, NFDataP a, Typeable b, NFDataP b) => NFDataP (a, b)
+ Control.DeepSeq.Bounded.NFDataP: instance (Typeable a, NFDataP a, Typeable b, NFDataP b, Typeable c, NFDataP c) => NFDataP (a, b, c)
+ Control.DeepSeq.Bounded.NFDataP: instance (Typeable a, NFDataP a, Typeable b, NFDataP b, Typeable c, NFDataP c, Typeable d, NFDataP d) => NFDataP (a, b, c, d)
+ Control.DeepSeq.Bounded.NFDataP: instance (Typeable a, NFDataP a, Typeable b, NFDataP b, Typeable c, NFDataP c, Typeable d, NFDataP d, Typeable e, NFDataP e) => NFDataP (a, b, c, d, e)
+ Control.DeepSeq.Bounded.NFDataP: instance (Typeable a, NFDataP a, Typeable b, NFDataP b, Typeable c, NFDataP c, Typeable d, NFDataP d, Typeable e, NFDataP e, Typeable f, NFDataP f) => NFDataP (a, b, c, d, e, f)
+ Control.DeepSeq.Bounded.NFDataP: instance (Typeable a, NFDataP a, Typeable b, NFDataP b, Typeable c, NFDataP c, Typeable d, NFDataP d, Typeable e, NFDataP e, Typeable f, NFDataP f, Typeable g, NFDataP g) => NFDataP (a, b, c, d, e, f, g)
+ Control.DeepSeq.Bounded.NFDataP: instance (Typeable a, Typeable b) => NFDataP (a -> b)
+ Control.DeepSeq.Bounded.NFDataP: instance Exception DeepSeqBounded_PingException
+ Control.DeepSeq.Bounded.NFDataP: instance NFDataP ()
+ Control.DeepSeq.Bounded.NFDataP: instance NFDataP Bool
+ Control.DeepSeq.Bounded.NFDataP: instance NFDataP Char
+ Control.DeepSeq.Bounded.NFDataP: instance NFDataP Double
+ Control.DeepSeq.Bounded.NFDataP: instance NFDataP Float
+ Control.DeepSeq.Bounded.NFDataP: instance NFDataP Int
+ Control.DeepSeq.Bounded.NFDataP: instance NFDataP Int16
+ Control.DeepSeq.Bounded.NFDataP: instance NFDataP Int32
+ Control.DeepSeq.Bounded.NFDataP: instance NFDataP Int64
+ Control.DeepSeq.Bounded.NFDataP: instance NFDataP Int8
+ Control.DeepSeq.Bounded.NFDataP: instance NFDataP Integer
+ Control.DeepSeq.Bounded.NFDataP: instance NFDataP Version
+ Control.DeepSeq.Bounded.NFDataP: instance NFDataP Word
+ Control.DeepSeq.Bounded.NFDataP: instance NFDataP Word16
+ Control.DeepSeq.Bounded.NFDataP: instance NFDataP Word32
+ Control.DeepSeq.Bounded.NFDataP: instance NFDataP Word64
+ Control.DeepSeq.Bounded.NFDataP: instance NFDataP Word8
+ Control.DeepSeq.Bounded.NFDataP: instance NFDataP a => NFDataP (Maybe a)
+ Control.DeepSeq.Bounded.NFDataP: instance NFDataP a => NFDataP [a]
+ Control.DeepSeq.Bounded.NFDataP: instance Show DeepSeqBounded_PingException
+ Control.DeepSeq.Bounded.NFDataP: instance Typeable DeepSeqBounded_PingException
+ Control.DeepSeq.Bounded.NFDataP: instance Typeable a => NFDataP (Fixed a)
+ Control.DeepSeq.Bounded.Pattern: instance Eq PatNode
+ Control.DeepSeq.Bounded.Pattern: instance Eq PatNodeAttrs
+ Control.DeepSeq.Bounded.Pattern: instance Eq SeqNode
+ Control.DeepSeq.Bounded.Pattern: instance Eq a => Eq (Rose a)
+ Control.DeepSeq.Bounded.Pattern: instance Functor Rose
+ Control.DeepSeq.Bounded.Pattern: instance NFData PatNode
+ Control.DeepSeq.Bounded.Pattern: instance NFData PatNodeAttrs
+ Control.DeepSeq.Bounded.Pattern: instance NFData ThreadId
+ Control.DeepSeq.Bounded.Pattern: instance NFData a => NFData (Rose a)
+ Control.DeepSeq.Bounded.Pattern: instance Ord SeqNode
+ Control.DeepSeq.Bounded.Pattern: instance Show PatNode
+ Control.DeepSeq.Bounded.Pattern: instance Show PatNodeAttrs
+ Control.DeepSeq.Bounded.Pattern: instance Show a => Show (Rose a)
+ Control.DeepSeq.Bounded.Pattern: instance Typeable PatNode
+ Control.DeepSeq.Bounded.Pattern: instance Typeable PatNodeAttrs
+ Control.DeepSeq.Bounded.Pattern: instance Typeable Rose

Files

changelog.txt view
@@ -1,13 +1,24 @@ -NOTE: My real "changelog" (a private document) is-over 8000 lines long, and I haven't really taken pains-to assure that this summary is complete.--The transition-5-6-7.html file probably contains better-information. It is in the ./HTML directory of the source-distribution, or online at-http://www.fremissant.net/deepseq-bounded/transition-5-6-7.html-(most up to date).+** 0.6.2.0 -> 0.7.0.0+ - although slated for early March, I'm just going ahead+   and releasing 0.7 now, which finalises the grammar, and+   largely closes the book on the first volume of this enterprise+ - plans from here to version 1.0:+    - definitely get rid of the T* nodes, and just rely on the attribute+    - still undecided to refactor PatNode as product instead of sum...+       - if do refactor, it'll be easier with T* nodes absorbed+    - if I can get better test suites in there, that would be swell+    - if things pass thorough testing, that will bring me to 0.8+       - in case a major bump itch was pending for any reason,+         NOW's the time to pull the bumper, rather than later!+    - between 0.8 and 1.0, there needs to be work on Seqable+       - though maybe there's not much to do, since it's (A) so minimalist,+         and (B) designed for use by auto-instrumentation tools+    - so basically, if everything in deepseq-bounded has polish+      and is well-tested, there's nothing holding back 1.0 I think...+       - just go 0.9 then give it a grace period, like let's say+         two months (seeing 0.9.1 0.9.2 ...), and after that,+         when things feel right, upload whatever I've got as 1.0  0.6.1.0 -> 0.6.2.0  - everything relating to attoparsec has been ripped out@@ -54,6 +65,9 @@  - decrufting of Compile_new_grammar.hs  ** 0.5.5 -> 0.6.0.0+ - the transition-5-6-7.html file contains additional details.+    - it is in the ./HTML directory of the source distribution, or online at+      http://www.fremissant.net/deepseq-bounded/transition-5-6-7.html  - many misc. bug fixes  - much polishing of documentation (corrections, elaborations, refinements)  - renamed module "...Bounded.Generics" to "...Bounded.Generic"
deepseq-bounded.cabal view
@@ -2,7 +2,7 @@ -------------------------------------------------------------------------------  name:		deepseq-bounded-version:        0.6.2.0+version:        0.7.0.0 synopsis:       Bounded deepseq, including support for generic deriving license:	BSD3 license-file:	LICENSE@@ -23,8 +23,6 @@ --tested-with:    GHC==7.6.3, GHC==7.8.*, GHC==7.10.1   -- illegal syntax  description:-    /NOTE: Version 0.6.* is a transitional version. Please refer to/ <http://www.fremissant.net/deepseq-bounded/transition-5-6-7.html this page> /for details about what has changed since 0.5.5, and what's in store when bump 0.6 to 0.7./-    .     This package provides methods for partially (or fully) evaluating data     structures (\"bounded deep evaluation\").     .@@ -58,6 +56,8 @@     Recent developments supporting parallelisation control (in <http://hackage.haskell.org/package/deepseq-bounded-0.6.0.0/docs/Control-DeepSeq-Bounded-Pattern.html Pattern>     and <http://hackage.haskell.org/package/deepseq-bounded-0.6.0.0/docs/Control-DeepSeq-Bounded-Seqable.html Seqable> modules) may justify renaming this library to     something which encompasses both strictness and parallelism aspects.+    .+    / NOTE: Versions >=0.6.* are substantially different from the original 0.5.* release, particularly as regards NFDataP. I should deprecate 0.5.* soon. /  extra-source-files:       README@@ -134,18 +134,6 @@ --Default: False   Manual: True -Flag PARALLELISM_EXPERIMENT-  Description: Deprecated; will be gone in 0.7. Only has any effect if NEW_IMPROVED_PATTERN_GRAMMAR is False (which is also deprecated, and will be gone in 0.7).-  Default: True---Default: False-  Manual: True--Flag NEW_IMPROVED_PATTERN_GRAMMAR-  Description: The language is about 25% less verbose with this flag set True. Set True by default since version 0.6.0.0. DEPRECATION WARNING: This flag will be removed in a major version or two, in the interests of maintainability. In case there are very early adopters out there, please update your code ASAP to use the new grammar...-  Default: True---Default: False-  Manual: True- -- Flag DEPTH_USES_INT64 --   Description: This won't be implemented for a while, probably. -- --Default: True@@ -282,30 +270,6 @@           , Control.DeepSeq.Bounded.Generic.GSeqable           , Control.DeepSeq.Bounded.NFDataPDyn -  -- temporary during NEW_IMPROVED_PATTERN_GRAMMAR transition...-  other-modules:-      Control.DeepSeq.Bounded.Flags-    , Control.DeepSeq.Bounded.Compile_shared_utils-    , Control.DeepSeq.Bounded.Compile_shared_utils2-  if flag(NEW_IMPROVED_PATTERN_GRAMMAR)-    other-modules:-        Control.DeepSeq.Bounded.Pattern_new_grammar-      , Control.DeepSeq.Bounded.Compile_new_grammar-      , Control.DeepSeq.Bounded.PatUtil_new_grammar-      , Control.DeepSeq.Bounded.NFDataP_new_grammar-    if ! flag(HASKELL98_FRAGMENT)-      other-modules:-          Control.DeepSeq.Bounded.Generic.GNFDataP_new_grammar-  else-    other-modules:-        Control.DeepSeq.Bounded.Pattern_old_grammar-      , Control.DeepSeq.Bounded.Compile_old_grammar-      , Control.DeepSeq.Bounded.PatUtil_old_grammar-      , Control.DeepSeq.Bounded.NFDataP_old_grammar-    if ! flag(HASKELL98_FRAGMENT)-      other-modules:-          Control.DeepSeq.Bounded.Generic.GNFDataP_old_grammar-   ghc-options: -optP-Wundef -fno-warn-overlapping-patterns    if flag(USE_CPPHS)@@ -333,8 +297,6 @@       -- but this could be done without the State monad (I read...). --  , mtl == 2.1.3.1     , mtl == 2.1.*--- Causes cabal configure to hang, again (was happening with cpphs dep before)!---- , mtl  ---- We don't really depend on the cpphs /library/, but installing ---- the library also installs the cpphs executable, so in case@@ -363,13 +325,10 @@   else      cpp-options: -DUSE_WW_DEEPSEQ=0 -  if flag(NEW_IMPROVED_PATTERN_GRAMMAR)-     if flag(USE_CURLY_BRACE_INSTEAD_OF_PAREN_FOR_SUBPATTERNS)-        cpp-options: -DUSE_CURLY_BRACE_INSTEAD_OF_PAREN_FOR_SUBPATTERNS=1-     else-        cpp-options: -DUSE_CURLY_BRACE_INSTEAD_OF_PAREN_FOR_SUBPATTERNS=0-  else+  if flag(USE_CURLY_BRACE_INSTEAD_OF_PAREN_FOR_SUBPATTERNS)      cpp-options: -DUSE_CURLY_BRACE_INSTEAD_OF_PAREN_FOR_SUBPATTERNS=1+  else+     cpp-options: -DUSE_CURLY_BRACE_INSTEAD_OF_PAREN_FOR_SUBPATTERNS=0    if flag(ABBREV_WN_AND_TN_CONCRETE_SYNTAX_TO_NUMBER_ALONE__SAFE_ONLY_TO_DEPTH_19)      cpp-options: -DABBREV_WN_AND_TN_CONCRETE_SYNTAX_TO_NUMBER_ALONE__SAFE_ONLY_TO_DEPTH_19=1@@ -381,14 +340,6 @@   else      cpp-options: -DABBREV_WN_AND_TN_CONCRETE_SYNTAX_TO_SINGLE_DIGIT__CAN_ONLY_EXPRESS_DOWN_TO_DEPTH_9=0 -  if flag(NEW_IMPROVED_PATTERN_GRAMMAR)-     cpp-options: -DPROVIDE_OLD_SHRINK_PAT=0-  else-     if flag(PROVIDE_OLD_SHRINK_PAT)-        cpp-options: -DPROVIDE_OLD_SHRINK_PAT=1-     else-        cpp-options: -DPROVIDE_OLD_SHRINK_PAT=0-   if flag(WARN_PATTERN_MATCH_FAILURE)      cpp-options: -DWARN_PATTERN_MATCH_FAILURE=1   else@@ -409,11 +360,6 @@   else      cpp-options: -DHASKELL98_FRAGMENT=0 -  if flag(NEW_IMPROVED_PATTERN_GRAMMAR)-     cpp-options: -DNEW_IMPROVED_PATTERN_GRAMMAR=1-  else-     cpp-options: -DNEW_IMPROVED_PATTERN_GRAMMAR=0- --if flag(DEPTH_USE_INT64) --   cpp-options: -DDEPTH_USE_INT64=1 --else@@ -434,18 +380,7 @@   else      cpp-options: -DUSE_PAR_SEQABLE=0 -  -- PARALLELISM_EXPERIMENT flag is deprecated (will vanish in 0.7)   if ! flag(HASKELL98_FRAGMENT)-     if flag(PARALLELISM_EXPERIMENT)-        build-depends:-            parallel == 3.2.*-        cpp-options: -DPARALLELISM_EXPERIMENT=1-     else-        cpp-options: -DPARALLELISM_EXPERIMENT=0-  else-     cpp-options: -DPARALLELISM_EXPERIMENT=0--  if ! flag(HASKELL98_FRAGMENT)      if flag(USE_PAR_PATNODE)         build-depends:             parallel == 3.2.*@@ -548,22 +483,11 @@      other-modules:       Blah98   else      other-modules:       Blah, Bottom, FooG-  if flag(NEW_IMPROVED_PATTERN_GRAMMAR)-    if flag(HASKELL98_FRAGMENT)-       other-modules:       Blah98_new_grammar-    else-       other-modules:       Blah_new_grammar-  else-    if flag(HASKELL98_FRAGMENT)-       other-modules:       Blah98_old_grammar-    else-       other-modules:       Blah_old_grammar    ghc-options: -optP-Wundef -fno-warn-overlapping-patterns    if flag(USE_CPPHS)-     ghc-options: -pgmPcpphs -optP --cpp---   ghc-options: -pgmPcpphs -optP--cpp+     ghc-options: -pgmPcpphs -optP--cpp --else --   ghc-options: -cpp @@ -634,18 +558,10 @@   else      cpp-options: -DWARN_PATTERN_MATCH_FAILURE=0 -  if flag(NEW_IMPROVED_PATTERN_GRAMMAR)-     cpp-options: -DNEW_IMPROVED_PATTERN_GRAMMAR=1-  else-     cpp-options: -DNEW_IMPROVED_PATTERN_GRAMMAR=0--  if flag(NEW_IMPROVED_PATTERN_GRAMMAR)-     if flag(USE_CURLY_BRACE_INSTEAD_OF_PAREN_FOR_SUBPATTERNS)-        cpp-options: -DUSE_CURLY_BRACE_INSTEAD_OF_PAREN_FOR_SUBPATTERNS=1-     else-        cpp-options: -DUSE_CURLY_BRACE_INSTEAD_OF_PAREN_FOR_SUBPATTERNS=0-  else+  if flag(USE_CURLY_BRACE_INSTEAD_OF_PAREN_FOR_SUBPATTERNS)      cpp-options: -DUSE_CURLY_BRACE_INSTEAD_OF_PAREN_FOR_SUBPATTERNS=1+  else+     cpp-options: -DUSE_CURLY_BRACE_INSTEAD_OF_PAREN_FOR_SUBPATTERNS=0    -- (Probably not actually referenced in the tests.)   if flag(ABBREV_WN_AND_TN_CONCRETE_SYNTAX_TO_NUMBER_ALONE__SAFE_ONLY_TO_DEPTH_19)@@ -675,17 +591,6 @@         cpp-options: -DUSE_PAR_SEQABLE=0   else      cpp-options: -DUSE_PAR_SEQABLE=0--  -- PARALLELISM_EXPERIMENT flag is deprecated (will vanish in 0.7)-  if ! flag(HASKELL98_FRAGMENT)-     if flag(PARALLELISM_EXPERIMENT)-        build-depends:-            parallel == 3.2.*-        cpp-options: -DPARALLELISM_EXPERIMENT=1-     else-        cpp-options: -DPARALLELISM_EXPERIMENT=0-  else-     cpp-options: -DPARALLELISM_EXPERIMENT=0    if ! flag(HASKELL98_FRAGMENT)      if flag(USE_PAR_PATNODE)
src/Control/DeepSeq/Bounded.hs view
@@ -108,14 +108,10 @@ #endif #endif -     , module Control.DeepSeq.Bounded.Flags-   )   where  ---------------------------------------------------------------------------------  import Control.DeepSeq.Bounded.Flags  #if PROVIDE_DATA_FAMILY   -- Remarkable, this is not already in scope by re-export!
src/Control/DeepSeq/Bounded/Compile.hs view
@@ -3,8 +3,52 @@    {-  LANGUAGE CPP #-} +#define DO_TRACE 0++#if ABBREV_WN_AND_TN_CONCRETE_SYNTAX_TO_NUMBER_ALONE__SAFE_ONLY_TO_DEPTH_19 && ABBREV_WN_AND_TN_CONCRETE_SYNTAX_TO_SINGLE_DIGIT__CAN_ONLY_EXPRESS_DOWN_TO_DEPTH_9+#error Please set at most one of the flags ABBREV_WN_AND_TN_CONCRETE_SYNTAX_TO_NUMBER_ALONE__SAFE_ONLY_TO_DEPTH_19 and ABBREV_WN_AND_TN_CONCRETE_SYNTAX_TO_SINGLE_DIGIT__CAN_ONLY_EXPRESS_DOWN_TO_DEPTH_9 to True.+#endif+++#define WARN_IGNORED_SUBPATTERNS 1+#define NEVER_IGNORE_SUBPATTERNS 0++-- Formerly DEBUG_WITH_DEEPSEQ_GENERICS.+-- Now also needed to force issuance of all compilePat warnings+-- (so not strictly a debugging flag anymore).+-- [Except it didn't work...]+--- #define NFDATA_INSTANCE_PATTERN 0  -- now a .cabal flag++#define DO_DERIVE_DATA_AND_TYPEABLE 0+#define DO_DERIVE_ONLY_TYPEABLE 1+#if DO_DERIVE_ONLY_TYPEABLE && DO_DERIVE_DATA_AND_TYPEABLE+#undef DO_DERIVE_ONLY_TYPEABLE+#warning DO_DERIVE_ONLY_TYPEABLE forced 0, due to DO_DERIVE_DATA_AND_TYPEABLE being 1.+#define DO_DERIVE_ONLY_TYPEABLE 0+#endif++-- Now specified via --flag=[-]USE_WWW_DEEPSEQ+--- #define USE_WW_DEEPSEQ 1+ ------------------------------------------------------------------------------- +#if DO_DERIVE_DATA_AND_TYPEABLE+  {-# LANGUAGE DeriveDataTypeable #-}+#endif+-- XXX Only needed for something in Blah.hs.+-- Check into it, and see if can't get rid of the need+-- for Typeable instances in here!+#if DO_DERIVE_ONLY_TYPEABLE+  {-# LANGUAGE DeriveDataTypeable #-}+#endif+#if NFDATA_INSTANCE_PATTERN+  -- For testing only (controlling trace interleaving):+  {-# LANGUAGE DeriveGeneric #-}+#endif+  {-  LANGUAGE DeriveFunctor #-}++-------------------------------------------------------------------------------+ -- | -- Module      :  Control.DeepSeq.Bounded.Compile -- Copyright   :  Andrew G. Seniuk 2014-2015@@ -12,7 +56,7 @@ -- -- Maintainer  :  Andrew Seniuk <rasfar@gmail.com> -- Stability   :  provisional--- Portability :  portable+-- Portability :  portable (H98) -- -- This is normally part of <http://hackage.haskell.org/package/deepseq-bounded-0.6.0.0/docs/Control-DeepSeq-Bounded-Pattern.html Pattern>, -- but is broken out for the transitional version 0.6.*.@@ -25,12 +69,489 @@       compilePat     , showPat +---   compilePat'  ,+   )   where  ------------------------------------------------------------------------------- -  import Control.DeepSeq.Bounded.Compile_shared_utils2 ( compilePat, showPat )+  import Control.DeepSeq.Bounded.Pattern+  import Control.DeepSeq.Bounded.PatUtil ( liftPats )++  import Data.Char ( isSpace )+  import Data.Char ( isLower )+  import Data.Char ( ord )+  import Data.Char ( isDigit )+  import Data.List ( intercalate )+  import Data.List ( sort )+  import Data.Maybe ( isNothing, fromJust )+  import Data.Maybe ( isJust )++#if 0++#if DO_DERIVE_DATA_AND_TYPEABLE+  import Data.Data ( Data )+  import Data.Typeable ( Typeable )+#elif DO_DERIVE_ONLY_TYPEABLE+  import Data.Typeable ( Typeable )+#endif++#if USE_WW_DEEPSEQ+  import Control.DeepSeq ( NFData )+#endif++#endif++  import Debug.Trace ( trace )++  -- The only uses of force in this module are for debugging purposes+  -- (including trying to get messages to be displayed in a timely+  -- manner, although that problem has not been completely solved).+  import Control.DeepSeq ( force )+#if 0+#if NFDATA_INSTANCE_PATTERN+  -- for helping trace debugging+  import qualified Control.DeepSeq.Generics as DSG+  import qualified GHC.Generics as GHC ( Generic )+#endif+#endif++-------------------------------------------------------------------------------++#if DO_TRACE+  mytrace = trace+#else+  mytrace _ = id+#endif++  -- XXX This is still lacks support for the two condensed grammars:+  -- ABBREV_WN_AND_TN_CONCRETE_SYNTAX_TO_NUMBER_ALONE__SAFE_ONLY_TO_DEPTH_19+  -- ABBREV_WN_AND_TN_CONCRETE_SYNTAX_TO_SINGLE_DIGIT__CAN_ONLY_EXPRESS_DOWN_TO_DEPTH_9++  compilePat' :: String -> Pattern+  compilePat' s+   | not $ null s'  = error $ "\ncompilePat: input rejected: "+                       ++ s+                       ++ if isNothing mmsg then "" else "\nParser message: "+                       ++ fromJust mmsg+                       ++ "\nPatterns parsed so far: ["+                       ++ intercalate ", " (map show pats)+                       ++ "]"+   | otherwise      = case pats of+       [] -> error $ "\ncompilePat: "+              ++ if null s then "empty input" else "vacuous input"+       [pat] -> setPatternPatNodeUniqueIDs 0 pat+       pats -> setPatternPatNodeUniqueIDs 0 $ liftPats pats+   where (pats, mmsg, s') = compilePats s []++  -- String in last component of result is unconsumed input.++  compilePats :: String -> [Pattern] -> ([Pattern], Maybe String, String)+  compilePats s acc+   | null s_ltrim  = (reverse acc, Nothing, s_ltrim)+   | otherwise     = case cpat s of+      (Left "", s') -> (reverse acc, Nothing, s')+--    (Left "", s') -> compilePats s' acc+      (Left msg, s') -> (reverse acc, Just msg, s')+      (Right pat, s') -> compilePats s' (pat:acc)+   where s_ltrim = dropWhile isSpace s++-- XXX Don't forget to do a post-pass to change W* nodes+-- to corresponding T* nodes, when : modifier was present!+-- Oops, guess I did it here; but the original idea would+-- be less cloning...++  cpat :: String -> (Either String Pattern, String)+--cpat _ | trace "J-1: " $ False  = undefined+  cpat [] = (Left "unexpected end of input", [])+--cpat s | trace ("J-2: "++show s) $ False  = undefined+  cpat s+   | null s''   = error "\ncompilePat: type constraint must precede a pattern node"+   | isW        = case c of+      '.' -> (Right $ Node (WI as) [], cs)+      '!' -> (Right $ Node (WS as) [], cs)+      '*' -> case parseInt cs [] of+               (Nothing, cs'') -> (Right $ Node (WW   as    ) [], cs'')+               (Just is, cs'') -> (Right $ Node (WN $ asn is) [], cs'')+#if USE_CURLY_BRACE_INSTEAD_OF_PAREN_FOR_SUBPATTERNS+      '{' ->+#else+      '(' ->+#endif+             if isNothing mmsg_subpats+             then (Right $ Node (WR as) subpats, cs_subpats)+             else (Left $ fromJust mmsg_subpats, cs_subpats)+#if USE_CURLY_BRACE_INSTEAD_OF_PAREN_FOR_SUBPATTERNS+      '}' ->+#else+      ')' ->+#endif+             (Left "", cs)+      c -> error $ "\ncompilePat: unexpected character '" ++ [c] ++ "'"+   | otherwise  = case c of+      '.' -> (Right $ Node (TI as) [], cs)+--    '!' -> (Right $ Node (TS as) [], cs)+      '*' -> case parseInt cs [] of+               (Nothing, cs'') -> (Right $ Node (TW   as    ) [], cs'')+               (Just is, cs'') -> (Right $ Node (TN $ asn is) [], cs'')+#if USE_CURLY_BRACE_INSTEAD_OF_PAREN_FOR_SUBPATTERNS+      '{' ->+#else+      '(' ->+#endif+             if isNothing mmsg_subpats+             then (Right $ Node (TR as) subpats, cs_subpats)+             else (Left $ fromJust mmsg_subpats, cs_subpats)+#if USE_CURLY_BRACE_INSTEAD_OF_PAREN_FOR_SUBPATTERNS+      '}' ->+#else+      ')' ->+#endif+             (Left "", cs)+      c -> error $ "\ncompilePat: unexpected character '" ++ [c] ++ "'"+   where+    s' = dropWhile isSpace s+    (c:cs) = s''+    (as_mods, mmsg_mods, s'') = cmods s'  -- collect any prefix modifiers+    as = case mmsg_mods of+           Nothing -> as_mods+           Just msg -> error $ "\ncompilePat: " ++ msg+    asn is = as { depth = read is :: Int }+    isW = not $ doConstrainType as+    (subpats, mmsg_subpats, cs_subpats) = compilePats cs []++  -- Accumulate any prefix modifiers into an empty PatNodeAttrs structure.+  cmods :: String -> (PatNodeAttrs, Maybe String, String)+  cmods s = cmods' s emptyPatNodeAttrs+  cmods' :: String -> PatNodeAttrs -> (PatNodeAttrs, Maybe String, String)+  cmods' [] as = (as, Nothing, [])+--cmods' [] as = (as, Just "cmods': unexpected end of input", [])+  cmods' s as = case c of+    ':' -> cmods' cs_types  as_types+    '@' -> cmods' cs_delay  as_delay+#if USE_PAR_PATNODE+    '=' -> cmods' cs_par    as_par+#endif+#if USE_PSEQ_PATNODE+    '>' -> cmods' cs_pseq   as_pseq+#endif+#if USE_TRACE_PATNODE+    '+' -> cmods' cs_trace  as_trace+#endif+#if USE_PING_PATNODE+    '^' -> cmods' cs_ping   as_ping+#endif+#if USE_DIE_PATNODE+    '/' -> cmods' cs_die    as_die+#endif+#if USE_TIMING_PATNODE+    '%' -> cmods' cs_timing as_timing+#endif+    _ -> (as, Nothing, s)+   where+    s'@(c:cs) = dropWhile isSpace s+    ( cs_types  , as_types  ) = parse_type_constraints          cs as+    ( cs_delay  , as_delay  ) = parse_delay                     cs as+#if USE_PAR_PATNODE+    ( cs_par    , as_par    ) = ( cs, as { doSpark  = True } )+#endif+#if USE_PSEQ_PATNODE+    ( cs_pseq   , as_pseq   ) = parse_pseq                      cs as+#endif+#if USE_TRACE_PATNODE+    ( cs_trace  , as_trace  ) = ( cs, as { doTrace  = True } )+#endif+#if USE_PING_PATNODE+    ( cs_ping   , as_ping   ) = ( cs, as { doPing   = True } )+#endif+#if USE_DIE_PATNODE+    ( cs_die    , as_die    ) = ( cs, as { doDie    = True } )+#endif+#if USE_TIMING_PATNODE+    ( cs_timing , as_timing ) = ( cs, as { doTiming = True } )+#endif++  parse_type_constraints :: String -> PatNodeAttrs -> (String, PatNodeAttrs)+  parse_type_constraints s'' as+--- | doConstrainType as  = trace "\nwarning: type constraints (:...:) mod given multiple times to a single node, so aggregating type lists." $ (s', as')+   | otherwise           = (s', as')+   where+    s = dropWhile isSpace s''+    as' = as { doConstrainType = True+             , typeConstraints = typeConstraints as ++ tys }+    (tys, s') = f s "" []+    -- Take up to the next ';', ':', or '\\' and deal.+    f :: String -> String -> [String] -> ([String],String)+    f s'' tyacc tysacc+     | null s'    = error "\ncompilePat: type constraint list not ':'-terminated"+     | '\\' == c  = if null cs+                    then f cs (c:tyacc) tysacc+                    else if ':' == head cs    -- note ty is already reversed+                         then f (tail cs) ((':':'\\':ty) ++ tyacc) tysacc+                         else f cs (('\\':ty) ++ tyacc) tysacc+     | ':' == c   = ( reverse $ (reverse $ tyacc ++ ty) : tysacc , dropWhile isSpace cs )+    -- otherwise ';' == c+     | otherwise  = f cs "" $ (reverse $ tyacc ++ ty) : tysacc+     where+      s = dropWhile isSpace s''+      (c:cs) = s'+      (ty',s') = span (\c->c/=';'&&c/=':'&&c/='\\') s+      ty = dropWhile isSpace $ reverse ty'  -- yeah yeah++  parse_delay :: String -> PatNodeAttrs -> (String, PatNodeAttrs)+  parse_delay [] as = error "\nparse_delay: unexpected end of input"+  parse_delay s'' as+--- | doDelay as     = error "\ncompilePat: delay (@) modifier given multiple times to a single node"+--- | doDelay as  = trace "\nwarning: delay (@) mod given multiple times to a single node, so summing." $ (s', as')+   | isNothing mis  = error $ "\nparse_delay: expected a digit 1-9 (not '" ++ [head s] ++ "')"+   | otherwise      = (s', as')+   where+    s = dropWhile isSpace s''+    as' = as { doDelay = True  -- (convenient to set both here)+             , delayus = delayus as + i }+    (mis, s') = parseInt s []+    is = fromJust mis+    i = read is :: Int++#if USE_PSEQ_PATNODE+  parse_pseq :: String -> PatNodeAttrs -> (String, PatNodeAttrs)+  parse_pseq s'' as+   | doPseq as  = error "\ncompilePat: pseq (>) modifier given multiple times to a single node"+   | not ok     = error "\ncompilePat: pseq permutation must cover an initial segment of abc..yz"+-- No harm in allowing it; as for testing arity mismatch, that is not+-- in the parser's purview (at least at this time).  It is easily done+-- as a post-parsing check.+--- | null perm  = error "\ncompilePat: empty pseq permutation"+   | otherwise  = (s', as')+   where+    s = dropWhile isSpace s''+    as' = as { doPseq = True  -- (convenient to set both here)+             , pseqPerm = Just $ map (\c -> ord c - ord 'a') perm }+    (perm, s') = span isLower s+    ok = sort perm == take (length perm) ['a'..'z']+#endif++-------------------------------------------------------------------------------++  -- XXX Doing this to ensure issuance of all warning messages+  -- pertaining to the pattern to be compiled!+  -- Which isn't quite working?!?.... [Never did resolve this.]+  compilePat :: String -> Pattern+#if NFDATA_INSTANCE_PATTERN+  compilePat s = force $ compilePat_ s+--compilePat s = let pat = force $! compilePat_ s in trace (show pat) $! pat+--compilePat s = let pat = force $ compilePat_ s in trace (show pat) $! pat+--compilePat s = let !pat = force $ compilePat_ s in trace (show pat) $ pat+--compilePat s = let pat = force $ compilePat_ s in trace (show pat) $ pat+#else+  compilePat = compilePat_+#endif++  compilePat_ :: String -> Pattern+  compilePat_ str = compilePat' str++-------------------------------------------------------------------------------++  -- | Inverse of 'compilePat'.+  --+  -- @showPat . compilePat patstring  =  patstring@+  --+  -- (up to optional whitespace, and canonical ordering of any attributes),+  -- provided that @compilePat patstring@ succeeds.+{--}+  -- /(And, only up to subpatterns elided from # ('WI' or 'TI') or from * ('WW', 'WN', 'TW', or 'TN') nodes, in case these are still accepted by the parser!)/++  showPat :: Pattern -> String+  showPat (Node pas chs)++    | doDelay  as  = "@" ++ show (delayus as)+                         ++ let as' = as { doDelay = False }+                            in showPat (Node (setPatNodeAttrs pas as') chs)+#if USE_PAR_PATNODE+    | doSpark  as  = "=" ++ let as' = as { doSpark = False }+                            in showPat (Node (setPatNodeAttrs pas as') chs)+#endif+#if USE_PSEQ_PATNODE+    | doPseq   as  = ">" ++ showPerm (pseqPerm as)+                         ++ let as' = as { doPseq  = False }+                            in showPat (Node (setPatNodeAttrs pas as') chs)+#endif+#if USE_TRACE_PATNODE+    | doTrace  as  = "+" ++ let as' = as { doTrace = False }+                            in showPat (Node (setPatNodeAttrs pas as') chs)+#endif+#if USE_PING_PATNODE+    | doPing   as  = "^" ++ let as' = as { doPing  = False }+                            in showPat (Node (setPatNodeAttrs pas as') chs)+#endif+#if USE_DIE_PATNODE+    | doDie    as  = "/" ++ let as' = as { doDie   = False }+                            in showPat (Node (setPatNodeAttrs pas as') chs)+#endif+#if USE_TIMING_PATNODE+    | doTiming as  = "%" ++ let as' = as { doTiming   = False }+                            in showPat (Node (setPatNodeAttrs pas as') chs)+#endif+    | doConstrainType as+       =+--       trace "showPat-doConstraintType HERE!" $+         ":" ++ treps_str+             ++ let as' = as { doConstrainType = False }+                in showPat (Node (setPatNodeAttrs pas as') chs)++#if ABBREV_WN_AND_TN_CONCRETE_SYNTAX_TO_SINGLE_DIGIT__CAN_ONLY_EXPRESS_DOWN_TO_DEPTH_9+    | WI{} <- pas  = "0"   ++ descend chs+#else+    | WI{} <- pas  = "."   ++ descend chs+#endif+    | WR{} <- pas  = ""    ++ descend chs ++ perhapsEmptySubpatterns+#if ABBREV_WN_AND_TN_CONCRETE_SYNTAX_TO_SINGLE_DIGIT__CAN_ONLY_EXPRESS_DOWN_TO_DEPTH_9+    | WS{} <- pas  = "1"   ++ descend chs+#else+    | WS{} <- pas  = "!"   ++ descend chs+#endif+#if ABBREV_WN_AND_TN_CONCRETE_SYNTAX_TO_NUMBER_ALONE__SAFE_ONLY_TO_DEPTH_19 || ABBREV_WN_AND_TN_CONCRETE_SYNTAX_TO_SINGLE_DIGIT__CAN_ONLY_EXPRESS_DOWN_TO_DEPTH_9+    | WN{} <- pas  =          show n ++ descend chs+#else+    | WN{} <- pas  = "*"   ++ show n ++ descend chs+#endif+#if USE_WW_DEEPSEQ+    | WW{} <- pas  = "*"   ++ descend chs+#endif++#if ABBREV_WN_AND_TN_CONCRETE_SYNTAX_TO_SINGLE_DIGIT__CAN_ONLY_EXPRESS_DOWN_TO_DEPTH_9+    | TI{} <- pas  = "0"   ++ descend chs+#else+    | TI{} <- pas  = "."   ++ descend chs+#endif+    | TR{} <- pas  = ""    ++ descend chs ++ perhapsEmptySubpatterns+--- #if ABBREV_WN_AND_TN_CONCRETE_SYNTAX_TO_SINGLE_DIGIT__CAN_ONLY_EXPRESS_DOWN_TO_DEPTH_9+---     | TS{} <- pas  = "1"   ++ descend chs+--- #else+---     | TS{} <- pas  = "!"   ++ descend chs+--- #endif+#if ABBREV_WN_AND_TN_CONCRETE_SYNTAX_TO_NUMBER_ALONE__SAFE_ONLY_TO_DEPTH_19 || ABBREV_WN_AND_TN_CONCRETE_SYNTAX_TO_SINGLE_DIGIT__CAN_ONLY_EXPRESS_DOWN_TO_DEPTH_9+    | TN{} <- pas  =          show n ++ descend chs+#else+    | TN{} <- pas  = "*"   ++ show n ++ descend chs+#endif+#if USE_WW_DEEPSEQ+    | TW{} <- pas  = "*"   ++ descend chs+#endif++   where+#if USE_CURLY_BRACE_INSTEAD_OF_PAREN_FOR_SUBPATTERNS+    emptySubpatterns = "{}"+#else+    emptySubpatterns = "()"+#endif+    perhapsEmptySubpatterns = if null chs then emptySubpatterns else ""+    as = getPatNodeAttrs pas+    n = depth as+    treps = typeConstraints as+    treps_str = intercalate ";" treps ++ ":"++  descend :: [Pattern] -> String+  descend chs+   | null chs = ""+#if USE_CURLY_BRACE_INSTEAD_OF_PAREN_FOR_SUBPATTERNS+   | otherwise = "{" ++ concatMap showPat chs ++ "}"+#else+   | otherwise = "(" ++ concatMap showPat chs ++ ")"+#endif++-------------------------------------------------------------------------------++  parseInt :: String -> String -> ( Maybe String, String )+  parseInt [] acc = ( if null acc then Nothing else Just acc , "" )+  parseInt s@(c:cs) acc+-- These should be safe cutoffs without having to worry about exact figures.+--- DEPTH_USES_INT64 isn't implemented yet, this is just a note+--- for future consideration. (Should be in NFDataN if anywhere...).+--- I'm not ready to make this sweeping change yet.+--- #if DEPTH_USES_INT64+---    | length acc > 19  = error $ "compilePat: * followed by too many (>19) digits"+--- #else+   | length acc > 9  = error $ "compilePat: * followed by too many (>9) digits"+--- #endif+   | isDigit c        = parseInt cs (acc++[c])+   | otherwise        = ( if null acc then Nothing else Just acc , s )++-------------------------------------------------------------------------------++  -- | Using String instead of TypeRep since I wasn't sure+  -- how to avoid mandatory recursion to complete the latter.+  -- (Probably it can be done -- ':~:' perhaps -- but I was+  -- unsure and this is working for the moment.)+  compileTypeReps :: String -> ([String], String)+--compileTypeReps :: String -> ([TypeRep], String)+  compileTypeReps cs = (treps,cs')+   where+    (tnames, cs') = parseTyNames cs+    parseTyNames :: String -> ([String], String)+    parseTyNames s = (sps', s')+     where+      sps' = map (dropWhile pstop) sps+--    !_ = trace ("(sps,s') = " ++ show (sps,s')) ()+      (sps,s') = splitPred psplit pstop s+--    (sps,s') = splitPred p s+      pstop x = x == '{' || x == '}'+--    pstop x = x == '{'+      psplit x = x == ' ' || pstop x+--    p x = x == ' ' || x == '{'+--    p x = not $ isAlphaNum x || x == '_' || x == '\''+#if 1+-- XXX In consideration of the recursion problem with mkTyConApp below,+-- try to use typeOf instead -- but, this won't work! Because we are+-- starting with a String encoding the ...+-- ... or will it? We have to compare two strings; one comes from+-- the user-supplied pattern string we're parsing; the other? We+-- are not "comparing equality" here, it will be done later; we're+-- only compiling a pattern...  So if the treps remain strings+-- in a Pattern, until we're ready to make comparisons; it's+-- inefficient unfortunately, but I feel this will work.+--   More detail: B/c when it comes time to match the pattern,+-- you DO have a concrete value (of some type); it is THEN that+-- you apply (show . typeRepTyCon . typeOf) to it, and then+-- make your Eq String comparison. [This can be optimised later;+-- I'm concerned now with a proof-of-concept, without TH.]+    treps = tnames+#else+    treps = map mktrep tnames+-- XXX You need the recursion for (==) to work; that may not mean+-- we can't use it, but will need some form of pattern-matching,+-- as full equality is going to be disfunctional. (B/c user would+-- have to specify the fully-recursive pattern [when they want to+-- use wildcards or stop nodes down there] -- totally ridiculous.)+--   This could be what :~: is for? (It's recursive, but you perhaps+-- can use in patterns without going full depth?)+-- mkTyConApp (mkTyCon3 "base" "Data.Either" "Either") [typeRep (Proxy::Proxy Bool), typeRep (Proxy::Proxy Int)] == typeRep (Proxy :: Proxy (Either Bool Int))+    mktrep :: String -> TypeRep+    mktrep tname = trep+     where+      tcon = mkTyCon3 "" "" tname+      trep = mkTyConApp tcon []+--mkTyCon3 :: 3xString -> TypeCon+--mkTyConApp :: TyCon -> [TypeRep] -> TypeRep+#endif++-------------------------------------------------------------------------------++  -- Split on the psplit predicate, stop consuming the list+  -- on the pstop predicate.+  splitPred :: (a -> Bool) -> (a -> Bool) -> [a] -> ([[a]], [a])+  splitPred psplit pstop list = splitPred' psplit pstop list []+  splitPred' :: (a -> Bool) -> (a -> Bool) -> [a] -> [[a]] -> ([[a]], [a])+  splitPred' psplit pstop list acc+   | null first  = {-trace "-1-" $-} (acc, rest)+   | null rest   = {-trace "-2-" $-} (acc', [])  -- or (acc, rest), obv.+   | pstop h     = {-trace "-3-" $-} (acc', rest)+   | otherwise   = {-trace "-4-" $-} splitPred' psplit pstop t acc'+   where+    (first,rest) = break psplit list+    (h:t) = rest+    acc' = acc ++ [first]  ------------------------------------------------------------------------------- 
− src/Control/DeepSeq/Bounded/Compile_new_grammar.hs
@@ -1,249 +0,0 @@-----------------------------------------------------------------------------------  {-  LANGUAGE CPP #-}--#define DO_TRACE 0--#if ABBREV_WN_AND_TN_CONCRETE_SYNTAX_TO_NUMBER_ALONE__SAFE_ONLY_TO_DEPTH_19 && ABBREV_WN_AND_TN_CONCRETE_SYNTAX_TO_SINGLE_DIGIT__CAN_ONLY_EXPRESS_DOWN_TO_DEPTH_9-#error Please set at most one of the flags ABBREV_WN_AND_TN_CONCRETE_SYNTAX_TO_NUMBER_ALONE__SAFE_ONLY_TO_DEPTH_19 and ABBREV_WN_AND_TN_CONCRETE_SYNTAX_TO_SINGLE_DIGIT__CAN_ONLY_EXPRESS_DOWN_TO_DEPTH_9 to True.-#endif------------------------------------------------------------------------------------- |--- Module      :  Control.DeepSeq.Bounded.Compile_new_grammar--- Copyright   :  Andrew G. Seniuk 2014-2015--- License     :  BSD-style (see the file LICENSE)------ Maintainer  :  Andrew Seniuk <rasfar@gmail.com>--- Stability   :  provisional--- Portability :  portable (H98)--------------------------------------------------------------------------------------  module Control.DeepSeq.Bounded.Compile_new_grammar-  (--      compilePat'  ,--  )-  where-----------------------------------------------------------------------------------  import Control.DeepSeq.Bounded.Pattern--  import Control.DeepSeq.Bounded.Compile_shared_utils--  import Data.Maybe ( isNothing, fromJust )--  import Data.List ( intercalate )--  import Debug.Trace ( trace )--  import Control.DeepSeq.Bounded.PatUtil ( liftPats )-  import Data.Char ( isSpace )-  import Data.Char ( isLower )-  import Data.List ( sort )-  import Data.Char ( ord )-  import Data.Maybe ( isJust )-----------------------------------------------------------------------------------#if DO_TRACE-  mytrace = trace-#else-  mytrace _ = id-#endif--  -- XXX This is still lacks support for the two condensed grammars:-  -- ABBREV_WN_AND_TN_CONCRETE_SYNTAX_TO_NUMBER_ALONE__SAFE_ONLY_TO_DEPTH_19-  -- ABBREV_WN_AND_TN_CONCRETE_SYNTAX_TO_SINGLE_DIGIT__CAN_ONLY_EXPRESS_DOWN_TO_DEPTH_9--  compilePat' :: String -> Pattern-  compilePat' s-   | not $ null s'  = error $ "\ncompilePat: input rejected: "-                       ++ s-                       ++ if isNothing mmsg then "" else "\nParser message: "-                       ++ fromJust mmsg-                       ++ "\nPatterns parsed so far: ["-                       ++ intercalate ", " (map show pats)-                       ++ "]"-   | otherwise      = case pats of-       [] -> error $ "\ncompilePat: "-              ++ if null s then "empty input" else "vacuous input"-       [pat] -> setPatternPatNodeUniqueIDs 0 pat-       pats -> setPatternPatNodeUniqueIDs 0 $ liftPats pats-   where (pats, mmsg, s') = compilePats s []--  -- String in last component of result is unconsumed input.--  compilePats :: String -> [Pattern] -> ([Pattern], Maybe String, String)-  compilePats s acc-   | null s_ltrim  = (reverse acc, Nothing, s_ltrim)-   | otherwise     = case cpat s of-      (Left "", s') -> (reverse acc, Nothing, s')---    (Left "", s') -> compilePats s' acc-      (Left msg, s') -> (reverse acc, Just msg, s')-      (Right pat, s') -> compilePats s' (pat:acc)-   where s_ltrim = dropWhile isSpace s---- XXX Don't forget to do a post-pass to change W* nodes--- to corresponding T* nodes, when : modifier was present!--- Oops, guess I did it here; but the original idea would--- be less cloning...--  cpat :: String -> (Either String Pattern, String)---cpat _ | trace "J-1: " $ False  = undefined-  cpat [] = (Left "unexpected end of input", [])---cpat s | trace ("J-2: "++show s) $ False  = undefined-  cpat s-   | null s''   = error "\ncompilePat: type constraint must precede a pattern node"-   | isW        = case c of-      '.' -> (Right $ Node (WI as) [], cs)-      '!' -> (Right $ Node (WS as) [], cs)-      '*' -> case parseInt cs [] of-               (Nothing, cs'') -> (Right $ Node (WW   as    ) [], cs'')-               (Just is, cs'') -> (Right $ Node (WN $ asn is) [], cs'')-      '(' -> if isNothing mmsg_subpats-             then (Right $ Node (WR as) subpats, cs_subpats)-             else (Left $ fromJust mmsg_subpats, cs_subpats)-      ')' -> (Left "", cs)-      c -> error $ "\ncompilePat: unexpected character '" ++ [c] ++ "'"-   | otherwise  = case c of-      '.' -> (Right $ Node (TI as) [], cs)---    '!' -> (Right $ Node (TS as) [], cs)-      '*' -> case parseInt cs [] of-               (Nothing, cs'') -> (Right $ Node (TW   as    ) [], cs'')-               (Just is, cs'') -> (Right $ Node (TN $ asn is) [], cs'')-      '(' -> if isNothing mmsg_subpats-             then (Right $ Node (TR as) subpats, cs_subpats)-             else (Left $ fromJust mmsg_subpats, cs_subpats)-      ')' -> (Left "", cs)-      c -> error $ "\ncompilePat: unexpected character '" ++ [c] ++ "'"-   where-    s' = dropWhile isSpace s-    (c:cs) = s''-    (as_mods, mmsg_mods, s'') = cmods s'  -- collect any prefix modifiers-    as = case mmsg_mods of-           Nothing -> as_mods-           Just msg -> error $ "\ncompilePat: " ++ msg-    asn is = as { depth = read is :: Int }-    isW = not $ doConstrainType as-    (subpats, mmsg_subpats, cs_subpats) = compilePats cs []--  -- Accumulate any prefix modifiers into an empty PatNodeAttrs structure.-  cmods :: String -> (PatNodeAttrs, Maybe String, String)-  cmods s = cmods' s emptyPatNodeAttrs-  cmods' :: String -> PatNodeAttrs -> (PatNodeAttrs, Maybe String, String)-  cmods' [] as = (as, Nothing, [])---cmods' [] as = (as, Just "cmods': unexpected end of input", [])-  cmods' s as = case c of-    ':' -> cmods' cs_types  as_types-    '@' -> cmods' cs_delay  as_delay-#if USE_PAR_PATNODE-    '=' -> cmods' cs_par    as_par-#endif-#if USE_PSEQ_PATNODE-    '>' -> cmods' cs_pseq   as_pseq-#endif-#if USE_TRACE_PATNODE-    '+' -> cmods' cs_trace  as_trace-#endif-#if USE_PING_PATNODE-    '^' -> cmods' cs_ping   as_ping-#endif-#if USE_DIE_PATNODE-    '/' -> cmods' cs_die    as_die-#endif-#if USE_TIMING_PATNODE-    '%' -> cmods' cs_timing as_timing-#endif-    _ -> (as, Nothing, s)-   where-    s'@(c:cs) = dropWhile isSpace s-    ( cs_types  , as_types  ) = parse_type_constraints          cs as-    ( cs_delay  , as_delay  ) = parse_delay                     cs as-#if USE_PAR_PATNODE-    ( cs_par    , as_par    ) = ( cs, as { doSpark  = True } )-#endif-#if USE_PSEQ_PATNODE-    ( cs_pseq   , as_pseq   ) = parse_pseq                      cs as-#endif-#if USE_TRACE_PATNODE-    ( cs_trace  , as_trace  ) = ( cs, as { doTrace  = True } )-#endif-#if USE_PING_PATNODE-    ( cs_ping   , as_ping   ) = ( cs, as { doPing   = True } )-#endif-#if USE_DIE_PATNODE-    ( cs_die    , as_die    ) = ( cs, as { doDie    = True } )-#endif-#if USE_TIMING_PATNODE-    ( cs_timing , as_timing ) = ( cs, as { doTiming = True } )-#endif--  parse_type_constraints :: String -> PatNodeAttrs -> (String, PatNodeAttrs)-  parse_type_constraints s'' as---- | doConstrainType as  = trace "\nwarning: type constraints (:...:) mod given multiple times to a single node, so aggregating type lists." $ (s', as')-   | otherwise           = (s', as')-   where-    s = dropWhile isSpace s''-    as' = as { doConstrainType = True-             , typeConstraints = typeConstraints as ++ tys }-    (tys, s') = f s "" []-    -- Take up to the next ';', ':', or '\\' and deal.-    f :: String -> String -> [String] -> ([String],String)-    f s'' tyacc tysacc-     | null s'    = error "\ncompilePat: type constraint list not ':'-terminated"-     | '\\' == c  = if null cs-                    then f cs (c:tyacc) tysacc-                    else if ':' == head cs    -- note ty is already reversed-                         then f (tail cs) ((':':'\\':ty) ++ tyacc) tysacc-                         else f cs (('\\':ty) ++ tyacc) tysacc-     | ':' == c   = ( reverse $ (reverse $ tyacc ++ ty) : tysacc , dropWhile isSpace cs )-    -- otherwise ';' == c-     | otherwise  = f cs "" $ (reverse $ tyacc ++ ty) : tysacc-     where-      s = dropWhile isSpace s''-      (c:cs) = s'-      (ty',s') = span (\c->c/=';'&&c/=':'&&c/='\\') s-      ty = dropWhile isSpace $ reverse ty'  -- yeah yeah--  parse_delay :: String -> PatNodeAttrs -> (String, PatNodeAttrs)-  parse_delay [] as = error "\nparse_delay: unexpected end of input"-  parse_delay s'' as---- | doDelay as     = error "\ncompilePat: delay (@) modifier given multiple times to a single node"---- | doDelay as  = trace "\nwarning: delay (@) mod given multiple times to a single node, so summing." $ (s', as')-   | isNothing mis  = error $ "\nparse_delay: expected a digit 1-9 (not '" ++ [head s] ++ "')"-   | otherwise      = (s', as')-   where-    s = dropWhile isSpace s''-    as' = as { doDelay = True  -- (convenient to set both here)-             , delayus = delayus as + i }-    (mis, s') = parseInt s []-    is = fromJust mis-    i = read is :: Int--#if USE_PSEQ_PATNODE-  parse_pseq :: String -> PatNodeAttrs -> (String, PatNodeAttrs)-  parse_pseq s'' as-   | doPseq as  = error "\ncompilePat: pseq (>) modifier given multiple times to a single node"-   | not ok     = error "\ncompilePat: pseq permutation must cover an initial segment of abc..yz"--- No harm in allowing it; as for testing arity mismatch, that is not--- in the parser's purview (at least at this time).  It is easily done--- as a post-parsing check.---- | null perm  = error "\ncompilePat: empty pseq permutation"-   | otherwise  = (s', as')-   where-    s = dropWhile isSpace s''-    as' = as { doPseq = True  -- (convenient to set both here)-             , pseqPerm = Just $ map (\c -> ord c - ord 'a') perm }-    (perm, s') = span isLower s-    ok = sort perm == take (length perm) ['a'..'z']-#endif----------------------------------------------------------------------------------
− src/Control/DeepSeq/Bounded/Compile_old_grammar.hs
@@ -1,260 +0,0 @@-----------------------------------------------------------------------------------  {-  LANGUAGE CPP #-}--#define DO_TRACE 0--#define WARN_IGNORED_SUBPATTERNS 1-#define NEVER_IGNORE_SUBPATTERNS 0---- Formerly DEBUG_WITH_DEEPSEQ_GENERICS.--- Now also needed to force issuance of all compilePat warnings--- (so not strictly a debugging flag anymore).--- [Except it didn't work...]---- #define NFDATA_INSTANCE_PATTERN 0  -- now a .cabal flag--#define DO_DERIVE_DATA_AND_TYPEABLE 0-#define DO_DERIVE_ONLY_TYPEABLE 1-#if DO_DERIVE_ONLY_TYPEABLE && DO_DERIVE_DATA_AND_TYPEABLE-#undef DO_DERIVE_ONLY_TYPEABLE-#warning DO_DERIVE_ONLY_TYPEABLE forced 0, due to DO_DERIVE_DATA_AND_TYPEABLE being 1.-#define DO_DERIVE_ONLY_TYPEABLE 0-#endif---- Now specified via --flag=[-]USE_WWW_DEEPSEQ---- #define USE_WW_DEEPSEQ 1-----------------------------------------------------------------------------------#if DO_DERIVE_DATA_AND_TYPEABLE-  {-# LANGUAGE DeriveDataTypeable #-}-#endif--- XXX Only needed for something in Blah.hs.--- Check into it, and see if can't get rid of the need--- for Typeable instances in here!-#if DO_DERIVE_ONLY_TYPEABLE-  {-# LANGUAGE DeriveDataTypeable #-}-#endif-#if NFDATA_INSTANCE_PATTERN-  -- For testing only (controlling trace interleaving):-  {-# LANGUAGE DeriveGeneric #-}-#endif-  {-  LANGUAGE DeriveFunctor #-}------------------------------------------------------------------------------------- |--- Module      :  Control.DeepSeq.Bounded.Compile_old_grammar--- Copyright   :  Andrew G. Seniuk 2014-2015--- License     :  BSD-style (see the file LICENSE)------ Maintainer  :  Andrew Seniuk <rasfar@gmail.com>--- Stability   :  experimental, deprecated--- Portability :  portable--------------------------------------------------------------------------------------  module Control.DeepSeq.Bounded.Compile_old_grammar---- {-# DEPRECATED "Use Wobble instead" #-}-  (--      compilePat'--  )-  where-----------------------------------------------------------------------------------  import Control.DeepSeq.Bounded.Pattern-  import Control.DeepSeq.Bounded.Compile_shared_utils--  import Data.Maybe ( isNothing, fromJust )-  import Data.Maybe ( isJust )--  import Debug.Trace ( trace )-----------------------------------------------------------------------------------#if DO_TRACE-  mytrace = trace-#else-  mytrace _ = id-#endif-----------------------------------------------------------------------------------  -- compilePat' parameters:-  --  spark    - the next node parsed will, when matched, spark parallel-  --             evaluation of its subpatterns-  --  mpn      - says what the last PatNode parsed was (list args are empty)-  --           - what do I mean "list args are empty"?-  --              - oh: T* nodes have a list arg-  --           - I see that mpn is never used (except in some dead code)...-  --  mn       - says what n is for rnfn (eg. 3 for "*3")-  --           - note that, when Just, this signals to parser that * is for-  --             a WN/TN node rather than a WW/TW node-  --  (t:ts)   - the list of type constraints (currently, constructor names)-  --           - list must be empty iff node is a T* node-  --  mptc     - Just pre-constraint character (Nothing is not possible)-  --  (c:cs)   - is what's left of the input string we're parsing-  --  acc      - is an accumulator parameter, collecting patterns parsed-  compilePat' :: Bool -> Maybe PatNode -> Maybe Int -> [String] -> Maybe Char -> String -> [Pattern] -> ([Pattern], String)-  -- This first binding in the compilePat' group is only for-  -- some error trapping (only matches in case of parse errors).-  compilePat' spark mpn mn (t:ts) (Just c) cs _--- XXX Now we need to allow there to be /no/ pre-treps char...-#if 1-   | not $ c `elem` ".*#"  = error $ "compilePat: parse error: pre-treps pattern char " ++ show c ++ " not one of .*#"-#else-   -- ?? it /seems/ okay without the '{'; not sure why it was included...---- | not $ c `elem` "{"  = error $ "compilePat: parse error: pre-treps pattern char " ++ show c ++ " not '{'"-   | not $ c `elem` "{.*#"  = error $ "compilePat: parse error: pre-treps pattern char " ++ show c ++ " not one of {.*#"-#endif-  compilePat' spark mpn mn _  mptc [] acc = mytrace "EMPTY" $ (acc, [])---compilePat' spark mpn mn [] mptc [] acc = mytrace "EMPTY" $ (acc, [])-  compilePat' spark mpn mn [] mptc (' ':cs) acc = mytrace "space" $ compilePat' spark mpn mn [] mptc cs acc-  compilePat' spark mpn mn [] mptc ('}':'{':cs) acc = error $ "compilePat: opening brace cannot follow closing brace"-  compilePat' spark mpn mn [] mptc ('}':cs) acc-#if 0-        -- Lenient parser tolerates subpatterns of these.-        -- (The semantics is that any such subpatterns are ignored ---        -- discarded with a warning.)-#if USE_WW_DEEPSEQ-   | isJust mpn, Just WW <- mpn  = trace "compilePat-\"}\": warning: * with subpattern" $ mytrace "}" $ (acc, cs)-#endif-   | isJust mpn, Just WI <- mpn  = trace "compilePat-\"}\": warning: # with subpattern" $ mytrace "}" $ (acc, cs)-#endif-   | otherwise  = mytrace "}" $ (acc, cs)-  compilePat' spark mpn mn [] mptc (c:':':cs) acc-   | null treps  = error $ "compilePat: colon must be followed by at least one type name"-   | otherwise   = compilePat' spark mpn mn treps (Just c) cs' acc-   where---  !_ = trace ("Boo: " ++ show (treps, cs')) ()-    (treps, cs') = compileTypeReps cs-  compilePat' spark mpn Nothing [] mptc ('@':cs) acc-   | isNothing mn  = error $ "compilePat: internal error @2 (please report this bug!)"-   | otherwise     = compilePat' spark mpn mn [] mptc ('@':cs') acc  -- mn is Just n-   where---  !_ = trace ("Boo: " ++ show (mn, cs')) ()-    (mn_, cs') = parseInt cs ""-    mn | isNothing mn_  = Nothing-       | otherwise      = Just ( read (fromJust mn_) :: Int )-  compilePat' spark mpn (Just n) [] mptc ('@':cs) acc-   = compilePat' False mpn Nothing [] mptc cs (acc++[node])-#if PARALLELISM_EXPERIMENT-    where node | spark      = Node (PN n) []-               | otherwise  = Node (WN n) []-#else-    where node = Node (WN n) []-#endif-  compilePat' spark mpn (Just n) [] mptc (c:cs) acc-   = error $ "compilePat: internal error @1(" ++ [c] ++ ") (please report this bug!)"-  compilePat' spark mpn mn [] mptc (c:'{':cs) acc = compilePat' spark mpn mn [] mptc cs' (acc++[node])-   where-    (chs, cs') = mytrace (".{-cs="++cs) $ compilePat' spark mpn mn [] mptc cs []-    node = case c of-        '.' -> mytrace (".{-recurs: "++show chs) $ Node WR chs-        -- Lenient parser tolerates subpatterns of these.-        -- (The semantics is that any such subpatterns are ignored ---        -- discarded with a warning.)--- It's more convenient to keep the subpatterns, if want to issue--- a warning when they don't match for type-constrained patterns.--- True the semantics is the same except for the warning message,--- but, well, I want to see it at the moment!-#if NEVER_IGNORE_SUBPATTERNS-#if ! WARN_IGNORED_SUBPATTERNS-#if USE_WW_DEEPSEQ-        '*' -> Node WW chs-#endif-        '#' -> Node WI chs-#else-#if USE_WW_DEEPSEQ-        '*' -> trace "compilePat-\"{\": warning: * with subpattern" $ Node WW chs-#endif-        '#' -> trace "compilePat-\"{\": warning: # with subpattern" $ Node WI chs-#endif-#else-#if ! WARN_IGNORED_SUBPATTERNS-#if USE_WW_DEEPSEQ-        '*' -> Node WW []-#endif-        '#' -> Node WI []-#else-#if USE_WW_DEEPSEQ-        '*' -> trace "compilePat-\"{\": warning: * with subpattern" $ Node WW []-#endif-        -- Yes, we do see the error for each test we expect a warning from!---      '#' -> error "compilePat-\"{\": warning: # with subpattern"---      '#' -> force $! trace "compilePat-\"{\": warning: # with subpattern" $! Node WI []-        '#' -> trace "compilePat-\"{\": warning: # with subpattern" $ Node WI []-#endif-#endif-        _ -> error $ "compilePat-\"{\": unexpected " ++ show c ++ " (cs'=" ++ cs'-  compilePat' spark mpn mn treps mptc ('{':cs) acc = compilePat' spark mpn mn [] mptc cs' (acc++[node])-   where-    (chs, cs') = mytrace ("T-{-cs="++cs) $ compilePat' spark mpn mn [] mptc cs []-    node-     | isJust mptc  = let c = fromJust mptc in case c of-        '.' -> mytrace ("T-{-recurs: "++show chs) $ Node (TR treps) chs-#if NEVER_IGNORE_SUBPATTERNS-#if ! WARN_IGNORED_SUBPATTERNS-#if USE_WW_DEEPSEQ-        '*' -> Node (TW treps) chs-#endif-        '#' -> Node (TI treps) chs-#else-#if USE_WW_DEEPSEQ-        '*' -> trace "compilePat-T-\"{\": warning: * with subpattern" $ Node (TW treps) chs-#endif-        '#' -> trace "compilePat-T-\"{\": warning: # with subpattern" $ Node (TI treps) chs-#endif-#else-#if ! WARN_IGNORED_SUBPATTERNS-#if USE_WW_DEEPSEQ-        '*' -> Node (TW treps) []-#endif-        '#' -> Node (TI treps) []-#else-#if USE_WW_DEEPSEQ-        '*' -> trace "compilePat-T-\"{\": warning: * with subpattern" $ Node (TW treps) []-#endif-        '#' -> trace "compilePat-T-\"{\": warning: # with subpattern" $ Node (TI treps) []-#endif-#endif-        _ -> error $ "compilePat-T-\"{\": unexpected " ++ show c ++ " (cs'=" ++ cs'-     | otherwise = error $ "T-{-recurs-OLDGRAM: "++show chs-#if PARALLELISM_EXPERIMENT-  compilePat' spark mpn mn treps mptc ('=':cs) acc = compilePat' True mpn mn treps mptc cs acc-#endif-  compilePat' spark mpn mn treps mptc (c:cs) acc = compilePat' False mpn mn [] mptc cs (acc++[node])---compilePat' spark mpn mn treps mptc (c:cs) acc = compilePat' False mpn mn [] mptc cs $ force (acc++[node])-   where-    node-#if PARALLELISM_EXPERIMENT-     | spark = case c of-        '.' -> mytrace ".:cs" $ Node PR []-#if USE_WW_DEEPSEQ-        '*' -> mytrace "*:cs" $ Node PW []-#endif-        _ -> error $ "compilePat-\"c:cs\"-spark: unexpected " ++ show c ++ " (cs=" ++ cs-#endif-     | null treps = case c of-        '.' -> mytrace ".:cs" $ Node WS []  -- sic!-#if USE_WW_DEEPSEQ-        '*' -> mytrace "*:cs" $ Node WW []-#endif-        '#' -> mytrace "#:cs" $ Node WI []-        _ -> error $ "compilePat-\"c:cs\": unexpected " ++ show c ++ " (cs=" ++ cs-     | otherwise = case c of-        '.' -> mytrace ".:cs" $ Node (TR treps) []---      '.' -> mytrace ".:cs" $ Node (TS treps) []-#if USE_WW_DEEPSEQ-        '*' -> mytrace "*:cs" $ Node (TW treps) []-#endif-        '#' -> mytrace "#:cs" $ Node (TI treps) []-        _ -> error $ "compilePat-T-\"c:cs\": unexpected " ++ show c ++ " (cs=" ++ cs----------------------------------------------------------------------------------
− src/Control/DeepSeq/Bounded/Compile_shared_utils.hs
@@ -1,174 +0,0 @@-----------------------------------------------------------------------------------  {-  LANGUAGE CPP #-}--#define DO_TRACE 0--#define WARN_IGNORED_SUBPATTERNS 1-#define NEVER_IGNORE_SUBPATTERNS 0---- Formerly DEBUG_WITH_DEEPSEQ_GENERICS.--- Now also needed to force issuance of all compilePat warnings--- (so not strictly a debugging flag anymore).--- [Except it didn't work...]---- #define NFDATA_INSTANCE_PATTERN 0  -- now a .cabal flag--#define DO_DERIVE_DATA_AND_TYPEABLE 0-#define DO_DERIVE_ONLY_TYPEABLE 1-#if DO_DERIVE_ONLY_TYPEABLE && DO_DERIVE_DATA_AND_TYPEABLE-#undef DO_DERIVE_ONLY_TYPEABLE-#warning DO_DERIVE_ONLY_TYPEABLE forced 0, due to DO_DERIVE_DATA_AND_TYPEABLE being 1.-#define DO_DERIVE_ONLY_TYPEABLE 0-#endif---- Now specified via --flag=[-]USE_WWW_DEEPSEQ---- #define USE_WW_DEEPSEQ 1-----------------------------------------------------------------------------------#if DO_DERIVE_DATA_AND_TYPEABLE-  {-# LANGUAGE DeriveDataTypeable #-}-#endif--- XXX Only needed for something in Blah.hs.--- Check into it, and see if can't get rid of the need--- for Typeable instances in here!-#if DO_DERIVE_ONLY_TYPEABLE-  {-# LANGUAGE DeriveDataTypeable #-}-#endif-#if NFDATA_INSTANCE_PATTERN-  -- For testing only (controlling trace interleaving):-  {-# LANGUAGE DeriveGeneric #-}-#endif-  {-  LANGUAGE DeriveFunctor #-}------------------------------------------------------------------------------------- |--- Module      :  Control.DeepSeq.Bounded.Compile_shared_utils--- Copyright   :  Andrew G. Seniuk 2014-2015--- License     :  BSD-style (see the file LICENSE)------ Maintainer  :  Andrew Seniuk <rasfar@gmail.com>--- Stability   :  provisional--- Portability :  portable--------------------------------------------------------------------------------------  module Control.DeepSeq.Bounded.Compile_shared_utils---- {-# DEPRECATED "Use Wobble instead" #-}-  (--    compileTypeReps  ,-    parseInt  ,--  )-  where-----------------------------------------------------------------------------------  import Data.Char ( isDigit )-----------------------------------------------------------------------------------#if DO_TRACE-  mytrace = trace-#else-  mytrace _ = id-#endif-----------------------------------------------------------------------------------  parseInt :: String -> String -> ( Maybe String, String )-  parseInt [] acc = ( if null acc then Nothing else Just acc , "" )-  parseInt s@(c:cs) acc--- These should be safe cutoffs without having to worry about exact figures.---- DEPTH_USES_INT64 isn't implemented yet, this is just a note---- for future consideration. (Should be in NFDataN if anywhere...).---- I'm not ready to make this sweeping change yet.---- #if DEPTH_USES_INT64----    | length acc > 19  = error $ "compilePat: * followed by too many (>19) digits"---- #else-   | length acc > 9  = error $ "compilePat: * followed by too many (>9) digits"---- #endif-   | isDigit c        = parseInt cs (acc++[c])-   | otherwise        = ( if null acc then Nothing else Just acc , s )-----------------------------------------------------------------------------------  -- | Using String instead of TypeRep since I wasn't sure-  -- how to avoid mandatory recursion to complete the latter.-  -- (Probably it can be done -- ':~:' perhaps -- but I was-  -- unsure and this is working for the moment.)-  compileTypeReps :: String -> ([String], String)---compileTypeReps :: String -> ([TypeRep], String)-  compileTypeReps cs = (treps,cs')-   where-    (tnames, cs') = parseTyNames cs-    parseTyNames :: String -> ([String], String)-    parseTyNames s = (sps', s')-     where-      sps' = map (dropWhile pstop) sps---    !_ = trace ("(sps,s') = " ++ show (sps,s')) ()-      (sps,s') = splitPred psplit pstop s---    (sps,s') = splitPred p s-      pstop x = x == '{' || x == '}'---    pstop x = x == '{'-      psplit x = x == ' ' || pstop x---    p x = x == ' ' || x == '{'---    p x = not $ isAlphaNum x || x == '_' || x == '\''-#if 1--- XXX In consideration of the recursion problem with mkTyConApp below,--- try to use typeOf instead -- but, this won't work! Because we are--- starting with a String encoding the ...--- ... or will it? We have to compare two strings; one comes from--- the user-supplied pattern string we're parsing; the other? We--- are not "comparing equality" here, it will be done later; we're--- only compiling a pattern...  So if the treps remain strings--- in a Pattern, until we're ready to make comparisons; it's--- inefficient unfortunately, but I feel this will work.---   More detail: B/c when it comes time to match the pattern,--- you DO have a concrete value (of some type); it is THEN that--- you apply (show . typeRepTyCon . typeOf) to it, and then--- make your Eq String comparison. [This can be optimised later;--- I'm concerned now with a proof-of-concept, without TH.]-    treps = tnames-#else-    treps = map mktrep tnames--- XXX You need the recursion for (==) to work; that may not mean--- we can't use it, but will need some form of pattern-matching,--- as full equality is going to be disfunctional. (B/c user would--- have to specify the fully-recursive pattern [when they want to--- use wildcards or stop nodes down there] -- totally ridiculous.)---   This could be what :~: is for? (It's recursive, but you perhaps--- can use in patterns without going full depth?)--- mkTyConApp (mkTyCon3 "base" "Data.Either" "Either") [typeRep (Proxy::Proxy Bool), typeRep (Proxy::Proxy Int)] == typeRep (Proxy :: Proxy (Either Bool Int))-    mktrep :: String -> TypeRep-    mktrep tname = trep-     where-      tcon = mkTyCon3 "" "" tname-      trep = mkTyConApp tcon []---mkTyCon3 :: 3xString -> TypeCon---mkTyConApp :: TyCon -> [TypeRep] -> TypeRep-#endif-----------------------------------------------------------------------------------  -- Split on the psplit predicate, stop consuming the list-  -- on the pstop predicate.-  splitPred :: (a -> Bool) -> (a -> Bool) -> [a] -> ([[a]], [a])-  splitPred psplit pstop list = splitPred' psplit pstop list []-  splitPred' :: (a -> Bool) -> (a -> Bool) -> [a] -> [[a]] -> ([[a]], [a])-  splitPred' psplit pstop list acc-   | null first  = {-trace "-1-" $-} (acc, rest)-   | null rest   = {-trace "-2-" $-} (acc', [])  -- or (acc, rest), obv.-   | pstop h     = {-trace "-3-" $-} (acc', rest)-   | otherwise   = {-trace "-4-" $-} splitPred' psplit pstop t acc'-   where-    (first,rest) = break psplit list-    (h:t) = rest-    acc' = acc ++ [first]----------------------------------------------------------------------------------
− src/Control/DeepSeq/Bounded/Compile_shared_utils2.hs
@@ -1,344 +0,0 @@-----------------------------------------------------------------------------------  {-  LANGUAGE CPP #-}--#define DO_TRACE 0--#define WARN_IGNORED_SUBPATTERNS 1-#define NEVER_IGNORE_SUBPATTERNS 0---- Formerly DEBUG_WITH_DEEPSEQ_GENERICS.--- Now also needed to force issuance of all compilePat warnings--- (so not strictly a debugging flag anymore).--- [Except it didn't work...]---- #define NFDATA_INSTANCE_PATTERN 0  -- now a .cabal flag--#define DO_DERIVE_DATA_AND_TYPEABLE 0-#define DO_DERIVE_ONLY_TYPEABLE 1-#if DO_DERIVE_ONLY_TYPEABLE && DO_DERIVE_DATA_AND_TYPEABLE-#undef DO_DERIVE_ONLY_TYPEABLE-#warning DO_DERIVE_ONLY_TYPEABLE forced 0, due to DO_DERIVE_DATA_AND_TYPEABLE being 1.-#define DO_DERIVE_ONLY_TYPEABLE 0-#endif---- Now specified via --flag=[-]USE_WWW_DEEPSEQ---- #define USE_WW_DEEPSEQ 1-----------------------------------------------------------------------------------#if DO_DERIVE_DATA_AND_TYPEABLE-  {-# LANGUAGE DeriveDataTypeable #-}-#endif--- XXX Only needed for something in Blah.hs.--- Check into it, and see if can't get rid of the need--- for Typeable instances in here!-#if DO_DERIVE_ONLY_TYPEABLE-  {-# LANGUAGE DeriveDataTypeable #-}-#endif-#if NFDATA_INSTANCE_PATTERN-  -- For testing only (controlling trace interleaving):-  {-# LANGUAGE DeriveGeneric #-}-#endif-  {-  LANGUAGE DeriveFunctor #-}------------------------------------------------------------------------------------- |--- Module      :  Control.DeepSeq.Bounded.Compile_shared_utils2--- Copyright   :  Andrew G. Seniuk 2014-2015--- License     :  BSD-style (see the file LICENSE)------ Maintainer  :  Andrew Seniuk <rasfar@gmail.com>--- Stability   :  provisional--- Portability :  portable--------------------------------------------------------------------------------------  module Control.DeepSeq.Bounded.Compile_shared_utils2---- {-# DEPRECATED "Use Wobble instead" #-}-  (--    compilePat  ,-    showPat  ,--  )-  where-----------------------------------------------------------------------------------  import Control.DeepSeq.Bounded.Pattern-  import Control.DeepSeq.Bounded.PatUtil ( liftPats )-  import Control.DeepSeq.Bounded.Compile_shared_utils ( parseInt )--#if 0--#if DO_DERIVE_DATA_AND_TYPEABLE-  import Data.Data ( Data )-  import Data.Typeable ( Typeable )-#elif DO_DERIVE_ONLY_TYPEABLE-  import Data.Typeable ( Typeable )-#endif--#if USE_WW_DEEPSEQ-  import Control.DeepSeq ( NFData )-#endif--#endif-  import Data.List ( intercalate )-#if 0-  import Data.Char ( isDigit )-  import Data.Maybe ( isNothing, fromJust )-  import Data.Maybe ( isJust )--#endif-  import Debug.Trace ( trace )-  -- The only uses of force in this module are for debugging purposes-  -- (including trying to get messages to be displayed in a timely-  -- manner, although that problem has not been completely solved).-  import Control.DeepSeq ( force )-#if 0-#if NFDATA_INSTANCE_PATTERN-  -- for helping trace debugging-  import qualified Control.DeepSeq.Generics as DSG-  import qualified GHC.Generics as GHC ( Generic )-#endif-#endif---- Temporary until commit to new grammar exclusively (or decide to--- really continue supporting both)...-#if NEW_IMPROVED_PATTERN_GRAMMAR-  import Control.DeepSeq.Bounded.Compile_new_grammar ( compilePat' )-#else-  import Control.DeepSeq.Bounded.Compile_old_grammar ( compilePat' )-#endif-----------------------------------------------------------------------------------#if DO_TRACE-  mytrace = trace-#else-  mytrace _ = id-#endif-----------------------------------------------------------------------------------  -- XXX Doing this to ensure issuance of all warning messages-  -- pertaining to the pattern to be compiled!-  -- Which isn't quite working?!?.... [Never did resolve this.]-  compilePat :: String -> Pattern-#if NFDATA_INSTANCE_PATTERN-  compilePat s = force $ compilePat_ s---compilePat s = let pat = force $! compilePat_ s in trace (show pat) $! pat---compilePat s = let pat = force $ compilePat_ s in trace (show pat) $! pat---compilePat s = let !pat = force $ compilePat_ s in trace (show pat) $ pat---compilePat s = let pat = force $ compilePat_ s in trace (show pat) $ pat-#else-  compilePat = compilePat_-#endif--#if NEW_IMPROVED_PATTERN_GRAMMAR--  compilePat_ :: String -> Pattern-  compilePat_ str = compilePat' str--#else--  compilePat_ :: String -> Pattern---compilePat_ :: String -> (Pattern, String)---compilePat_ s = Node WW []-  compilePat_ s-   | null plst         = error "compilePat: empty pattern (syntax error)"-   | length plst > 1   = error "compilePat: disconnected pattern (not rooted)\nPerhaps you used parentheses instead of braces?"-   | not $ null s'     = error $ "compilePat: parse error: not all input consumed\nRemaining: " ++ s'-#if 1-   | otherwise   = head plst-   where-#else--- When find the time, should add a CPP switch to enable emitting--- a warning message in these cases; but it's too common/useful to--- brutally disallow like this!...-   | WI <- p      = error "compilePat: top pattern node cannot be #"-   | TR _ <- p    = error "compilePat: top pattern node cannot be .:<qual>"-   | TN _ _ <- p  = error "compilePat: top pattern node cannot be *:<qual>"-   | TW _ <- p    = error "compilePat: top pattern node cannot be *:<qual>"-   | TI _ <- p    = error "compilePat: top pattern node cannot be #:<qual>"-   | otherwise    = hplst-   where-    hplst@(Node p _) = head plst-#endif-    (plst, s') = compilePat' False Nothing Nothing [] Nothing s_ []  -- XXX ??-    s_ = translateStarN s--  translateStarN [] = []-  translateStarN ('@':cs) = error $ "compilePat: parse error: unexpected '@'"-  translateStarN ('*':cs)-   | isNothing mn  = '*' : translateStarN cs'  -- or cs-   | otherwise     = '@' : ( fromJust mn ++ translateStarN cs' )-   where---  !_ = trace ("Boo: " ++ show (mn, cs')) ()-    (mn, cs') = parseInt cs ""-  translateStarN (c:cs) = c : translateStarN cs--#endif-----------------------------------------------------------------------------------  -- | Inverse of 'compilePat'.-  ---  -- @showPat . compilePat patstring  =  patstring@-  ---  -- (up to optional whitespace, and canonical ordering of any attributes),-  -- provided that @compilePat patstring@ succeeds.-  -- /(And, only up to subpatterns elided from # ('WI' or 'TI') or from * ('WW', 'WN', 'TW', or 'TN') nodes, in case these are still accepted by the parser!)/--#if NEW_IMPROVED_PATTERN_GRAMMAR--  showPat :: Pattern -> String-  showPat (Node pas chs)--    | doDelay  as  = "@" ++ show (delayus as)-                         ++ let as' = as { doDelay = False }-                            in showPat (Node (setPatNodeAttrs pas as') chs)-#if USE_PAR_PATNODE-    | doSpark  as  = "=" ++ let as' = as { doSpark = False }-                            in showPat (Node (setPatNodeAttrs pas as') chs)-#endif-#if USE_PSEQ_PATNODE-    | doPseq   as  = ">" ++ showPerm (pseqPerm as)-                         ++ let as' = as { doPseq  = False }-                            in showPat (Node (setPatNodeAttrs pas as') chs)-#endif-#if USE_TRACE_PATNODE-    | doTrace  as  = "+" ++ let as' = as { doTrace = False }-                            in showPat (Node (setPatNodeAttrs pas as') chs)-#endif-#if USE_PING_PATNODE-    | doPing   as  = "^" ++ let as' = as { doPing  = False }-                            in showPat (Node (setPatNodeAttrs pas as') chs)-#endif-#if USE_DIE_PATNODE-    | doDie    as  = "/" ++ let as' = as { doDie   = False }-                            in showPat (Node (setPatNodeAttrs pas as') chs)-#endif-#if USE_TIMING_PATNODE-    | doTiming as  = "%" ++ let as' = as { doTiming   = False }-                            in showPat (Node (setPatNodeAttrs pas as') chs)-#endif-    | doConstrainType as-       =---       trace "showPat-doConstraintType HERE!" $-         ":" ++ treps_str-             ++ let as' = as { doConstrainType = False }-                in showPat (Node (setPatNodeAttrs pas as') chs)--#if ABBREV_WN_AND_TN_CONCRETE_SYNTAX_TO_SINGLE_DIGIT__CAN_ONLY_EXPRESS_DOWN_TO_DEPTH_9-    | WI{} <- pas  = "0"   ++ descend chs-#else-    | WI{} <- pas  = "."   ++ descend chs-#endif-    | WR{} <- pas  = ""    ++ descend chs ++ perhapsEmptySubpatterns-#if ABBREV_WN_AND_TN_CONCRETE_SYNTAX_TO_SINGLE_DIGIT__CAN_ONLY_EXPRESS_DOWN_TO_DEPTH_9-    | WS{} <- pas  = "1"   ++ descend chs-#else-    | WS{} <- pas  = "!"   ++ descend chs-#endif-#if ABBREV_WN_AND_TN_CONCRETE_SYNTAX_TO_NUMBER_ALONE__SAFE_ONLY_TO_DEPTH_19 || ABBREV_WN_AND_TN_CONCRETE_SYNTAX_TO_SINGLE_DIGIT__CAN_ONLY_EXPRESS_DOWN_TO_DEPTH_9-    | WN{} <- pas  =          show n ++ descend chs-#else-    | WN{} <- pas  = "*"   ++ show n ++ descend chs-#endif-#if USE_WW_DEEPSEQ-    | WW{} <- pas  = "*"   ++ descend chs-#endif--#if ABBREV_WN_AND_TN_CONCRETE_SYNTAX_TO_SINGLE_DIGIT__CAN_ONLY_EXPRESS_DOWN_TO_DEPTH_9-    | TI{} <- pas  = "0"   ++ descend chs-#else-    | TI{} <- pas  = "."   ++ descend chs-#endif-    | TR{} <- pas  = ""    ++ descend chs ++ perhapsEmptySubpatterns---- #if ABBREV_WN_AND_TN_CONCRETE_SYNTAX_TO_SINGLE_DIGIT__CAN_ONLY_EXPRESS_DOWN_TO_DEPTH_9----     | TS{} <- pas  = "1"   ++ descend chs---- #else----     | TS{} <- pas  = "!"   ++ descend chs---- #endif-#if ABBREV_WN_AND_TN_CONCRETE_SYNTAX_TO_NUMBER_ALONE__SAFE_ONLY_TO_DEPTH_19 || ABBREV_WN_AND_TN_CONCRETE_SYNTAX_TO_SINGLE_DIGIT__CAN_ONLY_EXPRESS_DOWN_TO_DEPTH_9-    | TN{} <- pas  =          show n ++ descend chs-#else-    | TN{} <- pas  = "*"   ++ show n ++ descend chs-#endif-#if USE_WW_DEEPSEQ-    | TW{} <- pas  = "*"   ++ descend chs-#endif--   where-#if USE_CURLY_BRACE_INSTEAD_OF_PAREN_FOR_SUBPATTERNS-    emptySubpatterns = "{}"-#else-    emptySubpatterns = "()"-#endif-    perhapsEmptySubpatterns = if null chs then emptySubpatterns else ""-    as = getPatNodeAttrs pas-    n = depth as-    treps = typeConstraints as-    treps_str = intercalate ";" treps ++ ":"--#else---- XXX This looks to be wrong in several ways, but I'm going--- to leave it alone (it's as per 0.5.5), and focus on the--- new grammar case above.--  showPat :: Pattern -> String-  showPat (Node p chs)--    | WR         <- p  = "."  ++ descend chs ++ perhapsEmptySubpatterns-    | WS         <- p  = "."  ++ descend chs-    | WN n       <- p  = "*"  ++ show n-    | WI         <- p  = "#"  ++ descend chs-#if USE_WW_DEEPSEQ-    | WW         <- p  = "*"  ++ descend chs-#endif--#if PARALLELISM_EXPERIMENT-    | PR         <- p  = "=." ++ descend chs ++ perhapsEmptySubpatterns-    | PN n       <- p  = "=*" ++ show n ++ ":" ++ descend chs-#if USE_WW_DEEPSEQ-    | PW         <- p  = "=*"  ++ descend chs-#endif-#endif--    | TR treps   <- p  = ".:" ++ descendT treps chs ++ perhapsEmptySubpatterns-    | TI treps   <- p  = "#:" ++ descendT treps chs---- | TS treps   <- p  = ".:" ++ descendT treps chs-    | TN n treps <- p  = "*"  ++ show n ++ ":" ++ descendT treps chs-#if USE_WW_DEEPSEQ-    | TW treps   <- p  = "*:" ++ descendT treps chs-#endif-   where-#if USE_CURLY_BRACE_INSTEAD_OF_PAREN_FOR_SUBPATTERNS-    emptySubpatterns = "{}"-#else-    emptySubpatterns = "()"-#endif-    perhapsEmptySubpatterns = if null chs then emptySubpatterns else ""--  descendT :: [String] -> [Pattern] -> String-  descendT treps chs = treps_ ++ descend chs-   where treps_ = intercalate " " treps--#endif--  descend :: [Pattern] -> String-  descend chs-   | null chs = ""-#if USE_CURLY_BRACE_INSTEAD_OF_PAREN_FOR_SUBPATTERNS-   | otherwise = "{" ++ concatMap showPat chs ++ "}"-#else-   | otherwise = "(" ++ concatMap showPat chs ++ ")"-#endif----------------------------------------------------------------------------------
− src/Control/DeepSeq/Bounded/Flags.hs
@@ -1,116 +0,0 @@-----------------------------------------------------------------------------------  {-  LANGUAGE CPP #-}  -- specified in .cabal default-extensions-----------------------------------------------------------------------------------  {-  LANGUAGE BangPatterns #-}-  {-  OPTIONS_GHC -fno-warn-name-shadowing #-}------------------------------------------------------------------------------------- |--- Module      :  Control.DeepSeq.Bounded.Flags--- Copyright   :  Andrew G. Seniuk 2014-2015--- License     :  BSD-style (see the file LICENSE)------ Maintainer  :  Andrew Seniuk <rasfar@gmail.com>--- Stability   :  unstable--- Portability :  portable (CPP)------ This module exposes some of the deepseq-bounded Cabal flags,--- so reverse dependencies can check their status.-----------------------------------------------------------------------------------  module Control.DeepSeq.Bounded.Flags-  (--    -- * Transient flag while old grammar is phased out--    deepseq_bounded_flag__new_improved_pattern_grammar  ,--#if 0--    -- * Optional NFDataP features--    deepseq_bounded_flag__use_par_patnode  ,-    deepseq_bounded_flag__use_pseq_patnode  ,-    deepseq_bounded_flag__use_trace_patnode  ,-    deepseq_bounded_flag__use_ping_patnode  ,-    deepseq_bounded_flag__use_die_patnode  ,--#endif--#if 0--    -- * Quick and dirty way to get ahold of the ThreadId-    -- of the main thread, when seqaid is being used-    -- on the other side to instrument the executable-    -- we're testing, studying, optimising, whatever...--    deepseq_bounded_ioref__main_thread_id  ,--#endif--  )-  where--  import Data.IORef ( IORef, newIORef )-  import Control.Concurrent ( ThreadId )-  import System.IO.Unsafe ( unsafePerformIO )-----------------------------------------------------------------------------------#if 0--  deepseq_bounded_ioref__main_thread_id-   = unsafePerformIO $ newIORef (undefined::ThreadId)--#endif----------------------------------------------------------------------#if NEW_IMPROVED_PATTERN_GRAMMAR-  deepseq_bounded_flag__new_improved_pattern_grammar = True-#else-  deepseq_bounded_flag__new_improved_pattern_grammar = False-#endif----------------------------------------------------------------------#if 0--#if USE_PAR_PATNODE-  deepseq_bounded_flag__use_par_patnode = True-#else-  deepseq_bounded_flag__use_par_patnode = False-#endif-#if USE_PSEQ_PATNODE-  deepseq_bounded_flag__use_pseq_patnode = True-#else-  deepseq_bounded_flag__use_pseq_patnode = False-#endif-#if USE_TRACE_PATNODE-  deepseq_bounded_flag__use_trace_patnode = True-#else-  deepseq_bounded_flag__use_trace_patnode = False-#endif-#if USE_PING_PATNODE-  deepseq_bounded_flag__use_ping_patnode = True-#else-  deepseq_bounded_flag__use_ping_patnode = False-#endif-#if USE_DIE_PATNODE-  deepseq_bounded_flag__use_die_patnode = True-#else-  deepseq_bounded_flag__use_die_patnode = False-#endif--#endif------------------------------------------------------------------------------------------------------------------------------------------------------
src/Control/DeepSeq/Bounded/Generic/GNFDataP.hs view
@@ -3,8 +3,65 @@  {-  LANGUAGE CPP #-} +-- (Tracing code has mostly been removed for distribution.)+#define DO_TRACE 0+#define INCLUDE_SHOW_INSTANCES 0+ ------------------------------------------------------------------------------- +-- SOP cheat-sheet.+--+-- class SingI (Code a) => Generic a where+-- Associated Types:+--   type Code a :: [[*]]+-- Methods:+--   from :: a -> Rep a+--   to :: Rep a -> a+--+-- type Rep a = SOP I (Code a)+--+-- newtype SOP f xss = SOP (NS (NP f) xss)+--+-- data NS :: (k -> *) -> [k] -> * where+-- Constructors:+--   Z :: f x -> NS f (x : xs)	 +--   S :: NS f xs -> NS f (x : xs)	 +-- Examples:+--   Z         :: f x -> NS f (x ': xs)+--   S . Z     :: f y -> NS f (x ': y ': xs)+--   S . S . Z :: f z -> NS f (x ': y ': z ': xs)+--+-- data NP :: (k -> *) -> [k] -> * where+-- Constructors:+--   Nil :: NP f []	 +--   (:*) :: f x -> NP f xs -> NP f (x : xs) infixr 5	 +-- Examples (sic! they are correct):+--   I 'x'    :* I True  :* Nil  ::  NP I       '[ Char, Bool ]+--   K 0      :* K 1     :* Nil  ::  NP (K Int) '[ Char, Bool ]+--   Just 'x' :* Nothing :* Nil  ::  NP Maybe   '[ Char, Bool ]+--+--   > :m +Generics.SOP+--   > :m +Foo+--   > Generics.SOP.from $ G2 1 2 3+--   SOP (S (Z (I 1 :* (I 2 :* (I 3 :* Nil)))))+--   > Generics.SOP.to $ Generics.SOP.from $ G2 1 2 3 :: TG+--   G2 1 2 3++-------------------------------------------------------------------------------++  {-# LANGUAGE ScopedTypeVariables #-}+  {-# LANGUAGE DataKinds #-}+  {-# LANGUAGE TypeFamilies #-}+  {-# LANGUAGE ConstraintKinds #-}+#if __GLASGOW_HASKELL__ < 708+  {-# LANGUAGE GADTs #-}+#endif+  {-# LANGUAGE TemplateHaskell #-}++  {-# LANGUAGE BangPatterns #-}  -- only for tracing++-------------------------------------------------------------------------------+ -- | -- Module      :  Control.DeepSeq.Bounded.Generic.GNFDataP -- Copyright   :  Andrew G. Seniuk 2014-2015@@ -59,10 +116,14 @@   module Control.DeepSeq.Bounded.Generic.GNFDataP   ( -#if NEW_IMPROVED_PATTERN_GRAMMAR-    module Control.DeepSeq.Bounded.Generic.GNFDataP_new_grammar  ,-#else-    module Control.DeepSeq.Bounded.Generic.GNFDataP_old_grammar  ,+      grnfp++#if 0+      -- * "Control.DeepSeq" re-exports+    , deepseq+    , force+    , NFData ( rnf )+    , ($!!) #endif    )@@ -71,15 +132,322 @@ -------------------------------------------------------------------------------    -- for Haddock!-  import Control.DeepSeq.Bounded.NFDataP ( NFDataP )+--import Control.DeepSeq.Bounded.NFDataP ( NFDataP )    import Control.DeepSeq.Bounded.NFDataN ( NFDataN )   import Control.DeepSeq ( NFData )   import Data.Typeable ( Typeable ) -#if NEW_IMPROVED_PATTERN_GRAMMAR-  import Control.DeepSeq.Bounded.Generic.GNFDataP_new_grammar+  import Control.DeepSeq.Bounded.NFDataP ( NFDataP, rnfp )+  import Control.DeepSeq.Bounded.NFDataN (          rnfn )+  import Control.DeepSeq                 (          rnf  )++  import Control.DeepSeq.Bounded.NFDataP ( handleAttrs )++  import Control.DeepSeq.Bounded.Pattern ( Rose(..), Pattern(..) )+  import Control.DeepSeq.Bounded.Pattern ( PatNode(..), PatNodeAttrs(..) )+  import Control.DeepSeq.Bounded.Pattern ( getPatNodeAttrs )++  import Generics.SOP++#if USE_PAR_PATNODE+  import Control.Parallel ( par )+#endif+--- #warning GNFDataP USE_PSEQ_PATNODE still to do!...+#if USE_PSEQ_PATNODE+  import Control.Parallel ( pseq )+#endif++  import Data.Maybe+  import Debug.Trace ( trace )+--import System.IO.Unsafe ( unsafePerformIO )  -- for console output only++-------------------------------------------------------------------------------++#if DO_TRACE+  mytrace = trace+  mytrace' = trace #else-  import Control.DeepSeq.Bounded.Generic.GNFDataP_old_grammar+  mytrace x y = y+  mytrace' x y = y+#endif++-------------------------------------------------------------------------------++  grnfp :: forall a.+           (+             Generic a+           , HasDatatypeInfo a+--         , All Show (Map ConstructorInfo (Code a))+           , All2 NFDataP (Code a)+#if INCLUDE_SHOW_INSTANCES+           , All2 Show (Code a)+#endif+           , NFDataP a  -- NFData, NFDataN superclasses+           ) => Pattern -> a -> ()+  grnfp pat x = grnfp' dti proxy_a pat x xrep+   where+    dti = datatypeInfo proxy_a+    proxy_a = Proxy :: Proxy a+    xrep = from x++-------------------------------------------------------------------------------++  -- Show constraint is needed, but not NFData nor NFDataN.+  -- Not quite sure why, but whatever...+  grnfp' :: forall a.+            (+              Generic a+            , HasDatatypeInfo a+            , All2 NFDataP (Code a)+#if INCLUDE_SHOW_INSTANCES+            , All2 Show (Code a)+#endif+            , NFDataP a  -- NFData, NFDataN superclasses+            ) =>+                    DatatypeInfo (Code a)+                 -> Proxy a+                 -> Pattern+                 -> a+                 -> Rep a+                 -> ()+  grnfp' (ADT     _ _ cs) proxy_a pat x xrep+   = grnfpS cs         proxy_a pat x xrep+  grnfp' (Newtype _ _ c ) proxy_a pat x xrep+   = grnfpS (c :* Nil) proxy_a pat x xrep++-------------------------------------------------------------------------------++-- SOP works (here) by hitting the Z (meta)constructor for the+-- particular datatype constructor which is [inhabited].+-- i.e. This simply dials in the correct constructor.+-- Later: Looks like it does a bit more than that, now.+  grnfpS :: forall a xss.+            (+              All2 NFDataP xss+#if INCLUDE_SHOW_INSTANCES+            , All2 Show xss+#endif+            , NFDataP a  -- NFData, NFDataN superclasses+            ) =>+                    NP ConstructorInfo xss+                 -> Proxy a+                 -> Pattern+                 -> a+                 -> SOP I xss+                 -> ()++  grnfpS _ _ (Node WI{} _) _ _ = ()  -- needed!!+--grnfpS _ _ (Node WI{} _) _ (SOP (Z xs)) = ()  -- mustn't do!!+--grnfpS (m :* _) _ (Node WI{} _) _ _ = ()  -- seems not to spring the bottom++  grnfpS (m :* _) proxy_a pat@(Node pas pcs) x (SOP (Z xs))+--- | WI{} <- pas  = ()  -- too late! (SOP (Z xs)) has already forced+   | not status     = patMatchFail'' msg `seq` ()+--- | WI{} <- pas  = ()+   | handleAttrs pat x `seq` pat == Node XX []  = undefined+#if USE_PAR_PATNODE+   | doSpark as  = case pas of+       WW{} -> rnf x `par` ()+       WN{} -> rnfn n x `par` ()+       otherwise -> dorecurs+#endif+-- XXX So these TR and TI (and TW?... TN?...) also need to be up+-- in a top-level case before this one!+   | TR{} <- pas  = if elem tx treps then dorecurs else ()+#if USE_WW_DEEPSEQ+   | TI{} <- pas  = if elem tx treps then () else rnf x+   | TW{} <- pas  = if elem tx treps then rnf x else ()+#else+   | TI{} <- pas  = if elem tx treps then () else rnfn 999999 x  -- XXX thack!+#endif+--- | TI{} <- pas  = if elem tx treps then () else dorecurs+#if USE_WW_DEEPSEQ+   | WW{} <- pas  = rnf x+#endif+   | WN{} <- pas  = rnfn n x+#if USE_WW_DEEPSEQ+   | TW{} <- pas  = if elem tx treps then rnf x else ()  -- no better!+#endif+   | otherwise    = dorecurs+   where+    as = getPatNodeAttrs pas+    treps = typeConstraints as+    n = depth as+    (status,mmsg)  = grnfpP_validate True pas pcs tx xs+    !_ = mytrace ("*** "++tx) $ ()+    tx | (Constructor n) <- m  = n+       | (Infix n _ _) <- m    = n+       | (Record n _) <- m     = n+    !_ = mytrace ("VVV "++show status) $ ()+    msg = fromJust mmsg+#if USE_PAR_PATNODE+#if DO_TRACE+    dorecurs | doSpark as  = grnfpP_ m () True pas pcs xs `par` ()+             | otherwise   = grnfpP_ m () True pas pcs xs `seq` ()+#else+    dorecurs | doSpark as  = grnfpP m () True pas pcs xs `par` ()+             | otherwise   = grnfpP m () True pas pcs xs `seq` ()+#endif+#else+#if DO_TRACE+    dorecurs = grnfpP_ m () True p pcs xs `seq` ()+#else+    dorecurs = grnfpP m () True p pcs xs `seq` ()+#endif+#endif++  grnfpS (m :* ms) proxy_a pat x (SOP (S xss))+   = grnfpS ms proxy_a pat x (SOP xss)++  grnfpS _ _ _ _ _ = error "grnfpS: unexpected case!!"++-------------------------------------------------------------------------------++  grnfpP :: forall cs xs.+            (+              All NFDataP xs+#if INCLUDE_SHOW_INSTANCES+            , All Show xs+#endif+            ) =>+                    ConstructorInfo cs+                 -> ()+                 -> Bool+                 -> PatNode+                 -> [Pattern]+                 -> NP I xs+                 -> ()+  grnfpP ci acc b pp [] Nil = acc+  grnfpP ci acc True pp [] (I x :* xs)+   = grnfpP ci acc True pp [] xs+  grnfpP ci acc b pp (p@(Node pas pgcs):pcs) (I x :* xs)+   = grnfpP ci (acc `seq` step) False pp pcs xs+   where+    step | WI{} <- pas  = ()+         | TR{} <- pas  = if elem tx treps then thestep else ()+#if USE_WW_DEEPSEQ+         | TI{} <- pas  = if elem tx treps then () else rnf x+         | TW{} <- pas  = if elem tx treps then rnf x else ()+#else+         | TI{} <- pas  = if elem tx treps then () else rnfn 999999 x  -- XXX thack!+#endif+---      | TI{} <- pas  = if elem tx treps then () else thestep+         | otherwise    = thestep+     where+      as = getPatNodeAttrs pas+      treps = typeConstraints as+      thestep = rnfp p x+      tx | (Constructor n) <- ci  = n+         | (Infix n _ _) <- ci    = n+         | (Record n _) <- ci     = n+  grnfpP ci acc b pp ps xs+   = error $ "*6* "++show b++" "++show pp++" "++show ps++" "++show (lenxs xs)++-------------------------------------------------------------------------------++  -- Preliminary check for arity mismatch or constructor name mismatch.+  -- Note: I don't presently know of a way to obtain the arity of a ctor+  -- from it's name as a String. Arity checking is done between the+  -- pattern and the value, but the arity of a ctor named in a pattern+  -- constraints is not available.+  grnfpP_validate :: forall xs.+            (+              All NFDataP xs+#if INCLUDE_SHOW_INSTANCES+            , All Show xs+#endif+            ) =>+                    Bool+                 -> PatNode+                 -> [Pattern]+                 -> String+                 -> NP I xs+                 -> (Bool, Maybe String)+  grnfpP_validate True  pp@(TR as) ps tx xss+   | b          = grnfpP_validate' True pp ps tx xss+   | otherwise  = (False,Just $ "<generic> TR ctor name constraint mismatch (not "++tx++")")+   where b = head cnames == tx+         cnames = typeConstraints as+#if USE_WW_DEEPSEQ+  grnfpP_validate True  pp@(TW as) ps tx xss+   | b          = grnfpP_validate' True pp ps tx xss+   | otherwise  = (False,Just $ "<generic> TW ctor [should be type!] name constraint mismatch (not "++tx++")")+   where b = head cnames == tx+         cnames = typeConstraints as+#endif+  grnfpP_validate True  pp@(TI as) ps tx xss+   | b          = grnfpP_validate' True pp ps tx xss+   | otherwise  = (False,Just $ "<generic> TI ctor [should be type!] name constraint mismatch (not "++tx++")")+   where b = head cnames == tx+         cnames = typeConstraints as+  grnfpP_validate b     pp             ps tx xss+   = grnfpP_validate' b pp ps tx xss++  grnfpP_validate' :: forall xs.+            (+              All NFDataP xs+#if INCLUDE_SHOW_INSTANCES+            , All Show xs+#endif+            ) =>+                    Bool+                 -> PatNode+                 -> [Pattern]+                 -> String+                 -> NP I xs+                 -> (Bool, Maybe String)+  grnfpP_validate' True  (WI as) []  tx xss = (True,Nothing)+  grnfpP_validate' True  (WS as) []  tx xss = (True,Nothing)+  grnfpP_validate' True  (WN as) []  tx xss = (True,Nothing)+  grnfpP_validate' True  (WW as) []  tx xss = (True,Nothing)+  grnfpP_validate' True   pp     ps  tx xss+   | WS{} <- pp  = if lenps > 0 then (False,Nothing) else (True,Nothing)+   | b           = (True,Nothing)+   | otherwise   = (False,Just "<generic> arity mismatch #1")+   where+-- oops+--  as = getPatNodeAttrs pp+--  n = depth as+    b = lenps == lenxs xss+    lenps = length ps+  grnfpP_validate' False pp []      tx Nil+   = (True,Nothing)+  grnfpP_validate' False pp (p:pcs) tx (I x :* xs)+   = grnfpP_validate False pp pcs tx xs+  grnfpP_validate' b pp ps tx xs+   = error $ " &&& " ++ show b ++ " " ++ show pp ++ " " ++ show ps+-- = error $ show b ++ " " ++ show pp ++ " " ++ show ps ++ " " ++ show (hcliftA (Proxy :: Proxy Show) (K . show . unI) xs)++-------------------------------------------------------------------------------++  lenxs :: NP I xs' -> Int+  lenxs Nil = 0+  lenxs (I x' :* xs') = 1 + lenxs xs'+  lenxs _ = error "lenxs: unexpected"++-------------------------------------------------------------------------------++#if 0+-- Works so far as it goes, but is not currently used.+-- Also, this is exactly Data.Generics.Schemes.glength+  arity :: Data a => a -> Int+  arity = length . gmapQ (const ())+#endif++-------------------------------------------------------------------------------++  patMatchFail'' :: String -> ()+  patMatchFail'' msg+#if 0+     -- With this, the expected match failures are seen.+     = error "BOO!!!!"+#else+#if WARN_PATTERN_MATCH_FAILURE+     = trace ("GNFDataP: warning: pattern match failure (" ++ msg ++ ")") $ ()+--   = unsafePerformIO $! putStrLn $! "GNFDataP: warning: pattern match failure (" ++ msg ++ ")"+#else+     = ()+#endif #endif  -------------------------------------------------------------------------------
− src/Control/DeepSeq/Bounded/Generic/GNFDataP_new_grammar.hs
@@ -1,454 +0,0 @@-----------------------------------------------------------------------------------{-  LANGUAGE CPP #-}---- (Tracing code has mostly been removed for distribution.)-#define DO_TRACE 0-#define INCLUDE_SHOW_INSTANCES 0------------------------------------------------------------------------------------- SOP cheat-sheet.------ class SingI (Code a) => Generic a where--- Associated Types:---   type Code a :: [[*]]--- Methods:---   from :: a -> Rep a---   to :: Rep a -> a------ type Rep a = SOP I (Code a)------ newtype SOP f xss = SOP (NS (NP f) xss)------ data NS :: (k -> *) -> [k] -> * where--- Constructors:---   Z :: f x -> NS f (x : xs)	 ---   S :: NS f xs -> NS f (x : xs)	 --- Examples:---   Z         :: f x -> NS f (x ': xs)---   S . Z     :: f y -> NS f (x ': y ': xs)---   S . S . Z :: f z -> NS f (x ': y ': z ': xs)------ data NP :: (k -> *) -> [k] -> * where--- Constructors:---   Nil :: NP f []	 ---   (:*) :: f x -> NP f xs -> NP f (x : xs) infixr 5	 --- Examples (sic! they are correct):---   I 'x'    :* I True  :* Nil  ::  NP I       '[ Char, Bool ]---   K 0      :* K 1     :* Nil  ::  NP (K Int) '[ Char, Bool ]---   Just 'x' :* Nothing :* Nil  ::  NP Maybe   '[ Char, Bool ]------   > :m +Generics.SOP---   > :m +Foo---   > Generics.SOP.from $ G2 1 2 3---   SOP (S (Z (I 1 :* (I 2 :* (I 3 :* Nil)))))---   > Generics.SOP.to $ Generics.SOP.from $ G2 1 2 3 :: TG---   G2 1 2 3-----------------------------------------------------------------------------------  {-# LANGUAGE ScopedTypeVariables #-}-  {-# LANGUAGE DataKinds #-}-  {-# LANGUAGE TypeFamilies #-}-  {-# LANGUAGE ConstraintKinds #-}-#if __GLASGOW_HASKELL__ < 708-  {-# LANGUAGE GADTs #-}-#endif-  {-# LANGUAGE TemplateHaskell #-}--  {-# LANGUAGE BangPatterns #-}  -- only for tracing------------------------------------------------------------------------------------- |--- Module      :  Control.DeepSeq.Bounded.Generic.GNFDataP_new_grammar--- Copyright   :  Andrew G. Seniuk 2014-2015--- License     :  BSD-style (see the LICENSE file)------ Maintainer  :  Andrew Seniuk <rasfar@gmail.com>--- Stability   :  provisional--- Portability :  GHC (uses SOP)------ Support for generic deriving (via <http://hackage.haskell.org/package/generics-sop/docs/Generics-SOP.html Generics.SOP>) of 'NFDataP' instances.------ Note that 'NFDataP' has superclasses 'NFDataN', 'NFData' and 'Typeable'.------ This metaboilerplate is standard for using the generic deriving--- facilities of "GHC.Generics" and <http://hackage.haskell.org/package/generics-sop/docs/Generics-SOP.html Generics.SOP>.--- Consider <http://hackage.haskell.org/package/seqaid seqaid> for--- a turnkey solution.------ > {-# LANGUAGE TemplateHaskell #-}--- > {-# LANGUAGE DataKinds #-}--- > {-# LANGUAGE TypeFamilies #-}--- > {-# LANGUAGE DeriveGeneric #-}--- > {-# LANGUAGE DeriveDataTypeable #-}--- > {-# LANGUAGE GADTs #-}  -- for GHC < 7.8 (== 7.6.3)--- > --- > import Generics.SOP.TH--- > import Control.DeepSeq.Bounded ( NFDataP(..), grnfp )--- > import Control.DeepSeq.Bounded ( NFDataN(..), grnfn )--- > import Control.DeepSeq.Generics ( NFData(..), genericRnf )--- > import GHC.Generics ( Generic )    -- for deriving NFData--- > import Data.Typeable ( Typeable )  -- for name-constrained pattern nodes--- >--- > import Control.DeepSeq.Bounded ( forcep )--- > --- > data TA = A1 TB TA | A2  deriving ( Generic, Typeable )--- > instance NFData  TA where rnf  = genericRnf--- > instance NFDataN TA where rnfn = grnfn--- > instance NFDataP TA where rnfp = grnfp--- > --- > data TB = B1 Int | B2 TA  deriving ( Generic, Typeable )--- > instance NFData  TB where rnf  = genericRnf--- > instance NFDataN TB where rnfn = grnfn--- > instance NFDataP TB where rnfp = grnfp--- > --- > deriveGeneric ''TA--- > deriveGeneric ''TB--- >--- > main = return $! forcep "((!).)" (A1 (B2 undefined) A2)-----------------------------------------------------------------------------------  module Control.DeepSeq.Bounded.Generic.GNFDataP_new_grammar-  (--      grnfp--#if 0-      -- * "Control.DeepSeq" re-exports-    , deepseq-    , force-    , NFData ( rnf )-    , ($!!)-#endif--  )-  where-----------------------------------------------------------------------------------  -- for Haddock!---import Control.DeepSeq.Bounded.NFDataP ( NFDataP ) -  import Control.DeepSeq.Bounded.NFDataN ( NFDataN )-  import Control.DeepSeq ( NFData )-  import Data.Typeable ( Typeable )--  import Control.DeepSeq.Bounded.NFDataP ( NFDataP, rnfp )-  import Control.DeepSeq.Bounded.NFDataN (          rnfn )-  import Control.DeepSeq                 (          rnf  )--  import Control.DeepSeq.Bounded.NFDataP ( handleAttrs )--  import Control.DeepSeq.Bounded.Pattern ( Rose(..), Pattern(..) )-  import Control.DeepSeq.Bounded.Pattern ( PatNode(..), PatNodeAttrs(..) )-  import Control.DeepSeq.Bounded.Pattern ( getPatNodeAttrs )--  import Generics.SOP--#if USE_PAR_PATNODE-  import Control.Parallel ( par )-#endif---- #warning GNFDataP USE_PSEQ_PATNODE still to do!...-#if USE_PSEQ_PATNODE-  import Control.Parallel ( pseq )-#endif--  import Data.Maybe-  import Debug.Trace ( trace )---import System.IO.Unsafe ( unsafePerformIO )  -- for console output only-----------------------------------------------------------------------------------#if DO_TRACE-  mytrace = trace-  mytrace' = trace-#else-  mytrace x y = y-  mytrace' x y = y-#endif-----------------------------------------------------------------------------------  grnfp :: forall a.-           (-             Generic a-           , HasDatatypeInfo a---         , All Show (Map ConstructorInfo (Code a))-           , All2 NFDataP (Code a)-#if INCLUDE_SHOW_INSTANCES-           , All2 Show (Code a)-#endif-           , NFDataP a  -- NFData, NFDataN superclasses-           ) => Pattern -> a -> ()-  grnfp pat x = grnfp' dti proxy_a pat x xrep-   where-    dti = datatypeInfo proxy_a-    proxy_a = Proxy :: Proxy a-    xrep = from x-----------------------------------------------------------------------------------  -- Show constraint is needed, but not NFData nor NFDataN.-  -- Not quite sure why, but whatever...-  grnfp' :: forall a.-            (-              Generic a-            , HasDatatypeInfo a-            , All2 NFDataP (Code a)-#if INCLUDE_SHOW_INSTANCES-            , All2 Show (Code a)-#endif-            , NFDataP a  -- NFData, NFDataN superclasses-            ) =>-                    DatatypeInfo (Code a)-                 -> Proxy a-                 -> Pattern-                 -> a-                 -> Rep a-                 -> ()-  grnfp' (ADT     _ _ cs) proxy_a pat x xrep-   = grnfpS cs         proxy_a pat x xrep-  grnfp' (Newtype _ _ c ) proxy_a pat x xrep-   = grnfpS (c :* Nil) proxy_a pat x xrep------------------------------------------------------------------------------------- SOP works (here) by hitting the Z (meta)constructor for the--- particular datatype constructor which is [inhabited].--- i.e. This simply dials in the correct constructor.--- Later: Looks like it does a bit more than that, now.-  grnfpS :: forall a xss.-            (-              All2 NFDataP xss-#if INCLUDE_SHOW_INSTANCES-            , All2 Show xss-#endif-            , NFDataP a  -- NFData, NFDataN superclasses-            ) =>-                    NP ConstructorInfo xss-                 -> Proxy a-                 -> Pattern-                 -> a-                 -> SOP I xss-                 -> ()--  grnfpS _ _ (Node WI{} _) _ _ = ()  -- needed!!---grnfpS _ _ (Node WI{} _) _ (SOP (Z xs)) = ()  -- mustn't do!!---grnfpS (m :* _) _ (Node WI{} _) _ _ = ()  -- seems not to spring the bottom--  grnfpS (m :* _) proxy_a pat@(Node pas pcs) x (SOP (Z xs))---- | WI{} <- pas  = ()  -- too late! (SOP (Z xs)) has already forced-   | not status     = patMatchFail'' msg `seq` ()---- | WI{} <- pas  = ()-   | handleAttrs pat x `seq` pat == Node XX []  = undefined-#if USE_PAR_PATNODE-   | doSpark as  = case pas of-       WW{} -> rnf x `par` ()-       WN{} -> rnfn n x `par` ()-       otherwise -> dorecurs-#endif--- XXX So these TR and TI (and TW?... TN?...) also need to be up--- in a top-level case before this one!-   | TR{} <- pas  = if elem tx treps then dorecurs else ()-#if USE_WW_DEEPSEQ-   | TI{} <- pas  = if elem tx treps then () else rnf x-   | TW{} <- pas  = if elem tx treps then rnf x else ()-#else-   | TI{} <- pas  = if elem tx treps then () else rnfn 999999 x  -- XXX thack!-#endif---- | TI{} <- pas  = if elem tx treps then () else dorecurs-#if USE_WW_DEEPSEQ-   | WW{} <- pas  = rnf x-#endif-   | WN{} <- pas  = rnfn n x-#if USE_WW_DEEPSEQ-   | TW{} <- pas  = if elem tx treps then rnf x else ()  -- no better!-#endif-   | otherwise    = dorecurs-   where-    as = getPatNodeAttrs pas-    treps = typeConstraints as-    n = depth as-    (status,mmsg)  = grnfpP_validate True pas pcs tx xs-    !_ = mytrace ("*** "++tx) $ ()-    tx | (Constructor n) <- m  = n-       | (Infix n _ _) <- m    = n-       | (Record n _) <- m     = n-    !_ = mytrace ("VVV "++show status) $ ()-    msg = fromJust mmsg-#if USE_PAR_PATNODE-#if DO_TRACE-    dorecurs | doSpark as  = grnfpP_ m () True pas pcs xs `par` ()-             | otherwise   = grnfpP_ m () True pas pcs xs `seq` ()-#else-    dorecurs | doSpark as  = grnfpP m () True pas pcs xs `par` ()-             | otherwise   = grnfpP m () True pas pcs xs `seq` ()-#endif-#else-#if DO_TRACE-    dorecurs = grnfpP_ m () True p pcs xs `seq` ()-#else-    dorecurs = grnfpP m () True p pcs xs `seq` ()-#endif-#endif--  grnfpS (m :* ms) proxy_a pat x (SOP (S xss))-   = grnfpS ms proxy_a pat x (SOP xss)--  grnfpS _ _ _ _ _ = error "grnfpS: unexpected case!!"-----------------------------------------------------------------------------------  grnfpP :: forall cs xs.-            (-              All NFDataP xs-#if INCLUDE_SHOW_INSTANCES-            , All Show xs-#endif-            ) =>-                    ConstructorInfo cs-                 -> ()-                 -> Bool-                 -> PatNode-                 -> [Pattern]-                 -> NP I xs-                 -> ()-  grnfpP ci acc b pp [] Nil = acc-  grnfpP ci acc True pp [] (I x :* xs)-   = grnfpP ci acc True pp [] xs-  grnfpP ci acc b pp (p@(Node pas pgcs):pcs) (I x :* xs)-   = grnfpP ci (acc `seq` step) False pp pcs xs-   where-    step | WI{} <- pas  = ()-         | TR{} <- pas  = if elem tx treps then thestep else ()-#if USE_WW_DEEPSEQ-         | TI{} <- pas  = if elem tx treps then () else rnf x-         | TW{} <- pas  = if elem tx treps then rnf x else ()-#else-         | TI{} <- pas  = if elem tx treps then () else rnfn 999999 x  -- XXX thack!-#endif----      | TI{} <- pas  = if elem tx treps then () else thestep-         | otherwise    = thestep-     where-      as = getPatNodeAttrs pas-      treps = typeConstraints as-      thestep = rnfp p x-      tx | (Constructor n) <- ci  = n-         | (Infix n _ _) <- ci    = n-         | (Record n _) <- ci     = n-  grnfpP ci acc b pp ps xs-   = error $ "*6* "++show b++" "++show pp++" "++show ps++" "++show (lenxs xs)-----------------------------------------------------------------------------------  -- Preliminary check for arity mismatch or constructor name mismatch.-  -- Note: I don't presently know of a way to obtain the arity of a ctor-  -- from it's name as a String. Arity checking is done between the-  -- pattern and the value, but the arity of a ctor named in a pattern-  -- constraints is not available.-  grnfpP_validate :: forall xs.-            (-              All NFDataP xs-#if INCLUDE_SHOW_INSTANCES-            , All Show xs-#endif-            ) =>-                    Bool-                 -> PatNode-                 -> [Pattern]-                 -> String-                 -> NP I xs-                 -> (Bool, Maybe String)-  grnfpP_validate True  pp@(TR as) ps tx xss-   | b          = grnfpP_validate' True pp ps tx xss-   | otherwise  = (False,Just $ "<generic> TR ctor name constraint mismatch (not "++tx++")")-   where b = head cnames == tx-         cnames = typeConstraints as-#if USE_WW_DEEPSEQ-  grnfpP_validate True  pp@(TW as) ps tx xss-   | b          = grnfpP_validate' True pp ps tx xss-   | otherwise  = (False,Just $ "<generic> TW ctor [should be type!] name constraint mismatch (not "++tx++")")-   where b = head cnames == tx-         cnames = typeConstraints as-#endif-  grnfpP_validate True  pp@(TI as) ps tx xss-   | b          = grnfpP_validate' True pp ps tx xss-   | otherwise  = (False,Just $ "<generic> TI ctor [should be type!] name constraint mismatch (not "++tx++")")-   where b = head cnames == tx-         cnames = typeConstraints as-  grnfpP_validate b     pp             ps tx xss-   = grnfpP_validate' b pp ps tx xss--  grnfpP_validate' :: forall xs.-            (-              All NFDataP xs-#if INCLUDE_SHOW_INSTANCES-            , All Show xs-#endif-            ) =>-                    Bool-                 -> PatNode-                 -> [Pattern]-                 -> String-                 -> NP I xs-                 -> (Bool, Maybe String)-  grnfpP_validate' True  (WI as) []  tx xss = (True,Nothing)-  grnfpP_validate' True  (WS as) []  tx xss = (True,Nothing)-  grnfpP_validate' True  (WN as) []  tx xss = (True,Nothing)-  grnfpP_validate' True  (WW as) []  tx xss = (True,Nothing)-  grnfpP_validate' True   pp     ps  tx xss-   | WS{} <- pp  = if lenps > 0 then (False,Nothing) else (True,Nothing)-   | b           = (True,Nothing)-   | otherwise   = (False,Just "<generic> arity mismatch #1")-   where--- oops---  as = getPatNodeAttrs pp---  n = depth as-    b = lenps == lenxs xss-    lenps = length ps-  grnfpP_validate' False pp []      tx Nil-   = (True,Nothing)-  grnfpP_validate' False pp (p:pcs) tx (I x :* xs)-   = grnfpP_validate False pp pcs tx xs-  grnfpP_validate' b pp ps tx xs-   = error $ " &&& " ++ show b ++ " " ++ show pp ++ " " ++ show ps--- = error $ show b ++ " " ++ show pp ++ " " ++ show ps ++ " " ++ show (hcliftA (Proxy :: Proxy Show) (K . show . unI) xs)-----------------------------------------------------------------------------------  lenxs :: NP I xs' -> Int-  lenxs Nil = 0-  lenxs (I x' :* xs') = 1 + lenxs xs'-  lenxs _ = error "lenxs: unexpected"-----------------------------------------------------------------------------------#if 0--- Works so far as it goes, but is not currently used.--- Also, this is exactly Data.Generics.Schemes.glength-  arity :: Data a => a -> Int-  arity = length . gmapQ (const ())-#endif-----------------------------------------------------------------------------------  patMatchFail'' :: String -> ()-  patMatchFail'' msg-#if 0-     -- With this, the expected match failures are seen.-     = error "BOO!!!!"-#else-#if WARN_PATTERN_MATCH_FAILURE-     = trace ("GNFDataP: warning: pattern match failure (" ++ msg ++ ")") $ ()---   = unsafePerformIO $! putStrLn $! "GNFDataP: warning: pattern match failure (" ++ msg ++ ")"-#else-     = ()-#endif-#endif----------------------------------------------------------------------------------
− src/Control/DeepSeq/Bounded/Generic/GNFDataP_old_grammar.hs
@@ -1,411 +0,0 @@-----------------------------------------------------------------------------------{-  LANGUAGE CPP #-}---- (Tracing code has mostly been removed for distribution.)-#define DO_TRACE 0-#define INCLUDE_SHOW_INSTANCES 0------------------------------------------------------------------------------------- SOP cheat-sheet.------ class SingI (Code a) => Generic a where--- Associated Types:---   type Code a :: [[*]]--- Methods:---   from :: a -> Rep a---   to :: Rep a -> a------ type Rep a = SOP I (Code a)------ newtype SOP f xss = SOP (NS (NP f) xss)------ data NS :: (k -> *) -> [k] -> * where--- Constructors:---   Z :: f x -> NS f (x : xs)	 ---   S :: NS f xs -> NS f (x : xs)	 --- Examples:---   Z         :: f x -> NS f (x ': xs)---   S . Z     :: f y -> NS f (x ': y ': xs)---   S . S . Z :: f z -> NS f (x ': y ': z ': xs)------ data NP :: (k -> *) -> [k] -> * where--- Constructors:---   Nil :: NP f []	 ---   (:*) :: f x -> NP f xs -> NP f (x : xs) infixr 5	 --- Examples (sic! they are correct):---   I 'x'    :* I True  :* Nil  ::  NP I       '[ Char, Bool ]---   K 0      :* K 1     :* Nil  ::  NP (K Int) '[ Char, Bool ]---   Just 'x' :* Nothing :* Nil  ::  NP Maybe   '[ Char, Bool ]------   > :m +Generics.SOP---   > :m +Foo---   > Generics.SOP.from $ G2 1 2 3---   SOP (S (Z (I 1 :* (I 2 :* (I 3 :* Nil)))))---   > Generics.SOP.to $ Generics.SOP.from $ G2 1 2 3 :: TG---   G2 1 2 3-----------------------------------------------------------------------------------  {-# LANGUAGE ScopedTypeVariables #-}-  {-# LANGUAGE DataKinds #-}-  {-# LANGUAGE TypeFamilies #-}-  {-# LANGUAGE ConstraintKinds #-}-#if __GLASGOW_HASKELL__ < 708-  {-# LANGUAGE GADTs #-}-#endif-  {-# LANGUAGE TemplateHaskell #-}--  {-# LANGUAGE BangPatterns #-}  -- only for tracing------------------------------------------------------------------------------------- |--- Module      :  Control.DeepSeq.Bounded.Generic.GNFDataP_old_grammar--- Copyright   :  Andrew G. Seniuk 2014-2015--- License     :  BSD-style (see the LICENSE file)------ Maintainer  :  Andrew Seniuk <rasfar@gmail.com>--- Stability   :  provisional--- Portability :  GHC (uses SOP)------ Support for generic deriving (via <http://hackage.haskell.org/package/generics-sop/docs/Generics-SOP.html Generics.SOP>) of 'NFDataP' instances.------ Note that 'NFDataP' has superclasses 'NFDataN', 'NFData' and 'Typeable'.------ This metaboilerplate is standard for using the generic deriving--- facilities of "GHC.Generics" and <http://hackage.haskell.org/package/generics-sop/docs/Generics-SOP.html Generics.SOP>.--- Consider <http://hackage.haskell.org/package/seqaid seqaid> for--- a turnkey solution.------ > {-# LANGUAGE TemplateHaskell #-}--- > {-# LANGUAGE DataKinds #-}--- > {-# LANGUAGE TypeFamilies #-}--- > {-# LANGUAGE DeriveGeneric #-}--- > {-# LANGUAGE DeriveDataTypeable #-}--- > {-# LANGUAGE GADTs #-}  -- for GHC < 7.8 (== 7.6.3)--- > --- > import Generics.SOP.TH--- > import Control.DeepSeq.Bounded ( NFDataP(..), grnfp )--- > import Control.DeepSeq.Bounded ( NFDataN(..), grnfn )--- > import Control.DeepSeq.Generics ( NFData(..), genericRnf )--- > import GHC.Generics ( Generic )    -- for deriving NFData--- > import Data.Typeable ( Typeable )  -- for name-constrained pattern nodes--- >--- > import Control.DeepSeq.Bounded ( forcep )--- > --- > data TA = A1 TB TA | A2  deriving ( Generic, Typeable )--- > instance NFData  TA where rnf  = genericRnf--- > instance NFDataN TA where rnfn = grnfn--- > instance NFDataP TA where rnfp = grnfp--- > --- > data TB = B1 Int | B2 TA  deriving ( Generic, Typeable )--- > instance NFData  TB where rnf  = genericRnf--- > instance NFDataN TB where rnfn = grnfn--- > instance NFDataP TB where rnfp = grnfp--- > --- > deriveGeneric ''TA--- > deriveGeneric ''TB--- >--- > main = return $! forcep ".{.{.}.}" (A1 (B2 undefined) A2)-----------------------------------------------------------------------------------  module Control.DeepSeq.Bounded.Generic.GNFDataP_old_grammar-  (--      grnfp--#if 0-      -- * "Control.DeepSeq" re-exports-    , deepseq-    , force-    , NFData ( rnf )-    , ($!!)-#endif--  )-  where-----------------------------------------------------------------------------------  import Control.DeepSeq.Bounded.NFDataP ( NFDataP, rnfp )-  import Control.DeepSeq.Bounded.NFDataN (          rnfn )-  import Control.DeepSeq                 (          rnf  )--  import Control.DeepSeq.Bounded.Pattern ( Pattern(..), PatNode(..), Rose(..) )--  import Generics.SOP--#if PARALLELISM_EXPERIMENT-  import Control.Parallel ( par )-#endif--  import Data.Maybe-  import Debug.Trace ( trace )---import System.IO.Unsafe ( unsafePerformIO )  -- for console output only-----------------------------------------------------------------------------------#if DO_TRACE-  mytrace = trace-  mytrace' = trace-#else-  mytrace x y = y-  mytrace' x y = y-#endif-----------------------------------------------------------------------------------  grnfp :: forall a.-           (-             Generic a-           , HasDatatypeInfo a---         , All Show (Map ConstructorInfo (Code a))-           , All2 NFDataP (Code a)-#if INCLUDE_SHOW_INSTANCES-           , All2 Show (Code a)-#endif-           , NFDataP a  -- NFData, NFDataN superclasses-           ) => Pattern -> a -> ()-  grnfp pat x = grnfp' dti proxy_a pat x xrep-   where-    dti = datatypeInfo proxy_a-    proxy_a = Proxy :: Proxy a-    xrep = from x-----------------------------------------------------------------------------------  -- Show constraint is needed, but not NFData nor NFDataN.-  -- Not quite sure why, but whatever...-  grnfp' :: forall a.-            (-              Generic a-            , HasDatatypeInfo a-            , All2 NFDataP (Code a)-#if INCLUDE_SHOW_INSTANCES-            , All2 Show (Code a)-#endif-            , NFDataP a  -- NFData, NFDataN superclasses-            ) =>-                    DatatypeInfo (Code a)-                 -> Proxy a-                 -> Pattern-                 -> a-                 -> Rep a-                 -> ()-  grnfp' (ADT     _ _ cs) proxy_a pat x xrep-   = grnfpS cs         proxy_a pat x xrep-  grnfp' (Newtype _ _ c ) proxy_a pat x xrep-   = grnfpS (c :* Nil) proxy_a pat x xrep------------------------------------------------------------------------------------- SOP works (here) by hitting the Z (meta)constructor for the--- particular datatype constructor which is [inhabited].--- i.e. This simply dials in the correct constructor.--- Later: Looks like it does a bit more than that, now.-  grnfpS :: forall a xss.-            (-              All2 NFDataP xss-#if INCLUDE_SHOW_INSTANCES-            , All2 Show xss-#endif-            , NFDataP a  -- NFData, NFDataN superclasses-            ) =>-                    NP ConstructorInfo xss-                 -> Proxy a-                 -> Pattern-                 -> a-                 -> SOP I xss-                 -> ()--  grnfpS _ _ (Node WI _) _ _ = ()  -- needed!!---grnfpS _ _ (Node WI _) _ (SOP (Z xs)) = ()  -- mustn't do!!---grnfpS (m :* _) _ (Node WI _) _ _ = ()  -- seems not to spring the bottom--  grnfpS (m :* _) proxy_a (Node p pcs) x (SOP (Z xs))---- | WI       <- p  = ()  -- too late! (SOP (Z xs)) has already forced-   | not status     = patMatchFail'' msg `seq` ()---- | WI       <- p  = ()--- XXX So these TR and TI (and TW?... TN?...) also need to be up--- in a top-level case before this one!-   | TR treps <- p  = if elem tx treps then dorecurs else ()-   | TI treps <- p  = if elem tx treps then () else dorecurs-   | WW       <- p  = rnf x-   | WN n     <- p  = rnfn n x-#if PARALLELISM_EXPERIMENT-   | PW       <- p  = rnf x `par` ()-   | PN n     <- p  = rnfn n x `par` ()-#endif-   | TW treps <- p  = if elem tx treps then rnf x else ()  -- no better!-   | otherwise      = dorecurs-   where-    (status,mmsg)  = grnfpP_validate True p pcs tx xs-    !_ = mytrace ("*** "++tx) $ ()-    tx | (Constructor n) <- m  = n-       | (Infix n _ _) <- m    = n-       | (Record n _) <- m     = n-    !_ = mytrace ("VVV "++show status) $ ()-    msg = fromJust mmsg-#if PARALLELISM_EXPERIMENT-#if DO_TRACE-    dorecurs | PR <- p    = grnfpP_ m () True p pcs xs `par` ()-             | otherwise  = grnfpP_ m () True p pcs xs `seq` ()-#else-    dorecurs | PR <- p    = grnfpP m () True p pcs xs `par` ()-             | otherwise  = grnfpP m () True p pcs xs `seq` ()-#endif-#else-#if DO_TRACE-    dorecurs = grnfpP_ m () True p pcs xs `seq` ()-#else-    dorecurs = grnfpP m () True p pcs xs `seq` ()-#endif-#endif--  grnfpS (m :* ms) proxy_a pat x (SOP (S xss))-   = grnfpS ms proxy_a pat x (SOP xss)--  grnfpS _ _ _ _ _ = error "grnfpS: unexpected case!!"-----------------------------------------------------------------------------------  grnfpP :: forall cs xs.-            (-              All NFDataP xs-#if INCLUDE_SHOW_INSTANCES-            , All Show xs-#endif-            ) =>-                    ConstructorInfo cs-                 -> ()-                 -> Bool-                 -> PatNode-                 -> [Pattern]-                 -> NP I xs-                 -> ()-  grnfpP ci acc b pp [] Nil = acc-  grnfpP ci acc True pp [] (I x :* xs)-   = grnfpP ci acc True pp [] xs-  grnfpP ci acc b pp (p@(Node pn pgcs):pcs) (I x :* xs)-   = grnfpP ci (acc `seq` step) False pp pcs xs-   where-    step | WI <- pn        = ()-         | TR treps <- pn  = if elem tx treps then thestep else ()-         | TI treps <- pn  = if elem tx treps then () else thestep-         | otherwise       = thestep-     where-      thestep = rnfp p x-      tx | (Constructor n) <- ci  = n-         | (Infix n _ _) <- ci    = n-         | (Record n _) <- ci     = n-  grnfpP ci acc b pp ps xs-   = error $ "*6* "++show b++" "++show pp++" "++show ps++" "++show (lenxs xs)-----------------------------------------------------------------------------------  -- Preliminary check for arity mismatch or constructor name mismatch.-  -- Note: I don't presently know of a way to obtain the arity of a ctor-  -- from it's name as a String. Arity checking is done between the-  -- pattern and the value, but the arity of a ctor named in a pattern-  -- constraints is not available.-  grnfpP_validate :: forall xs.-            (-              All NFDataP xs-#if INCLUDE_SHOW_INSTANCES-            , All Show xs-#endif-            ) =>-                    Bool-                 -> PatNode-                 -> [Pattern]-                 -> String-                 -> NP I xs-                 -> (Bool, Maybe String)-  grnfpP_validate True  pp@(TR cnames) ps tx xss-   | b          = grnfpP_validate' True pp ps tx xss-   | otherwise  = (False,Just $ "<generic> TR ctor name constraint mismatch (not "++tx++")")-   where b = head cnames == tx-  grnfpP_validate True  pp@(TW cnames) ps tx xss-   | b          = grnfpP_validate' True pp ps tx xss-   | otherwise  = (False,Just $ "<generic> TW ctor name constraint mismatch (not "++tx++")")-   where b = head cnames == tx-  grnfpP_validate True  pp@(TI cnames) ps tx xss-   | b          = grnfpP_validate' True pp ps tx xss-   | otherwise  = (False,Just $ "<generic> TI ctor name constraint mismatch (not "++tx++")")-   where b = head cnames == tx-  grnfpP_validate b     pp             ps tx xss-   = grnfpP_validate' b pp ps tx xss--  grnfpP_validate' :: forall xs.-            (-              All NFDataP xs-#if INCLUDE_SHOW_INSTANCES-            , All Show xs-#endif-            ) =>-                    Bool-                 -> PatNode-                 -> [Pattern]-                 -> String-                 -> NP I xs-                 -> (Bool, Maybe String)-  grnfpP_validate' True   WS    []  tx xss = (True,Nothing)-  grnfpP_validate' True   WI    []  tx xss = (True,Nothing)-  grnfpP_validate' True  (WN n) []  tx xss = (True,Nothing)-  grnfpP_validate' True   WW    []  tx xss = (True,Nothing)-#if PARALLELISM_EXPERIMENT-  grnfpP_validate' True  (PN n) []  tx xss = (True,Nothing)-  grnfpP_validate' True   PW    []  tx xss = (True,Nothing)-#endif-  grnfpP_validate' True   pp    ps  tx xss-   | WS <- pp   = if lenps > 0 then (False,Nothing) else (True,Nothing)-   | b          = (True,Nothing)-   | otherwise  = (False,Just "<generic> arity mismatch #1")-   where-    b = lenps == lenxs xss-    lenps = length ps-  grnfpP_validate' False  pp    []  tx Nil = (True,Nothing)-  grnfpP_validate' False pp (p:pcs) tx (I x :* xs)-   = grnfpP_validate False pp pcs tx xs-  grnfpP_validate' b pp ps tx xs-   = error $ " &&& " ++ show b ++ " " ++ show pp ++ " " ++ show ps--- = error $ show b ++ " " ++ show pp ++ " " ++ show ps ++ " " ++ show (hcliftA (Proxy :: Proxy Show) (K . show . unI) xs)-----------------------------------------------------------------------------------  lenxs :: NP I xs' -> Int-  lenxs Nil = 0-  lenxs (I x' :* xs') = 1 + lenxs xs'-  lenxs _ = error "lenxs: unexpected"-----------------------------------------------------------------------------------#if 0--- Works so far as it goes, but is not currently used.--- Also, this is exactly Data.Generics.Schemes.glength-  arity :: Data a => a -> Int-  arity = length . gmapQ (const ())-#endif-----------------------------------------------------------------------------------  patMatchFail'' :: String -> ()-  patMatchFail'' msg-#if 0-     -- With this, the expected match failures are seen.-     = error "BOO!!!!"-#else-#if WARN_PATTERN_MATCH_FAILURE-     = trace ("GNFDataP: warning: pattern match failure (" ++ msg ++ ")") $ ()---   = unsafePerformIO $! putStrLn $! "GNFDataP: warning: pattern match failure (" ++ msg ++ ")"-#else-     = ()-#endif-#endif----------------------------------------------------------------------------------
src/Control/DeepSeq/Bounded/NFDataP.hs view
@@ -3,254 +3,1680 @@    {-  LANGUAGE CPP #-} ----------------------------------------------------------------------------------#if NEW_IMPROVED_PATTERN_GRAMMAR--- |--- Module      :  Control.DeepSeq.Bounded.NFDataP--- Copyright   :  Andrew G. Seniuk 2014-2015--- License     :  BSD-style (see the file LICENSE)------ Maintainer  :  Andrew Seniuk <rasfar@gmail.com>--- Stability   :  provisional--- Portability :  portable------ This module provides an overloaded function, 'deepseqp', for partially--- (or fully) evaluating data structures to bounded depth via pattern--- matching on term shape, and on class, type, and constructor names.------ There are two ways to use this API.------  (1) You can use the 'PatNode' constructors directly.------  (2) You can compile your patterns from strings in a concise---      embedded language.------ There's no difference in expressive power, but use of the DSL--- is recommended, because the embedded 'Pattern' compiler can catch--- some errors that GHC cannot (using 'PatNode' constructors explicitly).--- Also, the pattern strings are easier to read and write.------ With some qualifications (concerning 'WI' nodes, and 'PatNodeAttrs'--- configuration), composition fuses, and what's more, it's commutative...------ __Motivation__------ A typical use is to ensure any exceptions hidden within lazy--- fields of a data structure do not leak outside the scope of the--- exception handler; another is to force evaluation of a data structure in--- one thread, before passing it to another thread (preventing work moving--- to the wrong threads). Unlike <http://hackage.haskell.org/package/deepseq/docs/Control-DeepSeq.html DeepSeq>, potentially infinite values of coinductive--- data types are supported by principled bounding of deep evaluation.------ It is also useful for diagnostic purposes when trying to understand--- and manipulate space\/time trade-offs in lazy code,--- and as an optimal substitute for 'deepseq'--- (where \"optimal\" doesn't include changing the code to remove--- the need for artificial forcing!).------ 'deepseqp' with optimal patterns is usually a better solution--- even than stict fields in your data structures, because the--- latter will behave strictly everywhere the constructors--- are used, instead of just where its laziness is problematic.------ There may be possible applications to the prevention of resource leaks--- in lazy streaming, but I'm not certain.------ __Semantics__------ (For additional details, see "Control.DeepSeq.Bounded.Pattern".)------ 'deepseqp' and friends artifically force evaluation of a term--- so long as the pattern matches.------ A mismatch occurs at a pattern node when the corresponding constructor node either:------  * has arity different than the number of subpatterns (only when subpatterns given)------  * has class\/type\/name not named in the constraint (only when constraint given)------ A mismatch will cause evaluation down that branch to stop, but any--- upstream matching/forcing will continue uninterrupted.--- / (This behaviour can now be changed with 'PatNodeAttrs', available since 0.6.) /------ Note that patterns may extend beyond the values they match against,--- without incurring any mismatch. This semantics is not the only--- possible, but bear in mind that order of evaluation is nondeterministic,--- barring further measures.--- / (This behaviour can also now be changed with 'PatNodeAttrs'.) /------ See also <http://hackage.haskell.org/package/deepseq-bounded-0.6.0.0/docs/Control-DeepSeq-Bounded-NFDataPDyn.html NFDataPDyn> for another approach, which dynamically--- generates forcing patterns, and can depend on value info--- (in addition to type info).--- / (These dynamic aspects never received the attention I intended to give them, I got so caught up in seqaid, which offers similar features. Hopefully actual use of these tools in the near future will give me some perspective on whether/--- <http://hackage.haskell.org/package/deepseq-bounded-0.6.0.0/docs/Control-DeepSeq-Bounded-NFDataPDyn.html NFDataPDyn> /should get attention.) /----#else--- |--- Module      :  Control.DeepSeq.Bounded.NFDataP--- Copyright   :  Andrew G. Seniuk 2014-2015--- License     :  BSD-style (see the file LICENSE)------ Maintainer  :  Andrew Seniuk <rasfar@gmail.com>--- Stability   :  provisional--- Portability :  portable------ This module provides an overloaded function, 'deepseqp', for partially--- (or fully) evaluating data structures to bounded depth via pattern--- matching on term shape, and on class, type, and constructor names.------ There are two ways to use this API.------  (1) You can use the 'PatNode' constructors directly.------  (2) You can compile your patterns from strings in a concise---      embedded language.------ There's no difference in expressive power, but use of the DSL--- is recommended, because the embedded 'Pattern' compiler can catch--- some errors that GHC cannot (using 'PatNode' constructors explicitly).--- Also, the pattern strings are easier to read and write.------ __Motivation__------ A typical use is to ensure any exceptions hidden within lazy--- fields of a data structure do not leak outside the scope of the--- exception handler; another is to force evaluation of a data structure in--- one thread, before passing it to another thread (preventing work moving--- to the wrong threads). Unlike "DeepSeq", potentially infinite values of coinductive--- data types are supported by principled bounding of deep evaluation.------ It is also useful for diagnostic purposes when trying to understand--- and manipulate space\/time trade-offs in lazy code,--- and as an optimal substitute for 'deepseq'--- (where \"optimal\" doesn't include changing the code to remove--- the need for artificial forcing!).------ 'deepseqp' with optimal patterns is usually a better solution--- even than stict fields in your data structures, because the--- latter will behave strictly everywhere the constructors--- are used, instead of just where its laziness is problematic.------ There may be possible applications to the prevention of resource leaks--- in lazy streaming, but I'm not certain.------ __Semantics__------ (For additional details, see "Control.DeepSeq.Bounded.Pattern".)------ 'deepseqp' and friends artifically force evaluation of a term--- so long as the pattern matches.------ A mismatch occurs at a pattern node when the corresponding constructor node either:------  * has arity different than the number of subpatterns (only when subpatterns given)------  * has class\/type\/name not named in the constraint (only when constraint given)------ A mismatch will cause evaluation down that branch to stop, but any--- upstream matching/forcing will continue uninterrupted.--- Note that patterns may extend beyond the values they match against,--- without incurring any mismatch. This semantics is not the only--- possible, but bear in mind that order of evaluation is nondeterministic,--- barring further measures.------ See also "NFDataPDyn" for another approach, which dynamically--- generates forcing patterns, and can depend on value info--- (in addition to type info).----#endif-----------------------------------------------------------------------------------  module Control.DeepSeq.Bounded.NFDataP-  (--#if NEW_IMPROVED_PATTERN_GRAMMAR--     -- * Pattern-bounded analogues of 'deepseq' and 'force'--       deepseqp, forcep    -- take String arg (pattern DSL)--     -- * Avoid DSL compilation overhead-     ---     -- However, we don't anticipate that this overhead would be-     -- significant in most applications, because using <deepseq-bounded>-     -- in a tight loop would only be done for diagnostic purposes.--     , deepseqp_, forcep_  -- take Pattern structure arg--     -- * A custom exception, raised by choice 'PatNode's, that can be caught in the caller--#if USE_PING_PATNODE-     , DeepSeqBounded_PingException(..)-#endif--     -- * Related modules re-exported--     , module Control.DeepSeq.Bounded.Pattern-     , module Control.DeepSeq.Bounded.PatUtil  -- actually exports former--     -- * Class of things that can be evaluated over an arbitrary finite pattern--     , NFDataP(..)--     -- * Shared with GNFDataP (internal use)--     , handleAttrs  -- used by GNFDataP at least--#else--     -- * Pattern-bounded analogues of 'deepseq' and 'force'--       deepseqp, forcep    -- take String arg (pattern DSL)--     -- * Avoid DSL compilation overhead-     ---     -- However, we don't anticipate that this overhead would be-     -- significant in most applications, because using <deepseq-bounded>-     -- in a tight loop would only be done for diagnostic purposes.--     , deepseqp_, forcep_  -- take Pattern structure arg--#if 0-       -- Don't bother, really.-     , deepseqpM, forcepM  -- return lifted argument so can cope with bottom-     , deepseqpM_, forcepM_-#endif--     -- * Related modules re-exported--     , module Control.DeepSeq.Bounded.Pattern-     , module Control.DeepSeq.Bounded.PatUtil  -- actually exports former--     -- * Class of things that can be evaluated over an arbitrary finite pattern--     , NFDataP(..)--#endif----- #if NEW_IMPROVED_PATTERN_GRAMMAR----     module Control.DeepSeq.Bounded.NFDataP_new_grammar  ,---- #else----     module Control.DeepSeq.Bounded.NFDataP_old_grammar  ,---- #endif--  )-  where-----------------------------------------------------------------------------------#if NEW_IMPROVED_PATTERN_GRAMMAR-  import Control.DeepSeq.Bounded.NFDataP_new_grammar-#else-  import Control.DeepSeq.Bounded.NFDataP_old_grammar-#endif--  -- Necessity seems like a Haddock bug, as it is both imported-  -- and exported by PatUtil_{old,new}_*.hs.-  import Control.DeepSeq.Bounded.Pattern-  import Control.DeepSeq.Bounded.PatUtil+#define DO_TRACE 0++#define HANDLE_ATTRS_DATA_CONSTRAINT 0++-- XXX Note: Show constraints are for debugging purposes.+#define INCLUDE_SHOW_INSTANCES 0++-- Formerly DEBUG_WITH_DEEPSEQ_GENERICS.+-- Now also needed to force issuance of all compilePat warnings+-- (so not strictly a debugging flag anymore).+-- [Except it didn't work...]+--- #define NFDATA_INSTANCE_PATTERN 1  -- now it's a .cabal flag++-- Now specified via --flag=[-]USE_WWW_DEEPSEQ+--- #define USE_WW_DEEPSEQ 1++-------------------------------------------------------------------------------++  -- Used to create a custom Exception instance -- needed?+  -- I know we are no longer allowed to write our own instance?+  -- I thought Exceptions were in Haskell 98?...+  {-# LANGUAGE DeriveDataTypeable #-}++  -- For tracing only:+  {-  LANGUAGE BangPatterns #-}+  {-# LANGUAGE BangPatterns #-}++  {-# OPTIONS_GHC -fno-warn-name-shadowing #-}+  {-# OPTIONS_GHC -fno-warn-overlapping-patterns #-}++#if ! HASKELL98_FRAGMENT+  {-# LANGUAGE ScopedTypeVariables #-}+  {-  LANGUAGE RankNTypes #-}+  {-# LANGUAGE ConstraintKinds #-}+#endif++-------------------------------------------------------------------------------++-- |+-- Module      :  Control.DeepSeq.Bounded.NFDataP+-- Copyright   :  Andrew G. Seniuk 2014-2015+-- License     :  BSD-style (see the file LICENSE)+--+-- Maintainer  :  Andrew Seniuk <rasfar@gmail.com>+-- Stability   :  provisional+-- Portability :  portable+--+-- This module provides an overloaded function, 'deepseqp', for partially+-- (or fully) evaluating data structures to bounded depth via pattern+-- matching on term shape, and on class, type, and constructor names.+--+-- There are two ways to use this API.+--+--  (1) You can use the 'PatNode' constructors directly.+--+--  (2) You can compile your patterns from strings in a concise+--      embedded language.+--+-- There's no difference in expressive power, but use of the DSL+-- is recommended, because the embedded 'Pattern' compiler can catch+-- some errors that GHC cannot (using 'PatNode' constructors explicitly).+-- Also, the pattern strings are easier to read and write.+--+-- With some qualifications (concerning 'WI' nodes, and 'PatNodeAttrs'+-- configuration), composition fuses, and what's more, it's commutative...+--+-- __Motivation__+--+-- A typical use is to ensure any exceptions hidden within lazy+-- fields of a data structure do not leak outside the scope of the+-- exception handler; another is to force evaluation of a data structure in+-- one thread, before passing it to another thread (preventing work moving+-- to the wrong threads). Unlike <http://hackage.haskell.org/package/deepseq/docs/Control-DeepSeq.html DeepSeq>, potentially infinite values of coinductive+-- data types are supported by principled bounding of deep evaluation.+--+-- It is also useful for diagnostic purposes when trying to understand+-- and manipulate space\/time trade-offs in lazy code,+-- and as an optimal substitute for 'deepseq'+-- (where \"optimal\" doesn't include changing the code to remove+-- the need for artificial forcing!).+--+-- 'deepseqp' with optimal patterns is usually a better solution+-- even than stict fields in your data structures, because the+-- latter will behave strictly everywhere the constructors+-- are used, instead of just where its laziness is problematic.+--+-- There may be possible applications to the prevention of resource leaks+-- in lazy streaming, but I'm not certain.+--+-- __Semantics__+--+-- (For additional details, see "Control.DeepSeq.Bounded.Pattern".)+--+-- 'deepseqp' and friends artifically force evaluation of a term+-- so long as the pattern matches.+--+-- A mismatch occurs at a pattern node when the corresponding constructor node either:+--+--  * has arity different than the number of subpatterns (only when subpatterns given)+--+--  * has class\/type\/name not named in the constraint (only when constraint given)+--+-- A mismatch will cause evaluation down that branch to stop, but any+-- upstream matching/forcing will continue uninterrupted.+-- / (This behaviour can now be changed with 'PatNodeAttrs', available since 0.6.) /+--+-- Note that patterns may extend beyond the values they match against,+-- without incurring any mismatch. This semantics is not the only+-- possible, but bear in mind that order of evaluation is nondeterministic,+-- barring further measures.+-- / (This behaviour can also now be changed with 'PatNodeAttrs'.) /+--+-- See also <http://hackage.haskell.org/package/deepseq-bounded-0.6.0.0/docs/Control-DeepSeq-Bounded-NFDataPDyn.html NFDataPDyn> for another approach, which dynamically+-- generates forcing patterns, and can depend on value info+-- (in addition to type info).+-- / (These dynamic aspects never received the attention I intended to give them, I got so caught up in seqaid, which offers similar features. Hopefully actual use of these tools in the near future will give me some perspective on whether/+-- <http://hackage.haskell.org/package/deepseq-bounded-0.6.0.0/docs/Control-DeepSeq-Bounded-NFDataPDyn.html NFDataPDyn> /should get attention.) /+--++-------------------------------------------------------------------------------++  module Control.DeepSeq.Bounded.NFDataP+  (++     -- * Pattern-bounded analogues of 'deepseq' and 'force'++       deepseqp, forcep    -- take String arg (pattern DSL)++     -- * Avoid DSL compilation overhead+     --+     -- However, we don't anticipate that this overhead would be+     -- significant in most applications, because using <deepseq-bounded>+     -- in a tight loop would only be done for diagnostic purposes.++     , deepseqp_, forcep_  -- take Pattern structure arg++     -- * A custom exception, raised by choice 'PatNode's, that can be caught in the caller++#if USE_PING_PATNODE+     , DeepSeqBounded_PingException(..)+#endif++     -- * Related modules re-exported++     , module Control.DeepSeq.Bounded.Pattern+     , module Control.DeepSeq.Bounded.PatUtil  -- actually exports former++     -- * Class of things that can be evaluated over an arbitrary finite pattern++     , NFDataP(..)++     -- * Shared with GNFDataP (internal use)++     , handleAttrs  -- used by GNFDataP at least++  )+  where++-------------------------------------------------------------------------------++  import Control.DeepSeq.Bounded.Pattern+  import Control.DeepSeq.Bounded.Compile+  import Control.DeepSeq.Bounded.PatUtil ( unionPats, liftPats )++-- debugging...+#if 1+  import Control.DeepSeq.Bounded.PatUtil ( +             probDensRose+           , weightedRose+           , unzipRose+           , showRose+#if ! HASKELL98_FRAGMENT+           , Shape+           , shapeOf+           , ghom+#endif+         )+#endif++  import Control.DeepSeq.Bounded.NFDataN  -- finally used ("*3" etc.)++#if USE_WW_DEEPSEQ+  import Control.DeepSeq ( NFData )+  import Control.DeepSeq ( rnf )+#endif++#if HANDLE_ATTRS_DATA_CONSTRAINT+  -- Brought back only to add Data d constraint to handleAttrs, which+  -- is a hack so can print something distinct for multiple +-nodes...+  import Data.Data+#endif+--import Data.Data  -- "redundant" last checked++  import Data.Typeable ( Typeable )+#if 1+  import Data.Typeable ( typeOf )+#else+-- XXX These are NOT interchangeable!+#if __GLASGOW_HASKELL__ >= 781+  import Data.Typeable ( typeRep )+#else+  import Data.Typeable ( typeOf )+#endif+#endif+  import Data.Typeable ( mkTyCon3, mkTyConApp )+  import Data.Typeable ( typeRepTyCon )++#if USE_PAR_PATNODE+  import Control.Parallel ( par )+#endif+#if USE_PSEQ_PATNODE+  import Control.Parallel ( pseq )+#endif+#if USE_PING_PATNODE+  import Control.Concurrent ( myThreadId, killThread )+  import Control.Concurrent ( forkIO )+#endif++  import Control.Concurrent ( threadDelay )++  import Data.Int+  import Data.Word+  import Data.Ratio+  import Data.Complex+  import Data.Array+  import Data.Fixed+  import Data.Version++  import Data.Maybe ( Maybe(..), isJust, fromJust, isNothing )++  import Control.Exception ( Exception )+  import Control.Exception ( asyncExceptionFromException )+  import Control.Exception ( throwTo )+  import Control.Exception ( throw )+  import Control.Exception( AsyncException( UserInterrupt ) )++  import Control.Monad ( liftM )++  -- XXX unsafePerformIO *is* used [besides indirectly with trace and throwTo].+  -- Grep the source on a case by case basis...+  import System.IO.Unsafe ( unsafeInterleaveIO )+  import System.IO.Unsafe ( unsafeDupablePerformIO )+  import System.IO.Unsafe ( unsafePerformIO )+  import Control.Exception ( evaluate )++  import System.Random ( randomIO )++  import Debug.Trace ( trace )++-------------------------------------------------------------------------------++#if USE_PING_PATNODE+  data DeepSeqBounded_PingException = DeepSeqBounded_PingException String+    deriving (Show, Typeable)++  instance Exception DeepSeqBounded_PingException+#endif++-------------------------------------------------------------------------------++#if DO_TRACE+  mytrace = trace+#else+  mytrace _ = id+#endif++-------------------------------------------------------------------------------++--infixr 0 $!!++-------------------------------------------------------------------------------++-- XXX NOTE TO SELF: These comments are verbatim from Control.DeepSeq:+  -- | 'deepseqp' evaluates the first argument to the extent specified+  -- by a 'Pattern', before returning the second.+  --+  -- Quoting from the <http://hackage.haskell.org/package/deepseq/docs/Control-DeepSeq.html DeepSeq> documentation (<http://hackage.haskell.org/package/deepseq deepseq> package):+  --+  -- \"<http://hackage.haskell.org/package/deepseq/docs/Control-DeepSeq.html#t:deepseq deepseq> /can be useful for forcing pending exceptions, eradicating space leaks, or forcing lazy I\/O to happen.  It is also useful in conjunction with parallel Strategies (see the/ <http://hackage.haskell.org/package/parallel parallel> /package). /+  --+  -- / There is no guarantee about the ordering of evaluation.  The implementation may evaluate the components of the structure in any order or in parallel.  To impose an actual order on evaluation, use 'pseq' from "Control.Parallel" in the @parallel@ package.\" /+{--} -- XXX LATER: This is flawed for # at root of pattern.+#if ( ! HASKELL98_FRAGMENT ) && ( __GLASGOW_HASKELL__ >= 710 )+  deepseqp :: NFDataP_ictx a => String -> a -> b -> b+--deepseqp :: NFDataP_cctx a => String -> a -> b -> b+#else+#if INCLUDE_SHOW_INSTANCES+  deepseqp :: (Show a, NFDataP a) => String -> a -> b -> b+#else+  deepseqp :: NFDataP a => String -> a -> b -> b+#endif+#endif+#if 0+#elif 0+  deepseqp patstr a b = fromJust $ deepseqp_ (compilePat patstr) a b+--deepseqp patstr = fromJust $ deepseqp_ (compilePat patstr)+#elif 1+  deepseqp patstr = deepseqp_ (compilePat patstr)+#elif 0+  deepseqp patstr a b = rnfp (compilePat patstr) a `seq` b+  -- XXX Partially-applied; is that okay in GHC RULES?+  {-# RULES+    "deepseqp/composition"    forall p1 p2 x.  (.) (deepseqp p2) (deepseqp p1) x = deepseqp_ ( unionPats [compilePat p1, compilePat p2] ) x+      #-}+#endif++  -- | Self-composition fuses via+  --+  -- @+  --     "deepseqp_/composition"+  --        forall p1 p2 x1 x2.+  --            (.) ('deepseqp_' p2 x2) ('deepseqp_' p1 x1)+  --          = 'deepseqp_' ( 'liftPats' [p1, p2] ) (x1,x2)+  -- @+  --+  -- (Other fusion rules, not yet documented, may also be in effect.)+{--}+-- XXX LATER: This is flawed for # at root of pattern.+-- Maybe not quite flawed, just "untestable" if there's bottom at+-- the root of the value (that is to say, the value is (undefined::b).+#if ( ! HASKELL98_FRAGMENT ) && ( __GLASGOW_HASKELL__ >= 710 )+  deepseqp_ :: NFDataP_ictx a => Pattern -> a -> b -> b+--deepseqp_ :: NFDataP_cctx a => Pattern -> a -> b -> b+#else+#if INCLUDE_SHOW_INSTANCES+  deepseqp_ :: (Show a, NFDataP a) => Pattern -> a -> b -> b+#else+  deepseqp_ :: NFDataP a => Pattern -> a -> b -> b+#endif+#endif+#if 0+#elif 0+  deepseqp_ pat@(Node WI _) _ b = b+  deepseqp_ pat@(Node (TR as) chs) a b = if elem ta treps then doit `seq` b else b+   where ta = show $ typeRepTyCon $ typeOf a+         doit = rnfp pat a `seq` b+         treps = typeConstraints as+  deepseqp_ pat@(Node (TI as) chs) a b = if elem ta treps then b else doit `seq` b+   where ta = show $ typeRepTyCon $ typeOf a+         doit = rnfp pat a `seq` b+         treps = typeConstraints as+  deepseqp_ pat a b = rnfp pat a `seq` b+#elif 1+  deepseqp_ pat a b = rnfp pat a `seq` b+  -- XXX Need to double-check that this makes sense; didn't think+  -- it through -- when b != a, things are not so simple.+  -- XXX Partially-applied; is that okay in GHC RULES?+  {-# RULES+    "deepseqp_/composition"    forall p1 p2 x1 x2.  (.) (deepseqp_ p2 x2) (deepseqp_ p1 x1) = deepseqp_ ( liftPats [p1, p2] ) (x1,x2)+      #-}+--  "deepseqp_/composition"    forall p1 p2 x.  (.) (deepseqp_ p2) (deepseqp_ p1) x = deepseqp_ ( unionPats [p1, p2] ) x+#endif++-------------------------------------------------------------------------------++#if 0+  -- | the deep analogue of '$!'.  In the expression @f $!! x@, @x@ is+  -- fully evaluated before the function @f@ is applied to it.+  ($!!) :: (NFData a) => (a -> b) -> a -> b+  f $!! x = x `deepseq` f x+#endif++-- XXX NOTE TO SELF: These comments are verbatim from Control.DeepSeq:+  -- | A variant of 'deepseqp' that is sometimes convenient:+  --+  -- > forcep pat x = deepseqp pat x x   -- (cannot write x `deepseqp pat` x by analogy with x `deepseq` x)+  --+  -- @forcep pat x@ evaluates @x@ to the depth determined by @pat@, and+  -- then returns @x@.  Again from+  -- <http://hackage.haskell.org/package/deepseq deepseq>:+  -- / \"Note that @forcep pat x@ only takes effect when the value of @forcep pat x@ itself is demanded, so essentially it turns shallow evaluation into evaluation to arbitrary bounded depth.\" /+  --+  -- Composition fuses (see 'forcep_').+{--}+-- XXX What about fusion of mixed applications?...+-- XXX LATER: This is flawed for # at root of pattern.+#if ( ! HASKELL98_FRAGMENT ) && ( __GLASGOW_HASKELL__ >= 710 )+  forcep :: NFDataP_ictx a => String -> a -> a+--forcep :: NFDataP_cctx a => String -> a -> a+#else+#if INCLUDE_SHOW_INSTANCES+  forcep :: (Show a, NFDataP a) => String -> a -> a+#else+  forcep :: NFDataP a => String -> a -> a+#endif+#endif+#if 0+#elif 0+  forcep patstr x+   | p          = fromJust ma+-- | otherwise  = error "here"+   | otherwise  = undefined::a+   where ma = deepseqp_ (compilePat patstr) x x+         p = isJust ma+#elif 0+  forcep patstr x = fromJust $ deepseqp_ (compilePat patstr) x x+#elif 0+  forcep patstr x+   | b          = x+   | otherwise  = fromJust y+   where y = deepseqp_ (compilePat patstr) x (Just x)+         pat@(Node pas chs) = compilePat patstr+         b | WI <- pas  = True+           | TR <- pas  = True+           | TN <- pas  = True+           | TW <- pas  = True+           | TI <- pas  = True+           | otherwise  = False+#elif 1+  forcep patstr x = deepseqp_ (compilePat patstr) x x+--forcep patstr x = deepseqp patstr x x+  {-# RULES+    "forcep/composition"    forall p1 p2 x.  (.) (forcep p2) (forcep p1) x = forcep_ ( unionPats [compilePat p1, compilePat p2] ) x+      #-}+#endif++  -- | Self-composition fuses via+  --+  -- @+  --     "forcep_/composition"+  --        forall p1 p2 x.+  --            (.) ('forcep_' p2) ('forcep_' p1) x+  --          = 'forcep_' ( 'unionPats' [p1, p2] ) x+  -- @+  --+  -- (Other fusion rules, not yet documented, may also be in effect.)+{--}+-- XXX LATER: This is flawed for # at root of pattern.+#if ( ! HASKELL98_FRAGMENT ) && ( __GLASGOW_HASKELL__ >= 710 )+  forcep_ :: NFDataP_ictx a => Pattern -> a -> a+--forcep_ :: NFDataP_cctx a => Pattern -> a -> a+#else+#if INCLUDE_SHOW_INSTANCES+  forcep_ :: (Show a, NFDataP a) => Pattern -> a -> a+#else+  forcep_ :: NFDataP a => Pattern -> a -> a+#endif+#endif+#if 0+  forcep_ pat x = fromJust $ deepseqp_ pat x x+#else+  forcep_ pat x = deepseqp_ pat x x+  {-# RULES+    "forcep_/composition"    forall p1 p2 x.  (.) (forcep_ p2) (forcep_ p1) x = forcep_ ( unionPats [p1, p2] ) x+      #-}+#endif++-------------------------------------------------------------------------------++#if ! HASKELL98_FRAGMENT+-- We don't need 7.10 for tuple predicates /here/, but when try to+-- use in seqaid, the TH splice complains+--   Can't represent tuple predicates in Template Haskell:+--     Control.DeepSeq.Bounded.NFDataP_new_grammar.NFDataP_cctx+-- That is with GHC 7.8.4.+-- So we need template-haskell-2.10, which means need base >= base-4.8.0.0,+-- which means need GHC >= 7.10.+#if __GLASGOW_HASKELL__ >= 710+  -- XXX Not H98! -XConstraintKinds+  type NFDataP_cctx a+        = (+              Typeable a+#if HANDLE_ATTRS_DATA_CONSTRAINT+            , Data a+#endif+            , NFDataN a+#if USE_WW_DEEPSEQ+            , NFData a+#endif+          )+#if 0+-- XXX Because TH < 2.10 cannot hand tuple predicates,+-- even if the corresponding GHC can!+-- And this didn't help anyway, still get the error+-- when TH runs in seqaid...+  type NFDataP_ictx a+        = (+              Typeable a+#if HANDLE_ATTRS_DATA_CONSTRAINT+            , Data a+#endif+            , NFDataN a+#if USE_WW_DEEPSEQ+            , NFData a+#endif+            , NFDataP a+#if INCLUDE_SHOW_INSTANCES+            , Show a+#endif+          )+#else+  type NFDataP_ictx a+        = (+              NFDataP_cctx a+            , NFDataP a+#if INCLUDE_SHOW_INSTANCES+            , Show a+#endif+          )+#endif+#endif+#endif++-------------------------------------------------------------------------------++  -- | A class of types that can be evaluated over an arbitrary finite pattern.+#if ( ! HASKELL98_FRAGMENT ) && ( __GLASGOW_HASKELL__ >= 710 )+  class NFDataP_cctx a => NFDataP a where+#else+  class (+          Typeable a+#if HANDLE_ATTRS_DATA_CONSTRAINT+        , Data a+#endif+        , NFDataN a+#if USE_WW_DEEPSEQ+        , NFData a+#endif+        ) => NFDataP a where+#endif+    -- | Self-composition fuses via+    --+    -- @+    --     "rnfp/composition"+    --        forall p1 p2 x.+    --            (.) ('rnfp' p2) ('rnfp' p1) x+    --          = 'rnfp' ( 'unionPats' [p1, p2] ) x+    -- @+    --+    -- (Other fusion rules, not yet documented, may also be in effect.)+    {-  NOINLINE rnfp #-}+#if INCLUDE_SHOW_INSTANCES+    rnfp :: Show a => Pattern -> a -> ()+#else+    rnfp :: Pattern -> a -> ()+#endif+#if 0+--  rnfp p x | p `seq` trace "Boo!" () `seq` p == Node XX []  = undefined  -- does NOT work+--  rnfp p x | trace "Boo!" p `seq` p == Node XX []  = undefined  -- WORKS!!!+--  rnfp p x | trace "Boo!" () `seq` p == (trace "FOO!!" (Node XX []))  = undefined  -- FOO!! /is/ printed, though only once (like Boo)+--  rnfp p x | trace "Boo!" () `seq` p == Node XX []  = undefined  -- NOT works (printed once only)+--  rnfp p x | (trace "Boo!" p) == Node XX []  = undefined  -- WORKS!!! (printed every time)+--  rnfp p x | trace "Boo!" () `seq` p == Node TN{} []  = undefined+--  rnfp p x | trace "Boo!" () `seq` False  = undefined+--  rnfp p x | trace "Boo!" True, p `seq` False  = undefined+--  rnfp p x | trace "Boo!" False  = undefined+#endif+#if 1+    rnfp p x | handleAttrs p x == Node XX []  = undefined+--  rnfp p@(Node pn _) x | as <- getPatNodeAttrs pn, 9 == uniqueID as  = error $ showPatNodeRaw pn+--  rnfp p@(Node pn@(WI _) _) x = error $ showPatNodeRaw pn+--  rnfp p@(Node pn@WI{} _) x = error $ showPatNodeRaw pn+--  rnfp p@(Node WI{} _) x = handleAttrs p x `seq` ()+    rnfp (Node WI{} _) _ = ()+#else+    rnfp (Node WI{} _) _ = ()+#endif+    rnfp (Node (TR as) chs) d = if elem td treps then d `seq` () else ()+     where td = show $ typeRepTyCon $ typeOf d+           treps = typeConstraints as+    rnfp (Node (TI as) chs) d = if elem td treps then () else d `seq` ()+     where td = show $ typeRepTyCon $ typeOf d+           treps = typeConstraints as+#if USE_WW_DEEPSEQ+    -- complement of TI, equivalent to TR in this special case+    rnfp (Node (TW as) chs) d = if elem td treps then d `seq` () else ()+     where td = show $ typeRepTyCon $ typeOf d+           treps = typeConstraints as+#endif+#if 1+    rnfp _ d = d `seq` ()+--  rnfp _ _ = ()+#else+    -- XXX temporarily (at least) commenting out; not making any+    -- use of patternShapeOK -- but there is room for more+    -- error-trapping code in here, definitely...+    rnfp pat a | not $ patternShapeOK pat a  = ()+               | otherwise  = rnf a+#endif++  {-# RULES+    "rnfp/composition"    forall p1 p2 x.  (.) (rnfp p2) (rnfp p1) x = rnfp ( unionPats [p1, p2] ) x+      #-}+--  "rnfp/composition"    forall p1 p2 x.  compose (rnfp p2) (rnfp p1) x = rnfp ( unionPats [p1, p2] ) x+--  "rnfp/composition"    forall p1 p2 x.  ( rnfp p2 . rnfp p1 ) x = rnfp ( unionPats [p1, p2] ) x++-------------------------------------------------------------------------------++#if ( ! HASKELL98_FRAGMENT ) && ( __GLASGOW_HASKELL__ >= 710 )+  rnfp' :: NFDataP_ictx a => PatNode -> () -> a -> ()+#else+#if USE_WW_DEEPSEQ+  rnfp' :: (Typeable a, NFDataN a, NFData a) => PatNode -> () -> a -> ()+#else+  rnfp' :: (Typeable a, NFDataN a) => PatNode -> () -> a -> ()+#endif+#endif+  rnfp' pas recurs d+   -- I can only conclude that we've already evaluated the argument+   -- by the time this code runs (or that we evaluate it after...).+   -- But this code doesn't do the dirty deed!+   = {-trace ( "rnfp' " ++ show pat) $-}+     let+         td = show $ typeRepTyCon $ typeOf d  -- no problem on bottom+         as = getPatNodeAttrs pas+         treps = typeConstraints as+         n = depth as+     in+#if USE_PAR_PATNODE+     if doSpark as+     then+       case pas of+        WS{} -> () `par` ()+        WR{} -> recurs `par` ()+        WN{} -> rnfn n d `par` ()+#if USE_WW_DEEPSEQ+        WW{} -> rnf d `par` ()  -- should reimplement deepseq for uniformity...+#endif+        WI{} -> error "rnfp: unexpected =WI (please report this bug!)"+        _ -> error $ "rnfp: Unexpected PatNode (with doSpark): " ++ show pas ++ "(please report this bug!)"+     else+#endif+       case pas of+        WR{} -> recurs+        WS{} -> ()+--      WS{} -> d `seq` ()+        WN{} -> rnfn n d+#if USE_WW_DEEPSEQ+        WW{} -> rnf d  -- should reimplement deepseq for uniformity...+#endif+#if 0+        -- This code stays the same whether we (are able to) compare+        -- actual TypeRep's for equality, or we just hack it+        -- and match:  show . typeRepTyCon . typeOf+        TR{} ->  if       elem td treps then recurs else ()+#endif+#if 0+        -- This is not right. To pull this off (b/c it depends on+        -- types in the value you're matching with), need to construct+        -- the pattern dynamically.  In particular, to produce Nil+        -- where a TR (or TS) constraint causes (or would cause)+        -- match failure.+        TS{} ->  if       elem td treps then () else ()+#endif+        TN{} ->  if       elem td treps then rnfn n d else ()+#if USE_WW_DEEPSEQ+        TW{} ->  if       elem td treps then rnf d else ()+#endif+#if 0+        NTR{} -> if not $ elem td treps then recurs else ()+        NTN{} -> if not $ elem td treps then rnfn n d else ()+#if USE_WW_DEEPSEQ+        NTW{} -> if not $ elem td treps then rnf d else ()+#endif+#endif+        -- these handled upstream+        WI{} -> error "rnfp: unexpected WI (please report this bug!)"+        TR{} -> error "rnfp: unexpected TR (please report this bug!)"+        TI{} -> error "rnfp: unexpected TI (please report this bug!)"+        _ -> error $ "rnfp: Unexpected PatNode: " ++ show pas ++ " (please report this bug!)"++-------------------------------------------------------------------------------++#if 0+  compose = (.)+  {-# NOINLINE compose #-}+  -- Can't do this, unfortunately.  GHC warns it may get inlined before+  -- rules have a chance to fire.  I would rather avoid forcing the API+  -- user to use some custom "compose" function, since base (.) works+  -- perfectly, except it's hard to control its inlining...+  {-  NOINLINE (.) #-}+#endif++-------------------------------------------------------------------------------+-- Base nullary types.++  instance NFDataP Int+  instance NFDataP Word+  instance NFDataP Integer+  instance NFDataP Float+  instance NFDataP Double++  instance NFDataP Char+  instance NFDataP Bool+  instance NFDataP ()++  instance NFDataP Int8+  instance NFDataP Int16+  instance NFDataP Int32+  instance NFDataP Int64++  instance NFDataP Word8+  instance NFDataP Word16+  instance NFDataP Word32+  instance NFDataP Word64++-------------------------------------------------------------------------------+--- Fixed a++  instance Typeable a => NFDataP (Fixed a)+--instance NFDataP (Fixed a)++-------------------------------------------------------------------------------+--- a -> b++  -- [Quoted from deepseq:]+  -- This instance is for convenience and consistency with 'seq'.+  -- This assumes that WHNF is equivalent to NF for functions.+#if ( ! HASKELL98_FRAGMENT ) && ( __GLASGOW_HASKELL__ >= 710 )+  instance (NFDataP_ictx a, NFDataP_ictx b) => NFDataP (a -> b)+#else+  instance (+             Typeable a, Typeable b+#if HANDLE_ATTRS_DATA_CONSTRAINT+           , Data a, Data b  -- XXX why only needed in THIS instance?+#endif+           ) => NFDataP (a -> b)+--instance NFDataP (a -> b)+#endif++-------------------------------------------------------------------------------+--- Ratio a++  -- not taken to be a level of depth+#if ( ! HASKELL98_FRAGMENT ) && ( __GLASGOW_HASKELL__ >= 710 )+  instance (NFDataP_ictx a, Integral a) => NFDataP (Ratio a) where+#else+#if INCLUDE_SHOW_INSTANCES+  instance (Show a, Integral a, NFDataP a) => NFDataP (Ratio a) where+#else+  instance (Integral a, NFDataP a) => NFDataP (Ratio a) where+#endif+#endif+    -- XXX This is very dubious!...+    {-  NOINLINE rnfp #-}+    rnfp p x | handleAttrs p x == Node XX []  = undefined+    rnfp (Node WI{} _) _ = ()+    rnfp pat x = rnfp pat (numerator x, denominator x)++-------------------------------------------------------------------------------+--- Complex a++  -- Note that (Complex a) constructor (:+) has strict fields,+  -- so unwrapping the ctor also forces both components.+#if ( ! HASKELL98_FRAGMENT ) && ( __GLASGOW_HASKELL__ >= 710 )+  instance (NFDataP_ictx a, RealFloat a) => NFDataP (Complex a) where+#else+#if INCLUDE_SHOW_INSTANCES+  instance (Show a, RealFloat a, NFDataP a) => NFDataP (Complex a) where+#else+  instance (RealFloat a, NFDataP a) => NFDataP (Complex a) where+#endif+#endif+    {-  NOINLINE rnfp #-}+    rnfp p x | handleAttrs p x == Node XX []  = undefined+    rnfp (Node WI{} _) _ = ()+    rnfp pat@(Node pas chs) d+     | TR{} <- pas  = if elem td treps then recurs else ()+#if USE_WW_DEEPSEQ+     | TI{} <- pas  = if elem td treps then () else rnf d+     | TW{} <- pas  = if elem td treps then rnf d else ()+#else+     | TI{} <- pas  = if elem td treps then () else rnfn 999999 d  -- XXX thack!+#endif+     | otherwise    = rnfp' pas recurs d+     where+      as = getPatNodeAttrs pas+      treps = typeConstraints as+      td = show $ typeRepTyCon $ typeOf d+      recurs = case length chs of+        0 -> case pas of+              WS{} -> ()+              _ -> pat_match_fail+        2 -> let [px,py] = chs+                 (x:+y) = d+#if USE_PSEQ_PATNODE+             in pseq_condition pat [ rnfp px x+                                   , rnfp py y+                                   ]+#else+             in       rnfp px x+                `seq` rnfp py y+#endif+                `seq` ()  -- needed?+        _ -> pat_match_fail+      pat_match_fail = patMatchFail' "(Complex a)" pas chs d++-------------------------------------------------------------------------------+--- Maybe a++-- XXX Never until now (so much later) did I properly consider how to+-- handle a no-arg (nullary) constructor! It's not hard, but it's+-- significantly different than the other cases, as there's no+-- subvalue we can grab hold of -- there's no "d"; so this invalidates+-- all the code, in the posary (complement of nullary, coinage :) case+-- case, which references d.+#if ( ! HASKELL98_FRAGMENT ) && ( __GLASGOW_HASKELL__ >= 710 )+  instance NFDataP_ictx a => NFDataP (Maybe a) where+#else+#if INCLUDE_SHOW_INSTANCES+  instance (Show a, NFDataP a) => NFDataP (Maybe a) where+#else+  instance NFDataP a => NFDataP (Maybe a) where+#endif+#endif+    {-  NOINLINE rnfp #-}+    rnfp p x | handleAttrs p x == Node XX []  = undefined+    rnfp (Node WI{} _) _ = ()+    rnfp pat@(Node pas chs) Nothing+     | not $ null chs  = pat_match_fail+     | otherwise       = ()+     where+      pat_match_fail = patMatchFail' "Nothing" pas chs ()+    rnfp (Node pas chs) (Just d)+     | TR{} <- pas  = if elem td treps then recurs else ()+#if USE_WW_DEEPSEQ+     | TI{} <- pas  = if elem td treps then () else rnf d+     | TW{} <- pas  = if elem td treps then rnf d else ()+#else+     | TI{} <- pas  = if elem td treps then () else rnfn 999999 d  -- XXX thack!+#endif+     | otherwise    = rnfp' pas recurs d+     where+      as = getPatNodeAttrs pas+      treps = typeConstraints as+      td = show $ typeRepTyCon $ typeOf d+      recurs = case length chs of+        0 -> case pas of+              WS{} -> ()+              _ -> pat_match_fail+        1 -> let [p_J] = chs+             in       rnfp p_J d+                `seq` ()  -- needed?+        _ -> pat_match_fail+      pat_match_fail = patMatchFail' "Just" pas chs d+    rnfp (Node pas chs) d = patMatchFail pas chs d  -- unreachable++-------------------------------------------------------------------------------+--- Either a b++#if ( ! HASKELL98_FRAGMENT ) && ( __GLASGOW_HASKELL__ >= 710 )+  instance (NFDataP_ictx a, NFDataP_ictx b) => NFDataP (Either a b) where+#else+#if INCLUDE_SHOW_INSTANCES+  instance (Show a, Show b, NFDataP a, NFDataP b) => NFDataP (Either a b) where+#else+  instance (NFDataP a, NFDataP b) => NFDataP (Either a b) where+#endif+#endif+    {-  NOINLINE rnfp #-}+    rnfp p x | handleAttrs p x == Node XX []  = undefined+    rnfp (Node WI{} _) _ = ()+    rnfp (Node pas chs) (Left d)+     | TR{} <- pas  = if elem td treps then recurs else ()+#if USE_WW_DEEPSEQ+     | TI{} <- pas  = if elem td treps then () else rnf d+     | TW{} <- pas  = if elem td treps then rnf d else ()+#else+     | TI{} <- pas  = if elem td treps then () else rnfn 999999 d  -- XXX thack!+#endif+     | otherwise    = rnfp' pas recurs d+     where+      as = getPatNodeAttrs pas+      treps = typeConstraints as+      td = show $ typeRepTyCon $ typeOf d+      recurs = case length chs of+        0 -> case pas of+              WS{} -> ()+              _ -> pat_match_fail+        1 -> let [p_L] = chs+             in       rnfp p_L d+                `seq` ()  -- needed?+        _ -> pat_match_fail+      pat_match_fail = patMatchFail' "Left" pas chs d+--    pat_match_fail = patMatchFail' "(Either a b)" pas chs d+    rnfp (Node pas chs) (Right d)+     | TR{} <- pas  = if elem td treps then recurs else ()+#if USE_WW_DEEPSEQ+     | TI{} <- pas  = if elem td treps then () else rnf d+     | TW{} <- pas  = if elem td treps then rnf d else ()+#else+     | TI{} <- pas  = if elem td treps then () else rnfn 999999 d  -- XXX thack!+#endif+     | otherwise     = rnfp' pas recurs d+     where+      as = getPatNodeAttrs pas+      treps = typeConstraints as+      td = show $ typeRepTyCon $ typeOf d+      recurs = case length chs of+        0 -> case pas of+              WS{} -> ()+              _ -> pat_match_fail+        1 -> let [p_R] = chs+             in       rnfp p_R d+                `seq` ()  -- needed?+        _ -> pat_match_fail+      pat_match_fail = patMatchFail' "Right" pas chs d+--    pat_match_fail = patMatchFail' "(Either a b)" pas chs d+    rnfp (Node pas chs) d = patMatchFail pas chs d  -- unreachable++-------------------------------------------------------------------------------+--- Data.Version.Version++--- #if __GLASGOW_HASKELL__ < 781+--- -- requires -XStandaloneDeriving+--- -- orphan instance, but better than dropping support+--- -- (It seems it already has its Show instance!)+--- deriving instance Data Data.Version.Version+--- #endif++--deriving instance Data TypeRep  -- can't b/c not all data ctors are in scope!++  -- Data.Version ctor does /not/ have strict fields.+  instance NFDataP Data.Version.Version where+    {-  NOINLINE rnfp #-}+    rnfp p x | handleAttrs p x == Node XX []  = undefined+    rnfp (Node WI{} _) _ = ()+    rnfp pat@(Node pas chs) d+     | TR{} <- pas  = if elem td treps then recurs else ()+#if USE_WW_DEEPSEQ+     | TI{} <- pas  = if elem td treps then () else rnf d+     | TW{} <- pas  = if elem td treps then rnf d else ()+#else+     | TI{} <- pas  = if elem td treps then () else rnfn 999999 d  -- XXX thack!+#endif+     | otherwise    = rnfp' pas recurs d+     where+      as = getPatNodeAttrs pas+      treps = typeConstraints as+      td = show $ typeRepTyCon $ typeOf d+      recurs = case length chs of+        0 -> case pas of+              WS{} -> ()+              _ -> pat_match_fail+        2 -> let [pbr,ptags] = chs+                 Data.Version.Version branch tags = d+#if USE_PSEQ_PATNODE+             in pseq_condition pat [rnfp pbr branch, rnfp ptags tags]+#else+             in       rnfp pbr branch+                `seq` rnfp ptags tags+#endif+                `seq` ()  -- needed?+        _ -> pat_match_fail+      pat_match_fail = patMatchFail' "Data.Version.Version" pas chs d++-------------------------------------------------------------------------------+--- [a]++  -- Data.List ctors do /not/ have strict fields (i.e. (:) is not strict).+#if ( ! HASKELL98_FRAGMENT ) && ( __GLASGOW_HASKELL__ >= 710 )+  instance NFDataP_ictx a => NFDataP [a] where+#else+#if INCLUDE_SHOW_INSTANCES+  instance (Show a, NFDataP a) => NFDataP [a] where+#else+  instance NFDataP a => NFDataP [a] where+#endif+#endif+    {-  NOINLINE rnfp #-}+    rnfp p x | handleAttrs p x == Node XX []  = undefined+    rnfp (Node WI{} _) _ = ()+    rnfp _ [] = ()  -- perhaps dubious?...+    rnfp pat@(Node pas chs) d+     | TR{} <- pas  = if elem td treps then recurs else ()+#if USE_WW_DEEPSEQ+     | TI{} <- pas  = if elem td treps then () else rnf d+     | TW{} <- pas  = if elem td treps then rnf d else ()+#else+     | TI{} <- pas  = if elem td treps then () else rnfn 999999 d  -- XXX thack!+#endif+     | otherwise    = rnfp' pas recurs d+     where+      as = getPatNodeAttrs pas+      treps = typeConstraints as+      td = show $ typeRepTyCon $ typeOf d+      recurs = case length chs of+        0 -> case pas of+              WS{} -> ()+              _ -> pat_match_fail+        2 -> let [px,pxs] = chs+                 (x:xs) = d+#if USE_PSEQ_PATNODE+             in pseq_condition pat [rnfp px x, rnfp pxs xs]+#else+             in       rnfp px x+                `seq` rnfp pxs xs+#endif+                `seq` ()  -- needed?+        _ -> pat_match_fail+      pat_match_fail = patMatchFail' "[a]" pas chs d++-------------------------------------------------------------------------------+--- Array a b++  -- Data.Array ctor does /not/ have strict fields.+  -- not taken to be a level of depth+#if ( ! HASKELL98_FRAGMENT ) && ( __GLASGOW_HASKELL__ >= 710 )+  instance (Ix a, NFDataP_ictx a, NFDataP_ictx b) => NFDataP (Array a b) where+#else+#if INCLUDE_SHOW_INSTANCES+  instance (Show a, Show b, Ix a, NFDataP a, NFDataP b) => NFDataP (Array a b) where+#else+  instance (Ix a, NFDataP a, NFDataP b) => NFDataP (Array a b) where+#endif+#endif+    -- XXX This is very dubious!...+    {-  NOINLINE rnfp #-}+    rnfp p x | handleAttrs p x == Node XX []  = undefined+    rnfp (Node WI{} _) _ = ()+    rnfp pas x =        rnfp pas (bounds x, Data.Array.elems x)+                  `seq` ()  -- needed?++-------------------------------------------------------------------------------+--- (a,b)++#if ( ! HASKELL98_FRAGMENT ) && ( __GLASGOW_HASKELL__ >= 710 )+  instance (NFDataP_ictx a, NFDataP_ictx b) => NFDataP (a,b) where+#else+#if INCLUDE_SHOW_INSTANCES+  instance (Show a,Typeable a,NFDataP a, Show b,Typeable b,NFDataP b) => NFDataP (a,b) where+#else+  instance (Typeable a,NFDataP a, Typeable b,NFDataP b) => NFDataP (a,b) where+#endif+#endif+    {-  NOINLINE rnfp #-}+--  rnfp _ _ = error "booy"+--  rnfp p x | trace "hoop!" (handleAttrs p x) `seq` p == Node XX []  = undefined+    rnfp p x | handleAttrs p x `seq` p == Node XX []  = undefined+    rnfp (Node WI{} _) _ = ()+    rnfp pat@(Node pas chs) d+     | TR{} <- pas  = if elem td treps then recurs else ()+#if USE_WW_DEEPSEQ+     | TI{} <- pas  = if elem td treps then () else rnf d+     | TW{} <- pas  = if elem td treps then rnf d else ()+#else+     | TI{} <- pas  = if elem td treps then () else rnfn 999999 d  -- XXX thack!+#endif+     | otherwise    = rnfp' pas recurs d+     where+      as = getPatNodeAttrs pas+      treps = typeConstraints as+      td = show $ typeRepTyCon $ typeOf d+      recurs = case length chs of+        0 -> case pas of+              WS{} -> ()+              _ -> pat_match_fail+        2 -> let [px,py] = chs+                 (x,y) = d+#if USE_PSEQ_PATNODE+             in pseq_condition pat [rnfp px x, rnfp py y]+#else+             in       rnfp px x+                `seq` rnfp py y+#endif+                `seq` ()  -- needed?+        _ -> pat_match_fail+      pat_match_fail = patMatchFail' "(,)" pas chs d++-------------------------------------------------------------------------------+--- (a,b,c)++#if ( ! HASKELL98_FRAGMENT ) && ( __GLASGOW_HASKELL__ >= 710 )+  instance (NFDataP_ictx a, NFDataP_ictx b, NFDataP_ictx c) => NFDataP (a,b,c) where+#else+#if INCLUDE_SHOW_INSTANCES+  instance (Show a, Typeable a, NFDataP a, Show b, Typeable b, NFDataP b, Show c, Typeable c, NFDataP c) => NFDataP (a,b,c) where+#else+  instance (Typeable a, NFDataP a, Typeable b, NFDataP b, Typeable c, NFDataP c) => NFDataP (a,b,c) where+#endif+#endif+    {-  NOINLINE rnfp #-}+    rnfp p x | handleAttrs p x == Node XX []  = undefined+    rnfp (Node WI{} _) _ = ()+    rnfp pat@(Node pas chs) d+     | TR{} <- pas  = if elem td treps then recurs else ()+#if USE_WW_DEEPSEQ+     | TI{} <- pas  = if elem td treps then () else rnf d+     | TW{} <- pas  = if elem td treps then rnf d else ()+#else+     | TI{} <- pas  = if elem td treps then () else rnfn 999999 d  -- XXX thack!+#endif+     | otherwise    = rnfp' pas recurs d+     where+      as = getPatNodeAttrs pas+      treps = typeConstraints as+      td = show $ typeRepTyCon $ typeOf d+      recurs = case length chs of+        0 -> case pas of+              WS{} -> ()+              _ -> pat_match_fail+        3 -> {-trace "WWW" $-}+             let [px,py,pz] = chs+                 (x,y,z) = d+#if USE_PSEQ_PATNODE+             in pseq_condition pat [ rnfp px x+                                   , rnfp py y+                                   , rnfp pz z+                                   ]+#else+             in       ({-trace "XXX" $-} rnfp px x)+                `seq` ({-trace "YYY" $-} rnfp py y)+-- This WILL change the semantics unfortunately...+--              `seq` (trace ("YYY "++show py++" "++show y) $ rnfp py y)+                `seq` ({-trace "ZZZ" $-} rnfp pz z)+#endif+                `seq` ()  -- needed?+        _ -> pat_match_fail+      pat_match_fail = patMatchFail' "(,,)" pas chs d++-------------------------------------------------------------------------------+--- (a,b,c,d)++#if ( ! HASKELL98_FRAGMENT ) && ( __GLASGOW_HASKELL__ >= 710 )+  instance (NFDataP_ictx a, NFDataP_ictx b, NFDataP_ictx c, NFDataP_ictx d) => NFDataP (a,b,c,d) where+#else+#if INCLUDE_SHOW_INSTANCES+  instance (Show a, Typeable a, NFDataP a, Show b, Typeable b, NFDataP b, Show c, Typeable c, NFDataP c, Show d, Typeable d, NFDataP d) => NFDataP (a,b,c,d) where+#else+  instance (Typeable a, NFDataP a, Typeable b, NFDataP b, Typeable c, NFDataP c, Typeable d, NFDataP d) => NFDataP (a,b,c,d) where+#endif+#endif+    {-  NOINLINE rnfp #-}+    rnfp p x | handleAttrs p x == Node XX []  = undefined+    rnfp (Node WI{} _) _ = ()+    rnfp pat@(Node pas chs) d+     | TR{} <- pas  = if elem td treps then recurs else ()+#if USE_WW_DEEPSEQ+     | TI{} <- pas  = if elem td treps then () else rnf d+     | TW{} <- pas  = if elem td treps then rnf d else ()+#else+     | TI{} <- pas  = if elem td treps then () else rnfn 999999 d  -- XXX thack!+#endif+     | otherwise    = rnfp' pas recurs d+     where+      as = getPatNodeAttrs pas+      treps = typeConstraints as+      td = show $ typeRepTyCon $ typeOf d+      recurs = case length chs of+        0 -> case pas of+              WS{} -> ()+              _ -> pat_match_fail+        4 -> let [px1,px2,px3,px4] = chs+                 (x1,x2,x3,x4) = d+#if USE_PSEQ_PATNODE+             in pseq_condition pat [ rnfp px1 x1+                                   , rnfp px2 x2+                                   , rnfp px3 x3+                                   , rnfp px4 x4+                                   ]+#else+             in       rnfp px1 x1+                `seq` rnfp px2 x2+                `seq` rnfp px3 x3+                `seq` rnfp px4 x4+#endif+                `seq` ()  -- needed?+        _ -> pat_match_fail+      pat_match_fail = patMatchFail' "(,,,)" pas chs d++-------------------------------------------------------------------------------+--- (a,b,c,d,e)++#if ( ! HASKELL98_FRAGMENT ) && ( __GLASGOW_HASKELL__ >= 710 )+  instance (NFDataP_ictx a, NFDataP_ictx b, NFDataP_ictx c, NFDataP_ictx d, NFDataP_ictx e) =>+#else+#if INCLUDE_SHOW_INSTANCES+  instance (Show a, Typeable a, NFDataP a, Show b, Typeable b, NFDataP b, Show c, Typeable c, NFDataP c, Show d, Typeable d, NFDataP d, Show e, Typeable e, NFDataP e) =>+#else+  instance (Typeable a, NFDataP a, Typeable b, NFDataP b, Typeable c, NFDataP c, Typeable d, NFDataP d, Typeable e, NFDataP e) =>+#endif+#endif+         NFDataP (a, b, c, d, e) where+    {-  NOINLINE rnfp #-}+    rnfp p x | handleAttrs p x == Node XX []  = undefined+    rnfp (Node WI{} _) _ = ()+    rnfp pat@(Node pas chs) d+     | TR{} <- pas  = if elem td treps then recurs else ()+#if USE_WW_DEEPSEQ+     | TI{} <- pas  = if elem td treps then () else rnf d+     | TW{} <- pas  = if elem td treps then rnf d else ()+#else+     | TI{} <- pas  = if elem td treps then () else rnfn 999999 d  -- XXX thack!+#endif+     | otherwise    = rnfp' pas recurs d+     where+      as = getPatNodeAttrs pas+      treps = typeConstraints as+      td = show $ typeRepTyCon $ typeOf d+      recurs = case length chs of+        0 -> case pas of+              WS{} -> ()+              _ -> pat_match_fail+        5 -> let [px1,px2,px3,px4,px5] = chs+                 (x1,x2,x3,x4,x5) = d+#if USE_PSEQ_PATNODE+             in pseq_condition pat [ rnfp px1 x1+                                   , rnfp px2 x2+                                   , rnfp px3 x3+                                   , rnfp px4 x4+                                   , rnfp px5 x5+                                   ]+#else+             in       rnfp px1 x1+                `seq` rnfp px2 x2+                `seq` rnfp px3 x3+                `seq` rnfp px4 x4+                `seq` rnfp px5 x5+#endif+                `seq` ()  -- needed?+        _ -> pat_match_fail+      pat_match_fail = patMatchFail' "(,,,,)" pas chs d++-------------------------------------------------------------------------------+--- (a,b,c,d,e,f)++#if ( ! HASKELL98_FRAGMENT ) && ( __GLASGOW_HASKELL__ >= 710 )+  instance (NFDataP_ictx a, NFDataP_ictx b, NFDataP_ictx c, NFDataP_ictx d, NFDataP_ictx e, NFDataP_ictx f) =>+#else+#if INCLUDE_SHOW_INSTANCES+  instance (Show a, Typeable a, NFDataP a, Show b, Typeable b, NFDataP b, Show c, Typeable c, NFDataP c, Show d, Typeable d, NFDataP d, Show e, Typeable e, NFDataP e, Show f, Typeable f, NFDataP f) =>+#else+  instance (Typeable a, NFDataP a, Typeable b, NFDataP b, Typeable c, NFDataP c, Typeable d, NFDataP d, Typeable e, NFDataP e, Typeable f, NFDataP f) =>+#endif+#endif+         NFDataP (a, b, c, d, e, f) where+    {-  NOINLINE rnfp #-}+    rnfp p x | handleAttrs p x == Node XX []  = undefined+    rnfp (Node WI{} _) _ = ()+    rnfp pat@(Node pas chs) d+     | TR{} <- pas  = if elem td treps then recurs else ()+#if USE_WW_DEEPSEQ+     | TI{} <- pas  = if elem td treps then () else rnf d+     | TW{} <- pas  = if elem td treps then rnf d else ()+#else+     | TI{} <- pas  = if elem td treps then () else rnfn 999999 d  -- XXX thack!+#endif+     | otherwise    = rnfp' pas recurs d+     where+      as = getPatNodeAttrs pas+      treps = typeConstraints as+      td = show $ typeRepTyCon $ typeOf d+      recurs = case length chs of+        0 -> case pas of+              WS{} -> ()+              _ -> pat_match_fail+        6 -> let [px1,px2,px3,px4,px5,px6] = chs+                 (x1,x2,x3,x4,x5,x6) = d+#if USE_PSEQ_PATNODE+             in pseq_condition pat [ rnfp px1 x1+                                   , rnfp px2 x2+                                   , rnfp px3 x3+                                   , rnfp px4 x4+                                   , rnfp px5 x5+                                   , rnfp px6 x6+                                   ]+#else+             in       rnfp px1 x1+                `seq` rnfp px2 x2+                `seq` rnfp px3 x3+                `seq` rnfp px4 x4+                `seq` rnfp px5 x5+                `seq` rnfp px6 x6+#endif+                `seq` ()  -- needed?+        _ -> pat_match_fail+      pat_match_fail = patMatchFail' "(,,,,,)" pas chs d++-------------------------------------------------------------------------------+--- (a,b,c,d,e,f,g)++#if ( ! HASKELL98_FRAGMENT ) && ( __GLASGOW_HASKELL__ >= 710 )+  instance (NFDataP_ictx a, NFDataP_ictx b, NFDataP_ictx c, NFDataP_ictx d, NFDataP_ictx e, NFDataP_ictx f, NFDataP_ictx g) =>+#else+#if INCLUDE_SHOW_INSTANCES+  instance (Show a, Typeable a, NFDataP a, Show b, Typeable b, NFDataP b, Show c, Typeable c, NFDataP c, Show d, Typeable d, NFDataP d, Show e, Typeable e, NFDataP e, Show f, Typeable f, NFDataP f, Show g, Typeable g, NFDataP g) =>+#else+  instance (Typeable a, NFDataP a, Typeable b, NFDataP b, Typeable c, NFDataP c, Typeable d, NFDataP d, Typeable e, NFDataP e, Typeable f, NFDataP f, Typeable g, NFDataP g) =>+#endif+#endif+         NFDataP (a, b, c, d, e, f, g) where+    {-  NOINLINE rnfp #-}+    rnfp p x | handleAttrs p x == Node XX []  = undefined+    rnfp (Node WI{} _) _ = ()+    rnfp pat@(Node pas chs) d+     | TR{} <- pas  = if elem td treps then recurs else ()+#if USE_WW_DEEPSEQ+     | TI{} <- pas  = if elem td treps then () else rnf d+     | TW{} <- pas  = if elem td treps then rnf d else ()+#else+     | TI{} <- pas  = if elem td treps then () else rnfn 999999 d  -- XXX thack!+#endif+     | otherwise    = rnfp' pas recurs d+     where+      as = getPatNodeAttrs pas+      treps = typeConstraints as+      td = show $ typeRepTyCon $ typeOf d+      recurs = case length chs of+        0 -> case pas of+              WS{} -> ()+              _ -> pat_match_fail+        7 -> let [px1,px2,px3,px4,px5,px6,px7] = chs+                 (x1,x2,x3,x4,x5,x6,x7) = d+#if USE_PSEQ_PATNODE+             in pseq_condition pat [ rnfp px1 x1+                                   , rnfp px2 x2+                                   , rnfp px3 x3+                                   , rnfp px4 x4+                                   , rnfp px5 x5+                                   , rnfp px6 x6+                                   , rnfp px7 x7+                                   ]+#else+             in       rnfp px1 x1+                `seq` rnfp px2 x2+                `seq` rnfp px3 x3+                `seq` rnfp px4 x4+                `seq` rnfp px5 x5+                `seq` rnfp px6 x6+                `seq` rnfp px7 x7+#endif+                `seq` ()  -- needed?+        _ -> pat_match_fail+      pat_match_fail = patMatchFail' "(,,,,,,)" pas chs d++#if 0++-- XXX No Typeable instances for tuples larger than 7 in 7.8.1, seemingly?++-------------------------------------------------------------------------------+--- (a,b,c,d,e,f,g,h)++#if ( ! HASKELL98_FRAGMENT ) && ( __GLASGOW_HASKELL__ >= 710 )+  instance (NFDataP_ictx a, NFDataP_ictx b, NFDataP_ictx c, NFDataP_ictx d, NFDataP_ictx e, NFDataP_ictx f, NFDataP_ictx g, NFDataP_ictx h) =>+#else+#if INCLUDE_SHOW_INSTANCES+  instance (Show a, Typeable a, NFDataP a, Show b, Typeable b, NFDataP b, Show c, Typeable c, NFDataP c, Show d, Typeable d, NFDataP d, Show e, Typeable e, NFDataP e, Show f, Typeable f, NFDataP f, Show g, Typeable g, NFDataP g, Show h, Typeable h, NFDataP h) =>+#else+  instance (Typeable a, NFDataP a, Typeable b, NFDataP b, Typeable c, NFDataP c, Typeable d, NFDataP d, Typeable e, NFDataP e, Typeable f, NFDataP f, Typeable g, NFDataP g, Typeable h, NFDataP h) =>+#endif+#endif+         NFDataP (a, b, c, d, e, f, g, h) where+    {-  NOINLINE rnfp #-}+    rnfp p x | handleAttrs p x == Node XX []  = undefined+    rnfp (Node WI{} _) _ = ()+    rnfp pat@(Node pas chs) d+     | TR{} <- pas  = if elem td treps then recurs else ()+#if USE_WW_DEEPSEQ+     | TI{} <- pas  = if elem td treps then () else rnf d+     | TW{} <- pas  = if elem td treps then rnf d else ()+#else+     | TI{} <- pas  = if elem td treps then () else rnfn 999999 d  -- XXX thack!+#endif+     | otherwise    = rnfp' pas recurs d+     where+      as = getPatNodeAttrs pas+      treps = typeConstraints as+      td = show $ typeRepTyCon $ typeOf d+      recurs = case length chs of+        0 -> case pas of+              WS{} -> ()+              _ -> pat_match_fail+        8 -> let [px1,px2,px3,px4,px5,px6,px7,px8] = chs+                 (x1,x2,x3,x4,x5,x6,x7,x8) = d+#if USE_PSEQ_PATNODE+             in pseq_condition pat [ rnfp px1 x1+                                   , rnfp px2 x2+                                   , rnfp px3 x3+                                   , rnfp px4 x4+                                   , rnfp px5 x5+                                   , rnfp px6 x6+                                   , rnfp px7 x7+                                   , rnfp px8 x8+                                   ]+#else+             in       rnfp px1 x1+                `seq` rnfp px2 x2+                `seq` rnfp px3 x3+                `seq` rnfp px4 x4+                `seq` rnfp px5 x5+                `seq` rnfp px6 x6+                `seq` rnfp px7 x7+                `seq` rnfp px8 x8+#endif+                `seq` ()  -- needed?+        _ -> pat_match_fail+      pat_match_fail = patMatchFail' "(,,,,,,,)" pas chs d++#endif++-------------------------------------------------------------------------------++  patMatchFail :: (Show a, Show b) => a -> b -> c -> ()+  patMatchFail pas chs d+#if WARN_PATTERN_MATCH_FAILURE+   = ( unsafePerformIO $! putStrLn $! "NFDataP: warning: couldn't match " ++ show pas ++ " (having children " ++ show chs ++ ")" ) `seq` ()+#else+   = ()+#endif+-- = error $ "NFDataP: Couldn't match " ++ show pas ++ " (having children " ++ show chs ++ ")\nwith data " ++ show d++  patMatchFail' :: (Show a, Show b) => String -> a -> b -> c -> ()+  patMatchFail' inst pas chs d+#if WARN_PATTERN_MATCH_FAILURE+   = ( unsafePerformIO $! putStrLn $! "NFDataP: warning: instance " ++ inst ++ ": bad PatNode child list" ) `seq` patMatchFail pas chs d+#else+   = ()+#endif++-------------------------------------------------------------------------------++-- XXX Seeing as we're having troubles anyway, and considering+-- that most of this function requires popping into unsafePerformIO+-- anyway -- should the whole thing be returning IO, and then just+-- use unsafePerformIO in caller?++  -- This function collects all the "harmless impure things" we+  -- need to pop into IO to do.  To what extent we get away with+  -- this remains to be investigated...+  ------+  -- So, which of the PatNodeAttrs product type can be dealt with here?+  --   NOT doSpark  - dealt with downstream in rnfp'+  --   NOT doPseq   - about to be dealt with downstream (hopefully rnfp')...+  --       doDelay+  --       doTrace+  --       doPing+  --       doDie+  --       doTiming+  -----+  -- XXX Returning Pattern instead of Bool, in a continued attempt+  -- to outsmart GHC and get certain things to be evaluated...++  {-  NOINLINE handleAttrs #-}+#if 0+-- XXX XXX XXX testing only!!!! XXX XXX XXX+  handleAttrs pat@(Node p _) x = pat+#else+#if ! HASKELL98_FRAGMENT+#if HANDLE_ATTRS_DATA_CONSTRAINT+  handleAttrs :: forall d. Data d => Pattern -> d -> Pattern+--handleAttrs :: forall d. Data d => Pattern -> d -> Bool+  handleAttrs (Node p _) x+#else+  handleAttrs :: forall d. Typeable d => Pattern -> d -> Pattern+--handleAttrs :: forall d. Typeable d => Pattern -> d -> Bool+  handleAttrs (Node p _) x+#endif+#else+  handleAttrs :: Pattern -> a -> Pattern+--handleAttrs :: Pattern -> a -> Bool+  handleAttrs (Node p _) _+#endif+--- | doTrace as && trace ("HERE! "++show p++"\n"++show as) False = undefined+--- | trace ("HERE! "++show p++"\n"++show as) False = undefined+#if 0+    | uniqueID as ==  4 && trace ("HERE! "++show p++"\n"++show as) False = undefined+    | uniqueID as ==  9 && trace ("HERE! "++show p++"\n"++show as) False = undefined+    | uniqueID as == 11 && trace ("HERE! "++show p++"\n"++show as) False = undefined+#endif+--- | otherwise  = unsafePerformIO $! do+    | otherwise  = unsafePerformIO $ do+--- | otherwise  = trace ("BUHGO!") $ unsafePerformIO $ do+--- | otherwise  = trace ("BUHGO!") $ unsafeDupablePerformIO $ do+       let p0 = p+       p1 <- if doDelay as+             then dly p0 b+             else return p0+#if USE_TRACE_PATNODE+       p2 <- if doTrace as+             then trc p1 b msg_trc+             else return p1+#else+       let p2 = p1+#endif+#if USE_PING_PATNODE+       p3 <- if doPing as+             then png p2 b msg_png+             else return p2+#else+       let p3 = p2+#endif+#if USE_DIE_PATNODE+       p4 <- if doDie as+             then die p3 b msg_die+             else return p3+#else+       let p4 = p3+#endif+#if USE_TIMING_PATNODE+       p5 <- if doTiming as+             then timing p4 b msg_timing+             else return p4+#else+       let p5 = p4+#endif+       return $! Node p5 []+    | otherwise                   = Node p []  -- don't forget!+--- | otherwise                   = p     -- don't forget!+--- | otherwise                   = True  -- don't forget!+   where+#if 1+    b = False  -- WORKED for Ping/png; not working for Trace/trc...+#else+    b = unsafePerformIO $ ( randomIO :: IO Bool )  -- WORKS!!! (even though value is constant!)+#endif+    {-# NOINLINE dly #-}  -- XXX crucial+    dly p b+---  | trace "dly msg!" False = undefined+     | otherwise  = do+         if b+           then do+             !_ <- threadDelay $ delayus as+             return p+--           return $ not b+           else do+             !_ <- threadDelay $ delayus as+             return p+--           return '+#if USE_TRACE_PATNODE+    msg_trc =    "NFDataP: TRACE: " ++ show (uniqueID as)+#if ! HASKELL98_FRAGMENT+              ++ " " ++ show (typeOf x)+#if HANDLE_ATTRS_DATA_CONSTRAINT+              ++ "\n" ++ showRose (shapeOf x)+#endif+#endif+    {-# NOINLINE trc #-}  -- XXX crucial+    trc p b msg+---  | trace "trc msg!" False = undefined+     | otherwise  = do+         if b+           then do+---          !_ <- forkIO $ return (trace msg ())+---          !_ <- forkIO (return (trace msg ()))+             !_ <- trace msg $ return ()+             return p+--           return $ not b+           else do+---          !_ <- forkIO $ return (trace msg ())+---          !_ <- forkIO (return (trace msg ()))+             !_ <- trace msg $ return ()+             return p+--           return '+#endif+#if USE_PING_PATNODE+    msg_png =    "NFDataP: PING: " ++ show (uniqueID as)+#if ! HASKELL98_FRAGMENT+              ++ " " ++ show (typeOf x)+#if HANDLE_ATTRS_DATA_CONSTRAINT+              ++ "\n" ++ showRose (shapeOf x)+#endif+#endif+    {-# NOINLINE png #-}  -- XXX crucial+    -- Consider mkWeakThreadId :: ThreadId -> IO (Weak ThreadId)+    png p b msg+---  | trace "png msg!" False = undefined+#if 1+     | isNothing mpngtid  = do+--        b <- randomIO :: IO Bool+---      let b = False in+         if b+           then do+             return p+--           return $ not b+           else do+             return p+--           return b+#else+     | isNothing mpngtid  = False+#endif+     | otherwise  = do+--        b <- randomIO :: IO Bool+---      let b = False in+         if b+           then do+             !_ <- forkIO $ throw $ DeepSeqBounded_PingException msg+---          putStrLn "Carrying on FALSE ..."+             return p+--           return $ not b+           else do+             -- This worked! (exception thrown, yet continues)+             -- Getting repeatable actions still eludes...+--           evaluate (unsafeInterleaveIO (do+--           evaluate (unsafeDupablePerformIO (do+             !_ <- forkIO $ throw $ DeepSeqBounded_PingException msg+---          putStrLn "Carrying on TRUE ..."+             return p+--           return b+     where mpngtid = pingParentTID as+#endif+#if USE_DIE_PATNODE+    msg_die =    "NFDataP: DIE: " ++ show (uniqueID as)+#if ! HASKELL98_FRAGMENT+              ++ " " ++ show (typeOf x)+#if HANDLE_ATTRS_DATA_CONSTRAINT+              ++ "\n" ++ showRose (shapeOf x)+#endif+#endif+    {-# NOINLINE die #-}  -- XXX crucial (except perhaps in this die case...)+    die p b msg = do+      if b+        then do+          putStrLn msg >> myThreadId >>= killThread+          return p+--        return $ not b+        else do+          putStrLn msg >> myThreadId >>= killThread+          return p+--        return b+#endif+#if USE_TIMING_PATNODE+    msg_timing =    "NFDataP: TIMING: " ++ show (uniqueID as)+#if ! HASKELL98_FRAGMENT+                 ++ " " ++ show (typeOf x)+#if HANDLE_ATTRS_DATA_CONSTRAINT+                 ++ "\n" ++ showRose (shapeOf x)+#endif+#endif+    {-# NOINLINE timing #-}+    timing p b msg = do+      if b+        then do+          -- ... XXX+          return p+--        return $ not b+        else do+          -- ... XXX+          return p+--        return b+#endif+    as = getPatNodeAttrs p  -- XXX THIS IS BAD (bottleneck)+             -- [See 000-readme, cotemp 20150104.]+             -- Is there not a simpler way to get at the PatNodeAttr?+             -- One thing could do, is put the node type (WR, etc.)+             -- in PatNodeAttrs, and then PatNode = PatNodeAttrs.+             -- There's no real disadvantage, right? -- we can still+             -- pattern match almost as do now:+             --   (Node WR{} cs)               -- now+             --   (Node PN{nodeKind=WR}  cs)   -- hopefully!+#endif++-------------------------------------------------------------------------------++#if USE_PSEQ_PATNODE++  -- Note that, if USE_PSEQ_PATNODE flag is True, then Control.Parallel.pseq+  -- is used instead of Prelude.seq, whether or not a >cdba permutation was+  -- specified.  I'd kinda rather continue to use seq for the cases where+  -- no permutation was specified...+  pseq_condition :: Pattern -> [()] -> ()+--pseq_condition :: [Pattern] -> [()] -> ()+--pseq_condition :: [Pattern] -> [ Pattern -> x -> () ] -> ()+--pseq_condition :: [Pattern] -> [Pattern -> x -> ()] -> [Pattern -> x -> ()]+#if 0+#elif 1+  pseq_condition pat@(Node pn cs) fs+   | isNothing mperm  = foldr  seq () fs+   | otherwise        = foldr pseq () $ map (\i->(fs!!i)) perm+   where+    mperm = pseqPerm $ getPatNodeAttrs pn+    perm = fromJust mperm+#elif 0+  pseq_condition pat@(Node pn cs) fs+   = foldr pseq () fs'  -- is foldr the right fold?+   where+    mperm = pseqPerm $ getPatNodeAttrs pn+    perm = fromJust mperm+    fs' | isNothing mperm  = fs+        | otherwise        = map (\i->(fs!!i)) perm+#elif 0+  pseq_condition pats fs = foldr seq () fs  -- is foldr the right fold?+#endif++#endif  ------------------------------------------------------------------------------- 
− src/Control/DeepSeq/Bounded/NFDataP_new_grammar.hs
@@ -1,1580 +0,0 @@-----------------------------------------------------------------------------------  {-  LANGUAGE CPP #-}--#define DO_TRACE 0--#define HANDLE_ATTRS_DATA_CONSTRAINT 0---- XXX Note: Show constraints are for debugging purposes.-#define INCLUDE_SHOW_INSTANCES 0---- Formerly DEBUG_WITH_DEEPSEQ_GENERICS.--- Now also needed to force issuance of all compilePat warnings--- (so not strictly a debugging flag anymore).--- [Except it didn't work...]---- #define NFDATA_INSTANCE_PATTERN 1  -- now it's a .cabal flag---- Now specified via --flag=[-]USE_WWW_DEEPSEQ---- #define USE_WW_DEEPSEQ 1-----------------------------------------------------------------------------------  -- Used to create a custom Exception instance -- needed?-  -- I know we are no longer allowed to write our own instance?-  -- I thought Exceptions were in Haskell 98?...-  {-# LANGUAGE DeriveDataTypeable #-}--  -- For tracing only:-  {-  LANGUAGE BangPatterns #-}-  {-# LANGUAGE BangPatterns #-}--  {-# OPTIONS_GHC -fno-warn-name-shadowing #-}-  {-# OPTIONS_GHC -fno-warn-overlapping-patterns #-}--#if ! HASKELL98_FRAGMENT-  {-# LANGUAGE ScopedTypeVariables #-}-  {-  LANGUAGE RankNTypes #-}-  {-# LANGUAGE ConstraintKinds #-}-#endif------------------------------------------------------------------------------------- |--- Module      :  Control.DeepSeq.Bounded.NFDataP_new_grammar--- Copyright   :  Andrew G. Seniuk 2014-2015--- License     :  BSD-style (see the file LICENSE)------ Maintainer  :  Andrew Seniuk <rasfar@gmail.com>--- Stability   :  provisional--- Portability :  portable----{--}--- (Restore comment from NFDataP.hs when shed old grammar support.)-----------------------------------------------------------------------------------  module Control.DeepSeq.Bounded.NFDataP_new_grammar--- (Restore exports & comments from NFDataP.hs when shed old grammar support.)-  where-----------------------------------------------------------------------------------  import Control.DeepSeq.Bounded.Pattern-  import Control.DeepSeq.Bounded.Compile-  import Control.DeepSeq.Bounded.PatUtil ( unionPats, liftPats )---- debugging...-#if 1-  import Control.DeepSeq.Bounded.PatUtil ( -             probDensRose-           , weightedRose-           , unzipRose-           , showRose-#if ! HASKELL98_FRAGMENT-           , Shape-           , shapeOf-           , ghom-#endif-         )-#endif--  import Control.DeepSeq.Bounded.NFDataN  -- finally used ("*3" etc.)--#if USE_WW_DEEPSEQ-  import Control.DeepSeq ( NFData )-  import Control.DeepSeq ( rnf )-#endif--#if HANDLE_ATTRS_DATA_CONSTRAINT-  -- Brought back only to add Data d constraint to handleAttrs, which-  -- is a hack so can print something distinct for multiple +-nodes...-  import Data.Data-#endif---import Data.Data  -- "redundant" last checked--  import Data.Typeable ( Typeable )-#if 1-  import Data.Typeable ( typeOf )-#else--- XXX These are NOT interchangeable!-#if __GLASGOW_HASKELL__ >= 781-  import Data.Typeable ( typeRep )-#else-  import Data.Typeable ( typeOf )-#endif-#endif-  import Data.Typeable ( mkTyCon3, mkTyConApp )-  import Data.Typeable ( typeRepTyCon )--#if USE_PAR_PATNODE-  import Control.Parallel ( par )-#endif-#if USE_PSEQ_PATNODE-  import Control.Parallel ( pseq )-#endif-#if USE_PING_PATNODE-  import Control.Concurrent ( myThreadId, killThread )-  import Control.Concurrent ( forkIO )-#endif--  import Control.Concurrent ( threadDelay )--  import Data.Int-  import Data.Word-  import Data.Ratio-  import Data.Complex-  import Data.Array-  import Data.Fixed-  import Data.Version--  import Data.Maybe ( Maybe(..), isJust, fromJust, isNothing )--  import Control.Exception ( Exception )-  import Control.Exception ( asyncExceptionFromException )-  import Control.Exception ( throwTo )-  import Control.Exception ( throw )-  import Control.Exception( AsyncException( UserInterrupt ) )--  import Control.Monad ( liftM )--  -- XXX unsafePerformIO *is* used [besides indirectly with trace and throwTo].-  -- Grep the source on a case by case basis...-  import System.IO.Unsafe ( unsafeInterleaveIO )-  import System.IO.Unsafe ( unsafeDupablePerformIO )-  import System.IO.Unsafe ( unsafePerformIO )-  import Control.Exception ( evaluate )--  import System.Random ( randomIO )--  import Debug.Trace ( trace )-----------------------------------------------------------------------------------#if USE_PING_PATNODE-  data DeepSeqBounded_PingException = DeepSeqBounded_PingException String-    deriving (Show, Typeable)--  instance Exception DeepSeqBounded_PingException-#endif-----------------------------------------------------------------------------------#if DO_TRACE-  mytrace = trace-#else-  mytrace _ = id-#endif-------------------------------------------------------------------------------------infixr 0 $!!------------------------------------------------------------------------------------- XXX NOTE TO SELF: These comments are verbatim from Control.DeepSeq:-  -- | 'deepseqp' evaluates the first argument to the extent specified-  -- by a 'Pattern', before returning the second.-  ---  -- Quoting from the <http://hackage.haskell.org/package/deepseq/docs/Control-DeepSeq.html DeepSeq> documentation (<http://hackage.haskell.org/package/deepseq deepseq> package):-  ---  -- \"<http://hackage.haskell.org/package/deepseq/docs/Control-DeepSeq.html#t:deepseq deepseq> /can be useful for forcing pending exceptions, eradicating space leaks, or forcing lazy I\/O to happen.  It is also useful in conjunction with parallel Strategies (see the/ <http://hackage.haskell.org/package/parallel parallel> /package). /-  ---  -- / There is no guarantee about the ordering of evaluation.  The implementation may evaluate the components of the structure in any order or in parallel.  To impose an actual order on evaluation, use 'pseq' from "Control.Parallel" in the @parallel@ package.\" /-{--} -- XXX LATER: This is flawed for # at root of pattern.-#if ( ! HASKELL98_FRAGMENT ) && ( __GLASGOW_HASKELL__ >= 710 )-  deepseqp :: NFDataP_ictx a => String -> a -> b -> b---deepseqp :: NFDataP_cctx a => String -> a -> b -> b-#else-#if INCLUDE_SHOW_INSTANCES-  deepseqp :: (Show a, NFDataP a) => String -> a -> b -> b-#else-  deepseqp :: NFDataP a => String -> a -> b -> b-#endif-#endif-#if 0-#elif 0-  deepseqp patstr a b = fromJust $ deepseqp_ (compilePat patstr) a b---deepseqp patstr = fromJust $ deepseqp_ (compilePat patstr)-#elif 1-  deepseqp patstr = deepseqp_ (compilePat patstr)-#elif 0-  deepseqp patstr a b = rnfp (compilePat patstr) a `seq` b-  -- XXX Partially-applied; is that okay in GHC RULES?-  {-# RULES-    "deepseqp/composition"    forall p1 p2 x.  (.) (deepseqp p2) (deepseqp p1) x = deepseqp_ ( unionPats [compilePat p1, compilePat p2] ) x-      #-}-#endif--  -- | Self-composition fuses via-  ---  -- @-  --     "deepseqp_/composition"-  --        forall p1 p2 x1 x2.-  --            (.) ('deepseqp_' p2 x2) ('deepseqp_' p1 x1)-  --          = 'deepseqp_' ( 'liftPats' [p1, p2] ) (x1,x2)-  -- @-  ---  -- (Other fusion rules, not yet documented, may also be in effect.)-{--}--- XXX LATER: This is flawed for # at root of pattern.--- Maybe not quite flawed, just "untestable" if there's bottom at--- the root of the value (that is to say, the value is (undefined::b).-#if ( ! HASKELL98_FRAGMENT ) && ( __GLASGOW_HASKELL__ >= 710 )-  deepseqp_ :: NFDataP_ictx a => Pattern -> a -> b -> b---deepseqp_ :: NFDataP_cctx a => Pattern -> a -> b -> b-#else-#if INCLUDE_SHOW_INSTANCES-  deepseqp_ :: (Show a, NFDataP a) => Pattern -> a -> b -> b-#else-  deepseqp_ :: NFDataP a => Pattern -> a -> b -> b-#endif-#endif-#if 0-#elif 0-  deepseqp_ pat@(Node WI _) _ b = b-  deepseqp_ pat@(Node (TR as) chs) a b = if elem ta treps then doit `seq` b else b-   where ta = show $ typeRepTyCon $ typeOf a-         doit = rnfp pat a `seq` b-         treps = typeConstraints as-  deepseqp_ pat@(Node (TI as) chs) a b = if elem ta treps then b else doit `seq` b-   where ta = show $ typeRepTyCon $ typeOf a-         doit = rnfp pat a `seq` b-         treps = typeConstraints as-  deepseqp_ pat a b = rnfp pat a `seq` b-#elif 1-  deepseqp_ pat a b = rnfp pat a `seq` b-  -- XXX Need to double-check that this makes sense; didn't think-  -- it through -- when b != a, things are not so simple.-  -- XXX Partially-applied; is that okay in GHC RULES?-  {-# RULES-    "deepseqp_/composition"    forall p1 p2 x1 x2.  (.) (deepseqp_ p2 x2) (deepseqp_ p1 x1) = deepseqp_ ( liftPats [p1, p2] ) (x1,x2)-      #-}---  "deepseqp_/composition"    forall p1 p2 x.  (.) (deepseqp_ p2) (deepseqp_ p1) x = deepseqp_ ( unionPats [p1, p2] ) x-#endif-----------------------------------------------------------------------------------#if 0-  -- | the deep analogue of '$!'.  In the expression @f $!! x@, @x@ is-  -- fully evaluated before the function @f@ is applied to it.-  ($!!) :: (NFData a) => (a -> b) -> a -> b-  f $!! x = x `deepseq` f x-#endif---- XXX NOTE TO SELF: These comments are verbatim from Control.DeepSeq:-  -- | A variant of 'deepseqp' that is sometimes convenient:-  ---  -- > forcep pat x = deepseqp pat x x   -- (cannot write x `deepseqp pat` x by analogy with x `deepseq` x)-  ---  -- @forcep pat x@ evaluates @x@ to the depth determined by @pat@, and-  -- then returns @x@.  Again from-  -- <http://hackage.haskell.org/package/deepseq deepseq>:-  -- / \"Note that @forcep pat x@ only takes effect when the value of @forcep pat x@ itself is demanded, so essentially it turns shallow evaluation into evaluation to arbitrary bounded depth.\" /-  ---  -- Composition fuses (see 'forcep_').-{--}--- XXX What about fusion of mixed applications?...--- XXX LATER: This is flawed for # at root of pattern.-#if ( ! HASKELL98_FRAGMENT ) && ( __GLASGOW_HASKELL__ >= 710 )-  forcep :: NFDataP_ictx a => String -> a -> a---forcep :: NFDataP_cctx a => String -> a -> a-#else-#if INCLUDE_SHOW_INSTANCES-  forcep :: (Show a, NFDataP a) => String -> a -> a-#else-  forcep :: NFDataP a => String -> a -> a-#endif-#endif-#if 0-#elif 0-  forcep patstr x-   | p          = fromJust ma--- | otherwise  = error "here"-   | otherwise  = undefined::a-   where ma = deepseqp_ (compilePat patstr) x x-         p = isJust ma-#elif 0-  forcep patstr x = fromJust $ deepseqp_ (compilePat patstr) x x-#elif 0-  forcep patstr x-   | b          = x-   | otherwise  = fromJust y-   where y = deepseqp_ (compilePat patstr) x (Just x)-         pat@(Node pas chs) = compilePat patstr-         b | WI <- pas  = True-           | TR <- pas  = True-           | TN <- pas  = True-           | TW <- pas  = True-           | TI <- pas  = True-           | otherwise  = False-#elif 1-  forcep patstr x = deepseqp_ (compilePat patstr) x x---forcep patstr x = deepseqp patstr x x-  {-# RULES-    "forcep/composition"    forall p1 p2 x.  (.) (forcep p2) (forcep p1) x = forcep_ ( unionPats [compilePat p1, compilePat p2] ) x-      #-}-#endif--  -- | Self-composition fuses via-  ---  -- @-  --     "forcep_/composition"-  --        forall p1 p2 x.-  --            (.) ('forcep_' p2) ('forcep_' p1) x-  --          = 'forcep_' ( 'unionPats' [p1, p2] ) x-  -- @-  ---  -- (Other fusion rules, not yet documented, may also be in effect.)-{--}--- XXX LATER: This is flawed for # at root of pattern.-#if ( ! HASKELL98_FRAGMENT ) && ( __GLASGOW_HASKELL__ >= 710 )-  forcep_ :: NFDataP_ictx a => Pattern -> a -> a---forcep_ :: NFDataP_cctx a => Pattern -> a -> a-#else-#if INCLUDE_SHOW_INSTANCES-  forcep_ :: (Show a, NFDataP a) => Pattern -> a -> a-#else-  forcep_ :: NFDataP a => Pattern -> a -> a-#endif-#endif-#if 0-  forcep_ pat x = fromJust $ deepseqp_ pat x x-#else-  forcep_ pat x = deepseqp_ pat x x-  {-# RULES-    "forcep_/composition"    forall p1 p2 x.  (.) (forcep_ p2) (forcep_ p1) x = forcep_ ( unionPats [p1, p2] ) x-      #-}-#endif-----------------------------------------------------------------------------------#if ! HASKELL98_FRAGMENT--- We don't need 7.10 for tuple predicates /here/, but when try to--- use in seqaid, the TH splice complains---   Can't represent tuple predicates in Template Haskell:---     Control.DeepSeq.Bounded.NFDataP_new_grammar.NFDataP_cctx--- That is with GHC 7.8.4.--- So we need template-haskell-2.10, which means need base >= base-4.8.0.0,--- which means need GHC >= 7.10.-#if __GLASGOW_HASKELL__ >= 710-  -- XXX Not H98! -XConstraintKinds-  type NFDataP_cctx a-        = (-              Typeable a-#if HANDLE_ATTRS_DATA_CONSTRAINT-            , Data a-#endif-            , NFDataN a-#if USE_WW_DEEPSEQ-            , NFData a-#endif-          )-#if 0--- XXX Because TH < 2.10 cannot hand tuple predicates,--- even if the corresponding GHC can!--- And this didn't help anyway, still get the error--- when TH runs in seqaid...-  type NFDataP_ictx a-        = (-              Typeable a-#if HANDLE_ATTRS_DATA_CONSTRAINT-            , Data a-#endif-            , NFDataN a-#if USE_WW_DEEPSEQ-            , NFData a-#endif-            , NFDataP a-#if INCLUDE_SHOW_INSTANCES-            , Show a-#endif-          )-#else-  type NFDataP_ictx a-        = (-              NFDataP_cctx a-            , NFDataP a-#if INCLUDE_SHOW_INSTANCES-            , Show a-#endif-          )-#endif-#endif-#endif-----------------------------------------------------------------------------------  -- | A class of types that can be evaluated over an arbitrary finite pattern.-#if ( ! HASKELL98_FRAGMENT ) && ( __GLASGOW_HASKELL__ >= 710 )-  class NFDataP_cctx a => NFDataP a where-#else-  class (-          Typeable a-#if HANDLE_ATTRS_DATA_CONSTRAINT-        , Data a-#endif-        , NFDataN a-#if USE_WW_DEEPSEQ-        , NFData a-#endif-        ) => NFDataP a where-#endif-    -- | Self-composition fuses via-    ---    -- @-    --     "rnfp/composition"-    --        forall p1 p2 x.-    --            (.) ('rnfp' p2) ('rnfp' p1) x-    --          = 'rnfp' ( 'unionPats' [p1, p2] ) x-    -- @-    ---    -- (Other fusion rules, not yet documented, may also be in effect.)-    {-  NOINLINE rnfp #-}-#if INCLUDE_SHOW_INSTANCES-    rnfp :: Show a => Pattern -> a -> ()-#else-    rnfp :: Pattern -> a -> ()-#endif-#if 0---  rnfp p x | p `seq` trace "Boo!" () `seq` p == Node XX []  = undefined  -- does NOT work---  rnfp p x | trace "Boo!" p `seq` p == Node XX []  = undefined  -- WORKS!!!---  rnfp p x | trace "Boo!" () `seq` p == (trace "FOO!!" (Node XX []))  = undefined  -- FOO!! /is/ printed, though only once (like Boo)---  rnfp p x | trace "Boo!" () `seq` p == Node XX []  = undefined  -- NOT works (printed once only)---  rnfp p x | (trace "Boo!" p) == Node XX []  = undefined  -- WORKS!!! (printed every time)---  rnfp p x | trace "Boo!" () `seq` p == Node TN{} []  = undefined---  rnfp p x | trace "Boo!" () `seq` False  = undefined---  rnfp p x | trace "Boo!" True, p `seq` False  = undefined---  rnfp p x | trace "Boo!" False  = undefined-#endif-#if 1-    rnfp p x | handleAttrs p x == Node XX []  = undefined---  rnfp p@(Node pn _) x | as <- getPatNodeAttrs pn, 9 == uniqueID as  = error $ showPatNodeRaw pn---  rnfp p@(Node pn@(WI _) _) x = error $ showPatNodeRaw pn---  rnfp p@(Node pn@WI{} _) x = error $ showPatNodeRaw pn---  rnfp p@(Node WI{} _) x = handleAttrs p x `seq` ()-    rnfp (Node WI{} _) _ = ()-#else-    rnfp (Node WI{} _) _ = ()-#endif-    rnfp (Node (TR as) chs) d = if elem td treps then d `seq` () else ()-     where td = show $ typeRepTyCon $ typeOf d-           treps = typeConstraints as-    rnfp (Node (TI as) chs) d = if elem td treps then () else d `seq` ()-     where td = show $ typeRepTyCon $ typeOf d-           treps = typeConstraints as-#if USE_WW_DEEPSEQ-    -- complement of TI, equivalent to TR in this special case-    rnfp (Node (TW as) chs) d = if elem td treps then d `seq` () else ()-     where td = show $ typeRepTyCon $ typeOf d-           treps = typeConstraints as-#endif-#if 1-    rnfp _ d = d `seq` ()---  rnfp _ _ = ()-#else-    -- XXX temporarily (at least) commenting out; not making any-    -- use of patternShapeOK -- but there is room for more-    -- error-trapping code in here, definitely...-    rnfp pat a | not $ patternShapeOK pat a  = ()-               | otherwise  = rnf a-#endif--  {-# RULES-    "rnfp/composition"    forall p1 p2 x.  (.) (rnfp p2) (rnfp p1) x = rnfp ( unionPats [p1, p2] ) x-      #-}---  "rnfp/composition"    forall p1 p2 x.  compose (rnfp p2) (rnfp p1) x = rnfp ( unionPats [p1, p2] ) x---  "rnfp/composition"    forall p1 p2 x.  ( rnfp p2 . rnfp p1 ) x = rnfp ( unionPats [p1, p2] ) x-----------------------------------------------------------------------------------#if ( ! HASKELL98_FRAGMENT ) && ( __GLASGOW_HASKELL__ >= 710 )-  rnfp' :: NFDataP_ictx a => PatNode -> () -> a -> ()-#else-#if USE_WW_DEEPSEQ-  rnfp' :: (Typeable a, NFDataN a, NFData a) => PatNode -> () -> a -> ()-#else-  rnfp' :: (Typeable a, NFDataN a) => PatNode -> () -> a -> ()-#endif-#endif-  rnfp' pas recurs d-   -- I can only conclude that we've already evaluated the argument-   -- by the time this code runs (or that we evaluate it after...).-   -- But this code doesn't do the dirty deed!-   = {-trace ( "rnfp' " ++ show pat) $-}-     let-         td = show $ typeRepTyCon $ typeOf d  -- no problem on bottom-         as = getPatNodeAttrs pas-         treps = typeConstraints as-         n = depth as-     in-#if USE_PAR_PATNODE-     if doSpark as-     then-       case pas of-        WS{} -> () `par` ()-        WR{} -> recurs `par` ()-        WN{} -> rnfn n d `par` ()-#if USE_WW_DEEPSEQ-        WW{} -> rnf d `par` ()  -- should reimplement deepseq for uniformity...-#endif-        WI{} -> error "rnfp: unexpected =WI (please report this bug!)"-        _ -> error $ "rnfp: Unexpected PatNode (with doSpark): " ++ show pas ++ "(please report this bug!)"-     else-#endif-       case pas of-        WR{} -> recurs-        WS{} -> ()---      WS{} -> d `seq` ()-        WN{} -> rnfn n d-#if USE_WW_DEEPSEQ-        WW{} -> rnf d  -- should reimplement deepseq for uniformity...-#endif-#if 0-        -- This code stays the same whether we (are able to) compare-        -- actual TypeRep's for equality, or we just hack it-        -- and match:  show . typeRepTyCon . typeOf-        TR{} ->  if       elem td treps then recurs else ()-#endif-#if 0-        -- This is not right. To pull this off (b/c it depends on-        -- types in the value you're matching with), need to construct-        -- the pattern dynamically.  In particular, to produce Nil-        -- where a TR (or TS) constraint causes (or would cause)-        -- match failure.-        TS{} ->  if       elem td treps then () else ()-#endif-        TN{} ->  if       elem td treps then rnfn n d else ()-#if USE_WW_DEEPSEQ-        TW{} ->  if       elem td treps then rnf d else ()-#endif-#if 0-        NTR{} -> if not $ elem td treps then recurs else ()-        NTN{} -> if not $ elem td treps then rnfn n d else ()-#if USE_WW_DEEPSEQ-        NTW{} -> if not $ elem td treps then rnf d else ()-#endif-#endif-        -- these handled upstream-        WI{} -> error "rnfp: unexpected WI (please report this bug!)"-        TR{} -> error "rnfp: unexpected TR (please report this bug!)"-        TI{} -> error "rnfp: unexpected TI (please report this bug!)"-        _ -> error $ "rnfp: Unexpected PatNode: " ++ show pas ++ " (please report this bug!)"-----------------------------------------------------------------------------------#if 0-  compose = (.)-  {-# NOINLINE compose #-}-  -- Can't do this, unfortunately.  GHC warns it may get inlined before-  -- rules have a chance to fire.  I would rather avoid forcing the API-  -- user to use some custom "compose" function, since base (.) works-  -- perfectly, except it's hard to control its inlining...-  {-  NOINLINE (.) #-}-#endif------------------------------------------------------------------------------------ Base nullary types.--  instance NFDataP Int-  instance NFDataP Word-  instance NFDataP Integer-  instance NFDataP Float-  instance NFDataP Double--  instance NFDataP Char-  instance NFDataP Bool-  instance NFDataP ()--  instance NFDataP Int8-  instance NFDataP Int16-  instance NFDataP Int32-  instance NFDataP Int64--  instance NFDataP Word8-  instance NFDataP Word16-  instance NFDataP Word32-  instance NFDataP Word64------------------------------------------------------------------------------------- Fixed a--  instance Typeable a => NFDataP (Fixed a)---instance NFDataP (Fixed a)------------------------------------------------------------------------------------- a -> b--  -- [Quoted from deepseq:]-  -- This instance is for convenience and consistency with 'seq'.-  -- This assumes that WHNF is equivalent to NF for functions.-#if ( ! HASKELL98_FRAGMENT ) && ( __GLASGOW_HASKELL__ >= 710 )-  instance (NFDataP_ictx a, NFDataP_ictx b) => NFDataP (a -> b)-#else-  instance (-             Typeable a, Typeable b-#if HANDLE_ATTRS_DATA_CONSTRAINT-           , Data a, Data b  -- XXX why only needed in THIS instance?-#endif-           ) => NFDataP (a -> b)---instance NFDataP (a -> b)-#endif------------------------------------------------------------------------------------- Ratio a--  -- not taken to be a level of depth-#if ( ! HASKELL98_FRAGMENT ) && ( __GLASGOW_HASKELL__ >= 710 )-  instance (NFDataP_ictx a, Integral a) => NFDataP (Ratio a) where-#else-#if INCLUDE_SHOW_INSTANCES-  instance (Show a, Integral a, NFDataP a) => NFDataP (Ratio a) where-#else-  instance (Integral a, NFDataP a) => NFDataP (Ratio a) where-#endif-#endif-    -- XXX This is very dubious!...-    {-  NOINLINE rnfp #-}-    rnfp p x | handleAttrs p x == Node XX []  = undefined-    rnfp (Node WI{} _) _ = ()-    rnfp pat x = rnfp pat (numerator x, denominator x)------------------------------------------------------------------------------------- Complex a--  -- Note that (Complex a) constructor (:+) has strict fields,-  -- so unwrapping the ctor also forces both components.-#if ( ! HASKELL98_FRAGMENT ) && ( __GLASGOW_HASKELL__ >= 710 )-  instance (NFDataP_ictx a, RealFloat a) => NFDataP (Complex a) where-#else-#if INCLUDE_SHOW_INSTANCES-  instance (Show a, RealFloat a, NFDataP a) => NFDataP (Complex a) where-#else-  instance (RealFloat a, NFDataP a) => NFDataP (Complex a) where-#endif-#endif-    {-  NOINLINE rnfp #-}-    rnfp p x | handleAttrs p x == Node XX []  = undefined-    rnfp (Node WI{} _) _ = ()-    rnfp pat@(Node pas chs) d-     | TR{} <- pas  = if elem td treps then recurs else ()-#if USE_WW_DEEPSEQ-     | TI{} <- pas  = if elem td treps then () else rnf d-     | TW{} <- pas  = if elem td treps then rnf d else ()-#else-     | TI{} <- pas  = if elem td treps then () else rnfn 999999 d  -- XXX thack!-#endif-     | otherwise    = rnfp' pas recurs d-     where-      as = getPatNodeAttrs pas-      treps = typeConstraints as-      td = show $ typeRepTyCon $ typeOf d-      recurs = case length chs of-        0 -> case pas of-              WS{} -> ()-              _ -> pat_match_fail-        2 -> let [px,py] = chs-                 (x:+y) = d-#if USE_PSEQ_PATNODE-             in pseq_condition pat [ rnfp px x-                                   , rnfp py y-                                   ]-#else-             in       rnfp px x-                `seq` rnfp py y-#endif-                `seq` ()  -- needed?-        _ -> pat_match_fail-      pat_match_fail = patMatchFail' "(Complex a)" pas chs d------------------------------------------------------------------------------------- Maybe a---- XXX Never until now (so much later) did I properly consider how to--- handle a no-arg (nullary) constructor! It's not hard, but it's--- significantly different than the other cases, as there's no--- subvalue we can grab hold of -- there's no "d"; so this invalidates--- all the code, in the posary (complement of nullary, coinage :) case--- case, which references d.-#if ( ! HASKELL98_FRAGMENT ) && ( __GLASGOW_HASKELL__ >= 710 )-  instance NFDataP_ictx a => NFDataP (Maybe a) where-#else-#if INCLUDE_SHOW_INSTANCES-  instance (Show a, NFDataP a) => NFDataP (Maybe a) where-#else-  instance NFDataP a => NFDataP (Maybe a) where-#endif-#endif-    {-  NOINLINE rnfp #-}-    rnfp p x | handleAttrs p x == Node XX []  = undefined-    rnfp (Node WI{} _) _ = ()-    rnfp pat@(Node pas chs) Nothing-     | not $ null chs  = pat_match_fail-     | otherwise       = ()-     where-      pat_match_fail = patMatchFail' "Nothing" pas chs ()-    rnfp (Node pas chs) (Just d)-     | TR{} <- pas  = if elem td treps then recurs else ()-#if USE_WW_DEEPSEQ-     | TI{} <- pas  = if elem td treps then () else rnf d-     | TW{} <- pas  = if elem td treps then rnf d else ()-#else-     | TI{} <- pas  = if elem td treps then () else rnfn 999999 d  -- XXX thack!-#endif-     | otherwise    = rnfp' pas recurs d-     where-      as = getPatNodeAttrs pas-      treps = typeConstraints as-      td = show $ typeRepTyCon $ typeOf d-      recurs = case length chs of-        0 -> case pas of-              WS{} -> ()-              _ -> pat_match_fail-        1 -> let [p_J] = chs-             in       rnfp p_J d-                `seq` ()  -- needed?-        _ -> pat_match_fail-      pat_match_fail = patMatchFail' "Just" pas chs d-    rnfp (Node pas chs) d = patMatchFail pas chs d  -- unreachable------------------------------------------------------------------------------------- Either a b--#if ( ! HASKELL98_FRAGMENT ) && ( __GLASGOW_HASKELL__ >= 710 )-  instance (NFDataP_ictx a, NFDataP_ictx b) => NFDataP (Either a b) where-#else-#if INCLUDE_SHOW_INSTANCES-  instance (Show a, Show b, NFDataP a, NFDataP b) => NFDataP (Either a b) where-#else-  instance (NFDataP a, NFDataP b) => NFDataP (Either a b) where-#endif-#endif-    {-  NOINLINE rnfp #-}-    rnfp p x | handleAttrs p x == Node XX []  = undefined-    rnfp (Node WI{} _) _ = ()-    rnfp (Node pas chs) (Left d)-     | TR{} <- pas  = if elem td treps then recurs else ()-#if USE_WW_DEEPSEQ-     | TI{} <- pas  = if elem td treps then () else rnf d-     | TW{} <- pas  = if elem td treps then rnf d else ()-#else-     | TI{} <- pas  = if elem td treps then () else rnfn 999999 d  -- XXX thack!-#endif-     | otherwise    = rnfp' pas recurs d-     where-      as = getPatNodeAttrs pas-      treps = typeConstraints as-      td = show $ typeRepTyCon $ typeOf d-      recurs = case length chs of-        0 -> case pas of-              WS{} -> ()-              _ -> pat_match_fail-        1 -> let [p_L] = chs-             in       rnfp p_L d-                `seq` ()  -- needed?-        _ -> pat_match_fail-      pat_match_fail = patMatchFail' "Left" pas chs d---    pat_match_fail = patMatchFail' "(Either a b)" pas chs d-    rnfp (Node pas chs) (Right d)-     | TR{} <- pas  = if elem td treps then recurs else ()-#if USE_WW_DEEPSEQ-     | TI{} <- pas  = if elem td treps then () else rnf d-     | TW{} <- pas  = if elem td treps then rnf d else ()-#else-     | TI{} <- pas  = if elem td treps then () else rnfn 999999 d  -- XXX thack!-#endif-     | otherwise     = rnfp' pas recurs d-     where-      as = getPatNodeAttrs pas-      treps = typeConstraints as-      td = show $ typeRepTyCon $ typeOf d-      recurs = case length chs of-        0 -> case pas of-              WS{} -> ()-              _ -> pat_match_fail-        1 -> let [p_R] = chs-             in       rnfp p_R d-                `seq` ()  -- needed?-        _ -> pat_match_fail-      pat_match_fail = patMatchFail' "Right" pas chs d---    pat_match_fail = patMatchFail' "(Either a b)" pas chs d-    rnfp (Node pas chs) d = patMatchFail pas chs d  -- unreachable------------------------------------------------------------------------------------- Data.Version.Version----- #if __GLASGOW_HASKELL__ < 781---- -- requires -XStandaloneDeriving---- -- orphan instance, but better than dropping support---- -- (It seems it already has its Show instance!)---- deriving instance Data Data.Version.Version---- #endif----deriving instance Data TypeRep  -- can't b/c not all data ctors are in scope!--  -- Data.Version ctor does /not/ have strict fields.-  instance NFDataP Data.Version.Version where-    {-  NOINLINE rnfp #-}-    rnfp p x | handleAttrs p x == Node XX []  = undefined-    rnfp (Node WI{} _) _ = ()-    rnfp pat@(Node pas chs) d-     | TR{} <- pas  = if elem td treps then recurs else ()-#if USE_WW_DEEPSEQ-     | TI{} <- pas  = if elem td treps then () else rnf d-     | TW{} <- pas  = if elem td treps then rnf d else ()-#else-     | TI{} <- pas  = if elem td treps then () else rnfn 999999 d  -- XXX thack!-#endif-     | otherwise    = rnfp' pas recurs d-     where-      as = getPatNodeAttrs pas-      treps = typeConstraints as-      td = show $ typeRepTyCon $ typeOf d-      recurs = case length chs of-        0 -> case pas of-              WS{} -> ()-              _ -> pat_match_fail-        2 -> let [pbr,ptags] = chs-                 Data.Version.Version branch tags = d-#if USE_PSEQ_PATNODE-             in pseq_condition pat [rnfp pbr branch, rnfp ptags tags]-#else-             in       rnfp pbr branch-                `seq` rnfp ptags tags-#endif-                `seq` ()  -- needed?-        _ -> pat_match_fail-      pat_match_fail = patMatchFail' "Data.Version.Version" pas chs d------------------------------------------------------------------------------------- [a]--  -- Data.List ctors do /not/ have strict fields (i.e. (:) is not strict).-#if ( ! HASKELL98_FRAGMENT ) && ( __GLASGOW_HASKELL__ >= 710 )-  instance NFDataP_ictx a => NFDataP [a] where-#else-#if INCLUDE_SHOW_INSTANCES-  instance (Show a, NFDataP a) => NFDataP [a] where-#else-  instance NFDataP a => NFDataP [a] where-#endif-#endif-    {-  NOINLINE rnfp #-}-    rnfp p x | handleAttrs p x == Node XX []  = undefined-    rnfp (Node WI{} _) _ = ()-    rnfp _ [] = ()  -- perhaps dubious?...-    rnfp pat@(Node pas chs) d-     | TR{} <- pas  = if elem td treps then recurs else ()-#if USE_WW_DEEPSEQ-     | TI{} <- pas  = if elem td treps then () else rnf d-     | TW{} <- pas  = if elem td treps then rnf d else ()-#else-     | TI{} <- pas  = if elem td treps then () else rnfn 999999 d  -- XXX thack!-#endif-     | otherwise    = rnfp' pas recurs d-     where-      as = getPatNodeAttrs pas-      treps = typeConstraints as-      td = show $ typeRepTyCon $ typeOf d-      recurs = case length chs of-        0 -> case pas of-              WS{} -> ()-              _ -> pat_match_fail-        2 -> let [px,pxs] = chs-                 (x:xs) = d-#if USE_PSEQ_PATNODE-             in pseq_condition pat [rnfp px x, rnfp pxs xs]-#else-             in       rnfp px x-                `seq` rnfp pxs xs-#endif-                `seq` ()  -- needed?-        _ -> pat_match_fail-      pat_match_fail = patMatchFail' "[a]" pas chs d------------------------------------------------------------------------------------- Array a b--  -- Data.Array ctor does /not/ have strict fields.-  -- not taken to be a level of depth-#if ( ! HASKELL98_FRAGMENT ) && ( __GLASGOW_HASKELL__ >= 710 )-  instance (Ix a, NFDataP_ictx a, NFDataP_ictx b) => NFDataP (Array a b) where-#else-#if INCLUDE_SHOW_INSTANCES-  instance (Show a, Show b, Ix a, NFDataP a, NFDataP b) => NFDataP (Array a b) where-#else-  instance (Ix a, NFDataP a, NFDataP b) => NFDataP (Array a b) where-#endif-#endif-    -- XXX This is very dubious!...-    {-  NOINLINE rnfp #-}-    rnfp p x | handleAttrs p x == Node XX []  = undefined-    rnfp (Node WI{} _) _ = ()-    rnfp pas x =        rnfp pas (bounds x, Data.Array.elems x)-                  `seq` ()  -- needed?------------------------------------------------------------------------------------- (a,b)--#if ( ! HASKELL98_FRAGMENT ) && ( __GLASGOW_HASKELL__ >= 710 )-  instance (NFDataP_ictx a, NFDataP_ictx b) => NFDataP (a,b) where-#else-#if INCLUDE_SHOW_INSTANCES-  instance (Show a,Typeable a,NFDataP a, Show b,Typeable b,NFDataP b) => NFDataP (a,b) where-#else-  instance (Typeable a,NFDataP a, Typeable b,NFDataP b) => NFDataP (a,b) where-#endif-#endif-    {-  NOINLINE rnfp #-}---  rnfp _ _ = error "booy"---  rnfp p x | trace "hoop!" (handleAttrs p x) `seq` p == Node XX []  = undefined-    rnfp p x | handleAttrs p x `seq` p == Node XX []  = undefined-    rnfp (Node WI{} _) _ = ()-    rnfp pat@(Node pas chs) d-     | TR{} <- pas  = if elem td treps then recurs else ()-#if USE_WW_DEEPSEQ-     | TI{} <- pas  = if elem td treps then () else rnf d-     | TW{} <- pas  = if elem td treps then rnf d else ()-#else-     | TI{} <- pas  = if elem td treps then () else rnfn 999999 d  -- XXX thack!-#endif-     | otherwise    = rnfp' pas recurs d-     where-      as = getPatNodeAttrs pas-      treps = typeConstraints as-      td = show $ typeRepTyCon $ typeOf d-      recurs = case length chs of-        0 -> case pas of-              WS{} -> ()-              _ -> pat_match_fail-        2 -> let [px,py] = chs-                 (x,y) = d-#if USE_PSEQ_PATNODE-             in pseq_condition pat [rnfp px x, rnfp py y]-#else-             in       rnfp px x-                `seq` rnfp py y-#endif-                `seq` ()  -- needed?-        _ -> pat_match_fail-      pat_match_fail = patMatchFail' "(,)" pas chs d------------------------------------------------------------------------------------- (a,b,c)--#if ( ! HASKELL98_FRAGMENT ) && ( __GLASGOW_HASKELL__ >= 710 )-  instance (NFDataP_ictx a, NFDataP_ictx b, NFDataP_ictx c) => NFDataP (a,b,c) where-#else-#if INCLUDE_SHOW_INSTANCES-  instance (Show a, Typeable a, NFDataP a, Show b, Typeable b, NFDataP b, Show c, Typeable c, NFDataP c) => NFDataP (a,b,c) where-#else-  instance (Typeable a, NFDataP a, Typeable b, NFDataP b, Typeable c, NFDataP c) => NFDataP (a,b,c) where-#endif-#endif-    {-  NOINLINE rnfp #-}-    rnfp p x | handleAttrs p x == Node XX []  = undefined-    rnfp (Node WI{} _) _ = ()-    rnfp pat@(Node pas chs) d-     | TR{} <- pas  = if elem td treps then recurs else ()-#if USE_WW_DEEPSEQ-     | TI{} <- pas  = if elem td treps then () else rnf d-     | TW{} <- pas  = if elem td treps then rnf d else ()-#else-     | TI{} <- pas  = if elem td treps then () else rnfn 999999 d  -- XXX thack!-#endif-     | otherwise    = rnfp' pas recurs d-     where-      as = getPatNodeAttrs pas-      treps = typeConstraints as-      td = show $ typeRepTyCon $ typeOf d-      recurs = case length chs of-        0 -> case pas of-              WS{} -> ()-              _ -> pat_match_fail-        3 -> {-trace "WWW" $-}-             let [px,py,pz] = chs-                 (x,y,z) = d-#if USE_PSEQ_PATNODE-             in pseq_condition pat [ rnfp px x-                                   , rnfp py y-                                   , rnfp pz z-                                   ]-#else-             in       ({-trace "XXX" $-} rnfp px x)-                `seq` ({-trace "YYY" $-} rnfp py y)--- This WILL change the semantics unfortunately...---              `seq` (trace ("YYY "++show py++" "++show y) $ rnfp py y)-                `seq` ({-trace "ZZZ" $-} rnfp pz z)-#endif-                `seq` ()  -- needed?-        _ -> pat_match_fail-      pat_match_fail = patMatchFail' "(,,)" pas chs d------------------------------------------------------------------------------------- (a,b,c,d)--#if ( ! HASKELL98_FRAGMENT ) && ( __GLASGOW_HASKELL__ >= 710 )-  instance (NFDataP_ictx a, NFDataP_ictx b, NFDataP_ictx c, NFDataP_ictx d) => NFDataP (a,b,c,d) where-#else-#if INCLUDE_SHOW_INSTANCES-  instance (Show a, Typeable a, NFDataP a, Show b, Typeable b, NFDataP b, Show c, Typeable c, NFDataP c, Show d, Typeable d, NFDataP d) => NFDataP (a,b,c,d) where-#else-  instance (Typeable a, NFDataP a, Typeable b, NFDataP b, Typeable c, NFDataP c, Typeable d, NFDataP d) => NFDataP (a,b,c,d) where-#endif-#endif-    {-  NOINLINE rnfp #-}-    rnfp p x | handleAttrs p x == Node XX []  = undefined-    rnfp (Node WI{} _) _ = ()-    rnfp pat@(Node pas chs) d-     | TR{} <- pas  = if elem td treps then recurs else ()-#if USE_WW_DEEPSEQ-     | TI{} <- pas  = if elem td treps then () else rnf d-     | TW{} <- pas  = if elem td treps then rnf d else ()-#else-     | TI{} <- pas  = if elem td treps then () else rnfn 999999 d  -- XXX thack!-#endif-     | otherwise    = rnfp' pas recurs d-     where-      as = getPatNodeAttrs pas-      treps = typeConstraints as-      td = show $ typeRepTyCon $ typeOf d-      recurs = case length chs of-        0 -> case pas of-              WS{} -> ()-              _ -> pat_match_fail-        4 -> let [px1,px2,px3,px4] = chs-                 (x1,x2,x3,x4) = d-#if USE_PSEQ_PATNODE-             in pseq_condition pat [ rnfp px1 x1-                                   , rnfp px2 x2-                                   , rnfp px3 x3-                                   , rnfp px4 x4-                                   ]-#else-             in       rnfp px1 x1-                `seq` rnfp px2 x2-                `seq` rnfp px3 x3-                `seq` rnfp px4 x4-#endif-                `seq` ()  -- needed?-        _ -> pat_match_fail-      pat_match_fail = patMatchFail' "(,,,)" pas chs d------------------------------------------------------------------------------------- (a,b,c,d,e)--#if ( ! HASKELL98_FRAGMENT ) && ( __GLASGOW_HASKELL__ >= 710 )-  instance (NFDataP_ictx a, NFDataP_ictx b, NFDataP_ictx c, NFDataP_ictx d, NFDataP_ictx e) =>-#else-#if INCLUDE_SHOW_INSTANCES-  instance (Show a, Typeable a, NFDataP a, Show b, Typeable b, NFDataP b, Show c, Typeable c, NFDataP c, Show d, Typeable d, NFDataP d, Show e, Typeable e, NFDataP e) =>-#else-  instance (Typeable a, NFDataP a, Typeable b, NFDataP b, Typeable c, NFDataP c, Typeable d, NFDataP d, Typeable e, NFDataP e) =>-#endif-#endif-         NFDataP (a, b, c, d, e) where-    {-  NOINLINE rnfp #-}-    rnfp p x | handleAttrs p x == Node XX []  = undefined-    rnfp (Node WI{} _) _ = ()-    rnfp pat@(Node pas chs) d-     | TR{} <- pas  = if elem td treps then recurs else ()-#if USE_WW_DEEPSEQ-     | TI{} <- pas  = if elem td treps then () else rnf d-     | TW{} <- pas  = if elem td treps then rnf d else ()-#else-     | TI{} <- pas  = if elem td treps then () else rnfn 999999 d  -- XXX thack!-#endif-     | otherwise    = rnfp' pas recurs d-     where-      as = getPatNodeAttrs pas-      treps = typeConstraints as-      td = show $ typeRepTyCon $ typeOf d-      recurs = case length chs of-        0 -> case pas of-              WS{} -> ()-              _ -> pat_match_fail-        5 -> let [px1,px2,px3,px4,px5] = chs-                 (x1,x2,x3,x4,x5) = d-#if USE_PSEQ_PATNODE-             in pseq_condition pat [ rnfp px1 x1-                                   , rnfp px2 x2-                                   , rnfp px3 x3-                                   , rnfp px4 x4-                                   , rnfp px5 x5-                                   ]-#else-             in       rnfp px1 x1-                `seq` rnfp px2 x2-                `seq` rnfp px3 x3-                `seq` rnfp px4 x4-                `seq` rnfp px5 x5-#endif-                `seq` ()  -- needed?-        _ -> pat_match_fail-      pat_match_fail = patMatchFail' "(,,,,)" pas chs d------------------------------------------------------------------------------------- (a,b,c,d,e,f)--#if ( ! HASKELL98_FRAGMENT ) && ( __GLASGOW_HASKELL__ >= 710 )-  instance (NFDataP_ictx a, NFDataP_ictx b, NFDataP_ictx c, NFDataP_ictx d, NFDataP_ictx e, NFDataP_ictx f) =>-#else-#if INCLUDE_SHOW_INSTANCES-  instance (Show a, Typeable a, NFDataP a, Show b, Typeable b, NFDataP b, Show c, Typeable c, NFDataP c, Show d, Typeable d, NFDataP d, Show e, Typeable e, NFDataP e, Show f, Typeable f, NFDataP f) =>-#else-  instance (Typeable a, NFDataP a, Typeable b, NFDataP b, Typeable c, NFDataP c, Typeable d, NFDataP d, Typeable e, NFDataP e, Typeable f, NFDataP f) =>-#endif-#endif-         NFDataP (a, b, c, d, e, f) where-    {-  NOINLINE rnfp #-}-    rnfp p x | handleAttrs p x == Node XX []  = undefined-    rnfp (Node WI{} _) _ = ()-    rnfp pat@(Node pas chs) d-     | TR{} <- pas  = if elem td treps then recurs else ()-#if USE_WW_DEEPSEQ-     | TI{} <- pas  = if elem td treps then () else rnf d-     | TW{} <- pas  = if elem td treps then rnf d else ()-#else-     | TI{} <- pas  = if elem td treps then () else rnfn 999999 d  -- XXX thack!-#endif-     | otherwise    = rnfp' pas recurs d-     where-      as = getPatNodeAttrs pas-      treps = typeConstraints as-      td = show $ typeRepTyCon $ typeOf d-      recurs = case length chs of-        0 -> case pas of-              WS{} -> ()-              _ -> pat_match_fail-        6 -> let [px1,px2,px3,px4,px5,px6] = chs-                 (x1,x2,x3,x4,x5,x6) = d-#if USE_PSEQ_PATNODE-             in pseq_condition pat [ rnfp px1 x1-                                   , rnfp px2 x2-                                   , rnfp px3 x3-                                   , rnfp px4 x4-                                   , rnfp px5 x5-                                   , rnfp px6 x6-                                   ]-#else-             in       rnfp px1 x1-                `seq` rnfp px2 x2-                `seq` rnfp px3 x3-                `seq` rnfp px4 x4-                `seq` rnfp px5 x5-                `seq` rnfp px6 x6-#endif-                `seq` ()  -- needed?-        _ -> pat_match_fail-      pat_match_fail = patMatchFail' "(,,,,,)" pas chs d------------------------------------------------------------------------------------- (a,b,c,d,e,f,g)--#if ( ! HASKELL98_FRAGMENT ) && ( __GLASGOW_HASKELL__ >= 710 )-  instance (NFDataP_ictx a, NFDataP_ictx b, NFDataP_ictx c, NFDataP_ictx d, NFDataP_ictx e, NFDataP_ictx f, NFDataP_ictx g) =>-#else-#if INCLUDE_SHOW_INSTANCES-  instance (Show a, Typeable a, NFDataP a, Show b, Typeable b, NFDataP b, Show c, Typeable c, NFDataP c, Show d, Typeable d, NFDataP d, Show e, Typeable e, NFDataP e, Show f, Typeable f, NFDataP f, Show g, Typeable g, NFDataP g) =>-#else-  instance (Typeable a, NFDataP a, Typeable b, NFDataP b, Typeable c, NFDataP c, Typeable d, NFDataP d, Typeable e, NFDataP e, Typeable f, NFDataP f, Typeable g, NFDataP g) =>-#endif-#endif-         NFDataP (a, b, c, d, e, f, g) where-    {-  NOINLINE rnfp #-}-    rnfp p x | handleAttrs p x == Node XX []  = undefined-    rnfp (Node WI{} _) _ = ()-    rnfp pat@(Node pas chs) d-     | TR{} <- pas  = if elem td treps then recurs else ()-#if USE_WW_DEEPSEQ-     | TI{} <- pas  = if elem td treps then () else rnf d-     | TW{} <- pas  = if elem td treps then rnf d else ()-#else-     | TI{} <- pas  = if elem td treps then () else rnfn 999999 d  -- XXX thack!-#endif-     | otherwise    = rnfp' pas recurs d-     where-      as = getPatNodeAttrs pas-      treps = typeConstraints as-      td = show $ typeRepTyCon $ typeOf d-      recurs = case length chs of-        0 -> case pas of-              WS{} -> ()-              _ -> pat_match_fail-        7 -> let [px1,px2,px3,px4,px5,px6,px7] = chs-                 (x1,x2,x3,x4,x5,x6,x7) = d-#if USE_PSEQ_PATNODE-             in pseq_condition pat [ rnfp px1 x1-                                   , rnfp px2 x2-                                   , rnfp px3 x3-                                   , rnfp px4 x4-                                   , rnfp px5 x5-                                   , rnfp px6 x6-                                   , rnfp px7 x7-                                   ]-#else-             in       rnfp px1 x1-                `seq` rnfp px2 x2-                `seq` rnfp px3 x3-                `seq` rnfp px4 x4-                `seq` rnfp px5 x5-                `seq` rnfp px6 x6-                `seq` rnfp px7 x7-#endif-                `seq` ()  -- needed?-        _ -> pat_match_fail-      pat_match_fail = patMatchFail' "(,,,,,,)" pas chs d--#if 0---- XXX No Typeable instances for tuples larger than 7 in 7.8.1, seemingly?------------------------------------------------------------------------------------- (a,b,c,d,e,f,g,h)--#if ( ! HASKELL98_FRAGMENT ) && ( __GLASGOW_HASKELL__ >= 710 )-  instance (NFDataP_ictx a, NFDataP_ictx b, NFDataP_ictx c, NFDataP_ictx d, NFDataP_ictx e, NFDataP_ictx f, NFDataP_ictx g, NFDataP_ictx h) =>-#else-#if INCLUDE_SHOW_INSTANCES-  instance (Show a, Typeable a, NFDataP a, Show b, Typeable b, NFDataP b, Show c, Typeable c, NFDataP c, Show d, Typeable d, NFDataP d, Show e, Typeable e, NFDataP e, Show f, Typeable f, NFDataP f, Show g, Typeable g, NFDataP g, Show h, Typeable h, NFDataP h) =>-#else-  instance (Typeable a, NFDataP a, Typeable b, NFDataP b, Typeable c, NFDataP c, Typeable d, NFDataP d, Typeable e, NFDataP e, Typeable f, NFDataP f, Typeable g, NFDataP g, Typeable h, NFDataP h) =>-#endif-#endif-         NFDataP (a, b, c, d, e, f, g, h) where-    {-  NOINLINE rnfp #-}-    rnfp p x | handleAttrs p x == Node XX []  = undefined-    rnfp (Node WI{} _) _ = ()-    rnfp pat@(Node pas chs) d-     | TR{} <- pas  = if elem td treps then recurs else ()-#if USE_WW_DEEPSEQ-     | TI{} <- pas  = if elem td treps then () else rnf d-     | TW{} <- pas  = if elem td treps then rnf d else ()-#else-     | TI{} <- pas  = if elem td treps then () else rnfn 999999 d  -- XXX thack!-#endif-     | otherwise    = rnfp' pas recurs d-     where-      as = getPatNodeAttrs pas-      treps = typeConstraints as-      td = show $ typeRepTyCon $ typeOf d-      recurs = case length chs of-        0 -> case pas of-              WS{} -> ()-              _ -> pat_match_fail-        8 -> let [px1,px2,px3,px4,px5,px6,px7,px8] = chs-                 (x1,x2,x3,x4,x5,x6,x7,x8) = d-#if USE_PSEQ_PATNODE-             in pseq_condition pat [ rnfp px1 x1-                                   , rnfp px2 x2-                                   , rnfp px3 x3-                                   , rnfp px4 x4-                                   , rnfp px5 x5-                                   , rnfp px6 x6-                                   , rnfp px7 x7-                                   , rnfp px8 x8-                                   ]-#else-             in       rnfp px1 x1-                `seq` rnfp px2 x2-                `seq` rnfp px3 x3-                `seq` rnfp px4 x4-                `seq` rnfp px5 x5-                `seq` rnfp px6 x6-                `seq` rnfp px7 x7-                `seq` rnfp px8 x8-#endif-                `seq` ()  -- needed?-        _ -> pat_match_fail-      pat_match_fail = patMatchFail' "(,,,,,,,)" pas chs d--#endif-----------------------------------------------------------------------------------  patMatchFail :: (Show a, Show b) => a -> b -> c -> ()-  patMatchFail pas chs d-#if WARN_PATTERN_MATCH_FAILURE-   = ( unsafePerformIO $! putStrLn $! "NFDataP: warning: couldn't match " ++ show pas ++ " (having children " ++ show chs ++ ")" ) `seq` ()-#else-   = ()-#endif--- = error $ "NFDataP: Couldn't match " ++ show pas ++ " (having children " ++ show chs ++ ")\nwith data " ++ show d--  patMatchFail' :: (Show a, Show b) => String -> a -> b -> c -> ()-  patMatchFail' inst pas chs d-#if WARN_PATTERN_MATCH_FAILURE-   = ( unsafePerformIO $! putStrLn $! "NFDataP: warning: instance " ++ inst ++ ": bad PatNode child list" ) `seq` patMatchFail pas chs d-#else-   = ()-#endif------------------------------------------------------------------------------------- XXX Seeing as we're having troubles anyway, and considering--- that most of this function requires popping into unsafePerformIO--- anyway -- should the whole thing be returning IO, and then just--- use unsafePerformIO in caller?--  -- This function collects all the "harmless impure things" we-  -- need to pop into IO to do.  To what extent we get away with-  -- this remains to be investigated...-  -------  -- So, which of the PatNodeAttrs product type can be dealt with here?-  --   NOT doSpark  - dealt with downstream in rnfp'-  --   NOT doPseq   - about to be dealt with downstream (hopefully rnfp')...-  --       doDelay-  --       doTrace-  --       doPing-  --       doDie-  --       doTiming-  ------  -- XXX Returning Pattern instead of Bool, in a continued attempt-  -- to outsmart GHC and get certain things to be evaluated...--  {-  NOINLINE handleAttrs #-}-#if 0--- XXX XXX XXX testing only!!!! XXX XXX XXX-  handleAttrs pat@(Node p _) x = pat-#else-#if ! HASKELL98_FRAGMENT-#if HANDLE_ATTRS_DATA_CONSTRAINT-  handleAttrs :: forall d. Data d => Pattern -> d -> Pattern---handleAttrs :: forall d. Data d => Pattern -> d -> Bool-  handleAttrs (Node p _) x-#else-  handleAttrs :: forall d. Typeable d => Pattern -> d -> Pattern---handleAttrs :: forall d. Typeable d => Pattern -> d -> Bool-  handleAttrs (Node p _) x-#endif-#else-  handleAttrs :: Pattern -> a -> Pattern---handleAttrs :: Pattern -> a -> Bool-  handleAttrs (Node p _) _-#endif---- | doTrace as && trace ("HERE! "++show p++"\n"++show as) False = undefined---- | trace ("HERE! "++show p++"\n"++show as) False = undefined-#if 0-    | uniqueID as ==  4 && trace ("HERE! "++show p++"\n"++show as) False = undefined-    | uniqueID as ==  9 && trace ("HERE! "++show p++"\n"++show as) False = undefined-    | uniqueID as == 11 && trace ("HERE! "++show p++"\n"++show as) False = undefined-#endif---- | otherwise  = unsafePerformIO $! do-    | otherwise  = unsafePerformIO $ do---- | otherwise  = trace ("BUHGO!") $ unsafePerformIO $ do---- | otherwise  = trace ("BUHGO!") $ unsafeDupablePerformIO $ do-       let p0 = p-       p1 <- if doDelay as-             then dly p0 b-             else return p0-#if USE_TRACE_PATNODE-       p2 <- if doTrace as-             then trc p1 b msg_trc-             else return p1-#else-       let p2 = p1-#endif-#if USE_PING_PATNODE-       p3 <- if doPing as-             then png p2 b msg_png-             else return p2-#else-       let p3 = p2-#endif-#if USE_DIE_PATNODE-       p4 <- if doDie as-             then die p3 b msg_die-             else return p3-#else-       let p4 = p3-#endif-#if USE_TIMING_PATNODE-       p5 <- if doTiming as-             then timing p4 b msg_timing-             else return p4-#else-       let p5 = p4-#endif-       return $! Node p5 []-    | otherwise                   = Node p []  -- don't forget!---- | otherwise                   = p     -- don't forget!---- | otherwise                   = True  -- don't forget!-   where-#if 1-    b = False  -- WORKED for Ping/png; not working for Trace/trc...-#else-    b = unsafePerformIO $ ( randomIO :: IO Bool )  -- WORKS!!! (even though value is constant!)-#endif-    {-# NOINLINE dly #-}  -- XXX crucial-    dly p b----  | trace "dly msg!" False = undefined-     | otherwise  = do-         if b-           then do-             !_ <- threadDelay $ delayus as-             return p---           return $ not b-           else do-             !_ <- threadDelay $ delayus as-             return p---           return '-#if USE_TRACE_PATNODE-    msg_trc =    "NFDataP: TRACE: " ++ show (uniqueID as)-#if ! HASKELL98_FRAGMENT-              ++ " " ++ show (typeOf x)-#if HANDLE_ATTRS_DATA_CONSTRAINT-              ++ "\n" ++ showRose (shapeOf x)-#endif-#endif-    {-# NOINLINE trc #-}  -- XXX crucial-    trc p b msg----  | trace "trc msg!" False = undefined-     | otherwise  = do-         if b-           then do----          !_ <- forkIO $ return (trace msg ())----          !_ <- forkIO (return (trace msg ()))-             !_ <- trace msg $ return ()-             return p---           return $ not b-           else do----          !_ <- forkIO $ return (trace msg ())----          !_ <- forkIO (return (trace msg ()))-             !_ <- trace msg $ return ()-             return p---           return '-#endif-#if USE_PING_PATNODE-    msg_png =    "NFDataP: PING: " ++ show (uniqueID as)-#if ! HASKELL98_FRAGMENT-              ++ " " ++ show (typeOf x)-#if HANDLE_ATTRS_DATA_CONSTRAINT-              ++ "\n" ++ showRose (shapeOf x)-#endif-#endif-    {-# NOINLINE png #-}  -- XXX crucial-    -- Consider mkWeakThreadId :: ThreadId -> IO (Weak ThreadId)-    png p b msg----  | trace "png msg!" False = undefined-#if 1-     | isNothing mpngtid  = do---        b <- randomIO :: IO Bool----      let b = False in-         if b-           then do-             return p---           return $ not b-           else do-             return p---           return b-#else-     | isNothing mpngtid  = False-#endif-     | otherwise  = do---        b <- randomIO :: IO Bool----      let b = False in-         if b-           then do-             !_ <- forkIO $ throw $ DeepSeqBounded_PingException msg----          putStrLn "Carrying on FALSE ..."-             return p---           return $ not b-           else do-             -- This worked! (exception thrown, yet continues)-             -- Getting repeatable actions still eludes...---           evaluate (unsafeInterleaveIO (do---           evaluate (unsafeDupablePerformIO (do-             !_ <- forkIO $ throw $ DeepSeqBounded_PingException msg----          putStrLn "Carrying on TRUE ..."-             return p---           return b-     where mpngtid = pingParentTID as-#endif-#if USE_DIE_PATNODE-    msg_die =    "NFDataP: DIE: " ++ show (uniqueID as)-#if ! HASKELL98_FRAGMENT-              ++ " " ++ show (typeOf x)-#if HANDLE_ATTRS_DATA_CONSTRAINT-              ++ "\n" ++ showRose (shapeOf x)-#endif-#endif-    {-# NOINLINE die #-}  -- XXX crucial (except perhaps in this die case...)-    die p b msg = do-      if b-        then do-          putStrLn msg >> myThreadId >>= killThread-          return p---        return $ not b-        else do-          putStrLn msg >> myThreadId >>= killThread-          return p---        return b-#endif-#if USE_TIMING_PATNODE-    msg_timing =    "NFDataP: TIMING: " ++ show (uniqueID as)-#if ! HASKELL98_FRAGMENT-                 ++ " " ++ show (typeOf x)-#if HANDLE_ATTRS_DATA_CONSTRAINT-                 ++ "\n" ++ showRose (shapeOf x)-#endif-#endif-    {-# NOINLINE timing #-}-    timing p b msg = do-      if b-        then do-          -- ... XXX-          return p---        return $ not b-        else do-          -- ... XXX-          return p---        return b-#endif-    as = getPatNodeAttrs p  -- XXX THIS IS BAD (bottleneck)-             -- [See 000-readme, cotemp 20150104.]-             -- Is there not a simpler way to get at the PatNodeAttr?-             -- One thing could do, is put the node type (WR, etc.)-             -- in PatNodeAttrs, and then PatNode = PatNodeAttrs.-             -- There's no real disadvantage, right? -- we can still-             -- pattern match almost as do now:-             --   (Node WR{} cs)               -- now-             --   (Node PN{nodeKind=WR}  cs)   -- hopefully!-#endif-----------------------------------------------------------------------------------#if USE_PSEQ_PATNODE--  -- Note that, if USE_PSEQ_PATNODE flag is True, then Control.Parallel.pseq-  -- is used instead of Prelude.seq, whether or not a >cdba permutation was-  -- specified.  I'd kinda rather continue to use seq for the cases where-  -- no permutation was specified...-  pseq_condition :: Pattern -> [()] -> ()---pseq_condition :: [Pattern] -> [()] -> ()---pseq_condition :: [Pattern] -> [ Pattern -> x -> () ] -> ()---pseq_condition :: [Pattern] -> [Pattern -> x -> ()] -> [Pattern -> x -> ()]-#if 0-#elif 1-  pseq_condition pat@(Node pn cs) fs-   | isNothing mperm  = foldr  seq () fs-   | otherwise        = foldr pseq () $ map (\i->(fs!!i)) perm-   where-    mperm = pseqPerm $ getPatNodeAttrs pn-    perm = fromJust mperm-#elif 0-  pseq_condition pat@(Node pn cs) fs-   = foldr pseq () fs'  -- is foldr the right fold?-   where-    mperm = pseqPerm $ getPatNodeAttrs pn-    perm = fromJust mperm-    fs' | isNothing mperm  = fs-        | otherwise        = map (\i->(fs!!i)) perm-#elif 0-  pseq_condition pats fs = foldr seq () fs  -- is foldr the right fold?-#endif--#endif----------------------------------------------------------------------------------
− src/Control/DeepSeq/Bounded/NFDataP_old_grammar.hs
@@ -1,926 +0,0 @@-----------------------------------------------------------------------------------  {-  LANGUAGE CPP #-}--#define DO_TRACE 0---- XXX Note: Show constraints are for debugging purposes.-#define INCLUDE_SHOW_INSTANCES 0---- Formerly DEBUG_WITH_DEEPSEQ_GENERICS.--- Now also needed to force issuance of all compilePat warnings--- (so not strictly a debugging flag anymore).--- [Except it didn't work...]---- #define NFDATA_INSTANCE_PATTERN 1  -- now it's a .cabal flag---- Now specified via --flag=[-]USE_WWW_DEEPSEQ---- #define USE_WW_DEEPSEQ 1-----------------------------------------------------------------------------------  -- For tracing only:-  {-  LANGUAGE BangPatterns #-}--  {-# OPTIONS_GHC -fno-warn-name-shadowing #-}-  {-# OPTIONS_GHC -fno-warn-overlapping-patterns #-}------------------------------------------------------------------------------------- |--- Module      :  Control.DeepSeq.Bounded.NFDataP_old_grammar--- Copyright   :  Andrew G. Seniuk 2014-2015--- License     :  BSD-style (see the file LICENSE)------ Maintainer  :  Andrew Seniuk <rasfar@gmail.com>--- Stability   :  provisional--- Portability :  portable----{--}--- (Top-level comments are in NFDataP.hs.)-----------------------------------------------------------------------------------  module Control.DeepSeq.Bounded.NFDataP_old_grammar-  where-----------------------------------------------------------------------------------  import Control.DeepSeq.Bounded.Pattern-  import Control.DeepSeq.Bounded.Compile-  import Control.DeepSeq.Bounded.PatUtil ( unionPats, liftPats )--  import Control.DeepSeq.Bounded.NFDataN  -- finally used ("*3" etc.)--#if USE_WW_DEEPSEQ-  import Control.DeepSeq ( NFData )-  import Control.DeepSeq ( rnf )-#endif----import Data.Data  -- "redundant" last checked--  import Data.Typeable ( Typeable )-#if 1-  import Data.Typeable ( typeOf )-#else--- XXX These are NOT interchangeable!-#if __GLASGOW_HASKELL__ >= 781-  import Data.Typeable ( typeRep )-#else-  import Data.Typeable ( typeOf )-#endif-#endif-  import Data.Typeable ( mkTyCon3, mkTyConApp )-  import Data.Typeable ( typeRepTyCon )--#if PARALLELISM_EXPERIMENT-  import Control.Parallel ( par )-#endif--  import Data.Int-  import Data.Word-  import Data.Ratio-  import Data.Complex-  import Data.Array-  import Data.Fixed-  import Data.Version--  import Data.Maybe ( Maybe(..), isJust, fromJust )--  import System.IO.Unsafe ( unsafePerformIO )--  import Debug.Trace ( trace )-----------------------------------------------------------------------------------#if DO_TRACE-  mytrace = trace-#else-  mytrace _ = id-#endif-------------------------------------------------------------------------------------infixr 0 $!!------------------------------------------------------------------------------------- XXX NOTE: These need to return Maybe __, in order to handle--- patterns rooted at a WI (i.e. "#" or equivalent "#{...}").--- Since don't want to do that by default, will simply make--- it a DSL compilePat error...---- XXX NOTE TO SELF: These comments are verbatim from Control.DeepSeq:-  -- | 'deepseqp': evaluates the first argument to the depth specified-  -- by a 'Pattern', before returning the second.-  ---  -- Quoting from the DeepSeq.hs (deepseq package):-  ---  -- / \"'deepseq' can be useful for forcing pending exceptions, eradicating space leaks, or forcing lazy I\/O to happen.  It is also useful in conjunction with parallel Strategies (see the @parallel@ package). /-  ---  -- / There is no guarantee about the ordering of evaluation.  The implementation may evaluate the components of the structure in any order or in parallel.  To impose an actual order on evaluation, use 'pseq' from "Control.Parallel" in the @parallel@ package.\" /-  ---  -- Composition fuses (see 'deepseqp_').-{--} -- XXX LATER: This is flawed for # at root of pattern.-#if INCLUDE_SHOW_INSTANCES-  deepseqp :: (Show a, NFDataP a) => String -> a -> b -> b-#else-  deepseqp :: NFDataP a => String -> a -> b -> b-#endif-#if 0-#elif 0-  deepseqp patstr a b = fromJust $ deepseqp_ (compilePat patstr) a b---deepseqp patstr = fromJust $ deepseqp_ (compilePat patstr)-#elif 1-  deepseqp patstr = deepseqp_ (compilePat patstr)-#elif 0-  deepseqp patstr a b = rnfp (compilePat patstr) a `seq` b-  -- XXX Partially-applied; is that okay in GHC RULES?-  {-# RULES-    "deepseqp/composition"    forall p1 p2 x.  (.) (deepseqp p2) (deepseqp p1) x = deepseqp_ ( unionPats [compilePat p1, compilePat p2] ) x-      #-}-#endif--  -- | Self-composition fuses via-  ---  -- @-  --     "deepseqp_/composition"-  --        forall p1 p2 x1 x2.-  --            (.) ('deepseqp_' p2 x2) ('deepseqp_' p1 x1)-  --          = 'deepseqp_' ( 'liftPats' [p1, p2] ) (x1,x2)-  -- @-  ---  -- (Other fusion rules, not yet documented, may also be in effect.)-{--}-  -- XXX Oh! We have a fundamental problem here!-  -- I realised that-  --   forcep "#" (undefined::Int)-  -- was bottoming out. Then sought to repair that by "doing nothing"-  -- if WI etc. here, as in rnfp.-  -- However, how can we return type b, and "do nothing"?-  --  - if go "`seq` b" does this not force b?-  --    (don't see why it should actually)-  --  - if go "`seq` ()", this is a type error for deepseqp-  --  - if go "`seq` (undefined::b)", this defeats the purpose, as we-  --    precisely do not want to hit bottom... still, this might be-  --    a possible way, if can do it right....-  --  - if go "`seq` defaultValue_in_type_b" -- this is never acceptable-  --    in library code...-  --  - we CAN return Maybe b! This is, after all, deepseqp_-  --    Can decide how to cope with that in the caller.-  --    But at least the need to return type b here is lifted...-  -- As for the RULES, I think they're not ready to use now...--- XXX LATER: This is flawed for # at root of pattern.--- Maybe not quite flawed, just "untestable" if there's bottom at--- the root of the value (that is to say, the value is (undefined::b).-#if INCLUDE_SHOW_INSTANCES-  deepseqp_ :: (Show a, NFDataP a) => Pattern -> a -> b -> b-#else-  deepseqp_ :: NFDataP a => Pattern -> a -> b -> b-#endif-#if 0-#elif 0-  deepseqp_ pat@(Node WI _) _ b = b-  deepseqp_ pat@(Node (TR treps) chs) a b = if elem ta treps then doit `seq` b else b-   where ta = show $ typeRepTyCon $ typeOf a-         doit = rnfp pat a `seq` b-  deepseqp_ pat@(Node (TI treps) chs) a b = if elem ta treps then b else doit `seq` b-   where ta = show $ typeRepTyCon $ typeOf a-         doit = rnfp pat a `seq` b-  deepseqp_ pat a b = rnfp pat a `seq` b-#elif 1-  deepseqp_ pat a b = rnfp pat a `seq` b-  -- XXX Need to double-check that this makes sense; didn't think-  -- it through -- when b != a, things are not so simple.-  -- XXX Partially-applied; is that okay in GHC RULES?-  {-# RULES-    "deepseqp_/composition"    forall p1 p2 x1 x2.  (.) (deepseqp_ p2 x2) (deepseqp_ p1 x1) = deepseqp_ ( liftPats [p1, p2] ) (x1,x2)-      #-}---  "deepseqp_/composition"    forall p1 p2 x.  (.) (deepseqp_ p2) (deepseqp_ p1) x = deepseqp_ ( unionPats [p1, p2] ) x-#endif--  -- | Lifted result, so can cope with undefined values and-  -- still take the head in the caller (if call is after 'seq' or '$!'-  -- for instance).-#if INCLUDE_SHOW_INSTANCES-  deepseqpM :: (Show a, NFDataP a) => String -> a -> b -> Maybe b-#else-  deepseqpM :: NFDataP a => String -> a -> b -> Maybe b-#endif-  deepseqpM patstr a b = deepseqpM_ (compilePat patstr) a b-#if INCLUDE_SHOW_INSTANCES-  deepseqpM_ :: (Show a, NFDataP a) => Pattern -> a -> b -> Maybe b-#else-  deepseqpM_ :: NFDataP a => Pattern -> a -> b -> Maybe b-#endif-  deepseqpM_ pat@(Node WI _) _ _ = Nothing-  deepseqpM_ pat@(Node (TR treps) chs) a b = if elem ta treps then doit `seq` Just b else Nothing-   where ta = show $ typeRepTyCon $ typeOf a-         doit = rnfp pat a `seq` b-  deepseqpM_ pat@(Node (TI treps) chs) a b = if elem ta treps then Nothing else doit `seq` Just b-   where ta = show $ typeRepTyCon $ typeOf a-         doit = rnfp pat a `seq` b-  deepseqpM_ pat a b = rnfp pat a `seq` Just b-----------------------------------------------------------------------------------#if 0-  -- | the deep analogue of '$!'.  In the expression @f $!! x@, @x@ is-  -- fully evaluated before the function @f@ is applied to it.-  ($!!) :: (NFData a) => (a -> b) -> a -> b-  f $!! x = x `deepseq` f x-#endif--  -- | A variant of 'deepseqp' that is sometimes convenient:-  ---  -- > forcep pat x = deepseqp pat x x   -- (cannot write x `deepseqp pat` x by analogy with x `deepseq` x)-  ---  -- @forcep pat x@ evaluates @x@ to the depth determined by @pat@, and-  -- then returns @x@.  Note that @forcep pat x@ only takes effect-  -- when the value of @forcep pat x@ itself is demanded, so essentially-  -- it turns shallow evaluation into evaluation to arbitrary bounded depth.-  ---  -- Composition fuses (see 'forcep_').-{--}--- XXX What about mixed cases??...--- XXX LATER: This is flawed for # at root of pattern.-#if INCLUDE_SHOW_INSTANCES-  forcep :: (Show a, NFDataP a) => String -> a -> a-#else-  forcep :: NFDataP a => String -> a -> a-#endif-#if 0-#elif 0-  forcep patstr x-   | p          = fromJust ma--- | otherwise  = error "here"-   | otherwise  = undefined::a-   where ma = deepseqp_ (compilePat patstr) x x-         p = isJust ma-#elif 0-  forcep patstr x = fromJust $ deepseqp_ (compilePat patstr) x x-#elif 0-  forcep patstr x-   | b          = x-   | otherwise  = fromJust y-   where y = deepseqp_ (compilePat patstr) x (Just x)-         pat@(Node p chs) = compilePat patstr-         b | WI <- p      = True-           | TR _ <- p    = True-           | TN _ _ <- p  = True-           | TW _ <- p    = True-           | TI _ <- p    = True-           | otherwise    = False-#elif 1-  forcep patstr x = deepseqp_ (compilePat patstr) x x---forcep patstr x = deepseqp patstr x x-  {-# RULES-    "forcep/composition"    forall p1 p2 x.  (.) (forcep p2) (forcep p1) x = forcep_ ( unionPats [compilePat p1, compilePat p2] ) x-      #-}-#endif--  -- | Self-composition fuses via-  ---  -- @-  --     "forcep_/composition"-  --        forall p1 p2 x.-  --            (.) ('forcep_' p2) ('forcep_' p1) x-  --          = 'forcep_' ( 'unionPats' [p1, p2] ) x-  -- @-  ---  -- (Other fusion rules, not yet documented, may also be in effect.)-{--}--- XXX LATER: This is flawed for # at root of pattern.-#if INCLUDE_SHOW_INSTANCES-  forcep_ :: (Show a, NFDataP a) => Pattern -> a -> a-#else-  forcep_ :: NFDataP a => Pattern -> a -> a-#endif-#if 0-  forcep_ pat x = fromJust $ deepseqp_ pat x x-#else-  forcep_ pat x = deepseqp_ pat x x-  {-# RULES-    "forcep_/composition"    forall p1 p2 x.  (.) (forcep_ p2) (forcep_ p1) x = forcep_ ( unionPats [p1, p2] ) x-      #-}-#endif--  -- | Lifted result, so can cope with undefined values and-  -- still take the head in the caller (if call is after 'seq' or '$!'-  -- for instance).-#if INCLUDE_SHOW_INSTANCES-  forcepM :: (Show a, NFDataP a) => String -> a ->  Maybe a-#else-  forcepM :: NFDataP a => String -> a ->  Maybe a-#endif-  forcepM patstr a = forcepM_ (compilePat patstr) a-#if INCLUDE_SHOW_INSTANCES-  forcepM_ :: (Show a, NFDataP a) => Pattern -> a -> Maybe a-#else-  forcepM_ :: NFDataP a => Pattern -> a -> Maybe a-#endif-  forcepM_ pat x = deepseqpM_ pat x x-----------------------------------------------------------------------------------  -- | A class of types that can be evaluated over an arbitrary finite pattern.-#if USE_WW_DEEPSEQ-  class (Typeable a, NFDataN a, NFData a) => NFDataP a where-#else-  class (Typeable a, NFDataN a) => NFDataP a where-#endif-    -- | Self-composition fuses via-    ---    -- @-    --     "rnfp/composition"-    --        forall p1 p2 x.-    --            (.) ('rnfp' p2) ('rnfp' p1) x-    --          = 'rnfp' ( 'unionPats' [p1, p2] ) x-    -- @-    ---    -- (Other fusion rules, not yet documented, may also be in effect.)-    {-  NOINLINE rnfp #-}-#if INCLUDE_SHOW_INSTANCES-    rnfp :: Show a => Pattern -> a -> ()-#else-    rnfp :: Pattern -> a -> ()-#endif-    rnfp (Node WI _) _ = ()-    rnfp (Node (TR treps) chs) d = if elem td treps then d `seq` () else ()-     where td = show $ typeRepTyCon $ typeOf d-    rnfp (Node (TI treps) chs) d = if elem td treps then () else d `seq` ()-     where td = show $ typeRepTyCon $ typeOf d-#if 1-    rnfp _ d = d `seq` ()---  rnfp _ _ = ()-#else-    -- XXX temporarily (at least) commenting out; not making any-    -- use of patternShapeOK -- but there is room for more-    -- error-trapping code in here, definitely...-    rnfp pat a | not $ patternShapeOK pat a  = ()-               | otherwise  = rnf a-#endif--  {-# RULES-    "rnfp/composition"    forall p1 p2 x.  (.) (rnfp p2) (rnfp p1) x = rnfp ( unionPats [p1, p2] ) x-      #-}---  "rnfp/composition"    forall p1 p2 x.  compose (rnfp p2) (rnfp p1) x = rnfp ( unionPats [p1, p2] ) x---  "rnfp/composition"    forall p1 p2 x.  ( rnfp p2 . rnfp p1 ) x = rnfp ( unionPats [p1, p2] ) x-----------------------------------------------------------------------------------#if USE_WW_DEEPSEQ-  rnfp' :: (Typeable a, NFDataN a, NFData a) => PatNode -> () -> a -> ()-#else-  rnfp' :: (Typeable a, NFDataN a) => PatNode -> () -> a -> ()-#endif--- Sig. as it was as a class method of NFDataP:---rnfp' :: PatNode -> () -> a -> ()-  rnfp' pat recurs d-   -- I can only conclude that we've already evaluated the argument-   -- by the time this code runs (or that we evaluate it after...).-   -- But this code doesn't do the dirty deed!-   = {-trace ( "rnfp' " ++ show pat) $-}-     let td = show $ typeRepTyCon $ typeOf d in  -- no problem on bottom-     case pat of-      WI -> error "rnfp: unexpected WI (please report this bug!)"-      TR treps -> error "rnfp: unexpected TR (please report this bug!)"-      TI treps -> error "rnfp: unexpected TI (please report this bug!)"-#if PARALLELISM_EXPERIMENT-      -- XXX will this work? ... YES IT SEEMS TO!!! (Esp. evident in ghci.)-      PR -> recurs `par` ()-      PN n -> rnfn n d `par` ()-#if USE_WW_DEEPSEQ-      PW -> rnf d `par` ()  -- the only place deepseq package is used-#endif-#endif-#ifdef SEQUENTIALISM_EXPERIMENT-#error Sorry, SEQUENTIALISM_EXPERIMENT is not done yet.--- XXX Alas! This won't work, at least not according to the same method--- as PR etc.  There's no possible use in the `pseq` () section!--- (Unlike `par` (), which is already working for parallel speedup.)--- So, SEQUENTIALISM_EXPERIMENT may be the one where we would need--- to edit all the instances individually...  This again raises the--- question of how we handle higher-arity nodes? It makes no sense--- (unlike parallel) to pseq just one sibling. If you pseq a subset--- of siblings, their subharnesses will be sequenced, yes (and the--- remainder will be order-free).---   Unfortunately, to express this is not easy (unlike for parallel).--- So, this is on hold for the time being.---    SR -> recurs `pseq` ()-#endif-      WR -> recurs-      WS -> ()---      WS -> d `seq` ()-      WN n -> rnfn n d-#if USE_WW_DEEPSEQ-      WW -> rnf d  -- the only place deepseq package is used-#endif-      -- This code stays the same whether we (are able to) compare-      -- actual TypeRep's for equality, or we just hack it-      -- and match:  show . typeRepTyCon . typeOf-      TR treps ->  if       elem td treps then recurs else ()-#if 0-      -- This is not right. To pull this off (b/c it depends on-      -- types in the value your matching with), need to construct-      -- the pattern dynamically.  In particular, to produce Nil-      -- where a TR (or TS) constraint causes (or would cause)-      -- match failure.-      TS treps ->  if       elem td treps then () else ()-#endif-      TN n treps ->  if       elem td treps then rnfn n d else ()-#if USE_WW_DEEPSEQ-      TW treps ->  if       elem td treps then rnf d else ()-#endif-#if 0-      NTR treps -> if not $ elem td treps then recurs else ()-      NTN n treps -> if not $ elem td treps then rnfn n d else ()-#if USE_WW_DEEPSEQ-      NTW treps -> if not $ elem td treps then rnf d else ()-#endif-#endif-      _ -> error "rnfp: Unexpected constructor!"-----------------------------------------------------------------------------------#if 0-  compose = (.)-  {-# NOINLINE compose #-}-  -- Can't do this, unfortunately.  GHC warns it may get inlined before-  -- rules have a chance to fire.  I would rather avoid forcing the API-  -- user to use some custom "compose" function, since base (.) works-  -- perfectly, except it's hard to control its inlining...-  {-  NOINLINE (.) #-}-#endif-----------------------------------------------------------------------------------  instance NFDataP Int-  instance NFDataP Word-  instance NFDataP Integer-  instance NFDataP Float-  instance NFDataP Double--  instance NFDataP Char-#if 0--- (testing something or other)-  instance NFDataP Bool-   where-    rnfp (Node WI _) _ = ()-    rnfp _ d = d `seq` ()-#else-  instance NFDataP Bool-#endif-  instance NFDataP ()--  instance NFDataP Int8-  instance NFDataP Int16-  instance NFDataP Int32-  instance NFDataP Int64--  instance NFDataP Word8-  instance NFDataP Word16-  instance NFDataP Word32-  instance NFDataP Word64-----------------------------------------------------------------------------------  instance Typeable a => NFDataP (Fixed a)---instance NFDataP (Fixed a)-----------------------------------------------------------------------------------  -- [Quoted from deepseq:]-  -- This instance is for convenience and consistency with 'seq'.-  -- This assumes that WHNF is equivalent to NF for functions.-  instance (Typeable a, Typeable b) => NFDataP (a -> b)---instance NFDataP (a -> b)-----------------------------------------------------------------------------------#if 0---- XXX ignore if in IO (cludge easing an experiment...)--#if USE_WW_DEEPSEQ-  instance NFData a => NFData (IO a) where-    rnf x = ()  -- XXX ignore if in IO (cludge easing an experiment...)-#endif--  instance NFDataP a => NFDataP (IO a) where-    rnfp pat x = ()  -- XXX ignore if in IO (cludge easing an experiment...)--#endif-------------------------------------------------------------------------------------Rational and complex numbers.---- not taken to be a level of depth-#if INCLUDE_SHOW_INSTANCES-  instance (Show a, Integral a, NFDataP a) => NFDataP (Ratio a) where-#else-  instance (Integral a, NFDataP a) => NFDataP (Ratio a) where-#endif-    -- XXX This is very dubious!...-    {-  NOINLINE rnfp #-}-    rnfp (Node WI _) _ = ()-    rnfp pat x = rnfp pat (numerator x, denominator x)--  -- Note that (Complex a) constructor (:+) has strict fields,-  -- so unwrapping the ctor also forces both components.-#if INCLUDE_SHOW_INSTANCES-  instance (Show a, RealFloat a, NFDataP a) => NFDataP (Complex a) where-#else-  instance (RealFloat a, NFDataP a) => NFDataP (Complex a) where-#endif-    {-  NOINLINE rnfp #-}-    rnfp (Node WI _) _ = ()-    rnfp (Node pat chs) d-     | TR treps <- pat  = if elem td treps then recurs else ()-     | TI treps <- pat  = if elem td treps then () else recurs-     | otherwise        = rnfp' pat recurs d-     where-      td = show $ typeRepTyCon $ typeOf d-      recurs = case length chs of-        0 -> case pat of-              WS -> ()-              _ -> pat_match_fail-        2 -> let [px,py] = chs ; (x:+y) = d-             in       rnfp px x-                `seq` rnfp py y-                `seq` ()  -- needed?-        _ -> pat_match_fail-      pat_match_fail = patMatchFail' "(Complex a)" pat chs d-    rnfp (Node pat chs) d = patMatchFail pat chs d  -- unreachable---- XXX Never until now (so much later) did I properly consider how to--- handle a no-arg (nullary) constructor! It's not hard, but it's--- significantly different than the other cases, as there's no--- subvalue we can grab hold of -- there's no "d"; so this invalidates--- all the code, in the posary (complement of nullary, coinage :) case--- case, which references d.-#if INCLUDE_SHOW_INSTANCES-  instance (Show a, NFDataP a) => NFDataP (Maybe a) where-#else-  instance NFDataP a => NFDataP (Maybe a) where-#endif-    {-  NOINLINE rnfp #-}-    rnfp (Node WI _) _ = ()-    rnfp (Node pat chs) Nothing-     | not $ null chs   = pat_match_fail-     | otherwise        = ()-     where-      pat_match_fail = patMatchFail' "Nothing" pat chs ()-    rnfp (Node pat chs) (Just d)-     | TR treps <- pat  = if elem td treps then recurs else ()-     | TI treps <- pat  = if elem td treps then () else recurs-     | otherwise        = rnfp' pat recurs d-     where-      td = show $ typeRepTyCon $ typeOf d-      recurs = case length chs of-        0 -> case pat of-              WS -> ()-              _ -> pat_match_fail-        1 -> let [p_J] = chs-             in       rnfp p_J d-                `seq` ()  -- needed?-        _ -> pat_match_fail-      pat_match_fail = patMatchFail' "Just" pat chs d-    rnfp (Node pat chs) d = patMatchFail pat chs d  -- unreachable--#if INCLUDE_SHOW_INSTANCES-  instance (Show a, Show b, NFDataP a, NFDataP b) => NFDataP (Either a b) where-#else-  instance (NFDataP a, NFDataP b) => NFDataP (Either a b) where-#endif-    {-  NOINLINE rnfp #-}-    rnfp (Node WI _) _ = ()-    rnfp (Node pat chs) (Left d)-     | TR treps <- pat  = if elem td treps then recurs else ()-     | TI treps <- pat  = if elem td treps then () else recurs-     | otherwise        = rnfp' pat recurs d-     where-      td = show $ typeRepTyCon $ typeOf d-      recurs = case length chs of-        0 -> case pat of-              WS -> ()-              _ -> pat_match_fail-        1 -> let [p_L] = chs ;-             in       rnfp p_L d-                `seq` ()  -- needed?-        _ -> pat_match_fail-      pat_match_fail = patMatchFail' "Left" pat chs d---    pat_match_fail = patMatchFail' "(Either a b)" pat chs d-    rnfp (Node pat chs) (Right d)-     | TR treps <- pat  = if elem td treps then recurs else ()-     | TI treps <- pat  = if elem td treps then () else recurs-     | otherwise        = rnfp' pat recurs d-     where-      td = show $ typeRepTyCon $ typeOf d-      recurs = case length chs of-        0 -> case pat of-              WS -> ()-              _ -> pat_match_fail-        1 -> let [p_R] = chs-             in       rnfp p_R d-                `seq` ()  -- needed?-        _ -> pat_match_fail-      pat_match_fail = patMatchFail' "Right" pat chs d---    pat_match_fail = patMatchFail' "(Either a b)" pat chs d-    rnfp (Node pat chs) d = patMatchFail pat chs d  -- unreachable----- #if __GLASGOW_HASKELL__ < 781---- -- requires -XStandaloneDeriving---- -- orphan instance, but better than dropping support---- -- (It seems it already has its Show instance!)---- deriving instance Data Data.Version.Version---- #endif----deriving instance Data TypeRep  -- can't b/c not all data ctors are in scope!--  -- Data.Version ctor does /not/ have strict fields.-  instance NFDataP Data.Version.Version where-    {-  NOINLINE rnfp #-}-    rnfp (Node WI _) _ = ()-    rnfp (Node pat chs) d-     | TR treps <- pat  = if elem td treps then recurs else ()-     | TI treps <- pat  = if elem td treps then () else recurs-     | otherwise        = rnfp' pat recurs d-     where-      td = show $ typeRepTyCon $ typeOf d-      recurs = case length chs of-        0 -> case pat of-              WS -> ()-              _ -> pat_match_fail-        2 -> let [pbr,ptags] = chs ; Data.Version.Version branch tags = d-             in       rnfp pbr branch-                `seq` rnfp ptags tags-                `seq` ()  -- needed?-        _ -> pat_match_fail-      pat_match_fail = patMatchFail' "Data.Version.Version" pat chs d-    rnfp (Node pat chs) d = patMatchFail pat chs d  -- unreachable--  -- Data.List ctors do /not/ have strict fields (i.e. (:) is not strict).-#if INCLUDE_SHOW_INSTANCES-  instance (Show a, NFDataP a) => NFDataP [a] where-#else-  instance NFDataP a => NFDataP [a] where-#endif-    {-  NOINLINE rnfp #-}-    rnfp (Node WI _) _ = ()-    rnfp _ [] = ()  -- perhaps dubious?...-    rnfp (Node pat chs) d-     | TR treps <- pat  = if elem td treps then recurs else ()-     | TI treps <- pat  = if elem td treps then () else recurs-     | otherwise        = rnfp' pat recurs d-     where-      td = show $ typeRepTyCon $ typeOf d-      recurs = case length chs of-        0 -> case pat of-              WS -> ()-              _ -> pat_match_fail-        2 -> let [px,pxs] = chs ; (x:xs) = d-             in       rnfp px x-                `seq` rnfp pxs xs-                `seq` ()  -- needed?-        _ -> pat_match_fail-      pat_match_fail = patMatchFail' "[a]" pat chs d-    rnfp (Node pat chs) d = patMatchFail pat chs d  -- unreachable--  -- Data.Array ctor does /not/ have strict fields.-  -- not taken to be a level of depth-#if INCLUDE_SHOW_INSTANCES-  instance (Show a, Show b, Ix a, NFDataP a, NFDataP b) => NFDataP (Array a b) where-#else-  instance (Ix a, NFDataP a, NFDataP b) => NFDataP (Array a b) where-#endif-    -- XXX This is very dubious!...-    {-  NOINLINE rnfp #-}-    rnfp (Node WI _) _ = ()-    rnfp pat x =        rnfp pat (bounds x, Data.Array.elems x)-                  `seq` ()  -- needed?--#if INCLUDE_SHOW_INSTANCES-  instance (Show a,Typeable a,NFDataP a, Show b,Typeable b,NFDataP b) => NFDataP (a,b) where-#else-  instance (Typeable a,NFDataP a, Typeable b,NFDataP b) => NFDataP (a,b) where-#endif-    {-  NOINLINE rnfp #-}-    rnfp (Node WI _) _ = ()-    rnfp (Node pat chs) d-     | TR treps <- pat  = if elem td treps then recurs else ()-     | TI treps <- pat  = if elem td treps then () else recurs-     | otherwise        = rnfp' pat recurs d-     where-      td = show $ typeRepTyCon $ typeOf d-      recurs = case length chs of-        0 -> case pat of-              WS -> ()-              _ -> pat_match_fail-        2 -> let [px,py] = chs ; (x,y) = d-             in       rnfp px x-                `seq` rnfp py y-                `seq` ()  -- needed?-        _ -> pat_match_fail-      pat_match_fail = patMatchFail' "(,)" pat chs d-    rnfp (Node pat chs) d = patMatchFail pat chs d  -- unreachable--#if INCLUDE_SHOW_INSTANCES-  instance (Show a, Typeable a, NFDataP a, Show b, Typeable b, NFDataP b, Show c, Typeable c, NFDataP c) => NFDataP (a,b,c) where-#else-  instance (Typeable a, NFDataP a, Typeable b, NFDataP b, Typeable c, NFDataP c) => NFDataP (a,b,c) where-#endif-    {-  NOINLINE rnfp #-}-    rnfp (Node WI _) _ = ()-    rnfp (Node pat chs) d-     | TR treps <- pat  = if elem td treps then recurs else ()-     | TI treps <- pat  = if elem td treps then () else recurs-     | otherwise        = rnfp' pat recurs d-     where-      td = show $ typeRepTyCon $ typeOf d-      recurs = case length chs of-        0 -> case pat of-              WS -> ()-              _ -> pat_match_fail-        3 -> {-trace "WWW" $-} let [px,py,pz] = chs ; (x,y,z) = d-             in       ({-trace "XXX" $-} rnfp px x)-                `seq` ({-trace "YYY" $-} rnfp py y)--- This WILL change the semantics unfortunately...---              `seq` (trace ("YYY "++show py++" "++show y) $ rnfp py y)-                `seq` ({-trace "ZZZ" $-} rnfp pz z)-                `seq` ()  -- needed?-        _ -> pat_match_fail-      pat_match_fail = patMatchFail' "(,,)" pat chs d-    rnfp (Node pat chs) d = patMatchFail pat chs d  -- unreachable--#if INCLUDE_SHOW_INSTANCES-  instance (Show a, Typeable a, NFDataP a, Show b, Typeable b, NFDataP b, Show c, Typeable c, NFDataP c, Show d, Typeable d, NFDataP d) => NFDataP (a,b,c,d) where-#else-  instance (Typeable a, NFDataP a, Typeable b, NFDataP b, Typeable c, NFDataP c, Typeable d, NFDataP d) => NFDataP (a,b,c,d) where-#endif-    {-  NOINLINE rnfp #-}-    rnfp (Node WI _) _ = ()-    rnfp (Node pat chs) d-     | TR treps <- pat  = if elem td treps then recurs else ()-     | TI treps <- pat  = if elem td treps then () else recurs-     | otherwise        = rnfp' pat recurs d-     where-      td = show $ typeRepTyCon $ typeOf d-      recurs = case length chs of-        0 -> case pat of-              WS -> ()-              _ -> pat_match_fail-        4 -> let [px1,px2,px3,px4] = chs ; (x1,x2,x3,x4) = d-             in       rnfp px1 x1-                `seq` rnfp px2 x2-                `seq` rnfp px3 x3-                `seq` rnfp px4 x4-                `seq` ()  -- needed?-        _ -> pat_match_fail-      pat_match_fail = patMatchFail' "(,,,)" pat chs d-    rnfp (Node pat chs) d = patMatchFail pat chs d--#if INCLUDE_SHOW_INSTANCES-  instance (Show a1, Typeable a1, NFDataP a1, Show a2, Typeable a2, NFDataP a2, Show a3, Typeable a3, NFDataP a3, Show a4, Typeable a4, NFDataP a4, Show a5, Typeable a5, NFDataP a5) =>-#else-  instance (Typeable a1, NFDataP a1, Typeable a2, NFDataP a2, Typeable a3, NFDataP a3, Typeable a4, NFDataP a4, Typeable a5, NFDataP a5) =>-#endif-         NFDataP (a1, a2, a3, a4, a5) where-    {-  NOINLINE rnfp #-}-    rnfp (Node WI _) _ = ()-    rnfp (Node pat chs) d-     | TR treps <- pat  = if elem td treps then recurs else ()-     | TI treps <- pat  = if elem td treps then () else recurs-     | otherwise        = rnfp' pat recurs d-     where-      td = show $ typeRepTyCon $ typeOf d-      recurs = case length chs of-        0 -> case pat of-              WS -> ()-              _ -> pat_match_fail-        5 -> let [px1,px2,px3,px4,px5] = chs ; (x1,x2,x3,x4,x5) = d-             in       rnfp px1 x1-                `seq` rnfp px2 x2-                `seq` rnfp px3 x3-                `seq` rnfp px4 x4-                `seq` rnfp px5 x5-                `seq` ()  -- needed?-        _ -> pat_match_fail-      pat_match_fail = patMatchFail' "(,,,,)" pat chs d-    rnfp (Node pat chs) d = patMatchFail pat chs d--#if INCLUDE_SHOW_INSTANCES-  instance (Show a1, Typeable a1, NFDataP a1, Show a2, Typeable a2, NFDataP a2, Show a3, Typeable a3, NFDataP a3, Show a4, Typeable a4, NFDataP a4, Show a5, Typeable a5, NFDataP a5, Show a6, Typeable a6, NFDataP a6) =>-#else-  instance (Typeable a1, NFDataP a1, Typeable a2, NFDataP a2, Typeable a3, NFDataP a3, Typeable a4, NFDataP a4, Typeable a5, NFDataP a5, Typeable a6, NFDataP a6) =>-#endif-         NFDataP (a1, a2, a3, a4, a5, a6) where-    {-  NOINLINE rnfp #-}-    rnfp (Node WI _) _ = ()-    rnfp (Node pat chs) d-     | TR treps <- pat  = if elem td treps then recurs else ()-     | TI treps <- pat  = if elem td treps then () else recurs-     | otherwise        = rnfp' pat recurs d-     where-      td = show $ typeRepTyCon $ typeOf d-      recurs = case length chs of-        0 -> case pat of-              WS -> ()-              _ -> pat_match_fail-        6 -> let [px1,px2,px3,px4,px5,px6] = chs ; (x1,x2,x3,x4,x5,x6) = d-             in       rnfp px1 x1-                `seq` rnfp px2 x2-                `seq` rnfp px3 x3-                `seq` rnfp px4 x4-                `seq` rnfp px5 x5-                `seq` rnfp px6 x6-                `seq` ()  -- needed?-        _ -> pat_match_fail-      pat_match_fail = patMatchFail' "(,,,,,)" pat chs d-    rnfp (Node pat chs) d = patMatchFail pat chs d--#if INCLUDE_SHOW_INSTANCES-  instance (Show a1, Typeable a1, NFDataP a1, Show a2, Typeable a2, NFDataP a2, Show a3, Typeable a3, NFDataP a3, Show a4, Typeable a4, NFDataP a4, Show a5, Typeable a5, NFDataP a5, Show a6, Typeable a6, NFDataP a6, Show a7, Typeable a7, NFDataP a7) =>-#else-  instance (Typeable a1, NFDataP a1, Typeable a2, NFDataP a2, Typeable a3, NFDataP a3, Typeable a4, NFDataP a4, Typeable a5, NFDataP a5, Typeable a6, NFDataP a6, Typeable a7, NFDataP a7) =>-#endif-         NFDataP (a1, a2, a3, a4, a5, a6, a7) where-    {-  NOINLINE rnfp #-}-    rnfp (Node WI _) _ = ()-    rnfp (Node pat chs) d-     | TR treps <- pat  = if elem td treps then recurs else ()-     | TI treps <- pat  = if elem td treps then () else recurs-     | otherwise        = rnfp' pat recurs d-     where-      td = show $ typeRepTyCon $ typeOf d-      recurs = case length chs of-        0 -> case pat of-              WS -> ()-              _ -> pat_match_fail-        7 -> let [px1,px2,px3,px4,px5,px6,px7] = chs ; (x1,x2,x3,x4,x5,x6,x7) = d-             in       rnfp px1 x1-                `seq` rnfp px2 x2-                `seq` rnfp px3 x3-                `seq` rnfp px4 x4-                `seq` rnfp px5 x5-                `seq` rnfp px6 x6-                `seq` rnfp px7 x7-                `seq` ()  -- needed?-        _ -> pat_match_fail-      pat_match_fail = patMatchFail' "(,,,,,,)" pat chs d-    rnfp (Node pat chs) d = patMatchFail pat chs d---- No Typeable instances for tuples larger than 7 in 7.8.1, seemingly.-#if 0-  instance (Show a1, Typeable a1, NFDataP a1, Show a2, Typeable a2, NFDataP a2, Show a3, Typeable a3, NFDataP a3, Show a4, Typeable a4, NFDataP a4, Show a5, Typeable a5, NFDataP a5, Show a6, Typeable a6, NFDataP a6, Show a7, Typeable a7, NFDataP a7, Show a8, Typeable a8, NFDataP a8) =>-         NFDataP (a1, a2, a3, a4, a5, a6, a7, a8) where-    rnfp Nil _ = ()-    rnfp (Node pat [px1,px2,px3,px4,px5,px6,px7,px8]) d@(x1,x2,x3,x4,x5,x6,x7,x8) = rnfp' pat recurs d-     where recurs =       rnfp px1 x1-                    `seq` rnfp px2 x2-                    `seq` rnfp px3 x3-                    `seq` rnfp px4 x4-                    `seq` rnfp px5 x5-                    `seq` rnfp px6 x6-                    `seq` rnfp px7 x7-                    `seq` rnfp px8 x8-    rnfp (Node pat chs) d = patMatchFail pat chs d--  instance (Show a1, Typeable a1, NFDataP a1, Show a2, Typeable a2, NFDataP a2, Show a3, Typeable a3, NFDataP a3, Show a4, Typeable a4, NFDataP a4, Show a5, Typeable a5, NFDataP a5, Show a6, Typeable a6, NFDataP a6, Show a7, Typeable a7, NFDataP a7, Show a8, Typeable a8, NFDataP a8, Show a9, Typeable a9, NFDataP a9) =>-         NFDataP (a1, a2, a3, a4, a5, a6, a7, a8, a9) where-    rnfp Nil _ = ()-    rnfp (Node pat [px1,px2,px3,px4,px5,px6,px7,px8,px9]) d@(x1,x2,x3,x4,x5,x6,x7,x8,x9) = rnfp' pat recurs d-     where recurs =       rnfp px1 x1-                    `seq` rnfp px2 x2-                    `seq` rnfp px3 x3-                    `seq` rnfp px4 x4-                    `seq` rnfp px5 x5-                    `seq` rnfp px6 x6-                    `seq` rnfp px7 x7-                    `seq` rnfp px8 x8-                    `seq` rnfp px9 x9-    rnfp (Node pat chs) d = patMatchFail pat chs d-#endif-----------------------------------------------------------------------------------  patMatchFail :: (Show a, Show b) => a -> b -> c -> ()-  patMatchFail pat chs d-#if WARN_PATTERN_MATCH_FAILURE-   = ( unsafePerformIO $! putStrLn $! "NFDataP: warning: couldn't match " ++ show pat ++ " (having children " ++ show chs ++ ")" ) `seq` ()-#else-   = ()-#endif--- = error $ "NFDataP: Couldn't match " ++ show pat ++ " (having children " ++ show chs ++ ")\nwith data " ++ show d--  patMatchFail' :: (Show a, Show b) => String -> a -> b -> c -> ()-  patMatchFail' inst pat chs d-#if WARN_PATTERN_MATCH_FAILURE-   = ( unsafePerformIO $! putStrLn $! "NFDataP: warning: instance " ++ inst ++ ": bad PatNode child list" ) `seq` patMatchFail pat chs d-#else-   = ()-#endif----------------------------------------------------------------------------------
src/Control/DeepSeq/Bounded/PatUtil.hs view
@@ -3,135 +3,1236 @@    {-  LANGUAGE CPP #-} ------------------------------------------------------------------------------------ |--- Module      :  Control.DeepSeq.Bounded.PatUtil--- Copyright   :  Andrew G. Seniuk 2014-2015--- License     :  BSD-style (see the file LICENSE)------ Maintainer  :  Andrew Seniuk <rasfar@gmail.com>--- Stability   :  provisional--- Portability :  portable--------------------------------------------------------------------------------------  module Control.DeepSeq.Bounded.PatUtil-  (--#if NEW_IMPROVED_PATTERN_GRAMMAR--     -- * Basic operations on Patterns--       unionPats-     , intersectPats-     , subPat---   , unionPatsStr--#if ! HASKELL98_FRAGMENT-     -- * Operations for obtaining and modifying Patterns based on a term--     , mkPat-     , mkPatN-     , growPat-#endif--     -- * Operations for obtaining subpatterns (in the 'subPat' sense)--     , truncatePat-     , shrinkPat-#if PROVIDE_OLD_SHRINK_PAT-     , shrinkPat_old-#endif--     -- * Operations for the direct construction and perturbation of Patterns--     , emptyPat-     , liftPats--     , splicePats-     , elidePats--     , erodePat--     -- * Re-exported for convenience--     , module Control.DeepSeq.Bounded.Pattern--     -- * Debugging convenience--#if ! HASKELL98_FRAGMENT-     , Shape-     , shapeOf-     , ghom-#endif-     , probDensRose-     , weightedRose-     , unzipRose-     , showRose--#else--     -- * Basic operations on Patterns--       unionPats-     , intersectPats-     , subPat---   , unionPatsStr--#if ! HASKELL98_FRAGMENT-     -- * Operations for obtaining and modifying Patterns based on a term--     , mkPat-     , mkPatN-     , growPat-#endif--     -- * Operations for obtaining subpatterns (in the 'subPat' sense)--     , truncatePat-     , shrinkPat-#if PROVIDE_OLD_SHRINK_PAT-     , shrinkPat_old-#endif--     -- * Operations for the direct construction and perturbation of Patterns--     , emptyPat-     , liftPats--     , splicePats-     , elidePats--     , erodePat--     -- * Re-exported for convenience--     , module Control.DeepSeq.Bounded.Pattern--#endif----- #if NEW_IMPROVED_PATTERN_GRAMMAR----      module Control.DeepSeq.Bounded.PatUtil_new_grammar  ,---- #else----      module Control.DeepSeq.Bounded.PatUtil_old_grammar  ,---- #endif--  )-  where-----------------------------------------------------------------------------------#if NEW_IMPROVED_PATTERN_GRAMMAR-  import Control.DeepSeq.Bounded.PatUtil_new_grammar-#else-  import Control.DeepSeq.Bounded.PatUtil_old_grammar-#endif--  -- Necessity seems like a Haddock bug, as it is both imported-  -- and exported by PatUtil_{old,new}_*.hs.-  import Control.DeepSeq.Bounded.Pattern+-- XXX This is not correct! Use elidePats if you want something+-- arity-changing.  The only time it would be valid for shrinkPat+-- to produce a (Node WR []) is from some attribute-enriched+-- (Node WR []) or (Node TR []).+#define SHRINK_TO_EMPTY_WR 0++-- As for intersection, if the arities differ, the node+-- effectively becomes non-recursive.  (Whether this is+-- theoretically the best choice is still uncertain.)+-- What is certain is, unless support richer Pattern's,+-- a union of two recursive Pattern nodes with differing+-- arities is not well-definable.+--   The reason this switch exists at all is, it can+-- be expensive to compute this predicate, especially+-- considering that recursive nodes are very common,+-- with WR being ("in the average case") the single most+-- abundant node type in a pattern, probably followed+-- in order by WI, WS, WW, WN (or parallel counterparts).+#define ENFORCE_SAME_ARITY_UNION 1++#define DO_TRACE 0++-- Now specified via --flag=[-]USE_WWW_DEEPSEQ+--- #define USE_WW_DEEPSEQ 1++-------------------------------------------------------------------------------++  -- XXX For debugging only!+  {-# LANGUAGE BangPatterns #-}++  {-# LANGUAGE Rank2Types #-}+  {-  LANGUAGE ScopedTypeVariables #-}++-------------------------------------------------------------------------------++-- |+-- Module      :  Control.DeepSeq.Bounded.PatUtil+-- Copyright   :  Andrew G. Seniuk 2014-2015+-- License     :  BSD-style (see the file LICENSE)+--+-- Maintainer  :  Andrew Seniuk <rasfar@gmail.com>+-- Stability   :  provisional+-- Portability :  portable+--++-------------------------------------------------------------------------------++  module Control.DeepSeq.Bounded.PatUtil+  (++     -- * Basic operations on Patterns++       unionPats+     , intersectPats+     , subPat+--   , unionPatsStr++#if ! HASKELL98_FRAGMENT+     -- * Operations for obtaining and modifying Patterns based on a term++     , mkPat+     , mkPatN+     , growPat+#endif++     -- * Operations for obtaining subpatterns (in the 'subPat' sense)++     , truncatePat+     , shrinkPat++     -- * Operations for the direct construction and perturbation of Patterns++     , emptyPat+     , liftPats++     , splicePats+     , elidePats++     , erodePat++     -- * Re-exported for convenience++     , module Control.DeepSeq.Bounded.Pattern++     -- * Debugging convenience++#if ! HASKELL98_FRAGMENT+     , Shape+     , shapeOf+     , ghom+#endif+     , probDensRose+     , weightedRose+     , unzipRose+     , showRose++  )+  where++-------------------------------------------------------------------------------++  import Control.DeepSeq.Bounded.Pattern++  import Data.Maybe ( isNothing, fromJust )+  import Data.Maybe ( isJust )++#if ! HASKELL98_FRAGMENT+  import Data.Data ( Data )+  import Data.Generics ( GenericQ )+  import Data.Generics ( gmapQ )+#endif++  import Data.List ( findIndex )+--import Data.List ( elemIndex )+  import Data.List ( sortBy )+--import Data.List ( nub )+  import Data.List ( foldl' )+  import Data.List ( group )+  import Data.List ( sort )+  import Data.List ( intersect )++  import System.Random++  import Control.Concurrent ( ThreadId )++--import Control.Applicative ( (<$) )++  import Debug.Trace ( trace )+  import Control.DeepSeq ( force )++  -- For global Bool state, to indicate that a warning has already been issued.+  import Data.IORef+  import System.IO.Unsafe ( unsafePerformIO )++-------------------------------------------------------------------------------++#if DO_TRACE+  mytrace = trace+#else+  mytrace _ = id+#endif++-------------------------------------------------------------------------------++  firstWarningPassed :: IORef Bool+  firstWarningPassed = unsafePerformIO $ newIORef False++-------------------------------------------------------------------------------++  -- | Compute the union of a list of 'Pattern's.+  --+  -- Note that unionPats is undefined when homologous nodes+  -- specify incompatible arities (only possible when+  -- 'WR' or 'TR' are involved).+  --+  -- /__XXX__ Support for the various attributes is work in progress. It may be impossible to arrive at a consistent treatment for all attributes under unions. At the last moment, 0.6.0.0 will __not__ be supporting type constraints under union, intersection or testing subpattern predicate. This is work in progress, but the five un-modified @W*@ node types should be safe./+  unionPats :: [ Pattern ] -> Pattern+  unionPats [] = emptyPat+  -- Using force here, to try to prevent the regular output being+  -- interleaved with the trace message. it works, except for the+  -- opening " (if you're in ghci, anyways).+  unionPats ps = foldr1 (union' False) $ force $ map (clearTypeConstraints "unionPats") ps+--unionPats ps = foldr1 (union' False) ps+--unionPats ps = foldr1 union' $ trace (">> " ++ show ps) $ ps++  union' :: Bool -> Pattern -> Pattern -> Pattern++  -- We hit this coming in every time [modulo compiler/runtime+  -- optimisations], so performance counts.+  union' b (Node pas1 cs1) (Node pas2 cs2)+   | WI{} <- pas1               = Node pas2' cs2+   |               WI{} <- pas2 = Node pas1' cs1+   where+    pas1' = setPatNodeAttrs pas1 union_as+    pas2' = setPatNodeAttrs pas2 union_as+    union_as = unionAttrs [as1,as2]+    (as1, as2) = (getPatNodeAttrs pas1, getPatNodeAttrs pas2)++  -- Symmetric cases:+  union' _ nod1@(Node pas1 cs1) nod2@(Node pas2 cs2)+   -- XXX Those cases using zipWith are not correct,+   -- unless length cs1 == length cs2.  But one hates to+   -- have to compute that. Caveat Emptor! This will behave+   -- as a true union operator only if the child pattern lists+   -- are compatibly-sized!+   --   In seqaid (and in "correct" manual usage?), this problem+   -- will never arise.+#if 0+   -- XXX Don't do it! -- (==) on PatNode might be more expensive+   -- than I think, some attributes have list parameters...+   | p1 == p2           = Node p1 $ zipWith (union' b) cs1 cs2+#endif+#if ENFORCE_SAME_ARITY_UNION+   | WR{} <- pas1, WR{} <- pas2 = {-trace "WRWR" $-}+      if csokay then Node (WR union_as) $ zipWith (union' False) cs1 cs2+      else error "unionPat: WRWR: encountered arity disparity!"+#else+   | WR{} <- pas1, WR{} <- pas2 = {-trace "WRWR" $-} Node (WR union_as) $ zipWith (union' False) cs1 cs2+#endif+   | WS{} <- pas1, WS{} <- pas2 = {-trace "WSWS" $-} Node (WS union_as) []+   | WN{} <- pas1, WN{} <- pas2 = {-trace "WNWN" $-} Node (WN union_as) []+#if USE_WW_DEEPSEQ+   | WW{} <- pas1, WW{} <- pas2 = {-trace "WWWW" $-} Node (WW union_as) []+#endif+#if 0+#if ENFORCE_SAME_ARITY_UNION+   | TR{} <- pas1, TR{} <- pas2 = {-trace "TRTR" $-}+      if csokay then Node (TR union_as) $ zipWith (union' False) cs1 cs2+      else error "unionPat: TRTR: encountered arity disparity!"+#else+   | TR{} <- pas1, TR{} <- pas2+      = {-trace "TRTR" $-} Node (TR union_as) $ zipWith (union' False) cs1 cs2+#endif+   | TI{} <- pas1, TI{} <- pas2+      = {-trace "TITI" $-} Node (TI union_as) []+---   = {-trace "TITI" $-} Node (TI union_as) $ zipWith (union' False) cs1 cs2+----  = {-trace "TITI" $-} Node (TI union_as (intersectTys tys1 tys2)) $ zipWith (union' False) cs1 cs2+--- | TR{} cls1 tys1 cns1 <- p1, TR{} cls2 tys2 cns2 <- p2+----  = {-trace "TRWR" $-} Node (TR union_as (cls1++cls2) (tys1++tys2) (cns1++cns2)) $ zipWith union' cs1 cs2+#endif+   | otherwise  = union'asym_1 False (Node pas1 cs1) (Node pas2 cs2)+   where+    pas1' = setPatNodeAttrs pas1 union_as+    pas2' = setPatNodeAttrs pas2 union_as+    union_as = unionAttrs [as1,as2]+    (as1, as2) = (getPatNodeAttrs pas1, getPatNodeAttrs pas2)+#if ENFORCE_SAME_ARITY_UNION+    csokay = equilength cs1 cs2+#endif++  -- Now the asymmetric cases:+  -- XXX This probably has numerous bugs and oversights!+   -- XXX Those cases using zipWith are not correct,+   -- unless length cs1 == length cs2.  But one hates to+   -- have to compute that. Caveat Emptor! This will behave+   -- as a true union operator only if the child pattern lists+   -- are compatibly-sized!+   --   Actually, if zipWith (which is acting on two [Pattern];+   -- you could supply union-unit pattern for missing children+   -- in shorter list, but then which children exactly were missing?+   -- So rather than play such a game without a racket, we just+   -- require the lists to be the same length or all bets are off.+   --   In seqaid, this problem will never arise.+   -- And in "correct" manual usage?...++#if USE_WW_DEEPSEQ+  union'asym_1 b nod1@(Node pas1 cs1) nod2@(Node pas2 cs2)+   | WW{} <- pas1+      =+--      trace (if b then "**WW" else "WW**") $+        Node (WW union_as) []+   | not b      = union'asym_1 True nod2 nod1+   | otherwise  = union'asym_2 False nod1 nod2+   where+    union_as = unionAttrs [as1,as2]+    (as1, as2) = (getPatNodeAttrs pas1, getPatNodeAttrs pas2)+#endif++  union'asym_2 b nod1@(Node pas1 cs1) nod2@(Node pas2 cs2)+   | WN{} <- pas1+      =+--      trace (if b then "**WN" else "WN**") $+        union'asym_2_aux dep+   | not b      = union'asym_2 True nod2 nod1+   | otherwise  = union'asym_3 False nod1 nod2+   where+    union'asym_2_aux 0 = Node (WI union_as) []+    union'asym_2_aux 1 = Node (WS union_as) []+    union'asym_2_aux _ = Node (WN union_as) []+    union_as = unionAttrs [as1,as2]+    (as1, as2) = (getPatNodeAttrs pas1, getPatNodeAttrs pas2)+    dep = depth as1++-- XXX XXX+-- I think it is not possible to reconcile, say, WR with TW.+-- TW says rnf if in type; WR says recurse regardless of type+-- according to the subpatterns.  Ah! But the union is, a priori,+-- only well-defined if the WR shape is "elected" from the wild+-- shape of TW, so in fact the correct answer is TR!  Very interesting!!!+-----+-- But what of WR with TN?...  If WR pattern depth (levels of tree)+-- is less than the n of TN, then answer is again TR.  But if n is+-- deeper than the WR pattern shape?... Perhaps only in SOME places...+--   You can still perhaps reconcile it, but now some fairly serious+-- pattern surgery is required! "We have the technology"....+-------+  -- We have now to deal only with asymmetric combos+  -- of WR, TR, WS, and TI nodes.  Six cases (plus six+  -- automatically when re-call with flip).+  --   Oops, there are still also TW and TN nodes...+-------------+  --        WR   WS   TI   TR   TN   TW+  --+  --   WR   Sym  WRWS WRTI WRTR WRTN WRTW+  --+  --   WS   flip Sym  WSTI WSTR WSTN WSTW+  --+  --   TI   flip flip Sym  TITR TITN TITW+  --+  --   TR   flip flip flip Sym  TRTN TRTW+  --+  --   TN   flip flip flip flip Sym  TNTW+  --+  --   TW   flip flip flip flip flip Sym +-----------------+  -- Fifteen cases to consider in all. Can they all be logically reconciled?...+------------------------+  -- WRWS : WR wins (not quite trivial however)+  -- ... if we just let T* be broken for 0.6.0.0, we're done there!+  -- By "broken" meaning, better give an error -- could just erase+  -- the type constraints silently, but what use is that?+  union'asym_3 b nod1@(Node pas1 cs1) nod2@(Node pas2 cs2)+   | WR{} <- pas1, WS{} <- pas2 = {-trace "WRWS" $-} nod1'+#if 0+#if ENFORCE_SAME_ARITY_UNION+   | TR{} <- pas1, WR{} <- pas2 = {-trace "TRWR" $-}+      if csokay then nod1'+      else error $ "unionPat: " ++ if b then "WRTR" else "TRWR" ++ ": encountered arity disparity!"+#else+   | TR{} <- pas1, WR{} <- pas2 = {-trace "TRWR" $-} nod1'+#endif+   | TR{} <- pas1, WS{} <- pas2 = {-trace "TRWS" $-} nod1'+   | TI{} <- pas1, WR{} <- pas2 = {-trace "TIWR" $-} nod2'+   | TI{} <- pas1, WS{} <- pas2 = {-trace "TIWS" $-} nod2'+#if USE_WW_DEEPSEQ+   | TW{} <- pas1, WR{} <- pas2 = {-trace "TWWR" $-} nod1'+   | TW{} <- pas1, WS{} <- pas2 = {-trace "TWWS" $-} nod1'+   | TW{} <- pas1, WW{} <- pas2 = {-trace "TWWW" $-} nod2'+#endif+   | TI{} <- pas1, TR{} <- pas2+      = {-trace "TITR" $-} Node (TR union_as) $ zipWith (union'asym_3 False) cs1 cs2+#endif+   | not b = union'asym_3 True nod2 nod1+   | otherwise = error "unionPats: unexpected failure to (Haskell) pattern-match arguments!"+   where+--  cs1' = map (const emptyPat) cs1+    nod1' = Node pas1' cs1+    pas1' = setPatNodeAttrs pas1 union_as+    union_as = unionAttrs [as1,as2]+    (as1, as2) = (getPatNodeAttrs pas1, getPatNodeAttrs pas2)+#if ENFORCE_SAME_ARITY_UNION+    csokay = equilength cs1 cs2+#endif++-------------------------------------------------------------------------------++  -- | Compute the intersection of a list of 'Pattern's.+  --+  -- Where two (or more) homologous 'WR' nodes disagree in arity,+  -- the intersection at that position becomes 'WI'.+  --+  -- /__XXX__ This doesn't yet handle type-constrained 'PatNode's ('TI', 'TR', 'TN' or 'TW'). Other attributes are handled in a haphazard fashion. This is work in progress, but the five un-modified @W*@ node types should be safe./++  intersectPats :: [ Pattern ] -> Pattern+  intersectPats [] = emptyPat+  intersectPats ps = foldr1 (intersect' False) $ force $ map (clearTypeConstraints "intersectPats") ps++  intersect' :: Bool -> Pattern -> Pattern -> Pattern++  -- We hit this coming in every time [modulo compiler/runtime+  -- optimisations], so performance counts.+  intersect' b (Node pas1 cs1) (Node pas2 cs2)+   | WI{} <- pas1               = Node (WI intersect_as) []+   |               WI{} <- pas2 = Node (WI intersect_as) []+   where+    intersect_as = intersectAttrs [as1,as2]+    (as1, as2) = (getPatNodeAttrs pas1, getPatNodeAttrs pas2)++  -- Symmetric cases:+  intersect' _ nod1@(Node pas1 cs1) nod2@(Node pas2 cs2)+#if ENFORCE_SAME_ARITY_UNION+   | WR{} <- pas1, WR{} <- pas2 = {-trace "WRWR" $-}+      if csokay then Node (WR intersect_as) $ zipWith (intersect' False) cs1 cs2+      else error "intersectPat: WRWR: encountered arity disparity!"+#else+   | WR{} <- pas1, WR{} <- pas2 = {-trace "WRWR" $-} Node (WR intersect_as) $ zipWith (intersect' False) cs1 cs2+#endif+   | WS{} <- pas1, WS{} <- pas2 = {-trace "WSWS" $-} Node (WS intersect_as) []+   | WN{} <- pas1, WN{} <- pas2 = {-trace "WNWN" $-} Node (WN intersect_as) []+#if USE_WW_DEEPSEQ+   | WW{} <- pas1, WW{} <- pas2 = {-trace "WWWW" $-} Node (WW intersect_as) []+#endif+   -- XXX T* nodes not handled!+   | otherwise  = intersect'asym_1 False (Node pas1 cs1) (Node pas2 cs2)+   where+    pas1' = setPatNodeAttrs pas1 intersect_as+    pas2' = setPatNodeAttrs pas2 intersect_as+    intersect_as = intersectAttrs [as1,as2]+    (as1, as2) = (getPatNodeAttrs pas1, getPatNodeAttrs pas2)+#if ENFORCE_SAME_ARITY_UNION+    csokay = equilength cs1 cs2+#endif++  -- Now the asymmetric cases:+#if USE_WW_DEEPSEQ+  intersect'asym_1 b nod1@(Node pas1 cs1) nod2@(Node pas2 cs2)+   | WW{} <- pas1+      =+--      trace (if b then "**WW" else "WW**") $+        Node pas2' cs2+   | not b      = intersect'asym_1 True nod2 nod1+   | otherwise  = intersect'asym_2 False nod1 nod2+   where+    pas2' = setPatNodeAttrs pas2 intersect_as+    intersect_as = intersectAttrs [as1,as2]+    (as1, as2) = (getPatNodeAttrs pas1, getPatNodeAttrs pas2)+#endif++  intersect'asym_2 b nod1@(Node pas1 cs1) nod2@(Node pas2 cs2)+   | WN{} <- pas1+      =+--      trace (if b then "**WN" else "WN**") $+        truncatePat dep (Node (setPatNodeAttrs pas2 intersect_as) cs2)+--      intersect'asym_2_aux dep+   | not b      = intersect'asym_2 True nod2 nod1+   | otherwise  = intersect'asym_3 False nod1 nod2+   where+#if 0+    intersect'asym_2_aux 0 = Node (WI intersect_as) []+    intersect'asym_2_aux 1 = Node (WS intersect_as) []+    intersect'asym_2_aux _ = Node (WN intersect_as) []+#endif+    intersect_as = intersectAttrs [as1,as2]+    (as1, as2) = (getPatNodeAttrs pas1, getPatNodeAttrs pas2)+    dep = depth as1++  intersect'asym_3 b nod1@(Node pas1 cs1) nod2@(Node pas2 cs2)+   | WR{} <- pas1, WS{} <- pas2 = {-trace "WRWS" $-} nod1'+   -- XXX T* nodes not handled!+   | not b = intersect'asym_3 True nod2 nod1+   | otherwise = error "intersectPats: unexpected failure to (Haskell) pattern-match arguments!"+   where+    cs1' = map (const emptyPat) cs1+    nod1' = Node (WR intersect_as) cs1'+    intersect_as = intersectAttrs [as1,as2]+    (as1, as2) = (getPatNodeAttrs pas1, getPatNodeAttrs pas2)+#if ENFORCE_SAME_ARITY_UNION+    csokay = equilength cs1 cs2+#endif++-------------------------------------------------------------------------------++  -- | Return 'True' if the first pattern matches the second (and 'False' otherwise).+  --+  -- Arities must correspond (or the second pattern's node must be wild) for the match to succeed at each __recursive__ 'PatNode' (/i.e./ 'WR' or 'TR').+  -- Matching does not imply spanning; @'flip' 'subPat'@ would work for that.+  --+  -- /__XXX__ This doesn't yet handle type-constrained 'PatNode's ('TI', 'TR', 'TN' or 'TW'), because 'intersectPats' doesn't. Generally speaking, it is difficult to arrive at a good policy for subpattern, union and intersection, when mixed types of nodes with various attribute values are considered!  Other attributes are handled in a haphazard fashion. This is work in progress, but the five un-modified @W*@ node types should be safe./+  --+  -- More formally, we have two \"Subpattern Axioms\":+  --+  -- * __Not More Specifc__ &#8195; A subpattern (of a pattern) is never more specific (/i.e./ less permissive), in terms of what values it will match.+  --+  -- * __Not More Forcing__ &#8195; A subpattern never has greater forcing potential.+  --+  -- And a /proper/ subpattern will always be strictly more permissive or+  -- less forcing (or both).+  subPat :: Pattern -> Pattern -> Bool+  subPat p pp = p == intersectPats [p, pp]  -- probably faster on avg.+--subPat p pp = pp == unionPats [p, pp]++-------------------------------------------------------------------------------++  -- I guess I don't really clear the typeConstraints list,+  -- only toggle doConstrainType to False.+  clearTypeConstraints :: String -> Pattern -> Pattern+  clearTypeConstraints s (Node pas cs)+   = Node pas' $ map (clearTypeConstraints s) cs+   where+    as = getPatNodeAttrs pas+    as' = if doConstrainType as+--        then error "unionPats: type constraints unsupported!"+--        then trace "unionPats: warning: type constraints unsupported (cleared!)" as+          then unsafePerformIO $ do+                 firstwarnpassed <- readIORef firstWarningPassed+                 modifyIORef' firstWarningPassed (const True)+                 if firstwarnpassed+                   then return as+                   else trace (s ++ ": warning: type constraints unsupported (cleared!)")+                        $! return as+          else as+    as'' = as' { doConstrainType = False }+    pas' = setPatNodeAttrs pas as''++-------------------------------------------------------------------------------++  -- XXX Note: Concerning the doSpark field, there is a deeper issue+  -- lurking here. Parallelisation and strictification are orthogonal+  -- concerns, so trying to treat them uniformly can be awkward...++  unionAttrs :: [PatNodeAttrs] -> PatNodeAttrs+  unionAttrs [] = error "unionAttrs: called with empty list.\nPlease determine which library has called this function erroneously,\nand file a bug report or contact the maintainer of that project."+  unionAttrs as = foldl1 unionAttrs' as+  unionAttrs' :: PatNodeAttrs -> PatNodeAttrs -> PatNodeAttrs+  unionAttrs'+    (PatNodeAttrs+      uniq1+      dep1+      dotys1+      tys1+      dly1 dlyus1+#if USE_PAR_PATNODE+      spk1+#endif+#if USE_PSEQ_PATNODE+      pseq1 pseqperm1+#endif+#if USE_TRACE_PATNODE+      tr1+#endif+#if USE_PING_PATNODE+      ping1 pingtid1+#endif+#if USE_DIE_PATNODE+      die1+#endif+#if USE_TIMING_PATNODE+      timing1 ts1 parent_ts1 delta_ts1+#endif+    )+    (PatNodeAttrs+      uniq2+      dep2+      dotys2+      tys2+      dly2 dlyus2+#if USE_PAR_PATNODE+      spk2+#endif+#if USE_PSEQ_PATNODE+      pseq2 pseqperm2+#endif+#if USE_TRACE_PATNODE+      tr2+#endif+#if USE_PING_PATNODE+      ping2 pingtid2+#endif+#if USE_DIE_PATNODE+      die2+#endif+#if USE_TIMING_PATNODE+      timing2 ts2 parent_ts2 delta_ts2+#endif+    )+     = PatNodeAttrs+         (combineUniqueIDs uniq1 uniq2)+         (max dep1 dep2)+         (dotys1||dotys2)  -- SAME as intersection [?]+         (unionTys tys1 tys2)+         (dly1||dly2)  -- SAME as intersection [?]+         (combineDelays True dly1 dly2 dlyus1 dlyus2)  -- DIFFERENT for union and intersection [?]+#if USE_PAR_PATNODE+         (spk1||spk2)  -- seems the best choice for parallelism union semantics+#endif+#if USE_PSEQ_PATNODE+         (pseq1&&pseq2)  -- DIFFERENT for union and intersection [??]+         (combinePseqPerms pseqperm1 pseqperm2)  -- XXX SAME as intersection...+#endif+#if USE_TRACE_PATNODE+         (combineTraces tr1 tr2)  -- same for union and intersection+#endif+#if USE_PING_PATNODE+         (combinePings ping1 ping2)  -- same for union and intersection+         (combinePingParentTIDs pingtid1 pingtid2)  -- same for union and intersection+#endif+#if USE_DIE_PATNODE+         (die1||die2)  -- same for union and intersection+#endif+#if USE_TIMING_PATNODE+         -- same for union and intersection [?]+         -- XXX This is bogus, so it would be nice if it would issue a warning.+         -- We'd want to issue the warning only once per run, I think...+         (False) (0) (0) (0)+#endif++  intersectAttrs :: [PatNodeAttrs] -> PatNodeAttrs+  intersectAttrs [] = error "intersectAttrs: called with empty list.\nPlease determine which library has called this function erroneously,\nand file a bug report or contact the maintainer of that project."+  intersectAttrs as = foldr1 intersectAttrs' as+  intersectAttrs' :: PatNodeAttrs -> PatNodeAttrs -> PatNodeAttrs+  intersectAttrs'+    (PatNodeAttrs+      uniq1+      dep1+      dotys1+      tys1+      dly1 dlyus1+#if USE_PAR_PATNODE+      spk1+#endif+#if USE_PSEQ_PATNODE+      pseq1 pseqperm1+#endif+#if USE_TRACE_PATNODE+      tr1+#endif+#if USE_PING_PATNODE+      ping1 pingtid1+#endif+#if USE_DIE_PATNODE+      die1+#endif+#if USE_TIMING_PATNODE+      timing1 ts1 parent_ts1 delta_ts1+#endif+    )+    (PatNodeAttrs+      uniq2+      dep2+      dotys2+      tys2+      dly2 dlyus2+#if USE_PAR_PATNODE+      spk2+#endif+#if USE_PSEQ_PATNODE+      pseq2 pseqperm2+#endif+#if USE_TRACE_PATNODE+      tr2+#endif+#if USE_PING_PATNODE+      ping2 pingtid2+#endif+#if USE_DIE_PATNODE+      die2+#endif+#if USE_TIMING_PATNODE+      timing2 ts2 parent_ts2 delta_ts2+#endif+    )+     = PatNodeAttrs+         (combineUniqueIDs uniq1 uniq2)+         (min dep1 dep2)+         (dotys1||dotys2)  -- SAME as union [?]+         (intersectTys tys1 tys2)+         (dly1||dly2)  -- SAME as union [?]+         (combineDelays False dly1 dly2 dlyus1 dlyus2)  -- DIFFERENT for union and intersection [?]+#if USE_PAR_PATNODE+         (spk1||spk2)  -- seems the better choice+--       (spk1&&spk2)  -- dubious parallelism intersection semantics+#endif+#if USE_PSEQ_PATNODE+         (pseq1||pseq2)  -- DIFFERENT for union and intersection [??]+         (combinePseqPerms pseqperm1 pseqperm2)  -- XXX SAME as union...+#endif+#if USE_TRACE_PATNODE+         (combineTraces tr1 tr2)  -- same for union and intersection+#endif+#if USE_PING_PATNODE+         (combinePings ping1 ping2)  -- same for union and intersection+         (combinePingParentTIDs pingtid1 pingtid2)  -- same for union and intersection+#endif+#if USE_DIE_PATNODE+         (die1||die2)  -- same for union and intersection+#endif+#if USE_TIMING_PATNODE+         -- same for union and intersection [?]+         -- XXX This is bogus, so it would be nice if it would issue a warning.+         -- We'd want to issue the warning only once per run, I think...+         (False) (0) (0) (0)+#endif++-------------------------------------------------------------------------------++  -- The idea here is that, PatNodeAttrs only carries a Bool for each+  -- of combineTraces and combinePings, and the actual content of the+  -- log string or Exception message is a matter to be determined in+  -- the context that the logging/exception is triggered (demanded).++#if USE_TRACE_PATNODE+  combineTraces :: Bool -> Bool -> Bool+  combineTraces = (||)  -- for now, at least+#endif++#if USE_PSEQ_PATNODE+  combinePseqPerms :: Maybe [Int] -> Maybe [Int] -> Maybe [Int]+  combinePseqPerms mpsp1 mpsp2+   | isNothing mpsp1  = mpsp2+   | isNothing mpsp2  = mpsp1+   | mpsp1 == mpsp2   = mpsp1+   | otherwise        = trace "WARNING: combinePseqPerms: Incompatible permutations discarded (using id)." Nothing+#endif++#if USE_PING_PATNODE+  combinePingParentTIDs :: Maybe ThreadId -> Maybe ThreadId -> Maybe ThreadId+  combinePingParentTIDs mt1 mt2+   = if isNothing mt1 && isNothing mt2+     then Nothing+     else if isJust mt1 && isJust mt2 && t1 == t2+          then Just t1+#if 1+          else+#if 1+               trace+                 (    "combinePings: TID's differ: "+                   ++ show mt1 ++ " " ++ show mt2+                   ++ "\nCombining by choosing " ++ show mt1 ++ "!" )+#endif+                 mt1+#else+          -- XXX This shouldn't be "error"!+          else error $    "combinePings: TID's differ: "+                       ++ show mt1 ++ " " ++ show mt2+#endif+--        else Nothing+   where (t1,t2) = (fromJust mt1,fromJust mt2)++  combinePings :: Bool -> Bool -> Bool+  combinePings = (||)  -- for now, at least+#endif++  combineUniqueIDs :: Int -> Int -> Int+  combineUniqueIDs u1 u2+   | u1 == u2   = u1+   | otherwise  =+#if 0+-- Seeing as this will happen 99% of the time, it's a bit much+-- to issue a warning to console!+                  trace+                    ( "combineUniqueIDs: uniqueID's differ: "+                       ++ show u1 ++ " " ++ show u2 )+#endif+                    0++  -- Rather dubious.+  combineDelays :: Bool -> Bool -> Bool -> Int -> Int -> Int+  combineDelays from_union dly1 dly2 dlyus1 dlyus2+   | not dly1 && not dly2  = 0+   | not dly1              = dlyus2+   | not dly2              = dlyus1+   | from_union            = min dlyus1 dlyus2+   | otherwise             = max dlyus1 dlyus2++-------------------------------------------------------------------------------++  -- Probably overkill for typical lengths.+  -- Would pay to special case for some short lists.+  -- Optimisations come later.++  unionTys :: [String] -> [String] -> [String]+  unionTys ss1 ss2 = nubsort $ ss1 ++ ss2++  nubsort :: Ord a => [a] -> [a]+  nubsort = map head . group . sort++  intersectTys :: [String] -> [String] -> [String]+  intersectTys ss1 ss2 = intersect (nubsort ss1) (nubsort ss2)++-------------------------------------------------------------------------------++#if ENFORCE_SAME_ARITY_UNION+  -- Try to determine whether then lengths of the lists are+  -- the same or not without being too inefficient...+  {-# INLINE equilength #-}+  equilength :: [a] -> [b] -> Bool+#if 0+-- XXX But ... I feel like best practise is to use "length cs1 == length cs2",+-- since who knows, the compiler could optimise it into some sort of quasi-+-- list internal structure with O(1) length function.  That is not too+-- far fetched at all.  (Complexities as reported in the standard libraries+-- need not be strictly observed -- actual evaluations may exhibit lower+-- complexity without violating any specification...)  And if this happens,+-- then we've blocked the optimisation, so we get a 0.5*O(n) average case+-- algorithm instead of an O(n), but missed out on O(1)...+--   The only really safe way is to implement using your choice of+-- container with O(1) length.  Or of course, you could attempt to+-- maintain the length as associated data (extra field)...+  equilength (x:xs) (y:ys) = equilength xs ys+  equilength [] [] = True+  equilength _ _ = False+#else+  equilength cs1 cs2 = length cs1 == length cs2  -- ouch(?)+#endif+#endif++  zipWith_ :: String -> (a -> b -> c) -> [a] -> [b] -> (Bool,[c])+  zipWith_ caller f xs ys+   | b          = (b,zs)+   | otherwise  = trace (caller ++ ": node arity disparity!") (b,zs)+   where+    (b,zs') = zipWith_' f xs ys []+    zs = reverse zs'+  zipWith_' :: (a -> b -> c) -> [a] -> [b] -> [c] -> (Bool,[c])+  zipWith_' f (x:xs) (y:ys) acc = zipWith_' f xs ys (f x y : acc)+  zipWith_' _ [] [] acc = (True,acc)+  zipWith_' _ _ _ acc = (False,acc)++-------------------------------------------------------------------------------++  -- | Given an integer depth and a pattern, truncate the pattern to+  -- extend to at most this requested depth.+  --+  -- Nodes in the truncated pattern which were 'WR' and are now leaves,+  -- are changed to 'WI'.+  -- (This is a change from 0.5, where they were+  -- changed to 'WS', which violates the Subpattern Axiom concerning+  -- forcing potential.+  -- It may be further changed to 'WR'-bearing-'WI'-children+  -- in 0.7, which preserves arity info, as is consistent with the new+  -- treatment of 'mkPatN' in 0.6.)+  --+  -- /__XXX__ Note that @*N@ and @*W@ nodes are retained, so if you are using those then \"extend to at most this depth\" does not mean the forcing potential of the pattern is at most that depth...  It would be quite possible to improve this, so @*N@ (and @*W@ nodes, obviously) are \"weakened\" (depth is reduced) so that they end at the truncation depth, regardless of how far up they reside.  In particular, any @*N@ or @*W@ node at truncation depth could be replaced by @WS@.  This works well as all these node types are arity-agnostic./+  truncatePat :: Int -> Pattern -> Pattern+  truncatePat n node@(Node pas chs)+   | n <= 0     = Node (WS $ getPatNodeAttrs pas) []+   | otherwise  = Node pas $ map (truncatePat (-1+n)) chs++-------------------------------------------------------------------------------++  -- | There is no @Nil@ in the @Pattern@ type, but a single 'WI' node as+  -- empty pattern is a dependable way to ensure that the empty pattern+  -- never forces anything. This sets 'PatNodeAttrs' to 'emptyPatNodeAttrs'.+  emptyPat :: Pattern+  emptyPat = Node (WI emptyPatNodeAttrs) []  -- this should do it!++-------------------------------------------------------------------------------++#if ! HASKELL98_FRAGMENT+  -- | Obtain a lazy, potentially infinite pattern, matching the shape+  -- of an arbitrary term (value expression).+  --+  -- There is only one kind of 'PatNode' employed here, 'WR'.+  -- (__Note__:+  -- /This is an API breaking change from 0.5, where 'WS' also occurred./)+  --+  -- The 'Pattern' is extended indefinitely on demand.  In case the+  -- term has leaves, these will be 'WR' nodes with empty child lists+  -- in the corresponding pattern.+  --+  -- __Caveat__: Note that @mkPat@ gives counter-intuitive results when used+  -- on rose trees, in particular on 'Pattern' itself.+  -- For example, a rose tree with a single node will have a 3-node /\\ shape.)+  -- Formally, 'mkPat' is not idempotent on 'Pattern's, but rather grows+  -- without bound when iterated. This shouldn't be an issue in practise.+  mkPat :: forall d. Data d => d -> Pattern+  mkPat = f . shapeOf+   where+    f (Node _ cs) = Node pn $ map f cs+     where+      pn = WR emptyPatNodeAttrs+---   pn = let as = emptyPatNodeAttrs in if null cs then WS as else WR as++  -- | Obtain a lazy, finite pattern, matching the shape of+  -- an arbitrary term, but only down to at most depth @n@.+  --+  -- Satisfies @'forcep' . 'mkPatN' n = 'forcen' n@. /(Later: I kinda doubt that is true in full generality?... Although it does convey the idea.)/+  --+  -- Unlike 'mkPat', three pattern node contexts arise here:+  --+  -- * those corresponding to actual leaf (nullary) nodes of the term+  --+  --     * these are &#8195; @Node WR []@+  --+  -- * interior nodes of the pattern corresponding to interior nodes of the term+  --+  --     * these are &#8195; @Node WR chs@ &#8195; where @chs@ are the child subpatterns of this interior pattern node+  --+  -- * leaf nodes of the pattern corresponding to interior nodes of the term, that is, non-leaf nodes of the term which are at a depth @n@ of nested constructor applications.+  --+  --     * these are &#8195; @Node WR chs'@ &#8195; where &#8195; @chs' = map (const $ Node WI []) chs@+  --     * this essentially says we're allowed to know the arity of the node, but aside from this cardinal number we know nothing whatsoever concerning the child subpatterns and are not even permitted to evaluate their heads+  --+  -- All interior nodes are 'WR', and all leaf nodes are 'WI'; 'WS' never arise (which is a change from version 0.5).+  --+  -- See caveat in the 'mkPat' documentation.+  mkPatN :: forall d. Data d => Int -> d -> Pattern+  mkPatN n = f n . shapeOf+   where+    f n (Node _ cs)+     | 0 == n     = if null cs+                    then Node pn []+                    else Node pn $ map (const emptyPat) cs+     | otherwise  = Node pn $ map (f (-1+n)) cs+     where+      pn = WR emptyPatNodeAttrs+#endif++-------------------------------------------------------------------------------++  -- | Elide all leaves which have no non-leaf sibling.+  -- We want the pattern to still match the same value, only less of it.+  -- Merely eliding all leaves would, in most cases, cause match failure,+  -- so we have to be a bit more subtle.  There are some arbitrary+  -- decisions about the relaxation route through the lattice.+  -- (Refer to the source for details.)+  --+  -- More formally, we have some \"Shrinkage Axioms\".  The first+  -- two are really just the \"Subpattern Axioms\" again, that is,+  -- shrinkage is always to a subpattern in our sense of the+  -- word (see also 'subPat'):+  --+  -- * __Not More Specifc__ &#8195; Shrinkage is never towards a more specific (/i.e./ less permissive) pattern.+  --+  -- * __Not More Forcing__ &#8195; Shrinkage is never towards a pattern with greater forcing potential.+  --+  -- And additionally, for finite patterns only:+  --+  -- * __Non-Constancy__ &#8195; A finite pattern is constant under shrinkage /iff/ the pattern is trivial (emptyPat, \".\", Node WI []). However, infinite patterns have other limits.  For instance, the infinite pattern @'concat' $ 'repeat' "(."@ (yes you can do that!) is already stationary under shrinkage.+  --+  -- * __Convergence__ &#8195; On iteration, shrinkage of finite patterns reaches the trivial pattern in a number of steps proportional to the size of the initial pattern argument.  (Actually, @*N@ and @*W@ nodes can make this larger.)  However, in the case of infinite patterns, all bets are off: Simple examples exist which converge immediately, or which continue shrinking indefinitely.)+{--}+  -- XXX This has a bug -- it introduces WR []'s when the original+  -- node arity was not zero! The progression should be (in the+  -- newest syntax) something like:+  --   (.(!.))+  --   (.(..))+  --   (.!)+  --   (..)+  --   !+  --   .+  shrinkPat :: Pattern -> Pattern+  shrinkPat (Node pas cs)+#if USE_PAR_PATNODE+   -- take de-parallelisation as shrinkage+   -- XXX So should we take pseq-isation as further shrinkage?+   | doSpark as  = let as' = as { doSpark = False } in+                   case pas of+                    WI{} -> Node (WI as') []+                    WS{} -> Node (WI as') []+                    WR{} -> Node (WR as') cs+                    WN{} -> Node (WN as') []+#if USE_WW_DEEPSEQ+                    WW{} -> Node (WW as') []+#endif+#endif+   | WI{} <- pas  = Node (WI as) []  -- can't shrink (evt'ly elided from parent)+   | WS{} <- pas  = Node (WI as) []  -- may as well+   | WN{} <- pas+      = let n = depth as+            n' = -1+n+        in if n' <= 0 then Node (WI as) []+           else if n' == 1 then Node (WS as) []+           else let as' = as { depth = n' } in Node (WN as') []+#if USE_WW_DEEPSEQ+   | WW{} <- pas  = Node (WN as { depth = 5 }) []  -- XXX arbitrary hardcode+#endif+   -- take un-type-constrained as shrinkage (pattern becomes less specific)+   -- XXX Later: This is wrong. It is less specific, but it HAS MORE FORCING+   -- POTENTIAL (except in TI case).+   | TI{} <- pas  = Node (WI as) []+   | TR{} <- pas  = Node (WR as) cs+   | TN{} <- pas  = Node (WN as) []+#if USE_WW_DEEPSEQ+   | TW{} <- pas  = Node (WW as) []+#endif+#if SHRINK_TO_EMPTY_WR+   | WR{} <- pas , null cs  = Node (WI as) []+#endif+   -- If this node has any grandchildren, recurse on the children.+   | not $ null $ filter (\ (Node q gcs) -> not $ null gcs) cs+      = Node pas $ map shrinkPat cs+   -- At this point we know this node has no grandchildren.+   -- Check if all children are insulator nodes.+   | null $ filter (\ (Node pas _) -> case pas of { WI{} -> False ; _ -> True }) cs+      = case pas of+         -- Must go to WI, since .{##} -> . is /not/ a lazification.+         -- Later: Yes it is, isn't it?? Dot is a less constrained pattern...+#if SHRINK_TO_EMPTY_WR+         WR{} -> Node (WR as) []+#else+         WR{} -> Node (WI as) []+#endif+         -- We cannot make this simple TR -> WR (drop type constraints),+         -- since, while less specific, it forces more, violating the+         -- "second axiom of shrinkage".+         TR{} -> let as' = as { typeConstraints = [] } in Node (WI as') []  -- better?+--       TR{} -> Node (WI as) []  -- sic+         _ -> error "shrinkPat: unexpected!"+   | otherwise+      = Node pas $ map shrinkPat cs  -- still contains shrinkable children+   where+    as = getPatNodeAttrs pas++-------------------------------------------------------------------------------++#if ! HASKELL98_FRAGMENT+  -- | Grow all leaves by one level within the shape of the provided value.+  -- This is intended to be used with \"plain\" patterns, /i.e./ those+  -- containing only 'WR' and 'WI' nodes. (There is no code enforcing this.)+  -- A new growth node always replaces a 'WI' (leaf) node with a 'WR' node+  -- bearing the suitable number of 'WI' children to encode arity (see+  -- 'mkPat' for general commentary about this).+  growPat :: forall d. Data d => Pattern -> d -> Pattern+  growPat pat x = growPat' pat $ shapeOf x+  growPat' :: Pattern -> Shape -> Pattern+  growPat' (Node pas cs) (Node q ds)+   | null cs    = let subleaf = Node (WI $ getPatNodeAttrs pas) []+                      pas' = WR $ getPatNodeAttrs pas+                  in Node pas' $ map (const subleaf) ds+   | otherwise  = Node pas $ zipWith growPat' cs ds+#endif++-------------------------------------------------------------------------------++  -- | This creates a new 'WR' node, the common root, with 'PatNodeAttrs' set+  -- to 'emptyPatNodeAttrs'.  The argument patterns become the children of+  -- the root (order is preserved).+  liftPats :: [ Pattern ] -> Pattern+  liftPats ps = Node (WR emptyPatNodeAttrs) ps++-------------------------------------------------------------------------------++  -- | Add children to a node (interior or leaf) of the target.+  -- The first argument is target pattern, the second is a path (0-based+  -- indexing) from the root of the target to any choice node,+  -- and the third is a list of subpatterns for insertion, along with the+  -- indices of the insertion slots.+  -- Indices range through @-1,0..n@, where @n@ is the number of+  -- existing children, and @-1@ is short for @n@ (so you don't need+  -- to count off the children to append!).+  -- Indices are always relative to the original target as it was received.+  splicePats :: Pattern -> [Int] -> [ (Int, Pattern) ] -> Pattern+  splicePats target path isibs'+--- | isibs /= isibs'    = error "splicePats: siblings to be inserted must be indexed in increasing order"+--- | not uniqueIdxs     = error "splicePats: siblings to be inserted must be uniquely indexed"+--- | not $ isPath path  = error "splicePats: path malformed"+   | otherwise          = splice' target path isibs+   where+--  uniqueIdxs = length isibs == ( length $ nub $ map fst isibs )+    isibs = sortBy comp isibs'  -- questionable solution+     where+      comp (x1,_) (x2,_) = compare x1 x2+    -- Now, what's the clever way to do this? it's ugly manual+    -- recursion if don't think of something nicer. (This is+    -- the ugly manual recursion!)+    splice' :: Pattern -> [Int] -> [(Int,Pattern)] -> Pattern+    splice' (Node pas cs) [] isibs  -- end of path chain+     | maximum (map fst isibs) > ncs  = error "splicePats: insertion indices (0-based) must be\nno greater than the number of children"+     | or $ map ( (<(-1)) . fst ) isibs  = error "splicePats: insertion indices must be non-negative, or -1"+---  | or $ map ( (<0) . fst ) isibs  = error "splicePats: insertion indices must be non-negative"+     | not ( isWR pas || isTR pas )  = error $ "splicePats: path ends in non-recursive node type " ++ show pas+     | otherwise  = {-trace "**1**" $-} Node pas $ f 0 cs isibs_+     where+      ncs = length cs+      -- XXX I'm trying to remember why had isibs of -1 as special.+      -- (They're now filtered upstream of here in any case.)+      isibs_ = let lst = takeWhile ((== -1) . fst) isibs in+               drop (length lst) isibs ++ map (\ (x,y) -> (ncs,y)) lst+      f n cs [] = cs+      f n [] isibs_remaining = map snd isibs_remaining+--    f n [] isibs_remaining = error $ "splicePats: (2) path escapes target: " ++ show isibs_remaining  -- shouldn't happen+      f n lst1@(c:cs) lst2@((i,s):iss)+---    | trace ("**3**"++show lst1++" "++show lst2) False  = undefined+       | ii == n    = map snd ss ++ (c : f (1+n) cs ss')+       | otherwise  =                c : f (1+n) cs lst2+       where (ss,ss') = span (\ (i,s) -> i == n) lst2+             ii = i+--           ii = if i < 0 then ncs-(-i) else i+    splice' (Node pas cs) (i:is) isibs+---  | trace ("**4** "++show i++" / "++show cs++" / "++show pathcs) False  = undefined+     | null cs  = error "splicePats: path escapes target (depth)"+     | length cs < 1+i  = error "splicePats: path escapes target (breadth)"+     | null ccsR  = error "splicePats: (2) path escapes target (depth)"+-- Shouldn't be possible?+---  | not ( isWR pas || isTR pas )  = error $ "splicePats: path contains non-recursive node type " ++ show pas+     | otherwise  = {-trace "**2**" $-} Node pas (csL ++ [splice' c is isibs] ++ csR)+     where+      (c:csR) = ccsR+      (csL,ccsR) = splitAt i cs++-------------------------------------------------------------------------------++  -- | Elide children of a node (interior or leaf) of the target.+  -- The first argument is target pattern, the second is a path (0-based+  -- indexing) from the root of the target to any choice node,+  -- and the third is a list of child indices for elision.+  -- Indices range through @-1,0..n-1@, where @n@ is the number of+  -- existing children, and @-1@ is short for @n-1@ (so you don't need+  -- to count off the children to elide the rightmost).+  -- Indices are always relative to the original target as it was received.+  elidePats :: Pattern -> [Int] -> [Int] -> Pattern+  elidePats target path isibs' = elide' target path isibs+   where+    isibs = sortBy comp isibs'  -- questionable solution+     where comp x1 x2 = compare x1 x2+    -- (See comment in splicePats.)+    elide' :: Pattern -> [Int] -> [Int] -> Pattern+    elide' (Node pas cs) [] isibs  -- end of path chain+     | maximum isibs >= ncs  = error "elidePats: elision indices (0-based) must be\nless than the number of children"+     | or $ map (<(-1)) isibs  = error "elidePats: elision indices must be non-negative or -1"+---  | or $ map (<0) isibs  = error "elidePats: elision indices must be non-negative"+     | otherwise  = {-trace "**1**" $-} Node pas $ f 0 cs isibs_+     where+      ncs = length cs+      -- XXX I'm trying to remember why had isibs of -1 as special.+      -- (They're now filtered upstream of here in any case.)+      isibs_ = let lst = takeWhile (== -1) isibs in+               drop (length lst) isibs ++ map (\ x -> (-1+ncs)) lst+      f n cs [] = cs+      f n [] isibs_remaining = error $ "elidePats: (3) path escapes target: " ++ show isibs_remaining  -- shouldn't happen+      f n lst1@(c:cs) lst2@(i:iss)+---    | trace ("**3**"++show lst1++" "++show lst2) False  = undefined+       | ii == n    =     f (1+n) cs ss'+       | otherwise  = c : f (1+n) cs lst2+       where (ss,ss') = span (\ i -> i == n) lst2+             ii = i+--           ii = if i < 0 then ncs-(-i) else i+    elide' (Node pas cs) (i:is) isibs+---  | trace ("**4** "++show i++" / "++show cs++" / "++show pathcs) False  = undefined+     | null cs  = error "elidePats: path escapes target (depth)"+     | length cs < 1+i  = error "elidePats: path escapes target (breadth)"+     | null ccsR  = error "elidePats: (2) path escapes target (depth)"+     | otherwise  = {-trace "**2**" $-} Node pas (csL ++ [elide' c is isibs] ++ csR)+     where+      (c:csR) = ccsR+      (csL,ccsR) = splitAt i cs++-------------------------------------------------------------------------------++  -- | Select a leaf at random, and elide it.+  -- In order to achieve fairness, the node probabilities are+  -- weighted by nodes in branch.+  -- The path arg can "focus" the stochastic erosion to only+  -- consider leaves beneath a given node.+{--}+-- XXX Later: I don't understand. When would you want to+-- allow the number of children at a node to change (except+-- possibly to zero)?... Question applies also to splicePats+-- and to elidePats.+-- XXX It would be better if the weighting could be done once,+-- then maintained, but will have to see how it performs...+-- XXX Hey! This doesn't even need to call elidePats.+-- XXX Later: It would be nice if this could call shrinkPat+-- (or equivalent) on the leaves finally selected, so they+-- decrease forcing at finer granularity, eg. *3 -> *2 (not *3 -> #+-- or rather outright elided ... this is a different process though;+-- need to decide whether you want to let that arity change or not...)+  erodePat :: StdGen -> [Int] -> Pattern -> (Pattern, StdGen)+  -- Just descend the path, reconstructing recursively (usual thing),+  -- and when get to the node addressed by path, then choose (fair) your+  -- leaf under that.+  erodePat g (h:t) (Node pas chs)+   = ( Node pas $ left ++ [ ch'' ] ++ right , g' )+   where+    ch'' = ch'+--  ch'' = (\ (Node (r,pas) chs) -> Node r chs) ch'+    (ch',g') = erodePat g t lucky+    (left,lucky:right) = splitAt h chs+  erodePat g [] pat = (pat', g')+--erodePat g [] pat = trace (showRose wpat ++ "\n" ++ showRose (weightedRose pat)) $ (pat', g')+   where+    pat' = fst $ unzipRose wpat'+    !_ = probDensRose pat+--  !_ = force $ probDensRose pat+    (wpat', g') = f g wpat+--  !wpat@(Node pas chs) = probDensRose pat+    wpat@(Node pas chs) = probDensRose pat+    f :: StdGen -> Rose (PatNode,Double) -> (Rose (PatNode,Double), StdGen)+    f g (Node pas chs)+     | isNothing mh  = ( Node pas chs, g )  -- ??+     | null chs   = ( Node pas [], g )+---  | null chs   = ( Node pas [], g'' )+     | null gchs  = ( Node pas $ left ++ [ Node (WI emptyPatNodeAttrs,1.0) [] ] ++ right , g'' )+---  | null gchs  = ( Node pas $ left ++ right , g'' )+     | otherwise  = ( Node pas $ left ++ [ ch' ] ++ right , g'' )+     where+-- XXX I see; I have a logic error.+-- Cyclical definition.+-- null gchs+-- but gchs depends on lucky+-- and lucky depends on ... [?]+      (Node _ gchs) = lucky+      (ch',g'') = f g' lucky+      chprobs = map (\ (Node (_,pas) _) -> pas) chs+      mh = lucky_child 0 0.0 chprobs+#if 1+      h = fromJust mh+#else+      h | isNothing mh  = error "UNEXPECTED!"  -- definitely get here+        | otherwise     = fromJust mh+#endif+      (left,lucky:right) = splitAt h chs+--    !_ = trace ("r=" ++ show r) $ ()+--    (r,g') = trace "HERE!" $ randomR (0,1) g+      (r,g') = randomR (0,1) g+      lucky_child :: Int -> Double -> [Double] -> Maybe Int+      lucky_child idx acc [] = Nothing+      lucky_child idx acc (cp:cps)+---    | trace (" >>> " ++ show acc ++ "  " ++ show acc') $ False = undefined+       | acc' >= r   = Just idx+       | otherwise  = lucky_child (1+idx) acc' cps+       where+        acc' = acc + cp++-------------------------------------------------------------------------------++  -- See the sai-shape-syb package for an API full of this sort of thing.++#if ! HASKELL98_FRAGMENT+  type Shape = Rose ()+  shapeOf :: forall d. Data d => d -> Shape+  shapeOf = ghom $ const ()+  ghom :: forall r d. Data d => GenericQ r -> d -> Rose r+  ghom f x = foldl k b (gmapQ (ghom f) x)+   where+     b = Node (f x) []+     k (Node r chs) nod = Node r (chs++[nod])+#endif++  probDensRose :: Rose r -> Rose (r, Double)+  probDensRose = probDensRose' 1.0 . weightedRose+  probDensRose' :: Double -> Rose (r, Int) -> Rose (r, Double)+--probDensRose' p (Node (r,w) []) = Node (r,p) []  -- (helps avoid div-by-zero)+  probDensRose' p (Node (r,w) chs)+   = Node (r,p) $ zipWith probDensRose' chprobs chs+   where+    chwts   = map (\ (Node (_,w) _) -> w) chs+    chwtsum = foldl' (+) 0 chwts+    normfac = 1 / fromIntegral chwtsum+--- !_ = trace (" *** " ++ show chprobs)+    chprobs = map (\ (Node (_,w) _) -> normfac * (fromIntegral w)) chs++  weightedRose :: Rose r -> Rose (r, Int)+  weightedRose (Node r chs) = foldl k' b (map weightedRose chs)+   where+     k = (\ (r,w) (r',w') -> (r,w+w'))+     b = Node (r,1) []+     k' (Node rw chs) nod@(Node rw' _) = Node (rw `k` rw') (chs++[nod])++  unzipRose :: Rose (r, s) -> (Rose r, Rose s)+  unzipRose (Node (x,y) ns) = (Node x xns, Node y yns)+   where+    (xns,yns) = unzip $ map unzipRose ns++  showRose :: Show r => Rose r -> String+  showRose = show' 0+   where show' n (Node r chs)+           = indent n ++ show r ++ "\n" ++ concatMap (show' (1+n)) chs+              where indent n = concat $ replicate n "| "  ------------------------------------------------------------------------------- 
− src/Control/DeepSeq/Bounded/PatUtil_new_grammar.hs
@@ -1,1207 +0,0 @@-----------------------------------------------------------------------------------  {-  LANGUAGE CPP #-}---- XXX This is not correct! Use elidePats if you want something--- arity-changing.  The only time it would be valid for shrinkPat--- to produce a (Node WR []) is from some attribute-enriched--- (Node WR []) or (Node TR []).-#define SHRINK_TO_EMPTY_WR 0---- As for intersection, if the arities differ, the node--- effectively becomes non-recursive.  (Whether this is--- theoretically the best choice is still uncertain.)--- What is certain is, unless support richer Pattern's,--- a union of two recursive Pattern nodes with differing--- arities is not well-definable.---   The reason this switch exists at all is, it can--- be expensive to compute this predicate, especially--- considering that recursive nodes are very common,--- with WR being ("in the average case") the single most--- abundant node type in a pattern, probably followed--- in order by WI, WS, WW, WN (or parallel counterparts).-#define ENFORCE_SAME_ARITY_UNION 1--#define DO_TRACE 0---- Now specified via --flag=[-]USE_WWW_DEEPSEQ---- #define USE_WW_DEEPSEQ 1-----------------------------------------------------------------------------------  -- XXX For debugging only!-  {-# LANGUAGE BangPatterns #-}--  {-# LANGUAGE Rank2Types #-}-  {-  LANGUAGE ScopedTypeVariables #-}------------------------------------------------------------------------------------- |--- Module      :  Control.DeepSeq.Bounded.PatUtil_new_grammar--- Copyright   :  Andrew G. Seniuk 2014-2015--- License     :  BSD-style (see the file LICENSE)------ Maintainer  :  Andrew Seniuk <rasfar@gmail.com>--- Stability   :  provisional--- Portability :  portable, except mkPat, mkPatN and growPat (which use SYB)----{--}--- (Restore comment from PatUtil.hs when shed old grammar support.)-----------------------------------------------------------------------------------  module Control.DeepSeq.Bounded.PatUtil_new_grammar--- (Restore exports & comments from PatUtil.hs when shed old grammar support.)-  where-----------------------------------------------------------------------------------  import Control.DeepSeq.Bounded.Pattern--  import Data.Maybe ( isNothing, fromJust )-  import Data.Maybe ( isJust )--#if ! HASKELL98_FRAGMENT-  import Data.Data ( Data )-  import Data.Generics ( GenericQ )-  import Data.Generics ( gmapQ )-#endif--  import Data.List ( findIndex )---import Data.List ( elemIndex )-  import Data.List ( sortBy )---import Data.List ( nub )-  import Data.List ( foldl' )-  import Data.List ( group )-  import Data.List ( sort )-  import Data.List ( intersect )--  import System.Random--  import Control.Concurrent ( ThreadId )----import Control.Applicative ( (<$) )--  import Debug.Trace ( trace )-  import Control.DeepSeq ( force )--  -- For global Bool state, to indicate that a warning has already been issued.-  import Data.IORef-  import System.IO.Unsafe ( unsafePerformIO )-----------------------------------------------------------------------------------#if DO_TRACE-  mytrace = trace-#else-  mytrace _ = id-#endif-----------------------------------------------------------------------------------  firstWarningPassed :: IORef Bool-  firstWarningPassed = unsafePerformIO $ newIORef False-----------------------------------------------------------------------------------  -- | Compute the union of a list of 'Pattern's.-  ---  -- Note that unionPats is undefined when homologous nodes-  -- specify incompatible arities (only possible when-  -- 'WR' or 'TR' are involved).-  ---  -- /__XXX__ Support for the various attributes is work in progress. It may be impossible to arrive at a consistent treatment for all attributes under unions. At the last moment, 0.6.0.0 will __not__ be supporting type constraints under union, intersection or testing subpattern predicate. This is work in progress, but the five un-modified @W*@ node types should be safe./-  unionPats :: [ Pattern ] -> Pattern-  unionPats [] = emptyPat-  -- Using force here, to try to prevent the regular output being-  -- interleaved with the trace message. it works, except for the-  -- opening " (if you're in ghci, anyways).-  unionPats ps = foldr1 (union' False) $ force $ map (clearTypeConstraints "unionPats") ps---unionPats ps = foldr1 (union' False) ps---unionPats ps = foldr1 union' $ trace (">> " ++ show ps) $ ps--  union' :: Bool -> Pattern -> Pattern -> Pattern--  -- We hit this coming in every time [modulo compiler/runtime-  -- optimisations], so performance counts.-  union' b (Node pas1 cs1) (Node pas2 cs2)-   | WI{} <- pas1               = Node pas2' cs2-   |               WI{} <- pas2 = Node pas1' cs1-   where-    pas1' = setPatNodeAttrs pas1 union_as-    pas2' = setPatNodeAttrs pas2 union_as-    union_as = unionAttrs [as1,as2]-    (as1, as2) = (getPatNodeAttrs pas1, getPatNodeAttrs pas2)--  -- Symmetric cases:-  union' _ nod1@(Node pas1 cs1) nod2@(Node pas2 cs2)-   -- XXX Those cases using zipWith are not correct,-   -- unless length cs1 == length cs2.  But one hates to-   -- have to compute that. Caveat Emptor! This will behave-   -- as a true union operator only if the child pattern lists-   -- are compatibly-sized!-   --   In seqaid (and in "correct" manual usage?), this problem-   -- will never arise.-#if 0-   -- XXX Don't do it! -- (==) on PatNode might be more expensive-   -- than I think, some attributes have list parameters...-   | p1 == p2           = Node p1 $ zipWith (union' b) cs1 cs2-#endif-#if ENFORCE_SAME_ARITY_UNION-   | WR{} <- pas1, WR{} <- pas2 = {-trace "WRWR" $-}-      if csokay then Node (WR union_as) $ zipWith (union' False) cs1 cs2-      else error "unionPat: WRWR: encountered arity disparity!"-#else-   | WR{} <- pas1, WR{} <- pas2 = {-trace "WRWR" $-} Node (WR union_as) $ zipWith (union' False) cs1 cs2-#endif-   | WS{} <- pas1, WS{} <- pas2 = {-trace "WSWS" $-} Node (WS union_as) []-   | WN{} <- pas1, WN{} <- pas2 = {-trace "WNWN" $-} Node (WN union_as) []-#if USE_WW_DEEPSEQ-   | WW{} <- pas1, WW{} <- pas2 = {-trace "WWWW" $-} Node (WW union_as) []-#endif-#if 0-#if ENFORCE_SAME_ARITY_UNION-   | TR{} <- pas1, TR{} <- pas2 = {-trace "TRTR" $-}-      if csokay then Node (TR union_as) $ zipWith (union' False) cs1 cs2-      else error "unionPat: TRTR: encountered arity disparity!"-#else-   | TR{} <- pas1, TR{} <- pas2-      = {-trace "TRTR" $-} Node (TR union_as) $ zipWith (union' False) cs1 cs2-#endif-   | TI{} <- pas1, TI{} <- pas2-      = {-trace "TITI" $-} Node (TI union_as) []----   = {-trace "TITI" $-} Node (TI union_as) $ zipWith (union' False) cs1 cs2-----  = {-trace "TITI" $-} Node (TI union_as (intersectTys tys1 tys2)) $ zipWith (union' False) cs1 cs2---- | TR{} cls1 tys1 cns1 <- p1, TR{} cls2 tys2 cns2 <- p2-----  = {-trace "TRWR" $-} Node (TR union_as (cls1++cls2) (tys1++tys2) (cns1++cns2)) $ zipWith union' cs1 cs2-#endif-   | otherwise  = union'asym_1 False (Node pas1 cs1) (Node pas2 cs2)-   where-    pas1' = setPatNodeAttrs pas1 union_as-    pas2' = setPatNodeAttrs pas2 union_as-    union_as = unionAttrs [as1,as2]-    (as1, as2) = (getPatNodeAttrs pas1, getPatNodeAttrs pas2)-#if ENFORCE_SAME_ARITY_UNION-    csokay = equilength cs1 cs2-#endif--  -- Now the asymmetric cases:-  -- XXX This probably has numerous bugs and oversights!-   -- XXX Those cases using zipWith are not correct,-   -- unless length cs1 == length cs2.  But one hates to-   -- have to compute that. Caveat Emptor! This will behave-   -- as a true union operator only if the child pattern lists-   -- are compatibly-sized!-   --   Actually, if zipWith (which is acting on two [Pattern];-   -- you could supply union-unit pattern for missing children-   -- in shorter list, but then which children exactly were missing?-   -- So rather than play such a game without a racket, we just-   -- require the lists to be the same length or all bets are off.-   --   In seqaid, this problem will never arise.-   -- And in "correct" manual usage?...--#if USE_WW_DEEPSEQ-  union'asym_1 b nod1@(Node pas1 cs1) nod2@(Node pas2 cs2)-   | WW{} <- pas1-      =---      trace (if b then "**WW" else "WW**") $-        Node (WW union_as) []-   | not b      = union'asym_1 True nod2 nod1-   | otherwise  = union'asym_2 False nod1 nod2-   where-    union_as = unionAttrs [as1,as2]-    (as1, as2) = (getPatNodeAttrs pas1, getPatNodeAttrs pas2)-#endif--  union'asym_2 b nod1@(Node pas1 cs1) nod2@(Node pas2 cs2)-   | WN{} <- pas1-      =---      trace (if b then "**WN" else "WN**") $-        union'asym_2_aux dep-   | not b      = union'asym_2 True nod2 nod1-   | otherwise  = union'asym_3 False nod1 nod2-   where-    union'asym_2_aux 0 = Node (WI union_as) []-    union'asym_2_aux 1 = Node (WS union_as) []-    union'asym_2_aux _ = Node (WN union_as) []-    union_as = unionAttrs [as1,as2]-    (as1, as2) = (getPatNodeAttrs pas1, getPatNodeAttrs pas2)-    dep = depth as1---- XXX XXX--- I think it is not possible to reconcile, say, WR with TW.--- TW says rnf if in type; WR says recurse regardless of type--- according to the subpatterns.  Ah! But the union is, a priori,--- only well-defined if the WR shape is "elected" from the wild--- shape of TW, so in fact the correct answer is TR!  Very interesting!!!--------- But what of WR with TN?...  If WR pattern depth (levels of tree)--- is less than the n of TN, then answer is again TR.  But if n is--- deeper than the WR pattern shape?... Perhaps only in SOME places...---   You can still perhaps reconcile it, but now some fairly serious--- pattern surgery is required! "We have the technology"....---------  -- We have now to deal only with asymmetric combos-  -- of WR, TR, WS, and TI nodes.  Six cases (plus six-  -- automatically when re-call with flip).-  --   Oops, there are still also TW and TN nodes...---------------  --        WR   WS   TI   TR   TN   TW-  ---  --   WR   Sym  WRWS WRTI WRTR WRTN WRTW-  ---  --   WS   flip Sym  WSTI WSTR WSTN WSTW-  ---  --   TI   flip flip Sym  TITR TITN TITW-  ---  --   TR   flip flip flip Sym  TRTN TRTW-  ---  --   TN   flip flip flip flip Sym  TNTW-  ---  --   TW   flip flip flip flip flip Sym -------------------  -- Fifteen cases to consider in all. Can they all be logically reconciled?...--------------------------  -- WRWS : WR wins (not quite trivial however)-  -- ... if we just let T* be broken for 0.6.0.0, we're done there!-  -- By "broken" meaning, better give an error -- could just erase-  -- the type constraints silently, but what use is that?-  union'asym_3 b nod1@(Node pas1 cs1) nod2@(Node pas2 cs2)-   | WR{} <- pas1, WS{} <- pas2 = {-trace "WRWS" $-} nod1'-#if 0-#if ENFORCE_SAME_ARITY_UNION-   | TR{} <- pas1, WR{} <- pas2 = {-trace "TRWR" $-}-      if csokay then nod1'-      else error $ "unionPat: " ++ if b then "WRTR" else "TRWR" ++ ": encountered arity disparity!"-#else-   | TR{} <- pas1, WR{} <- pas2 = {-trace "TRWR" $-} nod1'-#endif-   | TR{} <- pas1, WS{} <- pas2 = {-trace "TRWS" $-} nod1'-   | TI{} <- pas1, WR{} <- pas2 = {-trace "TIWR" $-} nod2'-   | TI{} <- pas1, WS{} <- pas2 = {-trace "TIWS" $-} nod2'-#if USE_WW_DEEPSEQ-   | TW{} <- pas1, WR{} <- pas2 = {-trace "TWWR" $-} nod1'-   | TW{} <- pas1, WS{} <- pas2 = {-trace "TWWS" $-} nod1'-   | TW{} <- pas1, WW{} <- pas2 = {-trace "TWWW" $-} nod2'-#endif-   | TI{} <- pas1, TR{} <- pas2-      = {-trace "TITR" $-} Node (TR union_as) $ zipWith (union'asym_3 False) cs1 cs2-#endif-   | not b = union'asym_3 True nod2 nod1-   | otherwise = error "unionPats: unexpected failure to (Haskell) pattern-match arguments!"-   where---  cs1' = map (const emptyPat) cs1-    nod1' = Node pas1' cs1-    pas1' = setPatNodeAttrs pas1 union_as-    union_as = unionAttrs [as1,as2]-    (as1, as2) = (getPatNodeAttrs pas1, getPatNodeAttrs pas2)-#if ENFORCE_SAME_ARITY_UNION-    csokay = equilength cs1 cs2-#endif-----------------------------------------------------------------------------------  -- | Compute the intersection of a list of 'Pattern's.-  ---  -- Where two (or more) homologous 'WR' nodes disagree in arity,-  -- the intersection at that position becomes 'WI'.-  ---  -- /__XXX__ This doesn't yet handle type-constrained 'PatNode's ('TI', 'TR', 'TN' or 'TW'). Other attributes are handled in a haphazard fashion. This is work in progress, but the five un-modified @W*@ node types should be safe./--  intersectPats :: [ Pattern ] -> Pattern-  intersectPats [] = emptyPat-  intersectPats ps = foldr1 (intersect' False) $ force $ map (clearTypeConstraints "intersectPats") ps--  intersect' :: Bool -> Pattern -> Pattern -> Pattern--  -- We hit this coming in every time [modulo compiler/runtime-  -- optimisations], so performance counts.-  intersect' b (Node pas1 cs1) (Node pas2 cs2)-   | WI{} <- pas1               = Node (WI intersect_as) []-   |               WI{} <- pas2 = Node (WI intersect_as) []-   where-    intersect_as = intersectAttrs [as1,as2]-    (as1, as2) = (getPatNodeAttrs pas1, getPatNodeAttrs pas2)--  -- Symmetric cases:-  intersect' _ nod1@(Node pas1 cs1) nod2@(Node pas2 cs2)-#if ENFORCE_SAME_ARITY_UNION-   | WR{} <- pas1, WR{} <- pas2 = {-trace "WRWR" $-}-      if csokay then Node (WR intersect_as) $ zipWith (intersect' False) cs1 cs2-      else error "intersectPat: WRWR: encountered arity disparity!"-#else-   | WR{} <- pas1, WR{} <- pas2 = {-trace "WRWR" $-} Node (WR intersect_as) $ zipWith (intersect' False) cs1 cs2-#endif-   | WS{} <- pas1, WS{} <- pas2 = {-trace "WSWS" $-} Node (WS intersect_as) []-   | WN{} <- pas1, WN{} <- pas2 = {-trace "WNWN" $-} Node (WN intersect_as) []-#if USE_WW_DEEPSEQ-   | WW{} <- pas1, WW{} <- pas2 = {-trace "WWWW" $-} Node (WW intersect_as) []-#endif-   -- XXX T* nodes not handled!-   | otherwise  = intersect'asym_1 False (Node pas1 cs1) (Node pas2 cs2)-   where-    pas1' = setPatNodeAttrs pas1 intersect_as-    pas2' = setPatNodeAttrs pas2 intersect_as-    intersect_as = intersectAttrs [as1,as2]-    (as1, as2) = (getPatNodeAttrs pas1, getPatNodeAttrs pas2)-#if ENFORCE_SAME_ARITY_UNION-    csokay = equilength cs1 cs2-#endif--  -- Now the asymmetric cases:-#if USE_WW_DEEPSEQ-  intersect'asym_1 b nod1@(Node pas1 cs1) nod2@(Node pas2 cs2)-   | WW{} <- pas1-      =---      trace (if b then "**WW" else "WW**") $-        Node pas2' cs2-   | not b      = intersect'asym_1 True nod2 nod1-   | otherwise  = intersect'asym_2 False nod1 nod2-   where-    pas2' = setPatNodeAttrs pas2 intersect_as-    intersect_as = intersectAttrs [as1,as2]-    (as1, as2) = (getPatNodeAttrs pas1, getPatNodeAttrs pas2)-#endif--  intersect'asym_2 b nod1@(Node pas1 cs1) nod2@(Node pas2 cs2)-   | WN{} <- pas1-      =---      trace (if b then "**WN" else "WN**") $-        truncatePat dep (Node (setPatNodeAttrs pas2 intersect_as) cs2)---      intersect'asym_2_aux dep-   | not b      = intersect'asym_2 True nod2 nod1-   | otherwise  = intersect'asym_3 False nod1 nod2-   where-#if 0-    intersect'asym_2_aux 0 = Node (WI intersect_as) []-    intersect'asym_2_aux 1 = Node (WS intersect_as) []-    intersect'asym_2_aux _ = Node (WN intersect_as) []-#endif-    intersect_as = intersectAttrs [as1,as2]-    (as1, as2) = (getPatNodeAttrs pas1, getPatNodeAttrs pas2)-    dep = depth as1--  intersect'asym_3 b nod1@(Node pas1 cs1) nod2@(Node pas2 cs2)-   | WR{} <- pas1, WS{} <- pas2 = {-trace "WRWS" $-} nod1'-   -- XXX T* nodes not handled!-   | not b = intersect'asym_3 True nod2 nod1-   | otherwise = error "intersectPats: unexpected failure to (Haskell) pattern-match arguments!"-   where-    cs1' = map (const emptyPat) cs1-    nod1' = Node (WR intersect_as) cs1'-    intersect_as = intersectAttrs [as1,as2]-    (as1, as2) = (getPatNodeAttrs pas1, getPatNodeAttrs pas2)-#if ENFORCE_SAME_ARITY_UNION-    csokay = equilength cs1 cs2-#endif-----------------------------------------------------------------------------------  -- | Return 'True' if the first pattern matches the second (and 'False' otherwise).-  ---  -- Arities must correspond (or the second pattern's node must be wild) for the match to succeed at each __recursive__ 'PatNode' (/i.e./ 'WR' or 'TR').-  -- Matching does not imply spanning; @'flip' 'subPat'@ would work for that.-  ---  -- /__XXX__ This doesn't yet handle type-constrained 'PatNode's ('TI', 'TR', 'TN' or 'TW'), because 'intersectPats' doesn't. Generally speaking, it is difficult to arrive at a good policy for subpattern, union and intersection, when mixed types of nodes with various attribute values are considered!  Other attributes are handled in a haphazard fashion. This is work in progress, but the five un-modified @W*@ node types should be safe./-  ---  -- More formally, we have two \"Subpattern Axioms\":-  ---  -- * __Not More Specifc__ &#8195; A subpattern (of a pattern) is never more specific (/i.e./ less permissive), in terms of what values it will match.-  ---  -- * __Not More Forcing__ &#8195; A subpattern never has greater forcing potential.-  ---  -- And a /proper/ subpattern will always be strictly more permissive or-  -- less forcing (or both).-  subPat :: Pattern -> Pattern -> Bool-  subPat p pp = p == intersectPats [p, pp]  -- probably faster on avg.---subPat p pp = pp == unionPats [p, pp]-----------------------------------------------------------------------------------  -- I guess I don't really clear the typeConstraints list,-  -- only toggle doConstrainType to False.-  clearTypeConstraints :: String -> Pattern -> Pattern-  clearTypeConstraints s (Node pas cs)-   = Node pas' $ map (clearTypeConstraints s) cs-   where-    as = getPatNodeAttrs pas-    as' = if doConstrainType as---        then error "unionPats: type constraints unsupported!"---        then trace "unionPats: warning: type constraints unsupported (cleared!)" as-          then unsafePerformIO $ do-                 firstwarnpassed <- readIORef firstWarningPassed-                 modifyIORef' firstWarningPassed (const True)-                 if firstwarnpassed-                   then return as-                   else trace (s ++ ": warning: type constraints unsupported (cleared!)")-                        $! return as-          else as-    as'' = as' { doConstrainType = False }-    pas' = setPatNodeAttrs pas as''-----------------------------------------------------------------------------------  -- XXX Note: Concerning the doSpark field, there is a deeper issue-  -- lurking here. Parallelisation and strictification are orthogonal-  -- concerns, so trying to treat them uniformly can be awkward...--  unionAttrs :: [PatNodeAttrs] -> PatNodeAttrs-  unionAttrs [] = error "unionAttrs: called with empty list.\nPlease determine which library has called this function erroneously,\nand file a bug report or contact the maintainer of that project."-  unionAttrs as = foldl1 unionAttrs' as-  unionAttrs' :: PatNodeAttrs -> PatNodeAttrs -> PatNodeAttrs-  unionAttrs'-    (PatNodeAttrs-      uniq1-      dep1-      dotys1-      tys1-      dly1 dlyus1-#if USE_PAR_PATNODE-      spk1-#endif-#if USE_PSEQ_PATNODE-      pseq1 pseqperm1-#endif-#if USE_TRACE_PATNODE-      tr1-#endif-#if USE_PING_PATNODE-      ping1 pingtid1-#endif-#if USE_DIE_PATNODE-      die1-#endif-#if USE_TIMING_PATNODE-      timing1 ts1 parent_ts1 delta_ts1-#endif-    )-    (PatNodeAttrs-      uniq2-      dep2-      dotys2-      tys2-      dly2 dlyus2-#if USE_PAR_PATNODE-      spk2-#endif-#if USE_PSEQ_PATNODE-      pseq2 pseqperm2-#endif-#if USE_TRACE_PATNODE-      tr2-#endif-#if USE_PING_PATNODE-      ping2 pingtid2-#endif-#if USE_DIE_PATNODE-      die2-#endif-#if USE_TIMING_PATNODE-      timing2 ts2 parent_ts2 delta_ts2-#endif-    )-     = PatNodeAttrs-         (combineUniqueIDs uniq1 uniq2)-         (max dep1 dep2)-         (dotys1||dotys2)  -- SAME as intersection [?]-         (unionTys tys1 tys2)-         (dly1||dly2)  -- SAME as intersection [?]-         (combineDelays True dly1 dly2 dlyus1 dlyus2)  -- DIFFERENT for union and intersection [?]-#if USE_PAR_PATNODE-         (spk1||spk2)  -- seems the best choice for parallelism union semantics-#endif-#if USE_PSEQ_PATNODE-         (pseq1&&pseq2)  -- DIFFERENT for union and intersection [??]-         (combinePseqPerms pseqperm1 pseqperm2)  -- XXX SAME as intersection...-#endif-#if USE_TRACE_PATNODE-         (combineTraces tr1 tr2)  -- same for union and intersection-#endif-#if USE_PING_PATNODE-         (combinePings ping1 ping2)  -- same for union and intersection-         (combinePingParentTIDs pingtid1 pingtid2)  -- same for union and intersection-#endif-#if USE_DIE_PATNODE-         (die1||die2)  -- same for union and intersection-#endif-#if USE_TIMING_PATNODE-         -- same for union and intersection [?]-         -- XXX This is bogus, so it would be nice if it would issue a warning.-         -- We'd want to issue the warning only once per run, I think...-         (False) (0) (0) (0)-#endif--  intersectAttrs :: [PatNodeAttrs] -> PatNodeAttrs-  intersectAttrs [] = error "intersectAttrs: called with empty list.\nPlease determine which library has called this function erroneously,\nand file a bug report or contact the maintainer of that project."-  intersectAttrs as = foldr1 intersectAttrs' as-  intersectAttrs' :: PatNodeAttrs -> PatNodeAttrs -> PatNodeAttrs-  intersectAttrs'-    (PatNodeAttrs-      uniq1-      dep1-      dotys1-      tys1-      dly1 dlyus1-#if USE_PAR_PATNODE-      spk1-#endif-#if USE_PSEQ_PATNODE-      pseq1 pseqperm1-#endif-#if USE_TRACE_PATNODE-      tr1-#endif-#if USE_PING_PATNODE-      ping1 pingtid1-#endif-#if USE_DIE_PATNODE-      die1-#endif-#if USE_TIMING_PATNODE-      timing1 ts1 parent_ts1 delta_ts1-#endif-    )-    (PatNodeAttrs-      uniq2-      dep2-      dotys2-      tys2-      dly2 dlyus2-#if USE_PAR_PATNODE-      spk2-#endif-#if USE_PSEQ_PATNODE-      pseq2 pseqperm2-#endif-#if USE_TRACE_PATNODE-      tr2-#endif-#if USE_PING_PATNODE-      ping2 pingtid2-#endif-#if USE_DIE_PATNODE-      die2-#endif-#if USE_TIMING_PATNODE-      timing2 ts2 parent_ts2 delta_ts2-#endif-    )-     = PatNodeAttrs-         (combineUniqueIDs uniq1 uniq2)-         (min dep1 dep2)-         (dotys1||dotys2)  -- SAME as union [?]-         (intersectTys tys1 tys2)-         (dly1||dly2)  -- SAME as union [?]-         (combineDelays False dly1 dly2 dlyus1 dlyus2)  -- DIFFERENT for union and intersection [?]-#if USE_PAR_PATNODE-         (spk1||spk2)  -- seems the better choice---       (spk1&&spk2)  -- dubious parallelism intersection semantics-#endif-#if USE_PSEQ_PATNODE-         (pseq1||pseq2)  -- DIFFERENT for union and intersection [??]-         (combinePseqPerms pseqperm1 pseqperm2)  -- XXX SAME as union...-#endif-#if USE_TRACE_PATNODE-         (combineTraces tr1 tr2)  -- same for union and intersection-#endif-#if USE_PING_PATNODE-         (combinePings ping1 ping2)  -- same for union and intersection-         (combinePingParentTIDs pingtid1 pingtid2)  -- same for union and intersection-#endif-#if USE_DIE_PATNODE-         (die1||die2)  -- same for union and intersection-#endif-#if USE_TIMING_PATNODE-         -- same for union and intersection [?]-         -- XXX This is bogus, so it would be nice if it would issue a warning.-         -- We'd want to issue the warning only once per run, I think...-         (False) (0) (0) (0)-#endif-----------------------------------------------------------------------------------  -- The idea here is that, PatNodeAttrs only carries a Bool for each-  -- of combineTraces and combinePings, and the actual content of the-  -- log string or Exception message is a matter to be determined in-  -- the context that the logging/exception is triggered (demanded).--#if USE_TRACE_PATNODE-  combineTraces :: Bool -> Bool -> Bool-  combineTraces = (||)  -- for now, at least-#endif--#if USE_PSEQ_PATNODE-  combinePseqPerms :: Maybe [Int] -> Maybe [Int] -> Maybe [Int]-  combinePseqPerms mpsp1 mpsp2-   | isNothing mpsp1  = mpsp2-   | isNothing mpsp2  = mpsp1-   | mpsp1 == mpsp2   = mpsp1-   | otherwise        = trace "WARNING: combinePseqPerms: Incompatible permutations discarded (using id)." Nothing-#endif--#if USE_PING_PATNODE-  combinePingParentTIDs :: Maybe ThreadId -> Maybe ThreadId -> Maybe ThreadId-  combinePingParentTIDs mt1 mt2-   = if isNothing mt1 && isNothing mt2-     then Nothing-     else if isJust mt1 && isJust mt2 && t1 == t2-          then Just t1-#if 1-          else-#if 1-               trace-                 (    "combinePings: TID's differ: "-                   ++ show mt1 ++ " " ++ show mt2-                   ++ "\nCombining by choosing " ++ show mt1 ++ "!" )-#endif-                 mt1-#else-          -- XXX This shouldn't be "error"!-          else error $    "combinePings: TID's differ: "-                       ++ show mt1 ++ " " ++ show mt2-#endif---        else Nothing-   where (t1,t2) = (fromJust mt1,fromJust mt2)--  combinePings :: Bool -> Bool -> Bool-  combinePings = (||)  -- for now, at least-#endif--  combineUniqueIDs :: Int -> Int -> Int-  combineUniqueIDs u1 u2-   | u1 == u2   = u1-   | otherwise  =-#if 0--- Seeing as this will happen 99% of the time, it's a bit much--- to issue a warning to console!-                  trace-                    ( "combineUniqueIDs: uniqueID's differ: "-                       ++ show u1 ++ " " ++ show u2 )-#endif-                    0--  -- Rather dubious.-  combineDelays :: Bool -> Bool -> Bool -> Int -> Int -> Int-  combineDelays from_union dly1 dly2 dlyus1 dlyus2-   | not dly1 && not dly2  = 0-   | not dly1              = dlyus2-   | not dly2              = dlyus1-   | from_union            = min dlyus1 dlyus2-   | otherwise             = max dlyus1 dlyus2-----------------------------------------------------------------------------------  -- Probably overkill for typical lengths.-  -- Would pay to special case for some short lists.-  -- Optimisations come later.--  unionTys :: [String] -> [String] -> [String]-  unionTys ss1 ss2 = nubsort $ ss1 ++ ss2--  nubsort :: Ord a => [a] -> [a]-  nubsort = map head . group . sort--  intersectTys :: [String] -> [String] -> [String]-  intersectTys ss1 ss2 = intersect (nubsort ss1) (nubsort ss2)-----------------------------------------------------------------------------------#if ENFORCE_SAME_ARITY_UNION-  -- Try to determine whether then lengths of the lists are-  -- the same or not without being too inefficient...-  {-# INLINE equilength #-}-  equilength :: [a] -> [b] -> Bool-#if 0--- XXX But ... I feel like best practise is to use "length cs1 == length cs2",--- since who knows, the compiler could optimise it into some sort of quasi---- list internal structure with O(1) length function.  That is not too--- far fetched at all.  (Complexities as reported in the standard libraries--- need not be strictly observed -- actual evaluations may exhibit lower--- complexity without violating any specification...)  And if this happens,--- then we've blocked the optimisation, so we get a 0.5*O(n) average case--- algorithm instead of an O(n), but missed out on O(1)...---   The only really safe way is to implement using your choice of--- container with O(1) length.  Or of course, you could attempt to--- maintain the length as associated data (extra field)...-  equilength (x:xs) (y:ys) = equilength xs ys-  equilength [] [] = True-  equilength _ _ = False-#else-  equilength cs1 cs2 = length cs1 == length cs2  -- ouch(?)-#endif-#endif--  zipWith_ :: String -> (a -> b -> c) -> [a] -> [b] -> (Bool,[c])-  zipWith_ caller f xs ys-   | b          = (b,zs)-   | otherwise  = trace (caller ++ ": node arity disparity!") (b,zs)-   where-    (b,zs') = zipWith_' f xs ys []-    zs = reverse zs'-  zipWith_' :: (a -> b -> c) -> [a] -> [b] -> [c] -> (Bool,[c])-  zipWith_' f (x:xs) (y:ys) acc = zipWith_' f xs ys (f x y : acc)-  zipWith_' _ [] [] acc = (True,acc)-  zipWith_' _ _ _ acc = (False,acc)-----------------------------------------------------------------------------------  -- | Given an integer depth and a pattern, truncate the pattern to-  -- extend to at most this requested depth.-  ---  -- Nodes in the truncated pattern which were 'WR' and are now leaves,-  -- are changed to 'WI'.-  -- (This is a change from 0.5, where they were-  -- changed to 'WS', which violates the Subpattern Axiom concerning-  -- forcing potential.-  -- It may be further changed to 'WR'-bearing-'WI'-children-  -- in 0.7, which preserves arity info, as is consistent with the new-  -- treatment of 'mkPatN' in 0.6.)-  ---  -- /__XXX__ Note that @*N@ and @*W@ nodes are retained, so if you are using those then \"extend to at most this depth\" does not mean the forcing potential of the pattern is at most that depth...  It would be quite possible to improve this, so @*N@ (and @*W@ nodes, obviously) are \"weakened\" (depth is reduced) so that they end at the truncation depth, regardless of how far up they reside.  In particular, any @*N@ or @*W@ node at truncation depth could be replaced by @WS@.  This works well as all these node types are arity-agnostic./-  truncatePat :: Int -> Pattern -> Pattern-  truncatePat n node@(Node pas chs)-   | n <= 0     = Node (WS $ getPatNodeAttrs pas) []-   | otherwise  = Node pas $ map (truncatePat (-1+n)) chs-----------------------------------------------------------------------------------  -- | There is no @Nil@ in the @Pattern@ type, but a single 'WI' node as-  -- empty pattern is a dependable way to ensure that the empty pattern-  -- never forces anything. This sets 'PatNodeAttrs' to 'emptyPatNodeAttrs'.-  emptyPat :: Pattern-  emptyPat = Node (WI emptyPatNodeAttrs) []  -- this should do it!-----------------------------------------------------------------------------------#if ! HASKELL98_FRAGMENT-  -- | Obtain a lazy, potentially infinite pattern, matching the shape-  -- of an arbitrary term (value expression).-  ---  -- There is only one kind of 'PatNode' employed here, 'WR'.-  -- (__Note__:-  -- /This is an API breaking change from 0.5, where 'WS' also occurred./)-  ---  -- The 'Pattern' is extended indefinitely on demand.  In case the-  -- term has leaves, these will be 'WR' nodes with empty child lists-  -- in the corresponding pattern.-  ---  -- __Caveat__: Note that @mkPat@ gives counter-intuitive results when used-  -- on rose trees, in particular on 'Pattern' itself.-  -- For example, a rose tree with a single node will have a 3-node /\\ shape.)-  -- Formally, 'mkPat' is not idempotent on 'Pattern's, but rather grows-  -- without bound when iterated. This shouldn't be an issue in practise.-  mkPat :: forall d. Data d => d -> Pattern-  mkPat = f . shapeOf-   where-    f (Node _ cs) = Node pn $ map f cs-     where-      pn = WR emptyPatNodeAttrs----   pn = let as = emptyPatNodeAttrs in if null cs then WS as else WR as--  -- | Obtain a lazy, finite pattern, matching the shape of-  -- an arbitrary term, but only down to at most depth @n@.-  ---  -- Satisfies @'forcep' . 'mkPatN' n = 'forcen' n@. /(Later: I kinda doubt that is true in full generality?... Although it does convey the idea.)/-  ---  -- Unlike 'mkPat', three pattern node contexts arise here:-  ---  -- * those corresponding to actual leaf (nullary) nodes of the term-  ---  --     * these are &#8195; @Node WR []@-  ---  -- * interior nodes of the pattern corresponding to interior nodes of the term-  ---  --     * these are &#8195; @Node WR chs@ &#8195; where @chs@ are the child subpatterns of this interior pattern node-  ---  -- * leaf nodes of the pattern corresponding to interior nodes of the term, that is, non-leaf nodes of the term which are at a depth @n@ of nested constructor applications.-  ---  --     * these are &#8195; @Node WR chs'@ &#8195; where &#8195; @chs' = map (const $ Node WI []) chs@-  --     * this essentially says we're allowed to know the arity of the node, but aside from this cardinal number we know nothing whatsoever concerning the child subpatterns and are not even permitted to evaluate their heads-  ---  -- All interior nodes are 'WR', and all leaf nodes are 'WI'; 'WS' never arise (which is a change from version 0.5).-  ---  -- See caveat in the 'mkPat' documentation.-  mkPatN :: forall d. Data d => Int -> d -> Pattern-  mkPatN n = f n . shapeOf-   where-    f n (Node _ cs)-     | 0 == n     = if null cs-                    then Node pn []-                    else Node pn $ map (const emptyPat) cs-     | otherwise  = Node pn $ map (f (-1+n)) cs-     where-      pn = WR emptyPatNodeAttrs-#endif-----------------------------------------------------------------------------------  -- | Elide all leaves which have no non-leaf sibling.-  -- We want the pattern to still match the same value, only less of it.-  -- Merely eliding all leaves would, in most cases, cause match failure,-  -- so we have to be a bit more subtle.  There are some arbitrary-  -- decisions about the relaxation route through the lattice.-  -- (Refer to the source for details.)-  ---  -- More formally, we have some \"Shrinkage Axioms\".  The first-  -- two are really just the \"Subpattern Axioms\" again, that is,-  -- shrinkage is always to a subpattern in our sense of the-  -- word (see also 'subPat'):-  ---  -- * __Not More Specifc__ &#8195; Shrinkage is never towards a more specific (/i.e./ less permissive) pattern.-  ---  -- * __Not More Forcing__ &#8195; Shrinkage is never towards a pattern with greater forcing potential.-  ---  -- And additionally, for finite patterns only:-  ---  -- * __Non-Constancy__ &#8195; A finite pattern is constant under shrinkage /iff/ the pattern is trivial (emptyPat, \".\", Node WI []). However, infinite patterns have other limits.  For instance, the infinite pattern @'concat' $ 'repeat' "(."@ (yes you can do that!) is already stationary under shrinkage.-  ---  -- * __Convergence__ &#8195; On iteration, shrinkage of finite patterns reaches the trivial pattern in a number of steps proportional to the size of the initial pattern argument.  (Actually, @*N@ and @*W@ nodes can make this larger.)  However, in the case of infinite patterns, all bets are off: Simple examples exist which converge immediately, or which continue shrinking indefinitely.)-{--}-  -- XXX This has a bug -- it introduces WR []'s when the original-  -- node arity was not zero! The progression should be (in the-  -- newest syntax) something like:-  --   (.(!.))-  --   (.(..))-  --   (.!)-  --   (..)-  --   !-  --   .-  shrinkPat :: Pattern -> Pattern-  shrinkPat (Node pas cs)-#if USE_PAR_PATNODE-   -- take de-parallelisation as shrinkage-   -- XXX So should we take pseq-isation as further shrinkage?-   | doSpark as  = let as' = as { doSpark = False } in-                   case pas of-                    WI{} -> Node (WI as') []-                    WS{} -> Node (WI as') []-                    WR{} -> Node (WR as') cs-                    WN{} -> Node (WN as') []-#if USE_WW_DEEPSEQ-                    WW{} -> Node (WW as') []-#endif-#endif-   | WI{} <- pas  = Node (WI as) []  -- can't shrink (evt'ly elided from parent)-   | WS{} <- pas  = Node (WI as) []  -- may as well-   | WN{} <- pas-      = let n = depth as-            n' = -1+n-        in if n' <= 0 then Node (WI as) []-           else if n' == 1 then Node (WS as) []-           else let as' = as { depth = n' } in Node (WN as') []-#if USE_WW_DEEPSEQ-   | WW{} <- pas  = Node (WN as { depth = 5 }) []  -- XXX arbitrary hardcode-#endif-   -- take un-type-constrained as shrinkage (pattern becomes less specific)-   -- XXX Later: This is wrong. It is less specific, but it HAS MORE FORCING-   -- POTENTIAL (except in TI case).-   | TI{} <- pas  = Node (WI as) []-   | TR{} <- pas  = Node (WR as) cs-   | TN{} <- pas  = Node (WN as) []-#if USE_WW_DEEPSEQ-   | TW{} <- pas  = Node (WW as) []-#endif-#if SHRINK_TO_EMPTY_WR-   | WR{} <- pas , null cs  = Node (WI as) []-#endif-   -- If this node has any grandchildren, recurse on the children.-   | not $ null $ filter (\ (Node q gcs) -> not $ null gcs) cs-      = Node pas $ map shrinkPat cs-   -- At this point we know this node has no grandchildren.-   -- Check if all children are insulator nodes.-   | null $ filter (\ (Node pas _) -> case pas of { WI{} -> False ; _ -> True }) cs-      = case pas of-         -- Must go to WI, since .{##} -> . is /not/ a lazification.-         -- Later: Yes it is, isn't it?? Dot is a less constrained pattern...-#if SHRINK_TO_EMPTY_WR-         WR{} -> Node (WR as) []-#else-         WR{} -> Node (WI as) []-#endif-         -- We cannot make this simple TR -> WR (drop type constraints),-         -- since, while less specific, it forces more, violating the-         -- "second axiom of shrinkage".-         TR{} -> let as' = as { typeConstraints = [] } in Node (WI as') []  -- better?---       TR{} -> Node (WI as) []  -- sic-         _ -> error "shrinkPat: unexpected!"-   | otherwise-      = Node pas $ map shrinkPat cs  -- still contains shrinkable children-   where-    as = getPatNodeAttrs pas-----------------------------------------------------------------------------------#if PROVIDE_OLD_SHRINK_PAT-  -- | Old version, for temporary compatibility of seqaid demo mode.-  {-  DEPRECATED shrinkPat_old "For temporary compatibility of seqaid demo mode." #-}-  -- (Deprecation warning too noisy for me. Nobody will use this by accident.)-  shrinkPat_old :: Pattern -> Pattern-  shrinkPat_old (Node pas cs)-   | not $ null $ filter (\ (Node q gcs) -> not $ null gcs) cs  = Node pas $ map shrinkPat_old cs-   | WR{} <- pas  = Node (WS as) []-   | otherwise    = Node pas []-   where-    as = getPatNodeAttrs pas-#endif-----------------------------------------------------------------------------------#if ! HASKELL98_FRAGMENT-  -- | Grow all leaves by one level within the shape of the provided value.-  -- This is intended to be used with \"plain\" patterns, /i.e./ those-  -- containing only 'WR' and 'WI' nodes. (There is no code enforcing this.)-  -- A new growth node always replaces a 'WI' (leaf) node with a 'WR' node-  -- bearing the suitable number of 'WI' children to encode arity (see-  -- 'mkPat' for general commentary about this).-  growPat :: forall d. Data d => Pattern -> d -> Pattern-  growPat pat x = growPat' pat $ shapeOf x-  growPat' :: Pattern -> Shape -> Pattern-  growPat' (Node pas cs) (Node q ds)-   | null cs    = let subleaf = Node (WI $ getPatNodeAttrs pas) []-                      pas' = WR $ getPatNodeAttrs pas-                  in Node pas' $ map (const subleaf) ds-   | otherwise  = Node pas $ zipWith growPat' cs ds-#endif-----------------------------------------------------------------------------------  -- | This creates a new 'WR' node, the common root, with 'PatNodeAttrs' set-  -- to 'emptyPatNodeAttrs'.  The argument patterns become the children of-  -- the root (order is preserved).-  liftPats :: [ Pattern ] -> Pattern-  liftPats ps = Node (WR emptyPatNodeAttrs) ps-----------------------------------------------------------------------------------  -- | Add children to a node (interior or leaf) of the target.-  -- The first argument is target pattern, the second is a path (0-based-  -- indexing) from the root of the target to any choice node,-  -- and the third is a list of subpatterns for insertion, along with the-  -- indices of the insertion slots.-  -- Indices range through @-1,0..n@, where @n@ is the number of-  -- existing children, and @-1@ is short for @n@ (so you don't need-  -- to count off the children to append!).-  -- Indices are always relative to the original target as it was received.-  splicePats :: Pattern -> [Int] -> [ (Int, Pattern) ] -> Pattern-  splicePats target path isibs'---- | isibs /= isibs'    = error "splicePats: siblings to be inserted must be indexed in increasing order"---- | not uniqueIdxs     = error "splicePats: siblings to be inserted must be uniquely indexed"---- | not $ isPath path  = error "splicePats: path malformed"-   | otherwise          = splice' target path isibs-   where---  uniqueIdxs = length isibs == ( length $ nub $ map fst isibs )-    isibs = sortBy comp isibs'  -- questionable solution-     where-      comp (x1,_) (x2,_) = compare x1 x2-    -- Now, what's the clever way to do this? it's ugly manual-    -- recursion if don't think of something nicer. (This is-    -- the ugly manual recursion!)-    splice' :: Pattern -> [Int] -> [(Int,Pattern)] -> Pattern-    splice' (Node pas cs) [] isibs  -- end of path chain-     | maximum (map fst isibs) > ncs  = error "splicePats: insertion indices (0-based) must be\nno greater than the number of children"-     | or $ map ( (<(-1)) . fst ) isibs  = error "splicePats: insertion indices must be non-negative, or -1"----  | or $ map ( (<0) . fst ) isibs  = error "splicePats: insertion indices must be non-negative"-     | not ( isWR pas || isTR pas )  = error $ "splicePats: path ends in non-recursive node type " ++ show pas-     | otherwise  = {-trace "**1**" $-} Node pas $ f 0 cs isibs_-     where-      ncs = length cs-      -- XXX I'm trying to remember why had isibs of -1 as special.-      -- (They're now filtered upstream of here in any case.)-      isibs_ = let lst = takeWhile ((== -1) . fst) isibs in-               drop (length lst) isibs ++ map (\ (x,y) -> (ncs,y)) lst-      f n cs [] = cs-      f n [] isibs_remaining = map snd isibs_remaining---    f n [] isibs_remaining = error $ "splicePats: (2) path escapes target: " ++ show isibs_remaining  -- shouldn't happen-      f n lst1@(c:cs) lst2@((i,s):iss)----    | trace ("**3**"++show lst1++" "++show lst2) False  = undefined-       | ii == n    = map snd ss ++ (c : f (1+n) cs ss')-       | otherwise  =                c : f (1+n) cs lst2-       where (ss,ss') = span (\ (i,s) -> i == n) lst2-             ii = i---           ii = if i < 0 then ncs-(-i) else i-    splice' (Node pas cs) (i:is) isibs----  | trace ("**4** "++show i++" / "++show cs++" / "++show pathcs) False  = undefined-     | null cs  = error "splicePats: path escapes target (depth)"-     | length cs < 1+i  = error "splicePats: path escapes target (breadth)"-     | null ccsR  = error "splicePats: (2) path escapes target (depth)"--- Shouldn't be possible?----  | not ( isWR pas || isTR pas )  = error $ "splicePats: path contains non-recursive node type " ++ show pas-     | otherwise  = {-trace "**2**" $-} Node pas (csL ++ [splice' c is isibs] ++ csR)-     where-      (c:csR) = ccsR-      (csL,ccsR) = splitAt i cs-----------------------------------------------------------------------------------  -- | Elide children of a node (interior or leaf) of the target.-  -- The first argument is target pattern, the second is a path (0-based-  -- indexing) from the root of the target to any choice node,-  -- and the third is a list of child indices for elision.-  -- Indices range through @-1,0..n-1@, where @n@ is the number of-  -- existing children, and @-1@ is short for @n-1@ (so you don't need-  -- to count off the children to elide the rightmost).-  -- Indices are always relative to the original target as it was received.-  elidePats :: Pattern -> [Int] -> [Int] -> Pattern-  elidePats target path isibs' = elide' target path isibs-   where-    isibs = sortBy comp isibs'  -- questionable solution-     where comp x1 x2 = compare x1 x2-    -- (See comment in splicePats.)-    elide' :: Pattern -> [Int] -> [Int] -> Pattern-    elide' (Node pas cs) [] isibs  -- end of path chain-     | maximum isibs >= ncs  = error "elidePats: elision indices (0-based) must be\nless than the number of children"-     | or $ map (<(-1)) isibs  = error "elidePats: elision indices must be non-negative or -1"----  | or $ map (<0) isibs  = error "elidePats: elision indices must be non-negative"-     | otherwise  = {-trace "**1**" $-} Node pas $ f 0 cs isibs_-     where-      ncs = length cs-      -- XXX I'm trying to remember why had isibs of -1 as special.-      -- (They're now filtered upstream of here in any case.)-      isibs_ = let lst = takeWhile (== -1) isibs in-               drop (length lst) isibs ++ map (\ x -> (-1+ncs)) lst-      f n cs [] = cs-      f n [] isibs_remaining = error $ "elidePats: (3) path escapes target: " ++ show isibs_remaining  -- shouldn't happen-      f n lst1@(c:cs) lst2@(i:iss)----    | trace ("**3**"++show lst1++" "++show lst2) False  = undefined-       | ii == n    =     f (1+n) cs ss'-       | otherwise  = c : f (1+n) cs lst2-       where (ss,ss') = span (\ i -> i == n) lst2-             ii = i---           ii = if i < 0 then ncs-(-i) else i-    elide' (Node pas cs) (i:is) isibs----  | trace ("**4** "++show i++" / "++show cs++" / "++show pathcs) False  = undefined-     | null cs  = error "elidePats: path escapes target (depth)"-     | length cs < 1+i  = error "elidePats: path escapes target (breadth)"-     | null ccsR  = error "elidePats: (2) path escapes target (depth)"-     | otherwise  = {-trace "**2**" $-} Node pas (csL ++ [elide' c is isibs] ++ csR)-     where-      (c:csR) = ccsR-      (csL,ccsR) = splitAt i cs-----------------------------------------------------------------------------------  -- | Select a leaf at random, and elide it.-  -- In order to achieve fairness, the node probabilities are-  -- weighted by nodes in branch.-  -- The path arg can "focus" the stochastic erosion to only-  -- consider leaves beneath a given node.-{--}--- XXX Later: I don't understand. When would you want to--- allow the number of children at a node to change (except--- possibly to zero)?... Question applies also to splicePats--- and to elidePats.--- XXX It would be better if the weighting could be done once,--- then maintained, but will have to see how it performs...--- XXX Hey! This doesn't even need to call elidePats.--- XXX Later: It would be nice if this could call shrinkPat--- (or equivalent) on the leaves finally selected, so they--- decrease forcing at finer granularity, eg. *3 -> *2 (not *3 -> #--- or rather outright elided ... this is a different process though;--- need to decide whether you want to let that arity change or not...)-  erodePat :: StdGen -> [Int] -> Pattern -> (Pattern, StdGen)-  -- Just descend the path, reconstructing recursively (usual thing),-  -- and when get to the node addressed by path, then choose (fair) your-  -- leaf under that.-  erodePat g (h:t) (Node pas chs)-   = ( Node pas $ left ++ [ ch'' ] ++ right , g' )-   where-    ch'' = ch'---  ch'' = (\ (Node (r,pas) chs) -> Node r chs) ch'-    (ch',g') = erodePat g t lucky-    (left,lucky:right) = splitAt h chs-  erodePat g [] pat = (pat', g')---erodePat g [] pat = trace (showRose wpat ++ "\n" ++ showRose (weightedRose pat)) $ (pat', g')-   where-    pat' = fst $ unzipRose wpat'-    !_ = probDensRose pat---  !_ = force $ probDensRose pat-    (wpat', g') = f g wpat---  !wpat@(Node pas chs) = probDensRose pat-    wpat@(Node pas chs) = probDensRose pat-    f :: StdGen -> Rose (PatNode,Double) -> (Rose (PatNode,Double), StdGen)-    f g (Node pas chs)-     | isNothing mh  = ( Node pas chs, g )  -- ??-     | null chs   = ( Node pas [], g )----  | null chs   = ( Node pas [], g'' )-     | null gchs  = ( Node pas $ left ++ [ Node (WI emptyPatNodeAttrs,1.0) [] ] ++ right , g'' )----  | null gchs  = ( Node pas $ left ++ right , g'' )-     | otherwise  = ( Node pas $ left ++ [ ch' ] ++ right , g'' )-     where--- XXX I see; I have a logic error.--- Cyclical definition.--- null gchs--- but gchs depends on lucky--- and lucky depends on ... [?]-      (Node _ gchs) = lucky-      (ch',g'') = f g' lucky-      chprobs = map (\ (Node (_,pas) _) -> pas) chs-      mh = lucky_child 0 0.0 chprobs-#if 1-      h = fromJust mh-#else-      h | isNothing mh  = error "UNEXPECTED!"  -- definitely get here-        | otherwise     = fromJust mh-#endif-      (left,lucky:right) = splitAt h chs---    !_ = trace ("r=" ++ show r) $ ()---    (r,g') = trace "HERE!" $ randomR (0,1) g-      (r,g') = randomR (0,1) g-      lucky_child :: Int -> Double -> [Double] -> Maybe Int-      lucky_child idx acc [] = Nothing-      lucky_child idx acc (cp:cps)----    | trace (" >>> " ++ show acc ++ "  " ++ show acc') $ False = undefined-       | acc' >= r   = Just idx-       | otherwise  = lucky_child (1+idx) acc' cps-       where-        acc' = acc + cp-----------------------------------------------------------------------------------  -- See the sai-shape-syb package for an API full of this sort of thing.--#if ! HASKELL98_FRAGMENT-  type Shape = Rose ()-  shapeOf :: forall d. Data d => d -> Shape-  shapeOf = ghom $ const ()-  ghom :: forall r d. Data d => GenericQ r -> d -> Rose r-  ghom f x = foldl k b (gmapQ (ghom f) x)-   where-     b = Node (f x) []-     k (Node r chs) nod = Node r (chs++[nod])-#endif--  probDensRose :: Rose r -> Rose (r, Double)-  probDensRose = probDensRose' 1.0 . weightedRose-  probDensRose' :: Double -> Rose (r, Int) -> Rose (r, Double)---probDensRose' p (Node (r,w) []) = Node (r,p) []  -- (helps avoid div-by-zero)-  probDensRose' p (Node (r,w) chs)-   = Node (r,p) $ zipWith probDensRose' chprobs chs-   where-    chwts   = map (\ (Node (_,w) _) -> w) chs-    chwtsum = foldl' (+) 0 chwts-    normfac = 1 / fromIntegral chwtsum---- !_ = trace (" *** " ++ show chprobs)-    chprobs = map (\ (Node (_,w) _) -> normfac * (fromIntegral w)) chs--  weightedRose :: Rose r -> Rose (r, Int)-  weightedRose (Node r chs) = foldl k' b (map weightedRose chs)-   where-     k = (\ (r,w) (r',w') -> (r,w+w'))-     b = Node (r,1) []-     k' (Node rw chs) nod@(Node rw' _) = Node (rw `k` rw') (chs++[nod])--  unzipRose :: Rose (r, s) -> (Rose r, Rose s)-  unzipRose (Node (x,y) ns) = (Node x xns, Node y yns)-   where-    (xns,yns) = unzip $ map unzipRose ns--  showRose :: Show r => Rose r -> String-  showRose = show' 0-   where show' n (Node r chs)-           = indent n ++ show r ++ "\n" ++ concatMap (show' (1+n)) chs-              where indent n = concat $ replicate n "| "----------------------------------------------------------------------------------
− src/Control/DeepSeq/Bounded/PatUtil_old_grammar.hs
@@ -1,717 +0,0 @@-----------------------------------------------------------------------------------  {-  LANGUAGE CPP #-}--#define SHRINK_TO_EMPTY_WR 1---- Temporarily for compatibility of seqaid demo output--- with documents already written.-#define PROVIDE_OLD_SHRINK_PAT 1---- As for intersection, if the arities differ, the node--- effectively becomes non-recursive.  (Whether this is--- theoretically the best choice is still uncertain.)--- What is certain is, unless support richer Pattern's,--- a union of two recursive Pattern nodes with differing--- arities is not well-definable.---   The reason this switch exists at all is, it can--- be expensive to compute this predicate, especially--- considering that recursive nodes are very common,--- with WR being ("in the average case") the single most--- abundant node type in a pattern, probably followed--- in order by WS, WI, WW, WN (or parallel counterparts).-#define ENFORCE_SAME_ARITY_UNION 1--#define DO_TRACE 0---- Now specified via --flag=[-]USE_WWW_DEEPSEQ---- #define USE_WW_DEEPSEQ 1-----------------------------------------------------------------------------------  -- XXX For debugging only!-  {-# LANGUAGE BangPatterns #-}--  {-# LANGUAGE Rank2Types #-}-  {-  LANGUAGE ScopedTypeVariables #-}------------------------------------------------------------------------------------- |--- Module      :  Control.DeepSeq.Bounded.PatUtil_old_grammar--- Copyright   :  Andrew G. Seniuk 2014-2015--- License     :  BSD-style (see the file LICENSE)------ Maintainer  :  Andrew Seniuk <rasfar@gmail.com>--- Stability   :  provisional--- Portability :  portable, except mkPat, mkPatN and growPat (which use SYB)--------------------------------------------------------------------------------------  module Control.DeepSeq.Bounded.PatUtil_old_grammar-  where-----------------------------------------------------------------------------------  import Control.DeepSeq.Bounded.Pattern--  import Data.Maybe ( isNothing, fromJust )--#if ! HASKELL98_FRAGMENT-  import Data.Data ( Data )-  import Data.Generics ( GenericQ )-  import Data.Generics ( gmapQ )-#endif--  import Data.List ( findIndex )---import Data.List ( elemIndex )-  import Data.List ( sortBy )---import Data.List ( nub )-  import Data.List ( foldl' )-  import Data.List ( group )-  import Data.List ( sort )-  import Data.List ( intersect )--  import System.Random--  import Debug.Trace ( trace )-  import Control.DeepSeq ( force )-----------------------------------------------------------------------------------#if DO_TRACE-  mytrace = trace-#else-  mytrace _ = id-#endif-----------------------------------------------------------------------------------  -- | Compute the union of a list of 'Pattern's.-  unionPats :: [ Pattern ] -> Pattern-  unionPats [] = Node WI []  -- or what?---unionPats [] = Nil  -- or what?-  unionPats ps = foldr1 (union' False) ps---unionPats ps = foldr1 union' $ trace (">> " ++ show ps) $ ps---unionPats = foldr union' Nil-  union' :: Bool -> Pattern -> Pattern -> Pattern-#if 1-  union' _ (Node WI _) (Node WI _) = Node WI []-  union' _ p          (Node WI _) = p-  union' _ (Node WI _) p          = p-#else-  union' _ Nil Nil = {-trace "NilNil" $-} Nil  -- case not needed (caught by either of the next two!)-#if 0-  -- XXX Later: It is going to work out better if take the-  -- very opposite convention. That is consistent with-  -- how composition behaves when # is involved.-  -- This says # trumps any other pattern node. This is the only-  -- sensible resolution it seems to me, but sadly it breaks every-  -- law I've penned for NFDataP...-  union' _ p   Nil = {-trace ("pNil "++show p) $-} Nil-  union' _ Nil p   = {-trace ("Nilp "++show p) $-} Nil-#else-  -- This makes for less interesting composites perhaps, where # is-  -- involved, but at least it is consistent with non-fused composition.-  union' _ p   Nil = p-  union' _ Nil p   = p-#endif-#endif-  -- Symmetric cases:-  union' b node1@(Node p1 cs1) node2@(Node p2 cs2)-   -- XXX Those cases using zipWith are not correct,-   -- unless length cs1 == length cs2.  But one hates to-   -- have to compute that. Caveat Emptor! This will behave-   -- as a true union operator only if the child pattern lists-   -- are compatibly-sized!-   --   In seqaid (and in /correct/ manual use), this problem-   -- will never arise.-#if 0-   -- XXX Don't do it -- (==) on PatNode might be more expensive-   -- than I think, some nodes have list parameters...-   | p1 == p2           = Node p1 $ zipWith (union' b) cs1 cs2-#endif-#if ENFORCE_SAME_ARITY_UNION-   | WR <- p1, WR <- p2 = {-trace "WRWR" $-}-      if csokay then Node WR $ zipWith (union' False) cs1 cs2-      else error "unionPat: WRWR: encountered arity disparity!"-#else-   | WR <- p1, WR <- p2 = {-trace "WRWR" $-} Node WR $ zipWith (union' False) cs1 cs2-#endif-   | WS <- p1, WS <- p2 = {-trace "WSWS" $-} Node WS []-#if USE_WW_DEEPSEQ-   | WW <- p1, WW <- p2 = {-trace "WWWW" $-} Node WW []-#endif-#if ENFORCE_SAME_ARITY_UNION-   | TR tys1 <- p1, TR tys2 <- p2 = {-trace "TRTR" $-}-      if csokay then Node (TR (unionTys tys1 tys2)) $ zipWith (union' False) cs1 cs2-      else error "unionPat: TRTR: encountered arity disparity!"-   | TI tys1 <- p1, TI tys2 <- p2 = {-trace "TITI" $-}-      if csokay then Node (TI (intersectTys tys1 tys2)) $ zipWith (union' False) cs1 cs2-      else error "unionPat: TITI: encountered arity disparity!"-#else-   | TR tys1 <- p1, TR tys2 <- p2-      = {-trace "TRTR" $-} Node (TR (unionTys tys1 tys2)) $ zipWith (union' False) cs1 cs2-   | TI tys1 <- p1, TI tys2 <- p2-      = {-trace "TITI" $-} Node (TI (intersectTys tys1 tys2)) $ zipWith (union' False) cs1 cs2---- | TR cls1 tys1 cns1 <- p1, TR cls2 tys2 cns2 <- p2---    = {-trace "TRWR" $-} Node (TR (cls1++cls2) (tys1++tys2) (cns1++cns2)) $ zipWith union' cs1 cs2-#endif---- | ...-   where  -- (yes where's can be empty)-#if ENFORCE_SAME_ARITY_UNION-    csokay = length cs1 == length cs2  -- ouch-#endif-  -- Now the asymmetric cases:-  union' b node1@(Node p1 cs1) node2@(Node p2 cs2)-   -- XXX Those cases using zipWith are not correct,-   -- unless length cs1 == length cs2.  But one hates to-   -- have to compute that. Caveat Emptor! This will behave-   -- as a true union operator only if the child pattern lists-   -- are compatibly-sized!-   --   Actually, if zipWith (which is acting on two [Pattern];-   -- you could supply union-unit pattern for missing children-   -- in shorter list, but then which children exactly were missing?-   -- So rather than play such a game without a racket, we just-   -- require the lists to be the same length or all bets are off.-   --   In seqaid, this problem will never arise.-   -- And in /correct/ manual use...-   | WR <- p1, WS <- p2 = {-trace "WRWS" $-} Node WR cs1-#if USE_WW_DEEPSEQ-   | WR <- p1, WW <- p2 = {-trace "WRWW" $-} Node WW []-#endif-#if USE_WW_DEEPSEQ-   | WS <- p1, WW <- p2 = {-trace "WSWW" $-} Node WW []-#endif-#if ENFORCE_SAME_ARITY_UNION-   | TR _ <- p1, WR <- p2 = {-trace "TRWR" $-}-      if csokay then node1-      else error $ "unionPat: " ++ if b then "WRTR" else "TRWR" ++ ": encountered arity disparity!"-#else-   | TR _ <- p1, WR <- p2 = {-trace "TRWR" $-} node1-#endif-   | TR _ <- p1, WS <- p2 = {-trace "TRWS" $-} node1-#if USE_WW_DEEPSEQ-   | TR _ <- p1, WW <- p2 = {-trace "TRWW" $-} node2-#endif-#if ENFORCE_SAME_ARITY_UNION-   | TI _ <- p1, WR <- p2 = {-trace "TIWR" $-}-      if csokay then node2-      else error $ "unionPat: " ++ if b then "WRTI" else "TIWR" ++ ": encountered arity disparity!"-#else-   | TI _ <- p1, WR <- p2 = {-trace "TIWR" $-} node2-#endif-   | TI _ <- p1, WS <- p2 = {-trace "TIWS" $-} node2-#if USE_WW_DEEPSEQ-   | TI _ <- p1, WW <- p2 = {-trace "TIWW" $-} node2-#endif-#if 0-   | TS _ <- p1, WR <- p2 = {-trace "TSWR" $-} node2-   | TS _ <- p1, WS <- p2 = {-trace "TSWS" $-} node2-   | TS _ <- p1, WW <- p2 = {-trace "TSWW" $-} node2-#endif-#if USE_WW_DEEPSEQ-   | TW _ <- p1, WR <- p2 = {-trace "TWWR" $-} node1-   | TW _ <- p1, WS <- p2 = {-trace "TWWS" $-} node1-   | TW _ <- p1, WW <- p2 = {-trace "TWWW" $-} node2-#endif-#if ENFORCE_SAME_ARITY_UNION-   | TI tys1 <- p1, TR tys2 <- p2 = {-trace "TITR" $-}-      if csokay then Node (TR (tys1++tys2)) $ zipWith (union' False) cs1 cs2-      else error $ "unionPat: " ++ if b then "TRTI" else "TITR" ++ ": encountered arity disparity!"-#else-   | TI tys1 <- p1, TR tys2 <- p2-      = {-trace "TITR" $-} Node (TR (tys1++tys2)) $ zipWith (union' False) cs1 cs2-#endif---- | ...-   | not b = union' True node2 node1-   | otherwise = error "unionPats: unexpected failure to (Haskell) pattern-match arguments!"-   where  -- (yes where's can be empty)-#if ENFORCE_SAME_ARITY_UNION-    csokay = length cs1 == length cs2  -- ouch-#endif--#if 0-  -- | This (unionPatsStr) seems pretty silly?... (It is used in the tests though.)-  unionPatsStr :: [ String ] -> String-  unionPatsStr = showPat . unionPats . map compilePat-#endif-----------------------------------------------------------------------------------  -- Probably overkill for typical lengths.-  -- Would pay to special case for some short lists.-  -- Optimisations come later.--  unionTys :: [String] -> [String] -> [String]-  unionTys ss1 ss2 = nubsort $ ss1 ++ ss2--  nubsort :: Ord a => [a] -> [a]-  nubsort = map head . group . sort--  intersectTys :: [String] -> [String] -> [String]-  intersectTys ss1 ss2 = intersect (nubsort ss1) (nubsort ss2)-----------------------------------------------------------------------------------  -- | Return 'True' if the first pattern matches the second (and 'False' otherwise).-  ---  -- Note that matching does not imply spanning. Equality ('==') or @'flip' 'subPat'@ will work there, depending on your intentions.-  ---  -- XXX This doesn't yet handle type-constrained 'PatNode's-  -- ('TI', 'TR', 'TN' or 'TW'), because 'intersectPats' doesn't.-  subPat :: Pattern -> Pattern -> Bool-  subPat p pp = p == intersectPats [p, pp]  -- probably faster on avg.---subPat p pp = pp == unionPats [p, pp]-----------------------------------------------------------------------------------  -- | Compute the intersection of a list of 'Pattern's.-  ---  -- XXX This doesn't yet handle type-constrained 'PatNode's-  -- ('TI', 'TR', 'TN' or 'TW').-  intersectPats :: [ Pattern ] -> Pattern-  intersectPats [] = Node WI []  -- or what?-  intersectPats ps = foldr1 (intersection' False) ps-  intersection' :: Bool -> Pattern -> Pattern -> Pattern-  intersection' _ _           (Node WI _) = Node WI []-  intersection' _ (Node WI _) _           = Node WI []--- Note that chs1 == [] == chs2 (or at least is supposed to be),--- except for WR, PR and TR PatNode's.-  -- First check once for symmetric cases:-  intersection' b node1@(Node p1 cs1) node2@(Node p2 cs2)-#if 0-   -- XXX Don't do it -- (==) on PatNode might be more expensive-   -- than I think, some nodes have list parameters...-   -- (Could put this at top, allowing WN etc. to be accepted in many cases.)-   | p1 == p2      = Node p1 $ zipWith_ "intersection" (intersection' b) cs1 cs2-#endif-   | WS <- p1, WS <- p2  = node1-   | WR <- p1, WR <- p2  = let (b,zs) = zipWith_ "intersection" (intersection' b) cs1 cs2 in if b then Node WR zs else Node WS zs-   | WN n1 <- p1, WN n2 <- p2  = Node (WN (min n1 n2)) []-#if USE_WW_DEEPSEQ-#if PARALLELISM_EXPERIMENT-   | PW <- p1, PW <- p2  = node1-#endif-   | WW <- p1, WW <- p2  = node1-#endif-#if PARALLELISM_EXPERIMENT-   | PR <- p1, PR <- p2   = let (b,zs) = zipWith_ "intersection" (intersection' b) cs1 cs2 in if b then Node PR zs else Node WS zs-   | PN n1 <- p1, PN n2 <- p2  = Node (PN (min n1 n2)) []-#endif-  -- Now the asymmetric cases:-  intersection' b node1@(Node p1 cs1) node2@(Node p2 cs2)-   | WR <- p1, WS <- p2  = node2-#if USE_WW_DEEPSEQ-#if PARALLELISM_EXPERIMENT-   | PW <- p1  = node2-#endif-   | WW <- p1  = node2-#endif-   | WR <- p1, WN n2 <- p2  = truncatePat n2 node1-#if PARALLELISM_EXPERIMENT-   | PR <- p1, PN n2 <- p2  = truncatePat n2 node1-#endif-   | TI   _ <- p1  = error "intersectPats: can't handle TI PatNode's yet"-   | TR   _ <- p1  = error "intersectPats: can't handle TR PatNode's yet"-   | TN _ _ <- p1  = error "intersectPats: can't handle TN PatNode's yet"-#if USE_WW_DEEPSEQ-   | TW   _ <- p1  = error "intersectPats: can't handle TW PatNode's yet"-#endif-   | not b               = intersection' True node2 node1-   | otherwise = Node WI []---- | otherwise = error "intersectPats: unexpected failure to (Haskell) pattern-match arguments!"-----------------------------------------------------------------------------------  zipWith_ :: String -> (a -> b -> c) -> [a] -> [b] -> (Bool,[c])-  zipWith_ caller f xs ys-   | b          = (b,zs)-   | otherwise  = trace (caller ++ ": node arity disparity!") (b,zs)-   where-    (b,zs) = zipWith_' f xs ys []-  zipWith_' :: (a -> b -> c) -> [a] -> [b] -> [c] -> (Bool,[c])-  zipWith_' _ [] [] acc = (True,acc)-  zipWith_' f (x:xs) (y:ys) acc = zipWith_' f xs ys (f x y : acc)-  zipWith_' _ _ _ acc = (False,acc)-----------------------------------------------------------------------------------  -- | Given an integer depth and a pattern, truncate the pattern to-  -- extend to at most this requested depth.-  truncatePat :: Int -> Pattern -> Pattern-  truncatePat n node-   | n <= 0              = Node WS []-   | Node p chs <- node  = Node p $ map (truncatePat (-1+n)) chs-----------------------------------------------------------------------------------  -- | There is no Nil in the Pattern type, but a single 'WI' node as-  -- empty pattern is a dependable way to assure the empty pattern-  -- never forces anything.-  emptyPat :: Pattern-  emptyPat = Node WI []  -- should do it!-----------------------------------------------------------------------------------#if ! HASKELL98_FRAGMENT-  -- | Obtain a lazy pattern, matching the shape of-  -- an arbitrary term (value expression).-  -- Interior nodes will be 'WR', and leaves will be 'WS'.-  ---  -- Note this gives counter-intuitive results when used on @'Rose' a@.-  -- For example, a rose tree with a single node will have a 3-node /\\ shape.)-  -- Formally, 'mkPat' is not idempotent on 'Pattern's, but-  -- rather grows without bound when iterated. This shouldn't be-  -- an issue in practise.-  mkPat :: forall d. Data d => d -> Pattern-  mkPat = f . shapeOf-   where f (Node p cs) = Node (if null cs then WS else WR) $ map f cs---mkPat x = fmap (\ (Node p cs) -> if null cs then WS else WR) $ shapeOf x---mkPat x = (\ (Node p cs) -> if null cs then WS else WR) <$> shapeOf x---mkPat x = WR <$ shapeOf x--  -- | Obtain a lazy pattern, matching the shape of-  -- an arbitrary term, but only down to at most depth @n@.-  -- Interior nodes will be 'WR'.-  -- Leaf nodes will be 'WS' if they were leaves in the host value;-  -- otherwise (i.e. if they are at depth @n@) they will be 'WR'.-  ---  -- Satisfies @'forcep' . 'mkPatN' n = 'forcen' n@.-  ---  -- See caveat in the comment to 'mkPat'.-  mkPatN :: forall d. Data d => Int -> d -> Pattern-  mkPatN n = f n . shapeOf-   where-    f 0 (Node p cs) = Node (if null cs then WS else WR) []-    f n (Node p cs) = Node (if null cs then WS else WR) $ map (f (-1+n)) cs-#endif-----------------------------------------------------------------------------------  -- | Elide all leaves which have no non-leaf sibling.-  -- We want the pattern to still match the same value, only less of it.-  -- Merely eliding all leaves would, in most cases, cause match failure,-  -- so we have to be a bit more subtle.  There are some arbitrary-  -- decisions about the relaxation route through the lattice.-  -- (Refer to the source for details.)-  shrinkPat :: Pattern -> Pattern-  shrinkPat (Node p cs)-   | WI <- p  = Node WI []  -- can't shrink (eventually elided from parent)-   | WS <- p  = Node WI []  -- may as well-   | WN n <- p  = if n <= 1 then Node WI []-                  else if n == 2 then Node WS []-                  else Node (WN (-1+n)) []-#if USE_WW_DEEPSEQ-   | WW <- p  = Node (WN 5) []  -- XXX arbitrary hardcode-#endif-#if PARALLELISM_EXPERIMENT-   -- take de-parallelisation as shrinkage-   | PR <- p  = Node WR cs-   | PN n <- p  = Node (WN n) []-#if USE_WW_DEEPSEQ-   | PW <- p  = Node WW []-#endif-#endif-   -- take un-type-constrained as shrinkage-   | TI _ <- p  = Node WI []-   | TR _ <- p  = Node WR cs-   | TN n _ <- p  = Node (WN n) []-#if USE_WW_DEEPSEQ-   | TW _ <- p  = Node WW []-#endif-#if SHRINK_TO_EMPTY_WR-   | WR <- p , null cs  = Node WI []-#endif-   -- If this node has any grandchildren, recurse on the children.-   | not $ null $ filter (\ (Node q gcs) -> not $ null gcs) cs-      = Node p $ map shrinkPat cs-   -- At this point we know this node has no grandchildren.-   -- Check if all children are insulator nodes.-   | null $ filter (\ (Node p _) -> case p of { WI -> False ; _ -> True}) cs-      = case p of-         -- Must go to WI, since .{##} -> . is /not/ a lazification.-#if SHRINK_TO_EMPTY_WR-         WR -> Node WR []-#else-         WR -> Node WI []-#endif-#if PARALLELISM_EXPERIMENT-         PR -> Node WI []  -- sic-#endif-         TR _ -> Node WI []  -- sic-         _ -> error "shrinkPat: unexpected!"-   | otherwise-      = Node p $ map shrinkPat cs  -- still contains shrinkable children--#if 0-  canonicalisePostShrinkPat :: Pattern -> Pattern-  canonicalisePostShrinkPat nod@(Node p cs)-   | null $ filter (/= Node WI []) cs  = nod-   | otherwise                         = Node WI []-#endif-----------------------------------------------------------------------------------#if PROVIDE_OLD_SHRINK_PAT-  -- | Old version, for temporary compatibility of seqaid demo mode.-  {-  DEPRECATED shrinkPat_old "For temporary compatibility of seqaid demo mode." #-}-  -- (Deprecation warning too noisy for me. Nobody will use this by accident.)-  shrinkPat_old :: Pattern -> Pattern-  shrinkPat_old (Node p cs)-   | not $ null $ filter (\ (Node q gcs) -> not $ null gcs) cs  = Node p $ map shrinkPat_old cs-   | WR <- p  = Node WS []-   | otherwise  = Node p []-#endif-----------------------------------------------------------------------------------#if ! HASKELL98_FRAGMENT-  -- | Grow all leaves by one level within the shape of the provided value.-  growPat :: forall d. Data d => Pattern -> d -> Pattern-  growPat pat x = growPat' pat $ shapeOf x-  growPat' :: Pattern -> Shape -> Pattern-  growPat' (Node p []) (Node q ds) = Node p $ map (const (Node WS [])) ds-  growPat' (Node p cs) (Node q ds) = Node p $ zipWith growPat' cs ds-#endif-----------------------------------------------------------------------------------  -- | This creates a new 'WR' node, the common root. The argument patterns-  -- become the children of the root (order is preserved).-  liftPats :: [ Pattern ] -> Pattern-  liftPats ps = Node WR ps-----------------------------------------------------------------------------------  -- | Introduce siblings at a node (interior or leaf) of the target.-  -- The first argument is target, the second is a path, and the-  -- third is a list of subpatterns for insertion, along with the-  -- indices of the child before which to insert. If this index-  -- is negative, it counts from the right. Indices are always-  -- relative to the original target as it was received.-{--}--- XXX Later: I don't understand. When would you use this?--- You change the number of children at a node, which seems--- unuseful. More reasonable than insertion would be to replace--- select children with a new subpatterns.-  splicePats :: Pattern -> [Int] -> [ (Int, Pattern) ] -> Pattern-  splicePats target path isibs'---- | isibs /= isibs'    = error "splicePats: siblings to be inserted must be indexed in increasing order"---- | not uniqueIdxs     = error "splicePats: siblings to be inserted must be uniquely indexed"---- | not $ isPath path  = error "splicePats: path malformed"-   | otherwise          = splice' target path isibs-   where---  uniqueIdxs = length isibs == ( length $ nub $ map fst isibs )-    isibs = sortBy comp isibs'  -- questionable solution-     where-      comp (x1,_) (x2,_) = compare x1 x2-    -- Now, what's the clever way to do this? it's ugly manual-    -- recursion if don't think of something nicer. (This is-    -- the ugly manual recursion!)-    splice' (Node p cs) [] isibs  -- end of path chain-     | maximum (map fst isibs) > ncs  = error "splicePats: sibling indices must not exceed the number of existing children"-     | otherwise  = {-trace "**1**" $-} Node p $ f 0 cs isibs_-     where-      ncs = length cs-      isibs_ = let lst = takeWhile ((== -1) . fst) isibs in-               drop (length lst) isibs ++ map (\ (x,y) -> (ncs,y)) lst-      f n cs [] = cs-      f n [] isibs_remaining = map snd isibs_remaining---    f n [] isibs_remaining = error $ "splicePats: (2) path escapes target: " ++ show isibs_remaining  -- shouldn't happen-      f n lst1@(c:cs) lst2@((i,s):iss)----    | trace ("**3**"++show lst1++" "++show lst2) False  = undefined-       | ii == n    = map snd ss ++ (c : f (1+n) cs ss')-       | otherwise  =                c : f (1+n) cs lst2-       where (ss,ss') = span (\ (i,s) -> i == n) lst2-             ii = if i < 0 then ncs-(-i) else i-    splice' (Node p cs) (i:is) isibs----  | trace ("**4** "++show i++" / "++show cs++" / "++show pathcs) False  = undefined-     | null cs  = error "splicePats: path escapes target (depth)"-     | length cs < 1+i  = error "splicePats: path escapes target (breadth)"-     | null ccsR  = error "splicePats: (2) path escapes target (depth)"-     | otherwise  = {-trace "**2**" $-} Node p (csL ++ [splice' c is isibs] ++ csR)-     where-      (c:csR) = ccsR-      (csL,ccsR) = splitAt i cs-----------------------------------------------------------------------------------  -- | Elide siblings at a node (interior or leaf) of the target.-  -- The first argument is target, the second is a path, and the-  -- third is a list of child indices for elision.-  -- If this index is negative, it counts from the right.-  -- Indices are always relative to the original target as it was received.-{--}--- XXX Later: I don't understand. When would you want to--- change the number of children at a node (except possibly--- to zero)?...--- XXX This is templated from splicePats, and it seems more useful--- for it to just take a single path, or a list of paths; it doesn't--- really make sense to support multiple sibling elision in single pass.--- XXX Yes, change that! Let it take a list of paths instead.-  elidePats :: Pattern -> [Int] -> [Int] -> Pattern-  elidePats target path isibs'-   | otherwise          = elide' target path isibs-   where-    isibs = sortBy comp isibs'  -- questionable solution-     where-      comp x1 x2 = compare x1 x2-    -- (See comment in elidePats.)-    elide' (Node p cs) [] isibs  -- end of path chain-     | maximum isibs > ncs  = error "elidePats: sibling indices must not exceed the number of existing children"-     | otherwise  = {-trace "**1**" $-} Node p $ f 0 cs isibs_-     where-      ncs = length cs-      isibs_ = let lst = takeWhile (== -1) isibs in-               drop (length lst) isibs ++ map (\ x -> ncs) lst-      f n cs [] = cs-      f n [] isibs_remaining = error $ "elidePats: (2) path escapes target: " ++ show isibs_remaining  -- shouldn't happen-      f n lst1@(c:cs) lst2@(i:iss)----    | trace ("**3**"++show lst1++" "++show lst2) False  = undefined-       | ii == n    =     f (1+n) cs ss'-       | otherwise  = c : f (1+n) cs lst2-       where (ss,ss') = span (\ i -> i == n) lst2-             ii = if i < 0 then ncs-(-i) else i-    elide' (Node p cs) (i:is) isibs----  | trace ("**4** "++show i++" / "++show cs++" / "++show pathcs) False  = undefined-     | null cs  = error "elidePats: path escapes target (depth)"-     | length cs < 1+i  = error "elidePats: path escapes target (breadth)"-     | null ccsR  = error "elidePats: (2) path escapes target (depth)"-     | otherwise  = {-trace "**2**" $-} Node p (csL ++ [elide' c is isibs] ++ csR)-     where-      (c:csR) = ccsR-      (csL,ccsR) = splitAt i cs-----------------------------------------------------------------------------------  -- | Select a leaf at random, and elide it.-  -- In order to achieve fairness, the node probabilities are-  -- weighted by nodes in branch.-  -- The path arg can "focus" the stochastic erosion to only-  -- consider leaves beneath a given node.-{--}--- XXX Later: I don't understand. When would you want to--- allow the number of children at a node to change (except--- possibly to zero)?...--- XXX It would be better if the weighting could be done once,--- then maintained, but will have to see how it performs...--- XXX It is lamentable that the change history of this function--- along with the GHC error messages (notably the topmost of them)--- is lost, since stuff like this would make exellent input--- to compiler AI (for improving prioritisation of error--- messages for example; the "lexical tradition" is also--- at work here!...).--- XXX Hey! This doesn't even need to call elidePats.--- XXX Later: It would be nice if this could call shrinkPat--- (or equivalent) on the leaves finally selected, so they--- decrease forcing at finer granularity, eg. *3 -> *2 (not *3 -> #--- or rather outright elided ... this is a different process though;--- need to decide whether you want to let that arity change or not...)-  erodePat :: StdGen -> [Int] -> Pattern -> (Pattern, StdGen)-  -- Just descend the path, reconstructing recursively (usual thing),-  -- and when get to the node addressed by path, then choose (fair) your-  -- leaf under that.-  erodePat g (h:t) (Node pn chs)-   = ( Node pn $ left ++ [ ch'' ] ++ right , g' )-   where-    ch'' = ch'---  ch'' = (\ (Node (r,p) chs) -> Node r chs) ch'-    (ch',g') = erodePat g t lucky-    (left,lucky:right) = splitAt h chs-  erodePat g [] pat = (pat', g')---erodePat g [] pat = trace (showRose wpat ++ "\n" ++ showRose (weightedRose pat)) $ (pat', g')-   where-    pat' = fst $ unzipRose wpat'-    !_ = probDensRose pat---  !_ = force $ probDensRose pat-    (wpat', g') = f g wpat---  !wpat@(Node pn chs) = probDensRose pat-    wpat@(Node pn chs) = probDensRose pat-    f :: StdGen -> Rose (PatNode,Double) -> (Rose (PatNode,Double), StdGen)-    f g (Node pn chs)-     | isNothing mh  = ( Node pn chs, g )  -- ??-     | null chs   = ( Node pn [], g )----  | null chs   = ( Node pn [], g'' )-     | null gchs  = ( Node pn $ left ++ [ Node (WI,1.0) [] ] ++ right , g'' )----  | null gchs  = ( Node pn $ left ++ right , g'' )-     | otherwise  = ( Node pn $ left ++ [ ch' ] ++ right , g'' )-     where--- XXX I see; I have a logic error.--- Cyclical definition.--- null gchs--- but gchs depends on lucky--- and lucky depends on ... [?]-      (Node _ gchs) = lucky-      (ch',g'') = f g' lucky-      chprobs = map (\ (Node (_,p) _) -> p) chs-      mh = lucky_child 0 0.0 chprobs-#if 1-      h = fromJust mh-#else-      h | isNothing mh  = error "UNEXPECTED!"  -- definitely get here-        | otherwise     = fromJust mh-#endif-      (left,lucky:right) = splitAt h chs---    !_ = trace ("r=" ++ show r) $ ()---    (r,g') = trace "HERE!" $ randomR (0,1) g-      (r,g') = randomR (0,1) g-      lucky_child :: Int -> Double -> [Double] -> Maybe Int-      lucky_child idx acc [] = Nothing-      lucky_child idx acc (cp:cps)----    | trace (" >>> " ++ show acc ++ "  " ++ show acc') $ False = undefined-       | acc' >= r   = Just idx-       | otherwise  = lucky_child (1+idx) acc' cps-       where-        acc' = acc + cp-----------------------------------------------------------------------------------  -- See the sai-shape-syb package for an API full of this sort of thing.--#if ! HASKELL98_FRAGMENT-  type Shape = Rose ()-  shapeOf :: forall d. Data d => d -> Shape-  shapeOf = ghom $ const ()-  ghom :: forall r d. Data d => GenericQ r -> d -> Rose r-  ghom f x = foldl k b (gmapQ (ghom f) x)-   where-     b = Node (f x) []-     k (Node r chs) nod = Node r (chs++[nod])-#endif--  probDensRose :: Rose r -> Rose (r, Double)-  probDensRose = probDensRose' 1.0 . weightedRose-  probDensRose' :: Double -> Rose (r, Int) -> Rose (r, Double)---probDensRose' p (Node (r,w) []) = Node (r,p) []  -- (helps avoid div-by-zero)-  probDensRose' p (Node (r,w) chs)-   = Node (r,p) $ zipWith probDensRose' chprobs chs-   where-    chwts   = map (\ (Node (_,w) _) -> w) chs-    chwtsum = foldl' (+) 0 chwts-    normfac = 1 / fromIntegral chwtsum---- !_ = trace (" *** " ++ show chprobs)-    chprobs = map (\ (Node (_,w) _) -> normfac * (fromIntegral w)) chs--  weightedRose :: Rose r -> Rose (r, Int)-  weightedRose (Node r chs) = foldl k' b (map weightedRose chs)-   where-     k = (\ (r,w) (r',w') -> (r,w+w'))-     b = Node (r,1) []-     k' (Node rw chs) nod@(Node rw' _) = Node (rw `k` rw') (chs++[nod])--  unzipRose :: Rose (r, s) -> (Rose r, Rose s)-  unzipRose (Node (x,y) ns) = (Node x xns, Node y yns)-   where-    (xns,yns) = unzip $ map unzipRose ns--  showRose :: Show r => Rose r -> String-  showRose = show' 0-   where show' n (Node r chs)-           = indent n ++ show r ++ "\n" ++ concatMap (show' (1+n)) chs-              where indent n = concat $ replicate n "| "----------------------------------------------------------------------------------
src/Control/DeepSeq/Bounded/Pattern.hs view
@@ -3,8 +3,76 @@    {-  LANGUAGE CPP #-} +#define DO_TRACE 0++#define USE_POST_ORDER_IDS 0++#define SHOW_PAT_NODE_ATTRS 0++#define WARN_IGNORED_SUBPATTERNS 1+#define NEVER_IGNORE_SUBPATTERNS 0++-- Formerly DEBUG_WITH_DEEPSEQ_GENERICS.+-- Now also needed to force issuance of all compilePat warnings+-- (so not strictly a debugging flag anymore).+-- [Except it didn't work...]+--- #define NFDATA_INSTANCE_PATTERN 0  -- now a .cabal flag++#define DO_DERIVE_DATA_AND_TYPEABLE 0+#define DO_DERIVE_ONLY_TYPEABLE 1+#if DO_DERIVE_ONLY_TYPEABLE && DO_DERIVE_DATA_AND_TYPEABLE+#undef DO_DERIVE_ONLY_TYPEABLE+#warning DO_DERIVE_ONLY_TYPEABLE forced 0, due to DO_DERIVE_DATA_AND_TYPEABLE being 1.+#define DO_DERIVE_ONLY_TYPEABLE 0+#endif++-- Now specified via --flag=[-]USE_WWW_DEEPSEQ+--- #define USE_WW_DEEPSEQ 1+ ------------------------------------------------------------------------------- +-- Good idea: Let * be followed by an integer N.+-- This shall have the semantics that, when that node+-- is matched in the pattern, instead of rnf it is forcen N'd.++-- There may be fusion possible (which is worth trying here+-- for practise, even if this lib is not used much):+--+--   forcep p1 . forcep p2 = forcep (unionPat [p1,p2])+--+-- This holds if pattern doesn't contain #, or any (type-)constrained+-- subpatterns -- the latter might work out, if exclude # from them too,+-- but I'm not sure.  With #, we lose even monotonicity, let alone+-- the above law.+--+-- For the above to hold, remember, the union must have exactly+-- the "forcing potential" of the LHS -- no more, no less.++-------------------------------------------------------------------------------++#if DO_DERIVE_DATA_AND_TYPEABLE+  {-# LANGUAGE DeriveDataTypeable #-}+#endif+-- XXX Only needed for something in Blah.hs.+-- Check into it, and see if can't get rid of the need+-- for Typeable instances in here!+#if DO_DERIVE_ONLY_TYPEABLE+  {-# LANGUAGE DeriveDataTypeable #-}+#endif++-- Prefer to hand-write the NFData instance, so that can+-- use it with HASKELL98_FRAGMENT.+#if 0+#if NFDATA_INSTANCE_PATTERN+  -- For testing only (controlling trace interleaving):+  {-# LANGUAGE DeriveGeneric #-}+#endif+#endif++  {-  LANGUAGE DeriveFunctor #-}++-------------------------------------------------------------------------------+ -- | -- Module      :  Control.DeepSeq.Bounded.Pattern -- Copyright   :  Andrew G. Seniuk 2014-2015@@ -17,16 +85,9 @@  ------------------------------------------------------------------------------- --- (Warning is issued by Pattern_old_grammar.hs.)---- #if ! NEW_IMPROVED_PATTERN_GRAMMAR---- #warning You are using the old pattern grammar (NEW_IMPROVED_PATTERN_GRAMMAR flag is False). This will be deprecated in version 0.7.---- #endif-   module Control.DeepSeq.Bounded.Pattern   ( -#if NEW_IMPROVED_PATTERN_GRAMMAR-      -- * Pattern datatype         Pattern@@ -177,120 +238,710 @@       , SeqNode(..) +  )+  where++-------------------------------------------------------------------------------++#if DO_DERIVE_DATA_AND_TYPEABLE+  import Data.Data ( Data )+  import Data.Typeable ( Typeable )+#elif DO_DERIVE_ONLY_TYPEABLE+  import Data.Typeable ( Typeable )+#endif++#if USE_WW_DEEPSEQ+  import Control.DeepSeq ( NFData )+#endif++  import Control.Concurrent ( ThreadId )++  import Data.List ( intercalate )+  import Data.Char ( isDigit )+  import Data.Maybe ( isNothing, fromJust )+  import Data.Maybe ( isJust )++  import Debug.Trace ( trace )++#if USE_WW_DEEPSEQ+  -- The only uses of force in this module are for debugging purposes+  -- (including trying to get messages to be displayed in a timely+  -- manner, although that problem has not been completely solved).+  import Control.DeepSeq ( force )+#endif++-- (Hand write this NFData instance for greater portability.)+#if NFDATA_INSTANCE_PATTERN+  -- for helping trace debugging+#if 1+  import Control.DeepSeq #else+  import qualified Control.DeepSeq.Generics as DSG+  import qualified GHC.Generics as GHC ( Generic )+#endif+#endif -     -- * Pattern datatype+  import Data.Char ( ord )+  import Data.Char ( chr ) -       Pattern-     , PatNode(..)+  import Control.Monad.State as ST ---   , patternShapeOK  -- useful for defining instances of NFDataP+------------------------------------------------------------------------------- -     -- * Pattern DSL+#if DO_TRACE+  mytrace = trace+#else+  mytrace _ = id+#endif -     -- | __Grammar__-     ---     -- @-     -- /pat/ /->/ /[/ __=__ /]/ __.__ /[/ __{__ /{/ /pat/ /}/ __}__ /]/-     --     /|/  /(/ /[/ __=__ /]/ __*__ /[/ /decimalint/ /]/ /|/ __#__ /)/-     --     /|/  __.:__ /ctorname/ /{/ /space/ /ctorname/ /}/ __{__ /[/ /{/ /pat/ /}/ /]/ __}__-     --     /|/  /(/ __*__ /[/ /decimalint/ /]/ /|/ __#__ /)/ __:__ /typename/ /{/ /space/ /typename/ /}/ __{}__-     -- /typename/ -> /string/-     -- /ctorname/ -> /string/-     -- /decimalint/ -> /digit string not beginning with zero/-     -- /space/ -> /space character ASCII 0x32/-     -- @-     ---     -- Here is the grammar in a more <http://fremissant.net/deepseq-bounded/grammar.html vivid rendering>.-     -- (The Haddock markup makes it almost tricky to distinguish between metasyntax and concrete syntax.)-     ---     -- __Examples__-     ---     -- @\".{...}\"@ will match any ternary constructor.-     ---     -- @'rnfp' \".{...}\" expr@ will force evaluation of @expr@ to a depth of two,-     -- provided the head of @expr@ is a ternary constructor; otherwise it behaves-     -- as @'rnfp' \"#\" expr@ (/i.e./ do nothing).-     ---     -- @'rnfp' \".{###}\" expr@ will force it to only a depth of one. That is,-     -- @'rnfp' \".{###}\" expr = 'rnfp' \".\" expr@ when the head of @expr@-     -- is a ternary constructor; otherwise it won't perform any evaluation.-     ---     -- @'rnfp' \"*\" expr = 'rnf' expr@.-     ---     -- @'rnfp' \".{***}\" expr@ will 'rnf' (deep) any ternary constructor, but-     -- will not touch any constructor of other arity.-     ---     -- @'rnfp' \".{..{*.}.}\" expr@ will match any ternary constructor, then-     -- match the second subexpression constructor if it is binary, and-     -- if matching got this far, then the left sub-subexpression-     -- will be forced ('rnf'), but not the right.-     ---     -- @'rnfp' \".{.*:T{}#}\" expr@ will unwrap (shallow 'seq') the first-     -- subexpression of @expr@, and the third subexpression won't be touched.-     -- As for the second subexpression, if its type is @T@ it will be-     -- completely evaluated ('rnf'), but otherwise it won't be touched.-     ---     -- @'rnfp' \".{=**}\" expr@ will spark the /parallel/ complete evaluation of-     -- the two components of any pair. (Whether the computations actually-     -- run in parallel depends on resource availability, and the discretion-     -- of the RTS, as usual).-     ---     -- __Details__-     ---     -- The present pattern parser ignores any subpatterns of all-     -- pattern nodes except 'WR', 'TR' and 'PR', optionally emitting a warning.-     -- Hence, only 'WR', 'TR' and 'PR' patterns are potentially recursive.-     ---     -- When specifying a list of subpatterns with 'WR' or 'PR',-     -- in order for the match to succeed, the number of subpatterns must-     -- be equal to the arity of the named constructor.-     ---     -- Type constraints must always be followed by __{__ (opening brace) as delimiter.-     -- In the case of 'TR', if no recursion is desired, provide __{}__.-     -- In order for the match to succeed, the number of subpatterns must either-     -- be zero (__{}__), or be equal to the arity of the named constructor.-     --+-------------------------------------------------------------------------------++  data Rose a = Node a [ Rose a ]+-- (Hand write this NFData instance for greater portability.)+#if 0 && NFDATA_INSTANCE_PATTERN+#if DO_DERIVE_DATA_AND_TYPEABLE+   deriving (Show, Eq, GHC.Generic, Data, Typeable)+-- deriving (Show, Eq, Functor, GHC.Generic, Data, Typeable)+#elif DO_DERIVE_ONLY_TYPEABLE+   deriving (Show, Eq, GHC.Generic, Typeable)+#else+   deriving (Show, Eq, GHC.Generic)+#endif+#else+#if DO_DERIVE_DATA_AND_TYPEABLE+   deriving (Show, Eq, Data, Typeable)+#elif DO_DERIVE_ONLY_TYPEABLE+   deriving (Show, Eq, Typeable)+#else+   deriving (Show, Eq)+#endif+#endif+  type Pattern = Rose PatNode++  instance NFData a => NFData (Rose a) where+    rnf (Node x chs) = rnf x `seq` rnf chs++  instance Functor Rose where+    fmap f (Node x chs) = Node (f x) (map (fmap f) chs)++-- (Hand write this NFData instance for greater portability.)+#if 0+#if NFDATA_INSTANCE_PATTERN+  instance NFData a => NFData (Rose a) where rnf = DSG.genericRnf+#endif+#endif++-------------------------------------------------------------------------------++-- XXX+--+-- A major design decision needs to be made [does it?...]:+-- Is PatNode to remain a SUM ( ctor1 | ctor2 | ... ) or should+-- it be refactored to be a PRODUCT, i.e. a new field called+-- patNodeKind :: PatNodeKind, and all the fields of PatNodeAttrs+-- are lifted up to be siblings of patNodeKind in a single+-- top-level product (and PatNodeAttrs identifier elided).+--+-- The SUM has the advantage of convenient pattern-matching,+-- whereas the PRODUCT ... well, since we're using record syntax+-- (not yet in PatNode though!...), we CAN (I just discovered!)+-- do plain H98 pattern matching on multi-parameter constructors,+-- projecting out JUST any one value into a fresh pattern variable.+--+-- So in light of that, the refactoring to product has a lot to+-- recommend it -- however, will there not be a runtime penalty+-- of an extra wrapper or selector application or something?...+--+-- Am I missing anything crucial?...+--+-- If PatNode became a newtype, we pay only a compile-time price, right?...+--+-- Reading:+--+--   newtype Age = Age { unAge :: Int }+-- brings into scope both a constructor and a de-constructor:+--      Age :: Int -> Age+--    unAge :: Age -> Int+--+-- Thanks! I was just trying to remember this.+-- So incidentally, newtypes allow record syntax but only for+-- SINGLE PARAMETER constructor. (So newtypes will be of little+-- use if we adopted the product design above.)++-------------------------------------------------------------------------------++  -- | These attributes can be mixed freely. Certain combinations may+  -- seem unuseful, but nothing is prohibited by design.+  --+  -- While this may seem bloated, most of these capabilities can+  -- be truly banished from the code via build flags (USE_PAR_PATNODE etc.).+  --+  -- In the concrete pattern syntax, all attributes are represented+  -- as prefix modifiers (prefixing the+  -- @\'.\'@, @\'!\'@, @\'(\'@ or @\'*\'@+  -- pattern node designator).+  -- Prefix modifiers may be given in any order.+  --  {--}-     -- Old interjection:-     -- I regret that Haddock cannot offer better markup for distinguishing-     -- the metasyntax.  The bold is not bold enough.  The alternation symbol,-     -- although \/|\/ in the document comment, does not show as slanted for me.-     -- Had no luck using color, also Unicode support seems pretty sketchy.-     -- Embedding an image is possible via data URL, but this has been known-     -- to crash Haddock except for very small images.+  -- XXX Is there any particular reason these fields should be marked strict?+  -- Should they be explicitly unboxed as well? (Performance has been adequate+  -- for the purposes so far...).+  data PatNodeAttrs+         = PatNodeAttrs {+               uniqueID :: !Int              -- ^ Optional for convenience; set up with 'setPatternPatNodeUniqueIDs'. Beware that this function is not called automatically (or if it happens to be at the moment, this behaviour shouldn't be relied upon). For example, if you were to call <http://hackage.haskell.org/package/deepseq-bounded-0.6.0.0/docs/Control-DeepSeq-Bounded-PatUtil.html#v:growPat growPat>, the added nodes would all have \"uniqueID\" of 0.+             , depth :: !Int                 -- ^ (__*__/n/) &#8195; Depth of forcing for 'WN' and 'TN' nodes (/n/ is decimal integer depth).+             , doConstrainType :: !Bool      -- ^ (__:__) &#8195; Constrain pattern to match only types named in 'typeConstraints'. /__XXX__ This should be considered experimental still in 0.6. This and the "NFDataPDyn" aspects lost attention to/ <http://hackage.haskell.org/package/seqaid seqaid>.+             , typeConstraints :: ![String]  -- ^ The list of type rep strings used in the type constraint (when 'doConstrainType' is 'True').+             , doDelay :: !Bool              -- ^ (__@__) &#8195; Delay (current thread) for 'delayus' microseconds. /__XXX__ Still buggy?/+             , delayus :: !Int               -- ^ Microseconds of delay (when 'doDelay' is 'True').+#if USE_PAR_PATNODE+             , doSpark :: !Bool              -- ^ (__=__) &#8195; Spark matching for parallel evaluation.+#endif+#if USE_PSEQ_PATNODE+             , doPseq :: !Bool               -- ^ (__>__/perm/) &#8195; Sequence child subpattern matching, according to the permutation in 'pseqPerm'.+             , pseqPerm :: Maybe [Int]       -- ^ Lowercase alphabetic sequence is used in the concrete pattern syntax.  @__>cdba(wxyz)__@ will cause subpattern matching recursion on a quaternary constructor, with the subpattern computations sequenced @__y__@ then @__z__@ then @__x__@ then @__w__@ (order corresponds to @__cdba__@).+{-[XXX Until it really is, better not leave it saying so!] It is a runtime error (with a message), tested during matching, if this is a Just value and the list is not compatibly sized with the subpatterns. Sequencing syntax therefore would only work with 'WR' and 'TR' nodes, so we trap for the other cases and give a suitable error message.-}+#endif+#if USE_TRACE_PATNODE+             , doTrace :: !Bool              -- ^ (__+__) &#8195; Output a traceline to stderr.+#endif+#if USE_PING_PATNODE+             , doPing :: !Bool               -- ^ (__^__) &#8195; Raise informative (asynchronous? support is not strong for it, <http://hackage.haskell.org/package/base/docs/Control-Exception.html#v:throwTo throwTo> blocks...) exception /en passant/, for benefit of upstream. The exception is thrown in a new thread, so that the pattern matching continues; for a terminating version, see 'doDie'.+             , pingParentTID :: Maybe ThreadId  -- ^ Needed as argument for 'throwTo' call.+#endif+#if USE_DIE_PATNODE+             , doDie :: !Bool                -- ^ (__/__) &#8195; Kill (just this) thread.+#endif+#if USE_TIMING_PATNODE+             , doTiming           :: !Bool   -- ^ (__%__) &#8195; Note time passed since pattern-matched parent node. /__XXX__ Work in progress./+             , timestamp          :: !Int  -- XXX for now+             , parent_timestamp   :: !Int+             , delta_timestamp    :: !Int+#endif+           }+-- (Hand write this NFData instance for greater portability.)+#if 0 && NFDATA_INSTANCE_PATTERN+#if DO_DERIVE_DATA_AND_TYPEABLE+       deriving ( Show, Eq, Typeable, Data, GHC.Generic )+#elif DO_DERIVE_ONLY_TYPEABLE+       deriving ( Show, Eq, Typeable, GHC.Generic )+#else+       deriving ( Show, Eq, GHC.Generic )+#endif+#else+#if DO_DERIVE_DATA_AND_TYPEABLE+       deriving ( Show, Eq, Typeable )  -- Data apparently not needed+#elif DO_DERIVE_ONLY_TYPEABLE+       deriving ( Show, Eq, Typeable )+#else+       deriving ( Show, Eq )+#endif+#endif +#if NFDATA_INSTANCE_PATTERN+  instance NFData ThreadId where rnf x = ()+-- (Hand write this NFData instance for greater portability.)+--instance NFData PatNodeAttrs where rnf = DSG.genericRnf+  instance NFData PatNodeAttrs where+    rnf (PatNodeAttrs+           uniqueID+           depth+           doConstrainType+           typeConstraints+           doDelay+           delayus+#if USE_PAR_PATNODE+           doSpark+#endif+#if USE_PSEQ_PATNODE+           doPseq+           pseqPerm+#endif+#if USE_TRACE_PATNODE+           doTrace+#endif+#if USE_PING_PATNODE+           doPing+           pingParentTID+#endif+#if USE_DIE_PATNODE+           doDie+#endif+#if USE_TIMING_PATNODE+           doTiming+           timestamp+           parent_timestamp+           delta_timestamp+#endif+        )+     =+             uniqueID+       `seq` rnf depth+       `seq` rnf doConstrainType+       `seq` rnf typeConstraints+       `seq` rnf doDelay+       `seq` rnf delayus+#if USE_PAR_PATNODE+       `seq` rnf doSpark+#endif+#if USE_PSEQ_PATNODE+       `seq` rnf doPseq+       `seq` rnf pseqPerm+#endif+#if USE_TRACE_PATNODE+       `seq` rnf doTrace+#endif+#if USE_PING_PATNODE+       `seq` rnf doPing+       `seq` rnf pingParentTID+#endif+#if USE_DIE_PATNODE+       `seq` rnf doDie+#endif+#if USE_TIMING_PATNODE+       `seq` rnf doTiming+       `seq` rnf timestamp+       `seq` rnf parent_timestamp+       `seq` rnf delta_timestamp+#endif+#endif++  emptyPatNodeAttrs :: PatNodeAttrs+  emptyPatNodeAttrs+   = PatNodeAttrs {+         uniqueID           = 0+       , depth              = 0+       , doConstrainType    = False+       , typeConstraints    = []+       , doDelay            = False+       , delayus            = 0+#if USE_PAR_PATNODE+       , doSpark            = False+#endif+#if USE_PSEQ_PATNODE+       , doPseq             = False+       , pseqPerm           = Nothing+#endif+#if USE_TRACE_PATNODE+       , doTrace            = False+#endif+#if USE_PING_PATNODE+       , doPing             = False+       , pingParentTID      = Nothing+#endif+#if USE_DIE_PATNODE+       , doDie              = False+#endif+#if USE_TIMING_PATNODE+       , doTiming           = False+       , timestamp          = 0  -- Int for now+       , parent_timestamp   = 0+       , delta_timestamp    = 0+#endif+     }++-- (later: seems unused so commenting out)+--emptySparkPatNodeAttrs :: PatNodeAttrs+--emptySparkPatNodeAttrs = emptyPatNodeAttrs { doSpark = True }++  getPatNodeAttrs :: PatNode -> PatNodeAttrs+  getPatNodeAttrs pas = case pas of+    WI as -> as+    WS as -> as+    WR as -> as+    WN as -> as+#if USE_WW_DEEPSEQ+    WW as -> as+#endif+    TI as -> as+--  TS as -> as+    TR as -> as+    TN as -> as+#if USE_WW_DEEPSEQ+    TW as -> as+#endif+    _ -> error $ "getPatNodeAttrs: unexpected PatNode: " ++ show pas++  setPatNodeAttrs :: PatNode -> PatNodeAttrs -> PatNode+  setPatNodeAttrs pas as' = case pas of+    WI _ -> WI as'+    WS _ -> WS as'+    WR _ -> WR as'+    WN _ -> WN as'+#if USE_WW_DEEPSEQ+    WW _ -> WW as'+#endif+    TI _ -> TI as'+--  TS _ -> TS as'+    TR _ -> TR as'+    TN _ -> TN as'+#if USE_WW_DEEPSEQ+    TW _ -> TW as'+#endif+    _ -> error $ "setPatNodeAttrs: unexpected PatNode: " ++ show pas++#if USE_PING_PATNODE+  setPatNodePingParentTID :: ThreadId -> PatNode -> PatNode+  setPatNodePingParentTID tid pn = pn'+   where pn' = let as' = (getPatNodeAttrs pn) { pingParentTID = Just tid }+               in setPatNodeAttrs pn as'+#endif++  showPerm :: Maybe [Int] -> String+  showPerm Nothing = ""+  showPerm (Just lst) = showPerm' lst+  showPerm' [] = ""+  showPerm' (i:is) = (chr (i + ord 'a')) : showPerm' is++  -- Refer to http://stackoverflow.com/questions/12658443/how-to-decorate-a-tree-in-haskell/12658639 (among other SO questions) for good info and options.+  -- I've opted to remain H98 here, folloiwng Luis Casillas' answer.+  setPatternPatNodeUniqueIDs :: Int -> Pattern -> Pattern+  setPatternPatNodeUniqueIDs n pat+#if USE_POST_ORDER_IDS+   = ST.evalState (mapRoseM step pat) n+#else+   = ST.evalState (mapRoseM' step pat) n+#endif+   where+#if 1+    step :: PatNode -> ST.State Int PatNode+    step pn = do tag <- postIncrement+                 let as = getPatNodeAttrs pn+                 let as' = as { uniqueID = tag }+                 let pn' = setPatNodeAttrs pn as'+                 return pn'+#else+    step :: Pattern -> ST.State Int Pattern+    step p = do tag <- postIncrement+                let Node pn cs = p+                let p' = Node (pn { uniqueID = tag }) cs+                return p'+--              return (p, tag)+#endif++#if 1++-- This is from Luis Casillas' answer.+ #if 0--- These are now in Compile (but may move them back once sort out some stuff)-     , compilePat-     , showPat+  -- This function is not part of the solution, but it will help you+  -- understand mapRoseM below.+  mapRose :: (a -> b) -> Rose a -> Rose b+  mapRose fn (Node a subtrees) =+      let subtrees' = map (mapRose fn) subtrees+          a' = fn a+       in Node a' subtrees'++  -- Normally you'd write that function like this:+  mapRose' fn (Node a subtrees) = Node (fn a) $ map (mapRose' fn) subtrees #endif -     -- * Why depend on whole containers package, when we only want a rose tree+  -- But I wrote it out the long way to bring out the similarity to the+  -- following, which extracts the structure of the tagStep definition from+  -- the first solution above.+  mapRoseM :: Monad m => (a -> m b) -> Rose a -> m (Rose b)+  mapRoseM action (Node a subtrees) =+      do subtrees' <- mapM (mapRoseM action) subtrees+         a' <- action a+         return $ Node a' subtrees' -     , Rose(..)+  -- That whole business with getting the state and putting the successor+  -- in as the replacement can be abstracted out.  This action is like a+  -- post-increment operator.+  postIncrement :: Enum s => ST.State s s+  postIncrement = do val <- ST.get+                     ST.put (succ val)+                     return val -     -- * Preferred to have this in Seqable, but had cyclical dependency issues+#if 0+  -- Now tag can be easily written in terms of those.+  tag init tree = evalState (mapRoseM step tree) init+      where step a = do tag <- postIncrement+                        return (a, tag)+#endif -     , SeqNode(..)+  -- You can make mapRoseM process the local value+  -- before the subtrees if you want:+  mapRoseM' action (Node a subtrees) =+      do a' <- action a+         subtrees' <- mapM (mapRoseM' action) subtrees+         return $ Node a' subtrees' +#if 0+  -- And using Control.Monad you can turn this into a one-liner:+  mapRoseM action (Node a subtrees) =+      -- Apply the Rose constructor to the results of the two actions+      liftM2 Node (action a) (mapM (mapRoseM action) subtrees)++  -- Or in children-first order:+  mapRoseM' action (Node a subtrees) =+      liftM2 (flip Node ) (mapM (mapRoseM action) subtrees) (action a) #endif ---- #if NEW_IMPROVED_PATTERN_GRAMMAR----      module Control.DeepSeq.Bounded.Pattern_new_grammar  ,---- #else----      module Control.DeepSeq.Bounded.Pattern_old_grammar  ,---- #endif+#endif -  )-  where+------------------------------------------------------------------------------- +  -- XXX Is there any particular reason these fields should be marked strict?++  -- | Only 'WR' and 'TR' allow for explicit recursion.+  --+  -- All other 'PatNode' values are in leaf position when they occur.+  --+  -- Concrete syntax for @W*@ and @T*@ nodes are identical. A @T*@ node+  -- is simply a @W*@ node bearing a type constraint attribute.+  -- Please refer to the __Grammar__ further down this page for more details,+  -- and links to even more information.+  --+  -- /Notes:/+  --+  -- /I've kept the @T*@ types broken out as separate constructors, although they could be handled as special cases of @W*@ types in a way analogous to 'doSpark' ('PatNodeAttrs').  These were not \"absorbed\" because the semantics seems icky, and it's still not clear which @W*@ types even make sense with a type constraint.../+  --+  -- /I tried parametrising this, but it messed up my Show instance and seemed to be pulling me away from Haskell 98, so reverted.  It looks a bit ugly in the Haddock unfortunately, with the redundant column of @PatNodeAttrs@. The @T*@ nodes will be absorbed by 'PatNodeAttrs' in version 0.7, and it won't look so bad./+  data PatNode+       =++-- PatNodeAttrs was strict, but changed it b/c had problems using TN{}+-- form in some places (though not, apparantly, in all places)...+         WI !PatNodeAttrs  -- ^ (/__I__nsulate/, __.__ ) &#8195; Don't even unwrap the constructor of this node.+       | WR !PatNodeAttrs  -- ^ (/__R__ecurse/, __(__...__)__ ) &#8195; Continue pattern matching descendants, provided that arity is compatible (else the match fails).  Interior nodes of a pattern are always @WR@, /i.e./ @WR@ is the only @PatNode@ offering explicit recursion.  The rest (@?S@, @?N@, and @?W@) are implicitly recursive, but control is only as powerful as "NFDataN".+       | WS !PatNodeAttrs  -- ^ (/__S__top/, __!__ ) &#8195; Stop recursing (nothing more forced down this branch). This is equivalent to 'WN' at a 'depth' of 1. /'WS' is somewhat vestigial, and may be removed in 0.7./+       | WN !PatNodeAttrs  -- ^ (/__N__ (depth)/, __*__n ) &#8195; @<http://hackage.haskell.org/package/deepseq-bounded-0.6.0.0/docs/Control-DeepSeq-Bounded-NFDataN.html#t:NFDataN rnfn> n@ the branch under this node.+#if USE_WW_DEEPSEQ+       | WW !PatNodeAttrs  -- ^ (/__W__/ild, __*__ ) &#8195; Fully force (<http://hackage.haskell.org/package/deepseq/docs/Control-DeepSeq.html#t:NFData rnf>) the whole branch under this node. /Note that this is/ not /achievable as a limiting case of 'WN', so the existence of 'WW' is formally justifiable in a way that 'WS' is not. Having said that, for all practical purposes, a 'WN' with 'depth' @= maxBound::Int@ could be used for 'WW'.../+#endif+{--} -- XXX It's still unclear whether TI should allow subpatterns;+-- the alternative is for TI, when type doesn't match, to behave+-- as "." (no subpatterns); but since I say "otherwise behave as TR",+-- and TR says "continue pattern matching descendants", this seems to+-- say that subpatterns should be permitted.  Certainly it's no problem+-- to permit subpatterns in this case, but WI should still ignore+-- subpatterns since it will always be # regardless of node type.+-- (Subpatterns ought to be "safely redundant" in this case, but whether+-- they are depends on implementation and needs to be tested if allow+-- WI subpatterns to survive past the parser/compiler!)+--   And this all applies to TW and TN too, right? Yes.+-- It seems clear that TI, TW and TN should all allow subpatterns.+-- And that WI, WW and WN should elide them and issue a warning.+--   But, none of my present woes seem to be connected with this...+-- Nonetheless, it's important to pin down the semantics.+-- XXX Jan. '15: Soon these T* nodes will disappear, and the corresponding+-- PatNodeAttrs attributes will be used, as did for the P* (now doSpark) nodes.+       | TI !PatNodeAttrs  -- ^ Don't even unwrap the constructor of this node, if it's type is in the list; otherwise behave as 'WW'. (Note this behaviour is the complement of 'TW' behaviour.)+       | TR !PatNodeAttrs  -- ^ Match any of the types in the list (and continue pattern matching descendants); behave as 'WI' for nodes of type not in the list.+---    | TS !PatNodeAttrs  -- (never existed)+       | TN !PatNodeAttrs  -- ^ @<http://hackage.haskell.org/package/deepseq-bounded-0.6.0.0/docs/Control-DeepSeq-Bounded-NFDataN.html#t:NFDataN rnfn> n@ the branch under this node, if the node type matches any of the types in the list; otherwise behave as 'WI'.+#if USE_WW_DEEPSEQ+       | TW !PatNodeAttrs  -- ^ Fully force (<http://hackage.haskell.org/package/deepseq/docs/Control-DeepSeq.html#t:NFData rnf>) the whole branch under this node, if the node type matches any of the types in the list; otherwise behave as 'WI'. (Note this behaviour is the complement of 'TI' behaviour.)+#endif+       | XX                -- ^ Dummy node type reserved for internal use.++-- (Hand write this NFData instance for greater portability.)+#if 0 && NFDATA_INSTANCE_PATTERN+#if DO_DERIVE_DATA_AND_TYPEABLE+       deriving ( Eq, Typeable, Data, GHC.Generic )+#elif DO_DERIVE_ONLY_TYPEABLE+       deriving ( Eq, Typeable, GHC.Generic )+#else+       deriving ( Eq, GHC.Generic )+#endif+#else+#if DO_DERIVE_DATA_AND_TYPEABLE+       deriving ( Eq, Typeable )  -- Data apparently not needed+#elif DO_DERIVE_ONLY_TYPEABLE+       deriving ( Eq, Typeable )+#else+       deriving ( Eq )+#endif+#endif++#if NFDATA_INSTANCE_PATTERN+-- (Hand write this NFData instance for greater portability.)+--instance NFData PatNode where rnf = DSG.genericRnf+  instance NFData PatNode where+    rnf pas = rnf as where as = getPatNodeAttrs pas+#if 0+    rnf WI = True ; isWI _ = False+    rnf WR = True ; isWR _ = False+    rnf WS = True ; isWS _ = False+    rnf WN = True ; isWN _ = False+#if USE_WW_DEEPSEQ+    rnf WW = True ; isWW _ = False+#endif+    rnf TI = True ; isTI _ = False+    rnf TR = True ; isTR _ = False+    rnf TN as = True ; isTN _ = False+#if USE_WW_DEEPSEQ+    rnf TW as = True ; isTW _ = False+#endif+#endif+#endif++  isWI WI{} = True ; isWI _ = False+  isWR WR{} = True ; isWR _ = False+  isWS WS{} = True ; isWS _ = False+  isWN WN{} = True ; isWN _ = False+#if USE_WW_DEEPSEQ+  isWW WW{} = True ; isWW _ = False+#endif+  isTI TI{} = True ; isTI _ = False+  isTR TR{} = True ; isTR _ = False+  isTN TN{} = True ; isTN _ = False+#if USE_WW_DEEPSEQ+  isTW TW{} = True ; isTW _ = False+#endif++  instance Show PatNode where+#if SHOW_PAT_NODE_ATTRS++    show (WI as) = "WI " ++ show as+    show (WR as) = "WR " ++ show as+    show (WS as) = "WS " ++ show as+    show (WN as) = "WN " ++ show as+#if USE_WW_DEEPSEQ+    show (WW as) = "WW " ++ show as+#endif+    show (TI as) = "TI " ++ show as+    show (TR as) = "TR " ++ show as+    show (TN as) = "TN " ++ show as+#if USE_WW_DEEPSEQ+    show (TW as) = "TW " ++ show as+#endif++#else++    show pas+     | WI{} <- pas = s1++"WI"++s2+     | WR{} <- pas = s1++"WR"++s2+     | WS{} <- pas = s1++"WS"++s2+     | WN{} <- pas = s1++"WN"++s2'+#if USE_WW_DEEPSEQ+     | WW{} <- pas = s1++"WW"++s2+#endif+     | TI{} <- pas = s1++"TI"++s2''+     | TR{} <- pas = s1++"TR"++s2''+     | TN{} <- pas = s1++"TN"++s2'''+#if USE_WW_DEEPSEQ+     | TW{} <- pas = s1++"TW"++s2''+#endif+     where+      as = getPatNodeAttrs pas+      s1 =    ""+           ++ (if doDelay as then "@" ++ (show $ delayus as) else "")+#if USE_PAR_PATNODE+           ++ (if doSpark as then "=" else "")+#endif+#if USE_PSEQ_PATNODE+           ++ (if doPseq  as then ">" ++ (showPerm $ pseqPerm as) else "")+#endif+#if USE_TRACE_PATNODE+           ++ (if doTrace as then "+" else "")+#endif+#if USE_PING_PATNODE+           ++ (if doPing  as then "^" else "")+#endif+#if USE_DIE_PATNODE+           ++ (if doDie   as then "/" else "")+#endif+#if USE_TIMING_PATNODE+           ++ (if doTiming as then "%" else "")+#endif+      s2 = ""+      s2' = " " ++ show (depth as)+      s2'' = " (" ++ intercalate ";" (typeConstraints as) ++ ")"+      s2''' = s2' ++ s2''+#if 0+      doubleBackslashes :: String -> String+      doubleBackslashes ('\\':t) = '\\':'\\':doubleBackslashes t+      doubleBackslashes (h:t) = h:doubleBackslashes t+      doubleBackslashes [] = []+#endif++#endif++  showPatRaw :: Pattern -> String+  showPatRaw (Node pn cs) = showPatNodeRaw pn ++ "\n[" ++ intercalate "," (map showPatRaw cs) ++ "]"+  showPatNodeRaw :: PatNode -> String+  showPatNodeRaw (WI as) = "WI "++show as+  showPatNodeRaw (WR as) = "WR "++show as+  showPatNodeRaw (WS as) = "WS "++show as+  showPatNodeRaw (WN as) = "WN "++show as+#if USE_WW_DEEPSEQ+  showPatNodeRaw (WW as) = "WW "++show as+#endif+  showPatNodeRaw (TI as) = "TI "++show as+  showPatNodeRaw (TR as) = "TR "++show as+  showPatNodeRaw (TN as) = "TN "++show as+#if USE_WW_DEEPSEQ+  showPatNodeRaw (TW as) = "TW "++show as+#endif+ ------------------------------------------------------------------------------- -#if NEW_IMPROVED_PATTERN_GRAMMAR-  import Control.DeepSeq.Bounded.Pattern_new_grammar+#if 0+  patternShapeOK :: Data a => Pattern -> a -> Bool+  patternShapeOK pat x = S.shapeOf pat == S.shapeOf x+#endif++-------------------------------------------------------------------------------++  -- Note that Ord is derived, so the order that the constructors+  -- are listed matters!  (This only affects GHC rules, SFAIK.)+  -- (This data type is here, to avoid cyclical imports which+  -- GHC pretty much is useless with.)+  --------+  -- On the one hand, we want to keep this lightweight -- it can in+  -- principle be a single bit (Insulate/Propagate), as originally planned!+  -- But the Spark thing was too useful; and Print and Error would+  -- also be useful.  But they're more orthogonal.+  --------+  -- Later: Went with PatNodeAttrs for Pattern, but for Seqable+  -- we really prefer to keep it swift and simple for a while yet.+#if 0+  type Spark = Bool+  type PrintPeriod = Int+  type ErrorMsg = String+  data SeqNode =+           Insulate Spark PrintPeriod+         | Conduct Spark PrintPeriod+         | Force Spark PrintPeriod+         | Error ErrorMsg+    deriving ( Eq, Ord ) #else-  import Control.DeepSeq.Bounded.Pattern_old_grammar+  -- Later: Maybe "Insulate" is too strong a word. If going to "Insulate",+  -- then "external demand" (like demand generated by natural program+  -- evaluation) should also be repulsed (probably throwing an Error).+  -- "Conduct" would then permit these external demands to propagate,+  -- but will not cause any additional forcing.+  -- Then "Propagate" (which we can call "Force" now?) would carry+  -- the artificial forcing demands.+  -- So yeah, pretty much the above scheme, but try to get it happening+  -- for natural demand.+  -- If we can print trace info for every node, we can trace natural demand.+  -- And use that info, dynamically, to configure the harness.  In a sense+  -- it seems silly to do that, since that's what the RTS is already doing,+  -- but it's an important special case. If the natural demand pattern+  -- is constant (over a window), then (within that window) we can+  -- safely manipulate the harness so long as its artificial forcing+  -- doesn't extend beyond those natural bounds.  Why would you want+  -- to do this? I'm not sure, but it has theoretical interest at least.+  -- Because, for one thing, you are no longer at risk of changing+  -- the semantics by introducing new bottoms.  And so if the demand+  -- pattern is BIG, we could use the seqharn to parallelise it etc?+  -- Just the natural demand that is...  I hope so. That's the ticket.+  data SeqNode =+           Insulate+---      | Conduct+         | Propagate  -- XXX if include Conduct, then rename Propagate to Force+#if USE_PAR_SEQABLE+         | Spark+#endif+-- These would break the Ord; and besides, they're sort of orthogonal+-- (as is Spark)+---      | Print Int+---      | Error String+    deriving ( Eq, Ord )+--  deriving ( Eq, Ord, Show ) #endif  -------------------------------------------------------------------------------
− src/Control/DeepSeq/Bounded/Pattern_new_grammar.hs
@@ -1,800 +0,0 @@-----------------------------------------------------------------------------------  {-  LANGUAGE CPP #-}--#define DO_TRACE 0--#define USE_POST_ORDER_IDS 0--#define SHOW_PAT_NODE_ATTRS 0--#define WARN_IGNORED_SUBPATTERNS 1-#define NEVER_IGNORE_SUBPATTERNS 0---- Formerly DEBUG_WITH_DEEPSEQ_GENERICS.--- Now also needed to force issuance of all compilePat warnings--- (so not strictly a debugging flag anymore).--- [Except it didn't work...]---- #define NFDATA_INSTANCE_PATTERN 0  -- now a .cabal flag--#define DO_DERIVE_DATA_AND_TYPEABLE 0-#define DO_DERIVE_ONLY_TYPEABLE 1-#if DO_DERIVE_ONLY_TYPEABLE && DO_DERIVE_DATA_AND_TYPEABLE-#undef DO_DERIVE_ONLY_TYPEABLE-#warning DO_DERIVE_ONLY_TYPEABLE forced 0, due to DO_DERIVE_DATA_AND_TYPEABLE being 1.-#define DO_DERIVE_ONLY_TYPEABLE 0-#endif---- Now specified via --flag=[-]USE_WWW_DEEPSEQ---- #define USE_WW_DEEPSEQ 1------------------------------------------------------------------------------------- Good idea: Let * be followed by an integer N.--- This shall have the semantics that, when that node--- is matched in the pattern, instead of rnf it is forcen N'd.---- There may be fusion possible (which is worth trying here--- for practise, even if this lib is not used much):------   forcep p1 . forcep p2 = forcep (unionPat [p1,p2])------ This holds if pattern doesn't contain #, or any (type-)constrained--- subpatterns -- the latter might work out, if exclude # from them too,--- but I'm not sure.  With #, we lose even monotonicity, let alone--- the above law.------ For the above to hold, remember, the union must have exactly--- the "forcing potential" of the LHS -- no more, no less.-----------------------------------------------------------------------------------#if DO_DERIVE_DATA_AND_TYPEABLE-  {-# LANGUAGE DeriveDataTypeable #-}-#endif--- XXX Only needed for something in Blah.hs.--- Check into it, and see if can't get rid of the need--- for Typeable instances in here!-#if DO_DERIVE_ONLY_TYPEABLE-  {-# LANGUAGE DeriveDataTypeable #-}-#endif---- Prefer to hand-write the NFData instance, so that can--- use it with HASKELL98_FRAGMENT.-#if 0-#if NFDATA_INSTANCE_PATTERN-  -- For testing only (controlling trace interleaving):-  {-# LANGUAGE DeriveGeneric #-}-#endif-#endif--  {-  LANGUAGE DeriveFunctor #-}------------------------------------------------------------------------------------- |--- Module      :  Control.DeepSeq.Bounded.Pattern_new_grammar--- Copyright   :  Andrew G. Seniuk 2014-2015--- License     :  BSD-style (see the file LICENSE)------ Maintainer  :  Andrew Seniuk <rasfar@gmail.com>--- Stability   :  provisional--- Portability :  portable----{--}--- (Restore comment from Pattern.hs when shed old grammar support.)-----------------------------------------------------------------------------------  module Control.DeepSeq.Bounded.Pattern_new_grammar--- (Restore exports & comments from Pattern.hs when shed old grammar support.)-  where-----------------------------------------------------------------------------------#if DO_DERIVE_DATA_AND_TYPEABLE-  import Data.Data ( Data )-  import Data.Typeable ( Typeable )-#elif DO_DERIVE_ONLY_TYPEABLE-  import Data.Typeable ( Typeable )-#endif--#if USE_WW_DEEPSEQ-  import Control.DeepSeq ( NFData )-#endif--  import Control.Concurrent ( ThreadId )--  import Data.List ( intercalate )-  import Data.Char ( isDigit )-  import Data.Maybe ( isNothing, fromJust )-  import Data.Maybe ( isJust )--  import Debug.Trace ( trace )--#if USE_WW_DEEPSEQ-  -- The only uses of force in this module are for debugging purposes-  -- (including trying to get messages to be displayed in a timely-  -- manner, although that problem has not been completely solved).-  import Control.DeepSeq ( force )-#endif---- (Hand write this NFData instance for greater portability.)-#if NFDATA_INSTANCE_PATTERN-  -- for helping trace debugging-#if 1-  import Control.DeepSeq-#else-  import qualified Control.DeepSeq.Generics as DSG-  import qualified GHC.Generics as GHC ( Generic )-#endif-#endif--  import Data.Char ( ord )-  import Data.Char ( chr )--  import Control.Monad.State as ST-----------------------------------------------------------------------------------#if DO_TRACE-  mytrace = trace-#else-  mytrace _ = id-#endif-----------------------------------------------------------------------------------  data Rose a = Node a [ Rose a ]--- (Hand write this NFData instance for greater portability.)-#if 0 && NFDATA_INSTANCE_PATTERN-#if DO_DERIVE_DATA_AND_TYPEABLE-   deriving (Show, Eq, GHC.Generic, Data, Typeable)--- deriving (Show, Eq, Functor, GHC.Generic, Data, Typeable)-#elif DO_DERIVE_ONLY_TYPEABLE-   deriving (Show, Eq, GHC.Generic, Typeable)-#else-   deriving (Show, Eq, GHC.Generic)-#endif-#else-#if DO_DERIVE_DATA_AND_TYPEABLE-   deriving (Show, Eq, Data, Typeable)-#elif DO_DERIVE_ONLY_TYPEABLE-   deriving (Show, Eq, Typeable)-#else-   deriving (Show, Eq)-#endif-#endif-  type Pattern = Rose PatNode--  instance NFData a => NFData (Rose a) where-    rnf (Node x chs) = rnf x `seq` rnf chs--  instance Functor Rose where-    fmap f (Node x chs) = Node (f x) (map (fmap f) chs)---- (Hand write this NFData instance for greater portability.)-#if 0-#if NFDATA_INSTANCE_PATTERN-  instance NFData a => NFData (Rose a) where rnf = DSG.genericRnf-#endif-#endif------------------------------------------------------------------------------------- XXX------ A major design decision needs to be made [does it?...]:--- Is PatNode to remain a SUM ( ctor1 | ctor2 | ... ) or should--- it be refactored to be a PRODUCT, i.e. a new field called--- patNodeKind :: PatNodeKind, and all the fields of PatNodeAttrs--- are lifted up to be siblings of patNodeKind in a single--- top-level product (and PatNodeAttrs identifier elided).------ The SUM has the advantage of convenient pattern-matching,--- whereas the PRODUCT ... well, since we're using record syntax--- (not yet in PatNode though!...), we CAN (I just discovered!)--- do plain H98 pattern matching on multi-parameter constructors,--- projecting out JUST any one value into a fresh pattern variable.------ So in light of that, the refactoring to product has a lot to--- recommend it -- however, will there not be a runtime penalty--- of an extra wrapper or selector application or something?...------ Am I missing anything crucial?...------ If PatNode became a newtype, we pay only a compile-time price, right?...------ Reading:------   newtype Age = Age { unAge :: Int }--- brings into scope both a constructor and a de-constructor:---      Age :: Int -> Age---    unAge :: Age -> Int------ Thanks! I was just trying to remember this.--- So incidentally, newtypes allow record syntax but only for--- SINGLE PARAMETER constructor. (So newtypes will be of little--- use if we adopted the product design above.)-----------------------------------------------------------------------------------  -- | These attributes can be mixed freely. Certain combinations may-  -- seem unuseful, but nothing is prohibited by design.-  ---  -- While this may seem bloated, most of these capabilities can-  -- be truly banished from the code via build flags (USE_PAR_PATNODE etc.).-  ---  -- In the concrete pattern syntax, all attributes are represented-  -- as prefix modifiers (prefixing the-  -- @\'.\'@, @\'!\'@, @\'(\'@ or @\'*\'@-  -- pattern node designator),-  -- except for 'depth' and 'typeConstraints', which are postfix.-  -- Prefix modifiers may be given in any order, but the postfix-  -- must be in depth-then-type-constraints order when both are present.-  -- -{--}-  -- XXX Is there any particular reason these fields should be marked strict?-  -- Should they be explicitly unboxed as well? (Performance has been adequate-  -- for the purposes so far...).-  data PatNodeAttrs-         = PatNodeAttrs {-               uniqueID :: !Int              -- ^ Optional for convenience; set up with 'setPatternPatNodeUniqueIDs'. Beware that this function is not called automatically (or if it happens to be at the moment, this behaviour shouldn't be relied upon). For example, if you were to call <http://hackage.haskell.org/package/deepseq-bounded-0.6.0.0/docs/Control-DeepSeq-Bounded-PatUtil.html#v:growPat growPat>, the added nodes would all have \"uniqueID\" of 0.-             , depth :: !Int                 -- ^ (__*__/n/) &#8195; Depth of forcing for 'WN' and 'TN' nodes (/n/ is decimal integer depth).-             , doConstrainType :: !Bool      -- ^ (__:__) &#8195; Constrain pattern to match only types named in 'typeConstraints'. /__XXX__ This should be considered experimental still in 0.6. This and the "NFDataPDyn" aspects lost attention to/ <http://hackage.haskell.org/package/seqaid seqaid>.-             , typeConstraints :: ![String]  -- ^ The list of type rep strings used in the type constraint (when 'doConstrainType' is 'True').-             , doDelay :: !Bool              -- ^ (__@__) &#8195; Delay (current thread) for 'delayus' microseconds. /__XXX__ Still buggy?/-             , delayus :: !Int               -- ^ Microseconds of delay (when 'doDelay' is 'True').-#if USE_PAR_PATNODE-             , doSpark :: !Bool              -- ^ (__=__) &#8195; Spark matching for parallel evaluation.-#endif-#if USE_PSEQ_PATNODE-             , doPseq :: !Bool               -- ^ (__>__/perm/) &#8195; Sequence child subpattern matching, according to the permutation in 'pseqPerm'.-             , pseqPerm :: Maybe [Int]       -- ^ Lowercase alphabetic sequence is used in the concrete pattern syntax.  @__>cdba(wxyz)__@ will cause subpattern matching recursion on a quaternary constructor, with the subpattern computations sequenced @__y__@ then @__z__@ then @__x__@ then @__w__@ (order corresponds to @__cdba__@).-{-[XXX Until it really is, better not leave it saying so!] It is a runtime error (with a message), tested during matching, if this is a Just value and the list is not compatibly sized with the subpatterns. Sequencing syntax therefore would only work with 'WR' and 'TR' nodes, so we trap for the other cases and give a suitable error message.-}-#endif-#if USE_TRACE_PATNODE-             , doTrace :: !Bool              -- ^ (__+__) &#8195; Output a traceline to stderr.-#endif-#if USE_PING_PATNODE-             , doPing :: !Bool               -- ^ (__^__) &#8195; Raise informative (asynchronous? support is not strong for it, <http://hackage.haskell.org/package/base/docs/Control-Exception.html#v:throwTo throwTo> blocks...) exception /en passant/, for benefit of upstream. The exception is thrown in a new thread, so that the pattern matching continues; for a terminating version, see 'doDie'.-             , pingParentTID :: Maybe ThreadId  -- ^ Needed as argument for 'throwTo' call.-#endif-#if USE_DIE_PATNODE-             , doDie :: !Bool                -- ^ (__/__) &#8195; Kill (just this) thread.-#endif-#if USE_TIMING_PATNODE-             , doTiming           :: !Bool   -- ^ (__%__) &#8195; Note time passed since pattern-matched parent node. /__XXX__ Work in progress./-             , timestamp          :: !Int  -- XXX for now-             , parent_timestamp   :: !Int-             , delta_timestamp    :: !Int-#endif-           }--- (Hand write this NFData instance for greater portability.)-#if 0 && NFDATA_INSTANCE_PATTERN-#if DO_DERIVE_DATA_AND_TYPEABLE-       deriving ( Show, Eq, Typeable, Data, GHC.Generic )-#elif DO_DERIVE_ONLY_TYPEABLE-       deriving ( Show, Eq, Typeable, GHC.Generic )-#else-       deriving ( Show, Eq, GHC.Generic )-#endif-#else-#if DO_DERIVE_DATA_AND_TYPEABLE-       deriving ( Show, Eq, Typeable )  -- Data apparently not needed-#elif DO_DERIVE_ONLY_TYPEABLE-       deriving ( Show, Eq, Typeable )-#else-       deriving ( Show, Eq )-#endif-#endif--#if NFDATA_INSTANCE_PATTERN-  instance NFData ThreadId where rnf x = ()--- (Hand write this NFData instance for greater portability.)---instance NFData PatNodeAttrs where rnf = DSG.genericRnf-  instance NFData PatNodeAttrs where-    rnf (PatNodeAttrs-           uniqueID-           depth-           doConstrainType-           typeConstraints-           doDelay-           delayus-#if USE_PAR_PATNODE-           doSpark-#endif-#if USE_PSEQ_PATNODE-           doPseq-           pseqPerm-#endif-#if USE_TRACE_PATNODE-           doTrace-#endif-#if USE_PING_PATNODE-           doPing-           pingParentTID-#endif-#if USE_DIE_PATNODE-           doDie-#endif-#if USE_TIMING_PATNODE-           doTiming-           timestamp-           parent_timestamp-           delta_timestamp-#endif-        )-     =-             uniqueID-       `seq` rnf depth-       `seq` rnf doConstrainType-       `seq` rnf typeConstraints-       `seq` rnf doDelay-       `seq` rnf delayus-#if USE_PAR_PATNODE-       `seq` rnf doSpark-#endif-#if USE_PSEQ_PATNODE-       `seq` rnf doPseq-       `seq` rnf pseqPerm-#endif-#if USE_TRACE_PATNODE-       `seq` rnf doTrace-#endif-#if USE_PING_PATNODE-       `seq` rnf doPing-       `seq` rnf pingParentTID-#endif-#if USE_DIE_PATNODE-       `seq` rnf doDie-#endif-#if USE_TIMING_PATNODE-       `seq` rnf doTiming-       `seq` rnf timestamp-       `seq` rnf parent_timestamp-       `seq` rnf delta_timestamp-#endif-#endif--  emptyPatNodeAttrs :: PatNodeAttrs-  emptyPatNodeAttrs-   = PatNodeAttrs {-         uniqueID           = 0-       , depth              = 0-       , doConstrainType    = False-       , typeConstraints    = []-       , doDelay            = False-       , delayus            = 0-#if USE_PAR_PATNODE-       , doSpark            = False-#endif-#if USE_PSEQ_PATNODE-       , doPseq             = False-       , pseqPerm           = Nothing-#endif-#if USE_TRACE_PATNODE-       , doTrace            = False-#endif-#if USE_PING_PATNODE-       , doPing             = False-       , pingParentTID      = Nothing-#endif-#if USE_DIE_PATNODE-       , doDie              = False-#endif-#if USE_TIMING_PATNODE-       , doTiming           = False-       , timestamp          = 0  -- Int for now-       , parent_timestamp   = 0-       , delta_timestamp    = 0-#endif-     }---- (later: seems unused so commenting out)---emptySparkPatNodeAttrs :: PatNodeAttrs---emptySparkPatNodeAttrs = emptyPatNodeAttrs { doSpark = True }--  getPatNodeAttrs :: PatNode -> PatNodeAttrs-  getPatNodeAttrs pas = case pas of-    WI as -> as-    WS as -> as-    WR as -> as-    WN as -> as-#if USE_WW_DEEPSEQ-    WW as -> as-#endif-    TI as -> as---  TS as -> as-    TR as -> as-    TN as -> as-#if USE_WW_DEEPSEQ-    TW as -> as-#endif-    _ -> error $ "getPatNodeAttrs: unexpected PatNode: " ++ show pas--  setPatNodeAttrs :: PatNode -> PatNodeAttrs -> PatNode-  setPatNodeAttrs pas as' = case pas of-    WI _ -> WI as'-    WS _ -> WS as'-    WR _ -> WR as'-    WN _ -> WN as'-#if USE_WW_DEEPSEQ-    WW _ -> WW as'-#endif-    TI _ -> TI as'---  TS _ -> TS as'-    TR _ -> TR as'-    TN _ -> TN as'-#if USE_WW_DEEPSEQ-    TW _ -> TW as'-#endif-    _ -> error $ "setPatNodeAttrs: unexpected PatNode: " ++ show pas--#if USE_PING_PATNODE-  setPatNodePingParentTID :: ThreadId -> PatNode -> PatNode-  setPatNodePingParentTID tid pn = pn'-   where pn' = let as' = (getPatNodeAttrs pn) { pingParentTID = Just tid }-               in setPatNodeAttrs pn as'-#endif--  showPerm :: Maybe [Int] -> String-  showPerm Nothing = ""-  showPerm (Just lst) = showPerm' lst-  showPerm' [] = ""-  showPerm' (i:is) = (chr (i + ord 'a')) : showPerm' is--  -- Refer to http://stackoverflow.com/questions/12658443/how-to-decorate-a-tree-in-haskell/12658639 (among other SO questions) for good info and options.-  -- I've opted to remain H98 here, folloiwng Luis Casillas' answer.-  setPatternPatNodeUniqueIDs :: Int -> Pattern -> Pattern-  setPatternPatNodeUniqueIDs n pat-#if USE_POST_ORDER_IDS-   = ST.evalState (mapRoseM step pat) n-#else-   = ST.evalState (mapRoseM' step pat) n-#endif-   where-#if 1-    step :: PatNode -> ST.State Int PatNode-    step pn = do tag <- postIncrement-                 let as = getPatNodeAttrs pn-                 let as' = as { uniqueID = tag }-                 let pn' = setPatNodeAttrs pn as'-                 return pn'-#else-    step :: Pattern -> ST.State Int Pattern-    step p = do tag <- postIncrement-                let Node pn cs = p-                let p' = Node (pn { uniqueID = tag }) cs-                return p'---              return (p, tag)-#endif--#if 1---- This is from Luis Casillas' answer.--#if 0-  -- This function is not part of the solution, but it will help you-  -- understand mapRoseM below.-  mapRose :: (a -> b) -> Rose a -> Rose b-  mapRose fn (Node a subtrees) =-      let subtrees' = map (mapRose fn) subtrees-          a' = fn a-       in Node a' subtrees'--  -- Normally you'd write that function like this:-  mapRose' fn (Node a subtrees) = Node (fn a) $ map (mapRose' fn) subtrees-#endif--  -- But I wrote it out the long way to bring out the similarity to the-  -- following, which extracts the structure of the tagStep definition from-  -- the first solution above.-  mapRoseM :: Monad m => (a -> m b) -> Rose a -> m (Rose b)-  mapRoseM action (Node a subtrees) =-      do subtrees' <- mapM (mapRoseM action) subtrees-         a' <- action a-         return $ Node a' subtrees'--  -- That whole business with getting the state and putting the successor-  -- in as the replacement can be abstracted out.  This action is like a-  -- post-increment operator.-  postIncrement :: Enum s => ST.State s s-  postIncrement = do val <- ST.get-                     ST.put (succ val)-                     return val--#if 0-  -- Now tag can be easily written in terms of those.-  tag init tree = evalState (mapRoseM step tree) init-      where step a = do tag <- postIncrement-                        return (a, tag)-#endif--  -- You can make mapRoseM process the local value-  -- before the subtrees if you want:-  mapRoseM' action (Node a subtrees) =-      do a' <- action a-         subtrees' <- mapM (mapRoseM' action) subtrees-         return $ Node a' subtrees'--#if 0-  -- And using Control.Monad you can turn this into a one-liner:-  mapRoseM action (Node a subtrees) =-      -- Apply the Rose constructor to the results of the two actions-      liftM2 Node (action a) (mapM (mapRoseM action) subtrees)--  -- Or in children-first order:-  mapRoseM' action (Node a subtrees) =-      liftM2 (flip Node ) (mapM (mapRoseM action) subtrees) (action a)-#endif--#endif-----------------------------------------------------------------------------------  -- XXX Is there any particular reason these fields should be marked strict?--  -- | Only 'WR' and 'TR' allow for explicit recursion.-  ---  -- All other 'PatNode' values are in leaf position when they occur.-  ---  -- Concrete syntax for @W*@ and @T*@ nodes are identical. A @T*@ node-  -- is simply a @W*@ node bearing a type constraint attribute.-  -- Please refer to the __Grammar__ further down this page for more details,-  -- and links to even more information.-  ---  -- /Notes:/-  ---  -- /I've kept the @T*@ types broken out as separate constructors, although they could be handled as special cases of @W*@ types in a way analogous to 'doSpark' ('PatNodeAttrs').  These were not \"absorbed\" because the semantics seems icky, and it's still not clear which @W*@ types even make sense with a type constraint.../-  ---  -- /I tried parametrising this, but it messed up my Show instance and seemed to be pulling me away from Haskell 98, so reverted.  It looks a bit ugly in the Haddock unfortunately, with the redundant column of @PatNodeAttrs@. The @T*@ nodes will be absorbed by 'PatNodeAttrs' in version 0.7, and it won't look so bad./-  data PatNode-       =---- PatNodeAttrs was strict, but changed it b/c had problems using TN{}--- form in some places (though not, apparantly, in all places)...-         WI !PatNodeAttrs  -- ^ (/__I__nsulate/, __.__ ) &#8195; Don't even unwrap the constructor of this node.-       | WR !PatNodeAttrs  -- ^ (/__R__ecurse/, __(__...__)__ ) &#8195; Continue pattern matching descendants, provided that arity is compatible (else the match fails).  Interior nodes of a pattern are always @WR@, /i.e./ @WR@ is the only @PatNode@ offering explicit recursion.  The rest (@?S@, @?N@, and @?W@) are implicitly recursive, but control is only as powerful as "NFDataN".-       | WS !PatNodeAttrs  -- ^ (/__S__top/, __!__ ) &#8195; Stop recursing (nothing more forced down this branch). This is equivalent to 'WN' at a 'depth' of 1. /'WS' is somewhat vestigial, and may be removed in 0.7./-       | WN !PatNodeAttrs  -- ^ (/__N__ (depth)/, __*__n ) &#8195; @<http://hackage.haskell.org/package/deepseq-bounded-0.6.0.0/docs/Control-DeepSeq-Bounded-NFDataN.html#t:NFDataN rnfn> n@ the branch under this node.-#if USE_WW_DEEPSEQ-       | WW !PatNodeAttrs  -- ^ (/__W__/ild, __*__ ) &#8195; Fully force (<http://hackage.haskell.org/package/deepseq/docs/Control-DeepSeq.html#t:NFData rnf>) the whole branch under this node. /Note that this is/ not /achievable as a limiting case of 'WN', so the existence of 'WW' is formally justifiable in a way that 'WS' is not. Having said that, for all practical purposes, a 'WN' with 'depth' @= maxBound::Int@ could be used for 'WW'.../-#endif-{--} -- XXX It's still unclear whether TI should allow subpatterns;--- the alternative is for TI, when type doesn't match, to behave--- as "." (no subpatterns); but since I say "otherwise behave as TR",--- and TR says "continue pattern matching descendants", this seems to--- say that subpatterns should be permitted.  Certainly it's no problem--- to permit subpatterns in this case, but WI should still ignore--- subpatterns since it will always be # regardless of node type.--- (Subpatterns ought to be "safely redundant" in this case, but whether--- they are depends on implementation and needs to be tested if allow--- WI subpatterns to survive past the parser/compiler!)---   And this all applies to TW and TN too, right? Yes.--- It seems clear that TI, TW and TN should all allow subpatterns.--- And that WI, WW and WN should elide them and issue a warning.---   But, none of my present woes seem to be connected with this...--- Nonetheless, it's important to pin down the semantics.--- XXX Jan. '15: Soon these T* nodes will disappear, and the corresponding--- PatNodeAttrs attributes will be used, as did for the P* (now doSpark) nodes.-       | TI !PatNodeAttrs  -- ^ Don't even unwrap the constructor of this node, if it's type is in the list; otherwise behave as 'WW'. (Note this behaviour is the complement of 'TW' behaviour.)-       | TR !PatNodeAttrs  -- ^ Match any of the types in the list (and continue pattern matching descendants); behave as 'WI' for nodes of type not in the list.----    | TS !PatNodeAttrs  -- (never existed)-       | TN !PatNodeAttrs  -- ^ @<http://hackage.haskell.org/package/deepseq-bounded-0.6.0.0/docs/Control-DeepSeq-Bounded-NFDataN.html#t:NFDataN rnfn> n@ the branch under this node, if the node type matches any of the types in the list; otherwise behave as 'WI'.-#if USE_WW_DEEPSEQ-       | TW !PatNodeAttrs  -- ^ Fully force (<http://hackage.haskell.org/package/deepseq/docs/Control-DeepSeq.html#t:NFData rnf>) the whole branch under this node, if the node type matches any of the types in the list; otherwise behave as 'WI'. (Note this behaviour is the complement of 'TI' behaviour.)-#endif-       | XX                -- ^ Dummy node type reserved for internal use.---- (Hand write this NFData instance for greater portability.)-#if 0 && NFDATA_INSTANCE_PATTERN-#if DO_DERIVE_DATA_AND_TYPEABLE-       deriving ( Eq, Typeable, Data, GHC.Generic )-#elif DO_DERIVE_ONLY_TYPEABLE-       deriving ( Eq, Typeable, GHC.Generic )-#else-       deriving ( Eq, GHC.Generic )-#endif-#else-#if DO_DERIVE_DATA_AND_TYPEABLE-       deriving ( Eq, Typeable )  -- Data apparently not needed-#elif DO_DERIVE_ONLY_TYPEABLE-       deriving ( Eq, Typeable )-#else-       deriving ( Eq )-#endif-#endif--#if NFDATA_INSTANCE_PATTERN--- (Hand write this NFData instance for greater portability.)---instance NFData PatNode where rnf = DSG.genericRnf-  instance NFData PatNode where-    rnf pas = rnf as where as = getPatNodeAttrs pas-#if 0-    rnf WI = True ; isWI _ = False-    rnf WR = True ; isWR _ = False-    rnf WS = True ; isWS _ = False-    rnf WN = True ; isWN _ = False-#if USE_WW_DEEPSEQ-    rnf WW = True ; isWW _ = False-#endif-    rnf TI = True ; isTI _ = False-    rnf TR = True ; isTR _ = False-    rnf TN as = True ; isTN _ = False-#if USE_WW_DEEPSEQ-    rnf TW as = True ; isTW _ = False-#endif-#endif-#endif--  isWI WI{} = True ; isWI _ = False-  isWR WR{} = True ; isWR _ = False-  isWS WS{} = True ; isWS _ = False-  isWN WN{} = True ; isWN _ = False-#if USE_WW_DEEPSEQ-  isWW WW{} = True ; isWW _ = False-#endif-  isTI TI{} = True ; isTI _ = False-  isTR TR{} = True ; isTR _ = False-  isTN TN{} = True ; isTN _ = False-#if USE_WW_DEEPSEQ-  isTW TW{} = True ; isTW _ = False-#endif--  instance Show PatNode where-#if SHOW_PAT_NODE_ATTRS--    show (WI as) = "WI " ++ show as-    show (WR as) = "WR " ++ show as-    show (WS as) = "WS " ++ show as-    show (WN as) = "WN " ++ show as-#if USE_WW_DEEPSEQ-    show (WW as) = "WW " ++ show as-#endif-    show (TI as) = "TI " ++ show as-    show (TR as) = "TR " ++ show as-    show (TN as) = "TN " ++ show as-#if USE_WW_DEEPSEQ-    show (TW as) = "TW " ++ show as-#endif--#else--    show pas-     | WI{} <- pas = s1++"WI"++s2-     | WR{} <- pas = s1++"WR"++s2-     | WS{} <- pas = s1++"WS"++s2-     | WN{} <- pas = s1++"WN"++s2'-#if USE_WW_DEEPSEQ-     | WW{} <- pas = s1++"WW"++s2-#endif-     | TI{} <- pas = s1++"TI"++s2''-     | TR{} <- pas = s1++"TR"++s2''-     | TN{} <- pas = s1++"TN"++s2'''-#if USE_WW_DEEPSEQ-     | TW{} <- pas = s1++"TW"++s2''-#endif-     where-      as = getPatNodeAttrs pas-      s1 =    ""-           ++ (if doDelay as then "@" ++ (show $ delayus as) else "")-#if USE_PAR_PATNODE-           ++ (if doSpark as then "=" else "")-#endif-#if USE_PSEQ_PATNODE-           ++ (if doPseq  as then ">" ++ (showPerm $ pseqPerm as) else "")-#endif-#if USE_TRACE_PATNODE-           ++ (if doTrace as then "+" else "")-#endif-#if USE_PING_PATNODE-           ++ (if doPing  as then "^" else "")-#endif-#if USE_DIE_PATNODE-           ++ (if doDie   as then "/" else "")-#endif-#if USE_TIMING_PATNODE-           ++ (if doTiming as then "%" else "")-#endif-      s2 = ""-      s2' = " " ++ show (depth as)-      s2'' = " (" ++ intercalate ";" (typeConstraints as) ++ ")"-      s2''' = s2' ++ s2''-#if 0-      doubleBackslashes :: String -> String-      doubleBackslashes ('\\':t) = '\\':'\\':doubleBackslashes t-      doubleBackslashes (h:t) = h:doubleBackslashes t-      doubleBackslashes [] = []-#endif--#endif--  showPatRaw :: Pattern -> String-  showPatRaw (Node pn cs) = showPatNodeRaw pn ++ "\n[" ++ intercalate "," (map showPatRaw cs) ++ "]"-  showPatNodeRaw :: PatNode -> String-  showPatNodeRaw (WI as) = "WI "++show as-  showPatNodeRaw (WR as) = "WR "++show as-  showPatNodeRaw (WS as) = "WS "++show as-  showPatNodeRaw (WN as) = "WN "++show as-#if USE_WW_DEEPSEQ-  showPatNodeRaw (WW as) = "WW "++show as-#endif-  showPatNodeRaw (TI as) = "TI "++show as-  showPatNodeRaw (TR as) = "TR "++show as-  showPatNodeRaw (TN as) = "TN "++show as-#if USE_WW_DEEPSEQ-  showPatNodeRaw (TW as) = "TW "++show as-#endif-----------------------------------------------------------------------------------#if 0-  patternShapeOK :: Data a => Pattern -> a -> Bool-  patternShapeOK pat x = S.shapeOf pat == S.shapeOf x-#endif-----------------------------------------------------------------------------------  -- Note that Ord is derived, so the order that the constructors-  -- are listed matters!  (This only affects GHC rules, SFAIK.)-  -- (This data type is here, to avoid cyclical imports which-  -- GHC pretty much is useless with.)-  ---------  -- On the one hand, we want to keep this lightweight -- it can in-  -- principle be a single bit (Insulate/Propagate), as originally planned!-  -- But the Spark thing was too useful; and Print and Error would-  -- also be useful.  But they're more orthogonal.-  ---------  -- Later: Went with PatNodeAttrs for Pattern, but for Seqable-  -- we really prefer to keep it swift and simple for a while yet.-#if 0-  type Spark = Bool-  type PrintPeriod = Int-  type ErrorMsg = String-  data SeqNode =-           Insulate Spark PrintPeriod-         | Conduct Spark PrintPeriod-         | Force Spark PrintPeriod-         | Error ErrorMsg-    deriving ( Eq, Ord )-#else-  -- Later: Maybe "Insulate" is too strong a word. If going to "Insulate",-  -- then "external demand" (like demand generated by natural program-  -- evaluation) should also be repulsed (probably throwing an Error).-  -- "Conduct" would then permit these external demands to propagate,-  -- but will not cause any additional forcing.-  -- Then "Propagate" (which we can call "Force" now?) would carry-  -- the artificial forcing demands.-  -- So yeah, pretty much the above scheme, but try to get it happening-  -- for natural demand.-  -- If we can print trace info for every node, we can trace natural demand.-  -- And use that info, dynamically, to configure the harness.  In a sense-  -- it seems silly to do that, since that's what the RTS is already doing,-  -- but it's an important special case. If the natural demand pattern-  -- is constant (over a window), then (within that window) we can-  -- safely manipulate the harness so long as its artificial forcing-  -- doesn't extend beyond those natural bounds.  Why would you want-  -- to do this? I'm not sure, but it has theoretical interest at least.-  -- Because, for one thing, you are no longer at risk of changing-  -- the semantics by introducing new bottoms.  And so if the demand-  -- pattern is BIG, we could use the seqharn to parallelise it etc?-  -- Just the natural demand that is...  I hope so. That's the ticket.-  data SeqNode =-           Insulate----      | Conduct-         | Propagate  -- XXX if include Conduct, then rename Propagate to Force-#if USE_PAR_SEQABLE-         | Spark-#endif--- These would break the Ord; and besides, they're sort of orthogonal--- (as is Spark)----      | Print Int----      | Error String-    deriving ( Eq, Ord )---  deriving ( Eq, Ord, Show )-#endif----------------------------------------------------------------------------------
− src/Control/DeepSeq/Bounded/Pattern_old_grammar.hs
@@ -1,270 +0,0 @@-----------------------------------------------------------------------------------  {-  LANGUAGE CPP #-}--#define DO_TRACE 0--#define SHOW_PAT_NODE_ATTRS 0--#define WARN_IGNORED_SUBPATTERNS 1-#define NEVER_IGNORE_SUBPATTERNS 0---- Formerly DEBUG_WITH_DEEPSEQ_GENERICS.--- Now also needed to force issuance of all compilePat warnings--- (so not strictly a debugging flag anymore).--- [Except it didn't work...]---- #define NFDATA_INSTANCE_PATTERN 0  -- now a .cabal flag--#define DO_DERIVE_DATA_AND_TYPEABLE 0-#define DO_DERIVE_ONLY_TYPEABLE 1-#if DO_DERIVE_ONLY_TYPEABLE && DO_DERIVE_DATA_AND_TYPEABLE-#undef DO_DERIVE_ONLY_TYPEABLE-#warning DO_DERIVE_ONLY_TYPEABLE forced 0, due to DO_DERIVE_DATA_AND_TYPEABLE being 1.-#define DO_DERIVE_ONLY_TYPEABLE 0-#endif---- Now specified via --flag=[-]USE_WWW_DEEPSEQ---- #define USE_WW_DEEPSEQ 1------------------------------------------------------------------------------------- Good idea: Let * be followed by an integer N.--- This shall have the semantics that, when that node--- is matched in the pattern, instead of rnf it is forcen N'd.---- There may be fusion possible (which is worth trying here--- for practise, even if this lib is not used much):------   forcep p1 . forcep p2 = forcep (unionPat [p1,p2])------ This holds if pattern doesn't contain #, or any (type-)constrained--- subpatterns -- the latter might work out, if exclude # from them too,--- but I'm not sure.  With #, we lose even monotonicity, let alone--- the above law.------ For the above to hold, remember, the union must have exactly--- the "forcing potential" of the LHS -- no more, no less.-----------------------------------------------------------------------------------#if DO_DERIVE_DATA_AND_TYPEABLE-  {-# LANGUAGE DeriveDataTypeable #-}-#endif--- XXX Only needed for something in Blah.hs.--- Check into it, and see if can't get rid of the need--- for Typeable instances in here!-#if DO_DERIVE_ONLY_TYPEABLE-  {-# LANGUAGE DeriveDataTypeable #-}-#endif-#if NFDATA_INSTANCE_PATTERN-  -- For testing only (controlling trace interleaving):-  {-# LANGUAGE DeriveGeneric #-}-#endif-  {-  LANGUAGE DeriveFunctor #-}------------------------------------------------------------------------------------- |--- Module      :  Control.DeepSeq.Bounded.Pattern_old_grammar--- Copyright   :  Andrew G. Seniuk 2014-2015--- License     :  BSD-style (see the file LICENSE)------ Maintainer  :  Andrew Seniuk <rasfar@gmail.com>--- Stability   :  provisional--- Portability :  portable--------------------------------------------------------------------------------------#warning You are using the old pattern grammar (NEW_IMPROVED_PATTERN_GRAMMAR flag is False). This will be deprecated in version 0.7.--  module Control.DeepSeq.Bounded.Pattern_old_grammar---- {-# DEPRECATED "Use Wobble instead" #-}-  where-----------------------------------------------------------------------------------#if DO_DERIVE_DATA_AND_TYPEABLE-  import Data.Data ( Data )-  import Data.Typeable ( Typeable )-#elif DO_DERIVE_ONLY_TYPEABLE-  import Data.Typeable ( Typeable )-#endif--#if USE_WW_DEEPSEQ-  import Control.DeepSeq ( NFData )-#endif--  import Data.List ( intercalate )-  import Data.Char ( isDigit )-  import Data.Maybe ( isNothing, fromJust )-  import Data.Maybe ( isJust )--  import Debug.Trace ( trace )-#if USE_WW_DEEPSEQ-  -- The only uses of force in this module are for debugging purposes-  -- (including trying to get messages to be displayed in a timely-  -- manner, although that problem has not been completely solved).-  import Control.DeepSeq ( force )-#if NFDATA_INSTANCE_PATTERN-  -- for helping trace debugging-  import qualified Control.DeepSeq.Generics as DSG-  import qualified GHC.Generics as GHC ( Generic )-#endif-#endif-----------------------------------------------------------------------------------#if DO_TRACE-  mytrace = trace-#else-  mytrace _ = id-#endif-----------------------------------------------------------------------------------  data Rose a = Node a [ Rose a ]-#if NFDATA_INSTANCE_PATTERN-#if DO_DERIVE_DATA_AND_TYPEABLE-   deriving (Show, Eq, GHC.Generic, Data, Typeable)--- deriving (Show, Eq, Functor, GHC.Generic, Data, Typeable)-#elif DO_DERIVE_ONLY_TYPEABLE-   deriving (Show, Eq, GHC.Generic, Typeable)-#else-   deriving (Show, Eq, GHC.Generic)-#endif-#else-#if DO_DERIVE_DATA_AND_TYPEABLE-   deriving (Show, Eq, Data, Typeable)-#elif DO_DERIVE_ONLY_TYPEABLE-   deriving (Show, Eq, Typeable)-#else-   deriving (Show, Eq)-#endif-#endif-  type Pattern = Rose PatNode--  instance Functor Rose where-    fmap f (Node x chs) = Node (f x) (map (fmap f) chs)--#if NFDATA_INSTANCE_PATTERN-  instance NFData a => NFData (Rose a) where rnf = DSG.genericRnf-#endif-----------------------------------------------------------------------------------  -- | Note that only 'WR', 'TR' and 'PR' allow for explicit recursion.-  -- The other 'PatNode's are in leaf position when they occur in a 'Pattern'.--  data PatNode-       =--         WR  -- ^ Continue pattern matching descendants.-       | WS  -- ^ Stop recursing (nothing more forced down this branch).-       | WN Int  -- ^ @'rnfn' n@ the branch under this node.-#if USE_WW_DEEPSEQ-       | WW  -- ^ Fully force ('rnf') the whole branch under this node.-#endif-       | WI  -- ^ Don't even unwrap the constructor of this node.-{--} -- XXX It's still unclear whether TI should allow subpatterns;--- the alternative is for TI, when type doesn't match, to behave--- as "." (no subpatterns); but since I say "otherwise behave as TR",--- and TR says "continue pattern matching descendants", this seems to--- say that subpatterns should be permitted.  Certainly it's no problem--- to permit subpatterns in this case, but WI should still ignore--- subpatterns since it will always be # regardless of node type.--- (Subpatterns ought to be "safely redundant" in this case, but whether--- they are depends on implementation and needs to be tested if allow--- WI subpatterns to survive past the parser/compiler!)---   And this all applies to TW and TN too, right? Yes.--- It seems clear that TI, TW and TN should all allow subpatterns.--- And that WI, WW and WN should elide them and issue a warning.---   But, none of my present woes seem to be connected with this...--- Nonetheless, it's important to pin down the semantics.-#if 1-       | TR [String]  -- ^ Match any of the types in the list (and continue pattern matching descendants); behave as 'WI' for nodes of type not in the list. (Note this behaviour is the complement of 'TI' behaviour.)----    | TS [String]  -- ^ Same as 'TR' except no subpatterns present.-       | TN Int [String]  -- ^ @'rnfn' n@ the branch under this node, if the node type matches any of the types in the list.-#if USE_WW_DEEPSEQ-       | TW [String]  -- ^ Fully force ('rnf') the whole branch under this node, if the node type matches any of the types in the list; otherwise behave as 'WI'.-#endif-       | TI [String]  -- ^ Don't even unwrap the constructor of this node, if it's type is in the list; otherwise behave as 'WR'. (Note this behaviour is the complement of 'TR' behaviour.)-#else-       | TR [TypeRep]  -- ...-#endif-#if PARALLELISM_EXPERIMENT-       | PR  -- ^ Spark the pattern matching of this subtree.-       | PN Int  -- ^ Spark @'rnfn' n@ of this subtree.-#if USE_WW_DEEPSEQ-       | PW  -- ^ Spark the full forcing ('rnf') of this subtree.-#endif-#endif--#if NFDATA_INSTANCE_PATTERN-#if DO_DERIVE_DATA_AND_TYPEABLE-       deriving ( Show, Eq, Typeable, Data, GHC.Generic )-#elif DO_DERIVE_ONLY_TYPEABLE-       deriving ( Show, Eq, Typeable, GHC.Generic )-#else-       deriving ( Show, Eq, GHC.Generic )-#endif-#else-#if DO_DERIVE_DATA_AND_TYPEABLE-       deriving ( Show, Eq, Typeable )  -- Data apparently not needed-#elif DO_DERIVE_ONLY_TYPEABLE-       deriving ( Show, Eq, Typeable )-#else-       deriving ( Show, Eq )-#endif-#endif--#if NFDATA_INSTANCE_PATTERN-  instance NFData PatNode where rnf = DSG.genericRnf-#endif-----------------------------------------------------------------------------------#if 0-  patternShapeOK :: Data a => Pattern -> a -> Bool-  patternShapeOK pat x = S.shapeOf pat == S.shapeOf x-#endif-----------------------------------------------------------------------------------  -- Note that Ord is derived, so the order that the constructors-  -- are listed matters!  (This only affects GHC rules, SFAIK.)-  -- (This data type is here, to avoid cyclical imports which-  -- GHC pretty much is useless with.)-  ---------  -- On the one hand, we want to keep this lightweight -- it can in-  -- principle be a single bit (Insulate/Propagate), as originally planned!-  -- But the Spark thing was too useful; and Print and Error would-  -- also be useful.  But they're more orthogonal.-#if 0-  type Spark = Bool-  type PrintPeriod = Int-  type ErrorMsg = String-  data SeqNode =-           Insulate Spark PrintPeriod-         | Conduct Spark PrintPeriod-         | Force Spark PrintPeriod-         | Error ErrorMsg-    deriving ( Eq, Ord )-#else-  data SeqNode =-           Insulate----      | Conduct-         | Propagate  -- XXX if include Conduct, then rename Propagate to Force-#if PARALLELISM_EXPERIMENT-         | Spark-#endif--- These would break the Ord; and besides, they're sort of orthogonal--- (as is Spark)----      | Print Int----      | Error String-    deriving ( Eq, Ord )-#endif----------------------------------------------------------------------------------
tests/Blah.hs view
@@ -1,27 +1,3326 @@  ------------------------------------------------------------------------------- -{-# LANGUAGE CPP #-}-----------------------------------------------------------------------------------  module Blah ( run_tests ) where-----------------------------------------------------------------------------------#if NEW_IMPROVED_PATTERN_GRAMMAR--- XXX will find a solution not involving redundancy shortly.--- There's no reason to offer the braces versions in tests actually.--- But note that then the tests won't work in braces mode... Must warn.-#if USE_CURLY_BRACE_INSTEAD_OF_PAREN_FOR_SUBPATTERNS-#error To run the tests, you must build with the flag USE_CURLY_BRACE_INSTEAD_OF_PAREN_FOR_SUBPATTERNS set False (the default).---import Blah_new_grammar_braces-#else-  import Blah_new_grammar-#endif-#else-  import Blah_old_grammar-#endif---------------------------------------------------------------------------------+-- Disclaimer: I've not used HUnit yet. I'm using it only+-- as a "hook" so can compile/test in less clock time...+-- (I forget the details of how/why.)+--+-- Obviously, this should use proper HUnit eventually.+-- And QuickCheck and SmallCheck, DEFINITELY!!!...+-- This is a great case for those; and shape-syb no less.+--+-- This file could be cleaned up a lot, but that's+-- not quite a priority at the moment...+--+-- The reason I shied away from making it real HUnit tests+-- is probably related to the fancy exception throwing/catching+-- and catching of all exceptions (including error), etc.+-- Which was aggravated by the nature of this project and+-- of its tests, which hit bottom as a matter of course...+--+-- Yeah; and looking at examples of QuickCheck and SmallCheck,+-- it's still not clear to me how to work bottoming-out+-- into my tests.+--   I guess I could catch the bottoms in my code, and return+-- some reserved value to indicate that it occurred?...++-------------------------------------------------------------------------------++{-# LANGUAGE CPP #-}++-------------------------------------------------------------------------------++#define FOCUS_TEST 0+#define TRY_THIS 1+#define USE_TRACE 0++-------------------------------------------------------------------------------++-- Later: This may work with some versions of GHC, but I'm quite+-- sure I've seen it not work with some recent version...+-- Unfortunately, this doesn't work -- all pragmas are processed,+-- regardless of CPP (so CPP must run after).+-- The fact the CPP itself can be set via a pragma complicates this.+-- It could be made an exception, and the LANGUAGE CPP pragma could+-- be parsed regardless of CPP context (as all pragmas currently are).+-- As it is, we need separate source modules, and to switch at+-- import statements (and in the .cabal file).+-- THIS IS A BUG.+-- So anyhow, this is only here as a reminder:+---  #if ! HASKELL98_FRAGMENT+---  {-# LANGUAGE ... #-}+---  #endif+  {-# LANGUAGE DeriveGeneric #-}+  {-# LANGUAGE DeriveDataTypeable #-}  -- to make BottomedOut+  {-# LANGUAGE BangPatterns #-}++  {-# LANGUAGE Rank2Types #-}  -- for SYB (testing rnfpDyn and friends)++-------------------------------------------------------------------------------++  -- SOP pragmas:++  -- Not necessarily needed to work with SOP, but I think it'll+  -- be helpful here [?] ...+  {-# LANGUAGE ScopedTypeVariables #-}+  {-  LANGUAGE AllowAmbiguousTypes #-}++-- Actually, CPP doesn't work with Haskell (GHC) pragmas last I checked...+#if USE_SOP+  {-# LANGUAGE DataKinds #-}+  {-# LANGUAGE TypeFamilies #-}+  {-# LANGUAGE ConstraintKinds #-}+#if __GLASGOW_HASKELL__ < 708+  {-# LANGUAGE GADTs #-}+#endif+  {-# LANGUAGE TemplateHaskell #-}+#endif++-------------------------------------------------------------------------------++  module Blah ( run_tests ) where++-------------------------------------------------------------------------------++--import Common+  import Bottom+  import Foo+  import FooG++--import Control.DeepSeq.Generics+  import Control.DeepSeq.Bounded+--import Control.DeepSeq.Bounded hiding ( F )+  import Control.DeepSeq.Bounded.Generic++#if 0+  import GHC.Generics+--import GHC.Generics ( Generic )+#endif++  import Data.Maybe++  import Control.Exception+--import Control.Monad ( guard )+  import Control.Monad ( replicateM )+  import Control.Monad ( when )+  import Data.Typeable ( Typeable )+  import Data.Typeable ( typeOf )++  import Data.Data ( Data )++  import Data.Generics.Aliases ( mkQ, extQ, GenericQ )++--import Util ( spoor )+  import Debug.Trace ( trace )+  import Control.DeepSeq++#if __GLASGOW_HASKELL__ >= 708+  import Data.Typeable ( Proxy(..) )+#endif++#if USE_SOP+  import Generics.SOP hiding ( Shape )+#endif++  import System.Random++  import Data.List ( intercalate )++  import System.IO.Unsafe ( unsafePerformIO )++-------------------------------------------------------------------------------++  -- For convenience in GHCi interactive sessions:+  cp = compilePat+--cp = compilePat+  ip = intersectPats+  isp = subPat++  -- For more compact test expressions:+-- XXX Refer to Seqable.hs for comments about JUST_ALIAS_GSEQABLE.+#if 1+#if JUST_ALIAS_GSEQABLE+  fI :: forall a. Generic a => a -> a+  fI = force_ Insulate+  fP :: forall a. Generic a => a -> a+  fP = force_ Propagate+#else+  fI :: forall a. NFDataN a => a -> a+  fI = force_ Insulate+  fP :: forall a. NFDataN a => a -> a+  fP = force_ Propagate+#endif+#else+  fI = force_ Insulate+  fP = force_ Propagate+#endif++  gI :: forall a. Generic a => a -> a+  gI = gforce_ Insulate+  gP :: forall a. Generic a => a -> a+  gP = gforce_ Propagate++-------------------------------------------------------------------------------++  run_tests :: IO Int+  run_tests = do++    putStr "\n"+    -- So can notice the start when scrollback, esp. in ghci reload/reruns.+--  replicateM 50 $ putStrLn "################################################################################"+    putStrLn "\nTesting."+    putStrLn "\nNote that  __ = undefined  (abbrev. occurring in what follows)."++    -- XXX NOTE XXX+    --+    -- Most of the comments are pre-new-grammar (most of the comments+    -- are actually from no later than September 2014).  Some have been+    -- revised in light of the new grammar; many have not...++#if ! FOCUS_TEST++    let shs s p =+         unsafePerformIO $ +         catch+          ( return $! force $ "input:                       " ++ show p ++ "\n" ++ "expect: " ++ s ++ "\n   got: " ++ showPat p )+          ( \e -> do let err = show (e :: ErrorCall)+                     return err )++    let eas = emptyPatNodeAttrs+    let neas = eas { depth = 23 }+    let peas = eas { doSpark = True }+    let pneas = neas { doSpark = True }+    let teas = eas { doConstrainType = True, typeConstraints = ["Int"] }+    let nteas = teas { depth = 23 }+    let pteas = teas { doSpark = True }+    let pnteas = nteas { doSpark = True }+    let teas2 = eas { doConstrainType = True, typeConstraints = ["[Int]"] }+    let pteas2 = teas2 { doSpark = True }+    let ptneas2 = pteas2 { depth = 23 }+    let xxptneas2 = ptneas2 { doTrace = True, doPing = True }+    let xxpeas = eas { doSpark = True, doTrace = True, doPing = True }++    putStrLn "\nTesting showPat"+    putStrLn "---------------"++    putStrLn $ shs "*" $ Node (WW eas) []+    putStrLn $ shs "." $ Node (WI eas) []+    putStrLn $ shs "!" $ Node (WS eas) []+    putStrLn $ shs "()" $ Node (WR eas) []+    putStrLn $ shs "(*)" $ Node (WR eas) [Node (WW eas) []]+    putStrLn $ shs "(**)" $ Node (WR eas) [Node (WW eas) [],Node (WW eas) []]+    putStrLn $ shs "(!*)" $ Node (WR eas) [Node (WS eas) [],Node (WW eas) []]+    putStrLn $ shs "(.!)" $ Node (WR eas) [Node (WI eas) [],Node (WS eas) []]+    putStrLn $ shs "(.)" $ Node (WR eas) [Node (WI eas) []]+    putStrLn $ shs "((.))" $ Node (WR eas) [Node (WR eas) [Node (WI eas) []]]+    putStrLn $ shs "(*.(*.(*.)**.*).*)" $ Node (WR eas) [Node (WW eas) [],Node (WI eas) [],Node (WR eas) [Node (WW eas) [],Node (WI eas) [],Node (WR eas) [Node (WW eas) [],Node (WI eas) []],Node (WW eas) [],Node (WW eas) [],Node (WI eas) [],Node (WW eas) []],Node (WI eas) [],Node (WW eas) []]+    putStrLn $ shs "(.!(*23*))" $ Node (WR eas) [Node (WI eas) [],Node (WS eas) [],Node (WR eas) [Node (WN neas) [],Node (WW eas) []]]+#if USE_PAR_PATNODE+    putStrLn $ shs "(.=(=*23*)*)" $ Node (WR eas) [Node (WI eas) [],Node (WR peas) [Node (WN pneas) [],Node (WW eas) []],Node (WW eas) []]+#endif+    putStrLn $ shs ":Int:()"    $ Node (TR teas)  []+--- putStrLn $ shs ":Int:!"     $ Node (TS teas)  []+    putStrLn $ shs ":Int:*23"   $ Node (TN nteas) []+    putStrLn $ shs ":Int:*"     $ Node (TW teas)  []+    putStrLn $ shs ":Int:."     $ Node (TI teas)  []+    putStrLn $ shs "=:Int:()"    $ Node (TR pteas)  []+--- putStrLn $ shs "=:Int:!"     $ Node (TS pteas)  []+    putStrLn $ shs "=:Int:*23"   $ Node (TN pnteas) []+    putStrLn $ shs "=:Int:*"     $ Node (TW pteas)  []+    putStrLn $ shs "=:Int:."     $ Node (TI pteas)  []+    putStrLn $ shs "=:[Int]:()"   $ Node (TR pteas2)  []+    putStrLn $ shs "=:[Int]:*"   $ Node (TW pteas2)  []+    putStrLn $ shs "=:[Int]:*23"   $ Node (TN ptneas2)  []+    putStrLn $ shs "=+^()"        $ Node (WR xxpeas)  []  -- canonical ordering+--  putStrLn $ shs "+^=()"        $ Node (WR xxpeas)  []+    putStrLn $ shs "=+^:[Int]:*23"   $ Node (TN xxptneas2)  []++--  let shp s = s ++ replicate (30 - length s) ' ' ++ show (compilePat s)+    let shp s = +         unsafePerformIO $ do+           putStr $ s ++ replicate (30 - length s) ' '+           catch+            ( return $! force $ show (compilePat s) )+--          ( return $! force $ s ++ replicate (30 - length s) ' ' ++ show (compilePat s) )+            ( \e -> do let err = show (e :: ErrorCall)+                       return err )++    putStrLn "\nPattern                       Compiles to"+    putStrLn "-----------------------------------------"++--  putStrLn $ shp ""  -- empty pattern syntax error+    putStrLn $ shp "."  -- Node WI []  -- no parent to absorb (should be error)+    putStrLn $ shp "!"  -- Node WS []+    putStrLn $ shp "*"  -- Node WW []+    putStrLn $ shp "*!"  -- "disconnected pattern (not rooted)"+    putStrLn $ shp "()"  -- Node WR []+    putStrLn $ shp "(.)"  -- Node WR [Node WW []]+    putStrLn $ shp "(*)"  -- Node WR [Node WW []]+    putStrLn $ shp "(**)"  -- Node WR [Node WW [],Node WW []]+    putStrLn $ shp "(!*)"  -- Node WR [Node WS [],Node WW []]+    putStrLn $ shp "(.!)"  -- Node WR [Node WI [],Node WS []]+    putStrLn $ shp "(.(.))"  -- Node WR [Node WI [],Node WR [Node WI []]]+    putStrLn $ shp "((.))"  -- Node WR [Node WR [Node WI []]]+    putStrLn $ shp "(.(().))"  -- Node WR [Node WI [],Node WR [Node WR [],Node WI []]]+    putStrLn $ shp "(*.*.*.**.*.*)"+    putStrLn $ shp "(*.(*.(*.)*)*(.*).*)"+    putStrLn $ shp "(*.(*.(*.)*)*.*)"+    putStrLn $ shp "(*.(*.(*.)*)(*)(.*).*)"+    putStrLn $ shp "((!(!)(((!).!(!))))!(!(!)))"  -- of leaky fame+    putStrLn $ shp "*23"+    putStrLn $ shp "(.!(*23*))"+    putStrLn $ shp ":Int:"  -- see what happens+    putStrLn $ shp ":Int:()"+    putStrLn $ shp ":Int:!"  -- see what happens+    putStrLn $ shp ":Int."  -- see what happens+    putStrLn $ shp ":Int:."+    putStrLn $ shp ":Int:*"+    putStrLn $ shp ":Int*23"  -- see what happens+    putStrLn $ shp ":Int:*23"+#if USE_PAR_PATNODE+    putStrLn $ shp "=."  -- Node WI [] (doSpark=True)+    putStrLn $ shp "=!"  -- Node WS [] (doSpark=True)+    putStrLn $ shp "=*"  -- Node WW [] (doSpark=True)+    putStrLn $ shp "(.=(=*23*)*)"+    putStrLn $ shp "=:Int"  -- see what happens+    putStrLn $ shp "=:Int:()"+    putStrLn $ shp "=:Int:!"  -- see what happens+    putStrLn $ shp "=:Int:."+    putStrLn $ shp "=:Int:*"+    putStrLn $ shp "=:Int*23"  -- see what happens+    putStrLn $ shp "=:Int:*23"+    putStrLn $ shp "=:[Int]:()"+    putStrLn $ shp "=:[Int]:*"+    putStrLn $ shp "=:[Int]:*23"+    putStrLn $ shp "=+^()"+    putStrLn $ shp "+^=()"+    putStrLn $ shp "=+^:[Int]:*23"+#endif+    putStrLn $ shp " ! :G; How:. : A ()$)%&()(*&)*(_)+\"}>>=?}{\\:|B ; C ; D E F : ( . . ) "++    putStrLn ""+#endif++--  error "DEVEXIT"++#if ! FOCUS_TEST++#if 1+    let test_patterns10 = [+           (4,  "")  -- syntax error+         , (4,  "!..")  -- syntax error (disconnected pattern)+         , (1,  "(!..)")  -- fail+         , (5,  "(().().())")+         , (2,  "*")+         , (2,  "(***)")+         , (1,  "(...)")+         , (1,  "(*..)")+         , (2,  "(**.)")+         , (2,  "(..*)")++           -- Remember, [a] is a recursive binary ctor app!...+           -- The next four tests give instance errors for [a].+           -- (Later: Silent pattern-match failures, that is, because+           -- WARN_PATTERN_MATCH_FAILURE is False by default.)+           -- But if testing expTG_* (GNFDataP/grnfp) then+           -- it's no longer a list...+         , (13, "((*.*).)")+         , (13, "((*...).)")+         , (13, "((*....).)")+         , (13, "((*....)!)")  -- used to have "23" but that's incorrect++         , (1,  "((*.)*)")  -- used to have "2" but that's incorrect+         , (1,  "((*.).)")+         , (1,  "((*(.*)).)")+         , (1,  "((*(*.)).)")  -- used to have "2" but that's incorrect+         , (13, "((((.*))).)")  -- See above comment about [a] instance+         , (1,  "(.(((.*))).)")  -- used to have "2" but that's incorrect++           -- (See Book, p.84.)+         , (1,  "(!(!(.(!!))).)")+         , (1,  "(!(!(.*)).)")+         , (1,  "(*(*(.*)).)")+         , (2,  "(..*)")+         , (2,  "(*.*)")+         , (1,  ":Tuple3:(*(*(.*)).)")  -- oops...+         , (1,  ":(,,):(*(*(.*)).)")+         , (2,  ":(,,):(*(*(!*)).)")+         , (1,  ":Bool:(***)")  -- XXX makes no sense (but works) -- oh well;+                                -- this is an important point to note in+                                -- docs/blog also... [Later: old comment;+                                -- syntax has changed a lot since written...]+         , (4,  ":Bool*")  -- used to be 1, but now it's a syntax error+         , (1,  ":Bool:*")  -- new syntax requires terminating empty {}+         , (2,  ":(,,):*")+         , (2,  "(*.!)")++-- XXX OLD COMMENT BUT BEWARE... XXX+--   "This does what-- it says, it will only match a childless Bool node.+--    Still need to implement # when not in type."+-- Since {} are obligatory in the new grammar, for type-constrained * and #,+-- better make sure the semantics are implemented as specified. (They are+-- specified in the Pattern module Haddock API page.)++           -- New comment: Since #::typename can only choose+           -- between effectively behaving as either WI or WS,+           -- it is never recursive:  It forces at most one node!+         , (1,  "(*:Bool:..)")  -- was 2 which is incorrect+         , (1,  "(*:Int:..)")  -- was 2 which is incorrect+         , (1,  "(*:(,):..)")  -- was 2 which is incorrect+         , (1,  "(*:OutOfScopeType:..)")  -- was 2 which is incorrect+         , (1,  "(*:[Int]:..)")+         , (2,  "(*:[Int]:.!)")+         , (1,  "(*.:Bool:.)")+         , (2,  "(*.:Int:.)")+         , (2,  "(*.:(,):.)")+         , (2,  "(*.:OutOfScopeType:.)")+         , (2,  "(*.:[Int]:.)")++         , (2,  "(*:[Int]:*.)")+         , (1,  "(*:Bool:*.)")+         , (1,  "(*:Int:*.)")+         , (1,  "(*:(,):*.)")+         , (1,  "(*:OutOfScopeType:*.)")+         , (2,  "(*.:Bool:*)")+         , (1,  "(*.:Int:*)")+         , (1,  "(*.:(,):*)")++         , (1,  "(**2.)")+         , (2,  "(**3.)")+         , (1,  "(*:G2:..)")+         , (1,  "(*:Int:..)")+         ]+    doit14 True test_patterns10+--  doit10 True test_patterns10+#endif++#if USE_SOP++-- Seems fine; it's not a good test as the # in the middle+-- only forces one ctor when type doesn't match, and need+-- to force one more level to hit an undefined.+#if 1+    let test_patterns11 = [+           (4,  "")  -- syntax error++         , (1,  "(*:G2:..)")+         , (1,  "(*:Int:..)")+         ]+    doit15 True test_patterns11+#endif++#endif++#if USE_SOP++    -- exp = G2 5 __ 7 :: TG+-- All fine last checked.+#if 1+    let test_patterns12 = [++--         (4, "..")++           (2, "*")+         , (1, "*0")+         , (1, "*1")+         , (2, "*2")+         , (2, "*3")++         , (1, "(!.!)")+         , (2, "(!!!)")+         , (1, "(!!)")  -- due to patmatch failure+         , (2, "(!!!)")+         , (1, "(!!!!)")  -- due to patmatch failure++         , (1, ":G1:(!!)")+         , (1, ":G1:(!!!)")+         , (1, ":G2:(!!)")+         , (2, ":G2:(!!!)")+         , (1, ":TG:(!!!)")++         , (1, ":G1:*")+         , (2, ":G2:*")+         , (1, ":TG:*")+         , (2, ":Int:.")+         , (2, ":G1:.")+         , (1, ":G2:.")+         , (2, ":TG:.")+         , (1, ":Int:.")++         , (1, ":G1:.(!!)")  -- (used to be a syntax err)+         , (1, ":G1:*(!!)")  -- (used to be a syntax err)++         ]+    doit16 True test_patterns12++--  error "DEVEXIT"+#endif++#endif++#if USE_SOP++-- This should work, once the patterns are right for lists,+-- but until I get non-list generic tests working I'm not+-- going to struggle with this.+#if 0+    let test_patterns13 = [+-- expTH_1 = H2 1 [H1 2.3, H3, H4 (H3, I3 I2 (H1 4.5))] False    (for ref.)+-- expTH_4 = H2 1 [H1 2.3, H3, H4 (__, I3 __ (H1 4.5))] __       (in use)+           (4,  "")  -- syntax error+         , (1,  "(!(!(!((.(.!))!))).)")+         , (2,  "(!(!(!((!(.!))!))).)")+         , (2,  "(!(!(!((.(!!))!))).)")+         , (2,  "(!(!(!((.(.!))!)))!)")+         , (1,  "(!((!)(!((.(.(!)))!))).)")+         , (2,  "(!((!)(!((!(.(!)))!))).)")+         , (2,  "(!((!)(!((.(!(!)))!))).)")+         , (2,  "(!((!)(!((.(.(!)))!)))!)")+         , (2,  "(!((!)(!((.(.!(!)))!)))!)")+         ]+    doit17 True test_patterns13+#endif++#if 1+    let test_patterns14 = [+-- expTJ_1 = J2 ( 1, J4 ( J3, K3 K2 ( J1 4.5))) False     -- for ref.+-- expTJ_2 = J2 ( 1, J4 ( J3, K3 __ ( J1 4.5))) False+-- expTJ_3 = J2 ( 1, J4 ( __, K3 K2 ( J1 4.5))) False+-- expTJ_4 = J2 ( 1, J4 ( __, K3 __ ( J1 4.5))) __        -- in use+--           {  { {} {  { {}  {  {} { {  {} }}}}}}}+-- XXX The tuples are ctors, I forgot...+           (4 ,  "")  -- syntax error+#if 0+         , (1 ,  "!")+         , (13,  "()")+         , (13,  "(!)")+         , (2 ,  "(!!)")+         , (13,  "(!!!)")+         , (13,  "(!!!!)")+         , (13,  "(!!!!!)")+#endif+-- expTJ_1 = J2 ( 1, J4 ( J3, K3 K2 ( J1 4.5))) False     -- for ref.+--                J2 { (,) { I J4 { (,) { J3 K3 { K2 { J1 { 4.5 } } } } } } False }+--                .  {  .  { .  . {  .  { .  .  {  . { .  { .   } } } } } } . }+           -- this pattern also double-checked on paper+         , (2 ,  "((!((!(!(!)))))!)")+--       , (1 ,  "((!((!(.(!))))).)")  -- blows (in partic. expTJ_2)+         , (1 ,  "((!((.(!(!))))).)")  -- blows (in partic. expTJ_3)+--       , (1 ,  "((!((.(.(!))))).)")  -- blows (in partic. expTJ_4)+#if 0+         , (1 ,  "((!(.(..(..(.))))).)")  -- = "((!(.)).)" (no blow)+         , (1 ,  "((!(.(.(.(!))))).)")  -- = "((!(.)).)" (no blow)+         , (1 ,  "((!(.(!(.(!))))).)")  -- = "((!(.)).)" (no blow)+         , (1 ,  "((!((!(.(!))))).)")  -- blows+         , (1 ,  "((!((..(..(.))))).)")  -- blows+         , (1 ,  "((!(.)).)")             -- confirming (no blow)+#endif+#if 0+         , (2 ,  "((!((!(((!))))))!)")+         , (1 ,  "((!((.(.((!)))))).)")+         , (1 ,  ".(.(..(.(..(.(.(.)))))).)")+         , (1 ,  "(.(..(.(..(.(.(.)))))).)")+         , (1 ,  "((..(.(..(.(.(.)))))).)")+         , (1 ,  "((!(.(..(.(.(.)))))).)")+#endif+#if 0+         , (1,  "(!(.(.(!))).)")+         , (2,  "(!(!(!(!)))!)")+         , (2,  "*")+         , (2,  "(!*!)")+         , (2,  "(***)")+#endif+         ]+    doit18 True test_patterns14+#endif++#if 1+    let test_patterns14b = [+-- expTJ_5 = J2 ( 1, J4 ( __, K2 )) False+           (4 ,  "")  -- syntax error+         , (2 ,  "((!((!!)))!)")+         , (1 ,  "((!((.!)))!)")+         , (1 ,  "((!(.(!!)))!)")+         , (1 ,  "((!.((!!)))!)")+         ]+    doit18b True test_patterns14b+#endif++#if 1+    let test_patterns14c = [+-- expTJ_6 = J4 ( __, K2 ) False+           (4 ,  "")  -- syntax error+         , (2 ,  "((!!))")+         , (1 ,  "((.!))")+         , (1 ,  "(.(!!))")+         , (1 ,  ".((!!))")+         ]+    doit18c True test_patterns14c+#endif++#if 1+    let test_patterns14d = [+-- expTJ_7 = ( __, K2 )+           (4 ,  "")  -- syntax error+         , (2 ,  "(!!)")+         , (1 ,  "(.!)")+         , (1 ,  ".(!!)")+         ]+    doit18d True test_patterns14d+#endif++#if 1+    let test_patterns14e = [+-- expTJ_8 = __ :: TJ+           (4 ,  "")  -- syntax error+         , (2 ,  "!")+         , (1 ,  ".")+         ]+    doit18e True test_patterns14e+#endif++#if 1+    let test_patterns14f = [+-- expTJ_8 = (K5 (__::TJ))+           (4 ,  "")  -- syntax error+         , (1 ,  "!")+         , (1 ,  "(.)")+         , (2 ,  "(!)")+         , (1 ,  ".")+         ]+    doit18f True test_patterns14f+#endif++-- These work!+#if 1+    let test_patterns14g = [+#if TRY_THIS+-- exp = K3 (__::TK) J3+#else+-- exp = K3 K2 (__::TJ)+#endif+           (4 ,  "")  -- syntax error+         , (1 ,  "!")+#if TRY_THIS+         , (1 ,  "(.!)")+         , (2 ,  "(!.)")+#else+         , (2 ,  "(.!)")+         , (1 ,  "(!.)")+#endif+         , (2 ,  "(!!)")+         , (1 ,  ".")+         ]+    doit18g True test_patterns14g+#endif++-- Okay last I checked.+#if 1+    let test_patterns15 = [+-- expTL_1 = L1 5.6 (M1 True)+-- expTL_2 = L1 5.6 (M1 __)+-- expTL_3 = L1 5.6 __+-- expTL_4 = L1 __ (M1 True)+           (4 ,  "")  -- syntax error+#if 0+#elif 1+         , (1 ,  ".")+         , (5 ,  ".(!!)")+         , (1 ,  "(!!)")+         , (2 ,  "((!)!)")+         , (1 ,  "((.)!)")+#elif 0+         , (1 ,  ".")+         , (5 ,  ".(!!)")+         , (2 ,  "(!!)")+         , (1 ,  "(.(!))")+#elif 0+         , (1 ,  ".")+         , (5 ,  ".(!!)")+         , (2 ,  "(!!)")+         , (2 ,  "(!(!))")+         , (2 ,  "(!(.))")+#elif 0+         , (1 ,  ".")+         , (5 ,  ".(!!)")+         , (1 ,  "(!!)")+         , (2 ,  "(!(!))")+         , (1 ,  "(!(.))")+#endif+         ]+    doit19 True test_patterns15+#endif++-- Good test case for the problem. No tuples; every step is generic.+#if 1+    let test_patterns16 = [+-- expTK_1 = K3 K2 ( J1 4.5)     -- for ref.+-- expTK_2 = K3 __ ( J1 4.5)+--           {  {} { {  {} }}}+-- XXX Don't forget tuples are ctors...+           (4 ,  "")  -- syntax error+#if 0+         , (2 ,  "(!!)")+         , (1 ,  "(.!)")+         , (2 ,  "(!.)")+         , (1 ,  "(..)")+#else+         , (2 ,  "(!(!))")  -- ok+         , (1 ,  "(..)")     -- X+         , (1 ,  "(.!)")     -- X+         , (1 ,  "(.(.))")  -- X+         , (1 ,  "(.(!))")  -- X+         , (2 ,  "(!.(!))")  -- X  & this does give the . with subpat. warning!+         , (2 ,  "(!.(.))")  -- X  & why no warning about . with subpattern?+         , (1 ,  "(..(.))")  -- X  & why no warning about . with subpattern?+         , (1 ,  ".(..(.))")  -- ok & why no warning about . with subpattern?+#endif+         ]+    doit20 True test_patterns16+#endif++#endif++---------------------------------------------++#endif++#if 0 || ! FOCUS_TEST++-- Later: Oh! Don't be silly -- it's all compile-time, and the+-- size or shape of the list is irrelevant -- which rules+-- will fire depends on THIS FILE'S SOURCE CODE (not it's+-- data, including static values)!+-- XXX Even with empty list, the same rule firings occur!...+-- If comment out this block however, the rules do not fire!+#if 1+    -- Testing composition and union:+    let test_patterns11 = [+           (1, "!", "!")+         , (2, "!", "*")+         , (2, "*", "!")+         , (2, "*", "*")+         , (2, "(!!!)", "(*!!)")+         , (2, "(*!!)", "(!!*)")+         , (2, "(!*.)", "(!.!)")+         ]+    doit11 True test_patterns11+#endif++#endif++#if ! FOCUS_TEST++#if 1+    -- Testing splicePats+    let test_patterns12a = [+           (1, "!", [], [(0,"*")])+         , (1, "()", [], [(0,"*")])+         , (1, "!", [0], [(0,"*")])+         , (1, "(!!)", [], [(0,"*")])+         , (1, "(!!)", [0], [(0,"*")])+         , (1, "(!!)", [2], [(0,"*")])+         , (1, "(!!)", [], [(0,"*"),(0,".")])+         , (1, "(!!)", [], [(0,"*"),(1,".")])+         , (1, "(!!)", [], [(1,"."),(0,"*")])+         , (1, "(!!)", [], [(0,"*"),(2,".")])+         , (1, "(!!)", [], [(2,"*"),(2,"."),(2,".")])+         , (1, "(!!)", [], [(-1,"*")])+         , (1, "(!!)", [], [(0,"*")])+         , (1, "(!!)", [], [(1,"*")])+         , (1, "(!!)", [], [(2,"*")])+         , (1, "(!!)", [], [(3,"*")])+         , (1, "(!(!!)!)", [1], [(0,"*")])+         , (1, "(!(!!)!)", [1], [(0,"*3"),(1,"."),(2,"*")])+         , (1, "(!(!!)!)", [1,0], [(0,"*"),(0,".")])+         , (1, "((!!!)(()!)!)", [1], [(0,"*"),(0,".")])+         , (1, "((!!!)(()!)!)", [1,0], [(0,"*"),(0,".")])+         , (1, "((...)(().).)", [1,0], [(0,"*"),(0,".")])+         , (1, "(:(,,):(...)(().).)", [1,0], [(0,"*"),(0,".")])+         ]+    doit12 True test_patterns12a+#endif++#if 1+    -- Testing elidePats+    -- XXX There's a nice way to do this, by rewriting each test+    -- automatically (or via manual regex substitutions) so that+    -- the target is the result of the corresponding splicePats test.+    -- Unfortunately, the expected results are not encoded for+    -- the splicePats test, so oh well, for now at least, just+    -- build some fresh tests!+    let test_patterns12b = [+           (1, "((!!)!(!))", [], [0])+         , (1, "((!!)!(!))", [0], [0])+         , (1, "((!!)!(!))", [1], [0])+         , (1, "((!!)!(!))", [1], [1])+         ]+    doit12b True test_patterns12b+#endif++#endif++#if ! FOCUS_TEST++#if 1+    -- Testing erodePat+    -- XXX Note we toss the stdgen when done here...+    stdgen12c <- newStdGen+--  let stdgen12c = mkStdGen seed+    let test_patterns12c = [+           (1, "((!!)!(!))", [])  -- recursive test...+         ]+--  stdgen12c <- doit12c True test_patterns12c+#if 0+    stdgen12c' <- doit12c True test_patterns12c stdgen12c+    stdgen12c'' <- doit12c True test_patterns12c stdgen12c'+    stdgen12c''' <- doit12c True test_patterns12c stdgen12c''+    return ()+#else+#if 1+    stdgen12c' <- doit12c True test_patterns12c stdgen12c 5+    return ()+#else+    doit12c True test_patterns12c stdgen12c+      >>= doit12c True test_patterns12c+      >>= doit12c True test_patterns12c+      >>= doit12c True test_patterns12c+      >>= doit12c True test_patterns12c+      >>= doit12c True test_patterns12c+      >>= doit12c True test_patterns12c+      >>= doit12c True test_patterns12c+      >>= doit12c True test_patterns12c+#endif+#endif+#endif++#endif++#if 0 || ! FOCUS_TEST++#if 1+    -- Testing anything else we can with a single function!+    -- (Getting sick of this cloning.)+    -- Functions are listed in (current) export order.+    -- Things still needing testing are >'d.+    -- Things tested but failing some tests have a *.+    -- +    -- XXX Wow does this ever look cleaner with "Pat" instead of "Pattern"!...+    -- Fortunately splicePats is already tested separately; the rest+    -- we need to test deal only in Pat args (or list of same), so+    -- we can pass a couple [Pat] to test13 along with an Int code+    -- to control delegation.+    --  1    unionPats       :: [ Pat ] -> Pat+    --  2    intersectPats   :: [ Pat ] -> Pat+    --  3    subPat          :: Pat -> Pat -> Bool+--  --  4    unionPatssStr   :: [ String ] -> String+    --  5    emptyPat        :: Pat+    --  6    mkPat           :: forall d. Data d => d -> Pat+    --  7    growPat         :: forall d. Data d => Pat -> d -> Pat+    --  8    shrinkPat       :: Pat -> Pat+    --  9    liftPats        :: [ Pat ] -> Pat+    -- 10    splicePats      :: Pat -> [Int] -> [(Int, Pat)] -> Pat+    -- 11    isPath          :: Pat -> Bool+    -- 12    mkPatN          :: Int -> Pat -> Bool+    -- 13    elidePats       :: Pat -> Pat -> [Int] -> Pat+    -- 14    erodePat        :: StdGen -> [Int] -> Pat -> (Pat, StdGen)+    let test_patterns13 = [+           ( 1, ["(!!!)", "(!.)"], "")+         , ( 2, ["(!!!)", "(!.)"], "")+         , ( 3, ["!", "!"], "True")+         , ( 3, [".", "."], "True")+         , ( 3, ["*", "*"], "True")+         , ( 3, ["!", "()"], "True")+         , ( 3, ["()", "!"], "False")+         , ( 3, ["()", "(!)"], "False")+         , ( 3, ["(!)", "(!)"], "True")+         , ( 3, ["(!)", "(!!)"], "False")+         , ( 3, ["(!)", "((!))"], "True")+         , ( 3, ["(!!)", "(!.)"], "False")+         , ( 3, ["(!.)", "(!!)"], "True")+         , ( 3, ["(!!)", "(!!!)"], "False")+         , ( 3, ["()", "(!!!)"], "False")+         , ( 3, ["!", "(*!.)"], "True")+         , ( 3, [".", "(*!.)"], "True")+         , ( 3, ["*", "(*!.)"], "False")+         , ( 3, ["*", "(*)"], "False")+         , ( 3, ["*", "(**)"], "False")+         , ( 4, ["(!!!)", "(!.)"], "")+         , ( 5, ["(!!!)", "(!.)"], "")+         , ( 6, ["(!!!)", "(!.)"], "")+         -- matching against val = ([1,2,3::Int],(False,"foo"))+         -- mkPat val = "((!(!(!!)))(!(!(!(!!)))))"+         , ( 7, ["((!(!!))(!(!!)))"], "")+         , ( 7, ["((!(!(!!)))(!(!(!!))))"], "")+         , ( 7, ["((!(!(!!)))(!(!(!(!!)))))"], "")+         , ( 8, ["((!(!(!!)))(!(!(!(!!)))))"], "")+         , ( 8, ["((!(!(!!)))(!(!(!!))))"], "")+         , ( 8, ["((!(!!))(!(!!)))"], "")+         , ( 8, ["((.(!!))(.(*3!)))"], "")+         , ( 8, ["((.!)(.!))"], "")+         , ( 8, ["(!!)"], "")+         , ( 8, ["!"], "")+         , ( 9, ["(!!!)", "(!.)"], "")+         , (10, ["(!!!)", "(!.)"], "")+         , (11, ["(!!!)", "(!.)"], "")+         , (12, ["(!!!)", "(!.)"], "")+    -- 12    mkPatN          :: Int -> Pat -> Bool+    -- 13    elidePats        :: Pat -> Pat -> [Int] -> Pat+    -- 14    erodePat        :: StdGen -> [Int] -> Pat -> (Pat, StdGen)+         ]+    putStrLn "==================================================="+    putStrLn "Testing miscellaneous PatUtil functions..."+    doit13 True test_patterns13+#endif++#endif++#if ! FOCUS_TEST++#if 1+    -- Testing fusion+    putStrLn "\nTesting fusion\n-fenable-rewrite-rules -O -ddump-rules -ddump-simpl-stats -ddump-rule-firings\n"+    let exp12 = (3.4, [5,__,7], __) :: (Float, [Int], Bool)+    let get12 (_,xs,_) = (xs!!2)+    putStrLn $ show $ get12 $ ( forcep ":Bool:*" . forcep ":Int:*" ) exp12+    putStrLn $ show $ get12 $ ( forcep ":Bool:*" . forcep_ (compilePat ":Int:*") ) exp12+    putStrLn $ show $ get12 $ ( forcep_ (compilePat ":Bool:*") . forcep ":Int:*" ) exp12+    putStrLn $ show $ get12 $ ( forcep_ (compilePat ":Bool:*") . forcep_ (compilePat ":Int:*") ) exp12+#endif++#if 1+    putStrLn $ intercalate "\n"+     [ ""+     , "expN_1 = [__] :: [Int]"+     , "expN_2 = [0,1,__,3] :: [Int]"+     , "expN_3 = (3.4, [5,__,7], True) :: (Float, [Int], Bool)"+     , "expN_4 = (3.4, [5,__,7], __) :: (Float, [Int], Bool)"+     , ""+     , "getN_1 xs = show $ ()"+--   , "getN_1 xs = show $ head xs"+--   , "getN_2 xs = show $ (xs!!1)"+     , "getN_2 xs = show $ (xs!!3)"+     , "getN_3 (_,xs,_) = show $ (xs!!2)"+     ]+    doit5 1 0 1 "" >>= putStrLn+    doit6 1 0 1 "" >>= putStrLn+    doit7 1 0 1 "" >>= putStrLn+    doit8 1 0 1 "" >>= putStrLn+#if 0+    doit9 >>= putStrLn  -- XXX broken (whatever it is)+#endif+#endif++#if 1+    putStr hdline+    putStrLn "Testing generic GNFDataN (refer to Foo.hs for the defs).\n"+    putStr hline+#if 0+#if ! USE_SOP+    putStrLn $ show $ from expTE_1+    putStrLn $ show $ from $ F 23+    putStrLn $ show $ from $ Just 11  -- bad comparison: two constructors!+#endif+--  putStrLn $ show $ from $ Just (undefined::Int)+--  putStrLn $ show $ from expTE_2+--  putStrLn $ show $ from expTE_3+    putStr "\n"+    putStrLn $ ""+           ++ "expBase7 = B2 (A1 True 4) (B1 True (A2 undefined))\n"+           ++ "expBase8 = B2 (A1 undefined 4) (B1 True (A2 undefined))\n"+           ++ "expBase9 = B2 (A1 undefined 4) (B1 undefined (A2 undefined))\n"+           ++ "...\n"+           ++ "getB_1 (B2 _ (B1 b _)) = b\n"+           ++ "getB_2 (B2 (A1 _ n) _) = n\n"+#endif+    s2 <- doit2 1 0 1 ""+    putStrLn s2+#if 0+    putStrLn $ ""+           ++ "expTB_15 = (A3 (B3 False undefined 5) False)\n"+           ++ "getA (A3 _ b) = show b\n"+    s3 <- doit3 1 1 1 ""+    putStrLn s3+#endif+#endif++#if 0+    s4 <- doit4 1 0 1 ""+    putStrLn s4+#endif++#if 0+    putStrLn $ ""+           ++ "expBase1 = ([True,False],3,Just \"fox\")         :: ([Bool],Int,Maybe String)\n"+           ++ "expBase2 = ([True,False],__,Just \"fox\")        :: ([Bool],Int,Maybe String)\n"+           ++ "expBase3 = ([True,__],3,Just \"fox\")            :: ([Bool],Int,Maybe String)\n"+           ++ "expBase4 = ([True,__],3,Just __)               :: ([Bool],Int,Maybe String)\n"+           ++ "expBase5 = ([True,False],3,Just ['f',__,'x'])  :: ([Bool],Int,Maybe String)\n"+           ++ "expBase6 = ([True,False],3,Just __)            :: ([Bool],Int,Maybe String)\n"+           ++ "get1 ((x:_),_,_) = x           -- True\n"+           ++ "get2 (_,x,_) = x               -- 3\n"+           ++ "get3 (_,_,x) = fromJust x      -- \"fox\"\n"+           ++ "get4 (_,_,Just (x:_)) = x      -- 'f'\n"+    s1 <- doit1 1 1 1 ""+    putStrLn s1+#endif++#if USE_SOP++#if 1+    -- Testing rnfpDyn -- working+    putStrLn "\nTesting SOP rnfpDyn with SYB generic stop condition.\n"+#if 1+    let exp21 = (3.4, [5,__,7], __) :: (Float, [Int], Bool)+    let get21 (_,xs,_) = (xs!!2)+    let f21_a :: [Int] -> PatNode+        f21_a _ = WI emptyPatNodeAttrs+    let f21_b :: Bool -> PatNode+        f21_b _ = WI emptyPatNodeAttrs+    let fg21 :: GenericQ PatNode+        fg21 = mkQ (WR emptyPatNodeAttrs) f21_a `extQ` f21_b+--  let fg21 = mkQ (WR emptyPatNodeAttrs) f21_a `extQ` f21_b :: forall a. Data a => a -> PatNode+--  let fg21 = mkQ (WR emptyPatNodeAttrs) f21_a `extQ` f21_b :: GenericQ PatNode+    putStrLn $ show $ get21 $ forcepDyn fg21 exp21+#else+    let exp21 = (3.4, [5,__,7], False) :: (Float, [Int], Bool)+    let get21 (_,xs,_) = (xs!!2)+#if 0+#elif 1+    let f21 :: [Int] -> PatNode+        f21 _ = WI emptyPatNodeAttrs+    let fg21 :: GenericQ PatNode+        fg21 = mkQ (WR emptyPatNodeAttrs) f21+#elif 0+    let f21 :: (Float,[Int],Bool) -> PatNode+    -- Cannot do in SYB? We can't just "stop on any 3-tuple"; we need+    -- to give the types of the components of the tuple as well?+--  let f21 :: (,,) a b c -> PatNode+--  let f21 :: (,,) * * * -> PatNode+--  let f21 :: (,,) -> PatNode+--  let f21 :: (a,b,c) -> PatNode+--  let f21 :: (Typeable a,Typeable b,Typeable c) => (a,b,c) -> PatNode+--  let f21 :: (Data a,Typeable a,Data b,Typeable b,Data c,Typeable c) => (a,b,c) -> PatNode+        f21 _ = WI emptyPatNodeAttrs+--      f21 (x,y,z) = WI emptyPatNodeAttrs+    let fg21 :: GenericQ PatNode+        fg21 = mkQ (WR emptyPatNodeAttrs) f21+#elif 0+    let f21 :: Int -> PatNode+        f21 x = WI emptyPatNodeAttrs+--      f21 x = case x of { 5 -> WR emptyPatNodeAttrs ; _ -> WI emptyPatNodeAttrs }  -- "case x" forces x!+--  let (f21::Int->PatNode) x = case x of { 5 -> WR emptyPatNodeAttrs ; _ -> WI emptyPatNodeAttrs }+    let fg21 :: GenericQ PatNode+        fg21 = mkQ (WR emptyPatNodeAttrs) f21+#endif+    putStrLn $ show $ get21 $ forcepDyn fg21 exp21+#endif+#endif++#if 1+    -- Testing rnfpDyn again -- not working...+    putStrLn "\nTesting SOP/SYB rnfpDyn again.\n"+#if 0+#elif 1+    let exp22 = [[[__]],[[__,6],[7]]] :: [[[Int]]]+-- These three should be exactly equivalent (same core produced)?+--  let get22 xs = (((xs!!1)!!1)!!0)+--  let get22 [_,[[_,n],_]] = n+    let get22 (_:((_:n:_):_):_) = n+    let f22a :: Int -> PatNode+        f22a _ = trace "Noo-A" $ WI emptyPatNodeAttrs+    let f22b :: [Int] -> PatNode+        f22b _ = trace "Noo-B" $ WI emptyPatNodeAttrs+    let f22c :: [[Int]] -> PatNode+        f22c _ = trace "Noo-C" $ WI emptyPatNodeAttrs+    let f22d :: [[[Int]]] -> PatNode  -- goes boom+        f22d _ = trace "Noo-D" $ WI emptyPatNodeAttrs+    let fg22 :: GenericQ PatNode+        fg22 = mkQ (WR emptyPatNodeAttrs) id+--                                                              -- blows+--                                                 `extQ` f22d  -- blows+                                       `extQ` f22c `extQ` f22d  -- FINE+--                         `extQ` f22b `extQ` f22c `extQ` f22d  -- FINE+--             `extQ` f22a `extQ` f22b `extQ` f22c              -- blows+--             `extQ` f22a `extQ` f22b `extQ` f22c `extQ` f22d  -- FINE+#elif 0+    let exp22 = [[[__]],[[__,6],__,[7]]] :: [[[Int]]]+    let get22 xs = (((xs!!1)!!2)!!0)+    let f22 :: Int -> PatNode        -- goes boom+--  let f22 :: [Int] -> PatNode      -- goes boom+--  let f22 :: [[Int]] -> PatNode    -- goes boom+--  let f22 :: [[[Int]]] -> PatNode  -- goes boom+        f22 _ = trace "Noo-A" $ WI emptyPatNodeAttrs+    let fg22 :: GenericQ PatNode+        fg22 = mkQ (WR emptyPatNodeAttrs) f22+#else+    let exp22 = (3.4, [[[__]],[[__,6],__,[7]]], __) :: (Float, [[[Int]]], Bool)+--  let exp22 = (3.4, [[__],[[__,6],__,[7]]], __) :: (Float, [[[Int]]], Bool)+    let get22 (_,xs,_) = (((xs!!1)!!2)!!0)+    let f22_a :: [[Int]] -> PatNode+        f22_a _ = WI emptyPatNodeAttrs+    let f22_b :: Bool -> PatNode+        f22_b _ = WI emptyPatNodeAttrs+    let fg22 :: GenericQ PatNode+        fg22 = mkQ (WR emptyPatNodeAttrs) f22_a `extQ` f22_b+--  let fg22 = mkQ (WR emptyPatNodeAttrs) f22_a `extQ` f22_b :: forall a. Data a => a -> PatNode+--  let fg22 = mkQ (WR emptyPatNodeAttrs) f22_a `extQ` f22_b :: GenericQ PatNode+#endif+    putStrLn $ show $ get22 $ forcepDyn fg22 exp22+#endif++#if 1+#if __GLASGOW_HASKELL__ >= 708+-- XXX This isn't working yet.+-- And it won't work naively either, b/c SOP is *shallow*...+-- Note:+-- *Foo> :m +Generics.SOP+-- *Foo Generics.SOP> datatypeInfo (Proxy :: Proxy [[Int]])+-- ADT "GHC.Types" "[]" (Constructor "[]" :* (Infix ":" RightAssociative 5 :* Nil))+-- So, as done in GNFDataP, we need to pattern-match in tandem on this,+-- through the *S and *P SOP recursion auxilliaries...+-- XXX I came back to this -- getting type errors, could probably+-- get rid of by adding extra functions (as per GNFDataP.hs code),+-- but remember, this is supposed to be API-user code ... if it's+-- going to be that painful to write, we have a problem...+-- (Still, can probably write friendlier wrapper functions.)+    -- Testing rnfpDyn' with SOP generic stop condition+    putStrLn "\nTesting SOP rnfpDyn' with SOP generic stop condition.\n"+#if 0+#elif 1+    putStrLn $ doit23+#elif 0+    let exp23 = [[[__]],[[__,6],__,[7]]] :: [[[Int]]]+    let get23 xs = (((xs!!1)!!2)!!0)+    let fg23 :: forall a. (Generic a, HasDatatypeInfo a) => a -> PatNode+        fg23 d | cname == "[[Int]]"  = WI emptyPatNodeAttrs+               | otherwise           = WR emptyPatNodeAttrs+          where+#if 1+           ADT mname tname (Constructor cname :* _) = dti+--         ADT mname tname (Constructor cname :* _) = dti :: DatatypeInfo (Code a)+--         (mname,tname,cname) = case dti of ...+--         ADT mname tname (Constructor cname :* (Infix ":" RightAssociative 5 :* Nil)) = dti+#endif+           dti = datatypeInfo proxy_a+           proxy_a = Proxy :: Proxy a+           xrep = from d+    putStrLn $ show $ get23 $ forcepDyn' fg23 exp23+#endif+#endif+#endif++#if 1+-- Gave up on the fully-SOP one, at least for now, b/c+-- it seems like it's hard to write (much uglier than SYB one),+-- and then writing a friendly wrapper looks tough as well.+-- But here is a 3rd alternative, hybrid SOP/Typeable which+-- is even simpler from the user perspective, only less efficient.+    putStrLn "Testing SOP rnfpDyn'' with Typeable generic stop condition\n"+    let exp24 = [[[__]],[[__,6],__,[7]]] :: [[[Int]]]+    let get24 xs = (((xs!!1)!!2)!!0)+    let fg24 :: forall a. Typeable a => a -> PatNode+        fg24 d | t == "[[[Int]]]"  = WI emptyPatNodeAttrs+               | t == "[[Int]]"    = WI emptyPatNodeAttrs+               | otherwise         = WR emptyPatNodeAttrs+         where t = show $ typeOf d+    -- This is a simple alternative to the SOP/SYB hybrid.+    -- If efficiency isn't prime concern, this would appear to be+    -- even simpler ... the above looks much more lucid to me than+    -- the usual SYB way of mkQ/extQ; here, just define one normal+    -- function, and away you go...+    putStrLn $ show $ get24 $ forcepDyn'' fg24 exp24+#endif++#endif++#endif++#if ! FOCUS_TEST++#if 1+    putStrLn "\nTesting Seqable class (tuple with list):\n"+    let test_patterns24 = [+           (1,  1, (3.4, [5, __, 7], False))                        -- okay+         , (2,  2, fP (3.4, fP (5 : fP (__ : fP (7 : []))), __))    -- okay+         , (2,  3, fP (3.4, fP (5 : fI (__ : fP (7 : []))), __))    -- okay+         , (1,  4, fI (3.4, fP (5 : fI (__ : fP (7 : []))), __))    -- XXX+         , (1,  5, fI (3.4, fI (5 : fI (__ : fP (7 : []))), __))    -- okay+         , (2,  6, fI (3.4, fI (5 : fP (__ : fP (7 : []))), __))    -- okay+         , (1,  7, fI (3.4, fP (5 : fI (__ : fP (7 : []))), True))  -- XXX+         , (1,  8, fP (3.4, fI (5 : fI (__ : fP (7 : []))), True))  -- XXX+         , (1,  9, fP (3.4, fI (5 : fI (__ : fI (7 : []))), True))  -- XXX+         ] :: [(Int,Int,(Float,[Int],Bool))]+    doit24 True test_patterns24+#endif++#if 1+    putStrLn "\nTesting Seqable class (nested tuples):\n"+    let test_patterns25 = [+           (1,  1, (3.4, (__, 7), False))       -- okay+         , (1,  2, fI (3.4 ,fI (__, 7) ,__))    -- okay+         , (2,  3, fP (3.4 ,fP (__, 7) ,__))    -- XXX+         , (2,  4, fP (3.4 ,fI (__, 7) ,__))    -- XXX+         , (2,  5, fI (3.4 ,fP (__, 7) ,__))    -- XXX+         , (1,  6, fI (3.4 ,fI (__, 7) ,True))  -- okay+         , (2,  7, fP (3.4 ,fP (__, 7) ,True))  -- XXX+         , (1,  8, fP (3.4 ,fI (__, 7) ,True))  -- okay+         , (2,  9, fI (3.4 ,fP (__, 7) ,True))  -- XXX+         ] :: [(Int,Int,(Float,(Bool,Int),Bool))]+    doit25 True test_patterns25+#endif++#if USE_SOP++#if 1+    putStrLn "\nTesting generic Seqable (tuple with list):\n"+    let test_patterns26 = [+           (1,  1, (3.4, [5, __, 7], False))                        -- okay+         , (2,  2, gP (3.4, gP (5 : gP (__ : gP (7 : []))), __))    -- okay+         , (2,  3, gP (3.4, gP (5 : gI (__ : gP (7 : []))), __))    -- okay+         , (1,  4, gI (3.4, gP (5 : gI (__ : gP (7 : []))), __))    -- XXX+         , (1,  5, gI (3.4, gI (5 : gI (__ : gP (7 : []))), __))    -- okay+         , (2,  6, gI (3.4, gI (5 : gP (__ : gP (7 : []))), __))    -- okay+         , (1,  7, gI (3.4, gP (5 : gI (__ : gP (7 : []))), True))  -- XXX+         , (1,  8, gP (3.4, gI (5 : gI (__ : gP (7 : []))), True))  -- XXX+         , (1,  9, gP (3.4, gI (5 : gI (__ : gI (7 : []))), True))  -- XXX+         ] :: [(Int,Int,(Float,[Int],Bool))]+    doit26 True test_patterns26+#endif++#if 1+    putStrLn "\nTesting generic Seqable (expTJ_*):\n"+-- expTJ_1 = J2 ( 1, J4 ( J3, K3 K2 ( J1 4.5))) False     -- for ref.+-- expTJ_2 = J2 ( 1, J4 ( J3, K3 __ ( J1 4.5))) False+-- expTJ_3 = J2 ( 1, J4 ( __, K3 K2 ( J1 4.5))) False+-- expTJ_4 = J2 ( 1, J4 ( __, K3 __ ( J1 4.5))) __        -- in use+    let test_patterns27 = [+           (1,  1, gI (J2 (gI ( 1, gI (J4 (gI ( __, gI (K3 __ ( gI (J1 4.5)))))))) __))+         , (2,  2, gP (J2 (gP ( 1, gP (J4 (gP ( __, gP (K3 __ ( gP (J1 4.5)))))))) __))+         , (1,  3, gI (J2 (gP ( 1, gP (J4 (gI ( __, gI (K3 __ ( gP (J1 4.5)))))))) __))+         , (2,  4, gP (J2 (gP ( 1, gP (J4 (gI ( __, gI (K3 __ ( gP (J1 4.5)))))))) __))+         , (2,  5, gI (J2 (gP ( 1, gP (J4 (gP ( __, gI (K3 __ ( gP (J1 4.5)))))))) __))+         , (2,  6, gI (J2 (gP ( 1, gP (J4 (gI ( __, gP (K3 __ ( gP (J1 4.5)))))))) __))+         ] :: [(Int,Int,TJ)]+    doit27 True test_patterns27+#endif++#endif++#if 1+    putStrLn "\nTesting PatNodeAttrs (pattern node attributes):\n"+    -- exp = G2 5 __ 7 :: TG+    let test_patterns28 = [+#if 1+           (4,  "^^!")   -- syntax error+         , (4,  "^=^!")  -- syntax error+         , (2,  "=*")  -- XXX broken (at least in observability sense)+         , (2,  "+*")  -- fine (but see no trace message!)+         , (2,  "^*")  -- fine (but get no exception)+#if 1+         , (1,  "+^!")+         , (2,  "+^*")+         , (2,  "+^(.!.)")+         , (3,  "^+()")+         , (3,  "^+(!!)")+         , (2,  "^+(!!!)")+         , (3,  "^+(!!!!)")+#else+-- Later: This is now working -- too well, and the first / encountered+-- puts an end to the testing!+         , (2,  "/*")  -- fine (but no indication of termination)+         , (1,  "/+^!")+         , (2,  "/+^*")+         , (2,  "/+^(.!.)")+         , (3,  "^+/()")+         , (3,  "^+/(!!)")+         , (2,  "^+/(!!!)")+         , (3,  "^+/(!!!!)")+#endif+#else+           (4,  "^^!")   -- syntax error+         , (4,  "^=^!")  -- syntax error+         , (3,  "^=()")+         , (3,  "^=(!!)")+         , (2,  "^=(!!!)")+         , (3,  "^=(!!!!)")+--       , (1,  "/=+^!")+--       , (2,  "/=+^*")       -- XXX+--       , (2,  "/=+^(.!.)")   -- XXX+         , (2,  "*")+         , (2,  "(.!.)")+         , (2,  "=*")  -- XXX broken (at least in observability sense)+         , (2,  "+*")  -- fine (but see no trace message!)+         , (2,  "^*")  -- fine (but get no exception)+--       , (2,  "/*")  -- fine (but no indication of termination)+--       , (2,  "/+^(.!.)")  -- fine+#endif+         ]+    doit28 True test_patterns28+#endif++#if 1+    putStrLn "\nTesting PatNodeAttrs (pattern node attributes):\n"+    -- exp = ([0..999999],[1000000..1999999]),[2000000..3999999])+    let test_patterns29 = [+           (1,  "+( +>ba(+*+*)=+*)")+         , (1,  "+(=+>ba(+*+*) +*)")+--       , (1,  "(>ba(+*+*)+=*)")+         ]+    doit29 True test_patterns29+#endif++#endif++    putStrLn "\n"++    return 0++-------------------------------------------------------------------------------++  hline :: String+  hline = "---------------------------------------------------\n"+  hdline :: String+  hdline = "===================================================\n"++-------------------------------------------------------------------------------++  doit1 :: Int -> Int -> Int -> String -> IO String+  doit1 i j k acc+   -- this glitch (the exception that seemingly escapes my catch)+   -- happens just for these combos (and for all j):+-- | i == 3 && k == 4  = doit1 (1+i) j k acc  -- trying to avoid a glitch...+-- | i == 3 && k == 5  = doit1 (1+i) j k acc  -- trying to avoid a glitch...+-- | i == 3 && j < 4 && k == 5  = doit1 (1+i) j k acc  -- trying to avoid a glitch...+   | k == 7  = return acc+   | j == 6  = doit1 1 1 (1+k) acc+   | i == 5  = doit1 1 (1+j) k acc+   | otherwise  = do+      fexp <- catch+               -- The semantics of the !'s here are not what they were,+               -- since forcing in some places. [?] But at least the+               -- first one seems definitely still needed...+               -- LATER: The second one is also needed, finally seen!+               -- (It is needed for a version of getE _ = "getee", only.)+               -- XXX I'm just not sure whether the second ! is better+               -- to leave in or leave out...+               ( return $! get $! forcen dep exp )+               (\e -> do let err = show (e :: ErrorCall)+--             (\e -> do let err = show (e :: BottomedOut)+                         return err)+--    doit1 (1+i) j k $! force $ acc+      doit1 (1+i) j k $! acc+--    doit1 (1+i) j k $ acc+        ++ "( get" ++ show i ++ " $ forcen " ++ show dep ++ " expBase" ++ show k ++ " )  "+        ++ fexp ++ "\n"+   where+    exp = case k of+            1 -> expBase1+            2 -> expBase2+            3 -> expBase3+            4 -> expBase4+            5 -> expBase5+            6 -> expBase6+    get = case i of+           1 -> get1+           2 -> get2+--         3 -> unsafePerformIO . get3  -- yeesh!...+--         3 -> get3+           3 -> get3 (i,j,k)+           4 -> get4+    dep = j++  -- XXX All this fuss to deal with the case that the+  -- entire argument m is undefined (or whatever is going+  -- for "undefined" at the moment...) -- but, none of+  -- the expBase[1-5] have this! ch.+  myFromJust :: Maybe a -> IO (Either () a)+  myFromJust m = do+                    putStrLn "Boo!"+                    catch+                      (myFromJust' m)+                      (\e -> do putStrLn $! show (e::BottomedOut)+                                putStrLn "HERE!"+                                return $! Left ())+  myFromJust' :: Maybe a -> IO (Either () a)+  myFromJust' Nothing = do+--                         throw BottomedOut+                           return $! Left ()+  myFromJust' (Just x) = return $! Right x+--myFromJust _ = throw BottomedOut++--------------------------------++  doit2 :: Int -> Int -> Int -> String -> IO String+  doit2 i j k acc+-- | k == 2  = {- trace (show (i,j,k)) $ -} return acc+-- | k == 7  = return acc+   | k == 27  = return acc+-- | k == 21  = return acc+-- | k == 5  = return acc+-- | j == 15  = doit2 1 0 (1+k) acc+   | j == 11  = {- trace (show (i,j,k)) $ -} doit2 1 0 (1+k) acc+-- | j == 8  = {- trace (show (i,j,k)) $ -} doit2 1 0 (1+k) acc+-- | j == 3  = {- trace (show (i,j,k)) $ -} doit2 1 0 (1+k) acc+#if USE_TRACE+   | i == 2  = trace ("End of " ++ show (i,j',k')) $ doit2 1 (1+j) k acc+-- | i == 3  = trace ("End of " ++ show (i,j',k')) $ doit2 1 (1+j) k acc+#else+   | i == 2  = doit2 1 (1+j) k acc+-- | i == 3  = doit2 1 (1+j) k acc+#endif+   | otherwise  = do+      fexp <- catch+               ( return $! get $! forcen dep exp )+--             ( return $! get $! forcen dep exp )+               -- ErrorCall if use __ = undefined+               -- BottomedOut if use __ = throw BottomedOut+               (\e -> do let err = show (e :: ErrorCall)+--             (\e -> do let err = show (e :: BottomedOut)+                         return err)+      doit2 (1+i) j k $! acc+        ++ "( getB_" ++ show i ++ " $ forcen " ++ show dep ++ (if dep < 10 then " " else "") ++ " expTB_" ++ show (k'-6) ++ " )  "+--      ++ "( getB_" ++ show i ++ " $ forcen " ++ show dep ++ (if dep < 10 then " " else "") ++ " expBase" ++ show k' ++ " )  "+        ++ fexp ++ "\n"+   where+    exp = case k' of+            7 -> expBase7+            8 -> expBase8+            9 -> expBase9+            10 -> expBase10+            11 -> expBase11+            12 -> expBase12+            13 -> expBase13+            14 -> expBase14+            15 -> expBase15+            16 -> expBase16+            17 -> expBase17+            18 -> expBase18+            19 -> expBase19+            20 -> expBase20+            21 -> expBase20  -- fudge it!!+            22 -> expBase22+            23 -> expBase23+            24 -> expBase24+            25 -> expBase25+            26 -> expBase26+            27 -> expBase27+            28 -> expBase28+            29 -> expBase29+            30 -> expBase30+            31 -> expBase31+            32 -> expBase32+    get = case i of+           1 -> if k' >= 27 then getB_3 else getB_1+           2 -> getB_2+    dep = j'+    j' = j+--  j' = j+11+--  k' = k+26+    k' = k+6++  doit3 :: Int -> Int -> Int -> String -> IO String+  doit3 i j k acc+   | k == 2  = return acc+   | j == 8  = {- trace (show (i,j,k)) $ -} doit3 1 1 (1+k) acc+#if USE_TRACE+   | i == 2  = trace ("End of " ++ show (i,j',k')) $ doit3 1 (1+j) k acc+#else+   | i == 2  = doit3 1 (1+j) k acc+#endif+   | otherwise  = do+      fexp <- catch+               ( return $! get $! forcen dep exp )+               -- ErrorCall if use __ = undefined+               -- BottomedOut if use __ = throw BottomedOut+               (\e -> do let err = show (e :: ErrorCall)+--             (\e -> do let err = show (e :: BottomedOut)+                         return err)+      doit3 (1+i) j k $! acc+        ++ "( getB_" ++ show i ++ " $ forcen " ++ show dep ++ " expBase" ++ show k' ++ " )  "+        ++ fexp ++ "\n"+   where+    exp = case k' of+            21 -> expBase21+    get = case i of+           1 -> getA+    dep = j'+    i' = i+    j' = j+    k' = k+20++  doit4 :: Int -> Int -> Int -> String -> IO String+  doit4 i j k acc+-- | k == 2  = return acc+   | k == 4  = return acc+   | j == 8  = {- trace (show (i,j,k)) $ -} doit4 1 0 (1+k) acc+#if USE_TRACE+   | i == 2  = trace ("End of " ++ show (i,j',k')) $ doit4 1 (1+j) k acc+#else+   | i == 2  = doit4 1 (1+j) k acc+#endif+   | otherwise  = do+      fexp <- catch+               ( return $! get $! forcen dep exp )+               -- ErrorCall if use __ = undefined+               -- BottomedOut if use __ = throw BottomedOut+               (\e -> do let err = show (e :: ErrorCall)+--             (\e -> do let err = show (e :: BottomedOut)+                         return err)+      doit4 (1+i) j k $! acc+        ++ "( getE $ forcen " ++ show dep ++ " expTE_" ++ show k' ++ " )  "+        ++ fexp ++ "\n"+   where+    exp = case k' of+            1 -> expTE_1+            2 -> expTE_2+            3 -> expTE_3+    get = case i of+           1 -> getE+    dep = j'+    i' = i+    j' = j+    k' = k++-------------------------------------------------------------------------------++  doit5 :: Int -> Int -> Int -> String -> IO String+  doit5 i j k acc+   | k == 2  = return acc+   | j == 5  = {- trace (show (i,j,k)) $ -} doit5 1 0 (1+k) acc+#if USE_TRACE+   | i == 2  = trace ("End of " ++ show (i,j',k')) $ doit5 1 (1+j) k acc+#else+   | i == 2  = doit5 1 (1+j) k acc+#endif+   | otherwise  = do+      fexp <- catch+               ( return $! get $! forcen dep exp )+               -- ErrorCall if use __ = undefined+               -- BottomedOut if use __ = throw BottomedOut+               (\e -> do let err = show (e :: ErrorCall)+--             (\e -> do let err = show (e :: BottomedOut)+                         return err)+      doit5 (1+i) j k $! acc+        ++ "forcen " ++ show dep ++ " expN_" ++ show k' ++ " `seq` ()  =  "+        ++ fexp ++ "\n"+   where+    exp = case k' of+            1 -> expN_1+    get = case i of+           1 -> getN_1+    dep = j'+    i' = i+    j' = j+    k' = k++-------------------------------------------------------------------------------++  doit6 :: Int -> Int -> Int -> String -> IO String+  doit6 i j k acc+   | k == 2  = return acc+   | j == 5  = {- trace (show (i,j,k)) $ -} doit6 1 0 (1+k) acc+#if USE_TRACE+   | i == 2  = trace ("End of " ++ show (i',j',k')) $ doit6 1 (1+j) k acc+#else+   | i == 2  = doit6 1 (1+j) k acc+#endif+   | otherwise  = do+      fexp <- catch+               ( return $! get $! forcen dep exp )+               -- ErrorCall if use __ = undefined+               -- BottomedOut if use __ = throw BottomedOut+               (\e -> do let err = show (e :: ErrorCall)+--             (\e -> do let err = show (e :: BottomedOut)+                         return err)+      doit6 (1+i) j k $! acc+        ++ "getN_" ++ show i' ++" $ forcen " ++ show dep ++ " expN_" ++ show k' ++ "  =  "+        ++ fexp ++ "\n"+   where+    exp = case k' of+            _ -> expN_2+    get = case i of+           _ -> getN_2+    dep = j'+    i' = i+1+    j' = j+    k' = k+1++-------------------------------------------------------------------------------++  doit7 :: Int -> Int -> Int -> String -> IO String+  doit7 i j k acc+   | k == 2  = return acc+   | j == 5  = {- trace (show (i,j,k)) $ -} doit7 1 0 (1+k) acc+#if USE_TRACE+   | i == 2  = trace ("End of " ++ show (i',j',k')) $ doit7 1 (1+j) k acc+#else+   | i == 2  = doit7 1 (1+j) k acc+#endif+   | otherwise  = do+      fexp <- catch+               ( return $! get $! forcen dep exp )+               -- ErrorCall if use __ = undefined+               -- BottomedOut if use __ = throw BottomedOut+               (\e -> do let err = show (e :: ErrorCall)+--             (\e -> do let err = show (e :: BottomedOut)+                         return err)+      doit7 (1+i) j k $! acc+        ++ "getN_" ++ show i' ++" $ forcen " ++ show dep ++ " expN_" ++ show k' ++ "  =  "+        ++ fexp ++ "\n"+   where+    exp = case k' of+            _ -> expN_3+    get = case i of+           _ -> getN_3+    dep = j'+    i' = i+2+    j' = j+    k' = k+2++-------------------------------------------------------------------------------++  doit8 :: Int -> Int -> Int -> String -> IO String+  doit8 i j k acc+   | k == 2  = return acc+   | j == 5  = {- trace (show (i,j,k)) $ -} doit8 1 0 (1+k) acc+#if USE_TRACE+   | i == 2  = trace ("End of " ++ show (i',j',k')) $ doit8 1 (1+j) k acc+#else+   | i == 2  = doit8 1 (1+j) k acc+#endif+   | otherwise  = do+      fexp <- catch+               ( return $! get $! forcen dep exp )+               -- ErrorCall if use __ = undefined+               -- BottomedOut if use __ = throw BottomedOut+               (\e -> do let err = show (e :: ErrorCall)+--             (\e -> do let err = show (e :: BottomedOut)+                         return err)+      doit8 (1+i) j k $! acc+        ++ "getN_" ++ show i' ++" $ forcen " ++ show dep ++ " expN_" ++ show k' ++ "  =  "+        ++ fexp ++ "\n"+   where+    exp = case k' of+            _ -> expN_4+    get = case i of+           _ -> getN_3+    dep = j'+    i' = i+2+    j' = j+    k' = k+3++-------------------------------------------------------------------------------++#if 0++#if 0+  expP_1 = (3.4, [5,__,7], __) :: (Float, [Int], Bool)+  patP_1 = Node (TR [typeOf ((__,__,__)::(Float, [Int], Bool))])+             [ Node (TR [typeOf (__::Bool)]) []+--           [ Node (TR [typeOf (__::Float)]) []+--           [ Node (NTR [typeOf (__::Bool)]) []+--           [ Node (NTR [typeOf (__::Float)]) []+--           , Node WS []+             , Node (TW [typeOf ([__]::[Int])]) []+--           , Node (TR [typeOf ([__]::[Int])]) []+--           , Node (TR [typeOf ([__]::[Int])]) [ Node WS [], Node WS [] ]  -- why not?+             , Node WW []+--           , Node I []+             ]+  getP_1 (_,xs,_) = show $ (xs!!2)+#endif++  doit9 :: IO String+  doit9 = do+#if 0+    putStrLn $ intercalate "\n"+     [ ""+     , "expP_1 = (3.4, [5,__,7], __) :: (Float, [Int], Bool)"+     , "patP_1 = Node (T [typeOf ((__,__,__)::(Float, [Int], Bool))])"+     , "           [ Node W []"+     , "           , Node (T [typeOf ([__]::[Int])]) []"+     , "           , Node I []"+     , "           ]"+     , "getP_1 (_,xs,_) = show $ (xs!!2)"+     ]+    putStrLn "getP_1 $ forcep patP_1 expP_1"+#endif+    s <- catch+             ( return $! getP_1 $! forcep patP_1 expP_1 )+--           ( return $! getP_2 $! forcep patP_2 expP_2 )+--           ( return $! getP_3 $! forcep patP_3 expP_3 )+             -- ErrorCall if use __ = undefined+             -- BottomedOut if use __ = throw BottomedOut+             (\e -> do let err = show (e :: ErrorCall)+--           (\e -> do let err = show (e :: BottomedOut)+                       return err)+    return s++#endif++-------------------------------------------------------------------------------++  doit10 :: Bool -> [(Int,String)] -> IO ()+  doit10 _ [] = do+                   putStrLn "--------------------------------------------------"+                   return ()+  doit10 b ((code,patstr):t) = do+    let expect = case code of+                  1 -> "7"+                  2 -> "Prelude.undefined"+                  3 -> "pattern-match failure"+                  4 -> "syntax error"+                  5 -> "7 (but \"# with subpattern\" warning)"+                  6 -> "7 (but \"constraint/subpattern arity mismatch\" warning)"+#if WARN_PATTERN_MATCH_FAILURE+                  13 -> "7 (but with pattern-match failure warning)"+                  23 -> "Prelude.undefined (but with pattern-match failure warning)"+#else+                  13 -> "7 (with silent pattern-match failure)"+                  23 -> "Prelude.undefined (with silent pattern-match failure)"+#endif+                  _ -> error $ "doit10: unexpected code " ++ show code+    s <- catch+           ( do+                let exp = (3.4, [5,__,7], __) :: (Float, [Int], Bool)+                let pat = compilePat patstr+                let get (_,xs,_) = show $ (xs!!2)+                if b+                then do+                  putStrLn "==================================================="+                  putStrLn "exp = (3.4, [5,__,7], __) :: (Float, [Int], Bool)"+                  putStrLn "get (_,xs,_) = show $ (xs!!2)"+                  putStrLn "? = get $ forcep patstr exp"+                  putStrLn "==================================================="+                else do+                  putStrLn "---------------------------------------------------"+                putStrLn $ "patstr                   = " ++ patstr+                if code > 4+                then putStrLn $  "expected value           = " ++ expect+                else return ()+--              putStrLn $ "pat = " ++ show pat+                putStrLn $ "showPat.compilePat       = " ++ showPat pat+                if code <= 4+                then putStrLn $  "expected value           = " ++ expect+                else return ()+                s1 <- catch+                        ( return $! force $! get $! forcep patstr exp )+                        (\e -> do let err = show (e :: ErrorCall)+--                      (\e -> do let err = show (e :: BottomedOut)+                                  return err)+                putStr "actual value             = "+                return $! s1+           )+           -- ErrorCall if use __ = undefined+           -- BottomedOut if use __ = throw BottomedOut+           (\e -> do let err = show (e :: ErrorCall)+--         (\e -> do let err = show (e :: BottomedOut)+                     return err)+    putStrLn s+    doit10 False t++-------------------------------------------------------------------------------++  doit11 :: Bool -> [(Int,String,String)] -> IO ()+  doit11 _ [] = do+                   putStrLn "--------------------------------------------------"+                   return ()+  doit11 b ((code,patstr1,patstr2):t) = do+    let expect = case code of+                  1 -> "7"+                  2 -> "Prelude.undefined"+                  3 -> "pattern-match failure"+                  4 -> "syntax error"+                  5 -> "7 (but \"# with subpattern\" warning)"+                  6 -> "7 (but \"constraint/subpattern arity mismatch\" warning)"+                  _ -> error $ "doit11: unexpected code " ++ show code+    s <- catch+           ( do+                let exp = (3.4, [5,__,7], __) :: (Float, [Int], Bool)+                let patstrU = showPat $ unionPats [compilePat patstr1, compilePat patstr2]+                let pat1 = compilePat patstr1+                let pat2 = compilePat patstr2+                let patU = unionPats [pat1,pat2]+                let get (_,xs,_) = show $ (xs!!2)+                if b+                then do+                  putStrLn "==================================================="+                  putStrLn "exp = (3.4, [5,__,7], __) :: (Float, [Int], Bool)"+                  putStrLn "get (_,xs,_) = show $ (xs!!2)"+                  putStrLn "? = get $ ( forcep patstr2 . forcep patstr1 ) exp"+--                putStrLn "? = get $ ( forcep ( unionPatsStr [ patstr1, patstr2 ] ) ) exp"+                  putStrLn "? = get $! ( forcep_ ( unionPats [ pat1, pat2 ] ) ) exp"+                  putStrLn "(Results were more interesting with a previous semantics...)."+                  putStrLn "==================================================="+                else do+                  putStrLn "---------------------------------------------------"+                putStrLn $ "patstr1                     = " ++ patstr1+                putStrLn $ "patstr2                     = " ++ patstr2+                putStrLn $ "patstrU                     = " ++ patstrU+                if code > 4+                then putStrLn $  "expected value              = " ++ expect+                else return ()+--              putStrLn $ "pat = " ++ show pat+                putStrLn $ "showPat.compilePat patstr1  = " ++ showPat pat1+                putStrLn $ "showPat.compilePat patstr2  = " ++ showPat pat2+                putStrLn $ "showPat.compilePat patstrU  = " ++ showPat patU+                if code <= 4+                then putStrLn $  "expected value              = " ++ expect+                else return ()+                putStr "actual value                = "+                let s1 = get $! ( forcep patstr2 . forcep patstr1 ) exp+                putStrLn s1+                putStr "actual value                = "+                let s2 = get $! forcep patstrU exp+#if 1+                let s3 = s2+#else+                putStrLn s2+                let s3 = get $! forcep_ ( unionPats [ pat1, pat2 ] ) exp+#endif+                return $! s3+           )+           -- ErrorCall if use __ = undefined+           -- BottomedOut if use __ = throw BottomedOut+           (\e -> do let err = show (e :: ErrorCall)+--         (\e -> do let err = show (e :: BottomedOut)+                     return err)+    putStrLn s+    doit11 False t++-------------------------------------------------------------------------------++  doit12 :: Bool -> [(Int,String,[Int],[(Int,String)])] -> IO ()+--doit12 :: Bool -> [(Int,String,String,[(Int,String)])] -> IO ()+  doit12 _ [] = do+                   return ()+  doit12 b ((code,patstr1,path,isibs'):t) = do+    let expect = case code of+                  1 -> "7"+                  2 -> "Prelude.undefined"+                  3 -> "pattern-match failure"+                  4 -> "syntax error"+                  5 -> "7 (but \"# with subpattern\" warning)"+                  6 -> "7 (but \"constraint/subpattern arity mismatch\" warning)"+                  _ -> error $ "doit12: unexpected code " ++ show code+    s <- catch+           ( do+                let target = compilePat patstr1+--              let path = compilePat patstr2+                let isibs = map (\ (x,y) -> (x,compilePat y)) isibs'+                if b+                then do+                  putStr hdline+                  putStrLn "Testing splicePats."+                  putStr hline+                else return ()+                putStrLn $ "target       " ++ patstr1+                putStrLn $ "path         " ++ show path+--              putStrLn $ "path         " ++ patstr2+                putStrLn $ "isibs        " ++ show isibs'+                let s1 = force $ showPat $ splicePats target path isibs+--              let s1 = showPat $! splicePats target path isibs+--              let s1 = showPat $ splicePats target path isibs+                putStr "result       "+                return $! s1+           )+           -- ErrorCall if use __ = undefined+           -- BottomedOut if use __ = throw BottomedOut+           (\e -> do let err = show (e :: ErrorCall)+--         (\e -> do let err = show (e :: BottomedOut)+                     return err)+    putStrLn s+    if null t then return () else putStr hline+    doit12 False t++-------------------------------------------------------------------------------++  doit12b :: Bool -> [(Int,String,[Int],[Int])] -> IO ()+  doit12b _ [] = do+                   return ()+  doit12b b ((code,patstr1,path,isibs'):t) = do+    let expect = case code of+                  1 -> "7"+                  2 -> "Prelude.undefined"+                  3 -> "pattern-match failure"+                  4 -> "syntax error"+                  5 -> "7 (but \"# with subpattern\" warning)"+                  6 -> "7 (but \"constraint/subpattern arity mismatch\" warning)"+                  _ -> error $ "doit12b: unexpected code " ++ show code+    s <- catch+           ( do+                let target = compilePat patstr1+                let isibs = isibs'+                if b+                then do+                  putStr hdline+                  putStrLn "Testing elidePats."+                  putStr hline+                else return ()+                putStrLn $ "target       " ++ patstr1+                putStrLn $ "path         " ++ show path+                putStrLn $ "isibs        " ++ show isibs'+                let s1 = force $ showPat $ elidePats target path isibs+                putStr "result       "+                return $! s1+           )+           -- ErrorCall if use __ = undefined+           -- BottomedOut if use __ = throw BottomedOut+           (\e -> do let err = show (e :: ErrorCall)+--         (\e -> do let err = show (e :: BottomedOut)+                     return err)+    putStrLn s+    if null t then return () else putStr hline+    doit12b False t++-------------------------------------------------------------------------------++  -- This is the first recursive test [much later than "12" would suggest].+  doit12c :: Bool -> [(Int,String,[Int])] -> StdGen -> Int -> IO StdGen+--doit12c :: Bool -> [(Int,String,[Int],Int)] -> StdGen -> IO StdGen+--doit12c :: Bool -> [(Int,String,StdGen,[Int],Int)] -> IO StdGen+--doit12c :: Bool -> [(Int,String,StdGen,[Int],Int)] -> IO ()+  doit12c _ [] g _ = do+                   return g+--                 return ()+  doit12c b lst@((code,patstr1,path):t) g 0 = return g+  doit12c b lst@((code,patstr1,path):t) g nreps = do  -- but singleton expected?+    let expect = case code of+                  1 -> "7"+                  2 -> "Prelude.undefined"+                  3 -> "pattern-match failure"+                  4 -> "syntax error"+                  5 -> "7 (but \"# with subpattern\" warning)"+                  6 -> "7 (but \"constraint/subpattern arity mismatch\" warning)"+                  _ -> error $ "doit12c: unexpected code " ++ show code+    (s, g') <- catch+--  s <- catch+           ( do+                let target = compilePat patstr1+                if b+                then do+                  putStr hdline+                  putStrLn "Testing erodePat."+                  putStr hline+                else return ()+                putStrLn $ "target       " ++ patstr1+                putStrLn $ "stdgen       " ++ show g+                putStrLn $ "path         " ++ show path+                let (rslt, g') = erodePat g path target+                let s1 = force $ showPat $ rslt+--              let s1 = force $ showPat $ erodePat g path target+                putStr "result       "+                return $! (s1, g')+--              return $! s1+           )+           -- ErrorCall if use __ = undefined+           -- BottomedOut if use __ = throw BottomedOut+           (\e -> do let err = show (e :: ErrorCall)+--         (\e -> do let err = show (e :: BottomedOut)+                     return (err, g))+--                   return err)+    putStrLn s+    putStr hline+    doit12c False lst g' (-1+nreps)+--  doit12c False t g' (-1+nreps)++-------------------------------------------------------------------------------++  doit13 :: Bool -> [(Int,[String],String)] -> IO ()+  doit13 _ [] = do+                   putStr hline+                   return ()+  doit13 b ((code,patstrlst,expectstr):t) = do+    s <- catch+           ( do+                s1 <- case code of+-- Where were they done already?+-- Oh, in doit11 and doit12 above...+                       1 -> error $ hline ++ "unionPats test already done test13-1!"+--                     4 -> error $ hline ++ "unionPatsStr test already done test13-4!"+                       10 -> error $ hline ++ "splicePats test already done test13-10!"+                       11 -> error $ hline ++ "isPath test already done test13-11!"+    --  1    unionPats       :: [ Pat ] -> Pat+    --  2  * intersectPats   :: [ Pat ] -> Pat+    --  3  * subPat          :: Pat -> Pat -> Bool+--  --  4    unionPatsStr    :: [ String ] -> String+    --  5  * emptyPat        :: Pat+    --  6  * mkPat           :: forall d. Data d => d -> Pat+    --  7  * growPat         :: forall d. Data d => Pat -> d -> Pat+    --  8  * shrinkPat       :: Pat -> Pat+    --  9  * liftPats        :: [ Pat ] -> Pat+    -- 10    splicePats      :: Pat -> Pat -> [(Int, Pat)] -> Pat+    -- 11    isPath          :: Pat -> Bool+                       2 -> do+                               let patA = patstrlst!!0+                               let patB = patstrlst!!1+                               putStr hline+                               putStrLn "Testing      intersectPats [patA, patB]"+                               putStrLn $ "patA         " ++ patA+                               putStrLn $ "patB         " ++ patB+                               putStr $ "result       "+                               let s1 = force $ showPat $ intersectPats [compilePat patA, compilePat patB]+                               return s1+                       3 -> do+                               let patA = patstrlst!!0+                               let patB = patstrlst!!1+                               putStr hline+                               putStrLn "Testing      subPat patA patB"+                               putStrLn $ "patA         " ++ patA+                               putStrLn $ "patB         " ++ patB+                               let s1 = force $ show $ subPat (compilePat patA) (compilePat patB)+                               if s1 /= expectstr+                               then do putStrLn $ "expect       " ++ expectstr+                                       putStr $ "result       "+                               else putStr $ "as expected  "+                               return s1+                       5 -> do+                               putStr hline+                               putStrLn "Testing      emptyPat"+                               putStr $ "result       "+                               let s1 = force $ showPat $ emptyPat+                               return s1+                       6 -> do+                               putStr hline+                               putStrLn "Testing      mkPat ([1,2,3],(False,\"foo\"))"+                               putStr $ "result       "+                               let s1 = force $ showPat $ mkPat ([1,2,3::Int],(False,"foo"))+                               return s1+                       7 -> do+                               let patA = patstrlst!!0+                               putStr hline+                               putStrLn "Testing      growPat patA ([1,2,3],(False,\"foo\"))"+                               putStrLn $ "patA         " ++ patA+                               putStr $ "result       "+                               let s1 = force $ showPat $ growPat (compilePat patA) ([1,2,3::Int],(False,"foo"))+                               return s1+                       8 -> do+                               let patA = patstrlst!!0+                               putStr hline+                               putStrLn "Testing      shrinkPat patA"+                               putStrLn $ "patA         " ++ patA+                               putStr $ "result       "+                               let s1 = force $ showPat $ shrinkPat (compilePat patA)+                               return s1+                       9 -> do+                               putStr hline+                               putStrLn "Testing      liftPats patstrlst"+                               putStrLn $ "patstrs      " ++ show patstrlst+                               putStr $ "result       "+                               let s1 = force $ showPat $ liftPats $ map compilePat patstrlst+                               return s1+    -- 12    mkPatN          :: Int -> Pat -> Bool+    -- 13    elidePats        :: Pat -> Pat -> [Int] -> Pat+    -- 14    erodePat        :: StdGen -> [Int] -> Pat -> (Pat, StdGen)+                       12 -> do+                               putStr hline+                               putStrLn "Testing      mkPatN 2 ([1,2,3],(False,\"foo\"))"+                               putStr $ "result       "+                               let s1 = force $ showPat $ mkPatN 2 ([1,2,3::Int],(False,"foo"))+                               return s1+                       _ -> error $ "doit13: unexpected code " ++ show code+                return $! s1+           )+           -- ErrorCall if use __ = undefined+           -- BottomedOut if use __ = throw BottomedOut+           (\e -> do let err = show (e :: ErrorCall)+--         (\e -> do let err = show (e :: BottomedOut)+                     return err)+    putStrLn s+    doit13 False t++-------------------------------------------------------------------------------++  doit14 :: Bool -> [(Int,String)] -> IO ()+  doit14 _ [] = do+                   putStrLn "--------------------------------------------------"+                   return ()+  doit14 b ((code,patstr):t) = do+    let expect = case code of+                  1 -> "7"+                  2 -> "Prelude.undefined"+                  3 -> "pattern-match failure"+                  4 -> "syntax error"+                  5 -> "7 (but \"# with subpattern\" warning)"+                  6 -> "7 (but \"constraint/subpattern arity mismatch\" warning)"+#if WARN_PATTERN_MATCH_FAILURE+                  13 -> "7 (but with pattern-match failure warning)"+                  23 -> "Prelude.undefined (but with pattern-match failure warning)"+#else+                  13 -> "7 (with silent pattern-match failure)"+                  23 -> "Prelude.undefined (with silent pattern-match failure)"+#endif+                  _ -> error $ "doit14: unexpected code " ++ show code+    s <- catch+           ( do+                let exp = (3.4, [5,__,7], __) :: (Float, [Int], Bool)+                let pat = compilePat patstr+                let get (_,xs,_) = show $ (xs!!2)+                if b+                then do+                  putStrLn "==================================================="+                  putStrLn "exp = (3.4, [5,__,7], __) :: (Float, [Int], Bool)"+                  putStrLn "get (_,xs,_) = show $ (xs!!2)"+                  putStrLn "? = get $ forcep patstr exp"+                  putStrLn "==================================================="+                else do+                  putStrLn "---------------------------------------------------"+                putStrLn $ "patstr                   = " ++ patstr+                if code > 4+                then putStrLn $  "expected value           = " ++ expect+                else return ()+--              putStrLn $ "pat = " ++ show pat+                putStrLn $ "showPat.compilePat       = " ++ showPat pat+                if code <= 4+                then putStrLn $  "expected value           = " ++ expect+                else return ()+                s1 <- catch+                        ( return $! force $! get $! forcep patstr exp )+                        (\e -> do let err = show (e :: ErrorCall)+--                      (\e -> do let err = show (e :: BottomedOut)+                                  return err)+                putStr "actual value             = "+                return $! s1+           )+           -- ErrorCall if use __ = undefined+           -- BottomedOut if use __ = throw BottomedOut+           (\e -> do let err = show (e :: ErrorCall)+--         (\e -> do let err = show (e :: BottomedOut)+                     return err)+    putStrLn s+    doit14 False t++-------------------------------------------------------------------------------++#if USE_SOP++  -- This is an adaptation of doit10 to user-defined datatypes,+  -- for testing GNFDataP, which is finally within reach thanks+  -- to SOP!+  doit15 :: Bool -> [(Int,String)] -> IO ()+  doit15 _ [] = do+                   putStrLn "--------------------------------------------------"+                   return ()+  doit15 b ((code,patstr):t) = do+    let expect = case code of+                  1 -> "7"+                  2 -> "Prelude.undefined"+                  3 -> "pattern-match failure"+                  4 -> "syntax error"+                  5 -> "7 (but \"# with subpattern\" warning)"+                  6 -> "7 (but \"constraint/subpattern arity mismatch\" warning)"+#if WARN_PATTERN_MATCH_FAILURE+                  13 -> "7 (but with pattern-match failure warning)"+                  23 -> "Prelude.undefined (but with pattern-match failure warning)"+#else+                  13 -> "7 (with silent pattern-match failure)"+                  23 -> "Prelude.undefined (with silent pattern-match failure)"+#endif+                  _ -> error $ "doit15: unexpected code " ++ show code+    s <- catch+           ( do+                let exp = expTG_5  -- ( G1, G2 5 __ 7, __ )+--              let exp = expTG_4  -- ( G1, G2 5 6 7, __ )+--              let exp = expTG_3  -- ( G1, G2 __ __ 7, __ )+--              let exp = expTG_2  -- ( __, G2 __ __ 7, __ )+--              let exp = expTG_1  -- ( G1, G2 5 6 7, True )+--              let exp = (3.4, [5,__,7], __) :: (Float, [Int], Bool)+                let pat = compilePat patstr+                let get = getG+--              let get (_,xs,_) = show $ (xs!!2)+                if b+                then do+                  putStrLn "==================================================="+                  putStrLn "exp = (G1, G2 5 __ 7, __) :: (TG, TG, Bool)"+                  putStrLn "get (_,(G2 _ _ n),_) = n"+                  putStrLn "? = get $ forcep patstr exp"+                  putStrLn "==================================================="+                else do+                  putStrLn "---------------------------------------------------"+                putStrLn $ "patstr                   = " ++ patstr+                if code > 4+                then putStrLn $  "expected value           = " ++ expect+                else return ()+--              putStrLn $ "pat = " ++ show pat+                putStrLn $ "showPat.compilePat       = " ++ showPat pat+                if code <= 4+                then putStrLn $  "expected value           = " ++ expect+                else return ()+                s1 <- catch+                        ( return $! force $! get $! forcep patstr exp )+                        (\e -> do let err = show (e :: ErrorCall)+--                      (\e -> do let err = show (e :: BottomedOut)+                                  return err)+                putStr "actual value             = "+                return $! s1+           )+           -- ErrorCall if use __ = undefined+           -- BottomedOut if use __ = throw BottomedOut+           (\e -> do let err = show (e :: ErrorCall)+--         (\e -> do let err = show (e :: BottomedOut)+                     return err)+    putStrLn s+    doit15 False t++-------------------------------------------------------------------------------++  doit16 :: Bool -> [(Int,String)] -> IO ()+  doit16 _ [] = do+                   putStrLn "--------------------------------------------------"+                   return ()+  doit16 b ((code,patstr):t) = do+    let expect = case code of+                  1 -> "7"+                  2 -> "Prelude.undefined"+                  3 -> "pattern-match failure"+                  4 -> "syntax error"+                  5 -> "7 (but \"# with subpattern\" warning)"+                  6 -> "7 (but \"constraint/subpattern arity mismatch\" warning)"+#if WARN_PATTERN_MATCH_FAILURE+                  13 -> "7 (but with pattern-match failure warning)"+                  23 -> "Prelude.undefined (but with pattern-match failure warning)"+#else+                  13 -> "7 (with silent pattern-match failure)"+                  23 -> "Prelude.undefined (with silent pattern-match failure)"+#endif+                  _ -> error $ "doit16: unexpected code " ++ show code+    s <- catch+           ( do+                let exp = expTG_6  -- G2 5 __ 7+                let pat = compilePat patstr+                let get = getG'+                if b+                then do+                  putStrLn "==================================================="+                  putStrLn "exp = G2 5 __ 7 :: TG"+                  putStrLn "get (G2 _ _ n) = n"+                  putStrLn "? = get $ forcep patstr exp"+                  putStrLn "==================================================="+                else do+                  putStrLn "---------------------------------------------------"+                putStrLn $ "patstr                   = " ++ patstr+                if code > 4+                then putStrLn $  "expected value           = " ++ expect+                else return ()+--              putStrLn $ "pat = " ++ show pat+                putStrLn $ "showPat.compilePat       = " ++ showPat pat+                if code <= 4+                then putStrLn $  "expected value           = " ++ expect+                else return ()+                s1 <- catch+                        ( return $! force $! get $! forcep patstr exp )+                        (\e -> do let err = show (e :: ErrorCall)+--                      (\e -> do let err = show (e :: BottomedOut)+                                  return err)+                putStr "actual value             = "+                return $! s1+           )+           -- ErrorCall if use __ = undefined+           -- BottomedOut if use __ = throw BottomedOut+           (\e -> do let err = show (e :: ErrorCall)+--         (\e -> do let err = show (e :: BottomedOut)+                     return err)+    putStrLn s+    doit16 False t++-------------------------------------------------------------------------------++  doit17 :: Bool -> [(Int,String)] -> IO ()+  doit17 _ [] = do+                   putStrLn "--------------------------------------------------"+                   return ()+  doit17 b ((code,patstr):t) = do+    let expect = case code of+                  1 -> "4.5"+                  2 -> "Prelude.undefined"+                  3 -> "4.5 (due to pattern-match failure)"+                  4 -> "syntax error"+                  5 -> "4.5 (but \"# with subpattern\" warning)"+                  6 -> "4.5 (but \"constraint/subpattern arity mismatch\" warning)"+#if WARN_PATTERN_MATCH_FAILURE+                  13 -> "7 (but with pattern-match failure warning)"+                  23 -> "Prelude.undefined (but with pattern-match failure warning)"+#else+                  13 -> "7 (with silent pattern-match failure)"+                  23 -> "Prelude.undefined (with silent pattern-match failure)"+#endif+                  _ -> error $ "doit17: unexpected code " ++ show code+    s <- catch+           ( do+--              let exp = expTH_1  -- H2 1 [H1 2.3, H3, H4 (H3, I3 I2 (H1 4.5))] False+--              let exp = expTH_2  -- H2 1 [H1 2.3, H3, H4 (__, I3 I2 (H1 4.5))] False+--              let exp = expTH_3  -- H2 1 [H1 2.3, H3, H4 (__, I3 I2 (H1 4.5))] __+                let exp = expTH_4  -- H2 1 [H1 2.3, H3, H4 (__, I3 __ (H1 4.5))] __+                let pat = compilePat patstr+                let get = getH+                if b+                then do+                  putStrLn "==================================================="+                  putStrLn "exp = H2 1 [H1 2.3, H3, H4 (__, I3 I2 (H1 4.5))] __ :: TH"+--                putStrLn "exp = H2 1 [H1 2.3, H3, H4 (H3, I3 I2 (H1 4.5))] False :: TH"+                  putStrLn "get = (H2 _ [_, _, H4 (_, I3 _ (H1 f))] _) = show f"+                  putStrLn "? = get $ forcep patstr exp"+                  putStrLn "==================================================="+                else do+                  putStrLn "---------------------------------------------------"+                putStrLn $ "patstr                   = " ++ patstr+                if code > 4+                then putStrLn $  "expected value           = " ++ expect+                else return ()+--              putStrLn $ "pat = " ++ show pat+                putStrLn $ "showPat.compilePat       = " ++ showPat pat+                if code <= 4+                then putStrLn $  "expected value           = " ++ expect+                else return ()+                s1 <- catch+                        ( return $! force $! get $! forcep patstr exp )+                        (\e -> do let err = show (e :: ErrorCall)+--                      (\e -> do let err = show (e :: BottomedOut)+                                  return err)+                putStr "actual value             = "+                return $! s1+           )+           -- ErrorCall if use __ = undefined+           -- BottomedOut if use __ = throw BottomedOut+           (\e -> do let err = show (e :: ErrorCall)+--         (\e -> do let err = show (e :: BottomedOut)+                     return err)+    putStrLn s+    doit17 False t++-------------------------------------------------------------------------------++  doit18 :: Bool -> [(Int,String)] -> IO ()+  doit18 _ [] = do+                   putStrLn "--------------------------------------------------"+                   return ()+  doit18 b ((code,patstr):t) = do+    let expect = case code of+                  1 -> "4.5"+                  2 -> "Prelude.undefined"+                  3 -> "4.5 (due to pattern-match failure)"+                  4 -> "syntax error"+                  5 -> "4.5 (but \"# with subpattern\" warning)"+                  6 -> "4.5 (but \"constraint/subpattern arity mismatch\" warning)"+#if WARN_PATTERN_MATCH_FAILURE+                  13 -> "7 (but with pattern-match failure warning)"+                  23 -> "Prelude.undefined (but with pattern-match failure warning)"+#else+                  13 -> "7 (with silent pattern-match failure)"+                  23 -> "Prelude.undefined (with silent pattern-match failure)"+#endif+                  _ -> error $ "doit18: unexpected code " ++ show code+    s <- catch+           ( do+--              let exp = expTJ_1  -- J2 (1, J4 (J3, K3 K2 (J1 4.5))) False+--              let exp = expTJ_2  -- J2 (1, J4 (J3, K3 __ (J1 4.5))) False+                let exp = expTJ_3  -- J2 (1, J4 (__, K3 K2 (J1 4.5))) False+--              let exp = expTJ_4  -- J2 (1, J4 (__, K3 __ (J1 4.5))) __+                let pat = compilePat patstr+                let get = getJ+                if b+                then do+                  putStrLn "==================================================="+--                putStrLn "exp = J2 (1, J4 (J3, K3 K2 (J1 4.5))) False"+                  putStrLn "exp = J2 (1, J4 (J3, K3 __ (J1 4.5))) False"+--                putStrLn "exp = J2 (1, J4 (__, K3 K2 (J1 4.5))) False"+--                putStrLn "exp = J2 (1, J4 (__, K3 __ (J1 4.5))) __"+                  putStrLn "get = (J2 (_, J4 (_, K3 _ (J1 f))) _) = show f"+                  putStrLn "? = get $ forcep patstr exp"+                  putStrLn "==================================================="+                else do+                  putStrLn "---------------------------------------------------"+                putStrLn $ "patstr                   = " ++ patstr+                if code > 4+                then putStrLn $  "expected value           = " ++ expect+                else return ()+--              putStrLn $ "pat = " ++ show pat+                putStrLn $ "showPat.compilePat       = " ++ showPat pat+                if code <= 4+                then putStrLn $  "expected value           = " ++ expect+                else return ()+                s1 <- catch+                        ( return $! force $! get $! forcep patstr exp )+                        (\e -> do let err = show (e :: ErrorCall)+--                      (\e -> do let err = show (e :: BottomedOut)+                                  return err)+                putStr "actual value             = "+                return $! s1+           )+           -- ErrorCall if use __ = undefined+           -- BottomedOut if use __ = throw BottomedOut+           (\e -> do let err = show (e :: ErrorCall)+--         (\e -> do let err = show (e :: BottomedOut)+                     return err)+    putStrLn s+    doit18 False t++-------------------------------------------------------------------------------++  doit18b :: Bool -> [(Int,String)] -> IO ()+  doit18b _ [] = do+                   putStrLn "--------------------------------------------------"+                   return ()+  doit18b b ((code,patstr):t) = do+    let expect = case code of+                  1 -> "1"+                  2 -> "Prelude.undefined"+                  3 -> "1 (due to pattern-match failure)"+                  4 -> "syntax error"+                  5 -> "1 (but \"# with subpattern\" warning)"+                  6 -> "1 (but \"constraint/subpattern arity mismatch\" warning)"+#if WARN_PATTERN_MATCH_FAILURE+                  13 -> "7 (but with pattern-match failure warning)"+                  23 -> "Prelude.undefined (but with pattern-match failure warning)"+#else+                  13 -> "7 (with silent pattern-match failure)"+                  23 -> "Prelude.undefined (with silent pattern-match failure)"+#endif+                  _ -> error $ "doit18b: unexpected code " ++ show code+    s <- catch+           ( do+                let exp = expTJ_5  -- J2 (1, J4 (__, K2)) False+                let pat = compilePat patstr+                let get = getJ'+                if b+                then do+                  putStrLn "==================================================="+                  putStrLn "exp = J2 (1, J4 (__, K2)) False"+                  putStrLn "get ~_ = show 1  -- seems to suffice?!?..."+--                putStrLn "get (J2 (n, J4 (_, K2)) False) = show n"+                  putStrLn "? = get $ forcep patstr exp"+                  putStrLn "==================================================="+                else do+                  putStrLn "---------------------------------------------------"+                putStrLn $ "patstr                   = " ++ patstr+                if code > 4+                then putStrLn $  "expected value           = " ++ expect+                else return ()+--              putStrLn $ "pat = " ++ show pat+                putStrLn $ "showPat.compilePat       = " ++ showPat pat+                if code <= 4+                then putStrLn $  "expected value           = " ++ expect+                else return ()+                s1 <- catch+                        ( return $! force $! get $! forcep patstr exp )+                        (\e -> do let err = show (e :: ErrorCall)+--                      (\e -> do let err = show (e :: BottomedOut)+                                  return err)+                putStr "actual value             = "+                return $! s1+           )+           -- ErrorCall if use __ = undefined+           -- BottomedOut if use __ = throw BottomedOut+           (\e -> do let err = show (e :: ErrorCall)+--         (\e -> do let err = show (e :: BottomedOut)+                     return err)+    putStrLn s+    doit18b False t++-------------------------------------------------------------------------------++  doit18c :: Bool -> [(Int,String)] -> IO ()+  doit18c _ [] = do+                   putStrLn "--------------------------------------------------"+                   return ()+  doit18c b ((code,patstr):t) = do+    let expect = case code of+                  1 -> "1"+                  2 -> "Prelude.undefined"+                  3 -> "1 (due to pattern-match failure)"+                  4 -> "syntax error"+                  5 -> "1 (but \"# with subpattern\" warning)"+                  6 -> "1 (but \"constraint/subpattern arity mismatch\" warning)"+#if WARN_PATTERN_MATCH_FAILURE+                  13 -> "7 (but with pattern-match failure warning)"+                  23 -> "Prelude.undefined (but with pattern-match failure warning)"+#else+                  13 -> "7 (with silent pattern-match failure)"+                  23 -> "Prelude.undefined (with silent pattern-match failure)"+#endif+                  _ -> error $ "doit18c: unexpected code " ++ show code+    s <- catch+           ( do+                let exp = expTJ_6  -- J4 (__, K2)+                let pat = compilePat patstr+                let get = getJ6+                if b+                then do+                  putStrLn "==================================================="+                  putStrLn "exp = J4 (__, K2)"+                  putStrLn "get ~_ = show 1  -- seems to suffice?!?..."+--                putStrLn "get (J4 (_, K2)) = show n"+                  putStrLn "? = get $ forcep patstr exp"+                  putStrLn "==================================================="+                else do+                  putStrLn "---------------------------------------------------"+                putStrLn $ "patstr                   = " ++ patstr+                if code > 4+                then putStrLn $  "expected value           = " ++ expect+                else return ()+--              putStrLn $ "pat = " ++ show pat+                putStrLn $ "showPat.compilePat       = " ++ showPat pat+                if code <= 4+                then putStrLn $  "expected value           = " ++ expect+                else return ()+                s1 <- catch+                        ( return $! force $! get $! forcep patstr exp )+                        (\e -> do let err = show (e :: ErrorCall)+--                      (\e -> do let err = show (e :: BottomedOut)+                                  return err)+                putStr "actual value             = "+                return $! s1+           )+           -- ErrorCall if use __ = undefined+           -- BottomedOut if use __ = throw BottomedOut+           (\e -> do let err = show (e :: ErrorCall)+--         (\e -> do let err = show (e :: BottomedOut)+                     return err)+    putStrLn s+    doit18c False t++-------------------------------------------------------------------------------++  doit18d :: Bool -> [(Int,String)] -> IO ()+  doit18d _ [] = do+                   putStrLn "--------------------------------------------------"+                   return ()+  doit18d b ((code,patstr):t) = do+    let expect = case code of+                  1 -> "1"+                  2 -> "Prelude.undefined"+                  3 -> "1 (due to pattern-match failure)"+                  4 -> "syntax error"+                  5 -> "1 (but \"# with subpattern\" warning)"+                  6 -> "1 (but \"constraint/subpattern arity mismatch\" warning)"+#if WARN_PATTERN_MATCH_FAILURE+                  13 -> "7 (but with pattern-match failure warning)"+                  23 -> "Prelude.undefined (but with pattern-match failure warning)"+#else+                  13 -> "7 (with silent pattern-match failure)"+                  23 -> "Prelude.undefined (with silent pattern-match failure)"+#endif+                  _ -> error $ "doit18d: unexpected code " ++ show code+    s <- catch+           ( do+                let exp = expTJ_7  -- (__, K2)+                let pat = compilePat patstr+                let get = getJ7+                if b+                then do+                  putStrLn "==================================================="+                  putStrLn "exp = (__, K2)"+                  putStrLn "get ~_ = show 1  -- seems to suffice?!?..."+                  putStrLn "? = get $ forcep patstr exp"+                  putStrLn "==================================================="+                else do+                  putStrLn "---------------------------------------------------"+                putStrLn $ "patstr                   = " ++ patstr+                if code > 4+                then putStrLn $  "expected value           = " ++ expect+                else return ()+--              putStrLn $ "pat = " ++ show pat+                putStrLn $ "showPat.compilePat       = " ++ showPat pat+                if code <= 4+                then putStrLn $  "expected value           = " ++ expect+                else return ()+                s1 <- catch+                        ( return $! force $! get $! forcep patstr exp )+                        (\e -> do let err = show (e :: ErrorCall)+--                      (\e -> do let err = show (e :: BottomedOut)+                                  return err)+                putStr "actual value             = "+                return $! s1+           )+           -- ErrorCall if use __ = undefined+           -- BottomedOut if use __ = throw BottomedOut+           (\e -> do let err = show (e :: ErrorCall)+--         (\e -> do let err = show (e :: BottomedOut)+                     return err)+    putStrLn s+    doit18d False t++-------------------------------------------------------------------------------++  doit18e :: Bool -> [(Int,String)] -> IO ()+  doit18e _ [] = do+                   putStrLn "--------------------------------------------------"+                   return ()+  doit18e b ((code,patstr):t) = do+    let expect = case code of+                  1 -> "1"+                  2 -> "Prelude.undefined"+                  3 -> "1 (due to pattern-match failure)"+                  4 -> "syntax error"+                  5 -> "1 (but \"# with subpattern\" warning)"+                  6 -> "1 (but \"constraint/subpattern arity mismatch\" warning)"+#if WARN_PATTERN_MATCH_FAILURE+                  13 -> "7 (but with pattern-match failure warning)"+                  23 -> "Prelude.undefined (but with pattern-match failure warning)"+#else+                  13 -> "7 (with silent pattern-match failure)"+                  23 -> "Prelude.undefined (with silent pattern-match failure)"+#endif+                  _ -> error $ "doit18e: unexpected code " ++ show code+    s <- catch+           ( do+                let exp = expTJ_8  -- __ :: TJ+                let pat = compilePat patstr+                let get = getJ8+                if b+                then do+                  putStrLn "==================================================="+                  putStrLn "exp = __ :: TJ"+                  putStrLn "get ~_ = show 1  -- seems to suffice?!?..."+                  putStrLn "? = get $ forcep patstr exp"+                  putStrLn "==================================================="+                else do+                  putStrLn "---------------------------------------------------"+                putStrLn $ "patstr                   = " ++ patstr+                if code > 4+                then putStrLn $  "expected value           = " ++ expect+                else return ()+--              putStrLn $ "pat = " ++ show pat+                putStrLn $ "showPat.compilePat       = " ++ showPat pat+                if code <= 4+                then putStrLn $  "expected value           = " ++ expect+                else return ()+                s1 <- catch+                        ( return $! force $! get $! forcep patstr exp )+                        (\e -> do let err = show (e :: ErrorCall)+--                      (\e -> do let err = show (e :: BottomedOut)+                                  return err)+                putStr "actual value             = "+                return $! s1+           )+           -- ErrorCall if use __ = undefined+           -- BottomedOut if use __ = throw BottomedOut+           (\e -> do let err = show (e :: ErrorCall)+--         (\e -> do let err = show (e :: BottomedOut)+                     return err)+    putStrLn s+    doit18e False t++-------------------------------------------------------------------------------++  doit18f :: Bool -> [(Int,String)] -> IO ()+  doit18f _ [] = do+                   putStrLn "--------------------------------------------------"+                   return ()+  doit18f b ((code,patstr):t) = do+    let expect = case code of+                  1 -> "okay"+                  2 -> "Prelude.undefined"+                  3 -> "okay (due to pattern-match failure)"+                  4 -> "syntax error"+                  5 -> "okay (but \"# with subpattern\" warning)"+                  6 -> "okay (but \"constraint/subpattern arity mismatch\" warning)"+#if WARN_PATTERN_MATCH_FAILURE+                  13 -> "7 (but with pattern-match failure warning)"+                  23 -> "Prelude.undefined (but with pattern-match failure warning)"+#else+                  13 -> "7 (with silent pattern-match failure)"+                  23 -> "Prelude.undefined (with silent pattern-match failure)"+#endif+                  _ -> error $ "doit18f: unexpected code " ++ show code+    s <- catch+           ( do+                let exp = (K5 (__::TJ))+                let pat = compilePat patstr+                let get _ = "okay"+                if b+                then do+                  putStrLn "==================================================="+                  putStrLn "exp = (K5 (__::TJ))"+                  putStrLn "get ~_ = show 1  -- seems to suffice?!?..."+                  putStrLn "? = get $ forcep patstr exp"+                  putStrLn "==================================================="+                else do+                  putStrLn "---------------------------------------------------"+                putStrLn $ "patstr                   = " ++ patstr+                if code > 4+                then putStrLn $  "expected value           = " ++ expect+                else return ()+--              putStrLn $ "pat = " ++ show pat+                putStrLn $ "showPat.compilePat       = " ++ showPat pat+                if code <= 4+                then putStrLn $  "expected value           = " ++ expect+                else return ()+                s1 <- catch+                        ( return $! force $! get $! forcep patstr exp )+                        (\e -> do let err = show (e :: ErrorCall)+--                      (\e -> do let err = show (e :: BottomedOut)+                                  return err)+                putStr "actual value             = "+                return $! s1+           )+           -- ErrorCall if use __ = undefined+           -- BottomedOut if use __ = throw BottomedOut+           (\e -> do let err = show (e :: ErrorCall)+--         (\e -> do let err = show (e :: BottomedOut)+                     return err)+    putStrLn s+    doit18f False t+++-------------------------------------------------------------------------------++  doit18g :: Bool -> [(Int,String)] -> IO ()+  doit18g _ [] = do+                   putStrLn "--------------------------------------------------"+                   return ()+  doit18g b ((code,patstr):t) = do+    let expect = case code of+                  1 -> "okay"+                  2 -> "Prelude.undefined"+                  3 -> "okay (due to pattern-match failure)"+                  4 -> "syntax error"+                  5 -> "okay (but \"# with subpattern\" warning)"+                  6 -> "okay (but \"constraint/subpattern arity mismatch\" warning)"+#if WARN_PATTERN_MATCH_FAILURE+                  13 -> "7 (but with pattern-match failure warning)"+                  23 -> "Prelude.undefined (but with pattern-match failure warning)"+#else+                  13 -> "7 (with silent pattern-match failure)"+                  23 -> "Prelude.undefined (with silent pattern-match failure)"+#endif+                  _ -> error $ "doit18g: unexpected code " ++ show code+    s <- catch+           ( do+#if TRY_THIS+                let exp = K3 (__::TK) J3+#else+                let exp = K3 K2 (__::TJ)+#endif+                let pat = compilePat patstr+                let get _ = "okay"+                if b+                then do+                  putStrLn "==================================================="+#if TRY_THIS+                  putStrLn "exp = K3 (__::TK) J3"+#else+                  putStrLn "exp = K3 K2 (__::TJ)"+#endif+                  putStrLn "get ~_ = show 1  -- seems to suffice?!?..."+                  putStrLn "? = get $ forcep patstr exp"+                  putStrLn "==================================================="+                else do+                  putStrLn "---------------------------------------------------"+                putStrLn $ "patstr                   = " ++ patstr+                if code > 4+                then putStrLn $  "expected value           = " ++ expect+                else return ()+--              putStrLn $ "pat = " ++ show pat+                putStrLn $ "showPat.compilePat       = " ++ showPat pat+                if code <= 4+                then putStrLn $  "expected value           = " ++ expect+                else return ()+                s1 <- catch+                        ( return $! force $! get $! forcep patstr exp )+                        (\e -> do let err = show (e :: ErrorCall)+--                      (\e -> do let err = show (e :: BottomedOut)+                                  return err)+                putStr "actual value             = "+                return $! s1+           )+           -- ErrorCall if use __ = undefined+           -- BottomedOut if use __ = throw BottomedOut+           (\e -> do let err = show (e :: ErrorCall)+--         (\e -> do let err = show (e :: BottomedOut)+                     return err)+    putStrLn s+    doit18g False t++-------------------------------------------------------------------------------++  doit19 :: Bool -> [(Int,String)] -> IO ()+  doit19 _ [] = do+                   putStrLn "--------------------------------------------------"+                   return ()+  doit19 b ((code,patstr):t) = do+--  let expstr = "True"+    let expstr = "5.6"+    let expect = case code of+                  1 -> expstr+                  2 -> "Prelude.undefined"+                  3 -> expstr ++ " (due to pattern-match failure)"+                  4 -> "syntax error"+                  5 -> expstr ++ " (but \"# with subpattern\" warning)"+                  6 -> expstr ++ " (but \"constraint/subpattern arity mismatch\" warning)"+#if WARN_PATTERN_MATCH_FAILURE+                  13 -> "7 (but with pattern-match failure warning)"+                  23 -> "Prelude.undefined (but with pattern-match failure warning)"+#else+                  13 -> "7 (with silent pattern-match failure)"+                  23 -> "Prelude.undefined (with silent pattern-match failure)"+#endif+                  _ -> error $ "doit19: unexpected code " ++ show code+    s <- catch+           ( do+--              let exp = expTL_1  -- L1 5.6 (M1 True)+                let exp = expTL_2  -- L1 5.6 (M1 __)+--              let exp = expTL_3  -- L1 5.6 __+--              let exp = expTL_4  -- L1 __ (M1 True)+                let pat = compilePat patstr+                let get = getL+--              let get = getL'+                if b+                then do+                  putStrLn "==================================================="+                  putStrLn "exp = L1 5.6 (M1 __)"+--                putStrLn "exp = L1 5.6 __"+--                putStrLn "exp = L1 __ (M1 True)"+                  putStrLn "get (L1 f (M1 _)) = show f"+--                putStrLn "get (L1 f _) = show f"+--                putStrLn "get (L1 _ (M1 b)) = show b"+                  putStrLn "? = get $ forcep patstr exp"+                  putStrLn "==================================================="+                else do+                  putStrLn "---------------------------------------------------"+                putStrLn $ "patstr                   = " ++ patstr+                if code > 4+                then putStrLn $  "expected value           = " ++ expect+                else return ()+--              putStrLn $ "pat = " ++ show pat+                putStrLn $ "showPat.compilePat       = " ++ showPat pat+                if code <= 4+                then putStrLn $  "expected value           = " ++ expect+                else return ()+                s1 <- catch+                        ( return $! force $! get $! forcep patstr exp )+                        (\e -> do let err = show (e :: ErrorCall)+--                      (\e -> do let err = show (e :: BottomedOut)+                                  return err)+                putStr "actual value             = "+                return $! s1+           )+           -- ErrorCall if use __ = undefined+           -- BottomedOut if use __ = throw BottomedOut+           (\e -> do let err = show (e :: ErrorCall)+--         (\e -> do let err = show (e :: BottomedOut)+                     return err)+    putStrLn s+    doit19 False t++-------------------------------------------------------------------------------++  doit20 :: Bool -> [(Int,String)] -> IO ()+  doit20 _ [] = do+                   putStrLn "--------------------------------------------------"+                   return ()+  doit20 b ((code,patstr):t) = do+    let expect = case code of+                  1 -> "4.5"+                  2 -> "Prelude.undefined"+                  3 -> "4.5 (due to pattern-match failure)"+                  4 -> "syntax error"+                  5 -> "4.5 (but \"# with subpattern\" warning)"+                  6 -> "4.5 (but \"constraint/subpattern arity mismatch\" warning)"+#if WARN_PATTERN_MATCH_FAILURE+                  13 -> "7 (but with pattern-match failure warning)"+                  23 -> "Prelude.undefined (but with pattern-match failure warning)"+#else+                  13 -> "7 (with silent pattern-match failure)"+                  23 -> "Prelude.undefined (with silent pattern-match failure)"+#endif+                  _ -> error $ "doit20: unexpected code " ++ show code+    s <- catch+           ( do+--              let exp = expTK_1  -- K3 K2 (J1 4.5)+                let exp = expTK_2  -- K3 __ (J1 4.5)+                let pat = compilePat patstr+                let get = getK+                if b+                then do+                  putStrLn "==================================================="+--                putStrLn "exp = K3 K2 (J1 4.5)"+                  putStrLn "exp = K3 __ (J1 4.5)"+                  putStrLn "get = (K3 _ (J1 f)) = show f"+                  putStrLn "? = get $ forcep patstr exp"+                  putStrLn "==================================================="+                else do+                  putStrLn "---------------------------------------------------"+                putStrLn $ "patstr                   = " ++ patstr+                if code > 4+                then putStrLn $  "expected value           = " ++ expect+                else return ()+--              putStrLn $ "pat = " ++ show pat+                putStrLn $ "showPat.compilePat       = " ++ showPat pat+                if code <= 4+                then putStrLn $  "expected value           = " ++ expect+                else return ()+                s1 <- catch+                        ( return $! force $! get $! forcep patstr exp )+                        (\e -> do let err = show (e :: ErrorCall)+--                      (\e -> do let err = show (e :: BottomedOut)+                                  return err)+                putStr "actual value             = "+                return $! s1+           )+           -- ErrorCall if use __ = undefined+           -- BottomedOut if use __ = throw BottomedOut+           (\e -> do let err = show (e :: ErrorCall)+--         (\e -> do let err = show (e :: BottomedOut)+                     return err)+    putStrLn s+    doit20 False t++-------------------------------------------------------------------------------++#if __GLASGOW_HASKELL__ >= 708+  doit23 :: String+  doit23 = show $ fg23 exp23+--doit23 = show $ get23 $ forcepDyn' fg23 exp23+   where+    exp23 = [[[__]],[[__,6],__,[7]]] :: [[[Int]]]+    get23 xs = (((xs!!1)!!2)!!0)+#if 0+    fg23 :: forall a. (Generic a, HasDatatypeInfo a) => a -> DatatypeInfo (Code a)+    fg23 d = dti+#else+    fg23 :: forall a. (Generic a, HasDatatypeInfo a, All2 Show (Code a), Typeable a) => a -> PatNode+#if 1+    fg23 d = doit23' dti proxy_a d (from d)+#else+    fg23 d | cname == "[[Int]]"  = WI emptyPatNodeAttrs+           | otherwise           = WR emptyPatNodeAttrs+#endif+#endif+     where+--    ADT mname tname (Constructor cname :* _) = dti+--    ADT mname tname (Constructor cname :* _) = dti :: DatatypeInfo (Code a)+--    (mname,tname,cname) = case dti of ...+--    ADT mname tname (Constructor cname :* (Infix ":" RightAssociative 5 :* Nil)) = dti+      dti = datatypeInfo proxy_a+      proxy_a = Proxy :: Proxy a+      xrep = from d++  doit23' :: forall a.+             (+               Generic a+             , HasDatatypeInfo a+--           , All2 NFDataP (Code a)+             , All2 Show (Code a)+             , Typeable a+--           , NFDataN a+--           , NFDataP a+             ) =>+                     DatatypeInfo (Code a)+                  -> Proxy a+                  -> a+                  -> Rep a+                  -> PatNode+  doit23' (ADT     _ _ cs) proxy_a x xrep+   = doit23'' cs         proxy_a x xrep+  doit23' (Newtype _ _ c ) proxy_a x xrep+   = doit23'' (c :* Nil) proxy_a x xrep++  doit23'' :: forall a xss.+            (+              Generic a+            , HasDatatypeInfo a+            , All2 Show xss+            ) =>+                    NP ConstructorInfo xss+                 -> Proxy a+                 -> a+                 -> SOP I xss+                 -> PatNode+  doit23'' (m :* _) proxy_a x (SOP (Z xs))+   | tx == "[[Int]]"  = WI emptyPatNodeAttrs+   | otherwise        = WR emptyPatNodeAttrs+   where+    !_ = trace ("*** "++tx) $ ()+    tx | (Constructor n) <- m  = n+       | (Infix n _ _) <- m    = n+       | (Record n _) <- m     = n+  doit23'' (m :* ms) proxy_a x (SOP (S xss))+   = doit23'' ms proxy_a x (SOP xss)+  doit23'' _ _ _ _ = error "doit23'': unexpected case!!"+#endif++-------------------------------------------------------------------------------++#endif++  doit24 :: Bool -> [(Int,Int,(Float,[Int],Bool))] -> IO ()+  doit24 _ [] = do+                   putStrLn "--------------------------------------------------"+                   return ()+  doit24 b ((code,ident,exp):t) = do+    let expect = case code of+                  1 -> "7"+                  2 -> "Prelude.undefined"+                  3 -> "7 (due to pattern-match failure)"+                  4 -> "syntax error"+                  5 -> "7 (but \"# with subpattern\" warning)"+                  6 -> "7 (but \"constraint/subpattern arity mismatch\" warning)"+#if WARN_PATTERN_MATCH_FAILURE+                  13 -> "7 (but with pattern-match failure warning)"+                  23 -> "Prelude.undefined (but with pattern-match failure warning)"+#else+                  13 -> "7 (with silent pattern-match failure)"+                  23 -> "Prelude.undefined (with silent pattern-match failure)"+#endif+                  _ -> error $ "doit24: unexpected code " ++ show code+    s <- catch+           ( do+--              let exp = force_ Propagate (force_ Propagate 3.4, force_ Propagate (force_ Propagate 5 : (force_ Propagate __ : (force_ Propagate 7 : force_ Propagate []))), force_ Propagate __) :: (Float, [Int], Bool)+--              let seq_exp = mkSeqableHarness exp+--              let pat = compilePat patstr+                let get (_,xs,_) = show $ (xs!!2)+                if b+                then do+                  putStrLn "==================================================="+                  putStrLn "exp = <refer to test code>"+                  putStrLn "get (_,xs,_) = show $ (xs!!2)"+                  putStrLn "? = get $! exp"+                  putStrLn "==================================================="+                else do+                  putStrLn "---------------------------------------------------"+--              putStrLn $ "patstr                   = " ++ patstr+                if code > 4+                then putStrLn $  show ident ++ " expected value           = " ++ expect+                else return ()+--              putStrLn $ "pat = " ++ show pat+--              putStrLn $ "showPat.compilePat       = " ++ showPat pat+                if code <= 4+                then putStrLn $  show ident ++ " expected value           = " ++ expect+                else return ()+                s1 <- catch+                        ( return $! force $! get $! exp )+                        (\e -> do let err = show (e :: ErrorCall)+--                      (\e -> do let err = show (e :: BottomedOut)+                                  return err)+                putStr $ show ident ++ " actual value             = "+                return $! s1+           )+           -- ErrorCall if use __ = undefined+           -- BottomedOut if use __ = throw BottomedOut+           (\e -> do let err = show (e :: ErrorCall)+--         (\e -> do let err = show (e :: BottomedOut)+                     return err)+    putStrLn s+    doit24 False t++-------------------------------------------------------------------------------++  doit25 :: Bool -> [(Int,Int,(Float,(Bool,Int),Bool))] -> IO ()+  doit25 _ [] = do+                   putStrLn "--------------------------------------------------"+                   return ()+  doit25 b ((code,ident,exp):t) = do+    let expect = case code of+                  1 -> "7"+                  2 -> "Prelude.undefined"+                  3 -> "7 (due to pattern-match failure)"+                  4 -> "syntax error"+                  5 -> "7 (but \"# with subpattern\" warning)"+                  6 -> "7 (but \"constraint/subpattern arity mismatch\" warning)"+#if WARN_PATTERN_MATCH_FAILURE+                  13 -> "7 (but with pattern-match failure warning)"+                  23 -> "Prelude.undefined (but with pattern-match failure warning)"+#else+                  13 -> "7 (with silent pattern-match failure)"+                  23 -> "Prelude.undefined (with silent pattern-match failure)"+#endif+                  _ -> error $ "doit25: unexpected code " ++ show code+    s <- catch+           ( do+--              let exp = force_ Propagate (force_ Propagate 3.4, force_ Propagate (force_ Propagate 5 : (force_ Propagate __ : (force_ Propagate 7 : force_ Propagate []))), force_ Propagate __) :: (Float, [Int], Bool)+--              let seq_exp = mkSeqableHarness exp+--              let pat = compilePat patstr+                let get (_,(_,x),_) = show x+                if b+                then do+                  putStrLn "==================================================="+                  putStrLn "exp = <refer to test code>"+                  putStrLn "get (_,(_,x),_) = show x"+                  putStrLn "? = get $! exp"+                  putStrLn "==================================================="+                else do+                  putStrLn "---------------------------------------------------"+--              putStrLn $ "patstr                   = " ++ patstr+                if code > 4+                then putStrLn $  show ident ++ " expected value           = " ++ expect+                else return ()+--              putStrLn $ "pat = " ++ show pat+--              putStrLn $ "showPat.compilePat       = " ++ showPat pat+                if code <= 4+                then putStrLn $  show ident ++ " expected value           = " ++ expect+                else return ()+                s1 <- catch+                        ( return $! force $! get $! exp )+                        (\e -> do let err = show (e :: ErrorCall)+--                      (\e -> do let err = show (e :: BottomedOut)+                                  return err)+                putStr $ show ident ++ " actual value             = "+                return $! s1+           )+           -- ErrorCall if use __ = undefined+           -- BottomedOut if use __ = throw BottomedOut+           (\e -> do let err = show (e :: ErrorCall)+--         (\e -> do let err = show (e :: BottomedOut)+                     return err)+    putStrLn s+    doit25 False t++-------------------------------------------------------------------------------++#if USE_SOP++  doit26 :: Bool -> [(Int,Int,(Float,[Int],Bool))] -> IO ()+  doit26 _ [] = do+                   putStrLn "--------------------------------------------------"+                   return ()+  doit26 b ((code,ident,exp):t) = do+    let expect = case code of+                  1 -> "7"+                  2 -> "Prelude.undefined"+                  3 -> "7 (due to pattern-match failure)"+                  4 -> "syntax error"+                  5 -> "7 (but \"# with subpattern\" warning)"+                  6 -> "7 (but \"constraint/subpattern arity mismatch\" warning)"+#if WARN_PATTERN_MATCH_FAILURE+                  13 -> "7 (but with pattern-match failure warning)"+                  23 -> "Prelude.undefined (but with pattern-match failure warning)"+#else+                  13 -> "7 (with silent pattern-match failure)"+                  23 -> "Prelude.undefined (with silent pattern-match failure)"+#endif+                  _ -> error $ "doit26: unexpected code " ++ show code+    s <- catch+           ( do+--              let exp = force_ Propagate (force_ Propagate 3.4, force_ Propagate (force_ Propagate 5 : (force_ Propagate __ : (force_ Propagate 7 : force_ Propagate []))), force_ Propagate __) :: (Float, [Int], Bool)+--              let seq_exp = mkSeqableHarness exp+--              let pat = compilePat patstr+                let get (_,xs,_) = show $ (xs!!2)+                if b+                then do+                  putStrLn "==================================================="+                  putStrLn "exp = <refer to test code>"+                  putStrLn "get (_,xs,_) = show $ (xs!!2)"+                  putStrLn "? = get $! exp"+                  putStrLn "==================================================="+                else do+                  putStrLn "---------------------------------------------------"+--              putStrLn $ "patstr                   = " ++ patstr+                if code > 4+                then putStrLn $  show ident ++ " expected value           = " ++ expect+                else return ()+--              putStrLn $ "pat = " ++ show pat+--              putStrLn $ "showPat.compilePat       = " ++ showPat pat+                if code <= 4+                then putStrLn $  show ident ++ " expected value           = " ++ expect+                else return ()+                s1 <- catch+                        ( return $! force $! get $! exp )+                        (\e -> do let err = show (e :: ErrorCall)+--                      (\e -> do let err = show (e :: BottomedOut)+                                  return err)+                putStr $ show ident ++ " actual value             = "+                return $! s1+           )+           -- ErrorCall if use __ = undefined+           -- BottomedOut if use __ = throw BottomedOut+           (\e -> do let err = show (e :: ErrorCall)+--         (\e -> do let err = show (e :: BottomedOut)+                     return err)+    putStrLn s+    doit26 False t++-------------------------------------------------------------------------------++  doit27 :: Bool -> [(Int,Int,TJ)] -> IO ()+  doit27 _ [] = do+                   putStrLn "--------------------------------------------------"+                   return ()+  doit27 b ((code,ident,exp):t) = do+    let expect = case code of+                  1 -> "4.5"+                  2 -> "Prelude.undefined"+                  3 -> "4.5 (due to pattern-match failure)"+                  4 -> "syntax error"+                  5 -> "4.5 (but \"# with subpattern\" warning)"+                  6 -> "4.5 (but \"constraint/subpattern arity mismatch\" warning)"+#if WARN_PATTERN_MATCH_FAILURE+                  13 -> "7 (but with pattern-match failure warning)"+                  23 -> "Prelude.undefined (but with pattern-match failure warning)"+#else+                  13 -> "7 (with silent pattern-match failure)"+                  23 -> "Prelude.undefined (with silent pattern-match failure)"+#endif+                  _ -> error $ "doit27: unexpected code " ++ show code+    s <- catch+           ( do+--              let exp = expTJ_1  -- J2 (1, J4 (J3, K3 K2 (J1 4.5))) False+--              let exp = expTJ_2  -- J2 (1, J4 (J3, K3 __ (J1 4.5))) False+--              let exp = expTJ_3  -- J2 (1, J4 (__, K3 K2 (J1 4.5))) False+--              let exp = expTJ_4  -- J2 (1, J4 (__, K3 __ (J1 4.5))) __+--              let pat = compilePat patstr+                let get = getJ+                if b+                then do+                  putStrLn "==================================================="+--                putStrLn "exp = J2 (1, J4 (J3, K3 K2 (J1 4.5))) False"+--                putStrLn "exp = J2 (1, J4 (J3, K3 __ (J1 4.5))) False"+--                putStrLn "exp = J2 (1, J4 (__, K3 K2 (J1 4.5))) False"+                  putStrLn "exp = J2 (1, J4 (__, K3 __ (J1 4.5))) __"+                  putStrLn "get = (J2 (_, J4 (_, K3 _ (J1 f))) _) = show f"+                  putStrLn "? = get exp"+                  putStrLn "==================================================="+                else do+                  putStrLn "---------------------------------------------------"+--              putStrLn $ "patstr                   = " ++ patstr+                if code > 4+                then putStrLn $  show ident ++ " expected value           = " ++ expect+                else return ()+--              putStrLn $ "pat = " ++ show pat+--              putStrLn $ "showPat.compilePat       = " ++ showPat pat+                if code <= 4+                then putStrLn $  show ident ++ " expected value           = " ++ expect+                else return ()+                s1 <- catch+                        ( return $! force $! get $! exp )+                        (\e -> do let err = show (e :: ErrorCall)+--                      (\e -> do let err = show (e :: BottomedOut)+                                  return err)+                putStr $ show ident ++ " actual value             = "+                return $! s1+           )+           -- ErrorCall if use __ = undefined+           -- BottomedOut if use __ = throw BottomedOut+           (\e -> do let err = show (e :: ErrorCall)+--         (\e -> do let err = show (e :: BottomedOut)+                     return err)+    putStrLn s+    doit27 False t++-------------------------------------------------------------------------------++  doit28 :: Bool -> [(Int,String)] -> IO ()+  doit28 _ [] = do+                   putStrLn "--------------------------------------------------"+                   return ()+  doit28 b ((code,patstr):t) = do+    let expect = case code of+                  1 -> "7"+                  2 -> "Prelude.undefined"+                  3 -> "7 (due to pattern-match failure)"+                  4 -> "syntax error"+                  5 -> "7 (but \"# with subpattern\" warning)"+                  6 -> "7 (but \"constraint/subpattern arity mismatch\" warning)"+#if WARN_PATTERN_MATCH_FAILURE+                  13 -> "7 (but with pattern-match failure warning)"+                  23 -> "Prelude.undefined (but with pattern-match failure warning)"+#else+                  13 -> "7 (with silent pattern-match failure)"+                  23 -> "Prelude.undefined (with silent pattern-match failure)"+#endif+                  _ -> error $ "doit28: unexpected code " ++ show code+    s <- catch+           ( do+                let exp = expTG_6  -- G2 5 __ 7+                let pat = compilePat patstr+                let get = getG'+                if b+                then do+                  putStrLn "==================================================="+                  putStrLn "exp = G2 5 __ 7 :: TG"+                  putStrLn "get (G2 _ _ n) = n"+                  putStrLn "? = get $ forcep patstr exp"+                  putStrLn "==================================================="+                else do+                  putStrLn "---------------------------------------------------"+                putStrLn $ "patstr                   = " ++ patstr+                if code > 4+                then putStrLn $  "expected value           = " ++ expect+                else return ()+--              putStrLn $ "pat = " ++ show pat+                putStrLn $ "showPat.compilePat       = " ++ showPat pat+                if code <= 4+                then putStrLn $  "expected value           = " ++ expect+                else return ()+                s1 <- catch+                        ( return $! force $! get $! forcep patstr exp )+                        (\e -> do let err = show (e :: ErrorCall)+--                      (\e -> do let err = show (e :: BottomedOut)+                                  return err)+                putStr "actual value             = "+                return $! s1+           )+           -- ErrorCall if use __ = undefined+           -- BottomedOut if use __ = throw BottomedOut+           (\e -> do let err = show (e :: ErrorCall)+--         (\e -> do let err = show (e :: BottomedOut)+                     return err)+    putStrLn s+    doit28 False t++-------------------------------------------------------------------------------++  doit29 :: Bool -> [(Int,String)] -> IO ()+  doit29 _ [] = do+                   putStrLn "--------------------------------------------------"+                   return ()+  doit29 b ((code,patstr):t) = do+    let expect = case code of+                  1 -> "((999999,1999999),3999999)"+                  2 -> "Prelude.undefined"+                  3 -> "((999999,1999999),3999999) (due to pattern-match failure)"+                  4 -> "syntax error"+                  5 -> "((999999,1999999),3999999) (but \"# with subpattern\" warning)"+                  6 -> "((999999,1999999),3999999) (but \"constraint/subpattern arity mismatch\" warning)"+#if WARN_PATTERN_MATCH_FAILURE+                  13 -> "((999999,1999999),3999999) (but with pattern-match failure warning)"+                  23 -> "Prelude.undefined (but with pattern-match failure warning)"+#else+                  13 -> "((999999,1999999),3999999) (with silent pattern-match failure)"+                  23 -> "Prelude.undefined (with silent pattern-match failure)"+#endif+                  _ -> error $ "doit29: unexpected code " ++ show code+    s <- catch+           ( do+                let exp = (([0..999999::Int],[1000000..1999999::Int]),[2000000..3999999::Int])+                let pat = compilePat patstr+                let get ((xs,ys),zs) = show ((last xs,last ys),last zs)+                if b+                then do+                  putStrLn "==================================================="+                  putStrLn "exp = (([0..999999],[1000000..1999999]),[2000000..3999999])"+                  putStrLn "get ((xs,ys),zs) = show ((last xs,last ys),last zs)"+                  putStrLn "? = get $ forcep patstr exp"+                  putStrLn "==================================================="+                else do+                  putStrLn "---------------------------------------------------"+                putStrLn $ "patstr                   = " ++ patstr+                if code > 4+                then putStrLn $  "expected value           = " ++ expect+                else return ()+--              putStrLn $ "pat = " ++ show pat+                putStrLn $ "showPat.compilePat       = " ++ showPat pat+                if code <= 4+                then putStrLn $  "expected value           = " ++ expect+                else return ()+                s1 <- catch+                        ( return $! force $! get $! forcep patstr exp )+                        (\e -> do let err = show (e :: ErrorCall)+--                      (\e -> do let err = show (e :: BottomedOut)+                                  return err)+                putStr "actual value             = "+                return $! s1+           )+           -- ErrorCall if use __ = undefined+           -- BottomedOut if use __ = throw BottomedOut+           (\e -> do let err = show (e :: ErrorCall)+--         (\e -> do let err = show (e :: BottomedOut)+                     return err)+    putStrLn s+    doit29 False t++-------------------------------------------------------------------------------++#endif 
tests/Blah98.hs view
@@ -1,24 +1,1102 @@  ------------------------------------------------------------------------------- -{-# LANGUAGE CPP #-}-----------------------------------------------------------------------------------  module Blah98 ( run_tests ) where-----------------------------------------------------------------------------------#if NEW_IMPROVED_PATTERN_GRAMMAR-#if USE_CURLY_BRACE_INSTEAD_OF_PAREN_FOR_SUBPATTERNS-#error To run the tests, you must build with the flag USE_CURLY_BRACE_INSTEAD_OF_PAREN_FOR_SUBPATTERNS set False (the default).---import Blah98_new_grammar_braces-#else-  import Blah98_new_grammar-#endif-#else-  import Blah98_old_grammar-#endif+-- This is a pared-down version of Blah.hs, for testing+-- deepseq-bounded when built with the HASKELL98_FRAGMENT+-- flag set.  See Blah.hs for comments and other "flesh".++-------------------------------------------------------------------------------++{-# LANGUAGE CPP #-}++-------------------------------------------------------------------------------++#define FOCUS_TEST 0+#define USE_TRACE 0++-------------------------------------------------------------------------------++  module Blah98 ( run_tests ) where++-------------------------------------------------------------------------------++--import Common+  import Foo++  import Control.DeepSeq.Bounded hiding ( F )++  import Data.Maybe++  import Control.Exception+--import Control.Monad ( guard )+  import Control.Monad ( replicateM )+  import Control.Monad ( when )++  import Data.Typeable ( Typeable )+  import Data.Typeable ( typeOf )++--import Util ( spoor )+  import Debug.Trace ( trace )+  import Control.DeepSeq++  import Data.Typeable ( Proxy(..) )++  import Data.List ( intercalate )++  import System.IO.Unsafe ( unsafePerformIO )++-------------------------------------------------------------------------------++  -- For convenience in GHCi interactive sessions:+  cp = compilePat+--cp = compilePat+  ip = intersectPats+  isp = subPat++-------------------------------------------------------------------------------++  run_tests :: IO Int+  run_tests = do+    putStr "\n"+    -- So can notice the start when scrollback, esp. in ghci reload/reruns.+--  replicateM 50 $ putStrLn "################################################################################"+    putStrLn "\nTesting.\n"++#if ! FOCUS_TEST++#if 1+--  let shp s = s ++ replicate (30 - length s) ' ' ++ show (compilePat s)+    let shp s = +         unsafePerformIO $+         catch+          ( return $! force $ s ++ replicate (30 - length s) ' ' ++ show (compilePat s) )+          ( \e -> do let err = show (e :: ErrorCall)+                     return err )++    putStrLn "Pattern                       Compiles to"+--  putStrLn $ shp ""  -- empty pattern syntax error+    putStrLn $ shp "*"  -- Node WW []+--  putStrLn $ shp "@"  -- Node WS []  -- obsoleted (use "." w/o children)+    putStrLn $ shp "."  -- Node I []  -- no parent to absorb (should be error)+    putStrLn $ shp "!"  -- Node WS []+--  putStrLn $ shp "**"  -- Node WS []  -- "disconnected pattern (not rooted)"+--  putStrLn $ shp "!*"  -- Node WS []  -- "disconnected pattern (not rooted)"+--  putStrLn $ shp "*!"  -- Node WS []  -- "disconnected pattern (not rooted)"+    putStrLn $ shp "()"  -- Node WR []+    putStrLn $ shp "(*)"  -- Node WR [Node WW []]+    putStrLn $ shp "(**)"  -- Node WR [Node WW [],Node WW []]+    putStrLn $ shp "(!*)"  -- Node WR [Node WS [],Node WW []]+    putStrLn $ shp "(.!)"  -- Node WR [Node I [],Node WS []]+    putStrLn $ shp "(.(.))"  -- Node WR [Node I []] with warning+    putStrLn $ shp "((.))"  -- Node WR [Node WR [Node I []]]+    putStrLn $ shp "(*.*.*.**.*.*)"  -- looks fine+    putStrLn $ shp "(*.(*.(*.)*)*(.*).*)"  -- warning about *{...}+    putStrLn $ shp "(*.(*.(*.)*)*.*)"+--  putStrLn $ shp "(*.(*.(*.)*)(*)(.*).*)"  -- }{ syntax error+-- [old comment for that last:] NodeM WR [NodeM WW [],Nil,NodeM WR [NodeM WW [],Nil,NodeM WR [NodeM WW [],Nil],NodeM WW [],NodeM WW [],Nil,NodeM WW []],Nil,NodeM WW []] -- was wrong but is fixed I think+    putStrLn $ shp "(!*(*23*))"+#endif++#if 1+    let test_patterns10 = [+           (4,  "")  -- syntax error+         , (4,  "!..")  -- syntax error (disconnected pattern)+         , (1,  "(!..)")  -- fail+         , (5,  "(().().())")+         , (2,  "*")+         , (2,  "(***)")+         , (1,  "(...)")+         , (1,  "(*..)")+         , (2,  "(**.)")+         , (2,  "(..*)")++           -- Remember, [a] is a recursive binary ctor app!...+           -- The next four tests give instance errors for [a], but if+           -- testing expTG_* (GNFDataP/grnfp) then it's no longer a list...+         , (13, "(!(*.*).)")+         , (13, "(!(*...).)")+         , (13, "(!(*....).)")+         , (23, "(!(*....)!)")++         , (2,  "(!(*.)*)")+         , (1,  "(!(*.).)")+         , (1,  "(!(*(.*)).)")+         , (2,  "(!(*(*.)).)")+         , (13, "(!((!(.*))).)")  -- See above comment about [a] instance+         , (2,  "(.(!(!(.*))).)")++           -- (See Book, p.84.)+         , (1,  "(!(!(.(!!))).)")+         , (1,  "(!(!(.*)).)")+         , (1,  "(*(*(.*)).)")+         , (2,  "(..*)")+         , (2,  "(*.*)")+         , (1,  ":Tuple3:!(*(*(.*)).)")  -- oops...+         , (1,  ":(,,):!(*(*(.*)).)")+         , (2,  ":(,,):!(*(*(!*)).)")+         , (1,  ":Bool:!(***)")  -- XXX makes no sense (but works) -- oh well;+                                 -- this is an important point to note in+                                 -- docs/blog also...+         , (1,  ":Bool:*")+         , (2,  ":(,,):*")+         , (2,  "(*.!)")+         , (2,  "(*.:Bool:!)")  -- expect parse error+         , (1,  "(*.:Int:!)")  -- still need to implement . when not in type+         , (1,  "(*.:(,):!)")  -- still need to implement . when not in type+         , (1,  "(*.:Int:!)")  -- still need to implement . when not in type+         , (1,  "(*.:Int':!)")  -- still need to implement . when not in type+         , (1,  "(*.:Bool:.)")+         , (2,  "(*.:Int:.)")+         , (2,  "(*.:(,):.)")+         , (1,  "(*.:Bool:.)")+         , (2,  "(*.:Int:.)")+         , (2,  "(*.:(,):.)")+         , (1,  "(**2.)")+         , (2,  "(**3.)")+         , (1,  "(*:G2:.().)")+         , (1,  "(*:Int:.().)")+         ]+    doit14 True test_patterns10+--  doit10 True test_patterns10+#endif++#endif++---------------------------------------------++-- Later: Oh! Don't be silly -- it's all compile-time, and the+-- size or shape of the list is irrelevant -- which rules+-- will fire depends on THIS FILE'S SOURCE CODE (not it's+-- data, including static values)!+-- XXX Even with empty list, the same rule firings occur!...+-- If comment out this block however, the rules do not fire!+#if 1+    -- Testing composition and union:+    let test_patterns11 = [+           (1, "!", "!")+         , (2, "!", "*")+         , (2, "*", "!")+         , (2, "*", "*")+         , (2, "(!!!)", "(*!!)")+         , (2, "(*!!)", "(!!*)")+         , (2, "(!*.)", "(!.!)")+         ]+    doit11 True test_patterns11+#endif++#if 1+    -- Testing splicePats+    let test_patterns12 = [+#if 1+           (1, "!", [], [(0,"*")])+         , (1, "()", [], [(0,"*")])+         , (1, "!", [0], [(0,"*")])+         , (1, "(!!)", [], [(0,"*")])+         , (1, "(!!)", [0], [(0,"*")])+         , (1, "(!!)", [2], [(0,"*")])+         , (1, "(!!)", [], [(0,"*"),(0,".")])+         , (1, "(!!)", [], [(0,"*"),(1,".")])+         , (1, "(!!)", [], [(1,"."),(0,"*")])+         , (1, "(!!)", [], [(0,"*"),(2,".")])+         , (1, "(!!)", [], [(2,"*"),(2,"."),(2,".")])+         , (1, "(!!)", [], [(-1,"*")])+         , (1, "(!!)", [], [(0,"*")])+         , (1, "(!!)", [], [(1,"*")])+         , (1, "(!!)", [], [(2,"*")])+         , (1, "(!!)", [], [(3,"*")])+         , (1, "(!(!!)!)", [1], [(0,"*")])+         , (1, "(!(!!)!)", [1], [(0,"*3"),(1,"."),(2,"*")])+         , (1, "(!(!!)!)", [1,0], [(0,"*"),(0,".")])+         , (1, "((!!!)(()!)!)", [1], [(0,"*"),(0,".")])+         , (1, "((!!!)(()!)!)", [1,0], [(0,"*"),(0,".")])+         , (1, "((...)(().).)", [1,0], [(0,"*"),(0,".")])+         , (1, "(:(,,):!(...)(().).)", [1,0], [(0,"*"),(0,".")])+#else+           (1, "!", "()", [(0,"*")])+         , (1, "()", "()", [(0,"*")])+         , (1, "!", "(())", [(0,"*")])  -- added later, did uncover a bug! (irrefutable pattern failure)+         , (1, "(!!)", "()", [(0,"*")])+         , (1, "(!!)", "(())", [(0,"*")])+         , (1, "(!!)", "(!!())", [(0,"*")])+         , (1, "(!!)", "()", [(0,"*"),(0,".")])+         , (1, "(!!)", "()", [(0,"*"),(1,".")])+         , (1, "(!!)", "()", [(1,"."),(0,"*")])+         , (1, "(!!)", "()", [(0,"*"),(2,".")])+         , (1, "(!!)", "()", [(2,"*"),(2,"."),(2,".")])+         , (1, "(!!)", "()", [(-1,"*")])+         , (1, "(!!)", "()", [(0,"*")])+         , (1, "(!!)", "()", [(1,"*")])+         , (1, "(!!)", "()", [(2,"*")])+         , (1, "(!!)", "()", [(3,"*")])+         , (1, "(!(!!)!)", "(!()!)", [(0,"*")])+         , (1, "(!(!!)!)", "(!()!)", [(0,"*3"),(1,"."),(2,"*")])+         , (1, "(!(!!)!)", "(!(()!)!)", [(0,"*"),(0,".")])+         , (1, "(!(!!)!)", "(!(()))", [(0,"*"),(0,".")])+         , (1, "((!!!)(()!)!)", "(!())", [(0,"*"),(0,".")])+         , (1, "((!!!)(()!)!)", "(!(()))", [(0,"*"),(0,".")])+         , (1, "((...)(().).)", "(!(()))", [(0,"*"),(0,".")])+         , (1, "(:(,,):!(...)(().).)", "(!(()))", [(0,"*"),(0,".")])+#endif+         ]+    doit12 True test_patterns12+#endif++#if ! FOCUS_TEST++#if 1+    -- Testing anything else we can with a single function!+    -- (Getting sick of this cloning.)+    -- Functions are listed in (current) export order.+    -- Things still needing testing are >'d.+    -- Things tested but failing some tests have a *.+    -- +    -- XXX Wow does this ever look cleaner with "Pat" instead of "Pattern"!...+    -- Fortunately splicePats is already tested separately; the rest+    -- we need to test deal only in Pat args (or list of same), so+    -- we can pass a couple [Pat] to test13 along with an Int code+    -- to control delegation.+    --  1    unionPats       :: [ Pat ] -> Pat+    --  2    intersectPats   :: [ Pat ] -> Pat+    --  3    subPat          :: Pat -> Pat -> Bool+--  --  4    unionPatsStr    :: [ String ] -> String+    --  5    emptyPat        :: Pat+--  --  6    mkPat           :: forall d. Data d => d -> Pat+--  --  7    growPat         :: forall d. Data d => Pat -> d -> Pat+    --  8    shrinkPat       :: Pat -> Pat+    --  9    liftPats        :: [ Pat ] -> Pat+    -- 10    splicePats      :: Pat -> Pat -> [(Int, Pat)] -> Pat+    -- 11    isPath          :: Pat -> Bool+    let test_patterns13 = [+           ( 1, ["(!!!)", "(!.)"], "")+         , ( 2, ["(!!!)", "(!.)"], "")+         , ( 3, ["!", "!"], "True")+         , ( 3, [".", "."], "True")+         , ( 3, ["*", "*"], "True")+         , ( 3, ["!", "()"], "True")+         , ( 3, ["()", "!"], "False")+         , ( 3, ["()", "(!)"], "False")+         , ( 3, ["(!)", "(!)"], "True")+         , ( 3, ["(!)", "(!!)"], "False")+         , ( 3, ["(!)", "((!))"], "True")+         , ( 3, ["(!!)", "(!.)"], "False")+         , ( 3, ["(!.)", "(!!)"], "True")+         , ( 3, ["(!!)", "(!!!)"], "False")+         , ( 3, ["()", "(!!!)"], "False")+         , ( 3, ["!", "(*!.)"], "True")+         , ( 3, [".", "(*!.)"], "True")+         , ( 3, ["*", "(*!.)"], "False")+         , ( 3, ["*", "(*)"], "False")+         , ( 3, ["*", "(**)"], "False")+         , ( 4, ["(!!!)", "(!.)"], "")+         , ( 5, ["(!!!)", "(!.)"], "")+#if 0+         , ( 6, ["(!!!)", "(!.)"], "")+         -- matching against val = ([1,2,3::Int],(False,"foo"))+         -- mkPat val = "((!(!(!!)))(!(!(!(!!)))))"+#endif+#if 0+         , ( 7, ["((!(!!))(!(!!)))"], "")+         , ( 7, ["((!(!(!!)))(!(!(!!))))"], "")+         , ( 7, ["((!(!(!!)))(!(!(!(!!)))))"], "")+#endif+         , ( 8, ["((!(!(!!)))(!(!(!(!!)))))"], "")+         , ( 8, ["((!(!(!!)))(!(!(!!))))"], "")+         , ( 8, ["((!(!!))(!(!!)))"], "")+         , ( 8, ["((.(!!))(.(*3!)))"], "")+         , ( 8, ["((.!)(.!))"], "")+         , ( 8, ["(!!)"], "")+         , ( 8, ["!"], "")+         , ( 9, ["(!!!)", "(!.)"], "")+         , (10, ["(!!!)", "(!.)"], "")+         , (11, ["(!!!)", "(!.)"], "")+         ]+    putStrLn "===================================================="+    putStrLn "Testing miscellaneous NFDataP functions..."+    doit13 True test_patterns13+#endif++#if 1+    -- Testing fusion+    putStrLn "\nTesting fusion\n-fenable-rewrite-rules -O -ddump-rules -ddump-simpl-stats -ddump-rule-firings\n"+    let exp12 = (3.4, [5,__,7], __) :: (Float, [Int], Bool)+    let get12 (_,xs,_) = (xs!!2)+    putStrLn $ show $ get12 $ ( forcep ":Bool:*" . forcep ":Int:*" ) exp12+    putStrLn $ show $ get12 $ ( forcep ":Bool:*" . forcep_ (compilePat ":Int:*") ) exp12+    putStrLn $ show $ get12 $ ( forcep_ (compilePat ":Bool:*") . forcep ":Int:*" ) exp12+    putStrLn $ show $ get12 $ ( forcep_ (compilePat ":Bool:*") . forcep_ (compilePat ":Int:*") ) exp12+#endif++#if 1+    putStrLn $ intercalate "\n"+     [ ""+     , "expN_1 = [__] :: [Int]"+     , "expN_2 = [0,1,__,3] :: [Int]"+     , "expN_3 = (3.4, [5,__,7], True) :: (Float, [Int], Bool)"+     , "expN_4 = (3.4, [5,__,7], __) :: (Float, [Int], Bool)"+     , ""+     , "getN_1 xs = show $ ()"+--   , "getN_1 xs = show $ head xs"+--   , "getN_2 xs = show $ (xs!!1)"+     , "getN_2 xs = show $ (xs!!3)"+     , "getN_3 (_,xs,_) = show $ (xs!!2)"+     ]+    doit5 1 0 1 "" >>= putStrLn+    doit6 1 0 1 "" >>= putStrLn+    doit7 1 0 1 "" >>= putStrLn+    doit8 1 0 1 "" >>= putStrLn+#if 0+    doit9 >>= putStrLn  -- XXX broken (whatever it is)+#endif+#endif++#if 0+    s4 <- doit4 1 0 1 ""+    putStrLn s4+#endif++#if 0+    putStrLn $ ""+           ++ "expBase1 = ([True,False],3,Just \"fox\")         :: ([Bool],Int,Maybe String)\n"+           ++ "expBase2 = ([True,False],__,Just \"fox\")        :: ([Bool],Int,Maybe String)\n"+           ++ "expBase3 = ([True,__],3,Just \"fox\")            :: ([Bool],Int,Maybe String)\n"+           ++ "expBase4 = ([True,__],3,Just __)               :: ([Bool],Int,Maybe String)\n"+           ++ "expBase5 = ([True,False],3,Just ['f',__,'x'])  :: ([Bool],Int,Maybe String)\n"+           ++ "expBase6 = ([True,False],3,Just __)            :: ([Bool],Int,Maybe String)\n"+           ++ "get1 ((x:_),_,_) = x           -- True\n"+           ++ "get2 (_,x,_) = x               -- 3\n"+           ++ "get3 (_,_,x) = fromJust x      -- \"fox\"\n"+           ++ "get4 (_,_,Just (x:_)) = x      -- 'f'\n"+    s1 <- doit1 1 1 1 ""+    putStrLn s1+#endif++#endif++    return 0++-------------------------------------------------------------------------------++  hline :: String+  hline = "----------------------------------------------------\n"+  hdline :: String+  hdline = "====================================================\n"++-------------------------------------------------------------------------------++  doit1 :: Int -> Int -> Int -> String -> IO String+  doit1 i j k acc+   -- this glitch (the exception that seemingly escapes my catch)+   -- happens just for these combos (and for all j):+-- | i == 3 && k == 4  = doit1 (1+i) j k acc  -- trying to avoid a glitch...+-- | i == 3 && k == 5  = doit1 (1+i) j k acc  -- trying to avoid a glitch...+-- | i == 3 && j < 4 && k == 5  = doit1 (1+i) j k acc  -- trying to avoid a glitch...+   | k == 7  = return acc+   | j == 6  = doit1 1 1 (1+k) acc+   | i == 5  = doit1 1 (1+j) k acc+   | otherwise  = do+      fexp <- catch+               -- The semantics of the !'s here are not what they were,+               -- since forcing in some places. [?] But at least the+               -- first one seems definitely still needed...+               -- LATER: The second one is also needed, finally seen!+               -- (It is needed for a version of getE _ = "getee", only.)+               -- XXX I'm just not sure whether the second ! is better+               -- to leave in or leave out...+               ( return $! get $! forcen dep exp )+               (\e -> do let err = show (e :: ErrorCall)+--             (\e -> do let err = show (e :: BottomedOut)+                         return err)+--    doit1 (1+i) j k $! force $ acc+      doit1 (1+i) j k $! acc+--    doit1 (1+i) j k $ acc+        ++ "( get" ++ show i ++ " $ forcen " ++ show dep ++ " expBase" ++ show k ++ " )  "+        ++ fexp ++ "\n"+   where+    exp = case k of+            1 -> expBase1+            2 -> expBase2+            3 -> expBase3+            4 -> expBase4+            5 -> expBase5+            6 -> expBase6+    get = case i of+           1 -> get1+           2 -> get2+--         3 -> unsafePerformIO . get3  -- yeesh!...+--         3 -> get3+           3 -> get3 (i,j,k)+           4 -> get4+    dep = j++#if 0+  -- XXX All this fuss to deal with the case that the+  -- entire argument m is undefined (or whatever is going+  -- for "undefined" at the moment...) -- but, none of+  -- the expBase[1-5] have this! ch.+  myFromJust :: Maybe a -> IO (Either () a)+  myFromJust m = do+                    putStrLn "Boo!"+                    catch+                      (myFromJust' m)+                      (\e -> do putStrLn $! show (e::BottomedOut)+                                putStrLn "HERE!"+                                return $! Left ())+  myFromJust' :: Maybe a -> IO (Either () a)+  myFromJust' Nothing = do+--                         throw BottomedOut+                           return $! Left ()+  myFromJust' (Just x) = return $! Right x+--myFromJust _ = throw BottomedOut+#endif++--------------------------------++#if 0+  doit2 :: Int -> Int -> Int -> String -> IO String+  doit2 i j k acc+-- | k == 2  = {- trace (show (i,j,k)) $ -} return acc+-- | k == 7  = return acc+   | k == 27  = return acc+-- | k == 21  = return acc+-- | k == 5  = return acc+-- | j == 15  = doit2 1 0 (1+k) acc+   | j == 11  = {- trace (show (i,j,k)) $ -} doit2 1 0 (1+k) acc+-- | j == 8  = {- trace (show (i,j,k)) $ -} doit2 1 0 (1+k) acc+-- | j == 3  = {- trace (show (i,j,k)) $ -} doit2 1 0 (1+k) acc+#if USE_TRACE+   | i == 2  = trace ("End of " ++ show (i,j',k')) $ doit2 1 (1+j) k acc+-- | i == 3  = trace ("End of " ++ show (i,j',k')) $ doit2 1 (1+j) k acc+#else+   | i == 2  = doit2 1 (1+j) k acc+-- | i == 3  = doit2 1 (1+j) k acc+#endif+   | otherwise  = do+      fexp <- catch+               ( return $! get $! forcen dep exp )+--             ( return $! get $! forcen dep exp )+               -- ErrorCall if use __ = undefined+               -- BottomedOut if use __ = throw BottomedOut+               (\e -> do let err = show (e :: ErrorCall)+--             (\e -> do let err = show (e :: BottomedOut)+                         return err)+      doit2 (1+i) j k $! acc+        ++ "( getB_" ++ show i ++ " $ forcen " ++ show dep ++ (if dep < 10 then " " else "") ++ " expTB_" ++ show (k'-6) ++ " )  "+--      ++ "( getB_" ++ show i ++ " $ forcen " ++ show dep ++ (if dep < 10 then " " else "") ++ " expBase" ++ show k' ++ " )  "+        ++ fexp ++ "\n"+   where+    exp = case k' of+            7 -> expBase7+            8 -> expBase8+            9 -> expBase9+            10 -> expBase10+            11 -> expBase11+            12 -> expBase12+            13 -> expBase13+            14 -> expBase14+            15 -> expBase15+            16 -> expBase16+            17 -> expBase17+            18 -> expBase18+            19 -> expBase19+            20 -> expBase20+            21 -> expBase20  -- fudge it!!+            22 -> expBase22+            23 -> expBase23+            24 -> expBase24+            25 -> expBase25+            26 -> expBase26+            27 -> expBase27+            28 -> expBase28+            29 -> expBase29+            30 -> expBase30+            31 -> expBase31+            32 -> expBase32+    get = case i of+           1 -> if k' >= 27 then getB_3 else getB_1+           2 -> getB_2+    dep = j'+    j' = j+--  j' = j+11+--  k' = k+26+    k' = k+6+#endif++#if 0+  doit3 :: Int -> Int -> Int -> String -> IO String+  doit3 i j k acc+   | k == 2  = return acc+   | j == 8  = {- trace (show (i,j,k)) $ -} doit3 1 1 (1+k) acc+#if USE_TRACE+   | i == 2  = trace ("End of " ++ show (i,j',k')) $ doit3 1 (1+j) k acc+#else+   | i == 2  = doit3 1 (1+j) k acc+#endif+   | otherwise  = do+      fexp <- catch+               ( return $! get $! forcen dep exp )+               -- ErrorCall if use __ = undefined+               -- BottomedOut if use __ = throw BottomedOut+               (\e -> do let err = show (e :: ErrorCall)+--             (\e -> do let err = show (e :: BottomedOut)+                         return err)+      doit3 (1+i) j k $! acc+        ++ "( getB_" ++ show i ++ " $ forcen " ++ show dep ++ " expBase" ++ show k' ++ " )  "+        ++ fexp ++ "\n"+   where+    exp = case k' of+            21 -> expBase21+    get = case i of+           1 -> getA+    dep = j'+    i' = i+    j' = j+    k' = k+20+#endif++#if 0+  doit4 :: Int -> Int -> Int -> String -> IO String+  doit4 i j k acc+-- | k == 2  = return acc+   | k == 4  = return acc+   | j == 8  = {- trace (show (i,j,k)) $ -} doit4 1 0 (1+k) acc+#if USE_TRACE+   | i == 2  = trace ("End of " ++ show (i,j',k')) $ doit4 1 (1+j) k acc+#else+   | i == 2  = doit4 1 (1+j) k acc+#endif+   | otherwise  = do+      fexp <- catch+               ( return $! get $! forcen dep exp )+               -- ErrorCall if use __ = undefined+               -- BottomedOut if use __ = throw BottomedOut+               (\e -> do let err = show (e :: ErrorCall)+--             (\e -> do let err = show (e :: BottomedOut)+                         return err)+      doit4 (1+i) j k $! acc+        ++ "( getE $ forcen " ++ show dep ++ " expTE_" ++ show k' ++ " )  "+        ++ fexp ++ "\n"+   where+    exp = case k' of+            1 -> expTE_1+            2 -> expTE_2+            3 -> expTE_3+    get = case i of+           1 -> getE+    dep = j'+    i' = i+    j' = j+    k' = k+#endif++-------------------------------------------------------------------------------++  doit5 :: Int -> Int -> Int -> String -> IO String+  doit5 i j k acc+   | k == 2  = return acc+   | j == 5  = {- trace (show (i,j,k)) $ -} doit5 1 0 (1+k) acc+#if USE_TRACE+   | i == 2  = trace ("End of " ++ show (i,j',k')) $ doit5 1 (1+j) k acc+#else+   | i == 2  = doit5 1 (1+j) k acc+#endif+   | otherwise  = do+      fexp <- catch+               ( return $! get $! forcen dep exp )+               -- ErrorCall if use __ = undefined+               -- BottomedOut if use __ = throw BottomedOut+               (\e -> do let err = show (e :: ErrorCall)+--             (\e -> do let err = show (e :: BottomedOut)+                         return err)+      doit5 (1+i) j k $! acc+        ++ "forcen " ++ show dep ++ " expN_" ++ show k' ++ " `seq` ()  =  "+        ++ fexp ++ "\n"+   where+    exp = case k' of+            1 -> expN_1+    get = case i of+           1 -> getN_1+    dep = j'+    i' = i+    j' = j+    k' = k++-------------------------------------------------------------------------------++  doit6 :: Int -> Int -> Int -> String -> IO String+  doit6 i j k acc+   | k == 2  = return acc+   | j == 5  = {- trace (show (i,j,k)) $ -} doit6 1 0 (1+k) acc+#if USE_TRACE+   | i == 2  = trace ("End of " ++ show (i',j',k')) $ doit6 1 (1+j) k acc+#else+   | i == 2  = doit6 1 (1+j) k acc+#endif+   | otherwise  = do+      fexp <- catch+               ( return $! get $! forcen dep exp )+               -- ErrorCall if use __ = undefined+               -- BottomedOut if use __ = throw BottomedOut+               (\e -> do let err = show (e :: ErrorCall)+--             (\e -> do let err = show (e :: BottomedOut)+                         return err)+      doit6 (1+i) j k $! acc+        ++ "getN_" ++ show i' ++" $ forcen " ++ show dep ++ " expN_" ++ show k' ++ "  =  "+        ++ fexp ++ "\n"+   where+    exp = case k' of+            _ -> expN_2+    get = case i of+           _ -> getN_2+    dep = j'+    i' = i+1+    j' = j+    k' = k+1++-------------------------------------------------------------------------------++  doit7 :: Int -> Int -> Int -> String -> IO String+  doit7 i j k acc+   | k == 2  = return acc+   | j == 5  = {- trace (show (i,j,k)) $ -} doit7 1 0 (1+k) acc+#if USE_TRACE+   | i == 2  = trace ("End of " ++ show (i',j',k')) $ doit7 1 (1+j) k acc+#else+   | i == 2  = doit7 1 (1+j) k acc+#endif+   | otherwise  = do+      fexp <- catch+               ( return $! get $! forcen dep exp )+               -- ErrorCall if use __ = undefined+               -- BottomedOut if use __ = throw BottomedOut+               (\e -> do let err = show (e :: ErrorCall)+--             (\e -> do let err = show (e :: BottomedOut)+                         return err)+      doit7 (1+i) j k $! acc+        ++ "getN_" ++ show i' ++" $ forcen " ++ show dep ++ " expN_" ++ show k' ++ "  =  "+        ++ fexp ++ "\n"+   where+    exp = case k' of+            _ -> expN_3+    get = case i of+           _ -> getN_3+    dep = j'+    i' = i+2+    j' = j+    k' = k+2++-------------------------------------------------------------------------------++  doit8 :: Int -> Int -> Int -> String -> IO String+  doit8 i j k acc+   | k == 2  = return acc+   | j == 5  = {- trace (show (i,j,k)) $ -} doit8 1 0 (1+k) acc+#if USE_TRACE+   | i == 2  = trace ("End of " ++ show (i',j',k')) $ doit8 1 (1+j) k acc+#else+   | i == 2  = doit8 1 (1+j) k acc+#endif+   | otherwise  = do+      fexp <- catch+               ( return $! get $! forcen dep exp )+               -- ErrorCall if use __ = undefined+               -- BottomedOut if use __ = throw BottomedOut+               (\e -> do let err = show (e :: ErrorCall)+--             (\e -> do let err = show (e :: BottomedOut)+                         return err)+      doit8 (1+i) j k $! acc+        ++ "getN_" ++ show i' ++" $ forcen " ++ show dep ++ " expN_" ++ show k' ++ "  =  "+        ++ fexp ++ "\n"+   where+    exp = case k' of+            _ -> expN_4+    get = case i of+           _ -> getN_3+    dep = j'+    i' = i+2+    j' = j+    k' = k+3++-------------------------------------------------------------------------------++#if 0++#if 0+  expP_1 = (3.4, [5,__,7], __) :: (Float, [Int], Bool)+  patP_1 = Node (TR [typeOf ((__,__,__)::(Float, [Int], Bool))])+             [ Node (TR [typeOf (__::Bool)]) []+--           [ Node (TR [typeOf (__::Float)]) []+--           [ Node (NTR [typeOf (__::Bool)]) []+--           [ Node (NTR [typeOf (__::Float)]) []+--           , Node WS []+             , Node (TW [typeOf ([__]::[Int])]) []+--           , Node (TR [typeOf ([__]::[Int])]) []+--           , Node (TR [typeOf ([__]::[Int])]) [ Node WS [], Node WS [] ]  -- why not?+             , Node WW []+--           , Node I []+             ]+  getP_1 (_,xs,_) = show $ (xs!!2)+#endif++  doit9 :: IO String+  doit9 = do+#if 0+    putStrLn $ intercalate "\n"+     [ ""+     , "expP_1 = (3.4, [5,__,7], __) :: (Float, [Int], Bool)"+     , "patP_1 = Node (T [typeOf ((__,__,__)::(Float, [Int], Bool))])"+     , "           [ Node W []"+     , "           , Node (T [typeOf ([__]::[Int])]) []"+     , "           , Node I []"+     , "           ]"+     , "getP_1 (_,xs,_) = show $ (xs!!2)"+     ]+    putStrLn "getP_1 $ forcep patP_1 expP_1"+#endif+    s <- catch+             ( return $! getP_1 $! forcep patP_1 expP_1 )+--           ( return $! getP_2 $! forcep patP_2 expP_2 )+--           ( return $! getP_3 $! forcep patP_3 expP_3 )+             -- ErrorCall if use __ = undefined+             -- BottomedOut if use __ = throw BottomedOut+             (\e -> do let err = show (e :: ErrorCall)+--           (\e -> do let err = show (e :: BottomedOut)+                       return err)+    return s++#endif++-------------------------------------------------------------------------------++  doit10 :: Bool -> [(Int,String)] -> IO ()+  doit10 _ [] = do+                   putStrLn "----------------------------------------------------"+                   return ()+  doit10 b ((code,patstr):t) = do+    let expect = case code of+                  1 -> "7"+                  2 -> "Prelude.undefined"+                  3 -> "pattern-match failure"+                  4 -> "syntax error"+                  5 -> "7 (but \"# with subpattern\" warning)"+                  6 -> "7 (but \"constraint/subpattern arity mismatch\" warning)"+                  13 -> "7 (but with pattern-match failure warning)"+                  23 -> "Prelude.undefined (but with pattern-match failure warning)"+                  _ -> error $ "doit10: unexpected code " ++ show code+    s <- catch+           ( do+                let exp = (3.4, [5,__,7], __) :: (Float, [Int], Bool)+                let pat = compilePat patstr+                let get (_,xs,_) = show $ (xs!!2)+                if b+                 then do+                  putStrLn "===================================================="+                  putStrLn "exp = (3.4, [5,__,7], __) :: (Float, [Int], Bool)"+                  putStrLn "get (_,xs,_) = show $ (xs!!2)"+                  putStrLn "? = get $ forcep patstr exp"+                  putStrLn "===================================================="+                 else do+                  putStrLn "----------------------------------------------------"+                putStrLn $ "patstr                   = " ++ patstr+                if code > 4+                 then putStrLn $  "expected value           = " ++ expect+                 else return ()+--              putStrLn $ "pat = " ++ show pat+                putStrLn $ "showPat.compilePat       = " ++ showPat pat+                if code <= 4+                 then putStrLn $  "expected value           = " ++ expect+                 else return ()+                s1 <- catch+                        ( return $! force $! get $! forcep patstr exp )+                        (\e -> do let err = show (e :: ErrorCall)+--                      (\e -> do let err = show (e :: BottomedOut)+                                  return err)+                putStr "actual value             = "+                return $! s1+           )+           -- ErrorCall if use __ = undefined+           -- BottomedOut if use __ = throw BottomedOut+           (\e -> do let err = show (e :: ErrorCall)+--         (\e -> do let err = show (e :: BottomedOut)+                     return err)+    putStrLn s+    doit10 False t++-------------------------------------------------------------------------------++  doit11 :: Bool -> [(Int,String,String)] -> IO ()+  doit11 _ [] = do+                   putStrLn "----------------------------------------------------"+                   return ()+  doit11 b ((code,patstr1,patstr2):t) = do+    let expect = case code of+                  1 -> "7"+                  2 -> "Prelude.undefined"+                  3 -> "pattern-match failure"+                  4 -> "syntax error"+                  5 -> "7 (but \"# with subpattern\" warning)"+                  6 -> "7 (but \"constraint/subpattern arity mismatch\" warning)"+                  _ -> error $ "doit11: unexpected code " ++ show code+    s <- catch+           ( do+                let exp = (3.4, [5,__,7], __) :: (Float, [Int], Bool)+                let patstrU = showPat $ unionPats [compilePat patstr1, compilePat patstr2]+                let pat1 = compilePat patstr1+                let pat2 = compilePat patstr2+                let patU = unionPats [pat1,pat2]+                let get (_,xs,_) = show $ (xs!!2)+                if b+                 then do+                  putStrLn "===================================================="+                  putStrLn "exp = (3.4, [5,__,7], __) :: (Float, [Int], Bool)"+                  putStrLn "get (_,xs,_) = show $ (xs!!2)"+                  putStrLn "? = get $ ( forcep patstr2 . forcep patstr1 ) exp"+--                putStrLn "? = get $ ( forcep ( unionPatsStr [ patstr1, patstr2 ] ) ) exp"+                  putStrLn "? = get $! ( forcep_ ( unionPats [ pat1, pat2 ] ) ) exp"+                  putStrLn "(Results were more interesting with a previous semantics...)."+                  putStrLn "===================================================="+                 else do+                  putStrLn "----------------------------------------------------"+                putStrLn $ "patstr1                     = " ++ patstr1+                putStrLn $ "patstr2                     = " ++ patstr2+                putStrLn $ "patstrU                     = " ++ patstrU+                if code > 4+                 then putStrLn $  "expected value              = " ++ expect+                 else return ()+--              putStrLn $ "pat = " ++ show pat+                putStrLn $ "showPat.compilePat patstr1  = " ++ showPat pat1+                putStrLn $ "showPat.compilePat patstr2  = " ++ showPat pat2+                putStrLn $ "showPat.compilePat patstrU  = " ++ showPat patU+                if code <= 4+                 then putStrLn $  "expected value              = " ++ expect+                 else return ()+                putStr "actual value                = "+                let s1 = get $! ( forcep patstr2 . forcep patstr1 ) exp+                putStrLn s1+                putStr "actual value                = "+                let s2 = get $! forcep patstrU exp+#if 1+                let s3 = s2+#else+                putStrLn s2+                let s3 = get $! forcep_ ( unionPats [ pat1, pat2 ] ) exp+#endif+                return $! s3+           )+           -- ErrorCall if use __ = undefined+           -- BottomedOut if use __ = throw BottomedOut+           (\e -> do let err = show (e :: ErrorCall)+--         (\e -> do let err = show (e :: BottomedOut)+                     return err)+    putStrLn s+    doit11 False t++-------------------------------------------------------------------------------++  doit12 :: Bool -> [(Int,String,[Int],[(Int,String)])] -> IO ()+--doit12 :: Bool -> [(Int,String,String,[(Int,String)])] -> IO ()+  doit12 _ [] = do+                   return ()+  doit12 b ((code,patstr1,path,isibs'):t) = do+    let expect = case code of+                  1 -> "7"+                  2 -> "Prelude.undefined"+                  3 -> "pattern-match failure"+                  4 -> "syntax error"+                  5 -> "7 (but \"# with subpattern\" warning)"+                  6 -> "7 (but \"constraint/subpattern arity mismatch\" warning)"+                  _ -> error $ "doit12: unexpected code " ++ show code+    s <- catch+           ( do+                let target = compilePat patstr1+--              let path = compilePat patstr2+                let isibs = map (\ (x,y) -> (x,compilePat y)) isibs'+                if b+                 then do+                  putStr hdline+                  putStrLn "Testing splicePats."+                  putStr hline+                 else return ()+                putStrLn $ "target       " ++ patstr1+                putStrLn $ "path         " ++ show path+--              putStrLn $ "path         " ++ patstr2+                putStrLn $ "isibs        " ++ show isibs'+                let s1 = force $ showPat $ splicePats target path isibs+--              let s1 = showPat $! splicePats target path isibs+--              let s1 = showPat $ splicePats target path isibs+                putStr "result       "+                return $! s1+           )+           -- ErrorCall if use __ = undefined+           -- BottomedOut if use __ = throw BottomedOut+           (\e -> do let err = show (e :: ErrorCall)+--         (\e -> do let err = show (e :: BottomedOut)+                     return err)+    putStrLn s+    if null t then return () else putStr hline+    doit12 False t++-------------------------------------------------------------------------------++  doit13 :: Bool -> [(Int,[String],String)] -> IO ()+  doit13 _ [] = do+                   putStr hline+                   return ()+  doit13 b ((code,patstrlst,expectstr):t) = do+    s <- catch+           ( do+                s1 <- case code of+-- Where were they done already?+-- Oh, in doit11 and doit12 above...+                       1 -> error $ hline ++ "unionPats test already done test13-1!"+--                     4 -> error $ hline ++ "unionPatsStr test already done test13-4!"+                       10 -> error $ hline ++ "splicePats test already done test13-10!"+                       11 -> error $ hline ++ "isPath test already done test13-11!"+    --  1    unionPats       :: [ Pat ] -> Pat+    --  2  * intersectPats   :: [ Pat ] -> Pat+    --  3  * subPat          :: Pat -> Pat -> Bool+--  --  4    unionPatsStr    :: [ String ] -> String+    --  5  * emptyPat        :: Pat+--  --  6  * mkPat           :: forall d. Data d => d -> Pat+--  --  7  * growPat         :: forall d. Data d => Pat -> d -> Pat+    --  8  * shrinkPat       :: Pat -> Pat+    --  9  * liftPats        :: [ Pat ] -> Pat+    -- 10    splicePats      :: Pat -> Pat -> [(Int, Pat)] -> Pat+    -- 11    isPath          :: Pat -> Bool+                       2 -> do+                               let patA = patstrlst!!0+                               let patB = patstrlst!!1+                               putStr hline+                               putStrLn "Testing      intersectPats [patA, patB]"+                               putStrLn $ "patA         " ++ patA+                               putStrLn $ "patB         " ++ patB+                               putStr $ "result       "+                               let s1 = force $ showPat $ intersectPats [compilePat patA, compilePat patB]+                               return s1+                       3 -> do+                               let patA = patstrlst!!0+                               let patB = patstrlst!!1+                               putStr hline+                               putStrLn "Testing      subPat patA patB"+                               putStrLn $ "patA         " ++ patA+                               putStrLn $ "patB         " ++ patB+                               let s1 = force $ show $ subPat (compilePat patA) (compilePat patB)+                               if s1 /= expectstr+                                then do putStrLn $ "expect       " ++ expectstr+                                        putStr $ "result       "+                                else putStr $ "as expected  "+                               return s1+                       5 -> do+                               putStr hline+                               putStrLn "Testing      emptyPat"+                               putStr $ "result       "+                               let s1 = force $ showPat $ emptyPat+                               return s1+                       6 -> do+#if 0+                               putStr hline+                               putStrLn "Testing      mkPat ([1,2,3],(False,\"foo\"))"+                               putStr $ "result       "+                               let s1 = force $ showPat $ mkPat ([1,2,3::Int],(False,"foo"))+                               return s1+#else+                               return ""+#endif+                       7 -> do+#if 0+                               let patA = patstrlst!!0+                               putStr hline+                               putStrLn "Testing      growPat patA ([1,2,3],(False,\"foo\"))"+                               putStrLn $ "patA         " ++ patA+                               putStr $ "result       "+                               let s1 = force $ showPat $ growPat (compilePat patA) ([1,2,3::Int],(False,"foo"))+                               return s1+#else+                               return ""+#endif+                       8 -> do+                               let patA = patstrlst!!0+                               putStr hline+                               putStrLn "Testing      shrinkPat patA"+                               putStrLn $ "patA         " ++ patA+                               putStr $ "result       "+                               let s1 = force $ showPat $ shrinkPat (compilePat patA)+                               return s1+                       9 -> do+                               putStr hline+                               putStrLn "Testing      liftPats patstrlst"+                               putStrLn $ "patstrs      " ++ show patstrlst+                               putStr $ "result       "+                               let s1 = force $ showPat $ liftPats $ map compilePat patstrlst+                               return s1+                       _ -> error $ "doit13: unexpected code " ++ show code+                return $! s1+           )+           -- ErrorCall if use __ = undefined+           -- BottomedOut if use __ = throw BottomedOut+           (\e -> do let err = show (e :: ErrorCall)+--         (\e -> do let err = show (e :: BottomedOut)+                     return err)+    putStrLn s+    doit13 False t++-------------------------------------------------------------------------------++  -- This is an adaptation of doit10 to user-defined datatypes,+  -- for testing GNFDataP, which is finally within reach thanks+  -- to SOP!+  doit14 :: Bool -> [(Int,String)] -> IO ()+  doit14 _ [] = do+                   putStrLn "----------------------------------------------------"+                   return ()+  doit14 b ((code,patstr):t) = do+    let expect = case code of+                  1 -> "7"+                  2 -> "Prelude.undefined"+                  3 -> "pattern-match failure"+                  4 -> "syntax error"+                  5 -> "7 (but \"# with subpattern\" warning)"+                  6 -> "7 (but \"constraint/subpattern arity mismatch\" warning)"+                  13 -> "7 (but with pattern-match failure warning)"+                  23 -> "Prelude.undefined (but with pattern-match failure warning)"+                  _ -> error $ "doit14: unexpected code " ++ show code+    s <- catch+           ( do+                let exp = (3.4, [5,__,7], __) :: (Float, [Int], Bool)+                let pat = compilePat patstr+                let get (_,xs,_) = show $ (xs!!2)+                if b+                 then do+                  putStrLn "===================================================="+                  putStrLn "exp = (3.4, [5,__,7], __) :: (Float, [Int], Bool)"+                  putStrLn "get (_,xs,_) = show $ (xs!!2)"+                  putStrLn "? = get $ forcep patstr exp"+                  putStrLn "===================================================="+                 else do+                  putStrLn "----------------------------------------------------"+                putStrLn $ "patstr                   = " ++ patstr+                if code > 4+                 then putStrLn $  "expected value           = " ++ expect+                 else return ()+--              putStrLn $ "pat = " ++ show pat+                putStrLn $ "showPat.compilePat       = " ++ showPat pat+                if code <= 4+                 then putStrLn $  "expected value           = " ++ expect+                 else return ()+                s1 <- catch+                        ( return $! force $! get $! forcep patstr exp )+                        (\e -> do let err = show (e :: ErrorCall)+--                      (\e -> do let err = show (e :: BottomedOut)+                                  return err)+                putStr "actual value             = "+                return $! s1+           )+           -- ErrorCall if use __ = undefined+           -- BottomedOut if use __ = throw BottomedOut+           (\e -> do let err = show (e :: ErrorCall)+--         (\e -> do let err = show (e :: BottomedOut)+                     return err)+    putStrLn s+    doit14 False t  ------------------------------------------------------------------------------- 
− tests/Blah98_new_grammar.hs
@@ -1,1102 +0,0 @@------------------------------------------------------------------------------------- This is a pared-down version of Blah.hs, for testing--- deepseq-bounded when built with the HASKELL98_FRAGMENT--- flag set.  See Blah.hs for comments and other "flesh".-----------------------------------------------------------------------------------{-# LANGUAGE CPP #-}-----------------------------------------------------------------------------------#define FOCUS_TEST 0-#define USE_TRACE 0-----------------------------------------------------------------------------------  module Blah98_new_grammar ( run_tests ) where-------------------------------------------------------------------------------------import Common-  import Foo--  import Control.DeepSeq.Bounded hiding ( F )--  import Data.Maybe--  import Control.Exception---import Control.Monad ( guard )-  import Control.Monad ( replicateM )-  import Control.Monad ( when )--  import Data.Typeable ( Typeable )-  import Data.Typeable ( typeOf )----import Util ( spoor )-  import Debug.Trace ( trace )-  import Control.DeepSeq--  import Data.Typeable ( Proxy(..) )--  import Data.List ( intercalate )--  import System.IO.Unsafe ( unsafePerformIO )-----------------------------------------------------------------------------------  -- For convenience in GHCi interactive sessions:-  cp = compilePat---cp = compilePat-  ip = intersectPats-  isp = subPat-----------------------------------------------------------------------------------  run_tests :: IO Int-  run_tests = do-    putStr "\n"-    -- So can notice the start when scrollback, esp. in ghci reload/reruns.---  replicateM 50 $ putStrLn "################################################################################"-    putStrLn "\nTesting.\n"--#if ! FOCUS_TEST--#if 1---  let shp s = s ++ replicate (30 - length s) ' ' ++ show (compilePat s)-    let shp s = -         unsafePerformIO $-         catch-          ( return $! force $ s ++ replicate (30 - length s) ' ' ++ show (compilePat s) )-          ( \e -> do let err = show (e :: ErrorCall)-                     return err )--    putStrLn "Pattern                       Compiles to"---  putStrLn $ shp ""  -- empty pattern syntax error-    putStrLn $ shp "*"  -- Node WW []---  putStrLn $ shp "@"  -- Node WS []  -- obsoleted (use "." w/o children)-    putStrLn $ shp "."  -- Node I []  -- no parent to absorb (should be error)-    putStrLn $ shp "!"  -- Node WS []---  putStrLn $ shp "**"  -- Node WS []  -- "disconnected pattern (not rooted)"---  putStrLn $ shp "!*"  -- Node WS []  -- "disconnected pattern (not rooted)"---  putStrLn $ shp "*!"  -- Node WS []  -- "disconnected pattern (not rooted)"-    putStrLn $ shp "()"  -- Node WR []-    putStrLn $ shp "(*)"  -- Node WR [Node WW []]-    putStrLn $ shp "(**)"  -- Node WR [Node WW [],Node WW []]-    putStrLn $ shp "(!*)"  -- Node WR [Node WS [],Node WW []]-    putStrLn $ shp "(.!)"  -- Node WR [Node I [],Node WS []]-    putStrLn $ shp "(.(.))"  -- Node WR [Node I []] with warning-    putStrLn $ shp "((.))"  -- Node WR [Node WR [Node I []]]-    putStrLn $ shp "(*.*.*.**.*.*)"  -- looks fine-    putStrLn $ shp "(*.(*.(*.)*)*(.*).*)"  -- warning about *{...}-    putStrLn $ shp "(*.(*.(*.)*)*.*)"---  putStrLn $ shp "(*.(*.(*.)*)(*)(.*).*)"  -- }{ syntax error--- [old comment for that last:] NodeM WR [NodeM WW [],Nil,NodeM WR [NodeM WW [],Nil,NodeM WR [NodeM WW [],Nil],NodeM WW [],NodeM WW [],Nil,NodeM WW []],Nil,NodeM WW []] -- was wrong but is fixed I think-    putStrLn $ shp "(!*(*23*))"-#endif--#if 1-    let test_patterns10 = [-           (4,  "")  -- syntax error-         , (4,  "!..")  -- syntax error (disconnected pattern)-         , (1,  "(!..)")  -- fail-         , (5,  "(().().())")-         , (2,  "*")-         , (2,  "(***)")-         , (1,  "(...)")-         , (1,  "(*..)")-         , (2,  "(**.)")-         , (2,  "(..*)")--           -- Remember, [a] is a recursive binary ctor app!...-           -- The next four tests give instance errors for [a], but if-           -- testing expTG_* (GNFDataP/grnfp) then it's no longer a list...-         , (13, "(!(*.*).)")-         , (13, "(!(*...).)")-         , (13, "(!(*....).)")-         , (23, "(!(*....)!)")--         , (2,  "(!(*.)*)")-         , (1,  "(!(*.).)")-         , (1,  "(!(*(.*)).)")-         , (2,  "(!(*(*.)).)")-         , (13, "(!((!(.*))).)")  -- See above comment about [a] instance-         , (2,  "(.(!(!(.*))).)")--           -- (See Book, p.84.)-         , (1,  "(!(!(.(!!))).)")-         , (1,  "(!(!(.*)).)")-         , (1,  "(*(*(.*)).)")-         , (2,  "(..*)")-         , (2,  "(*.*)")-         , (1,  ":Tuple3:!(*(*(.*)).)")  -- oops...-         , (1,  ":(,,):!(*(*(.*)).)")-         , (2,  ":(,,):!(*(*(!*)).)")-         , (1,  ":Bool:!(***)")  -- XXX makes no sense (but works) -- oh well;-                                 -- this is an important point to note in-                                 -- docs/blog also...-         , (1,  ":Bool:*")-         , (2,  ":(,,):*")-         , (2,  "(*.!)")-         , (2,  "(*.:Bool:!)")  -- expect parse error-         , (1,  "(*.:Int:!)")  -- still need to implement . when not in type-         , (1,  "(*.:(,):!)")  -- still need to implement . when not in type-         , (1,  "(*.:Int:!)")  -- still need to implement . when not in type-         , (1,  "(*.:Int':!)")  -- still need to implement . when not in type-         , (1,  "(*.:Bool:.)")-         , (2,  "(*.:Int:.)")-         , (2,  "(*.:(,):.)")-         , (1,  "(*.:Bool:.)")-         , (2,  "(*.:Int:.)")-         , (2,  "(*.:(,):.)")-         , (1,  "(**2.)")-         , (2,  "(**3.)")-         , (1,  "(*:G2:.().)")-         , (1,  "(*:Int:.().)")-         ]-    doit14 True test_patterns10---  doit10 True test_patterns10-#endif--#endif--------------------------------------------------- Later: Oh! Don't be silly -- it's all compile-time, and the--- size or shape of the list is irrelevant -- which rules--- will fire depends on THIS FILE'S SOURCE CODE (not it's--- data, including static values)!--- XXX Even with empty list, the same rule firings occur!...--- If comment out this block however, the rules do not fire!-#if 1-    -- Testing composition and union:-    let test_patterns11 = [-           (1, "!", "!")-         , (2, "!", "*")-         , (2, "*", "!")-         , (2, "*", "*")-         , (2, "(!!!)", "(*!!)")-         , (2, "(*!!)", "(!!*)")-         , (2, "(!*.)", "(!.!)")-         ]-    doit11 True test_patterns11-#endif--#if 1-    -- Testing splicePats-    let test_patterns12 = [-#if 1-           (1, "!", [], [(0,"*")])-         , (1, "()", [], [(0,"*")])-         , (1, "!", [0], [(0,"*")])-         , (1, "(!!)", [], [(0,"*")])-         , (1, "(!!)", [0], [(0,"*")])-         , (1, "(!!)", [2], [(0,"*")])-         , (1, "(!!)", [], [(0,"*"),(0,".")])-         , (1, "(!!)", [], [(0,"*"),(1,".")])-         , (1, "(!!)", [], [(1,"."),(0,"*")])-         , (1, "(!!)", [], [(0,"*"),(2,".")])-         , (1, "(!!)", [], [(2,"*"),(2,"."),(2,".")])-         , (1, "(!!)", [], [(-1,"*")])-         , (1, "(!!)", [], [(0,"*")])-         , (1, "(!!)", [], [(1,"*")])-         , (1, "(!!)", [], [(2,"*")])-         , (1, "(!!)", [], [(3,"*")])-         , (1, "(!(!!)!)", [1], [(0,"*")])-         , (1, "(!(!!)!)", [1], [(0,"*3"),(1,"."),(2,"*")])-         , (1, "(!(!!)!)", [1,0], [(0,"*"),(0,".")])-         , (1, "((!!!)(()!)!)", [1], [(0,"*"),(0,".")])-         , (1, "((!!!)(()!)!)", [1,0], [(0,"*"),(0,".")])-         , (1, "((...)(().).)", [1,0], [(0,"*"),(0,".")])-         , (1, "(:(,,):!(...)(().).)", [1,0], [(0,"*"),(0,".")])-#else-           (1, "!", "()", [(0,"*")])-         , (1, "()", "()", [(0,"*")])-         , (1, "!", "(())", [(0,"*")])  -- added later, did uncover a bug! (irrefutable pattern failure)-         , (1, "(!!)", "()", [(0,"*")])-         , (1, "(!!)", "(())", [(0,"*")])-         , (1, "(!!)", "(!!())", [(0,"*")])-         , (1, "(!!)", "()", [(0,"*"),(0,".")])-         , (1, "(!!)", "()", [(0,"*"),(1,".")])-         , (1, "(!!)", "()", [(1,"."),(0,"*")])-         , (1, "(!!)", "()", [(0,"*"),(2,".")])-         , (1, "(!!)", "()", [(2,"*"),(2,"."),(2,".")])-         , (1, "(!!)", "()", [(-1,"*")])-         , (1, "(!!)", "()", [(0,"*")])-         , (1, "(!!)", "()", [(1,"*")])-         , (1, "(!!)", "()", [(2,"*")])-         , (1, "(!!)", "()", [(3,"*")])-         , (1, "(!(!!)!)", "(!()!)", [(0,"*")])-         , (1, "(!(!!)!)", "(!()!)", [(0,"*3"),(1,"."),(2,"*")])-         , (1, "(!(!!)!)", "(!(()!)!)", [(0,"*"),(0,".")])-         , (1, "(!(!!)!)", "(!(()))", [(0,"*"),(0,".")])-         , (1, "((!!!)(()!)!)", "(!())", [(0,"*"),(0,".")])-         , (1, "((!!!)(()!)!)", "(!(()))", [(0,"*"),(0,".")])-         , (1, "((...)(().).)", "(!(()))", [(0,"*"),(0,".")])-         , (1, "(:(,,):!(...)(().).)", "(!(()))", [(0,"*"),(0,".")])-#endif-         ]-    doit12 True test_patterns12-#endif--#if ! FOCUS_TEST--#if 1-    -- Testing anything else we can with a single function!-    -- (Getting sick of this cloning.)-    -- Functions are listed in (current) export order.-    -- Things still needing testing are >'d.-    -- Things tested but failing some tests have a *.-    -- -    -- XXX Wow does this ever look cleaner with "Pat" instead of "Pattern"!...-    -- Fortunately splicePats is already tested separately; the rest-    -- we need to test deal only in Pat args (or list of same), so-    -- we can pass a couple [Pat] to test13 along with an Int code-    -- to control delegation.-    --  1    unionPats       :: [ Pat ] -> Pat-    --  2    intersectPats   :: [ Pat ] -> Pat-    --  3    subPat          :: Pat -> Pat -> Bool---  --  4    unionPatsStr    :: [ String ] -> String-    --  5    emptyPat        :: Pat---  --  6    mkPat           :: forall d. Data d => d -> Pat---  --  7    growPat         :: forall d. Data d => Pat -> d -> Pat-    --  8    shrinkPat       :: Pat -> Pat-    --  9    liftPats        :: [ Pat ] -> Pat-    -- 10    splicePats      :: Pat -> Pat -> [(Int, Pat)] -> Pat-    -- 11    isPath          :: Pat -> Bool-    let test_patterns13 = [-           ( 1, ["(!!!)", "(!.)"], "")-         , ( 2, ["(!!!)", "(!.)"], "")-         , ( 3, ["!", "!"], "True")-         , ( 3, [".", "."], "True")-         , ( 3, ["*", "*"], "True")-         , ( 3, ["!", "()"], "True")-         , ( 3, ["()", "!"], "False")-         , ( 3, ["()", "(!)"], "False")-         , ( 3, ["(!)", "(!)"], "True")-         , ( 3, ["(!)", "(!!)"], "False")-         , ( 3, ["(!)", "((!))"], "True")-         , ( 3, ["(!!)", "(!.)"], "False")-         , ( 3, ["(!.)", "(!!)"], "True")-         , ( 3, ["(!!)", "(!!!)"], "False")-         , ( 3, ["()", "(!!!)"], "False")-         , ( 3, ["!", "(*!.)"], "True")-         , ( 3, [".", "(*!.)"], "True")-         , ( 3, ["*", "(*!.)"], "False")-         , ( 3, ["*", "(*)"], "False")-         , ( 3, ["*", "(**)"], "False")-         , ( 4, ["(!!!)", "(!.)"], "")-         , ( 5, ["(!!!)", "(!.)"], "")-#if 0-         , ( 6, ["(!!!)", "(!.)"], "")-         -- matching against val = ([1,2,3::Int],(False,"foo"))-         -- mkPat val = "((!(!(!!)))(!(!(!(!!)))))"-#endif-#if 0-         , ( 7, ["((!(!!))(!(!!)))"], "")-         , ( 7, ["((!(!(!!)))(!(!(!!))))"], "")-         , ( 7, ["((!(!(!!)))(!(!(!(!!)))))"], "")-#endif-         , ( 8, ["((!(!(!!)))(!(!(!(!!)))))"], "")-         , ( 8, ["((!(!(!!)))(!(!(!!))))"], "")-         , ( 8, ["((!(!!))(!(!!)))"], "")-         , ( 8, ["((.(!!))(.(*3!)))"], "")-         , ( 8, ["((.!)(.!))"], "")-         , ( 8, ["(!!)"], "")-         , ( 8, ["!"], "")-         , ( 9, ["(!!!)", "(!.)"], "")-         , (10, ["(!!!)", "(!.)"], "")-         , (11, ["(!!!)", "(!.)"], "")-         ]-    putStrLn "===================================================="-    putStrLn "Testing miscellaneous NFDataP functions..."-    doit13 True test_patterns13-#endif--#if 1-    -- Testing fusion-    putStrLn "\nTesting fusion\n-fenable-rewrite-rules -O -ddump-rules -ddump-simpl-stats -ddump-rule-firings\n"-    let exp12 = (3.4, [5,__,7], __) :: (Float, [Int], Bool)-    let get12 (_,xs,_) = (xs!!2)-    putStrLn $ show $ get12 $ ( forcep ":Bool:*" . forcep ":Int:*" ) exp12-    putStrLn $ show $ get12 $ ( forcep ":Bool:*" . forcep_ (compilePat ":Int:*") ) exp12-    putStrLn $ show $ get12 $ ( forcep_ (compilePat ":Bool:*") . forcep ":Int:*" ) exp12-    putStrLn $ show $ get12 $ ( forcep_ (compilePat ":Bool:*") . forcep_ (compilePat ":Int:*") ) exp12-#endif--#if 1-    putStrLn $ intercalate "\n"-     [ ""-     , "expN_1 = [__] :: [Int]"-     , "expN_2 = [0,1,__,3] :: [Int]"-     , "expN_3 = (3.4, [5,__,7], True) :: (Float, [Int], Bool)"-     , "expN_4 = (3.4, [5,__,7], __) :: (Float, [Int], Bool)"-     , ""-     , "getN_1 xs = show $ ()"---   , "getN_1 xs = show $ head xs"---   , "getN_2 xs = show $ (xs!!1)"-     , "getN_2 xs = show $ (xs!!3)"-     , "getN_3 (_,xs,_) = show $ (xs!!2)"-     ]-    doit5 1 0 1 "" >>= putStrLn-    doit6 1 0 1 "" >>= putStrLn-    doit7 1 0 1 "" >>= putStrLn-    doit8 1 0 1 "" >>= putStrLn-#if 0-    doit9 >>= putStrLn  -- XXX broken (whatever it is)-#endif-#endif--#if 0-    s4 <- doit4 1 0 1 ""-    putStrLn s4-#endif--#if 0-    putStrLn $ ""-           ++ "expBase1 = ([True,False],3,Just \"fox\")         :: ([Bool],Int,Maybe String)\n"-           ++ "expBase2 = ([True,False],__,Just \"fox\")        :: ([Bool],Int,Maybe String)\n"-           ++ "expBase3 = ([True,__],3,Just \"fox\")            :: ([Bool],Int,Maybe String)\n"-           ++ "expBase4 = ([True,__],3,Just __)               :: ([Bool],Int,Maybe String)\n"-           ++ "expBase5 = ([True,False],3,Just ['f',__,'x'])  :: ([Bool],Int,Maybe String)\n"-           ++ "expBase6 = ([True,False],3,Just __)            :: ([Bool],Int,Maybe String)\n"-           ++ "get1 ((x:_),_,_) = x           -- True\n"-           ++ "get2 (_,x,_) = x               -- 3\n"-           ++ "get3 (_,_,x) = fromJust x      -- \"fox\"\n"-           ++ "get4 (_,_,Just (x:_)) = x      -- 'f'\n"-    s1 <- doit1 1 1 1 ""-    putStrLn s1-#endif--#endif--    return 0-----------------------------------------------------------------------------------  hline :: String-  hline = "----------------------------------------------------\n"-  hdline :: String-  hdline = "====================================================\n"-----------------------------------------------------------------------------------  doit1 :: Int -> Int -> Int -> String -> IO String-  doit1 i j k acc-   -- this glitch (the exception that seemingly escapes my catch)-   -- happens just for these combos (and for all j):--- | i == 3 && k == 4  = doit1 (1+i) j k acc  -- trying to avoid a glitch...--- | i == 3 && k == 5  = doit1 (1+i) j k acc  -- trying to avoid a glitch...--- | i == 3 && j < 4 && k == 5  = doit1 (1+i) j k acc  -- trying to avoid a glitch...-   | k == 7  = return acc-   | j == 6  = doit1 1 1 (1+k) acc-   | i == 5  = doit1 1 (1+j) k acc-   | otherwise  = do-      fexp <- catch-               -- The semantics of the !'s here are not what they were,-               -- since forcing in some places. [?] But at least the-               -- first one seems definitely still needed...-               -- LATER: The second one is also needed, finally seen!-               -- (It is needed for a version of getE _ = "getee", only.)-               -- XXX I'm just not sure whether the second ! is better-               -- to leave in or leave out...-               ( return $! get $! forcen dep exp )-               (\e -> do let err = show (e :: ErrorCall)---             (\e -> do let err = show (e :: BottomedOut)-                         return err)---    doit1 (1+i) j k $! force $ acc-      doit1 (1+i) j k $! acc---    doit1 (1+i) j k $ acc-        ++ "( get" ++ show i ++ " $ forcen " ++ show dep ++ " expBase" ++ show k ++ " )  "-        ++ fexp ++ "\n"-   where-    exp = case k of-            1 -> expBase1-            2 -> expBase2-            3 -> expBase3-            4 -> expBase4-            5 -> expBase5-            6 -> expBase6-    get = case i of-           1 -> get1-           2 -> get2---         3 -> unsafePerformIO . get3  -- yeesh!...---         3 -> get3-           3 -> get3 (i,j,k)-           4 -> get4-    dep = j--#if 0-  -- XXX All this fuss to deal with the case that the-  -- entire argument m is undefined (or whatever is going-  -- for "undefined" at the moment...) -- but, none of-  -- the expBase[1-5] have this! ch.-  myFromJust :: Maybe a -> IO (Either () a)-  myFromJust m = do-                    putStrLn "Boo!"-                    catch-                      (myFromJust' m)-                      (\e -> do putStrLn $! show (e::BottomedOut)-                                putStrLn "HERE!"-                                return $! Left ())-  myFromJust' :: Maybe a -> IO (Either () a)-  myFromJust' Nothing = do---                         throw BottomedOut-                           return $! Left ()-  myFromJust' (Just x) = return $! Right x---myFromJust _ = throw BottomedOut-#endif------------------------------------#if 0-  doit2 :: Int -> Int -> Int -> String -> IO String-  doit2 i j k acc--- | k == 2  = {- trace (show (i,j,k)) $ -} return acc--- | k == 7  = return acc-   | k == 27  = return acc--- | k == 21  = return acc--- | k == 5  = return acc--- | j == 15  = doit2 1 0 (1+k) acc-   | j == 11  = {- trace (show (i,j,k)) $ -} doit2 1 0 (1+k) acc--- | j == 8  = {- trace (show (i,j,k)) $ -} doit2 1 0 (1+k) acc--- | j == 3  = {- trace (show (i,j,k)) $ -} doit2 1 0 (1+k) acc-#if USE_TRACE-   | i == 2  = trace ("End of " ++ show (i,j',k')) $ doit2 1 (1+j) k acc--- | i == 3  = trace ("End of " ++ show (i,j',k')) $ doit2 1 (1+j) k acc-#else-   | i == 2  = doit2 1 (1+j) k acc--- | i == 3  = doit2 1 (1+j) k acc-#endif-   | otherwise  = do-      fexp <- catch-               ( return $! get $! forcen dep exp )---             ( return $! get $! forcen dep exp )-               -- ErrorCall if use __ = undefined-               -- BottomedOut if use __ = throw BottomedOut-               (\e -> do let err = show (e :: ErrorCall)---             (\e -> do let err = show (e :: BottomedOut)-                         return err)-      doit2 (1+i) j k $! acc-        ++ "( getB_" ++ show i ++ " $ forcen " ++ show dep ++ (if dep < 10 then " " else "") ++ " expTB_" ++ show (k'-6) ++ " )  "---      ++ "( getB_" ++ show i ++ " $ forcen " ++ show dep ++ (if dep < 10 then " " else "") ++ " expBase" ++ show k' ++ " )  "-        ++ fexp ++ "\n"-   where-    exp = case k' of-            7 -> expBase7-            8 -> expBase8-            9 -> expBase9-            10 -> expBase10-            11 -> expBase11-            12 -> expBase12-            13 -> expBase13-            14 -> expBase14-            15 -> expBase15-            16 -> expBase16-            17 -> expBase17-            18 -> expBase18-            19 -> expBase19-            20 -> expBase20-            21 -> expBase20  -- fudge it!!-            22 -> expBase22-            23 -> expBase23-            24 -> expBase24-            25 -> expBase25-            26 -> expBase26-            27 -> expBase27-            28 -> expBase28-            29 -> expBase29-            30 -> expBase30-            31 -> expBase31-            32 -> expBase32-    get = case i of-           1 -> if k' >= 27 then getB_3 else getB_1-           2 -> getB_2-    dep = j'-    j' = j---  j' = j+11---  k' = k+26-    k' = k+6-#endif--#if 0-  doit3 :: Int -> Int -> Int -> String -> IO String-  doit3 i j k acc-   | k == 2  = return acc-   | j == 8  = {- trace (show (i,j,k)) $ -} doit3 1 1 (1+k) acc-#if USE_TRACE-   | i == 2  = trace ("End of " ++ show (i,j',k')) $ doit3 1 (1+j) k acc-#else-   | i == 2  = doit3 1 (1+j) k acc-#endif-   | otherwise  = do-      fexp <- catch-               ( return $! get $! forcen dep exp )-               -- ErrorCall if use __ = undefined-               -- BottomedOut if use __ = throw BottomedOut-               (\e -> do let err = show (e :: ErrorCall)---             (\e -> do let err = show (e :: BottomedOut)-                         return err)-      doit3 (1+i) j k $! acc-        ++ "( getB_" ++ show i ++ " $ forcen " ++ show dep ++ " expBase" ++ show k' ++ " )  "-        ++ fexp ++ "\n"-   where-    exp = case k' of-            21 -> expBase21-    get = case i of-           1 -> getA-    dep = j'-    i' = i-    j' = j-    k' = k+20-#endif--#if 0-  doit4 :: Int -> Int -> Int -> String -> IO String-  doit4 i j k acc--- | k == 2  = return acc-   | k == 4  = return acc-   | j == 8  = {- trace (show (i,j,k)) $ -} doit4 1 0 (1+k) acc-#if USE_TRACE-   | i == 2  = trace ("End of " ++ show (i,j',k')) $ doit4 1 (1+j) k acc-#else-   | i == 2  = doit4 1 (1+j) k acc-#endif-   | otherwise  = do-      fexp <- catch-               ( return $! get $! forcen dep exp )-               -- ErrorCall if use __ = undefined-               -- BottomedOut if use __ = throw BottomedOut-               (\e -> do let err = show (e :: ErrorCall)---             (\e -> do let err = show (e :: BottomedOut)-                         return err)-      doit4 (1+i) j k $! acc-        ++ "( getE $ forcen " ++ show dep ++ " expTE_" ++ show k' ++ " )  "-        ++ fexp ++ "\n"-   where-    exp = case k' of-            1 -> expTE_1-            2 -> expTE_2-            3 -> expTE_3-    get = case i of-           1 -> getE-    dep = j'-    i' = i-    j' = j-    k' = k-#endif-----------------------------------------------------------------------------------  doit5 :: Int -> Int -> Int -> String -> IO String-  doit5 i j k acc-   | k == 2  = return acc-   | j == 5  = {- trace (show (i,j,k)) $ -} doit5 1 0 (1+k) acc-#if USE_TRACE-   | i == 2  = trace ("End of " ++ show (i,j',k')) $ doit5 1 (1+j) k acc-#else-   | i == 2  = doit5 1 (1+j) k acc-#endif-   | otherwise  = do-      fexp <- catch-               ( return $! get $! forcen dep exp )-               -- ErrorCall if use __ = undefined-               -- BottomedOut if use __ = throw BottomedOut-               (\e -> do let err = show (e :: ErrorCall)---             (\e -> do let err = show (e :: BottomedOut)-                         return err)-      doit5 (1+i) j k $! acc-        ++ "forcen " ++ show dep ++ " expN_" ++ show k' ++ " `seq` ()  =  "-        ++ fexp ++ "\n"-   where-    exp = case k' of-            1 -> expN_1-    get = case i of-           1 -> getN_1-    dep = j'-    i' = i-    j' = j-    k' = k-----------------------------------------------------------------------------------  doit6 :: Int -> Int -> Int -> String -> IO String-  doit6 i j k acc-   | k == 2  = return acc-   | j == 5  = {- trace (show (i,j,k)) $ -} doit6 1 0 (1+k) acc-#if USE_TRACE-   | i == 2  = trace ("End of " ++ show (i',j',k')) $ doit6 1 (1+j) k acc-#else-   | i == 2  = doit6 1 (1+j) k acc-#endif-   | otherwise  = do-      fexp <- catch-               ( return $! get $! forcen dep exp )-               -- ErrorCall if use __ = undefined-               -- BottomedOut if use __ = throw BottomedOut-               (\e -> do let err = show (e :: ErrorCall)---             (\e -> do let err = show (e :: BottomedOut)-                         return err)-      doit6 (1+i) j k $! acc-        ++ "getN_" ++ show i' ++" $ forcen " ++ show dep ++ " expN_" ++ show k' ++ "  =  "-        ++ fexp ++ "\n"-   where-    exp = case k' of-            _ -> expN_2-    get = case i of-           _ -> getN_2-    dep = j'-    i' = i+1-    j' = j-    k' = k+1-----------------------------------------------------------------------------------  doit7 :: Int -> Int -> Int -> String -> IO String-  doit7 i j k acc-   | k == 2  = return acc-   | j == 5  = {- trace (show (i,j,k)) $ -} doit7 1 0 (1+k) acc-#if USE_TRACE-   | i == 2  = trace ("End of " ++ show (i',j',k')) $ doit7 1 (1+j) k acc-#else-   | i == 2  = doit7 1 (1+j) k acc-#endif-   | otherwise  = do-      fexp <- catch-               ( return $! get $! forcen dep exp )-               -- ErrorCall if use __ = undefined-               -- BottomedOut if use __ = throw BottomedOut-               (\e -> do let err = show (e :: ErrorCall)---             (\e -> do let err = show (e :: BottomedOut)-                         return err)-      doit7 (1+i) j k $! acc-        ++ "getN_" ++ show i' ++" $ forcen " ++ show dep ++ " expN_" ++ show k' ++ "  =  "-        ++ fexp ++ "\n"-   where-    exp = case k' of-            _ -> expN_3-    get = case i of-           _ -> getN_3-    dep = j'-    i' = i+2-    j' = j-    k' = k+2-----------------------------------------------------------------------------------  doit8 :: Int -> Int -> Int -> String -> IO String-  doit8 i j k acc-   | k == 2  = return acc-   | j == 5  = {- trace (show (i,j,k)) $ -} doit8 1 0 (1+k) acc-#if USE_TRACE-   | i == 2  = trace ("End of " ++ show (i',j',k')) $ doit8 1 (1+j) k acc-#else-   | i == 2  = doit8 1 (1+j) k acc-#endif-   | otherwise  = do-      fexp <- catch-               ( return $! get $! forcen dep exp )-               -- ErrorCall if use __ = undefined-               -- BottomedOut if use __ = throw BottomedOut-               (\e -> do let err = show (e :: ErrorCall)---             (\e -> do let err = show (e :: BottomedOut)-                         return err)-      doit8 (1+i) j k $! acc-        ++ "getN_" ++ show i' ++" $ forcen " ++ show dep ++ " expN_" ++ show k' ++ "  =  "-        ++ fexp ++ "\n"-   where-    exp = case k' of-            _ -> expN_4-    get = case i of-           _ -> getN_3-    dep = j'-    i' = i+2-    j' = j-    k' = k+3-----------------------------------------------------------------------------------#if 0--#if 0-  expP_1 = (3.4, [5,__,7], __) :: (Float, [Int], Bool)-  patP_1 = Node (TR [typeOf ((__,__,__)::(Float, [Int], Bool))])-             [ Node (TR [typeOf (__::Bool)]) []---           [ Node (TR [typeOf (__::Float)]) []---           [ Node (NTR [typeOf (__::Bool)]) []---           [ Node (NTR [typeOf (__::Float)]) []---           , Node WS []-             , Node (TW [typeOf ([__]::[Int])]) []---           , Node (TR [typeOf ([__]::[Int])]) []---           , Node (TR [typeOf ([__]::[Int])]) [ Node WS [], Node WS [] ]  -- why not?-             , Node WW []---           , Node I []-             ]-  getP_1 (_,xs,_) = show $ (xs!!2)-#endif--  doit9 :: IO String-  doit9 = do-#if 0-    putStrLn $ intercalate "\n"-     [ ""-     , "expP_1 = (3.4, [5,__,7], __) :: (Float, [Int], Bool)"-     , "patP_1 = Node (T [typeOf ((__,__,__)::(Float, [Int], Bool))])"-     , "           [ Node W []"-     , "           , Node (T [typeOf ([__]::[Int])]) []"-     , "           , Node I []"-     , "           ]"-     , "getP_1 (_,xs,_) = show $ (xs!!2)"-     ]-    putStrLn "getP_1 $ forcep patP_1 expP_1"-#endif-    s <- catch-             ( return $! getP_1 $! forcep patP_1 expP_1 )---           ( return $! getP_2 $! forcep patP_2 expP_2 )---           ( return $! getP_3 $! forcep patP_3 expP_3 )-             -- ErrorCall if use __ = undefined-             -- BottomedOut if use __ = throw BottomedOut-             (\e -> do let err = show (e :: ErrorCall)---           (\e -> do let err = show (e :: BottomedOut)-                       return err)-    return s--#endif-----------------------------------------------------------------------------------  doit10 :: Bool -> [(Int,String)] -> IO ()-  doit10 _ [] = do-                   putStrLn "----------------------------------------------------"-                   return ()-  doit10 b ((code,patstr):t) = do-    let expect = case code of-                  1 -> "7"-                  2 -> "Prelude.undefined"-                  3 -> "pattern-match failure"-                  4 -> "syntax error"-                  5 -> "7 (but \"# with subpattern\" warning)"-                  6 -> "7 (but \"constraint/subpattern arity mismatch\" warning)"-                  13 -> "7 (but with pattern-match failure warning)"-                  23 -> "Prelude.undefined (but with pattern-match failure warning)"-                  _ -> error $ "doit10: unexpected code " ++ show code-    s <- catch-           ( do-                let exp = (3.4, [5,__,7], __) :: (Float, [Int], Bool)-                let pat = compilePat patstr-                let get (_,xs,_) = show $ (xs!!2)-                if b-                 then do-                  putStrLn "===================================================="-                  putStrLn "exp = (3.4, [5,__,7], __) :: (Float, [Int], Bool)"-                  putStrLn "get (_,xs,_) = show $ (xs!!2)"-                  putStrLn "? = get $ forcep patstr exp"-                  putStrLn "===================================================="-                 else do-                  putStrLn "----------------------------------------------------"-                putStrLn $ "patstr                   = " ++ patstr-                if code > 4-                 then putStrLn $  "expected value           = " ++ expect-                 else return ()---              putStrLn $ "pat = " ++ show pat-                putStrLn $ "showPat.compilePat       = " ++ showPat pat-                if code <= 4-                 then putStrLn $  "expected value           = " ++ expect-                 else return ()-                s1 <- catch-                        ( return $! force $! get $! forcep patstr exp )-                        (\e -> do let err = show (e :: ErrorCall)---                      (\e -> do let err = show (e :: BottomedOut)-                                  return err)-                putStr "actual value             = "-                return $! s1-           )-           -- ErrorCall if use __ = undefined-           -- BottomedOut if use __ = throw BottomedOut-           (\e -> do let err = show (e :: ErrorCall)---         (\e -> do let err = show (e :: BottomedOut)-                     return err)-    putStrLn s-    doit10 False t-----------------------------------------------------------------------------------  doit11 :: Bool -> [(Int,String,String)] -> IO ()-  doit11 _ [] = do-                   putStrLn "----------------------------------------------------"-                   return ()-  doit11 b ((code,patstr1,patstr2):t) = do-    let expect = case code of-                  1 -> "7"-                  2 -> "Prelude.undefined"-                  3 -> "pattern-match failure"-                  4 -> "syntax error"-                  5 -> "7 (but \"# with subpattern\" warning)"-                  6 -> "7 (but \"constraint/subpattern arity mismatch\" warning)"-                  _ -> error $ "doit11: unexpected code " ++ show code-    s <- catch-           ( do-                let exp = (3.4, [5,__,7], __) :: (Float, [Int], Bool)-                let patstrU = showPat $ unionPats [compilePat patstr1, compilePat patstr2]-                let pat1 = compilePat patstr1-                let pat2 = compilePat patstr2-                let patU = unionPats [pat1,pat2]-                let get (_,xs,_) = show $ (xs!!2)-                if b-                 then do-                  putStrLn "===================================================="-                  putStrLn "exp = (3.4, [5,__,7], __) :: (Float, [Int], Bool)"-                  putStrLn "get (_,xs,_) = show $ (xs!!2)"-                  putStrLn "? = get $ ( forcep patstr2 . forcep patstr1 ) exp"---                putStrLn "? = get $ ( forcep ( unionPatsStr [ patstr1, patstr2 ] ) ) exp"-                  putStrLn "? = get $! ( forcep_ ( unionPats [ pat1, pat2 ] ) ) exp"-                  putStrLn "(Results were more interesting with a previous semantics...)."-                  putStrLn "===================================================="-                 else do-                  putStrLn "----------------------------------------------------"-                putStrLn $ "patstr1                     = " ++ patstr1-                putStrLn $ "patstr2                     = " ++ patstr2-                putStrLn $ "patstrU                     = " ++ patstrU-                if code > 4-                 then putStrLn $  "expected value              = " ++ expect-                 else return ()---              putStrLn $ "pat = " ++ show pat-                putStrLn $ "showPat.compilePat patstr1  = " ++ showPat pat1-                putStrLn $ "showPat.compilePat patstr2  = " ++ showPat pat2-                putStrLn $ "showPat.compilePat patstrU  = " ++ showPat patU-                if code <= 4-                 then putStrLn $  "expected value              = " ++ expect-                 else return ()-                putStr "actual value                = "-                let s1 = get $! ( forcep patstr2 . forcep patstr1 ) exp-                putStrLn s1-                putStr "actual value                = "-                let s2 = get $! forcep patstrU exp-#if 1-                let s3 = s2-#else-                putStrLn s2-                let s3 = get $! forcep_ ( unionPats [ pat1, pat2 ] ) exp-#endif-                return $! s3-           )-           -- ErrorCall if use __ = undefined-           -- BottomedOut if use __ = throw BottomedOut-           (\e -> do let err = show (e :: ErrorCall)---         (\e -> do let err = show (e :: BottomedOut)-                     return err)-    putStrLn s-    doit11 False t-----------------------------------------------------------------------------------  doit12 :: Bool -> [(Int,String,[Int],[(Int,String)])] -> IO ()---doit12 :: Bool -> [(Int,String,String,[(Int,String)])] -> IO ()-  doit12 _ [] = do-                   return ()-  doit12 b ((code,patstr1,path,isibs'):t) = do-    let expect = case code of-                  1 -> "7"-                  2 -> "Prelude.undefined"-                  3 -> "pattern-match failure"-                  4 -> "syntax error"-                  5 -> "7 (but \"# with subpattern\" warning)"-                  6 -> "7 (but \"constraint/subpattern arity mismatch\" warning)"-                  _ -> error $ "doit12: unexpected code " ++ show code-    s <- catch-           ( do-                let target = compilePat patstr1---              let path = compilePat patstr2-                let isibs = map (\ (x,y) -> (x,compilePat y)) isibs'-                if b-                 then do-                  putStr hdline-                  putStrLn "Testing splicePats."-                  putStr hline-                 else return ()-                putStrLn $ "target       " ++ patstr1-                putStrLn $ "path         " ++ show path---              putStrLn $ "path         " ++ patstr2-                putStrLn $ "isibs        " ++ show isibs'-                let s1 = force $ showPat $ splicePats target path isibs---              let s1 = showPat $! splicePats target path isibs---              let s1 = showPat $ splicePats target path isibs-                putStr "result       "-                return $! s1-           )-           -- ErrorCall if use __ = undefined-           -- BottomedOut if use __ = throw BottomedOut-           (\e -> do let err = show (e :: ErrorCall)---         (\e -> do let err = show (e :: BottomedOut)-                     return err)-    putStrLn s-    if null t then return () else putStr hline-    doit12 False t-----------------------------------------------------------------------------------  doit13 :: Bool -> [(Int,[String],String)] -> IO ()-  doit13 _ [] = do-                   putStr hline-                   return ()-  doit13 b ((code,patstrlst,expectstr):t) = do-    s <- catch-           ( do-                s1 <- case code of--- Where were they done already?--- Oh, in doit11 and doit12 above...-                       1 -> error $ hline ++ "unionPats test already done test13-1!"---                     4 -> error $ hline ++ "unionPatsStr test already done test13-4!"-                       10 -> error $ hline ++ "splicePats test already done test13-10!"-                       11 -> error $ hline ++ "isPath test already done test13-11!"-    --  1    unionPats       :: [ Pat ] -> Pat-    --  2  * intersectPats   :: [ Pat ] -> Pat-    --  3  * subPat          :: Pat -> Pat -> Bool---  --  4    unionPatsStr    :: [ String ] -> String-    --  5  * emptyPat        :: Pat---  --  6  * mkPat           :: forall d. Data d => d -> Pat---  --  7  * growPat         :: forall d. Data d => Pat -> d -> Pat-    --  8  * shrinkPat       :: Pat -> Pat-    --  9  * liftPats        :: [ Pat ] -> Pat-    -- 10    splicePats      :: Pat -> Pat -> [(Int, Pat)] -> Pat-    -- 11    isPath          :: Pat -> Bool-                       2 -> do-                               let patA = patstrlst!!0-                               let patB = patstrlst!!1-                               putStr hline-                               putStrLn "Testing      intersectPats [patA, patB]"-                               putStrLn $ "patA         " ++ patA-                               putStrLn $ "patB         " ++ patB-                               putStr $ "result       "-                               let s1 = force $ showPat $ intersectPats [compilePat patA, compilePat patB]-                               return s1-                       3 -> do-                               let patA = patstrlst!!0-                               let patB = patstrlst!!1-                               putStr hline-                               putStrLn "Testing      subPat patA patB"-                               putStrLn $ "patA         " ++ patA-                               putStrLn $ "patB         " ++ patB-                               let s1 = force $ show $ subPat (compilePat patA) (compilePat patB)-                               if s1 /= expectstr-                                then do putStrLn $ "expect       " ++ expectstr-                                        putStr $ "result       "-                                else putStr $ "as expected  "-                               return s1-                       5 -> do-                               putStr hline-                               putStrLn "Testing      emptyPat"-                               putStr $ "result       "-                               let s1 = force $ showPat $ emptyPat-                               return s1-                       6 -> do-#if 0-                               putStr hline-                               putStrLn "Testing      mkPat ([1,2,3],(False,\"foo\"))"-                               putStr $ "result       "-                               let s1 = force $ showPat $ mkPat ([1,2,3::Int],(False,"foo"))-                               return s1-#else-                               return ""-#endif-                       7 -> do-#if 0-                               let patA = patstrlst!!0-                               putStr hline-                               putStrLn "Testing      growPat patA ([1,2,3],(False,\"foo\"))"-                               putStrLn $ "patA         " ++ patA-                               putStr $ "result       "-                               let s1 = force $ showPat $ growPat (compilePat patA) ([1,2,3::Int],(False,"foo"))-                               return s1-#else-                               return ""-#endif-                       8 -> do-                               let patA = patstrlst!!0-                               putStr hline-                               putStrLn "Testing      shrinkPat patA"-                               putStrLn $ "patA         " ++ patA-                               putStr $ "result       "-                               let s1 = force $ showPat $ shrinkPat (compilePat patA)-                               return s1-                       9 -> do-                               putStr hline-                               putStrLn "Testing      liftPats patstrlst"-                               putStrLn $ "patstrs      " ++ show patstrlst-                               putStr $ "result       "-                               let s1 = force $ showPat $ liftPats $ map compilePat patstrlst-                               return s1-                       _ -> error $ "doit13: unexpected code " ++ show code-                return $! s1-           )-           -- ErrorCall if use __ = undefined-           -- BottomedOut if use __ = throw BottomedOut-           (\e -> do let err = show (e :: ErrorCall)---         (\e -> do let err = show (e :: BottomedOut)-                     return err)-    putStrLn s-    doit13 False t-----------------------------------------------------------------------------------  -- This is an adaptation of doit10 to user-defined datatypes,-  -- for testing GNFDataP, which is finally within reach thanks-  -- to SOP!-  doit14 :: Bool -> [(Int,String)] -> IO ()-  doit14 _ [] = do-                   putStrLn "----------------------------------------------------"-                   return ()-  doit14 b ((code,patstr):t) = do-    let expect = case code of-                  1 -> "7"-                  2 -> "Prelude.undefined"-                  3 -> "pattern-match failure"-                  4 -> "syntax error"-                  5 -> "7 (but \"# with subpattern\" warning)"-                  6 -> "7 (but \"constraint/subpattern arity mismatch\" warning)"-                  13 -> "7 (but with pattern-match failure warning)"-                  23 -> "Prelude.undefined (but with pattern-match failure warning)"-                  _ -> error $ "doit14: unexpected code " ++ show code-    s <- catch-           ( do-                let exp = (3.4, [5,__,7], __) :: (Float, [Int], Bool)-                let pat = compilePat patstr-                let get (_,xs,_) = show $ (xs!!2)-                if b-                 then do-                  putStrLn "===================================================="-                  putStrLn "exp = (3.4, [5,__,7], __) :: (Float, [Int], Bool)"-                  putStrLn "get (_,xs,_) = show $ (xs!!2)"-                  putStrLn "? = get $ forcep patstr exp"-                  putStrLn "===================================================="-                 else do-                  putStrLn "----------------------------------------------------"-                putStrLn $ "patstr                   = " ++ patstr-                if code > 4-                 then putStrLn $  "expected value           = " ++ expect-                 else return ()---              putStrLn $ "pat = " ++ show pat-                putStrLn $ "showPat.compilePat       = " ++ showPat pat-                if code <= 4-                 then putStrLn $  "expected value           = " ++ expect-                 else return ()-                s1 <- catch-                        ( return $! force $! get $! forcep patstr exp )-                        (\e -> do let err = show (e :: ErrorCall)---                      (\e -> do let err = show (e :: BottomedOut)-                                  return err)-                putStr "actual value             = "-                return $! s1-           )-           -- ErrorCall if use __ = undefined-           -- BottomedOut if use __ = throw BottomedOut-           (\e -> do let err = show (e :: ErrorCall)---         (\e -> do let err = show (e :: BottomedOut)-                     return err)-    putStrLn s-    doit14 False t----------------------------------------------------------------------------------
− tests/Blah98_old_grammar.hs
@@ -1,1102 +0,0 @@------------------------------------------------------------------------------------- This is a pared-down version of Blah.hs, for testing--- deepseq-bounded when built with the HASKELL98_FRAGMENT--- flag set.  See Blah.hs for comments and other "flesh".-----------------------------------------------------------------------------------{-# LANGUAGE CPP #-}-----------------------------------------------------------------------------------#define FOCUS_TEST 0-#define USE_TRACE 0-----------------------------------------------------------------------------------  module Blah98_old_grammar ( run_tests ) where-----------------------------------------------------------------------------------  import Foo--  import Control.DeepSeq.Bounded hiding ( F )--  import Data.Maybe--  import Control.Exception---import Control.Monad ( guard )-  import Control.Monad ( replicateM )-  import Control.Monad ( when )--  import Data.Typeable ( Typeable )-  import Data.Typeable ( typeOf )----import Util ( spoor )-  import Debug.Trace ( trace )-  import Control.DeepSeq--  import Data.Typeable ( Proxy(..) )--  import Data.List ( intercalate )--  import System.IO.Unsafe ( unsafePerformIO )-----------------------------------------------------------------------------------  -- For convenience in GHCi interactive sessions:-  cp = compilePat-  ip = intersectPats-  isp = subPat-----------------------------------------------------------------------------------  run_tests :: IO Int-  run_tests = do-    putStr "\n"-    -- So can notice the start when scrollback, esp. in ghci reload/reruns.---  replicateM 50 $ putStrLn "################################################################################"-    putStrLn "\nTesting.\n"--#if ! FOCUS_TEST--#if 1---  let shp s = s ++ replicate (30 - length s) ' ' ++ show (compilePat s)-    let shp s = -         unsafePerformIO $-         catch-          ( return $! force $ s ++ replicate (30 - length s) ' ' ++ show (compilePat s) )-          ( \e -> do let err = show (e :: ErrorCall)-                     return err )--    putStrLn "Pattern                       Compiles to"---  putStrLn $ shp ""  -- empty pattern syntax error-    putStrLn $ shp "*"  -- Node WW []---  putStrLn $ shp "@"  -- Node WS []  -- obsoleted (use "." w/o children)-    putStrLn $ shp "#"  -- Node I []  -- no parent to absorb (should be error)-    putStrLn $ shp "."  -- Node WS []---  putStrLn $ shp "**"  -- Node WS []  -- "disconnected pattern (not rooted)"---  putStrLn $ shp ".*"  -- Node WS []  -- "disconnected pattern (not rooted)"---  putStrLn $ shp "*."  -- Node WS []  -- "disconnected pattern (not rooted)"-    putStrLn $ shp ".{}"  -- Node WR []-    putStrLn $ shp ".{*}"  -- Node WR [Node WW []]-    putStrLn $ shp ".{**}"  -- Node WR [Node WW [],Node WW []]-    putStrLn $ shp ".{.*}"  -- Node WR [Node WS [],Node WW []]-    putStrLn $ shp ".{#.}"  -- Node WR [Node I [],Node WS []]-    putStrLn $ shp ".{#{#}}"  -- Node WR [Node I []] with warning-    putStrLn $ shp ".{.{#}}"  -- Node WR [Node WR [Node I []]]-    putStrLn $ shp ".{*#*#*#**#*#*}"  -- looks fine-    putStrLn $ shp ".{*#.{*#.{*#}*}*{#*}#*}"  -- warning about *{...}-    putStrLn $ shp ".{*#.{*#.{*#}*}*#*}"---  putStrLn $ shp ".{*#.{*#.{*#}*}{*}{#*}#*}"  -- }{ syntax error--- [old comment for that last:] NodeM WR [NodeM WW [],Nil,NodeM WR [NodeM WW [],Nil,NodeM WR [NodeM WW [],Nil],NodeM WW [],NodeM WW [],Nil,NodeM WW []],Nil,NodeM WW []] -- was wrong but is fixed I think-    putStrLn $ shp ".{.*.{*23*}}"-#endif--#if 1-    let test_patterns10 = [-           (4,  "")  -- syntax error-         , (4,  ".##")  -- syntax error (disconnected pattern)-         , (1,  ".{.##}")  -- fail-         , (5,  ".{.{}#{}#{}}")-         , (2,  "*")-         , (2,  ".{***}")-         , (1,  ".{###}")-         , (1,  ".{*##}")-         , (2,  ".{**#}")-         , (2,  ".{##*}")--           -- Remember, [a] is a recursive binary ctor app!...-           -- The next four tests give instance errors for [a], but if-           -- testing expTG_* (GNFDataP/grnfp) then it's no longer a list...-         , (13, ".{..{*#*}#}")-         , (13, ".{..{*###}#}")-         , (13, ".{..{*####}#}")-         , (23, ".{..{*####}.}")--         , (2,  ".{..{*#}*}")-         , (1,  ".{..{*#}#}")-         , (1,  ".{..{*.{#*}}#}")-         , (2,  ".{..{*.{*#}}#}")-         , (13, ".{..{.{..{#*}}}#}")  -- See above comment about [a] instance-         , (2,  ".{#.{..{..{#*}}}#}")--           -- (See Book, p.84.)-         , (1,  ".{..{..{#.{..}}}#}")-         , (1,  ".{..{..{#*}}#}")-         , (1,  ".{*.{*.{#*}}#}")-         , (2,  ".{##*}")-         , (2,  ".{*#*}")-         , (1,  ".:Tuple3{*.{*.{#*}}#}")  -- oops...-         , (1,  ".:(,,){*.{*.{#*}}#}")-         , (2,  ".:(,,){*.{*.{.*}}#}")-         , (1,  ".:Bool{***}")  -- XXX makes no sense (but works) -- oh well;-                                  -- this is an important point to note in-                                  -- docs/blog also...-         , (1,  "*:Bool")-         , (2,  "*:(,,)")-         , (2,  ".{*#.}")-         , (2,  ".{*#.:Bool}")  -- XXX this gives parse error on 2nd .-         , (2,  ".{*#.:Bool{}}")  -- XXX this gives no parse error; if it does what-                                  -- it says, it will only match a childless Bool node-         , (1,  ".{*#.:Int{}}")  -- still need to implement # when not in type-         , (1,  ".{*#.:(,){}}")  -- still need to implement # when not in type-         , (1,  ".{*#.:Int }")  -- still need to implement # when not in type-         , (1,  ".{*#.:Int'}")  -- still need to implement # when not in type-         , (1,  ".{*##:Bool}")-         , (2,  ".{*##:Int}")-         , (2,  ".{*##:(,)}")-         , (1,  ".{*##:Bool{}}")-         , (2,  ".{*##:Int{}}")-         , (2,  ".{*##:(,){}}")-         , (1,  ".{**2#}")-         , (2,  ".{**3#}")-         , (1,  ".{*#:G2{}#}")-         , (1,  ".{*#:Int{}#}")-         ]-    doit14 True test_patterns10---  doit10 True test_patterns10-#endif--#endif--------------------------------------------------- Later: Oh! Don't be silly -- it's all compile-time, and the--- size or shape of the list is irrelevant -- which rules--- will fire depends on THIS FILE'S SOURCE CODE (not it's--- data, including static values)!--- XXX Even with empty list, the same rule firings occur!...--- If comment out this block however, the rules do not fire!-#if 1-    -- Testing composition and union:-    let test_patterns11 = [-           (1, ".", ".")-         , (2, ".", "*")-         , (2, "*", ".")-         , (2, "*", "*")-         , (2, ".{...}", ".{*..}")-         , (2, ".{*..}", ".{..*}")-         , (2, ".{.*#}", ".{.#.}")-         ]-    doit11 True test_patterns11-#endif--#if 1-    -- Testing splicePats-    let test_patterns12 = [-#if 1-           (1, ".", [], [(0,"*")])-         , (1, ".{}", [], [(0,"*")])-         , (1, ".", [0], [(0,"*")])-         , (1, ".{..}", [], [(0,"*")])-         , (1, ".{..}", [0], [(0,"*")])-         , (1, ".{..}", [2], [(0,"*")])-         , (1, ".{..}", [], [(0,"*"),(0,"#")])-         , (1, ".{..}", [], [(0,"*"),(1,"#")])-         , (1, ".{..}", [], [(1,"#"),(0,"*")])-         , (1, ".{..}", [], [(0,"*"),(2,"#")])-         , (1, ".{..}", [], [(2,"*"),(2,"#"),(2,"#")])-         , (1, ".{..}", [], [(-1,"*")])-         , (1, ".{..}", [], [(0,"*")])-         , (1, ".{..}", [], [(1,"*")])-         , (1, ".{..}", [], [(2,"*")])-         , (1, ".{..}", [], [(3,"*")])-         , (1, ".{..{..}.}", [1], [(0,"*")])-         , (1, ".{..{..}.}", [1], [(0,"*3"),(1,"#"),(2,"*")])-         , (1, ".{..{..}.}", [1,0], [(0,"*"),(0,"#")])-         , (1, ".{.{...}.{.{}.}.}", [1], [(0,"*"),(0,"#")])-         , (1, ".{.{...}.{.{}.}.}", [1,0], [(0,"*"),(0,"#")])-         , (1, ".{.{###}.{.{}#}#}", [1,0], [(0,"*"),(0,"#")])-         , (1, ".{.:(,,){###}.{.{}#}#}", [1,0], [(0,"*"),(0,"#")])-#else-           (1, ".", ".{}", [(0,"*")])-         , (1, ".{}", ".{}", [(0,"*")])-         , (1, ".", ".{.{}}", [(0,"*")])  -- added later, did uncover a bug! (irrefutable pattern failure)-         , (1, ".{..}", ".{}", [(0,"*")])-         , (1, ".{..}", ".{.{}}", [(0,"*")])-         , (1, ".{..}", ".{...{}}", [(0,"*")])-         , (1, ".{..}", ".{}", [(0,"*"),(0,"#")])-         , (1, ".{..}", ".{}", [(0,"*"),(1,"#")])-         , (1, ".{..}", ".{}", [(1,"#"),(0,"*")])-         , (1, ".{..}", ".{}", [(0,"*"),(2,"#")])-         , (1, ".{..}", ".{}", [(2,"*"),(2,"#"),(2,"#")])-         , (1, ".{..}", ".{}", [(-1,"*")])-         , (1, ".{..}", ".{}", [(0,"*")])-         , (1, ".{..}", ".{}", [(1,"*")])-         , (1, ".{..}", ".{}", [(2,"*")])-         , (1, ".{..}", ".{}", [(3,"*")])-         , (1, ".{..{..}.}", ".{..{}.}", [(0,"*")])-         , (1, ".{..{..}.}", ".{..{}.}", [(0,"*3"),(1,"#"),(2,"*")])-         , (1, ".{..{..}.}", ".{..{.{}.}.}", [(0,"*"),(0,"#")])-         , (1, ".{..{..}.}", ".{..{.{}}}", [(0,"*"),(0,"#")])-         , (1, ".{.{...}.{.{}.}.}", ".{..{}}", [(0,"*"),(0,"#")])-         , (1, ".{.{...}.{.{}.}.}", ".{..{.{}}}", [(0,"*"),(0,"#")])-         , (1, ".{.{###}.{.{}#}#}", ".{..{.{}}}", [(0,"*"),(0,"#")])-         , (1, ".{.:(,,){###}.{.{}#}#}", ".{..{.{}}}", [(0,"*"),(0,"#")])-#endif-         ]-    doit12 True test_patterns12-#endif--#if ! FOCUS_TEST--#if 1-    -- Testing anything else we can with a single function!-    -- (Getting sick of this cloning.)-    -- Functions are listed in (current) export order.-    -- Things still needing testing are >'d.-    -- Things tested but failing some tests have a *.-    -- -    -- XXX Wow does this ever look cleaner with "Pat" instead of "Pattern"!...-    -- Fortunately splicePats is already tested separately; the rest-    -- we need to test deal only in Pat args (or list of same), so-    -- we can pass a couple [Pat] to test13 along with an Int code-    -- to control delegation.-    --  1    unionPats       :: [ Pat ] -> Pat-    --  2    intersectPats   :: [ Pat ] -> Pat-    --  3    subPat          :: Pat -> Pat -> Bool---  --  4    unionPatsStr    :: [ String ] -> String-    --  5    emptyPat        :: Pat---  --  6    mkPat           :: forall d. Data d => d -> Pat---  --  7    growPat         :: forall d. Data d => Pat -> d -> Pat-    --  8    shrinkPat       :: Pat -> Pat-    --  9    liftPats        :: [ Pat ] -> Pat-    -- 10    splicePats      :: Pat -> Pat -> [(Int, Pat)] -> Pat-    -- 11    isPath          :: Pat -> Bool-    let test_patterns13 = [-           ( 1, [".{...}", ".{.#}"], "")-         , ( 2, [".{...}", ".{.#}"], "")-         , ( 3, [".", "."], "True")-         , ( 3, ["#", "#"], "True")-         , ( 3, ["*", "*"], "True")-         , ( 3, [".", ".{}"], "True")-         , ( 3, [".{}", "."], "False")-         , ( 3, [".{}", ".{.}"], "False")-         , ( 3, [".{.}", ".{.}"], "True")-         , ( 3, [".{.}", ".{..}"], "False")-         , ( 3, [".{.}", ".{.{.}}"], "True")-         , ( 3, [".{..}", ".{.#}"], "False")-         , ( 3, [".{.#}", ".{..}"], "True")-         , ( 3, [".{..}", ".{...}"], "False")-         , ( 3, [".{}", ".{...}"], "False")-         , ( 3, [".", ".{*.#}"], "True")-         , ( 3, ["#", ".{*.#}"], "True")-         , ( 3, ["*", ".{*.#}"], "False")-         , ( 3, ["*", ".{*}"], "False")-         , ( 3, ["*", ".{**}"], "False")-         , ( 4, [".{...}", ".{.#}"], "")-         , ( 5, [".{...}", ".{.#}"], "")-#if 0-         , ( 6, [".{...}", ".{.#}"], "")-         -- matching against val = ([1,2,3::Int],(False,"foo"))-         -- mkPat val = ".{.{..{..{..}}}.{..{..{..{..}}}}}"-#endif-#if 0-         , ( 7, [".{.{..{..}}.{..{..}}}"], "")-         , ( 7, [".{.{..{..{..}}}.{..{..{..}}}}"], "")-         , ( 7, [".{.{..{..{..}}}.{..{..{..{..}}}}}"], "")-#endif-         , ( 8, [".{.{..{..{..}}}.{..{..{..{..}}}}}"], "")-         , ( 8, [".{.{..{..{..}}}.{..{..{..}}}}"], "")-         , ( 8, [".{.{..{..}}.{..{..}}}"], "")-         , ( 8, [".{.{#.{..}}.{#.{*3.}}}"], "")-         , ( 8, [".{.{#.}.{#.}}"], "")-         , ( 8, [".{..}"], "")-         , ( 8, ["."], "")-         , ( 9, [".{...}", ".{.#}"], "")-         , (10, [".{...}", ".{.#}"], "")-         , (11, [".{...}", ".{.#}"], "")-         ]-    putStrLn "===================================================="-    putStrLn "Testing miscellaneous NFDataP functions..."-    doit13 True test_patterns13-#endif--#if 1-    -- Testing fusion-    putStrLn "\nTesting fusion\n-fenable-rewrite-rules -O -ddump-rules -ddump-simpl-stats -ddump-rule-firings\n"-    let exp12 = (3.4, [5,__,7], __) :: (Float, [Int], Bool)-    let get12 (_,xs,_) = (xs!!2)-    putStrLn $ show $ get12 $ ( forcep ".:Bool{}" . forcep ".:Int{}" ) exp12-    putStrLn $ show $ get12 $ ( forcep ".:Bool{}" . forcep_ (compilePat ".:Int{}") ) exp12-    putStrLn $ show $ get12 $ ( forcep_ (compilePat ".:Bool{}") . forcep ".:Int{}" ) exp12-    putStrLn $ show $ get12 $ ( forcep_ (compilePat ".:Bool{}") . forcep_ (compilePat ".:Int{}") ) exp12-#endif--#if 1-    putStrLn $ intercalate "\n"-     [ ""-     , "expN_1 = [__] :: [Int]"-     , "expN_2 = [0,1,__,3] :: [Int]"-     , "expN_3 = (3.4, [5,__,7], True) :: (Float, [Int], Bool)"-     , "expN_4 = (3.4, [5,__,7], __) :: (Float, [Int], Bool)"-     , ""-     , "getN_1 xs = show $ ()"---   , "getN_1 xs = show $ head xs"---   , "getN_2 xs = show $ (xs!!1)"-     , "getN_2 xs = show $ (xs!!3)"-     , "getN_3 (_,xs,_) = show $ (xs!!2)"-     ]-    doit5 1 0 1 "" >>= putStrLn-    doit6 1 0 1 "" >>= putStrLn-    doit7 1 0 1 "" >>= putStrLn-    doit8 1 0 1 "" >>= putStrLn-#if 0-    doit9 >>= putStrLn  -- XXX broken (whatever it is)-#endif-#endif--#if 0-    s4 <- doit4 1 0 1 ""-    putStrLn s4-#endif--#if 0-    putStrLn $ ""-           ++ "expBase1 = ([True,False],3,Just \"fox\")         :: ([Bool],Int,Maybe String)\n"-           ++ "expBase2 = ([True,False],__,Just \"fox\")        :: ([Bool],Int,Maybe String)\n"-           ++ "expBase3 = ([True,__],3,Just \"fox\")            :: ([Bool],Int,Maybe String)\n"-           ++ "expBase4 = ([True,__],3,Just __)               :: ([Bool],Int,Maybe String)\n"-           ++ "expBase5 = ([True,False],3,Just ['f',__,'x'])  :: ([Bool],Int,Maybe String)\n"-           ++ "expBase6 = ([True,False],3,Just __)            :: ([Bool],Int,Maybe String)\n"-           ++ "get1 ((x:_),_,_) = x           -- True\n"-           ++ "get2 (_,x,_) = x               -- 3\n"-           ++ "get3 (_,_,x) = fromJust x      -- \"fox\"\n"-           ++ "get4 (_,_,Just (x:_)) = x      -- 'f'\n"-    s1 <- doit1 1 1 1 ""-    putStrLn s1-#endif--#endif--    return 0-----------------------------------------------------------------------------------  hline :: String-  hline = "----------------------------------------------------\n"-  hdline :: String-  hdline = "====================================================\n"-----------------------------------------------------------------------------------  doit1 :: Int -> Int -> Int -> String -> IO String-  doit1 i j k acc-   -- this glitch (the exception that seemingly escapes my catch)-   -- happens just for these combos (and for all j):--- | i == 3 && k == 4  = doit1 (1+i) j k acc  -- trying to avoid a glitch...--- | i == 3 && k == 5  = doit1 (1+i) j k acc  -- trying to avoid a glitch...--- | i == 3 && j < 4 && k == 5  = doit1 (1+i) j k acc  -- trying to avoid a glitch...-   | k == 7  = return acc-   | j == 6  = doit1 1 1 (1+k) acc-   | i == 5  = doit1 1 (1+j) k acc-   | otherwise  = do-      fexp <- catch-               -- The semantics of the !'s here are not what they were,-               -- since forcing in some places. [?] But at least the-               -- first one seems definitely still needed...-               -- LATER: The second one is also needed, finally seen!-               -- (It is needed for a version of getE _ = "getee", only.)-               -- XXX I'm just not sure whether the second ! is better-               -- to leave in or leave out...-               ( return $! get $! forcen dep exp )-               (\e -> do let err = show (e :: ErrorCall)---             (\e -> do let err = show (e :: BottomedOut)-                         return err)---    doit1 (1+i) j k $! force $ acc-      doit1 (1+i) j k $! acc---    doit1 (1+i) j k $ acc-        ++ "( get" ++ show i ++ " $ forcen " ++ show dep ++ " expBase" ++ show k ++ " )  "-        ++ fexp ++ "\n"-   where-    exp = case k of-            1 -> expBase1-            2 -> expBase2-            3 -> expBase3-            4 -> expBase4-            5 -> expBase5-            6 -> expBase6-    get = case i of-           1 -> get1-           2 -> get2---         3 -> unsafePerformIO . get3  -- yeesh!...---         3 -> get3-           3 -> get3 (i,j,k)-           4 -> get4-    dep = j--#if 0-  -- XXX All this fuss to deal with the case that the-  -- entire argument m is undefined (or whatever is going-  -- for "undefined" at the moment...) -- but, none of-  -- the expBase[1-5] have this! ch.-  myFromJust :: Maybe a -> IO (Either () a)-  myFromJust m = do-                    putStrLn "Boo!"-                    catch-                      (myFromJust' m)-                      (\e -> do putStrLn $! show (e::BottomedOut)-                                putStrLn "HERE!"-                                return $! Left ())-  myFromJust' :: Maybe a -> IO (Either () a)-  myFromJust' Nothing = do---                         throw BottomedOut-                           return $! Left ()-  myFromJust' (Just x) = return $! Right x---myFromJust _ = throw BottomedOut-#endif------------------------------------#if 0-  doit2 :: Int -> Int -> Int -> String -> IO String-  doit2 i j k acc--- | k == 2  = {- trace (show (i,j,k)) $ -} return acc--- | k == 7  = return acc-   | k == 27  = return acc--- | k == 21  = return acc--- | k == 5  = return acc--- | j == 15  = doit2 1 0 (1+k) acc-   | j == 11  = {- trace (show (i,j,k)) $ -} doit2 1 0 (1+k) acc--- | j == 8  = {- trace (show (i,j,k)) $ -} doit2 1 0 (1+k) acc--- | j == 3  = {- trace (show (i,j,k)) $ -} doit2 1 0 (1+k) acc-#if USE_TRACE-   | i == 2  = trace ("End of " ++ show (i,j',k')) $ doit2 1 (1+j) k acc--- | i == 3  = trace ("End of " ++ show (i,j',k')) $ doit2 1 (1+j) k acc-#else-   | i == 2  = doit2 1 (1+j) k acc--- | i == 3  = doit2 1 (1+j) k acc-#endif-   | otherwise  = do-      fexp <- catch-               ( return $! get $! forcen dep exp )---             ( return $! get $! forcen dep exp )-               -- ErrorCall if use __ = undefined-               -- BottomedOut if use __ = throw BottomedOut-               (\e -> do let err = show (e :: ErrorCall)---             (\e -> do let err = show (e :: BottomedOut)-                         return err)-      doit2 (1+i) j k $! acc-        ++ "( getB_" ++ show i ++ " $ forcen " ++ show dep ++ (if dep < 10 then " " else "") ++ " expTB_" ++ show (k'-6) ++ " )  "---      ++ "( getB_" ++ show i ++ " $ forcen " ++ show dep ++ (if dep < 10 then " " else "") ++ " expBase" ++ show k' ++ " )  "-        ++ fexp ++ "\n"-   where-    exp = case k' of-            7 -> expBase7-            8 -> expBase8-            9 -> expBase9-            10 -> expBase10-            11 -> expBase11-            12 -> expBase12-            13 -> expBase13-            14 -> expBase14-            15 -> expBase15-            16 -> expBase16-            17 -> expBase17-            18 -> expBase18-            19 -> expBase19-            20 -> expBase20-            21 -> expBase20  -- fudge it!!-            22 -> expBase22-            23 -> expBase23-            24 -> expBase24-            25 -> expBase25-            26 -> expBase26-            27 -> expBase27-            28 -> expBase28-            29 -> expBase29-            30 -> expBase30-            31 -> expBase31-            32 -> expBase32-    get = case i of-           1 -> if k' >= 27 then getB_3 else getB_1-           2 -> getB_2-    dep = j'-    j' = j---  j' = j+11---  k' = k+26-    k' = k+6-#endif--#if 0-  doit3 :: Int -> Int -> Int -> String -> IO String-  doit3 i j k acc-   | k == 2  = return acc-   | j == 8  = {- trace (show (i,j,k)) $ -} doit3 1 1 (1+k) acc-#if USE_TRACE-   | i == 2  = trace ("End of " ++ show (i,j',k')) $ doit3 1 (1+j) k acc-#else-   | i == 2  = doit3 1 (1+j) k acc-#endif-   | otherwise  = do-      fexp <- catch-               ( return $! get $! forcen dep exp )-               -- ErrorCall if use __ = undefined-               -- BottomedOut if use __ = throw BottomedOut-               (\e -> do let err = show (e :: ErrorCall)---             (\e -> do let err = show (e :: BottomedOut)-                         return err)-      doit3 (1+i) j k $! acc-        ++ "( getB_" ++ show i ++ " $ forcen " ++ show dep ++ " expBase" ++ show k' ++ " )  "-        ++ fexp ++ "\n"-   where-    exp = case k' of-            21 -> expBase21-    get = case i of-           1 -> getA-    dep = j'-    i' = i-    j' = j-    k' = k+20-#endif--#if 0-  doit4 :: Int -> Int -> Int -> String -> IO String-  doit4 i j k acc--- | k == 2  = return acc-   | k == 4  = return acc-   | j == 8  = {- trace (show (i,j,k)) $ -} doit4 1 0 (1+k) acc-#if USE_TRACE-   | i == 2  = trace ("End of " ++ show (i,j',k')) $ doit4 1 (1+j) k acc-#else-   | i == 2  = doit4 1 (1+j) k acc-#endif-   | otherwise  = do-      fexp <- catch-               ( return $! get $! forcen dep exp )-               -- ErrorCall if use __ = undefined-               -- BottomedOut if use __ = throw BottomedOut-               (\e -> do let err = show (e :: ErrorCall)---             (\e -> do let err = show (e :: BottomedOut)-                         return err)-      doit4 (1+i) j k $! acc-        ++ "( getE $ forcen " ++ show dep ++ " expTE_" ++ show k' ++ " )  "-        ++ fexp ++ "\n"-   where-    exp = case k' of-            1 -> expTE_1-            2 -> expTE_2-            3 -> expTE_3-    get = case i of-           1 -> getE-    dep = j'-    i' = i-    j' = j-    k' = k-#endif-----------------------------------------------------------------------------------  doit5 :: Int -> Int -> Int -> String -> IO String-  doit5 i j k acc-   | k == 2  = return acc-   | j == 5  = {- trace (show (i,j,k)) $ -} doit5 1 0 (1+k) acc-#if USE_TRACE-   | i == 2  = trace ("End of " ++ show (i,j',k')) $ doit5 1 (1+j) k acc-#else-   | i == 2  = doit5 1 (1+j) k acc-#endif-   | otherwise  = do-      fexp <- catch-               ( return $! get $! forcen dep exp )-               -- ErrorCall if use __ = undefined-               -- BottomedOut if use __ = throw BottomedOut-               (\e -> do let err = show (e :: ErrorCall)---             (\e -> do let err = show (e :: BottomedOut)-                         return err)-      doit5 (1+i) j k $! acc-        ++ "forcen " ++ show dep ++ " expN_" ++ show k' ++ " `seq` ()  =  "-        ++ fexp ++ "\n"-   where-    exp = case k' of-            1 -> expN_1-    get = case i of-           1 -> getN_1-    dep = j'-    i' = i-    j' = j-    k' = k-----------------------------------------------------------------------------------  doit6 :: Int -> Int -> Int -> String -> IO String-  doit6 i j k acc-   | k == 2  = return acc-   | j == 5  = {- trace (show (i,j,k)) $ -} doit6 1 0 (1+k) acc-#if USE_TRACE-   | i == 2  = trace ("End of " ++ show (i',j',k')) $ doit6 1 (1+j) k acc-#else-   | i == 2  = doit6 1 (1+j) k acc-#endif-   | otherwise  = do-      fexp <- catch-               ( return $! get $! forcen dep exp )-               -- ErrorCall if use __ = undefined-               -- BottomedOut if use __ = throw BottomedOut-               (\e -> do let err = show (e :: ErrorCall)---             (\e -> do let err = show (e :: BottomedOut)-                         return err)-      doit6 (1+i) j k $! acc-        ++ "getN_" ++ show i' ++" $ forcen " ++ show dep ++ " expN_" ++ show k' ++ "  =  "-        ++ fexp ++ "\n"-   where-    exp = case k' of-            _ -> expN_2-    get = case i of-           _ -> getN_2-    dep = j'-    i' = i+1-    j' = j-    k' = k+1-----------------------------------------------------------------------------------  doit7 :: Int -> Int -> Int -> String -> IO String-  doit7 i j k acc-   | k == 2  = return acc-   | j == 5  = {- trace (show (i,j,k)) $ -} doit7 1 0 (1+k) acc-#if USE_TRACE-   | i == 2  = trace ("End of " ++ show (i',j',k')) $ doit7 1 (1+j) k acc-#else-   | i == 2  = doit7 1 (1+j) k acc-#endif-   | otherwise  = do-      fexp <- catch-               ( return $! get $! forcen dep exp )-               -- ErrorCall if use __ = undefined-               -- BottomedOut if use __ = throw BottomedOut-               (\e -> do let err = show (e :: ErrorCall)---             (\e -> do let err = show (e :: BottomedOut)-                         return err)-      doit7 (1+i) j k $! acc-        ++ "getN_" ++ show i' ++" $ forcen " ++ show dep ++ " expN_" ++ show k' ++ "  =  "-        ++ fexp ++ "\n"-   where-    exp = case k' of-            _ -> expN_3-    get = case i of-           _ -> getN_3-    dep = j'-    i' = i+2-    j' = j-    k' = k+2-----------------------------------------------------------------------------------  doit8 :: Int -> Int -> Int -> String -> IO String-  doit8 i j k acc-   | k == 2  = return acc-   | j == 5  = {- trace (show (i,j,k)) $ -} doit8 1 0 (1+k) acc-#if USE_TRACE-   | i == 2  = trace ("End of " ++ show (i',j',k')) $ doit8 1 (1+j) k acc-#else-   | i == 2  = doit8 1 (1+j) k acc-#endif-   | otherwise  = do-      fexp <- catch-               ( return $! get $! forcen dep exp )-               -- ErrorCall if use __ = undefined-               -- BottomedOut if use __ = throw BottomedOut-               (\e -> do let err = show (e :: ErrorCall)---             (\e -> do let err = show (e :: BottomedOut)-                         return err)-      doit8 (1+i) j k $! acc-        ++ "getN_" ++ show i' ++" $ forcen " ++ show dep ++ " expN_" ++ show k' ++ "  =  "-        ++ fexp ++ "\n"-   where-    exp = case k' of-            _ -> expN_4-    get = case i of-           _ -> getN_3-    dep = j'-    i' = i+2-    j' = j-    k' = k+3-----------------------------------------------------------------------------------#if 0--#if 0-  expP_1 = (3.4, [5,__,7], __) :: (Float, [Int], Bool)-  patP_1 = Node (TR [typeOf ((__,__,__)::(Float, [Int], Bool))])-             [ Node (TR [typeOf (__::Bool)]) []---           [ Node (TR [typeOf (__::Float)]) []---           [ Node (NTR [typeOf (__::Bool)]) []---           [ Node (NTR [typeOf (__::Float)]) []---           , Node WS []-             , Node (TW [typeOf ([__]::[Int])]) []---           , Node (TR [typeOf ([__]::[Int])]) []---           , Node (TR [typeOf ([__]::[Int])]) [ Node WS [], Node WS [] ]  -- why not?-             , Node WW []---           , Node I []-             ]-  getP_1 (_,xs,_) = show $ (xs!!2)-#endif--  doit9 :: IO String-  doit9 = do-#if 0-    putStrLn $ intercalate "\n"-     [ ""-     , "expP_1 = (3.4, [5,__,7], __) :: (Float, [Int], Bool)"-     , "patP_1 = Node (T [typeOf ((__,__,__)::(Float, [Int], Bool))])"-     , "           [ Node W []"-     , "           , Node (T [typeOf ([__]::[Int])]) []"-     , "           , Node I []"-     , "           ]"-     , "getP_1 (_,xs,_) = show $ (xs!!2)"-     ]-    putStrLn "getP_1 $ forcep patP_1 expP_1"-#endif-    s <- catch-             ( return $! getP_1 $! forcep patP_1 expP_1 )---           ( return $! getP_2 $! forcep patP_2 expP_2 )---           ( return $! getP_3 $! forcep patP_3 expP_3 )-             -- ErrorCall if use __ = undefined-             -- BottomedOut if use __ = throw BottomedOut-             (\e -> do let err = show (e :: ErrorCall)---           (\e -> do let err = show (e :: BottomedOut)-                       return err)-    return s--#endif-----------------------------------------------------------------------------------  doit10 :: Bool -> [(Int,String)] -> IO ()-  doit10 _ [] = do-                   putStrLn "----------------------------------------------------"-                   return ()-  doit10 b ((code,patstr):t) = do-    let expect = case code of-                  1 -> "7"-                  2 -> "Prelude.undefined"-                  3 -> "pattern-match failure"-                  4 -> "syntax error"-                  5 -> "7 (but \"# with subpattern\" warning)"-                  6 -> "7 (but \"constraint/subpattern arity mismatch\" warning)"-                  13 -> "7 (but with pattern-match failure warning)"-                  23 -> "Prelude.undefined (but with pattern-match failure warning)"-                  _ -> error $ "doit10: unexpected code " ++ show code-    s <- catch-           ( do-                let exp = (3.4, [5,__,7], __) :: (Float, [Int], Bool)-                let pat = compilePat patstr-                let get (_,xs,_) = show $ (xs!!2)-                if b-                 then do-                  putStrLn "===================================================="-                  putStrLn "exp = (3.4, [5,__,7], __) :: (Float, [Int], Bool)"-                  putStrLn "get (_,xs,_) = show $ (xs!!2)"-                  putStrLn "? = get $ forcep patstr exp"-                  putStrLn "===================================================="-                 else do-                  putStrLn "----------------------------------------------------"-                putStrLn $ "patstr                   = " ++ patstr-                if code > 4-                 then putStrLn $  "expected value           = " ++ expect-                 else return ()---              putStrLn $ "pat = " ++ show pat-                putStrLn $ "showPat.compilePat       = " ++ showPat pat-                if code <= 4-                 then putStrLn $  "expected value           = " ++ expect-                 else return ()-                s1 <- catch-                        ( return $! force $! get $! forcep patstr exp )-                        (\e -> do let err = show (e :: ErrorCall)---                      (\e -> do let err = show (e :: BottomedOut)-                                  return err)-                putStr "actual value             = "-                return $! s1-           )-           -- ErrorCall if use __ = undefined-           -- BottomedOut if use __ = throw BottomedOut-           (\e -> do let err = show (e :: ErrorCall)---         (\e -> do let err = show (e :: BottomedOut)-                     return err)-    putStrLn s-    doit10 False t-----------------------------------------------------------------------------------  doit11 :: Bool -> [(Int,String,String)] -> IO ()-  doit11 _ [] = do-                   putStrLn "----------------------------------------------------"-                   return ()-  doit11 b ((code,patstr1,patstr2):t) = do-    let expect = case code of-                  1 -> "7"-                  2 -> "Prelude.undefined"-                  3 -> "pattern-match failure"-                  4 -> "syntax error"-                  5 -> "7 (but \"# with subpattern\" warning)"-                  6 -> "7 (but \"constraint/subpattern arity mismatch\" warning)"-                  _ -> error $ "doit11: unexpected code " ++ show code-    s <- catch-           ( do-                let exp = (3.4, [5,__,7], __) :: (Float, [Int], Bool)-                let patstrU = showPat $ unionPats [compilePat patstr1, compilePat patstr2]-                let pat1 = compilePat patstr1-                let pat2 = compilePat patstr2-                let patU = unionPats [pat1,pat2]-                let get (_,xs,_) = show $ (xs!!2)-                if b-                 then do-                  putStrLn "===================================================="-                  putStrLn "exp = (3.4, [5,__,7], __) :: (Float, [Int], Bool)"-                  putStrLn "get (_,xs,_) = show $ (xs!!2)"-                  putStrLn "? = get $ ( forcep patstr2 . forcep patstr1 ) exp"---                putStrLn "? = get $ ( forcep ( unionPatsStr [ patstr1, patstr2 ] ) ) exp"-                  putStrLn "? = get $! ( forcep_ ( unionPats [ pat1, pat2 ] ) ) exp"-                  putStrLn "(Results were more interesting with a previous semantics...)."-                  putStrLn "===================================================="-                 else do-                  putStrLn "----------------------------------------------------"-                putStrLn $ "patstr1                     = " ++ patstr1-                putStrLn $ "patstr2                     = " ++ patstr2-                putStrLn $ "patstrU                     = " ++ patstrU-                if code > 4-                 then putStrLn $  "expected value              = " ++ expect-                 else return ()---              putStrLn $ "pat = " ++ show pat-                putStrLn $ "showPat.compilePat patstr1  = " ++ showPat pat1-                putStrLn $ "showPat.compilePat patstr2  = " ++ showPat pat2-                putStrLn $ "showPat.compilePat patstrU  = " ++ showPat patU-                if code <= 4-                 then putStrLn $  "expected value              = " ++ expect-                 else return ()-                putStr "actual value                = "-                let s1 = get $! ( forcep patstr2 . forcep patstr1 ) exp-                putStrLn s1-                putStr "actual value                = "-                let s2 = get $! forcep patstrU exp-#if 1-                let s3 = s2-#else-                putStrLn s2-                let s3 = get $! forcep_ ( unionPats [ pat1, pat2 ] ) exp-#endif-                return $! s3-           )-           -- ErrorCall if use __ = undefined-           -- BottomedOut if use __ = throw BottomedOut-           (\e -> do let err = show (e :: ErrorCall)---         (\e -> do let err = show (e :: BottomedOut)-                     return err)-    putStrLn s-    doit11 False t-----------------------------------------------------------------------------------  doit12 :: Bool -> [(Int,String,[Int],[(Int,String)])] -> IO ()---doit12 :: Bool -> [(Int,String,String,[(Int,String)])] -> IO ()-  doit12 _ [] = do-                   return ()-  doit12 b ((code,patstr1,path,isibs'):t) = do-    let expect = case code of-                  1 -> "7"-                  2 -> "Prelude.undefined"-                  3 -> "pattern-match failure"-                  4 -> "syntax error"-                  5 -> "7 (but \"# with subpattern\" warning)"-                  6 -> "7 (but \"constraint/subpattern arity mismatch\" warning)"-                  _ -> error $ "doit12: unexpected code " ++ show code-    s <- catch-           ( do-                let target = compilePat patstr1---              let path = compilePat patstr2-                let isibs = map (\ (x,y) -> (x,compilePat y)) isibs'-                if b-                 then do-                  putStr hdline-                  putStrLn "Testing splicePats."-                  putStr hline-                 else return ()-                putStrLn $ "target       " ++ patstr1-                putStrLn $ "path         " ++ show path---              putStrLn $ "path         " ++ patstr2-                putStrLn $ "isibs        " ++ show isibs'-                let s1 = force $ showPat $ splicePats target path isibs---              let s1 = showPat $! splicePats target path isibs---              let s1 = showPat $ splicePats target path isibs-                putStr "result       "-                return $! s1-           )-           -- ErrorCall if use __ = undefined-           -- BottomedOut if use __ = throw BottomedOut-           (\e -> do let err = show (e :: ErrorCall)---         (\e -> do let err = show (e :: BottomedOut)-                     return err)-    putStrLn s-    if null t then return () else putStr hline-    doit12 False t-----------------------------------------------------------------------------------  doit13 :: Bool -> [(Int,[String],String)] -> IO ()-  doit13 _ [] = do-                   putStr hline-                   return ()-  doit13 b ((code,patstrlst,expectstr):t) = do-    s <- catch-           ( do-                s1 <- case code of--- Where were they done already?--- Oh, in doit11 and doit12 above...-                       1 -> error $ hline ++ "unionPats test already done test13-1!"---                     4 -> error $ hline ++ "unionPatsStr test already done test13-4!"-                       10 -> error $ hline ++ "splicePats test already done test13-10!"-                       11 -> error $ hline ++ "isPath test already done test13-11!"-    --  1    unionPats       :: [ Pat ] -> Pat-    --  2  * intersectPats   :: [ Pat ] -> Pat-    --  3  * subPat          :: Pat -> Pat -> Bool---  --  4    unionPatsStr    :: [ String ] -> String-    --  5  * emptyPat        :: Pat---  --  6  * mkPat           :: forall d. Data d => d -> Pat---  --  7  * growPat         :: forall d. Data d => Pat -> d -> Pat-    --  8  * shrinkPat       :: Pat -> Pat-    --  9  * liftPats        :: [ Pat ] -> Pat-    -- 10    splicePats      :: Pat -> Pat -> [(Int, Pat)] -> Pat-    -- 11    isPath          :: Pat -> Bool-                       2 -> do-                               let patA = patstrlst!!0-                               let patB = patstrlst!!1-                               putStr hline-                               putStrLn "Testing      intersectPats [patA, patB]"-                               putStrLn $ "patA         " ++ patA-                               putStrLn $ "patB         " ++ patB-                               putStr $ "result       "-                               let s1 = force $ showPat $ intersectPats [compilePat patA, compilePat patB]-                               return s1-                       3 -> do-                               let patA = patstrlst!!0-                               let patB = patstrlst!!1-                               putStr hline-                               putStrLn "Testing      subPat patA patB"-                               putStrLn $ "patA         " ++ patA-                               putStrLn $ "patB         " ++ patB-                               let s1 = force $ show $ subPat (compilePat patA) (compilePat patB)-                               if s1 /= expectstr-                                then do putStrLn $ "expect       " ++ expectstr-                                        putStr $ "result       "-                                else putStr $ "as expected  "-                               return s1-                       5 -> do-                               putStr hline-                               putStrLn "Testing      emptyPat"-                               putStr $ "result       "-                               let s1 = force $ showPat $ emptyPat-                               return s1-                       6 -> do-#if 0-                               putStr hline-                               putStrLn "Testing      mkPat ([1,2,3],(False,\"foo\"))"-                               putStr $ "result       "-                               let s1 = force $ showPat $ mkPat ([1,2,3::Int],(False,"foo"))-                               return s1-#else-                               return ""-#endif-                       7 -> do-#if 0-                               let patA = patstrlst!!0-                               putStr hline-                               putStrLn "Testing      growPat patA ([1,2,3],(False,\"foo\"))"-                               putStrLn $ "patA         " ++ patA-                               putStr $ "result       "-                               let s1 = force $ showPat $ growPat (compilePat patA) ([1,2,3::Int],(False,"foo"))-                               return s1-#else-                               return ""-#endif-                       8 -> do-                               let patA = patstrlst!!0-                               putStr hline-                               putStrLn "Testing      shrinkPat patA"-                               putStrLn $ "patA         " ++ patA-                               putStr $ "result       "-                               let s1 = force $ showPat $ shrinkPat (compilePat patA)-                               return s1-                       9 -> do-                               putStr hline-                               putStrLn "Testing      liftPats patstrlst"-                               putStrLn $ "patstrs      " ++ show patstrlst-                               putStr $ "result       "-                               let s1 = force $ showPat $ liftPats $ map compilePat patstrlst-                               return s1-                       _ -> error $ "doit13: unexpected code " ++ show code-                return $! s1-           )-           -- ErrorCall if use __ = undefined-           -- BottomedOut if use __ = throw BottomedOut-           (\e -> do let err = show (e :: ErrorCall)---         (\e -> do let err = show (e :: BottomedOut)-                     return err)-    putStrLn s-    doit13 False t-----------------------------------------------------------------------------------  -- This is an adaptation of doit10 to user-defined datatypes,-  -- for testing GNFDataP, which is finally within reach thanks-  -- to SOP!-  doit14 :: Bool -> [(Int,String)] -> IO ()-  doit14 _ [] = do-                   putStrLn "----------------------------------------------------"-                   return ()-  doit14 b ((code,patstr):t) = do-    let expect = case code of-                  1 -> "7"-                  2 -> "Prelude.undefined"-                  3 -> "pattern-match failure"-                  4 -> "syntax error"-                  5 -> "7 (but \"# with subpattern\" warning)"-                  6 -> "7 (but \"constraint/subpattern arity mismatch\" warning)"-                  13 -> "7 (but with pattern-match failure warning)"-                  23 -> "Prelude.undefined (but with pattern-match failure warning)"-                  _ -> error $ "doit14: unexpected code " ++ show code-    s <- catch-           ( do-                let exp = (3.4, [5,__,7], __) :: (Float, [Int], Bool)-                let pat = compilePat patstr-                let get (_,xs,_) = show $ (xs!!2)-                if b-                 then do-                  putStrLn "===================================================="-                  putStrLn "exp = (3.4, [5,__,7], __) :: (Float, [Int], Bool)"-                  putStrLn "get (_,xs,_) = show $ (xs!!2)"-                  putStrLn "? = get $ forcep patstr exp"-                  putStrLn "===================================================="-                 else do-                  putStrLn "----------------------------------------------------"-                putStrLn $ "patstr                   = " ++ patstr-                if code > 4-                 then putStrLn $  "expected value           = " ++ expect-                 else return ()---              putStrLn $ "pat = " ++ show pat-                putStrLn $ "showPat.compilePat       = " ++ showPat pat-                if code <= 4-                 then putStrLn $  "expected value           = " ++ expect-                 else return ()-                s1 <- catch-                        ( return $! force $! get $! forcep patstr exp )-                        (\e -> do let err = show (e :: ErrorCall)---                      (\e -> do let err = show (e :: BottomedOut)-                                  return err)-                putStr "actual value             = "-                return $! s1-           )-           -- ErrorCall if use __ = undefined-           -- BottomedOut if use __ = throw BottomedOut-           (\e -> do let err = show (e :: ErrorCall)---         (\e -> do let err = show (e :: BottomedOut)-                     return err)-    putStrLn s-    doit14 False t----------------------------------------------------------------------------------
− tests/Blah_new_grammar.hs
@@ -1,3326 +0,0 @@------------------------------------------------------------------------------------- Disclaimer: I've not used HUnit yet. I'm using it only--- as a "hook" so can compile/test in less clock time...--- (I forget the details of how/why.)------ Obviously, this should use proper HUnit eventually.--- And QuickCheck and SmallCheck, DEFINITELY!!!...--- This is a great case for those; and shape-syb no less.------ This file could be cleaned up a lot, but that's--- not quite a priority at the moment...------ The reason I shied away from making it real HUnit tests--- is probably related to the fancy exception throwing/catching--- and catching of all exceptions (including error), etc.--- Which was aggravated by the nature of this project and--- of its tests, which hit bottom as a matter of course...------ Yeah; and looking at examples of QuickCheck and SmallCheck,--- it's still not clear to me how to work bottoming-out--- into my tests.---   I guess I could catch the bottoms in my code, and return--- some reserved value to indicate that it occurred?...-----------------------------------------------------------------------------------{-# LANGUAGE CPP #-}-----------------------------------------------------------------------------------#define FOCUS_TEST 0-#define TRY_THIS 1-#define USE_TRACE 0------------------------------------------------------------------------------------- Later: This may work with some versions of GHC, but I'm quite--- sure I've seen it not work with some recent version...--- Unfortunately, this doesn't work -- all pragmas are processed,--- regardless of CPP (so CPP must run after).--- The fact the CPP itself can be set via a pragma complicates this.--- It could be made an exception, and the LANGUAGE CPP pragma could--- be parsed regardless of CPP context (as all pragmas currently are).--- As it is, we need separate source modules, and to switch at--- import statements (and in the .cabal file).--- THIS IS A BUG.--- So anyhow, this is only here as a reminder:----  #if ! HASKELL98_FRAGMENT----  {-# LANGUAGE ... #-}----  #endif-  {-# LANGUAGE DeriveGeneric #-}-  {-# LANGUAGE DeriveDataTypeable #-}  -- to make BottomedOut-  {-# LANGUAGE BangPatterns #-}--  {-# LANGUAGE Rank2Types #-}  -- for SYB (testing rnfpDyn and friends)-----------------------------------------------------------------------------------  -- SOP pragmas:--  -- Not necessarily needed to work with SOP, but I think it'll-  -- be helpful here [?] ...-  {-# LANGUAGE ScopedTypeVariables #-}-  {-  LANGUAGE AllowAmbiguousTypes #-}---- Actually, CPP doesn't work with Haskell (GHC) pragmas last I checked...-#if USE_SOP-  {-# LANGUAGE DataKinds #-}-  {-# LANGUAGE TypeFamilies #-}-  {-# LANGUAGE ConstraintKinds #-}-#if __GLASGOW_HASKELL__ < 708-  {-# LANGUAGE GADTs #-}-#endif-  {-# LANGUAGE TemplateHaskell #-}-#endif-----------------------------------------------------------------------------------  module Blah_new_grammar ( run_tests ) where-------------------------------------------------------------------------------------import Common-  import Bottom-  import Foo-  import FooG----import Control.DeepSeq.Generics-  import Control.DeepSeq.Bounded---import Control.DeepSeq.Bounded hiding ( F )-  import Control.DeepSeq.Bounded.Generic--#if 0-  import GHC.Generics---import GHC.Generics ( Generic )-#endif--  import Data.Maybe--  import Control.Exception---import Control.Monad ( guard )-  import Control.Monad ( replicateM )-  import Control.Monad ( when )-  import Data.Typeable ( Typeable )-  import Data.Typeable ( typeOf )--  import Data.Data ( Data )--  import Data.Generics.Aliases ( mkQ, extQ, GenericQ )----import Util ( spoor )-  import Debug.Trace ( trace )-  import Control.DeepSeq--#if __GLASGOW_HASKELL__ >= 708-  import Data.Typeable ( Proxy(..) )-#endif--#if USE_SOP-  import Generics.SOP hiding ( Shape )-#endif--  import System.Random--  import Data.List ( intercalate )--  import System.IO.Unsafe ( unsafePerformIO )-----------------------------------------------------------------------------------  -- For convenience in GHCi interactive sessions:-  cp = compilePat---cp = compilePat-  ip = intersectPats-  isp = subPat--  -- For more compact test expressions:--- XXX Refer to Seqable.hs for comments about JUST_ALIAS_GSEQABLE.-#if 1-#if JUST_ALIAS_GSEQABLE-  fI :: forall a. Generic a => a -> a-  fI = force_ Insulate-  fP :: forall a. Generic a => a -> a-  fP = force_ Propagate-#else-  fI :: forall a. NFDataN a => a -> a-  fI = force_ Insulate-  fP :: forall a. NFDataN a => a -> a-  fP = force_ Propagate-#endif-#else-  fI = force_ Insulate-  fP = force_ Propagate-#endif--  gI :: forall a. Generic a => a -> a-  gI = gforce_ Insulate-  gP :: forall a. Generic a => a -> a-  gP = gforce_ Propagate-----------------------------------------------------------------------------------  run_tests :: IO Int-  run_tests = do--    putStr "\n"-    -- So can notice the start when scrollback, esp. in ghci reload/reruns.---  replicateM 50 $ putStrLn "################################################################################"-    putStrLn "\nTesting."-    putStrLn "\nNote that  __ = undefined  (abbrev. occurring in what follows)."--    -- XXX NOTE XXX-    ---    -- Most of the comments are pre-new-grammar (most of the comments-    -- are actually from no later than September 2014).  Some have been-    -- revised in light of the new grammar; many have not...--#if ! FOCUS_TEST--    let shs s p =-         unsafePerformIO $ -         catch-          ( return $! force $ "input:                       " ++ show p ++ "\n" ++ "expect: " ++ s ++ "\n   got: " ++ showPat p )-          ( \e -> do let err = show (e :: ErrorCall)-                     return err )--    let eas = emptyPatNodeAttrs-    let neas = eas { depth = 23 }-    let peas = eas { doSpark = True }-    let pneas = neas { doSpark = True }-    let teas = eas { doConstrainType = True, typeConstraints = ["Int"] }-    let nteas = teas { depth = 23 }-    let pteas = teas { doSpark = True }-    let pnteas = nteas { doSpark = True }-    let teas2 = eas { doConstrainType = True, typeConstraints = ["[Int]"] }-    let pteas2 = teas2 { doSpark = True }-    let ptneas2 = pteas2 { depth = 23 }-    let xxptneas2 = ptneas2 { doTrace = True, doPing = True }-    let xxpeas = eas { doSpark = True, doTrace = True, doPing = True }--    putStrLn "\nTesting showPat"-    putStrLn "---------------"--    putStrLn $ shs "*" $ Node (WW eas) []-    putStrLn $ shs "." $ Node (WI eas) []-    putStrLn $ shs "!" $ Node (WS eas) []-    putStrLn $ shs "()" $ Node (WR eas) []-    putStrLn $ shs "(*)" $ Node (WR eas) [Node (WW eas) []]-    putStrLn $ shs "(**)" $ Node (WR eas) [Node (WW eas) [],Node (WW eas) []]-    putStrLn $ shs "(!*)" $ Node (WR eas) [Node (WS eas) [],Node (WW eas) []]-    putStrLn $ shs "(.!)" $ Node (WR eas) [Node (WI eas) [],Node (WS eas) []]-    putStrLn $ shs "(.)" $ Node (WR eas) [Node (WI eas) []]-    putStrLn $ shs "((.))" $ Node (WR eas) [Node (WR eas) [Node (WI eas) []]]-    putStrLn $ shs "(*.(*.(*.)**.*).*)" $ Node (WR eas) [Node (WW eas) [],Node (WI eas) [],Node (WR eas) [Node (WW eas) [],Node (WI eas) [],Node (WR eas) [Node (WW eas) [],Node (WI eas) []],Node (WW eas) [],Node (WW eas) [],Node (WI eas) [],Node (WW eas) []],Node (WI eas) [],Node (WW eas) []]-    putStrLn $ shs "(.!(*23*))" $ Node (WR eas) [Node (WI eas) [],Node (WS eas) [],Node (WR eas) [Node (WN neas) [],Node (WW eas) []]]-#if PARALLELISM_EXPERIMENT-    putStrLn $ shs "(.=(=*23*)*)" $ Node (WR eas) [Node (WI eas) [],Node (WR peas) [Node (WN pneas) [],Node (WW eas) []],Node (WW eas) []]-#endif-    putStrLn $ shs ":Int:()"    $ Node (TR teas)  []---- putStrLn $ shs ":Int:!"     $ Node (TS teas)  []-    putStrLn $ shs ":Int:*23"   $ Node (TN nteas) []-    putStrLn $ shs ":Int:*"     $ Node (TW teas)  []-    putStrLn $ shs ":Int:."     $ Node (TI teas)  []-    putStrLn $ shs "=:Int:()"    $ Node (TR pteas)  []---- putStrLn $ shs "=:Int:!"     $ Node (TS pteas)  []-    putStrLn $ shs "=:Int:*23"   $ Node (TN pnteas) []-    putStrLn $ shs "=:Int:*"     $ Node (TW pteas)  []-    putStrLn $ shs "=:Int:."     $ Node (TI pteas)  []-    putStrLn $ shs "=:[Int]:()"   $ Node (TR pteas2)  []-    putStrLn $ shs "=:[Int]:*"   $ Node (TW pteas2)  []-    putStrLn $ shs "=:[Int]:*23"   $ Node (TN ptneas2)  []-    putStrLn $ shs "=+^()"        $ Node (WR xxpeas)  []  -- canonical ordering---  putStrLn $ shs "+^=()"        $ Node (WR xxpeas)  []-    putStrLn $ shs "=+^:[Int]:*23"   $ Node (TN xxptneas2)  []----  let shp s = s ++ replicate (30 - length s) ' ' ++ show (compilePat s)-    let shp s = -         unsafePerformIO $ do-           putStr $ s ++ replicate (30 - length s) ' '-           catch-            ( return $! force $ show (compilePat s) )---          ( return $! force $ s ++ replicate (30 - length s) ' ' ++ show (compilePat s) )-            ( \e -> do let err = show (e :: ErrorCall)-                       return err )--    putStrLn "\nPattern                       Compiles to"-    putStrLn "-----------------------------------------"----  putStrLn $ shp ""  -- empty pattern syntax error-    putStrLn $ shp "."  -- Node WI []  -- no parent to absorb (should be error)-    putStrLn $ shp "!"  -- Node WS []-    putStrLn $ shp "*"  -- Node WW []-    putStrLn $ shp "*!"  -- "disconnected pattern (not rooted)"-    putStrLn $ shp "()"  -- Node WR []-    putStrLn $ shp "(.)"  -- Node WR [Node WW []]-    putStrLn $ shp "(*)"  -- Node WR [Node WW []]-    putStrLn $ shp "(**)"  -- Node WR [Node WW [],Node WW []]-    putStrLn $ shp "(!*)"  -- Node WR [Node WS [],Node WW []]-    putStrLn $ shp "(.!)"  -- Node WR [Node WI [],Node WS []]-    putStrLn $ shp "(.(.))"  -- Node WR [Node WI [],Node WR [Node WI []]]-    putStrLn $ shp "((.))"  -- Node WR [Node WR [Node WI []]]-    putStrLn $ shp "(.(().))"  -- Node WR [Node WI [],Node WR [Node WR [],Node WI []]]-    putStrLn $ shp "(*.*.*.**.*.*)"-    putStrLn $ shp "(*.(*.(*.)*)*(.*).*)"-    putStrLn $ shp "(*.(*.(*.)*)*.*)"-    putStrLn $ shp "(*.(*.(*.)*)(*)(.*).*)"-    putStrLn $ shp "((!(!)(((!).!(!))))!(!(!)))"  -- of leaky fame-    putStrLn $ shp "*23"-    putStrLn $ shp "(.!(*23*))"-    putStrLn $ shp ":Int:"  -- see what happens-    putStrLn $ shp ":Int:()"-    putStrLn $ shp ":Int:!"  -- see what happens-    putStrLn $ shp ":Int."  -- see what happens-    putStrLn $ shp ":Int:."-    putStrLn $ shp ":Int:*"-    putStrLn $ shp ":Int*23"  -- see what happens-    putStrLn $ shp ":Int:*23"-#if PARALLELISM_EXPERIMENT-    putStrLn $ shp "=."  -- Node WI [] (doSpark=True)-    putStrLn $ shp "=!"  -- Node WS [] (doSpark=True)-    putStrLn $ shp "=*"  -- Node WW [] (doSpark=True)-    putStrLn $ shp "(.=(=*23*)*)"-    putStrLn $ shp "=:Int"  -- see what happens-    putStrLn $ shp "=:Int:()"-    putStrLn $ shp "=:Int:!"  -- see what happens-    putStrLn $ shp "=:Int:."-    putStrLn $ shp "=:Int:*"-    putStrLn $ shp "=:Int*23"  -- see what happens-    putStrLn $ shp "=:Int:*23"-    putStrLn $ shp "=:[Int]:()"-    putStrLn $ shp "=:[Int]:*"-    putStrLn $ shp "=:[Int]:*23"-    putStrLn $ shp "=+^()"-    putStrLn $ shp "+^=()"-    putStrLn $ shp "=+^:[Int]:*23"-#endif-    putStrLn $ shp " ! :G; How:. : A ()$)%&()(*&)*(_)+\"}>>=?}{\\:|B ; C ; D E F : ( . . ) "--    putStrLn ""-#endif----  error "DEVEXIT"--#if ! FOCUS_TEST--#if 1-    let test_patterns10 = [-           (4,  "")  -- syntax error-         , (4,  "!..")  -- syntax error (disconnected pattern)-         , (1,  "(!..)")  -- fail-         , (5,  "(().().())")-         , (2,  "*")-         , (2,  "(***)")-         , (1,  "(...)")-         , (1,  "(*..)")-         , (2,  "(**.)")-         , (2,  "(..*)")--           -- Remember, [a] is a recursive binary ctor app!...-           -- The next four tests give instance errors for [a].-           -- (Later: Silent pattern-match failures, that is, because-           -- WARN_PATTERN_MATCH_FAILURE is False by default.)-           -- But if testing expTG_* (GNFDataP/grnfp) then-           -- it's no longer a list...-         , (13, "((*.*).)")-         , (13, "((*...).)")-         , (13, "((*....).)")-         , (13, "((*....)!)")  -- used to have "23" but that's incorrect--         , (1,  "((*.)*)")  -- used to have "2" but that's incorrect-         , (1,  "((*.).)")-         , (1,  "((*(.*)).)")-         , (1,  "((*(*.)).)")  -- used to have "2" but that's incorrect-         , (13, "((((.*))).)")  -- See above comment about [a] instance-         , (1,  "(.(((.*))).)")  -- used to have "2" but that's incorrect--           -- (See Book, p.84.)-         , (1,  "(!(!(.(!!))).)")-         , (1,  "(!(!(.*)).)")-         , (1,  "(*(*(.*)).)")-         , (2,  "(..*)")-         , (2,  "(*.*)")-         , (1,  ":Tuple3:(*(*(.*)).)")  -- oops...-         , (1,  ":(,,):(*(*(.*)).)")-         , (2,  ":(,,):(*(*(!*)).)")-         , (1,  ":Bool:(***)")  -- XXX makes no sense (but works) -- oh well;-                                -- this is an important point to note in-                                -- docs/blog also... [Later: old comment;-                                -- syntax has changed a lot since written...]-         , (4,  ":Bool*")  -- used to be 1, but now it's a syntax error-         , (1,  ":Bool:*")  -- new syntax requires terminating empty {}-         , (2,  ":(,,):*")-         , (2,  "(*.!)")---- XXX OLD COMMENT BUT BEWARE... XXX---   "This does what-- it says, it will only match a childless Bool node.---    Still need to implement # when not in type."--- Since {} are obligatory in the new grammar, for type-constrained * and #,--- better make sure the semantics are implemented as specified. (They are--- specified in the Pattern module Haddock API page.)--           -- New comment: Since #::typename can only choose-           -- between effectively behaving as either WI or WS,-           -- it is never recursive:  It forces at most one node!-         , (1,  "(*:Bool:..)")  -- was 2 which is incorrect-         , (1,  "(*:Int:..)")  -- was 2 which is incorrect-         , (1,  "(*:(,):..)")  -- was 2 which is incorrect-         , (1,  "(*:OutOfScopeType:..)")  -- was 2 which is incorrect-         , (1,  "(*:[Int]:..)")-         , (2,  "(*:[Int]:.!)")-         , (1,  "(*.:Bool:.)")-         , (2,  "(*.:Int:.)")-         , (2,  "(*.:(,):.)")-         , (2,  "(*.:OutOfScopeType:.)")-         , (2,  "(*.:[Int]:.)")--         , (2,  "(*:[Int]:*.)")-         , (1,  "(*:Bool:*.)")-         , (1,  "(*:Int:*.)")-         , (1,  "(*:(,):*.)")-         , (1,  "(*:OutOfScopeType:*.)")-         , (2,  "(*.:Bool:*)")-         , (1,  "(*.:Int:*)")-         , (1,  "(*.:(,):*)")--         , (1,  "(**2.)")-         , (2,  "(**3.)")-         , (1,  "(*:G2:..)")-         , (1,  "(*:Int:..)")-         ]-    doit14 True test_patterns10---  doit10 True test_patterns10-#endif--#if USE_SOP---- Seems fine; it's not a good test as the # in the middle--- only forces one ctor when type doesn't match, and need--- to force one more level to hit an undefined.-#if 1-    let test_patterns11 = [-           (4,  "")  -- syntax error--         , (1,  "(*:G2:..)")-         , (1,  "(*:Int:..)")-         ]-    doit15 True test_patterns11-#endif--#endif--#if USE_SOP--    -- exp = G2 5 __ 7 :: TG--- All fine last checked.-#if 1-    let test_patterns12 = [----         (4, "..")--           (2, "*")-         , (1, "*0")-         , (1, "*1")-         , (2, "*2")-         , (2, "*3")--         , (1, "(!.!)")-         , (2, "(!!!)")-         , (1, "(!!)")  -- due to patmatch failure-         , (2, "(!!!)")-         , (1, "(!!!!)")  -- due to patmatch failure--         , (1, ":G1:(!!)")-         , (1, ":G1:(!!!)")-         , (1, ":G2:(!!)")-         , (2, ":G2:(!!!)")-         , (1, ":TG:(!!!)")--         , (1, ":G1:*")-         , (2, ":G2:*")-         , (1, ":TG:*")-         , (2, ":Int:.")-         , (2, ":G1:.")-         , (1, ":G2:.")-         , (2, ":TG:.")-         , (1, ":Int:.")--         , (1, ":G1:.(!!)")  -- (used to be a syntax err)-         , (1, ":G1:*(!!)")  -- (used to be a syntax err)--         ]-    doit16 True test_patterns12----  error "DEVEXIT"-#endif--#endif--#if USE_SOP---- This should work, once the patterns are right for lists,--- but until I get non-list generic tests working I'm not--- going to struggle with this.-#if 0-    let test_patterns13 = [--- expTH_1 = H2 1 [H1 2.3, H3, H4 (H3, I3 I2 (H1 4.5))] False    (for ref.)--- expTH_4 = H2 1 [H1 2.3, H3, H4 (__, I3 __ (H1 4.5))] __       (in use)-           (4,  "")  -- syntax error-         , (1,  "(!(!(!((.(.!))!))).)")-         , (2,  "(!(!(!((!(.!))!))).)")-         , (2,  "(!(!(!((.(!!))!))).)")-         , (2,  "(!(!(!((.(.!))!)))!)")-         , (1,  "(!((!)(!((.(.(!)))!))).)")-         , (2,  "(!((!)(!((!(.(!)))!))).)")-         , (2,  "(!((!)(!((.(!(!)))!))).)")-         , (2,  "(!((!)(!((.(.(!)))!)))!)")-         , (2,  "(!((!)(!((.(.!(!)))!)))!)")-         ]-    doit17 True test_patterns13-#endif--#if 1-    let test_patterns14 = [--- expTJ_1 = J2 ( 1, J4 ( J3, K3 K2 ( J1 4.5))) False     -- for ref.--- expTJ_2 = J2 ( 1, J4 ( J3, K3 __ ( J1 4.5))) False--- expTJ_3 = J2 ( 1, J4 ( __, K3 K2 ( J1 4.5))) False--- expTJ_4 = J2 ( 1, J4 ( __, K3 __ ( J1 4.5))) __        -- in use---           {  { {} {  { {}  {  {} { {  {} }}}}}}}--- XXX The tuples are ctors, I forgot...-           (4 ,  "")  -- syntax error-#if 0-         , (1 ,  "!")-         , (13,  "()")-         , (13,  "(!)")-         , (2 ,  "(!!)")-         , (13,  "(!!!)")-         , (13,  "(!!!!)")-         , (13,  "(!!!!!)")-#endif--- expTJ_1 = J2 ( 1, J4 ( J3, K3 K2 ( J1 4.5))) False     -- for ref.---                J2 { (,) { I J4 { (,) { J3 K3 { K2 { J1 { 4.5 } } } } } } False }---                .  {  .  { .  . {  .  { .  .  {  . { .  { .   } } } } } } . }-           -- this pattern also double-checked on paper-         , (2 ,  "((!((!(!(!)))))!)")---       , (1 ,  "((!((!(.(!))))).)")  -- blows (in partic. expTJ_2)-         , (1 ,  "((!((.(!(!))))).)")  -- blows (in partic. expTJ_3)---       , (1 ,  "((!((.(.(!))))).)")  -- blows (in partic. expTJ_4)-#if 0-         , (1 ,  "((!(.(..(..(.))))).)")  -- = "((!(.)).)" (no blow)-         , (1 ,  "((!(.(.(.(!))))).)")  -- = "((!(.)).)" (no blow)-         , (1 ,  "((!(.(!(.(!))))).)")  -- = "((!(.)).)" (no blow)-         , (1 ,  "((!((!(.(!))))).)")  -- blows-         , (1 ,  "((!((..(..(.))))).)")  -- blows-         , (1 ,  "((!(.)).)")             -- confirming (no blow)-#endif-#if 0-         , (2 ,  "((!((!(((!))))))!)")-         , (1 ,  "((!((.(.((!)))))).)")-         , (1 ,  ".(.(..(.(..(.(.(.)))))).)")-         , (1 ,  "(.(..(.(..(.(.(.)))))).)")-         , (1 ,  "((..(.(..(.(.(.)))))).)")-         , (1 ,  "((!(.(..(.(.(.)))))).)")-#endif-#if 0-         , (1,  "(!(.(.(!))).)")-         , (2,  "(!(!(!(!)))!)")-         , (2,  "*")-         , (2,  "(!*!)")-         , (2,  "(***)")-#endif-         ]-    doit18 True test_patterns14-#endif--#if 1-    let test_patterns14b = [--- expTJ_5 = J2 ( 1, J4 ( __, K2 )) False-           (4 ,  "")  -- syntax error-         , (2 ,  "((!((!!)))!)")-         , (1 ,  "((!((.!)))!)")-         , (1 ,  "((!(.(!!)))!)")-         , (1 ,  "((!.((!!)))!)")-         ]-    doit18b True test_patterns14b-#endif--#if 1-    let test_patterns14c = [--- expTJ_6 = J4 ( __, K2 ) False-           (4 ,  "")  -- syntax error-         , (2 ,  "((!!))")-         , (1 ,  "((.!))")-         , (1 ,  "(.(!!))")-         , (1 ,  ".((!!))")-         ]-    doit18c True test_patterns14c-#endif--#if 1-    let test_patterns14d = [--- expTJ_7 = ( __, K2 )-           (4 ,  "")  -- syntax error-         , (2 ,  "(!!)")-         , (1 ,  "(.!)")-         , (1 ,  ".(!!)")-         ]-    doit18d True test_patterns14d-#endif--#if 1-    let test_patterns14e = [--- expTJ_8 = __ :: TJ-           (4 ,  "")  -- syntax error-         , (2 ,  "!")-         , (1 ,  ".")-         ]-    doit18e True test_patterns14e-#endif--#if 1-    let test_patterns14f = [--- expTJ_8 = (K5 (__::TJ))-           (4 ,  "")  -- syntax error-         , (1 ,  "!")-         , (1 ,  "(.)")-         , (2 ,  "(!)")-         , (1 ,  ".")-         ]-    doit18f True test_patterns14f-#endif---- These work!-#if 1-    let test_patterns14g = [-#if TRY_THIS--- exp = K3 (__::TK) J3-#else--- exp = K3 K2 (__::TJ)-#endif-           (4 ,  "")  -- syntax error-         , (1 ,  "!")-#if TRY_THIS-         , (1 ,  "(.!)")-         , (2 ,  "(!.)")-#else-         , (2 ,  "(.!)")-         , (1 ,  "(!.)")-#endif-         , (2 ,  "(!!)")-         , (1 ,  ".")-         ]-    doit18g True test_patterns14g-#endif---- Okay last I checked.-#if 1-    let test_patterns15 = [--- expTL_1 = L1 5.6 (M1 True)--- expTL_2 = L1 5.6 (M1 __)--- expTL_3 = L1 5.6 __--- expTL_4 = L1 __ (M1 True)-           (4 ,  "")  -- syntax error-#if 0-#elif 1-         , (1 ,  ".")-         , (5 ,  ".(!!)")-         , (1 ,  "(!!)")-         , (2 ,  "((!)!)")-         , (1 ,  "((.)!)")-#elif 0-         , (1 ,  ".")-         , (5 ,  ".(!!)")-         , (2 ,  "(!!)")-         , (1 ,  "(.(!))")-#elif 0-         , (1 ,  ".")-         , (5 ,  ".(!!)")-         , (2 ,  "(!!)")-         , (2 ,  "(!(!))")-         , (2 ,  "(!(.))")-#elif 0-         , (1 ,  ".")-         , (5 ,  ".(!!)")-         , (1 ,  "(!!)")-         , (2 ,  "(!(!))")-         , (1 ,  "(!(.))")-#endif-         ]-    doit19 True test_patterns15-#endif---- Good test case for the problem. No tuples; every step is generic.-#if 1-    let test_patterns16 = [--- expTK_1 = K3 K2 ( J1 4.5)     -- for ref.--- expTK_2 = K3 __ ( J1 4.5)---           {  {} { {  {} }}}--- XXX Don't forget tuples are ctors...-           (4 ,  "")  -- syntax error-#if 0-         , (2 ,  "(!!)")-         , (1 ,  "(.!)")-         , (2 ,  "(!.)")-         , (1 ,  "(..)")-#else-         , (2 ,  "(!(!))")  -- ok-         , (1 ,  "(..)")     -- X-         , (1 ,  "(.!)")     -- X-         , (1 ,  "(.(.))")  -- X-         , (1 ,  "(.(!))")  -- X-         , (2 ,  "(!.(!))")  -- X  & this does give the . with subpat. warning!-         , (2 ,  "(!.(.))")  -- X  & why no warning about . with subpattern?-         , (1 ,  "(..(.))")  -- X  & why no warning about . with subpattern?-         , (1 ,  ".(..(.))")  -- ok & why no warning about . with subpattern?-#endif-         ]-    doit20 True test_patterns16-#endif--#endif-------------------------------------------------#endif--#if 0 || ! FOCUS_TEST---- Later: Oh! Don't be silly -- it's all compile-time, and the--- size or shape of the list is irrelevant -- which rules--- will fire depends on THIS FILE'S SOURCE CODE (not it's--- data, including static values)!--- XXX Even with empty list, the same rule firings occur!...--- If comment out this block however, the rules do not fire!-#if 1-    -- Testing composition and union:-    let test_patterns11 = [-           (1, "!", "!")-         , (2, "!", "*")-         , (2, "*", "!")-         , (2, "*", "*")-         , (2, "(!!!)", "(*!!)")-         , (2, "(*!!)", "(!!*)")-         , (2, "(!*.)", "(!.!)")-         ]-    doit11 True test_patterns11-#endif--#endif--#if ! FOCUS_TEST--#if 1-    -- Testing splicePats-    let test_patterns12a = [-           (1, "!", [], [(0,"*")])-         , (1, "()", [], [(0,"*")])-         , (1, "!", [0], [(0,"*")])-         , (1, "(!!)", [], [(0,"*")])-         , (1, "(!!)", [0], [(0,"*")])-         , (1, "(!!)", [2], [(0,"*")])-         , (1, "(!!)", [], [(0,"*"),(0,".")])-         , (1, "(!!)", [], [(0,"*"),(1,".")])-         , (1, "(!!)", [], [(1,"."),(0,"*")])-         , (1, "(!!)", [], [(0,"*"),(2,".")])-         , (1, "(!!)", [], [(2,"*"),(2,"."),(2,".")])-         , (1, "(!!)", [], [(-1,"*")])-         , (1, "(!!)", [], [(0,"*")])-         , (1, "(!!)", [], [(1,"*")])-         , (1, "(!!)", [], [(2,"*")])-         , (1, "(!!)", [], [(3,"*")])-         , (1, "(!(!!)!)", [1], [(0,"*")])-         , (1, "(!(!!)!)", [1], [(0,"*3"),(1,"."),(2,"*")])-         , (1, "(!(!!)!)", [1,0], [(0,"*"),(0,".")])-         , (1, "((!!!)(()!)!)", [1], [(0,"*"),(0,".")])-         , (1, "((!!!)(()!)!)", [1,0], [(0,"*"),(0,".")])-         , (1, "((...)(().).)", [1,0], [(0,"*"),(0,".")])-         , (1, "(:(,,):(...)(().).)", [1,0], [(0,"*"),(0,".")])-         ]-    doit12 True test_patterns12a-#endif--#if 1-    -- Testing elidePats-    -- XXX There's a nice way to do this, by rewriting each test-    -- automatically (or via manual regex substitutions) so that-    -- the target is the result of the corresponding splicePats test.-    -- Unfortunately, the expected results are not encoded for-    -- the splicePats test, so oh well, for now at least, just-    -- build some fresh tests!-    let test_patterns12b = [-           (1, "((!!)!(!))", [], [0])-         , (1, "((!!)!(!))", [0], [0])-         , (1, "((!!)!(!))", [1], [0])-         , (1, "((!!)!(!))", [1], [1])-         ]-    doit12b True test_patterns12b-#endif--#endif--#if ! FOCUS_TEST--#if 1-    -- Testing erodePat-    -- XXX Note we toss the stdgen when done here...-    stdgen12c <- newStdGen---  let stdgen12c = mkStdGen seed-    let test_patterns12c = [-           (1, "((!!)!(!))", [])  -- recursive test...-         ]---  stdgen12c <- doit12c True test_patterns12c-#if 0-    stdgen12c' <- doit12c True test_patterns12c stdgen12c-    stdgen12c'' <- doit12c True test_patterns12c stdgen12c'-    stdgen12c''' <- doit12c True test_patterns12c stdgen12c''-    return ()-#else-#if 1-    stdgen12c' <- doit12c True test_patterns12c stdgen12c 5-    return ()-#else-    doit12c True test_patterns12c stdgen12c-      >>= doit12c True test_patterns12c-      >>= doit12c True test_patterns12c-      >>= doit12c True test_patterns12c-      >>= doit12c True test_patterns12c-      >>= doit12c True test_patterns12c-      >>= doit12c True test_patterns12c-      >>= doit12c True test_patterns12c-      >>= doit12c True test_patterns12c-#endif-#endif-#endif--#endif--#if 0 || ! FOCUS_TEST--#if 1-    -- Testing anything else we can with a single function!-    -- (Getting sick of this cloning.)-    -- Functions are listed in (current) export order.-    -- Things still needing testing are >'d.-    -- Things tested but failing some tests have a *.-    -- -    -- XXX Wow does this ever look cleaner with "Pat" instead of "Pattern"!...-    -- Fortunately splicePats is already tested separately; the rest-    -- we need to test deal only in Pat args (or list of same), so-    -- we can pass a couple [Pat] to test13 along with an Int code-    -- to control delegation.-    --  1    unionPats       :: [ Pat ] -> Pat-    --  2    intersectPats   :: [ Pat ] -> Pat-    --  3    subPat          :: Pat -> Pat -> Bool---  --  4    unionPatssStr   :: [ String ] -> String-    --  5    emptyPat        :: Pat-    --  6    mkPat           :: forall d. Data d => d -> Pat-    --  7    growPat         :: forall d. Data d => Pat -> d -> Pat-    --  8    shrinkPat       :: Pat -> Pat-    --  9    liftPats        :: [ Pat ] -> Pat-    -- 10    splicePats      :: Pat -> [Int] -> [(Int, Pat)] -> Pat-    -- 11    isPath          :: Pat -> Bool-    -- 12    mkPatN          :: Int -> Pat -> Bool-    -- 13    elidePats       :: Pat -> Pat -> [Int] -> Pat-    -- 14    erodePat        :: StdGen -> [Int] -> Pat -> (Pat, StdGen)-    let test_patterns13 = [-           ( 1, ["(!!!)", "(!.)"], "")-         , ( 2, ["(!!!)", "(!.)"], "")-         , ( 3, ["!", "!"], "True")-         , ( 3, [".", "."], "True")-         , ( 3, ["*", "*"], "True")-         , ( 3, ["!", "()"], "True")-         , ( 3, ["()", "!"], "False")-         , ( 3, ["()", "(!)"], "False")-         , ( 3, ["(!)", "(!)"], "True")-         , ( 3, ["(!)", "(!!)"], "False")-         , ( 3, ["(!)", "((!))"], "True")-         , ( 3, ["(!!)", "(!.)"], "False")-         , ( 3, ["(!.)", "(!!)"], "True")-         , ( 3, ["(!!)", "(!!!)"], "False")-         , ( 3, ["()", "(!!!)"], "False")-         , ( 3, ["!", "(*!.)"], "True")-         , ( 3, [".", "(*!.)"], "True")-         , ( 3, ["*", "(*!.)"], "False")-         , ( 3, ["*", "(*)"], "False")-         , ( 3, ["*", "(**)"], "False")-         , ( 4, ["(!!!)", "(!.)"], "")-         , ( 5, ["(!!!)", "(!.)"], "")-         , ( 6, ["(!!!)", "(!.)"], "")-         -- matching against val = ([1,2,3::Int],(False,"foo"))-         -- mkPat val = "((!(!(!!)))(!(!(!(!!)))))"-         , ( 7, ["((!(!!))(!(!!)))"], "")-         , ( 7, ["((!(!(!!)))(!(!(!!))))"], "")-         , ( 7, ["((!(!(!!)))(!(!(!(!!)))))"], "")-         , ( 8, ["((!(!(!!)))(!(!(!(!!)))))"], "")-         , ( 8, ["((!(!(!!)))(!(!(!!))))"], "")-         , ( 8, ["((!(!!))(!(!!)))"], "")-         , ( 8, ["((.(!!))(.(*3!)))"], "")-         , ( 8, ["((.!)(.!))"], "")-         , ( 8, ["(!!)"], "")-         , ( 8, ["!"], "")-         , ( 9, ["(!!!)", "(!.)"], "")-         , (10, ["(!!!)", "(!.)"], "")-         , (11, ["(!!!)", "(!.)"], "")-         , (12, ["(!!!)", "(!.)"], "")-    -- 12    mkPatN          :: Int -> Pat -> Bool-    -- 13    elidePats        :: Pat -> Pat -> [Int] -> Pat-    -- 14    erodePat        :: StdGen -> [Int] -> Pat -> (Pat, StdGen)-         ]-    putStrLn "==================================================="-    putStrLn "Testing miscellaneous PatUtil functions..."-    doit13 True test_patterns13-#endif--#endif--#if ! FOCUS_TEST--#if 1-    -- Testing fusion-    putStrLn "\nTesting fusion\n-fenable-rewrite-rules -O -ddump-rules -ddump-simpl-stats -ddump-rule-firings\n"-    let exp12 = (3.4, [5,__,7], __) :: (Float, [Int], Bool)-    let get12 (_,xs,_) = (xs!!2)-    putStrLn $ show $ get12 $ ( forcep ":Bool:*" . forcep ":Int:*" ) exp12-    putStrLn $ show $ get12 $ ( forcep ":Bool:*" . forcep_ (compilePat ":Int:*") ) exp12-    putStrLn $ show $ get12 $ ( forcep_ (compilePat ":Bool:*") . forcep ":Int:*" ) exp12-    putStrLn $ show $ get12 $ ( forcep_ (compilePat ":Bool:*") . forcep_ (compilePat ":Int:*") ) exp12-#endif--#if 1-    putStrLn $ intercalate "\n"-     [ ""-     , "expN_1 = [__] :: [Int]"-     , "expN_2 = [0,1,__,3] :: [Int]"-     , "expN_3 = (3.4, [5,__,7], True) :: (Float, [Int], Bool)"-     , "expN_4 = (3.4, [5,__,7], __) :: (Float, [Int], Bool)"-     , ""-     , "getN_1 xs = show $ ()"---   , "getN_1 xs = show $ head xs"---   , "getN_2 xs = show $ (xs!!1)"-     , "getN_2 xs = show $ (xs!!3)"-     , "getN_3 (_,xs,_) = show $ (xs!!2)"-     ]-    doit5 1 0 1 "" >>= putStrLn-    doit6 1 0 1 "" >>= putStrLn-    doit7 1 0 1 "" >>= putStrLn-    doit8 1 0 1 "" >>= putStrLn-#if 0-    doit9 >>= putStrLn  -- XXX broken (whatever it is)-#endif-#endif--#if 1-    putStr hdline-    putStrLn "Testing generic GNFDataN (refer to Foo.hs for the defs).\n"-    putStr hline-#if 0-#if ! USE_SOP-    putStrLn $ show $ from expTE_1-    putStrLn $ show $ from $ F 23-    putStrLn $ show $ from $ Just 11  -- bad comparison: two constructors!-#endif---  putStrLn $ show $ from $ Just (undefined::Int)---  putStrLn $ show $ from expTE_2---  putStrLn $ show $ from expTE_3-    putStr "\n"-    putStrLn $ ""-           ++ "expBase7 = B2 (A1 True 4) (B1 True (A2 undefined))\n"-           ++ "expBase8 = B2 (A1 undefined 4) (B1 True (A2 undefined))\n"-           ++ "expBase9 = B2 (A1 undefined 4) (B1 undefined (A2 undefined))\n"-           ++ "...\n"-           ++ "getB_1 (B2 _ (B1 b _)) = b\n"-           ++ "getB_2 (B2 (A1 _ n) _) = n\n"-#endif-    s2 <- doit2 1 0 1 ""-    putStrLn s2-#if 0-    putStrLn $ ""-           ++ "expTB_15 = (A3 (B3 False undefined 5) False)\n"-           ++ "getA (A3 _ b) = show b\n"-    s3 <- doit3 1 1 1 ""-    putStrLn s3-#endif-#endif--#if 0-    s4 <- doit4 1 0 1 ""-    putStrLn s4-#endif--#if 0-    putStrLn $ ""-           ++ "expBase1 = ([True,False],3,Just \"fox\")         :: ([Bool],Int,Maybe String)\n"-           ++ "expBase2 = ([True,False],__,Just \"fox\")        :: ([Bool],Int,Maybe String)\n"-           ++ "expBase3 = ([True,__],3,Just \"fox\")            :: ([Bool],Int,Maybe String)\n"-           ++ "expBase4 = ([True,__],3,Just __)               :: ([Bool],Int,Maybe String)\n"-           ++ "expBase5 = ([True,False],3,Just ['f',__,'x'])  :: ([Bool],Int,Maybe String)\n"-           ++ "expBase6 = ([True,False],3,Just __)            :: ([Bool],Int,Maybe String)\n"-           ++ "get1 ((x:_),_,_) = x           -- True\n"-           ++ "get2 (_,x,_) = x               -- 3\n"-           ++ "get3 (_,_,x) = fromJust x      -- \"fox\"\n"-           ++ "get4 (_,_,Just (x:_)) = x      -- 'f'\n"-    s1 <- doit1 1 1 1 ""-    putStrLn s1-#endif--#if USE_SOP--#if 1-    -- Testing rnfpDyn -- working-    putStrLn "\nTesting SOP rnfpDyn with SYB generic stop condition.\n"-#if 1-    let exp21 = (3.4, [5,__,7], __) :: (Float, [Int], Bool)-    let get21 (_,xs,_) = (xs!!2)-    let f21_a :: [Int] -> PatNode-        f21_a _ = WI emptyPatNodeAttrs-    let f21_b :: Bool -> PatNode-        f21_b _ = WI emptyPatNodeAttrs-    let fg21 :: GenericQ PatNode-        fg21 = mkQ (WR emptyPatNodeAttrs) f21_a `extQ` f21_b---  let fg21 = mkQ (WR emptyPatNodeAttrs) f21_a `extQ` f21_b :: forall a. Data a => a -> PatNode---  let fg21 = mkQ (WR emptyPatNodeAttrs) f21_a `extQ` f21_b :: GenericQ PatNode-    putStrLn $ show $ get21 $ forcepDyn fg21 exp21-#else-    let exp21 = (3.4, [5,__,7], False) :: (Float, [Int], Bool)-    let get21 (_,xs,_) = (xs!!2)-#if 0-#elif 1-    let f21 :: [Int] -> PatNode-        f21 _ = WI emptyPatNodeAttrs-    let fg21 :: GenericQ PatNode-        fg21 = mkQ (WR emptyPatNodeAttrs) f21-#elif 0-    let f21 :: (Float,[Int],Bool) -> PatNode-    -- Cannot do in SYB? We can't just "stop on any 3-tuple"; we need-    -- to give the types of the components of the tuple as well?---  let f21 :: (,,) a b c -> PatNode---  let f21 :: (,,) * * * -> PatNode---  let f21 :: (,,) -> PatNode---  let f21 :: (a,b,c) -> PatNode---  let f21 :: (Typeable a,Typeable b,Typeable c) => (a,b,c) -> PatNode---  let f21 :: (Data a,Typeable a,Data b,Typeable b,Data c,Typeable c) => (a,b,c) -> PatNode-        f21 _ = WI emptyPatNodeAttrs---      f21 (x,y,z) = WI emptyPatNodeAttrs-    let fg21 :: GenericQ PatNode-        fg21 = mkQ (WR emptyPatNodeAttrs) f21-#elif 0-    let f21 :: Int -> PatNode-        f21 x = WI emptyPatNodeAttrs---      f21 x = case x of { 5 -> WR emptyPatNodeAttrs ; _ -> WI emptyPatNodeAttrs }  -- "case x" forces x!---  let (f21::Int->PatNode) x = case x of { 5 -> WR emptyPatNodeAttrs ; _ -> WI emptyPatNodeAttrs }-    let fg21 :: GenericQ PatNode-        fg21 = mkQ (WR emptyPatNodeAttrs) f21-#endif-    putStrLn $ show $ get21 $ forcepDyn fg21 exp21-#endif-#endif--#if 1-    -- Testing rnfpDyn again -- not working...-    putStrLn "\nTesting SOP/SYB rnfpDyn again.\n"-#if 0-#elif 1-    let exp22 = [[[__]],[[__,6],[7]]] :: [[[Int]]]--- These three should be exactly equivalent (same core produced)?---  let get22 xs = (((xs!!1)!!1)!!0)---  let get22 [_,[[_,n],_]] = n-    let get22 (_:((_:n:_):_):_) = n-    let f22a :: Int -> PatNode-        f22a _ = trace "Noo-A" $ WI emptyPatNodeAttrs-    let f22b :: [Int] -> PatNode-        f22b _ = trace "Noo-B" $ WI emptyPatNodeAttrs-    let f22c :: [[Int]] -> PatNode-        f22c _ = trace "Noo-C" $ WI emptyPatNodeAttrs-    let f22d :: [[[Int]]] -> PatNode  -- goes boom-        f22d _ = trace "Noo-D" $ WI emptyPatNodeAttrs-    let fg22 :: GenericQ PatNode-        fg22 = mkQ (WR emptyPatNodeAttrs) id---                                                              -- blows---                                                 `extQ` f22d  -- blows-                                       `extQ` f22c `extQ` f22d  -- FINE---                         `extQ` f22b `extQ` f22c `extQ` f22d  -- FINE---             `extQ` f22a `extQ` f22b `extQ` f22c              -- blows---             `extQ` f22a `extQ` f22b `extQ` f22c `extQ` f22d  -- FINE-#elif 0-    let exp22 = [[[__]],[[__,6],__,[7]]] :: [[[Int]]]-    let get22 xs = (((xs!!1)!!2)!!0)-    let f22 :: Int -> PatNode        -- goes boom---  let f22 :: [Int] -> PatNode      -- goes boom---  let f22 :: [[Int]] -> PatNode    -- goes boom---  let f22 :: [[[Int]]] -> PatNode  -- goes boom-        f22 _ = trace "Noo-A" $ WI emptyPatNodeAttrs-    let fg22 :: GenericQ PatNode-        fg22 = mkQ (WR emptyPatNodeAttrs) f22-#else-    let exp22 = (3.4, [[[__]],[[__,6],__,[7]]], __) :: (Float, [[[Int]]], Bool)---  let exp22 = (3.4, [[__],[[__,6],__,[7]]], __) :: (Float, [[[Int]]], Bool)-    let get22 (_,xs,_) = (((xs!!1)!!2)!!0)-    let f22_a :: [[Int]] -> PatNode-        f22_a _ = WI emptyPatNodeAttrs-    let f22_b :: Bool -> PatNode-        f22_b _ = WI emptyPatNodeAttrs-    let fg22 :: GenericQ PatNode-        fg22 = mkQ (WR emptyPatNodeAttrs) f22_a `extQ` f22_b---  let fg22 = mkQ (WR emptyPatNodeAttrs) f22_a `extQ` f22_b :: forall a. Data a => a -> PatNode---  let fg22 = mkQ (WR emptyPatNodeAttrs) f22_a `extQ` f22_b :: GenericQ PatNode-#endif-    putStrLn $ show $ get22 $ forcepDyn fg22 exp22-#endif--#if 1-#if __GLASGOW_HASKELL__ >= 708--- XXX This isn't working yet.--- And it won't work naively either, b/c SOP is *shallow*...--- Note:--- *Foo> :m +Generics.SOP--- *Foo Generics.SOP> datatypeInfo (Proxy :: Proxy [[Int]])--- ADT "GHC.Types" "[]" (Constructor "[]" :* (Infix ":" RightAssociative 5 :* Nil))--- So, as done in GNFDataP, we need to pattern-match in tandem on this,--- through the *S and *P SOP recursion auxilliaries...--- XXX I came back to this -- getting type errors, could probably--- get rid of by adding extra functions (as per GNFDataP.hs code),--- but remember, this is supposed to be API-user code ... if it's--- going to be that painful to write, we have a problem...--- (Still, can probably write friendlier wrapper functions.)-    -- Testing rnfpDyn' with SOP generic stop condition-    putStrLn "\nTesting SOP rnfpDyn' with SOP generic stop condition.\n"-#if 0-#elif 1-    putStrLn $ doit23-#elif 0-    let exp23 = [[[__]],[[__,6],__,[7]]] :: [[[Int]]]-    let get23 xs = (((xs!!1)!!2)!!0)-    let fg23 :: forall a. (Generic a, HasDatatypeInfo a) => a -> PatNode-        fg23 d | cname == "[[Int]]"  = WI emptyPatNodeAttrs-               | otherwise           = WR emptyPatNodeAttrs-          where-#if 1-           ADT mname tname (Constructor cname :* _) = dti---         ADT mname tname (Constructor cname :* _) = dti :: DatatypeInfo (Code a)---         (mname,tname,cname) = case dti of ...---         ADT mname tname (Constructor cname :* (Infix ":" RightAssociative 5 :* Nil)) = dti-#endif-           dti = datatypeInfo proxy_a-           proxy_a = Proxy :: Proxy a-           xrep = from d-    putStrLn $ show $ get23 $ forcepDyn' fg23 exp23-#endif-#endif-#endif--#if 1--- Gave up on the fully-SOP one, at least for now, b/c--- it seems like it's hard to write (much uglier than SYB one),--- and then writing a friendly wrapper looks tough as well.--- But here is a 3rd alternative, hybrid SOP/Typeable which--- is even simpler from the user perspective, only less efficient.-    putStrLn "Testing SOP rnfpDyn'' with Typeable generic stop condition\n"-    let exp24 = [[[__]],[[__,6],__,[7]]] :: [[[Int]]]-    let get24 xs = (((xs!!1)!!2)!!0)-    let fg24 :: forall a. Typeable a => a -> PatNode-        fg24 d | t == "[[[Int]]]"  = WI emptyPatNodeAttrs-               | t == "[[Int]]"    = WI emptyPatNodeAttrs-               | otherwise         = WR emptyPatNodeAttrs-         where t = show $ typeOf d-    -- This is a simple alternative to the SOP/SYB hybrid.-    -- If efficiency isn't prime concern, this would appear to be-    -- even simpler ... the above looks much more lucid to me than-    -- the usual SYB way of mkQ/extQ; here, just define one normal-    -- function, and away you go...-    putStrLn $ show $ get24 $ forcepDyn'' fg24 exp24-#endif--#endif--#endif--#if ! FOCUS_TEST--#if 1-    putStrLn "\nTesting Seqable class (tuple with list):\n"-    let test_patterns24 = [-           (1,  1, (3.4, [5, __, 7], False))                        -- okay-         , (2,  2, fP (3.4, fP (5 : fP (__ : fP (7 : []))), __))    -- okay-         , (2,  3, fP (3.4, fP (5 : fI (__ : fP (7 : []))), __))    -- okay-         , (1,  4, fI (3.4, fP (5 : fI (__ : fP (7 : []))), __))    -- XXX-         , (1,  5, fI (3.4, fI (5 : fI (__ : fP (7 : []))), __))    -- okay-         , (2,  6, fI (3.4, fI (5 : fP (__ : fP (7 : []))), __))    -- okay-         , (1,  7, fI (3.4, fP (5 : fI (__ : fP (7 : []))), True))  -- XXX-         , (1,  8, fP (3.4, fI (5 : fI (__ : fP (7 : []))), True))  -- XXX-         , (1,  9, fP (3.4, fI (5 : fI (__ : fI (7 : []))), True))  -- XXX-         ] :: [(Int,Int,(Float,[Int],Bool))]-    doit24 True test_patterns24-#endif--#if 1-    putStrLn "\nTesting Seqable class (nested tuples):\n"-    let test_patterns25 = [-           (1,  1, (3.4, (__, 7), False))       -- okay-         , (1,  2, fI (3.4 ,fI (__, 7) ,__))    -- okay-         , (2,  3, fP (3.4 ,fP (__, 7) ,__))    -- XXX-         , (2,  4, fP (3.4 ,fI (__, 7) ,__))    -- XXX-         , (2,  5, fI (3.4 ,fP (__, 7) ,__))    -- XXX-         , (1,  6, fI (3.4 ,fI (__, 7) ,True))  -- okay-         , (2,  7, fP (3.4 ,fP (__, 7) ,True))  -- XXX-         , (1,  8, fP (3.4 ,fI (__, 7) ,True))  -- okay-         , (2,  9, fI (3.4 ,fP (__, 7) ,True))  -- XXX-         ] :: [(Int,Int,(Float,(Bool,Int),Bool))]-    doit25 True test_patterns25-#endif--#if USE_SOP--#if 1-    putStrLn "\nTesting generic Seqable (tuple with list):\n"-    let test_patterns26 = [-           (1,  1, (3.4, [5, __, 7], False))                        -- okay-         , (2,  2, gP (3.4, gP (5 : gP (__ : gP (7 : []))), __))    -- okay-         , (2,  3, gP (3.4, gP (5 : gI (__ : gP (7 : []))), __))    -- okay-         , (1,  4, gI (3.4, gP (5 : gI (__ : gP (7 : []))), __))    -- XXX-         , (1,  5, gI (3.4, gI (5 : gI (__ : gP (7 : []))), __))    -- okay-         , (2,  6, gI (3.4, gI (5 : gP (__ : gP (7 : []))), __))    -- okay-         , (1,  7, gI (3.4, gP (5 : gI (__ : gP (7 : []))), True))  -- XXX-         , (1,  8, gP (3.4, gI (5 : gI (__ : gP (7 : []))), True))  -- XXX-         , (1,  9, gP (3.4, gI (5 : gI (__ : gI (7 : []))), True))  -- XXX-         ] :: [(Int,Int,(Float,[Int],Bool))]-    doit26 True test_patterns26-#endif--#if 1-    putStrLn "\nTesting generic Seqable (expTJ_*):\n"--- expTJ_1 = J2 ( 1, J4 ( J3, K3 K2 ( J1 4.5))) False     -- for ref.--- expTJ_2 = J2 ( 1, J4 ( J3, K3 __ ( J1 4.5))) False--- expTJ_3 = J2 ( 1, J4 ( __, K3 K2 ( J1 4.5))) False--- expTJ_4 = J2 ( 1, J4 ( __, K3 __ ( J1 4.5))) __        -- in use-    let test_patterns27 = [-           (1,  1, gI (J2 (gI ( 1, gI (J4 (gI ( __, gI (K3 __ ( gI (J1 4.5)))))))) __))-         , (2,  2, gP (J2 (gP ( 1, gP (J4 (gP ( __, gP (K3 __ ( gP (J1 4.5)))))))) __))-         , (1,  3, gI (J2 (gP ( 1, gP (J4 (gI ( __, gI (K3 __ ( gP (J1 4.5)))))))) __))-         , (2,  4, gP (J2 (gP ( 1, gP (J4 (gI ( __, gI (K3 __ ( gP (J1 4.5)))))))) __))-         , (2,  5, gI (J2 (gP ( 1, gP (J4 (gP ( __, gI (K3 __ ( gP (J1 4.5)))))))) __))-         , (2,  6, gI (J2 (gP ( 1, gP (J4 (gI ( __, gP (K3 __ ( gP (J1 4.5)))))))) __))-         ] :: [(Int,Int,TJ)]-    doit27 True test_patterns27-#endif--#endif--#if 1-    putStrLn "\nTesting PatNodeAttrs (pattern node attributes):\n"-    -- exp = G2 5 __ 7 :: TG-    let test_patterns28 = [-#if 1-           (4,  "^^!")   -- syntax error-         , (4,  "^=^!")  -- syntax error-         , (2,  "=*")  -- XXX broken (at least in observability sense)-         , (2,  "+*")  -- fine (but see no trace message!)-         , (2,  "^*")  -- fine (but get no exception)-#if 1-         , (1,  "+^!")-         , (2,  "+^*")-         , (2,  "+^(.!.)")-         , (3,  "^+()")-         , (3,  "^+(!!)")-         , (2,  "^+(!!!)")-         , (3,  "^+(!!!!)")-#else--- Later: This is now working -- too well, and the first / encountered--- puts an end to the testing!-         , (2,  "/*")  -- fine (but no indication of termination)-         , (1,  "/+^!")-         , (2,  "/+^*")-         , (2,  "/+^(.!.)")-         , (3,  "^+/()")-         , (3,  "^+/(!!)")-         , (2,  "^+/(!!!)")-         , (3,  "^+/(!!!!)")-#endif-#else-           (4,  "^^!")   -- syntax error-         , (4,  "^=^!")  -- syntax error-         , (3,  "^=()")-         , (3,  "^=(!!)")-         , (2,  "^=(!!!)")-         , (3,  "^=(!!!!)")---       , (1,  "/=+^!")---       , (2,  "/=+^*")       -- XXX---       , (2,  "/=+^(.!.)")   -- XXX-         , (2,  "*")-         , (2,  "(.!.)")-         , (2,  "=*")  -- XXX broken (at least in observability sense)-         , (2,  "+*")  -- fine (but see no trace message!)-         , (2,  "^*")  -- fine (but get no exception)---       , (2,  "/*")  -- fine (but no indication of termination)---       , (2,  "/+^(.!.)")  -- fine-#endif-         ]-    doit28 True test_patterns28-#endif--#if 1-    putStrLn "\nTesting PatNodeAttrs (pattern node attributes):\n"-    -- exp = ([0..999999],[1000000..1999999]),[2000000..3999999])-    let test_patterns29 = [-           (1,  "+( +>ba(+*+*)=+*)")-         , (1,  "+(=+>ba(+*+*) +*)")---       , (1,  "(>ba(+*+*)+=*)")-         ]-    doit29 True test_patterns29-#endif--#endif--    putStrLn "\n"--    return 0-----------------------------------------------------------------------------------  hline :: String-  hline = "---------------------------------------------------\n"-  hdline :: String-  hdline = "===================================================\n"-----------------------------------------------------------------------------------  doit1 :: Int -> Int -> Int -> String -> IO String-  doit1 i j k acc-   -- this glitch (the exception that seemingly escapes my catch)-   -- happens just for these combos (and for all j):--- | i == 3 && k == 4  = doit1 (1+i) j k acc  -- trying to avoid a glitch...--- | i == 3 && k == 5  = doit1 (1+i) j k acc  -- trying to avoid a glitch...--- | i == 3 && j < 4 && k == 5  = doit1 (1+i) j k acc  -- trying to avoid a glitch...-   | k == 7  = return acc-   | j == 6  = doit1 1 1 (1+k) acc-   | i == 5  = doit1 1 (1+j) k acc-   | otherwise  = do-      fexp <- catch-               -- The semantics of the !'s here are not what they were,-               -- since forcing in some places. [?] But at least the-               -- first one seems definitely still needed...-               -- LATER: The second one is also needed, finally seen!-               -- (It is needed for a version of getE _ = "getee", only.)-               -- XXX I'm just not sure whether the second ! is better-               -- to leave in or leave out...-               ( return $! get $! forcen dep exp )-               (\e -> do let err = show (e :: ErrorCall)---             (\e -> do let err = show (e :: BottomedOut)-                         return err)---    doit1 (1+i) j k $! force $ acc-      doit1 (1+i) j k $! acc---    doit1 (1+i) j k $ acc-        ++ "( get" ++ show i ++ " $ forcen " ++ show dep ++ " expBase" ++ show k ++ " )  "-        ++ fexp ++ "\n"-   where-    exp = case k of-            1 -> expBase1-            2 -> expBase2-            3 -> expBase3-            4 -> expBase4-            5 -> expBase5-            6 -> expBase6-    get = case i of-           1 -> get1-           2 -> get2---         3 -> unsafePerformIO . get3  -- yeesh!...---         3 -> get3-           3 -> get3 (i,j,k)-           4 -> get4-    dep = j--  -- XXX All this fuss to deal with the case that the-  -- entire argument m is undefined (or whatever is going-  -- for "undefined" at the moment...) -- but, none of-  -- the expBase[1-5] have this! ch.-  myFromJust :: Maybe a -> IO (Either () a)-  myFromJust m = do-                    putStrLn "Boo!"-                    catch-                      (myFromJust' m)-                      (\e -> do putStrLn $! show (e::BottomedOut)-                                putStrLn "HERE!"-                                return $! Left ())-  myFromJust' :: Maybe a -> IO (Either () a)-  myFromJust' Nothing = do---                         throw BottomedOut-                           return $! Left ()-  myFromJust' (Just x) = return $! Right x---myFromJust _ = throw BottomedOut------------------------------------  doit2 :: Int -> Int -> Int -> String -> IO String-  doit2 i j k acc--- | k == 2  = {- trace (show (i,j,k)) $ -} return acc--- | k == 7  = return acc-   | k == 27  = return acc--- | k == 21  = return acc--- | k == 5  = return acc--- | j == 15  = doit2 1 0 (1+k) acc-   | j == 11  = {- trace (show (i,j,k)) $ -} doit2 1 0 (1+k) acc--- | j == 8  = {- trace (show (i,j,k)) $ -} doit2 1 0 (1+k) acc--- | j == 3  = {- trace (show (i,j,k)) $ -} doit2 1 0 (1+k) acc-#if USE_TRACE-   | i == 2  = trace ("End of " ++ show (i,j',k')) $ doit2 1 (1+j) k acc--- | i == 3  = trace ("End of " ++ show (i,j',k')) $ doit2 1 (1+j) k acc-#else-   | i == 2  = doit2 1 (1+j) k acc--- | i == 3  = doit2 1 (1+j) k acc-#endif-   | otherwise  = do-      fexp <- catch-               ( return $! get $! forcen dep exp )---             ( return $! get $! forcen dep exp )-               -- ErrorCall if use __ = undefined-               -- BottomedOut if use __ = throw BottomedOut-               (\e -> do let err = show (e :: ErrorCall)---             (\e -> do let err = show (e :: BottomedOut)-                         return err)-      doit2 (1+i) j k $! acc-        ++ "( getB_" ++ show i ++ " $ forcen " ++ show dep ++ (if dep < 10 then " " else "") ++ " expTB_" ++ show (k'-6) ++ " )  "---      ++ "( getB_" ++ show i ++ " $ forcen " ++ show dep ++ (if dep < 10 then " " else "") ++ " expBase" ++ show k' ++ " )  "-        ++ fexp ++ "\n"-   where-    exp = case k' of-            7 -> expBase7-            8 -> expBase8-            9 -> expBase9-            10 -> expBase10-            11 -> expBase11-            12 -> expBase12-            13 -> expBase13-            14 -> expBase14-            15 -> expBase15-            16 -> expBase16-            17 -> expBase17-            18 -> expBase18-            19 -> expBase19-            20 -> expBase20-            21 -> expBase20  -- fudge it!!-            22 -> expBase22-            23 -> expBase23-            24 -> expBase24-            25 -> expBase25-            26 -> expBase26-            27 -> expBase27-            28 -> expBase28-            29 -> expBase29-            30 -> expBase30-            31 -> expBase31-            32 -> expBase32-    get = case i of-           1 -> if k' >= 27 then getB_3 else getB_1-           2 -> getB_2-    dep = j'-    j' = j---  j' = j+11---  k' = k+26-    k' = k+6--  doit3 :: Int -> Int -> Int -> String -> IO String-  doit3 i j k acc-   | k == 2  = return acc-   | j == 8  = {- trace (show (i,j,k)) $ -} doit3 1 1 (1+k) acc-#if USE_TRACE-   | i == 2  = trace ("End of " ++ show (i,j',k')) $ doit3 1 (1+j) k acc-#else-   | i == 2  = doit3 1 (1+j) k acc-#endif-   | otherwise  = do-      fexp <- catch-               ( return $! get $! forcen dep exp )-               -- ErrorCall if use __ = undefined-               -- BottomedOut if use __ = throw BottomedOut-               (\e -> do let err = show (e :: ErrorCall)---             (\e -> do let err = show (e :: BottomedOut)-                         return err)-      doit3 (1+i) j k $! acc-        ++ "( getB_" ++ show i ++ " $ forcen " ++ show dep ++ " expBase" ++ show k' ++ " )  "-        ++ fexp ++ "\n"-   where-    exp = case k' of-            21 -> expBase21-    get = case i of-           1 -> getA-    dep = j'-    i' = i-    j' = j-    k' = k+20--  doit4 :: Int -> Int -> Int -> String -> IO String-  doit4 i j k acc--- | k == 2  = return acc-   | k == 4  = return acc-   | j == 8  = {- trace (show (i,j,k)) $ -} doit4 1 0 (1+k) acc-#if USE_TRACE-   | i == 2  = trace ("End of " ++ show (i,j',k')) $ doit4 1 (1+j) k acc-#else-   | i == 2  = doit4 1 (1+j) k acc-#endif-   | otherwise  = do-      fexp <- catch-               ( return $! get $! forcen dep exp )-               -- ErrorCall if use __ = undefined-               -- BottomedOut if use __ = throw BottomedOut-               (\e -> do let err = show (e :: ErrorCall)---             (\e -> do let err = show (e :: BottomedOut)-                         return err)-      doit4 (1+i) j k $! acc-        ++ "( getE $ forcen " ++ show dep ++ " expTE_" ++ show k' ++ " )  "-        ++ fexp ++ "\n"-   where-    exp = case k' of-            1 -> expTE_1-            2 -> expTE_2-            3 -> expTE_3-    get = case i of-           1 -> getE-    dep = j'-    i' = i-    j' = j-    k' = k-----------------------------------------------------------------------------------  doit5 :: Int -> Int -> Int -> String -> IO String-  doit5 i j k acc-   | k == 2  = return acc-   | j == 5  = {- trace (show (i,j,k)) $ -} doit5 1 0 (1+k) acc-#if USE_TRACE-   | i == 2  = trace ("End of " ++ show (i,j',k')) $ doit5 1 (1+j) k acc-#else-   | i == 2  = doit5 1 (1+j) k acc-#endif-   | otherwise  = do-      fexp <- catch-               ( return $! get $! forcen dep exp )-               -- ErrorCall if use __ = undefined-               -- BottomedOut if use __ = throw BottomedOut-               (\e -> do let err = show (e :: ErrorCall)---             (\e -> do let err = show (e :: BottomedOut)-                         return err)-      doit5 (1+i) j k $! acc-        ++ "forcen " ++ show dep ++ " expN_" ++ show k' ++ " `seq` ()  =  "-        ++ fexp ++ "\n"-   where-    exp = case k' of-            1 -> expN_1-    get = case i of-           1 -> getN_1-    dep = j'-    i' = i-    j' = j-    k' = k-----------------------------------------------------------------------------------  doit6 :: Int -> Int -> Int -> String -> IO String-  doit6 i j k acc-   | k == 2  = return acc-   | j == 5  = {- trace (show (i,j,k)) $ -} doit6 1 0 (1+k) acc-#if USE_TRACE-   | i == 2  = trace ("End of " ++ show (i',j',k')) $ doit6 1 (1+j) k acc-#else-   | i == 2  = doit6 1 (1+j) k acc-#endif-   | otherwise  = do-      fexp <- catch-               ( return $! get $! forcen dep exp )-               -- ErrorCall if use __ = undefined-               -- BottomedOut if use __ = throw BottomedOut-               (\e -> do let err = show (e :: ErrorCall)---             (\e -> do let err = show (e :: BottomedOut)-                         return err)-      doit6 (1+i) j k $! acc-        ++ "getN_" ++ show i' ++" $ forcen " ++ show dep ++ " expN_" ++ show k' ++ "  =  "-        ++ fexp ++ "\n"-   where-    exp = case k' of-            _ -> expN_2-    get = case i of-           _ -> getN_2-    dep = j'-    i' = i+1-    j' = j-    k' = k+1-----------------------------------------------------------------------------------  doit7 :: Int -> Int -> Int -> String -> IO String-  doit7 i j k acc-   | k == 2  = return acc-   | j == 5  = {- trace (show (i,j,k)) $ -} doit7 1 0 (1+k) acc-#if USE_TRACE-   | i == 2  = trace ("End of " ++ show (i',j',k')) $ doit7 1 (1+j) k acc-#else-   | i == 2  = doit7 1 (1+j) k acc-#endif-   | otherwise  = do-      fexp <- catch-               ( return $! get $! forcen dep exp )-               -- ErrorCall if use __ = undefined-               -- BottomedOut if use __ = throw BottomedOut-               (\e -> do let err = show (e :: ErrorCall)---             (\e -> do let err = show (e :: BottomedOut)-                         return err)-      doit7 (1+i) j k $! acc-        ++ "getN_" ++ show i' ++" $ forcen " ++ show dep ++ " expN_" ++ show k' ++ "  =  "-        ++ fexp ++ "\n"-   where-    exp = case k' of-            _ -> expN_3-    get = case i of-           _ -> getN_3-    dep = j'-    i' = i+2-    j' = j-    k' = k+2-----------------------------------------------------------------------------------  doit8 :: Int -> Int -> Int -> String -> IO String-  doit8 i j k acc-   | k == 2  = return acc-   | j == 5  = {- trace (show (i,j,k)) $ -} doit8 1 0 (1+k) acc-#if USE_TRACE-   | i == 2  = trace ("End of " ++ show (i',j',k')) $ doit8 1 (1+j) k acc-#else-   | i == 2  = doit8 1 (1+j) k acc-#endif-   | otherwise  = do-      fexp <- catch-               ( return $! get $! forcen dep exp )-               -- ErrorCall if use __ = undefined-               -- BottomedOut if use __ = throw BottomedOut-               (\e -> do let err = show (e :: ErrorCall)---             (\e -> do let err = show (e :: BottomedOut)-                         return err)-      doit8 (1+i) j k $! acc-        ++ "getN_" ++ show i' ++" $ forcen " ++ show dep ++ " expN_" ++ show k' ++ "  =  "-        ++ fexp ++ "\n"-   where-    exp = case k' of-            _ -> expN_4-    get = case i of-           _ -> getN_3-    dep = j'-    i' = i+2-    j' = j-    k' = k+3-----------------------------------------------------------------------------------#if 0--#if 0-  expP_1 = (3.4, [5,__,7], __) :: (Float, [Int], Bool)-  patP_1 = Node (TR [typeOf ((__,__,__)::(Float, [Int], Bool))])-             [ Node (TR [typeOf (__::Bool)]) []---           [ Node (TR [typeOf (__::Float)]) []---           [ Node (NTR [typeOf (__::Bool)]) []---           [ Node (NTR [typeOf (__::Float)]) []---           , Node WS []-             , Node (TW [typeOf ([__]::[Int])]) []---           , Node (TR [typeOf ([__]::[Int])]) []---           , Node (TR [typeOf ([__]::[Int])]) [ Node WS [], Node WS [] ]  -- why not?-             , Node WW []---           , Node I []-             ]-  getP_1 (_,xs,_) = show $ (xs!!2)-#endif--  doit9 :: IO String-  doit9 = do-#if 0-    putStrLn $ intercalate "\n"-     [ ""-     , "expP_1 = (3.4, [5,__,7], __) :: (Float, [Int], Bool)"-     , "patP_1 = Node (T [typeOf ((__,__,__)::(Float, [Int], Bool))])"-     , "           [ Node W []"-     , "           , Node (T [typeOf ([__]::[Int])]) []"-     , "           , Node I []"-     , "           ]"-     , "getP_1 (_,xs,_) = show $ (xs!!2)"-     ]-    putStrLn "getP_1 $ forcep patP_1 expP_1"-#endif-    s <- catch-             ( return $! getP_1 $! forcep patP_1 expP_1 )---           ( return $! getP_2 $! forcep patP_2 expP_2 )---           ( return $! getP_3 $! forcep patP_3 expP_3 )-             -- ErrorCall if use __ = undefined-             -- BottomedOut if use __ = throw BottomedOut-             (\e -> do let err = show (e :: ErrorCall)---           (\e -> do let err = show (e :: BottomedOut)-                       return err)-    return s--#endif-----------------------------------------------------------------------------------  doit10 :: Bool -> [(Int,String)] -> IO ()-  doit10 _ [] = do-                   putStrLn "--------------------------------------------------"-                   return ()-  doit10 b ((code,patstr):t) = do-    let expect = case code of-                  1 -> "7"-                  2 -> "Prelude.undefined"-                  3 -> "pattern-match failure"-                  4 -> "syntax error"-                  5 -> "7 (but \"# with subpattern\" warning)"-                  6 -> "7 (but \"constraint/subpattern arity mismatch\" warning)"-#if WARN_PATTERN_MATCH_FAILURE-                  13 -> "7 (but with pattern-match failure warning)"-                  23 -> "Prelude.undefined (but with pattern-match failure warning)"-#else-                  13 -> "7 (with silent pattern-match failure)"-                  23 -> "Prelude.undefined (with silent pattern-match failure)"-#endif-                  _ -> error $ "doit10: unexpected code " ++ show code-    s <- catch-           ( do-                let exp = (3.4, [5,__,7], __) :: (Float, [Int], Bool)-                let pat = compilePat patstr-                let get (_,xs,_) = show $ (xs!!2)-                if b-                then do-                  putStrLn "==================================================="-                  putStrLn "exp = (3.4, [5,__,7], __) :: (Float, [Int], Bool)"-                  putStrLn "get (_,xs,_) = show $ (xs!!2)"-                  putStrLn "? = get $ forcep patstr exp"-                  putStrLn "==================================================="-                else do-                  putStrLn "---------------------------------------------------"-                putStrLn $ "patstr                   = " ++ patstr-                if code > 4-                then putStrLn $  "expected value           = " ++ expect-                else return ()---              putStrLn $ "pat = " ++ show pat-                putStrLn $ "showPat.compilePat       = " ++ showPat pat-                if code <= 4-                then putStrLn $  "expected value           = " ++ expect-                else return ()-                s1 <- catch-                        ( return $! force $! get $! forcep patstr exp )-                        (\e -> do let err = show (e :: ErrorCall)---                      (\e -> do let err = show (e :: BottomedOut)-                                  return err)-                putStr "actual value             = "-                return $! s1-           )-           -- ErrorCall if use __ = undefined-           -- BottomedOut if use __ = throw BottomedOut-           (\e -> do let err = show (e :: ErrorCall)---         (\e -> do let err = show (e :: BottomedOut)-                     return err)-    putStrLn s-    doit10 False t-----------------------------------------------------------------------------------  doit11 :: Bool -> [(Int,String,String)] -> IO ()-  doit11 _ [] = do-                   putStrLn "--------------------------------------------------"-                   return ()-  doit11 b ((code,patstr1,patstr2):t) = do-    let expect = case code of-                  1 -> "7"-                  2 -> "Prelude.undefined"-                  3 -> "pattern-match failure"-                  4 -> "syntax error"-                  5 -> "7 (but \"# with subpattern\" warning)"-                  6 -> "7 (but \"constraint/subpattern arity mismatch\" warning)"-                  _ -> error $ "doit11: unexpected code " ++ show code-    s <- catch-           ( do-                let exp = (3.4, [5,__,7], __) :: (Float, [Int], Bool)-                let patstrU = showPat $ unionPats [compilePat patstr1, compilePat patstr2]-                let pat1 = compilePat patstr1-                let pat2 = compilePat patstr2-                let patU = unionPats [pat1,pat2]-                let get (_,xs,_) = show $ (xs!!2)-                if b-                then do-                  putStrLn "==================================================="-                  putStrLn "exp = (3.4, [5,__,7], __) :: (Float, [Int], Bool)"-                  putStrLn "get (_,xs,_) = show $ (xs!!2)"-                  putStrLn "? = get $ ( forcep patstr2 . forcep patstr1 ) exp"---                putStrLn "? = get $ ( forcep ( unionPatsStr [ patstr1, patstr2 ] ) ) exp"-                  putStrLn "? = get $! ( forcep_ ( unionPats [ pat1, pat2 ] ) ) exp"-                  putStrLn "(Results were more interesting with a previous semantics...)."-                  putStrLn "==================================================="-                else do-                  putStrLn "---------------------------------------------------"-                putStrLn $ "patstr1                     = " ++ patstr1-                putStrLn $ "patstr2                     = " ++ patstr2-                putStrLn $ "patstrU                     = " ++ patstrU-                if code > 4-                then putStrLn $  "expected value              = " ++ expect-                else return ()---              putStrLn $ "pat = " ++ show pat-                putStrLn $ "showPat.compilePat patstr1  = " ++ showPat pat1-                putStrLn $ "showPat.compilePat patstr2  = " ++ showPat pat2-                putStrLn $ "showPat.compilePat patstrU  = " ++ showPat patU-                if code <= 4-                then putStrLn $  "expected value              = " ++ expect-                else return ()-                putStr "actual value                = "-                let s1 = get $! ( forcep patstr2 . forcep patstr1 ) exp-                putStrLn s1-                putStr "actual value                = "-                let s2 = get $! forcep patstrU exp-#if 1-                let s3 = s2-#else-                putStrLn s2-                let s3 = get $! forcep_ ( unionPats [ pat1, pat2 ] ) exp-#endif-                return $! s3-           )-           -- ErrorCall if use __ = undefined-           -- BottomedOut if use __ = throw BottomedOut-           (\e -> do let err = show (e :: ErrorCall)---         (\e -> do let err = show (e :: BottomedOut)-                     return err)-    putStrLn s-    doit11 False t-----------------------------------------------------------------------------------  doit12 :: Bool -> [(Int,String,[Int],[(Int,String)])] -> IO ()---doit12 :: Bool -> [(Int,String,String,[(Int,String)])] -> IO ()-  doit12 _ [] = do-                   return ()-  doit12 b ((code,patstr1,path,isibs'):t) = do-    let expect = case code of-                  1 -> "7"-                  2 -> "Prelude.undefined"-                  3 -> "pattern-match failure"-                  4 -> "syntax error"-                  5 -> "7 (but \"# with subpattern\" warning)"-                  6 -> "7 (but \"constraint/subpattern arity mismatch\" warning)"-                  _ -> error $ "doit12: unexpected code " ++ show code-    s <- catch-           ( do-                let target = compilePat patstr1---              let path = compilePat patstr2-                let isibs = map (\ (x,y) -> (x,compilePat y)) isibs'-                if b-                then do-                  putStr hdline-                  putStrLn "Testing splicePats."-                  putStr hline-                else return ()-                putStrLn $ "target       " ++ patstr1-                putStrLn $ "path         " ++ show path---              putStrLn $ "path         " ++ patstr2-                putStrLn $ "isibs        " ++ show isibs'-                let s1 = force $ showPat $ splicePats target path isibs---              let s1 = showPat $! splicePats target path isibs---              let s1 = showPat $ splicePats target path isibs-                putStr "result       "-                return $! s1-           )-           -- ErrorCall if use __ = undefined-           -- BottomedOut if use __ = throw BottomedOut-           (\e -> do let err = show (e :: ErrorCall)---         (\e -> do let err = show (e :: BottomedOut)-                     return err)-    putStrLn s-    if null t then return () else putStr hline-    doit12 False t-----------------------------------------------------------------------------------  doit12b :: Bool -> [(Int,String,[Int],[Int])] -> IO ()-  doit12b _ [] = do-                   return ()-  doit12b b ((code,patstr1,path,isibs'):t) = do-    let expect = case code of-                  1 -> "7"-                  2 -> "Prelude.undefined"-                  3 -> "pattern-match failure"-                  4 -> "syntax error"-                  5 -> "7 (but \"# with subpattern\" warning)"-                  6 -> "7 (but \"constraint/subpattern arity mismatch\" warning)"-                  _ -> error $ "doit12b: unexpected code " ++ show code-    s <- catch-           ( do-                let target = compilePat patstr1-                let isibs = isibs'-                if b-                then do-                  putStr hdline-                  putStrLn "Testing elidePats."-                  putStr hline-                else return ()-                putStrLn $ "target       " ++ patstr1-                putStrLn $ "path         " ++ show path-                putStrLn $ "isibs        " ++ show isibs'-                let s1 = force $ showPat $ elidePats target path isibs-                putStr "result       "-                return $! s1-           )-           -- ErrorCall if use __ = undefined-           -- BottomedOut if use __ = throw BottomedOut-           (\e -> do let err = show (e :: ErrorCall)---         (\e -> do let err = show (e :: BottomedOut)-                     return err)-    putStrLn s-    if null t then return () else putStr hline-    doit12b False t-----------------------------------------------------------------------------------  -- This is the first recursive test [much later than "12" would suggest].-  doit12c :: Bool -> [(Int,String,[Int])] -> StdGen -> Int -> IO StdGen---doit12c :: Bool -> [(Int,String,[Int],Int)] -> StdGen -> IO StdGen---doit12c :: Bool -> [(Int,String,StdGen,[Int],Int)] -> IO StdGen---doit12c :: Bool -> [(Int,String,StdGen,[Int],Int)] -> IO ()-  doit12c _ [] g _ = do-                   return g---                 return ()-  doit12c b lst@((code,patstr1,path):t) g 0 = return g-  doit12c b lst@((code,patstr1,path):t) g nreps = do  -- but singleton expected?-    let expect = case code of-                  1 -> "7"-                  2 -> "Prelude.undefined"-                  3 -> "pattern-match failure"-                  4 -> "syntax error"-                  5 -> "7 (but \"# with subpattern\" warning)"-                  6 -> "7 (but \"constraint/subpattern arity mismatch\" warning)"-                  _ -> error $ "doit12c: unexpected code " ++ show code-    (s, g') <- catch---  s <- catch-           ( do-                let target = compilePat patstr1-                if b-                then do-                  putStr hdline-                  putStrLn "Testing erodePat."-                  putStr hline-                else return ()-                putStrLn $ "target       " ++ patstr1-                putStrLn $ "stdgen       " ++ show g-                putStrLn $ "path         " ++ show path-                let (rslt, g') = erodePat g path target-                let s1 = force $ showPat $ rslt---              let s1 = force $ showPat $ erodePat g path target-                putStr "result       "-                return $! (s1, g')---              return $! s1-           )-           -- ErrorCall if use __ = undefined-           -- BottomedOut if use __ = throw BottomedOut-           (\e -> do let err = show (e :: ErrorCall)---         (\e -> do let err = show (e :: BottomedOut)-                     return (err, g))---                   return err)-    putStrLn s-    putStr hline-    doit12c False lst g' (-1+nreps)---  doit12c False t g' (-1+nreps)-----------------------------------------------------------------------------------  doit13 :: Bool -> [(Int,[String],String)] -> IO ()-  doit13 _ [] = do-                   putStr hline-                   return ()-  doit13 b ((code,patstrlst,expectstr):t) = do-    s <- catch-           ( do-                s1 <- case code of--- Where were they done already?--- Oh, in doit11 and doit12 above...-                       1 -> error $ hline ++ "unionPats test already done test13-1!"---                     4 -> error $ hline ++ "unionPatsStr test already done test13-4!"-                       10 -> error $ hline ++ "splicePats test already done test13-10!"-                       11 -> error $ hline ++ "isPath test already done test13-11!"-    --  1    unionPats       :: [ Pat ] -> Pat-    --  2  * intersectPats   :: [ Pat ] -> Pat-    --  3  * subPat          :: Pat -> Pat -> Bool---  --  4    unionPatsStr    :: [ String ] -> String-    --  5  * emptyPat        :: Pat-    --  6  * mkPat           :: forall d. Data d => d -> Pat-    --  7  * growPat         :: forall d. Data d => Pat -> d -> Pat-    --  8  * shrinkPat       :: Pat -> Pat-    --  9  * liftPats        :: [ Pat ] -> Pat-    -- 10    splicePats      :: Pat -> Pat -> [(Int, Pat)] -> Pat-    -- 11    isPath          :: Pat -> Bool-                       2 -> do-                               let patA = patstrlst!!0-                               let patB = patstrlst!!1-                               putStr hline-                               putStrLn "Testing      intersectPats [patA, patB]"-                               putStrLn $ "patA         " ++ patA-                               putStrLn $ "patB         " ++ patB-                               putStr $ "result       "-                               let s1 = force $ showPat $ intersectPats [compilePat patA, compilePat patB]-                               return s1-                       3 -> do-                               let patA = patstrlst!!0-                               let patB = patstrlst!!1-                               putStr hline-                               putStrLn "Testing      subPat patA patB"-                               putStrLn $ "patA         " ++ patA-                               putStrLn $ "patB         " ++ patB-                               let s1 = force $ show $ subPat (compilePat patA) (compilePat patB)-                               if s1 /= expectstr-                               then do putStrLn $ "expect       " ++ expectstr-                                       putStr $ "result       "-                               else putStr $ "as expected  "-                               return s1-                       5 -> do-                               putStr hline-                               putStrLn "Testing      emptyPat"-                               putStr $ "result       "-                               let s1 = force $ showPat $ emptyPat-                               return s1-                       6 -> do-                               putStr hline-                               putStrLn "Testing      mkPat ([1,2,3],(False,\"foo\"))"-                               putStr $ "result       "-                               let s1 = force $ showPat $ mkPat ([1,2,3::Int],(False,"foo"))-                               return s1-                       7 -> do-                               let patA = patstrlst!!0-                               putStr hline-                               putStrLn "Testing      growPat patA ([1,2,3],(False,\"foo\"))"-                               putStrLn $ "patA         " ++ patA-                               putStr $ "result       "-                               let s1 = force $ showPat $ growPat (compilePat patA) ([1,2,3::Int],(False,"foo"))-                               return s1-                       8 -> do-                               let patA = patstrlst!!0-                               putStr hline-                               putStrLn "Testing      shrinkPat patA"-                               putStrLn $ "patA         " ++ patA-                               putStr $ "result       "-                               let s1 = force $ showPat $ shrinkPat (compilePat patA)-                               return s1-                       9 -> do-                               putStr hline-                               putStrLn "Testing      liftPats patstrlst"-                               putStrLn $ "patstrs      " ++ show patstrlst-                               putStr $ "result       "-                               let s1 = force $ showPat $ liftPats $ map compilePat patstrlst-                               return s1-    -- 12    mkPatN          :: Int -> Pat -> Bool-    -- 13    elidePats        :: Pat -> Pat -> [Int] -> Pat-    -- 14    erodePat        :: StdGen -> [Int] -> Pat -> (Pat, StdGen)-                       12 -> do-                               putStr hline-                               putStrLn "Testing      mkPatN 2 ([1,2,3],(False,\"foo\"))"-                               putStr $ "result       "-                               let s1 = force $ showPat $ mkPatN 2 ([1,2,3::Int],(False,"foo"))-                               return s1-                       _ -> error $ "doit13: unexpected code " ++ show code-                return $! s1-           )-           -- ErrorCall if use __ = undefined-           -- BottomedOut if use __ = throw BottomedOut-           (\e -> do let err = show (e :: ErrorCall)---         (\e -> do let err = show (e :: BottomedOut)-                     return err)-    putStrLn s-    doit13 False t-----------------------------------------------------------------------------------  doit14 :: Bool -> [(Int,String)] -> IO ()-  doit14 _ [] = do-                   putStrLn "--------------------------------------------------"-                   return ()-  doit14 b ((code,patstr):t) = do-    let expect = case code of-                  1 -> "7"-                  2 -> "Prelude.undefined"-                  3 -> "pattern-match failure"-                  4 -> "syntax error"-                  5 -> "7 (but \"# with subpattern\" warning)"-                  6 -> "7 (but \"constraint/subpattern arity mismatch\" warning)"-#if WARN_PATTERN_MATCH_FAILURE-                  13 -> "7 (but with pattern-match failure warning)"-                  23 -> "Prelude.undefined (but with pattern-match failure warning)"-#else-                  13 -> "7 (with silent pattern-match failure)"-                  23 -> "Prelude.undefined (with silent pattern-match failure)"-#endif-                  _ -> error $ "doit14: unexpected code " ++ show code-    s <- catch-           ( do-                let exp = (3.4, [5,__,7], __) :: (Float, [Int], Bool)-                let pat = compilePat patstr-                let get (_,xs,_) = show $ (xs!!2)-                if b-                then do-                  putStrLn "==================================================="-                  putStrLn "exp = (3.4, [5,__,7], __) :: (Float, [Int], Bool)"-                  putStrLn "get (_,xs,_) = show $ (xs!!2)"-                  putStrLn "? = get $ forcep patstr exp"-                  putStrLn "==================================================="-                else do-                  putStrLn "---------------------------------------------------"-                putStrLn $ "patstr                   = " ++ patstr-                if code > 4-                then putStrLn $  "expected value           = " ++ expect-                else return ()---              putStrLn $ "pat = " ++ show pat-                putStrLn $ "showPat.compilePat       = " ++ showPat pat-                if code <= 4-                then putStrLn $  "expected value           = " ++ expect-                else return ()-                s1 <- catch-                        ( return $! force $! get $! forcep patstr exp )-                        (\e -> do let err = show (e :: ErrorCall)---                      (\e -> do let err = show (e :: BottomedOut)-                                  return err)-                putStr "actual value             = "-                return $! s1-           )-           -- ErrorCall if use __ = undefined-           -- BottomedOut if use __ = throw BottomedOut-           (\e -> do let err = show (e :: ErrorCall)---         (\e -> do let err = show (e :: BottomedOut)-                     return err)-    putStrLn s-    doit14 False t-----------------------------------------------------------------------------------#if USE_SOP--  -- This is an adaptation of doit10 to user-defined datatypes,-  -- for testing GNFDataP, which is finally within reach thanks-  -- to SOP!-  doit15 :: Bool -> [(Int,String)] -> IO ()-  doit15 _ [] = do-                   putStrLn "--------------------------------------------------"-                   return ()-  doit15 b ((code,patstr):t) = do-    let expect = case code of-                  1 -> "7"-                  2 -> "Prelude.undefined"-                  3 -> "pattern-match failure"-                  4 -> "syntax error"-                  5 -> "7 (but \"# with subpattern\" warning)"-                  6 -> "7 (but \"constraint/subpattern arity mismatch\" warning)"-#if WARN_PATTERN_MATCH_FAILURE-                  13 -> "7 (but with pattern-match failure warning)"-                  23 -> "Prelude.undefined (but with pattern-match failure warning)"-#else-                  13 -> "7 (with silent pattern-match failure)"-                  23 -> "Prelude.undefined (with silent pattern-match failure)"-#endif-                  _ -> error $ "doit15: unexpected code " ++ show code-    s <- catch-           ( do-                let exp = expTG_5  -- ( G1, G2 5 __ 7, __ )---              let exp = expTG_4  -- ( G1, G2 5 6 7, __ )---              let exp = expTG_3  -- ( G1, G2 __ __ 7, __ )---              let exp = expTG_2  -- ( __, G2 __ __ 7, __ )---              let exp = expTG_1  -- ( G1, G2 5 6 7, True )---              let exp = (3.4, [5,__,7], __) :: (Float, [Int], Bool)-                let pat = compilePat patstr-                let get = getG---              let get (_,xs,_) = show $ (xs!!2)-                if b-                then do-                  putStrLn "==================================================="-                  putStrLn "exp = (G1, G2 5 __ 7, __) :: (TG, TG, Bool)"-                  putStrLn "get (_,(G2 _ _ n),_) = n"-                  putStrLn "? = get $ forcep patstr exp"-                  putStrLn "==================================================="-                else do-                  putStrLn "---------------------------------------------------"-                putStrLn $ "patstr                   = " ++ patstr-                if code > 4-                then putStrLn $  "expected value           = " ++ expect-                else return ()---              putStrLn $ "pat = " ++ show pat-                putStrLn $ "showPat.compilePat       = " ++ showPat pat-                if code <= 4-                then putStrLn $  "expected value           = " ++ expect-                else return ()-                s1 <- catch-                        ( return $! force $! get $! forcep patstr exp )-                        (\e -> do let err = show (e :: ErrorCall)---                      (\e -> do let err = show (e :: BottomedOut)-                                  return err)-                putStr "actual value             = "-                return $! s1-           )-           -- ErrorCall if use __ = undefined-           -- BottomedOut if use __ = throw BottomedOut-           (\e -> do let err = show (e :: ErrorCall)---         (\e -> do let err = show (e :: BottomedOut)-                     return err)-    putStrLn s-    doit15 False t-----------------------------------------------------------------------------------  doit16 :: Bool -> [(Int,String)] -> IO ()-  doit16 _ [] = do-                   putStrLn "--------------------------------------------------"-                   return ()-  doit16 b ((code,patstr):t) = do-    let expect = case code of-                  1 -> "7"-                  2 -> "Prelude.undefined"-                  3 -> "pattern-match failure"-                  4 -> "syntax error"-                  5 -> "7 (but \"# with subpattern\" warning)"-                  6 -> "7 (but \"constraint/subpattern arity mismatch\" warning)"-#if WARN_PATTERN_MATCH_FAILURE-                  13 -> "7 (but with pattern-match failure warning)"-                  23 -> "Prelude.undefined (but with pattern-match failure warning)"-#else-                  13 -> "7 (with silent pattern-match failure)"-                  23 -> "Prelude.undefined (with silent pattern-match failure)"-#endif-                  _ -> error $ "doit16: unexpected code " ++ show code-    s <- catch-           ( do-                let exp = expTG_6  -- G2 5 __ 7-                let pat = compilePat patstr-                let get = getG'-                if b-                then do-                  putStrLn "==================================================="-                  putStrLn "exp = G2 5 __ 7 :: TG"-                  putStrLn "get (G2 _ _ n) = n"-                  putStrLn "? = get $ forcep patstr exp"-                  putStrLn "==================================================="-                else do-                  putStrLn "---------------------------------------------------"-                putStrLn $ "patstr                   = " ++ patstr-                if code > 4-                then putStrLn $  "expected value           = " ++ expect-                else return ()---              putStrLn $ "pat = " ++ show pat-                putStrLn $ "showPat.compilePat       = " ++ showPat pat-                if code <= 4-                then putStrLn $  "expected value           = " ++ expect-                else return ()-                s1 <- catch-                        ( return $! force $! get $! forcep patstr exp )-                        (\e -> do let err = show (e :: ErrorCall)---                      (\e -> do let err = show (e :: BottomedOut)-                                  return err)-                putStr "actual value             = "-                return $! s1-           )-           -- ErrorCall if use __ = undefined-           -- BottomedOut if use __ = throw BottomedOut-           (\e -> do let err = show (e :: ErrorCall)---         (\e -> do let err = show (e :: BottomedOut)-                     return err)-    putStrLn s-    doit16 False t-----------------------------------------------------------------------------------  doit17 :: Bool -> [(Int,String)] -> IO ()-  doit17 _ [] = do-                   putStrLn "--------------------------------------------------"-                   return ()-  doit17 b ((code,patstr):t) = do-    let expect = case code of-                  1 -> "4.5"-                  2 -> "Prelude.undefined"-                  3 -> "4.5 (due to pattern-match failure)"-                  4 -> "syntax error"-                  5 -> "4.5 (but \"# with subpattern\" warning)"-                  6 -> "4.5 (but \"constraint/subpattern arity mismatch\" warning)"-#if WARN_PATTERN_MATCH_FAILURE-                  13 -> "7 (but with pattern-match failure warning)"-                  23 -> "Prelude.undefined (but with pattern-match failure warning)"-#else-                  13 -> "7 (with silent pattern-match failure)"-                  23 -> "Prelude.undefined (with silent pattern-match failure)"-#endif-                  _ -> error $ "doit17: unexpected code " ++ show code-    s <- catch-           ( do---              let exp = expTH_1  -- H2 1 [H1 2.3, H3, H4 (H3, I3 I2 (H1 4.5))] False---              let exp = expTH_2  -- H2 1 [H1 2.3, H3, H4 (__, I3 I2 (H1 4.5))] False---              let exp = expTH_3  -- H2 1 [H1 2.3, H3, H4 (__, I3 I2 (H1 4.5))] __-                let exp = expTH_4  -- H2 1 [H1 2.3, H3, H4 (__, I3 __ (H1 4.5))] __-                let pat = compilePat patstr-                let get = getH-                if b-                then do-                  putStrLn "==================================================="-                  putStrLn "exp = H2 1 [H1 2.3, H3, H4 (__, I3 I2 (H1 4.5))] __ :: TH"---                putStrLn "exp = H2 1 [H1 2.3, H3, H4 (H3, I3 I2 (H1 4.5))] False :: TH"-                  putStrLn "get = (H2 _ [_, _, H4 (_, I3 _ (H1 f))] _) = show f"-                  putStrLn "? = get $ forcep patstr exp"-                  putStrLn "==================================================="-                else do-                  putStrLn "---------------------------------------------------"-                putStrLn $ "patstr                   = " ++ patstr-                if code > 4-                then putStrLn $  "expected value           = " ++ expect-                else return ()---              putStrLn $ "pat = " ++ show pat-                putStrLn $ "showPat.compilePat       = " ++ showPat pat-                if code <= 4-                then putStrLn $  "expected value           = " ++ expect-                else return ()-                s1 <- catch-                        ( return $! force $! get $! forcep patstr exp )-                        (\e -> do let err = show (e :: ErrorCall)---                      (\e -> do let err = show (e :: BottomedOut)-                                  return err)-                putStr "actual value             = "-                return $! s1-           )-           -- ErrorCall if use __ = undefined-           -- BottomedOut if use __ = throw BottomedOut-           (\e -> do let err = show (e :: ErrorCall)---         (\e -> do let err = show (e :: BottomedOut)-                     return err)-    putStrLn s-    doit17 False t-----------------------------------------------------------------------------------  doit18 :: Bool -> [(Int,String)] -> IO ()-  doit18 _ [] = do-                   putStrLn "--------------------------------------------------"-                   return ()-  doit18 b ((code,patstr):t) = do-    let expect = case code of-                  1 -> "4.5"-                  2 -> "Prelude.undefined"-                  3 -> "4.5 (due to pattern-match failure)"-                  4 -> "syntax error"-                  5 -> "4.5 (but \"# with subpattern\" warning)"-                  6 -> "4.5 (but \"constraint/subpattern arity mismatch\" warning)"-#if WARN_PATTERN_MATCH_FAILURE-                  13 -> "7 (but with pattern-match failure warning)"-                  23 -> "Prelude.undefined (but with pattern-match failure warning)"-#else-                  13 -> "7 (with silent pattern-match failure)"-                  23 -> "Prelude.undefined (with silent pattern-match failure)"-#endif-                  _ -> error $ "doit18: unexpected code " ++ show code-    s <- catch-           ( do---              let exp = expTJ_1  -- J2 (1, J4 (J3, K3 K2 (J1 4.5))) False---              let exp = expTJ_2  -- J2 (1, J4 (J3, K3 __ (J1 4.5))) False-                let exp = expTJ_3  -- J2 (1, J4 (__, K3 K2 (J1 4.5))) False---              let exp = expTJ_4  -- J2 (1, J4 (__, K3 __ (J1 4.5))) __-                let pat = compilePat patstr-                let get = getJ-                if b-                then do-                  putStrLn "==================================================="---                putStrLn "exp = J2 (1, J4 (J3, K3 K2 (J1 4.5))) False"-                  putStrLn "exp = J2 (1, J4 (J3, K3 __ (J1 4.5))) False"---                putStrLn "exp = J2 (1, J4 (__, K3 K2 (J1 4.5))) False"---                putStrLn "exp = J2 (1, J4 (__, K3 __ (J1 4.5))) __"-                  putStrLn "get = (J2 (_, J4 (_, K3 _ (J1 f))) _) = show f"-                  putStrLn "? = get $ forcep patstr exp"-                  putStrLn "==================================================="-                else do-                  putStrLn "---------------------------------------------------"-                putStrLn $ "patstr                   = " ++ patstr-                if code > 4-                then putStrLn $  "expected value           = " ++ expect-                else return ()---              putStrLn $ "pat = " ++ show pat-                putStrLn $ "showPat.compilePat       = " ++ showPat pat-                if code <= 4-                then putStrLn $  "expected value           = " ++ expect-                else return ()-                s1 <- catch-                        ( return $! force $! get $! forcep patstr exp )-                        (\e -> do let err = show (e :: ErrorCall)---                      (\e -> do let err = show (e :: BottomedOut)-                                  return err)-                putStr "actual value             = "-                return $! s1-           )-           -- ErrorCall if use __ = undefined-           -- BottomedOut if use __ = throw BottomedOut-           (\e -> do let err = show (e :: ErrorCall)---         (\e -> do let err = show (e :: BottomedOut)-                     return err)-    putStrLn s-    doit18 False t-----------------------------------------------------------------------------------  doit18b :: Bool -> [(Int,String)] -> IO ()-  doit18b _ [] = do-                   putStrLn "--------------------------------------------------"-                   return ()-  doit18b b ((code,patstr):t) = do-    let expect = case code of-                  1 -> "1"-                  2 -> "Prelude.undefined"-                  3 -> "1 (due to pattern-match failure)"-                  4 -> "syntax error"-                  5 -> "1 (but \"# with subpattern\" warning)"-                  6 -> "1 (but \"constraint/subpattern arity mismatch\" warning)"-#if WARN_PATTERN_MATCH_FAILURE-                  13 -> "7 (but with pattern-match failure warning)"-                  23 -> "Prelude.undefined (but with pattern-match failure warning)"-#else-                  13 -> "7 (with silent pattern-match failure)"-                  23 -> "Prelude.undefined (with silent pattern-match failure)"-#endif-                  _ -> error $ "doit18b: unexpected code " ++ show code-    s <- catch-           ( do-                let exp = expTJ_5  -- J2 (1, J4 (__, K2)) False-                let pat = compilePat patstr-                let get = getJ'-                if b-                then do-                  putStrLn "==================================================="-                  putStrLn "exp = J2 (1, J4 (__, K2)) False"-                  putStrLn "get ~_ = show 1  -- seems to suffice?!?..."---                putStrLn "get (J2 (n, J4 (_, K2)) False) = show n"-                  putStrLn "? = get $ forcep patstr exp"-                  putStrLn "==================================================="-                else do-                  putStrLn "---------------------------------------------------"-                putStrLn $ "patstr                   = " ++ patstr-                if code > 4-                then putStrLn $  "expected value           = " ++ expect-                else return ()---              putStrLn $ "pat = " ++ show pat-                putStrLn $ "showPat.compilePat       = " ++ showPat pat-                if code <= 4-                then putStrLn $  "expected value           = " ++ expect-                else return ()-                s1 <- catch-                        ( return $! force $! get $! forcep patstr exp )-                        (\e -> do let err = show (e :: ErrorCall)---                      (\e -> do let err = show (e :: BottomedOut)-                                  return err)-                putStr "actual value             = "-                return $! s1-           )-           -- ErrorCall if use __ = undefined-           -- BottomedOut if use __ = throw BottomedOut-           (\e -> do let err = show (e :: ErrorCall)---         (\e -> do let err = show (e :: BottomedOut)-                     return err)-    putStrLn s-    doit18b False t-----------------------------------------------------------------------------------  doit18c :: Bool -> [(Int,String)] -> IO ()-  doit18c _ [] = do-                   putStrLn "--------------------------------------------------"-                   return ()-  doit18c b ((code,patstr):t) = do-    let expect = case code of-                  1 -> "1"-                  2 -> "Prelude.undefined"-                  3 -> "1 (due to pattern-match failure)"-                  4 -> "syntax error"-                  5 -> "1 (but \"# with subpattern\" warning)"-                  6 -> "1 (but \"constraint/subpattern arity mismatch\" warning)"-#if WARN_PATTERN_MATCH_FAILURE-                  13 -> "7 (but with pattern-match failure warning)"-                  23 -> "Prelude.undefined (but with pattern-match failure warning)"-#else-                  13 -> "7 (with silent pattern-match failure)"-                  23 -> "Prelude.undefined (with silent pattern-match failure)"-#endif-                  _ -> error $ "doit18c: unexpected code " ++ show code-    s <- catch-           ( do-                let exp = expTJ_6  -- J4 (__, K2)-                let pat = compilePat patstr-                let get = getJ6-                if b-                then do-                  putStrLn "==================================================="-                  putStrLn "exp = J4 (__, K2)"-                  putStrLn "get ~_ = show 1  -- seems to suffice?!?..."---                putStrLn "get (J4 (_, K2)) = show n"-                  putStrLn "? = get $ forcep patstr exp"-                  putStrLn "==================================================="-                else do-                  putStrLn "---------------------------------------------------"-                putStrLn $ "patstr                   = " ++ patstr-                if code > 4-                then putStrLn $  "expected value           = " ++ expect-                else return ()---              putStrLn $ "pat = " ++ show pat-                putStrLn $ "showPat.compilePat       = " ++ showPat pat-                if code <= 4-                then putStrLn $  "expected value           = " ++ expect-                else return ()-                s1 <- catch-                        ( return $! force $! get $! forcep patstr exp )-                        (\e -> do let err = show (e :: ErrorCall)---                      (\e -> do let err = show (e :: BottomedOut)-                                  return err)-                putStr "actual value             = "-                return $! s1-           )-           -- ErrorCall if use __ = undefined-           -- BottomedOut if use __ = throw BottomedOut-           (\e -> do let err = show (e :: ErrorCall)---         (\e -> do let err = show (e :: BottomedOut)-                     return err)-    putStrLn s-    doit18c False t-----------------------------------------------------------------------------------  doit18d :: Bool -> [(Int,String)] -> IO ()-  doit18d _ [] = do-                   putStrLn "--------------------------------------------------"-                   return ()-  doit18d b ((code,patstr):t) = do-    let expect = case code of-                  1 -> "1"-                  2 -> "Prelude.undefined"-                  3 -> "1 (due to pattern-match failure)"-                  4 -> "syntax error"-                  5 -> "1 (but \"# with subpattern\" warning)"-                  6 -> "1 (but \"constraint/subpattern arity mismatch\" warning)"-#if WARN_PATTERN_MATCH_FAILURE-                  13 -> "7 (but with pattern-match failure warning)"-                  23 -> "Prelude.undefined (but with pattern-match failure warning)"-#else-                  13 -> "7 (with silent pattern-match failure)"-                  23 -> "Prelude.undefined (with silent pattern-match failure)"-#endif-                  _ -> error $ "doit18d: unexpected code " ++ show code-    s <- catch-           ( do-                let exp = expTJ_7  -- (__, K2)-                let pat = compilePat patstr-                let get = getJ7-                if b-                then do-                  putStrLn "==================================================="-                  putStrLn "exp = (__, K2)"-                  putStrLn "get ~_ = show 1  -- seems to suffice?!?..."-                  putStrLn "? = get $ forcep patstr exp"-                  putStrLn "==================================================="-                else do-                  putStrLn "---------------------------------------------------"-                putStrLn $ "patstr                   = " ++ patstr-                if code > 4-                then putStrLn $  "expected value           = " ++ expect-                else return ()---              putStrLn $ "pat = " ++ show pat-                putStrLn $ "showPat.compilePat       = " ++ showPat pat-                if code <= 4-                then putStrLn $  "expected value           = " ++ expect-                else return ()-                s1 <- catch-                        ( return $! force $! get $! forcep patstr exp )-                        (\e -> do let err = show (e :: ErrorCall)---                      (\e -> do let err = show (e :: BottomedOut)-                                  return err)-                putStr "actual value             = "-                return $! s1-           )-           -- ErrorCall if use __ = undefined-           -- BottomedOut if use __ = throw BottomedOut-           (\e -> do let err = show (e :: ErrorCall)---         (\e -> do let err = show (e :: BottomedOut)-                     return err)-    putStrLn s-    doit18d False t-----------------------------------------------------------------------------------  doit18e :: Bool -> [(Int,String)] -> IO ()-  doit18e _ [] = do-                   putStrLn "--------------------------------------------------"-                   return ()-  doit18e b ((code,patstr):t) = do-    let expect = case code of-                  1 -> "1"-                  2 -> "Prelude.undefined"-                  3 -> "1 (due to pattern-match failure)"-                  4 -> "syntax error"-                  5 -> "1 (but \"# with subpattern\" warning)"-                  6 -> "1 (but \"constraint/subpattern arity mismatch\" warning)"-#if WARN_PATTERN_MATCH_FAILURE-                  13 -> "7 (but with pattern-match failure warning)"-                  23 -> "Prelude.undefined (but with pattern-match failure warning)"-#else-                  13 -> "7 (with silent pattern-match failure)"-                  23 -> "Prelude.undefined (with silent pattern-match failure)"-#endif-                  _ -> error $ "doit18e: unexpected code " ++ show code-    s <- catch-           ( do-                let exp = expTJ_8  -- __ :: TJ-                let pat = compilePat patstr-                let get = getJ8-                if b-                then do-                  putStrLn "==================================================="-                  putStrLn "exp = __ :: TJ"-                  putStrLn "get ~_ = show 1  -- seems to suffice?!?..."-                  putStrLn "? = get $ forcep patstr exp"-                  putStrLn "==================================================="-                else do-                  putStrLn "---------------------------------------------------"-                putStrLn $ "patstr                   = " ++ patstr-                if code > 4-                then putStrLn $  "expected value           = " ++ expect-                else return ()---              putStrLn $ "pat = " ++ show pat-                putStrLn $ "showPat.compilePat       = " ++ showPat pat-                if code <= 4-                then putStrLn $  "expected value           = " ++ expect-                else return ()-                s1 <- catch-                        ( return $! force $! get $! forcep patstr exp )-                        (\e -> do let err = show (e :: ErrorCall)---                      (\e -> do let err = show (e :: BottomedOut)-                                  return err)-                putStr "actual value             = "-                return $! s1-           )-           -- ErrorCall if use __ = undefined-           -- BottomedOut if use __ = throw BottomedOut-           (\e -> do let err = show (e :: ErrorCall)---         (\e -> do let err = show (e :: BottomedOut)-                     return err)-    putStrLn s-    doit18e False t-----------------------------------------------------------------------------------  doit18f :: Bool -> [(Int,String)] -> IO ()-  doit18f _ [] = do-                   putStrLn "--------------------------------------------------"-                   return ()-  doit18f b ((code,patstr):t) = do-    let expect = case code of-                  1 -> "okay"-                  2 -> "Prelude.undefined"-                  3 -> "okay (due to pattern-match failure)"-                  4 -> "syntax error"-                  5 -> "okay (but \"# with subpattern\" warning)"-                  6 -> "okay (but \"constraint/subpattern arity mismatch\" warning)"-#if WARN_PATTERN_MATCH_FAILURE-                  13 -> "7 (but with pattern-match failure warning)"-                  23 -> "Prelude.undefined (but with pattern-match failure warning)"-#else-                  13 -> "7 (with silent pattern-match failure)"-                  23 -> "Prelude.undefined (with silent pattern-match failure)"-#endif-                  _ -> error $ "doit18f: unexpected code " ++ show code-    s <- catch-           ( do-                let exp = (K5 (__::TJ))-                let pat = compilePat patstr-                let get _ = "okay"-                if b-                then do-                  putStrLn "==================================================="-                  putStrLn "exp = (K5 (__::TJ))"-                  putStrLn "get ~_ = show 1  -- seems to suffice?!?..."-                  putStrLn "? = get $ forcep patstr exp"-                  putStrLn "==================================================="-                else do-                  putStrLn "---------------------------------------------------"-                putStrLn $ "patstr                   = " ++ patstr-                if code > 4-                then putStrLn $  "expected value           = " ++ expect-                else return ()---              putStrLn $ "pat = " ++ show pat-                putStrLn $ "showPat.compilePat       = " ++ showPat pat-                if code <= 4-                then putStrLn $  "expected value           = " ++ expect-                else return ()-                s1 <- catch-                        ( return $! force $! get $! forcep patstr exp )-                        (\e -> do let err = show (e :: ErrorCall)---                      (\e -> do let err = show (e :: BottomedOut)-                                  return err)-                putStr "actual value             = "-                return $! s1-           )-           -- ErrorCall if use __ = undefined-           -- BottomedOut if use __ = throw BottomedOut-           (\e -> do let err = show (e :: ErrorCall)---         (\e -> do let err = show (e :: BottomedOut)-                     return err)-    putStrLn s-    doit18f False t------------------------------------------------------------------------------------  doit18g :: Bool -> [(Int,String)] -> IO ()-  doit18g _ [] = do-                   putStrLn "--------------------------------------------------"-                   return ()-  doit18g b ((code,patstr):t) = do-    let expect = case code of-                  1 -> "okay"-                  2 -> "Prelude.undefined"-                  3 -> "okay (due to pattern-match failure)"-                  4 -> "syntax error"-                  5 -> "okay (but \"# with subpattern\" warning)"-                  6 -> "okay (but \"constraint/subpattern arity mismatch\" warning)"-#if WARN_PATTERN_MATCH_FAILURE-                  13 -> "7 (but with pattern-match failure warning)"-                  23 -> "Prelude.undefined (but with pattern-match failure warning)"-#else-                  13 -> "7 (with silent pattern-match failure)"-                  23 -> "Prelude.undefined (with silent pattern-match failure)"-#endif-                  _ -> error $ "doit18g: unexpected code " ++ show code-    s <- catch-           ( do-#if TRY_THIS-                let exp = K3 (__::TK) J3-#else-                let exp = K3 K2 (__::TJ)-#endif-                let pat = compilePat patstr-                let get _ = "okay"-                if b-                then do-                  putStrLn "==================================================="-#if TRY_THIS-                  putStrLn "exp = K3 (__::TK) J3"-#else-                  putStrLn "exp = K3 K2 (__::TJ)"-#endif-                  putStrLn "get ~_ = show 1  -- seems to suffice?!?..."-                  putStrLn "? = get $ forcep patstr exp"-                  putStrLn "==================================================="-                else do-                  putStrLn "---------------------------------------------------"-                putStrLn $ "patstr                   = " ++ patstr-                if code > 4-                then putStrLn $  "expected value           = " ++ expect-                else return ()---              putStrLn $ "pat = " ++ show pat-                putStrLn $ "showPat.compilePat       = " ++ showPat pat-                if code <= 4-                then putStrLn $  "expected value           = " ++ expect-                else return ()-                s1 <- catch-                        ( return $! force $! get $! forcep patstr exp )-                        (\e -> do let err = show (e :: ErrorCall)---                      (\e -> do let err = show (e :: BottomedOut)-                                  return err)-                putStr "actual value             = "-                return $! s1-           )-           -- ErrorCall if use __ = undefined-           -- BottomedOut if use __ = throw BottomedOut-           (\e -> do let err = show (e :: ErrorCall)---         (\e -> do let err = show (e :: BottomedOut)-                     return err)-    putStrLn s-    doit18g False t-----------------------------------------------------------------------------------  doit19 :: Bool -> [(Int,String)] -> IO ()-  doit19 _ [] = do-                   putStrLn "--------------------------------------------------"-                   return ()-  doit19 b ((code,patstr):t) = do---  let expstr = "True"-    let expstr = "5.6"-    let expect = case code of-                  1 -> expstr-                  2 -> "Prelude.undefined"-                  3 -> expstr ++ " (due to pattern-match failure)"-                  4 -> "syntax error"-                  5 -> expstr ++ " (but \"# with subpattern\" warning)"-                  6 -> expstr ++ " (but \"constraint/subpattern arity mismatch\" warning)"-#if WARN_PATTERN_MATCH_FAILURE-                  13 -> "7 (but with pattern-match failure warning)"-                  23 -> "Prelude.undefined (but with pattern-match failure warning)"-#else-                  13 -> "7 (with silent pattern-match failure)"-                  23 -> "Prelude.undefined (with silent pattern-match failure)"-#endif-                  _ -> error $ "doit19: unexpected code " ++ show code-    s <- catch-           ( do---              let exp = expTL_1  -- L1 5.6 (M1 True)-                let exp = expTL_2  -- L1 5.6 (M1 __)---              let exp = expTL_3  -- L1 5.6 __---              let exp = expTL_4  -- L1 __ (M1 True)-                let pat = compilePat patstr-                let get = getL---              let get = getL'-                if b-                then do-                  putStrLn "==================================================="-                  putStrLn "exp = L1 5.6 (M1 __)"---                putStrLn "exp = L1 5.6 __"---                putStrLn "exp = L1 __ (M1 True)"-                  putStrLn "get (L1 f (M1 _)) = show f"---                putStrLn "get (L1 f _) = show f"---                putStrLn "get (L1 _ (M1 b)) = show b"-                  putStrLn "? = get $ forcep patstr exp"-                  putStrLn "==================================================="-                else do-                  putStrLn "---------------------------------------------------"-                putStrLn $ "patstr                   = " ++ patstr-                if code > 4-                then putStrLn $  "expected value           = " ++ expect-                else return ()---              putStrLn $ "pat = " ++ show pat-                putStrLn $ "showPat.compilePat       = " ++ showPat pat-                if code <= 4-                then putStrLn $  "expected value           = " ++ expect-                else return ()-                s1 <- catch-                        ( return $! force $! get $! forcep patstr exp )-                        (\e -> do let err = show (e :: ErrorCall)---                      (\e -> do let err = show (e :: BottomedOut)-                                  return err)-                putStr "actual value             = "-                return $! s1-           )-           -- ErrorCall if use __ = undefined-           -- BottomedOut if use __ = throw BottomedOut-           (\e -> do let err = show (e :: ErrorCall)---         (\e -> do let err = show (e :: BottomedOut)-                     return err)-    putStrLn s-    doit19 False t-----------------------------------------------------------------------------------  doit20 :: Bool -> [(Int,String)] -> IO ()-  doit20 _ [] = do-                   putStrLn "--------------------------------------------------"-                   return ()-  doit20 b ((code,patstr):t) = do-    let expect = case code of-                  1 -> "4.5"-                  2 -> "Prelude.undefined"-                  3 -> "4.5 (due to pattern-match failure)"-                  4 -> "syntax error"-                  5 -> "4.5 (but \"# with subpattern\" warning)"-                  6 -> "4.5 (but \"constraint/subpattern arity mismatch\" warning)"-#if WARN_PATTERN_MATCH_FAILURE-                  13 -> "7 (but with pattern-match failure warning)"-                  23 -> "Prelude.undefined (but with pattern-match failure warning)"-#else-                  13 -> "7 (with silent pattern-match failure)"-                  23 -> "Prelude.undefined (with silent pattern-match failure)"-#endif-                  _ -> error $ "doit20: unexpected code " ++ show code-    s <- catch-           ( do---              let exp = expTK_1  -- K3 K2 (J1 4.5)-                let exp = expTK_2  -- K3 __ (J1 4.5)-                let pat = compilePat patstr-                let get = getK-                if b-                then do-                  putStrLn "==================================================="---                putStrLn "exp = K3 K2 (J1 4.5)"-                  putStrLn "exp = K3 __ (J1 4.5)"-                  putStrLn "get = (K3 _ (J1 f)) = show f"-                  putStrLn "? = get $ forcep patstr exp"-                  putStrLn "==================================================="-                else do-                  putStrLn "---------------------------------------------------"-                putStrLn $ "patstr                   = " ++ patstr-                if code > 4-                then putStrLn $  "expected value           = " ++ expect-                else return ()---              putStrLn $ "pat = " ++ show pat-                putStrLn $ "showPat.compilePat       = " ++ showPat pat-                if code <= 4-                then putStrLn $  "expected value           = " ++ expect-                else return ()-                s1 <- catch-                        ( return $! force $! get $! forcep patstr exp )-                        (\e -> do let err = show (e :: ErrorCall)---                      (\e -> do let err = show (e :: BottomedOut)-                                  return err)-                putStr "actual value             = "-                return $! s1-           )-           -- ErrorCall if use __ = undefined-           -- BottomedOut if use __ = throw BottomedOut-           (\e -> do let err = show (e :: ErrorCall)---         (\e -> do let err = show (e :: BottomedOut)-                     return err)-    putStrLn s-    doit20 False t-----------------------------------------------------------------------------------#if __GLASGOW_HASKELL__ >= 708-  doit23 :: String-  doit23 = show $ fg23 exp23---doit23 = show $ get23 $ forcepDyn' fg23 exp23-   where-    exp23 = [[[__]],[[__,6],__,[7]]] :: [[[Int]]]-    get23 xs = (((xs!!1)!!2)!!0)-#if 0-    fg23 :: forall a. (Generic a, HasDatatypeInfo a) => a -> DatatypeInfo (Code a)-    fg23 d = dti-#else-    fg23 :: forall a. (Generic a, HasDatatypeInfo a, All2 Show (Code a), Typeable a) => a -> PatNode-#if 1-    fg23 d = doit23' dti proxy_a d (from d)-#else-    fg23 d | cname == "[[Int]]"  = WI emptyPatNodeAttrs-           | otherwise           = WR emptyPatNodeAttrs-#endif-#endif-     where---    ADT mname tname (Constructor cname :* _) = dti---    ADT mname tname (Constructor cname :* _) = dti :: DatatypeInfo (Code a)---    (mname,tname,cname) = case dti of ...---    ADT mname tname (Constructor cname :* (Infix ":" RightAssociative 5 :* Nil)) = dti-      dti = datatypeInfo proxy_a-      proxy_a = Proxy :: Proxy a-      xrep = from d--  doit23' :: forall a.-             (-               Generic a-             , HasDatatypeInfo a---           , All2 NFDataP (Code a)-             , All2 Show (Code a)-             , Typeable a---           , NFDataN a---           , NFDataP a-             ) =>-                     DatatypeInfo (Code a)-                  -> Proxy a-                  -> a-                  -> Rep a-                  -> PatNode-  doit23' (ADT     _ _ cs) proxy_a x xrep-   = doit23'' cs         proxy_a x xrep-  doit23' (Newtype _ _ c ) proxy_a x xrep-   = doit23'' (c :* Nil) proxy_a x xrep--  doit23'' :: forall a xss.-            (-              Generic a-            , HasDatatypeInfo a-            , All2 Show xss-            ) =>-                    NP ConstructorInfo xss-                 -> Proxy a-                 -> a-                 -> SOP I xss-                 -> PatNode-  doit23'' (m :* _) proxy_a x (SOP (Z xs))-   | tx == "[[Int]]"  = WI emptyPatNodeAttrs-   | otherwise        = WR emptyPatNodeAttrs-   where-    !_ = trace ("*** "++tx) $ ()-    tx | (Constructor n) <- m  = n-       | (Infix n _ _) <- m    = n-       | (Record n _) <- m     = n-  doit23'' (m :* ms) proxy_a x (SOP (S xss))-   = doit23'' ms proxy_a x (SOP xss)-  doit23'' _ _ _ _ = error "doit23'': unexpected case!!"-#endif-----------------------------------------------------------------------------------#endif--  doit24 :: Bool -> [(Int,Int,(Float,[Int],Bool))] -> IO ()-  doit24 _ [] = do-                   putStrLn "--------------------------------------------------"-                   return ()-  doit24 b ((code,ident,exp):t) = do-    let expect = case code of-                  1 -> "7"-                  2 -> "Prelude.undefined"-                  3 -> "7 (due to pattern-match failure)"-                  4 -> "syntax error"-                  5 -> "7 (but \"# with subpattern\" warning)"-                  6 -> "7 (but \"constraint/subpattern arity mismatch\" warning)"-#if WARN_PATTERN_MATCH_FAILURE-                  13 -> "7 (but with pattern-match failure warning)"-                  23 -> "Prelude.undefined (but with pattern-match failure warning)"-#else-                  13 -> "7 (with silent pattern-match failure)"-                  23 -> "Prelude.undefined (with silent pattern-match failure)"-#endif-                  _ -> error $ "doit24: unexpected code " ++ show code-    s <- catch-           ( do---              let exp = force_ Propagate (force_ Propagate 3.4, force_ Propagate (force_ Propagate 5 : (force_ Propagate __ : (force_ Propagate 7 : force_ Propagate []))), force_ Propagate __) :: (Float, [Int], Bool)---              let seq_exp = mkSeqableHarness exp---              let pat = compilePat patstr-                let get (_,xs,_) = show $ (xs!!2)-                if b-                then do-                  putStrLn "==================================================="-                  putStrLn "exp = <refer to test code>"-                  putStrLn "get (_,xs,_) = show $ (xs!!2)"-                  putStrLn "? = get $! exp"-                  putStrLn "==================================================="-                else do-                  putStrLn "---------------------------------------------------"---              putStrLn $ "patstr                   = " ++ patstr-                if code > 4-                then putStrLn $  show ident ++ " expected value           = " ++ expect-                else return ()---              putStrLn $ "pat = " ++ show pat---              putStrLn $ "showPat.compilePat       = " ++ showPat pat-                if code <= 4-                then putStrLn $  show ident ++ " expected value           = " ++ expect-                else return ()-                s1 <- catch-                        ( return $! force $! get $! exp )-                        (\e -> do let err = show (e :: ErrorCall)---                      (\e -> do let err = show (e :: BottomedOut)-                                  return err)-                putStr $ show ident ++ " actual value             = "-                return $! s1-           )-           -- ErrorCall if use __ = undefined-           -- BottomedOut if use __ = throw BottomedOut-           (\e -> do let err = show (e :: ErrorCall)---         (\e -> do let err = show (e :: BottomedOut)-                     return err)-    putStrLn s-    doit24 False t-----------------------------------------------------------------------------------  doit25 :: Bool -> [(Int,Int,(Float,(Bool,Int),Bool))] -> IO ()-  doit25 _ [] = do-                   putStrLn "--------------------------------------------------"-                   return ()-  doit25 b ((code,ident,exp):t) = do-    let expect = case code of-                  1 -> "7"-                  2 -> "Prelude.undefined"-                  3 -> "7 (due to pattern-match failure)"-                  4 -> "syntax error"-                  5 -> "7 (but \"# with subpattern\" warning)"-                  6 -> "7 (but \"constraint/subpattern arity mismatch\" warning)"-#if WARN_PATTERN_MATCH_FAILURE-                  13 -> "7 (but with pattern-match failure warning)"-                  23 -> "Prelude.undefined (but with pattern-match failure warning)"-#else-                  13 -> "7 (with silent pattern-match failure)"-                  23 -> "Prelude.undefined (with silent pattern-match failure)"-#endif-                  _ -> error $ "doit25: unexpected code " ++ show code-    s <- catch-           ( do---              let exp = force_ Propagate (force_ Propagate 3.4, force_ Propagate (force_ Propagate 5 : (force_ Propagate __ : (force_ Propagate 7 : force_ Propagate []))), force_ Propagate __) :: (Float, [Int], Bool)---              let seq_exp = mkSeqableHarness exp---              let pat = compilePat patstr-                let get (_,(_,x),_) = show x-                if b-                then do-                  putStrLn "==================================================="-                  putStrLn "exp = <refer to test code>"-                  putStrLn "get (_,(_,x),_) = show x"-                  putStrLn "? = get $! exp"-                  putStrLn "==================================================="-                else do-                  putStrLn "---------------------------------------------------"---              putStrLn $ "patstr                   = " ++ patstr-                if code > 4-                then putStrLn $  show ident ++ " expected value           = " ++ expect-                else return ()---              putStrLn $ "pat = " ++ show pat---              putStrLn $ "showPat.compilePat       = " ++ showPat pat-                if code <= 4-                then putStrLn $  show ident ++ " expected value           = " ++ expect-                else return ()-                s1 <- catch-                        ( return $! force $! get $! exp )-                        (\e -> do let err = show (e :: ErrorCall)---                      (\e -> do let err = show (e :: BottomedOut)-                                  return err)-                putStr $ show ident ++ " actual value             = "-                return $! s1-           )-           -- ErrorCall if use __ = undefined-           -- BottomedOut if use __ = throw BottomedOut-           (\e -> do let err = show (e :: ErrorCall)---         (\e -> do let err = show (e :: BottomedOut)-                     return err)-    putStrLn s-    doit25 False t-----------------------------------------------------------------------------------#if USE_SOP--  doit26 :: Bool -> [(Int,Int,(Float,[Int],Bool))] -> IO ()-  doit26 _ [] = do-                   putStrLn "--------------------------------------------------"-                   return ()-  doit26 b ((code,ident,exp):t) = do-    let expect = case code of-                  1 -> "7"-                  2 -> "Prelude.undefined"-                  3 -> "7 (due to pattern-match failure)"-                  4 -> "syntax error"-                  5 -> "7 (but \"# with subpattern\" warning)"-                  6 -> "7 (but \"constraint/subpattern arity mismatch\" warning)"-#if WARN_PATTERN_MATCH_FAILURE-                  13 -> "7 (but with pattern-match failure warning)"-                  23 -> "Prelude.undefined (but with pattern-match failure warning)"-#else-                  13 -> "7 (with silent pattern-match failure)"-                  23 -> "Prelude.undefined (with silent pattern-match failure)"-#endif-                  _ -> error $ "doit26: unexpected code " ++ show code-    s <- catch-           ( do---              let exp = force_ Propagate (force_ Propagate 3.4, force_ Propagate (force_ Propagate 5 : (force_ Propagate __ : (force_ Propagate 7 : force_ Propagate []))), force_ Propagate __) :: (Float, [Int], Bool)---              let seq_exp = mkSeqableHarness exp---              let pat = compilePat patstr-                let get (_,xs,_) = show $ (xs!!2)-                if b-                then do-                  putStrLn "==================================================="-                  putStrLn "exp = <refer to test code>"-                  putStrLn "get (_,xs,_) = show $ (xs!!2)"-                  putStrLn "? = get $! exp"-                  putStrLn "==================================================="-                else do-                  putStrLn "---------------------------------------------------"---              putStrLn $ "patstr                   = " ++ patstr-                if code > 4-                then putStrLn $  show ident ++ " expected value           = " ++ expect-                else return ()---              putStrLn $ "pat = " ++ show pat---              putStrLn $ "showPat.compilePat       = " ++ showPat pat-                if code <= 4-                then putStrLn $  show ident ++ " expected value           = " ++ expect-                else return ()-                s1 <- catch-                        ( return $! force $! get $! exp )-                        (\e -> do let err = show (e :: ErrorCall)---                      (\e -> do let err = show (e :: BottomedOut)-                                  return err)-                putStr $ show ident ++ " actual value             = "-                return $! s1-           )-           -- ErrorCall if use __ = undefined-           -- BottomedOut if use __ = throw BottomedOut-           (\e -> do let err = show (e :: ErrorCall)---         (\e -> do let err = show (e :: BottomedOut)-                     return err)-    putStrLn s-    doit26 False t-----------------------------------------------------------------------------------  doit27 :: Bool -> [(Int,Int,TJ)] -> IO ()-  doit27 _ [] = do-                   putStrLn "--------------------------------------------------"-                   return ()-  doit27 b ((code,ident,exp):t) = do-    let expect = case code of-                  1 -> "4.5"-                  2 -> "Prelude.undefined"-                  3 -> "4.5 (due to pattern-match failure)"-                  4 -> "syntax error"-                  5 -> "4.5 (but \"# with subpattern\" warning)"-                  6 -> "4.5 (but \"constraint/subpattern arity mismatch\" warning)"-#if WARN_PATTERN_MATCH_FAILURE-                  13 -> "7 (but with pattern-match failure warning)"-                  23 -> "Prelude.undefined (but with pattern-match failure warning)"-#else-                  13 -> "7 (with silent pattern-match failure)"-                  23 -> "Prelude.undefined (with silent pattern-match failure)"-#endif-                  _ -> error $ "doit27: unexpected code " ++ show code-    s <- catch-           ( do---              let exp = expTJ_1  -- J2 (1, J4 (J3, K3 K2 (J1 4.5))) False---              let exp = expTJ_2  -- J2 (1, J4 (J3, K3 __ (J1 4.5))) False---              let exp = expTJ_3  -- J2 (1, J4 (__, K3 K2 (J1 4.5))) False---              let exp = expTJ_4  -- J2 (1, J4 (__, K3 __ (J1 4.5))) __---              let pat = compilePat patstr-                let get = getJ-                if b-                then do-                  putStrLn "==================================================="---                putStrLn "exp = J2 (1, J4 (J3, K3 K2 (J1 4.5))) False"---                putStrLn "exp = J2 (1, J4 (J3, K3 __ (J1 4.5))) False"---                putStrLn "exp = J2 (1, J4 (__, K3 K2 (J1 4.5))) False"-                  putStrLn "exp = J2 (1, J4 (__, K3 __ (J1 4.5))) __"-                  putStrLn "get = (J2 (_, J4 (_, K3 _ (J1 f))) _) = show f"-                  putStrLn "? = get exp"-                  putStrLn "==================================================="-                else do-                  putStrLn "---------------------------------------------------"---              putStrLn $ "patstr                   = " ++ patstr-                if code > 4-                then putStrLn $  show ident ++ " expected value           = " ++ expect-                else return ()---              putStrLn $ "pat = " ++ show pat---              putStrLn $ "showPat.compilePat       = " ++ showPat pat-                if code <= 4-                then putStrLn $  show ident ++ " expected value           = " ++ expect-                else return ()-                s1 <- catch-                        ( return $! force $! get $! exp )-                        (\e -> do let err = show (e :: ErrorCall)---                      (\e -> do let err = show (e :: BottomedOut)-                                  return err)-                putStr $ show ident ++ " actual value             = "-                return $! s1-           )-           -- ErrorCall if use __ = undefined-           -- BottomedOut if use __ = throw BottomedOut-           (\e -> do let err = show (e :: ErrorCall)---         (\e -> do let err = show (e :: BottomedOut)-                     return err)-    putStrLn s-    doit27 False t-----------------------------------------------------------------------------------  doit28 :: Bool -> [(Int,String)] -> IO ()-  doit28 _ [] = do-                   putStrLn "--------------------------------------------------"-                   return ()-  doit28 b ((code,patstr):t) = do-    let expect = case code of-                  1 -> "7"-                  2 -> "Prelude.undefined"-                  3 -> "7 (due to pattern-match failure)"-                  4 -> "syntax error"-                  5 -> "7 (but \"# with subpattern\" warning)"-                  6 -> "7 (but \"constraint/subpattern arity mismatch\" warning)"-#if WARN_PATTERN_MATCH_FAILURE-                  13 -> "7 (but with pattern-match failure warning)"-                  23 -> "Prelude.undefined (but with pattern-match failure warning)"-#else-                  13 -> "7 (with silent pattern-match failure)"-                  23 -> "Prelude.undefined (with silent pattern-match failure)"-#endif-                  _ -> error $ "doit28: unexpected code " ++ show code-    s <- catch-           ( do-                let exp = expTG_6  -- G2 5 __ 7-                let pat = compilePat patstr-                let get = getG'-                if b-                then do-                  putStrLn "==================================================="-                  putStrLn "exp = G2 5 __ 7 :: TG"-                  putStrLn "get (G2 _ _ n) = n"-                  putStrLn "? = get $ forcep patstr exp"-                  putStrLn "==================================================="-                else do-                  putStrLn "---------------------------------------------------"-                putStrLn $ "patstr                   = " ++ patstr-                if code > 4-                then putStrLn $  "expected value           = " ++ expect-                else return ()---              putStrLn $ "pat = " ++ show pat-                putStrLn $ "showPat.compilePat       = " ++ showPat pat-                if code <= 4-                then putStrLn $  "expected value           = " ++ expect-                else return ()-                s1 <- catch-                        ( return $! force $! get $! forcep patstr exp )-                        (\e -> do let err = show (e :: ErrorCall)---                      (\e -> do let err = show (e :: BottomedOut)-                                  return err)-                putStr "actual value             = "-                return $! s1-           )-           -- ErrorCall if use __ = undefined-           -- BottomedOut if use __ = throw BottomedOut-           (\e -> do let err = show (e :: ErrorCall)---         (\e -> do let err = show (e :: BottomedOut)-                     return err)-    putStrLn s-    doit28 False t-----------------------------------------------------------------------------------  doit29 :: Bool -> [(Int,String)] -> IO ()-  doit29 _ [] = do-                   putStrLn "--------------------------------------------------"-                   return ()-  doit29 b ((code,patstr):t) = do-    let expect = case code of-                  1 -> "((999999,1999999),3999999)"-                  2 -> "Prelude.undefined"-                  3 -> "((999999,1999999),3999999) (due to pattern-match failure)"-                  4 -> "syntax error"-                  5 -> "((999999,1999999),3999999) (but \"# with subpattern\" warning)"-                  6 -> "((999999,1999999),3999999) (but \"constraint/subpattern arity mismatch\" warning)"-#if WARN_PATTERN_MATCH_FAILURE-                  13 -> "((999999,1999999),3999999) (but with pattern-match failure warning)"-                  23 -> "Prelude.undefined (but with pattern-match failure warning)"-#else-                  13 -> "((999999,1999999),3999999) (with silent pattern-match failure)"-                  23 -> "Prelude.undefined (with silent pattern-match failure)"-#endif-                  _ -> error $ "doit29: unexpected code " ++ show code-    s <- catch-           ( do-                let exp = (([0..999999::Int],[1000000..1999999::Int]),[2000000..3999999::Int])-                let pat = compilePat patstr-                let get ((xs,ys),zs) = show ((last xs,last ys),last zs)-                if b-                then do-                  putStrLn "==================================================="-                  putStrLn "exp = (([0..999999],[1000000..1999999]),[2000000..3999999])"-                  putStrLn "get ((xs,ys),zs) = show ((last xs,last ys),last zs)"-                  putStrLn "? = get $ forcep patstr exp"-                  putStrLn "==================================================="-                else do-                  putStrLn "---------------------------------------------------"-                putStrLn $ "patstr                   = " ++ patstr-                if code > 4-                then putStrLn $  "expected value           = " ++ expect-                else return ()---              putStrLn $ "pat = " ++ show pat-                putStrLn $ "showPat.compilePat       = " ++ showPat pat-                if code <= 4-                then putStrLn $  "expected value           = " ++ expect-                else return ()-                s1 <- catch-                        ( return $! force $! get $! forcep patstr exp )-                        (\e -> do let err = show (e :: ErrorCall)---                      (\e -> do let err = show (e :: BottomedOut)-                                  return err)-                putStr "actual value             = "-                return $! s1-           )-           -- ErrorCall if use __ = undefined-           -- BottomedOut if use __ = throw BottomedOut-           (\e -> do let err = show (e :: ErrorCall)---         (\e -> do let err = show (e :: BottomedOut)-                     return err)-    putStrLn s-    doit29 False t-----------------------------------------------------------------------------------#endif-
− tests/Blah_old_grammar.hs
@@ -1,3000 +0,0 @@------------------------------------------------------------------------------------- Disclaimer: I've not used HUnit yet. I'm using it only--- as a "hook" so can compile/test in less clock time...--- (I forget the details of how why.)------ Obviously, this should use proper HUnit eventually.--- And QuickCheck and SmallCheck, DEFINITELY!!!...--- This is a great case for those; and shape-syb no less.------ This file could be cleaned up a lot, but that's--- not quite a priority at the moment...------ The reason I shied away from making it real HUnit tests--- is probably related to the fancy exception throwing/catching--- and catching of all exceptions (including error), etc.--- Which was aggravated by the nature of this project and--- of its tests, which hit bottom as a matter of course...------ Yeah; and looking at examples of QuickCheck and SmallCheck,--- it's still not clear to me how to work bottoming-out--- into my tests.---   I guess I could catch the bottoms in my code, and return--- some reserved value to indicate that it occurred?...-----------------------------------------------------------------------------------{-# LANGUAGE CPP #-}-----------------------------------------------------------------------------------#define FOCUS_TEST 0-#define USE_TRACE 0------------------------------------------------------------------------------------- Later: This may work with some versions of GHC, but I'm quite--- sure I've seen it not work with some recent version...--- Unfortunately, this doesn't work -- all pragmas are processed,--- regardless of CPP (so CPP must run after).--- The fact the CPP itself can be set via a pragma complicates this.--- It could be made an exception, and the LANGUAGE CPP pragma could--- be parsed regardless of CPP context (as all pragmas currently are).--- As it is, we need separate source modules, and to switch at--- import statements (and in the .cabal file).--- THIS IS A BUG.--- So anyhow, this is only here as a reminder:----  #if ! HASKELL98_FRAGMENT----  {-# LANGUAGE ... #-}----  #endif-  {-# LANGUAGE DeriveGeneric #-}-  {-# LANGUAGE DeriveDataTypeable #-}  -- to make BottomedOut-  {-# LANGUAGE BangPatterns #-}--  {-# LANGUAGE Rank2Types #-}  -- for SYB (testing rnfpDyn and friends)-----------------------------------------------------------------------------------  -- SOP pragmas:--  -- Not necessarily needed to work with SOP, but I think it'll-  -- be helpful here [?] ...-  {-# LANGUAGE ScopedTypeVariables #-}-  {-  LANGUAGE AllowAmbiguousTypes #-}---- Actually, CPP doesn't work with Haskell (GHC) pragmas last I checked...-#if USE_SOP-  {-# LANGUAGE DataKinds #-}-  {-# LANGUAGE TypeFamilies #-}-  {-# LANGUAGE ConstraintKinds #-}-#if __GLASGOW_HASKELL__ < 708-  {-# LANGUAGE GADTs #-}-#endif-  {-# LANGUAGE TemplateHaskell #-}-#endif-----------------------------------------------------------------------------------  module Blah_old_grammar ( run_tests ) where-----------------------------------------------------------------------------------  import Bottom-  import Foo-  import FooG----import Control.DeepSeq.Generics-  import Control.DeepSeq.Bounded---import Control.DeepSeq.Bounded hiding ( F )-  import Control.DeepSeq.Bounded.Generic--#if 0-  import GHC.Generics---import GHC.Generics ( Generic )-#endif--  import Data.Maybe--  import Control.Exception---import Control.Monad ( guard )-  import Control.Monad ( replicateM )-  import Control.Monad ( when )-  import Data.Typeable ( Typeable )-  import Data.Typeable ( typeOf )--  import Data.Data ( Data )--  import Data.Generics.Aliases ( mkQ, extQ, GenericQ )----import Util ( spoor )-  import Debug.Trace ( trace )-  import Control.DeepSeq--#if __GLASGOW_HASKELL__ >= 708-  import Data.Typeable ( Proxy(..) )-#endif--#if USE_SOP-  import Generics.SOP hiding ( Shape )-#endif--  import System.Random--  import Data.List ( intercalate )--  import System.IO.Unsafe ( unsafePerformIO )-----------------------------------------------------------------------------------  -- For convenience in GHCi interactive sessions:-  cp = compilePat-  ip = intersectPats-  isp = subPat--  -- For more compact test expressions:--- XXX Refer to Seqable.hs for comments about JUST_ALIAS_GSEQABLE.-#if 1-#if JUST_ALIAS_GSEQABLE-  fI :: forall a. Generic a => a -> a-  fI = force_ Insulate-  fP :: forall a. Generic a => a -> a-  fP = force_ Propagate-#else-  fI :: forall a. NFDataN a => a -> a-  fI = force_ Insulate-  fP :: forall a. NFDataN a => a -> a-  fP = force_ Propagate-#endif-#else-  fI = force_ Insulate-  fP = force_ Propagate-#endif--  gI :: forall a. Generic a => a -> a-  gI = gforce_ Insulate-  gP :: forall a. Generic a => a -> a-  gP = gforce_ Propagate-----------------------------------------------------------------------------------  run_tests :: IO Int-  run_tests = do--    putStr "\n"-    -- So can notice the start when scrollback, esp. in ghci reload/reruns.---  replicateM 50 $ putStrLn "################################################################################"-    putStrLn "\nTesting.\n"--#if ! FOCUS_TEST--#if 1---  let shp s = s ++ replicate (30 - length s) ' ' ++ show (compilePat s)-    let shp s = -         unsafePerformIO $ -         catch-          ( return $! force $ s ++ replicate (30 - length s) ' ' ++ show (compilePat s) )-          ( \e -> do let err = show (e :: ErrorCall)-                     return err )--    putStrLn "Pattern                       Compiles to"---  putStrLn $ shp ""  -- empty pattern syntax error-    putStrLn $ shp "*"  -- Node WW []---  putStrLn $ shp "@"  -- Node WS []  -- obsoleted (use "." w/o children)-    putStrLn $ shp "#"  -- Node I []  -- no parent to absorb (should be error)-    putStrLn $ shp "."  -- Node WS []---  putStrLn $ shp "**"  -- Node WS []  -- "disconnected pattern (not rooted)"---  putStrLn $ shp ".*"  -- Node WS []  -- "disconnected pattern (not rooted)"---  putStrLn $ shp "*."  -- Node WS []  -- "disconnected pattern (not rooted)"-    putStrLn $ shp ".{}"  -- Node WR []-    putStrLn $ shp ".{*}"  -- Node WR [Node WW []]-    putStrLn $ shp ".{**}"  -- Node WR [Node WW [],Node WW []]-    putStrLn $ shp ".{.*}"  -- Node WR [Node WS [],Node WW []]-    putStrLn $ shp ".{#.}"  -- Node WR [Node I [],Node WS []]-    putStrLn $ shp ".{#{#}}"  -- Node WR [Node I []] with warning-    putStrLn $ shp ".{.{#}}"  -- Node WR [Node WR [Node I []]]-    putStrLn $ shp ".{*#*#*#**#*#*}"  -- looks fine-    putStrLn $ shp ".{*#.{*#.{*#}*}*{#*}#*}"  -- warning about *{...}-    putStrLn $ shp ".{*#.{*#.{*#}*}*#*}"---  putStrLn $ shp ".{*#.{*#.{*#}*}{*}{#*}#*}"  -- }{ syntax error--- [old comment for that last:] NodeM WR [NodeM WW [],Nil,NodeM WR [NodeM WW [],Nil,NodeM WR [NodeM WW [],Nil],NodeM WW [],NodeM WW [],Nil,NodeM WW []],Nil,NodeM WW []] -- was wrong but is fixed I think-    putStrLn $ shp ".{.*.{*23*}}"-#if PARALLELISM_EXPERIMENT-    putStrLn $ shp ".{.=*.{=*23*}}"-#endif-#endif--#endif--#if ! FOCUS_TEST--#if 1-    let test_patterns10 = [-           (4,  "")  -- syntax error-         , (4,  ".##")  -- syntax error (disconnected pattern)-         , (1,  ".{.##}")  -- fail-         , (5,  ".{.{}#{}#{}}")-         , (2,  "*")-         , (2,  ".{***}")-         , (1,  ".{###}")-         , (1,  ".{*##}")-         , (2,  ".{**#}")-         , (2,  ".{##*}")--           -- Remember, [a] is a recursive binary ctor app!...-           -- The next four tests give instance errors for [a], but if-           -- testing expTG_* (GNFDataP/grnfp) then it's no longer a list...-         , (13, ".{..{*#*}#}")-         , (13, ".{..{*###}#}")-         , (13, ".{..{*####}#}")-         , (23, ".{..{*####}.}")--         , (2,  ".{..{*#}*}")-         , (1,  ".{..{*#}#}")-         , (1,  ".{..{*.{#*}}#}")-         , (2,  ".{..{*.{*#}}#}")-         , (13, ".{..{.{..{#*}}}#}")  -- See above comment about [a] instance-         , (2,  ".{#.{..{..{#*}}}#}")--           -- (See Book, p.84.)-         , (1,  ".{..{..{#.{..}}}#}")-         , (1,  ".{..{..{#*}}#}")-         , (1,  ".{*.{*.{#*}}#}")-         , (2,  ".{##*}")-         , (2,  ".{*#*}")-         , (1,  ".:Tuple3{*.{*.{#*}}#}")  -- oops...-         , (1,  ".:(,,){*.{*.{#*}}#}")-         , (2,  ".:(,,){*.{*.{.*}}#}")-         , (1,  ".:Bool{***}")  -- XXX makes no sense (but works) -- oh well;-                                  -- this is an important point to note in-                                  -- docs/blog also...-         , (1,  "*:Bool")-         , (2,  "*:(,,)")-         , (2,  ".{*#.}")-         , (2,  ".{*#.:Bool}")  -- XXX this gives parse error on 2nd .-         , (2,  ".{*#.:Bool{}}")  -- XXX this gives no parse error; if it does what-                                  -- it says, it will only match a childless Bool node-         , (1,  ".{*#.:Int{}}")  -- still need to implement # when not in type-         , (1,  ".{*#.:(,){}}")  -- still need to implement # when not in type-         , (1,  ".{*#.:Int }")  -- still need to implement # when not in type-         , (1,  ".{*#.:Int'}")  -- still need to implement # when not in type-         , (1,  ".{*##:Bool}")-         , (2,  ".{*##:Int}")-         , (2,  ".{*##:(,)}")-         , (1,  ".{*##:Bool{}}")-         , (2,  ".{*##:Int{}}")-         , (2,  ".{*##:(,){}}")-         , (1,  ".{**2#}")-         , (2,  ".{**3#}")-         , (1,  ".{*#:G2{}#}")-         , (1,  ".{*#:Int{}#}")-         ]-    doit14 True test_patterns10---  doit10 True test_patterns10-#endif--#if USE_SOP---- Seems fine; it's not a good test as the # in the middle--- only forces one ctor when type doesn't match, and need--- to force one more level to hit an undefined.-#if 1-    let test_patterns11 = [-           (4,  "")  -- syntax error-#if 0-         , (4,  ".##")  -- syntax error (disconnected pattern)-         , (1,  ".{.##}")  -- fail-         , (5,  ".{.{}#{}#{}}")-         , (2,  "*")-         , (2,  ".{***}")-         , (1,  ".{###}")-         , (1,  ".{*##}")-         , (2,  ".{**#}")-         , (2,  ".{##*}")--           -- Remember, [a] is a recursive binary ctor app!...-           -- The next four tests give instance errors for [a], but if-           -- testing expTG_* (GNFDataP/grnfp) then it's no longer a list...-         , (13, ".{..{*#}#}")-         , (13, ".{..{*###}#}")-         , (13, ".{..{*####}#}")-         , (23, ".{..{*####}.}")--         , (2,  ".{..{*##}*}")-         , (1,  ".{..{*##}#}")-         , (1,  ".{..{*#*}#}")-         , (2,  ".{..{**#}#}")--           -- (See Book, p.84.)-         , (1,  ".{..{.#.}#}")-         , (1,  ".{..{.#*}#}")-         , (1,  ".{*.{*#*}#}")-         , (2,  ".{##*}")-         , (2,  ".{*#*}")-         , (1,  ".:Tuple3{*.{*#*}#}")  -- oops...-         , (1,  ".:(,,){*.{*#*}#}")-         , (2,  ".:(,,){*.{*.*}#}")-         , (1,  ".:Bool{***}")  -- XXX makes no sense (but works) -- oh well;-                                -- this is an important point to note in-                                -- docs/blog also...-         , (1,  "*:Bool")-         , (2,  "*:(,,)")-         , (2,  ".{*#.}")-         , (2,  ".{*#.:Bool}")  -- XXX this gives parse error on 2nd .-         , (2,  ".{*#.:Bool{}}")  -- XXX this gives no parse error; if it does what-                                  -- it says, it will only match a childless Bool node-         , (1,  ".{*#.:Int{}}")  -- still need to implement # when not in type-         , (1,  ".{*#.:(,){}}")  -- still need to implement # when not in type-         , (1,  ".{*#.:Int }")  -- still need to implement # when not in type-         , (1,  ".{*#.:Int'}")  -- still need to implement # when not in type-         , (1,  ".{*##:Bool}")-         , (2,  ".{*##:Int}")-         , (2,  ".{*##:(,)}")-         , (1,  ".{*##:Bool{}}")-         , (2,  ".{*##:Int{}}")-         , (2,  ".{*##:(,){}}")-         , (1,  ".{**0#}")-         , (1,  ".{**1#}")-         , (2,  ".{**2#}")-         , (2,  ".{**3#}")-#endif-         , (1,  ".{*#:G2{}#}")-         , (1,  ".{*#:Int{}#}")-         ]-    doit15 True test_patterns11-#endif--#endif--#if USE_SOP---- All fine last checked.-#if 1-    let test_patterns12 = [-#if 0-           (1, ".{.##}")-#else-#if 1-           (4, "..")--         , (2, "*")-         , (1, "*0")-         , (1, "*1")-         , (2, "*2")-         , (2, "*3")--#if 1--         , (1, ".{.#.}")-         , (2, ".{...}")--         , (1, "*:TG")  -- (misuse; TG is a type name, not the name of a ctor)-         , (1, "*:G1")-         , (2, "*:G2")-         , (1, "*:G1{..}")-         , (1, "*:G1{...}")-         , (2, "*:G2{..}")-         , (2, "*:G2{...}")--         -- the getter used makes the rest uninteresting (none touch bottom)-         , (1, "#:G1")-         , (1, "#:G2")-         , (1, "#:G1{..}")-         , (1, "#:G1{...}")---       , (6, "#:G1{...}")-         , (1, "#:G2{..}")-         , (1, "#:G2{...}")--         , (1, ".:G1{..}")-         , (1, ".:G1{...}")-         , (1, ".:G2{..}")-         , (2, ".:G2{...}")-#endif-#else-           (2, "#:G1{}")-         , (1, "#:G2{}")-         , (2, "#:Int{}")-         , (1, "*:G1")-         , (2, "*:G2")-         , (1, "*:G1{}")-         , (2, "*:G2{}")-         , (1, "*:Int{}")-         , (2, "*:G2{..}")-         , (2, "*:G2{...}")-         , (2, "*{..}")-         , (2, "*{....}")-         , (1, ".{..}")-         , (2, ".{...}")-         , (1, ".{....}")-#endif-#endif-         ]-    doit16 True test_patterns12-#endif--#endif--#if USE_SOP---- This should work, once the patterns are right for lists,--- but until I get non-list generic tests working I'm not--- going to struggle with this.-#if 0-    let test_patterns13 = [--- expTH_1 = H2 1 [H1 2.3, H3, H4 (H3, I3 I2 (H1 4.5))] False    (for ref.)--- expTH_4 = H2 1 [H1 2.3, H3, H4 (__, I3 __ (H1 4.5))] __       (in use)-           (4,  "")  -- syntax error-         , (1,  ".{..{..{..{.{#.{#.}}.}}}#}")-         , (2,  ".{..{..{..{.{..{#.}}.}}}#}")-         , (2,  ".{..{..{..{.{#.{..}}.}}}#}")-         , (2,  ".{..{..{..{.{#.{#.}}.}}}.}")-         , (1,  ".{..{.{.}.{..{.{#.{#.{.}}}.}}}#}")-         , (2,  ".{..{.{.}.{..{.{..{#.{.}}}.}}}#}")-         , (2,  ".{..{.{.}.{..{.{#.{..{.}}}.}}}#}")-         , (2,  ".{..{.{.}.{..{.{#.{#.{.}}}.}}}.}")-         , (2,  ".{..{.{.}.{..{.{#.{#..{.}}}.}}}.}")-         ]-    doit17 True test_patterns13-#endif--#if 1-    let test_patterns14 = [--- expTJ_1 = J2 ( 1, J4 ( J3, K3 K2 ( J1 4.5))) False     -- for ref.--- expTJ_2 = J2 ( 1, J4 ( J3, K3 __ ( J1 4.5))) False--- expTJ_3 = J2 ( 1, J4 ( __, K3 K2 ( J1 4.5))) False--- expTJ_4 = J2 ( 1, J4 ( __, K3 __ ( J1 4.5))) __        -- in use---           {  { {} {  { {}  {  {} { {  {} }}}}}}}--- XXX The tuples are ctors, I forgot...-           (4 ,  "")  -- syntax error-#if 0-         , (1 ,  ".")-         , (13,  ".{}")-         , (13,  ".{.}")-         , (2 ,  ".{..}")-         , (13,  ".{...}")-         , (13,  ".{....}")-         , (13,  ".{.....}")-#endif--- expTJ_1 = J2 ( 1, J4 ( J3, K3 K2 ( J1 4.5))) False     -- for ref.---                J2 { (,) { I J4 { (,) { J3 K3 { K2 { J1 { 4.5 } } } } } } False }---                .  {  .  { .  . {  .  { .  .  {  . { .  { .   } } } } } } . }-           -- this pattern also double-checked on paper-         , (2 ,  ".{.{..{.{..{..{.}}}}}.}")---       , (1 ,  ".{.{..{.{..{#.{.}}}}}#}")  -- blows (in partic. expTJ_2)-         , (1 ,  ".{.{..{.{#.{..{.}}}}}#}")  -- blows (in partic. expTJ_3)---       , (1 ,  ".{.{..{.{#.{#.{.}}}}}#}")  -- blows (in partic. expTJ_4)-#if 0-         , (1 ,  ".{.{..{#{##{##{#}}}}}#}")  -- = ".{.{..{#}}#}" (no blow)-         , (1 ,  ".{.{..{#{#.{#.{.}}}}}#}")  -- = ".{.{..{#}}#}" (no blow)-         , (1 ,  ".{.{..{#{..{#.{.}}}}}#}")  -- = ".{.{..{#}}#}" (no blow)-         , (1 ,  ".{.{..{.{..{#.{.}}}}}#}")  -- blows-         , (1 ,  ".{.{..{.{##{##{#}}}}}#}")  -- blows-         , (1 ,  ".{.{..{#}}#}")             -- confirming (no blow)-#endif-#if 0-         , (2 ,  ".{.{..{.{..{.{.{.}}}}}}.}")-         , (1 ,  ".{.{..{.{#.{#{.{.}}}}}}#}")-         , (1 ,  "#{#{##{#{##{#{#{#}}}}}}#}")-         , (1 ,  ".{#{##{#{##{#{#{#}}}}}}#}")-         , (1 ,  ".{.{##{#{##{#{#{#}}}}}}#}")-         , (1 ,  ".{.{..{#{##{#{#{#}}}}}}#}")-#endif-#if 0-         , (1,  ".{..{#.{#.{.}}}#}")-         , (2,  ".{..{..{..{.}}}.}")-         , (2,  "*")-         , (2,  ".{.*.}")-         , (2,  ".{***}")-#endif-         ]-    doit18 True test_patterns14-#endif--#if 1-    let test_patterns14b = [--- expTJ_5 = J2 ( 1, J4 ( __, K2 )) False-           (4 ,  "")  -- syntax error-         , (2 ,  ".{.{..{.{..}}}.}")-         , (1 ,  ".{.{..{.{#.}}}.}")-         , (1 ,  ".{.{..{#{..}}}.}")-         , (1 ,  ".{.{.#{.{..}}}.}")-         ]-    doit18b True test_patterns14b-#endif--#if 1-    let test_patterns14c = [--- expTJ_6 = J4 ( __, K2 ) False-           (4 ,  "")  -- syntax error-         , (2 ,  ".{.{..}}")-         , (1 ,  ".{.{#.}}")-         , (1 ,  ".{#{..}}")-         , (1 ,  "#{.{..}}")-         ]-    doit18c True test_patterns14c-#endif--#if 1-    let test_patterns14d = [--- expTJ_7 = ( __, K2 )-           (4 ,  "")  -- syntax error-         , (2 ,  ".{..}")-         , (1 ,  ".{#.}")-         , (1 ,  "#{..}")-         ]-    doit18d True test_patterns14d-#endif--#if 1-    let test_patterns14e = [--- expTJ_8 = __ :: TJ-           (4 ,  "")  -- syntax error-         , (2 ,  ".")-         , (1 ,  "#")-         ]-    doit18e True test_patterns14e-#endif--#if 1-    let test_patterns14f = [--- expTJ_8 = (K5 (__::TJ))-           (4 ,  "")  -- syntax error-         , (1 ,  ".")-         , (1 ,  ".{#}")-         , (2 ,  ".{.}")-         , (1 ,  "#")-         ]-    doit18f True test_patterns14f-#endif---- These work!-#define TRY_THIS 1-#if 1-    let test_patterns14g = [-#if TRY_THIS--- exp = K3 (__::TK) J3-#else--- exp = K3 K2 (__::TJ)-#endif-           (4 ,  "")  -- syntax error-         , (1 ,  ".")-#if TRY_THIS-         , (1 ,  ".{#.}")-         , (2 ,  ".{.#}")-#else-         , (2 ,  ".{#.}")-         , (1 ,  ".{.#}")-#endif-         , (2 ,  ".{..}")-         , (1 ,  "#")-         ]-    doit18g True test_patterns14g-#endif---- Okay last I checked.-#if 1-    let test_patterns15 = [--- expTL_1 = L1 5.6 (M1 True)--- expTL_2 = L1 5.6 (M1 __)--- expTL_3 = L1 5.6 __--- expTL_4 = L1 __ (M1 True)-           (4 ,  "")  -- syntax error-#if 0-#elif 1-         , (1 ,  "#")-         , (5 ,  "#{..}")-         , (1 ,  ".{..}")-         , (2 ,  ".{.{.}.}")-         , (1 ,  ".{.{#}.}")-#elif 0-         , (1 ,  "#")-         , (5 ,  "#{..}")-         , (2 ,  ".{..}")-         , (1 ,  ".{#.{.}}")-#elif 0-         , (1 ,  "#")-         , (5 ,  "#{..}")-         , (2 ,  ".{..}")-         , (2 ,  ".{..{.}}")-         , (2 ,  ".{..{#}}")-#elif 0-         , (1 ,  "#")-         , (5 ,  "#{..}")-         , (1 ,  ".{..}")-         , (2 ,  ".{..{.}}")-         , (1 ,  ".{..{#}}")-#endif-         ]-    doit19 True test_patterns15-#endif---- Good test case for the problem. No tuples; every step is generic.-#if 1-    let test_patterns16 = [--- expTK_1 = K3 K2 ( J1 4.5)     -- for ref.--- expTK_2 = K3 __ ( J1 4.5)---           {  {} { {  {} }}}--- XXX Don't forget tuples are ctors...-           (4 ,  "")  -- syntax error-#if 0-         , (2 ,  ".{..}")-         , (1 ,  ".{#.}")-         , (2 ,  ".{.#}")-         , (1 ,  ".{##}")-#else-         , (2 ,  ".{..{.}}")  -- ok-         , (1 ,  ".{##}")     -- X-         , (1 ,  ".{#.}")     -- X-         , (1 ,  ".{#.{#}}")  -- X-         , (1 ,  ".{#.{.}}")  -- X-         , (2 ,  ".{.#{.}}")  -- X  & this does give the # with subpat. warning.-         , (2 ,  ".{.#{#}}")  -- X  & why no warning about # with subpattern?-         , (1 ,  ".{##{#}}")  -- X  & why no warning about # with subpattern?-         , (1 ,  "#{##{#}}")  -- ok & why no warning about # with subpattern?-#endif-         ]-    doit20 True test_patterns16-#endif--#endif-------------------------------------------------#endif---- Later: Oh! Don't be silly -- it's all compile-time, and the--- size or shape of the list is irrelevant -- which rules--- will fire depends on THIS FILE'S SOURCE CODE (not it's--- data, including static values)!--- XXX Even with empty list, the same rule firings occur!...--- If comment out this block however, the rules do not fire!-#if 1-    -- Testing composition and union:-    let test_patterns11 = [-           (1, ".", ".")-         , (2, ".", "*")-         , (2, "*", ".")-         , (2, "*", "*")-         , (2, ".{...}", ".{*..}")-         , (2, ".{*..}", ".{..*}")-         , (2, ".{.*#}", ".{.#.}")-         ]-    doit11 True test_patterns11-#endif--#if ! FOCUS_TEST--#if 1-    -- Testing splicePats-    let test_patterns12 = [-           (1, ".", [], [(0,"*")])-         , (1, ".{}", [], [(0,"*")])-         , (1, ".", [0], [(0,"*")])-         , (1, ".{..}", [], [(0,"*")])-         , (1, ".{..}", [0], [(0,"*")])-         , (1, ".{..}", [2], [(0,"*")])-         , (1, ".{..}", [], [(0,"*"),(0,"#")])-         , (1, ".{..}", [], [(0,"*"),(1,"#")])-         , (1, ".{..}", [], [(1,"#"),(0,"*")])-         , (1, ".{..}", [], [(0,"*"),(2,"#")])-         , (1, ".{..}", [], [(2,"*"),(2,"#"),(2,"#")])-         , (1, ".{..}", [], [(-1,"*")])-         , (1, ".{..}", [], [(0,"*")])-         , (1, ".{..}", [], [(1,"*")])-         , (1, ".{..}", [], [(2,"*")])-         , (1, ".{..}", [], [(3,"*")])-         , (1, ".{..{..}.}", [1], [(0,"*")])-         , (1, ".{..{..}.}", [1], [(0,"*3"),(1,"#"),(2,"*")])-         , (1, ".{..{..}.}", [1,0], [(0,"*"),(0,"#")])-         , (1, ".{.{...}.{.{}.}.}", [1], [(0,"*"),(0,"#")])-         , (1, ".{.{...}.{.{}.}.}", [1,0], [(0,"*"),(0,"#")])-         , (1, ".{.{###}.{.{}#}#}", [1,0], [(0,"*"),(0,"#")])-         , (1, ".{.:(,,){###}.{.{}#}#}", [1,0], [(0,"*"),(0,"#")])-         ]-    doit12 True test_patterns12-#endif--#if 1-    -- Testing elidePats-    -- XXX There's a nice way to do this, by rewriting each test-    -- automatically (or via manual regex substitutions) so that-    -- the target is the result of the corresponding splicePats test.-    -- Unfortunately, the expected results are not encoded for-    -- the splicePats test, so oh well, for now at least, just-    -- build some fresh tests!-    let test_patterns12b = [-           (1, ".{.{..}..{.}}", [], [0])-         , (1, ".{.{..}..{.}}", [0], [0])-         , (1, ".{.{..}..{.}}", [1], [0])-         , (1, ".{.{..}..{.}}", [1], [1])-         ]-    doit12b True test_patterns12b-#endif--#endif--#if ! FOCUS_TEST--#if 1-    -- Testing erodePat-    -- XXX Note we toss the stdgen when done here...-    stdgen12c <- newStdGen---  let stdgen12c = mkStdGen seed-    let test_patterns12c = [-           (1, ".{.{..}..{.}}", [])  -- recursive test...-         ]---  stdgen12c <- doit12c True test_patterns12c-#if 0-    stdgen12c' <- doit12c True test_patterns12c stdgen12c-    stdgen12c'' <- doit12c True test_patterns12c stdgen12c'-    stdgen12c''' <- doit12c True test_patterns12c stdgen12c''-    return ()-#else-#if 1-    stdgen12c' <- doit12c True test_patterns12c stdgen12c 5-    return ()-#else-    doit12c True test_patterns12c stdgen12c-      >>= doit12c True test_patterns12c-      >>= doit12c True test_patterns12c-      >>= doit12c True test_patterns12c-      >>= doit12c True test_patterns12c-      >>= doit12c True test_patterns12c-      >>= doit12c True test_patterns12c-      >>= doit12c True test_patterns12c-      >>= doit12c True test_patterns12c-#endif-#endif-#endif--#endif--#if 1-    -- Testing anything else we can with a single function!-    -- (Getting sick of this cloning.)-    -- Functions are listed in (current) export order.-    -- Things still needing testing are >'d.-    -- Things tested but failing some tests have a *.-    -- -    -- XXX Wow does this ever look cleaner with "Pat" instead of "Pattern"!...-    -- Fortunately splicePats is already tested separately; the rest-    -- we need to test deal only in Pat args (or list of same), so-    -- we can pass a couple [Pat] to test13 along with an Int code-    -- to control delegation.-    --  1    unionPats       :: [ Pat ] -> Pat-    --  2    intersectPats   :: [ Pat ] -> Pat-    --  3    subPat          :: Pat -> Pat -> Bool---  --  4    unionPatssStr   :: [ String ] -> String-    --  5    emptyPat        :: Pat-    --  6    mkPat           :: forall d. Data d => d -> Pat-    --  7    growPat         :: forall d. Data d => Pat -> d -> Pat-    --  8    shrinkPat       :: Pat -> Pat-    --  9    liftPats        :: [ Pat ] -> Pat-    -- 10    splicePats      :: Pat -> [Int] -> [(Int, Pat)] -> Pat-    -- 11    isPath          :: Pat -> Bool-    -- 12    mkPatN          :: Int -> Pat -> Bool-    -- 13    elidePats       :: Pat -> Pat -> [Int] -> Pat-    -- 14    erodePat        :: StdGen -> [Int] -> Pat -> (Pat, StdGen)-    let test_patterns13 = [-           ( 1, [".{...}", ".{.#}"], "")-         , ( 2, [".{...}", ".{.#}"], "")-         , ( 3, [".", "."], "True")-         , ( 3, ["#", "#"], "True")-         , ( 3, ["*", "*"], "True")-         , ( 3, [".", ".{}"], "True")-         , ( 3, [".{}", "."], "False")-         , ( 3, [".{}", ".{.}"], "False")-         , ( 3, [".{.}", ".{.}"], "True")-         , ( 3, [".{.}", ".{..}"], "False")-         , ( 3, [".{.}", ".{.{.}}"], "True")-         , ( 3, [".{..}", ".{.#}"], "False")-         , ( 3, [".{.#}", ".{..}"], "True")-         , ( 3, [".{..}", ".{...}"], "False")-         , ( 3, [".{}", ".{...}"], "False")-         , ( 3, [".", ".{*.#}"], "True")-         , ( 3, ["#", ".{*.#}"], "True")-         , ( 3, ["*", ".{*.#}"], "False")-         , ( 3, ["*", ".{*}"], "False")-         , ( 3, ["*", ".{**}"], "False")-         , ( 4, [".{...}", ".{.#}"], "")-         , ( 5, [".{...}", ".{.#}"], "")-         , ( 6, [".{...}", ".{.#}"], "")-         -- matching against val = ([1,2,3::Int],(False,"foo"))-         -- mkPat val = ".{.{..{..{..}}}.{..{..{..{..}}}}}"-         , ( 7, [".{.{..{..}}.{..{..}}}"], "")-         , ( 7, [".{.{..{..{..}}}.{..{..{..}}}}"], "")-         , ( 7, [".{.{..{..{..}}}.{..{..{..{..}}}}}"], "")-         , ( 8, [".{.{..{..{..}}}.{..{..{..{..}}}}}"], "")-         , ( 8, [".{.{..{..{..}}}.{..{..{..}}}}"], "")-         , ( 8, [".{.{..{..}}.{..{..}}}"], "")-         , ( 8, [".{.{#.{..}}.{#.{*3.}}}"], "")-         , ( 8, [".{.{#.}.{#.}}"], "")-         , ( 8, [".{..}"], "")-         , ( 8, ["."], "")-         , ( 9, [".{...}", ".{.#}"], "")-         , (10, [".{...}", ".{.#}"], "")-         , (11, [".{...}", ".{.#}"], "")-         , (12, [".{...}", ".{.#}"], "")-    -- 12    mkPatN          :: Int -> Pat -> Bool-    -- 13    elidePats        :: Pat -> Pat -> [Int] -> Pat-    -- 14    erodePat        :: StdGen -> [Int] -> Pat -> (Pat, StdGen)-         ]-    putStrLn "==================================================="-    putStrLn "Testing miscellaneous PatUtil functions..."-    doit13 True test_patterns13-#endif--#if ! FOCUS_TEST--#if 1-    -- Testing fusion-    putStrLn "\nTesting fusion\n-fenable-rewrite-rules -O -ddump-rules -ddump-simpl-stats -ddump-rule-firings\n"-    let exp12 = (3.4, [5,__,7], __) :: (Float, [Int], Bool)-    let get12 (_,xs,_) = (xs!!2)-    putStrLn $ show $ get12 $ ( forcep ".:Bool{}" . forcep ".:Int{}" ) exp12-    putStrLn $ show $ get12 $ ( forcep ".:Bool{}" . forcep_ (compilePat ".:Int{}") ) exp12-    putStrLn $ show $ get12 $ ( forcep_ (compilePat ".:Bool{}") . forcep ".:Int{}" ) exp12-    putStrLn $ show $ get12 $ ( forcep_ (compilePat ".:Bool{}") . forcep_ (compilePat ".:Int{}") ) exp12-#endif--#if 1-    putStrLn $ intercalate "\n"-     [ ""-     , "expN_1 = [__] :: [Int]"-     , "expN_2 = [0,1,__,3] :: [Int]"-     , "expN_3 = (3.4, [5,__,7], True) :: (Float, [Int], Bool)"-     , "expN_4 = (3.4, [5,__,7], __) :: (Float, [Int], Bool)"-     , ""-     , "getN_1 xs = show $ ()"---   , "getN_1 xs = show $ head xs"---   , "getN_2 xs = show $ (xs!!1)"-     , "getN_2 xs = show $ (xs!!3)"-     , "getN_3 (_,xs,_) = show $ (xs!!2)"-     ]-    doit5 1 0 1 "" >>= putStrLn-    doit6 1 0 1 "" >>= putStrLn-    doit7 1 0 1 "" >>= putStrLn-    doit8 1 0 1 "" >>= putStrLn-#if 0-    doit9 >>= putStrLn  -- XXX broken (whatever it is)-#endif-#endif--#if 1-    putStr hdline-    putStrLn "Testing generic GNFDataN (refer to Foo.hs for the defs).\n"-    putStr hline-#if 0-#if ! USE_SOP-    putStrLn $ show $ from expTE_1-    putStrLn $ show $ from $ F 23-    putStrLn $ show $ from $ Just 11  -- bad comparison: two constructors!-#endif---  putStrLn $ show $ from $ Just (undefined::Int)---  putStrLn $ show $ from expTE_2---  putStrLn $ show $ from expTE_3-    putStr "\n"-    putStrLn $ ""-           ++ "expBase7 = B2 (A1 True 4) (B1 True (A2 undefined))\n"-           ++ "expBase8 = B2 (A1 undefined 4) (B1 True (A2 undefined))\n"-           ++ "expBase9 = B2 (A1 undefined 4) (B1 undefined (A2 undefined))\n"-           ++ "...\n"-           ++ "getB_1 (B2 _ (B1 b _)) = b\n"-           ++ "getB_2 (B2 (A1 _ n) _) = n\n"-#endif-    s2 <- doit2 1 0 1 ""-    putStrLn s2-#if 0-    putStrLn $ ""-           ++ "expTB_15 = (A3 (B3 False undefined 5) False)\n"-           ++ "getA (A3 _ b) = show b\n"-    s3 <- doit3 1 1 1 ""-    putStrLn s3-#endif-#endif--#if 0-    s4 <- doit4 1 0 1 ""-    putStrLn s4-#endif--#if 0-    putStrLn $ ""-           ++ "expBase1 = ([True,False],3,Just \"fox\")         :: ([Bool],Int,Maybe String)\n"-           ++ "expBase2 = ([True,False],__,Just \"fox\")        :: ([Bool],Int,Maybe String)\n"-           ++ "expBase3 = ([True,__],3,Just \"fox\")            :: ([Bool],Int,Maybe String)\n"-           ++ "expBase4 = ([True,__],3,Just __)               :: ([Bool],Int,Maybe String)\n"-           ++ "expBase5 = ([True,False],3,Just ['f',__,'x'])  :: ([Bool],Int,Maybe String)\n"-           ++ "expBase6 = ([True,False],3,Just __)            :: ([Bool],Int,Maybe String)\n"-           ++ "get1 ((x:_),_,_) = x           -- True\n"-           ++ "get2 (_,x,_) = x               -- 3\n"-           ++ "get3 (_,_,x) = fromJust x      -- \"fox\"\n"-           ++ "get4 (_,_,Just (x:_)) = x      -- 'f'\n"-    s1 <- doit1 1 1 1 ""-    putStrLn s1-#endif--#if USE_SOP--#if 1-    -- Testing rnfpDyn -- working-    putStrLn "\nTesting SOP rnfpDyn with SYB generic stop condition.\n"-#if 1-    let exp21 = (3.4, [5,__,7], __) :: (Float, [Int], Bool)-    let get21 (_,xs,_) = (xs!!2)-    let f21_a :: [Int] -> PatNode-        f21_a _ = WI-    let f21_b :: Bool -> PatNode-        f21_b _ = WI-    let fg21 :: GenericQ PatNode-        fg21 = mkQ WR f21_a `extQ` f21_b---  let fg21 = mkQ WR f21_a `extQ` f21_b :: forall a. Data a => a -> PatNode---  let fg21 = mkQ WR f21_a `extQ` f21_b :: GenericQ PatNode-    putStrLn $ show $ get21 $ forcepDyn fg21 exp21-#else-    let exp21 = (3.4, [5,__,7], False) :: (Float, [Int], Bool)-    let get21 (_,xs,_) = (xs!!2)-#if 0-#elif 1-    let f21 :: [Int] -> PatNode-        f21 _ = WI-    let fg21 :: GenericQ PatNode-        fg21 = mkQ WR f21-#elif 0-    let f21 :: (Float,[Int],Bool) -> PatNode-    -- Cannot do in SYB? We can't just "stop on any 3-tuple"; we need-    -- to give the types of the components of the tuple as well?---  let f21 :: (,,) a b c -> PatNode---  let f21 :: (,,) * * * -> PatNode---  let f21 :: (,,) -> PatNode---  let f21 :: (a,b,c) -> PatNode---  let f21 :: (Typeable a,Typeable b,Typeable c) => (a,b,c) -> PatNode---  let f21 :: (Data a,Typeable a,Data b,Typeable b,Data c,Typeable c) => (a,b,c) -> PatNode-        f21 _ = WI---      f21 (x,y,z) = WI-    let fg21 :: GenericQ PatNode-        fg21 = mkQ WR f21-#elif 0-    let f21 :: Int -> PatNode-        f21 x = WI---      f21 x = case x of { 5 -> WR ; _ -> WI }  -- "case x" forces x!---  let (f21::Int->PatNode) x = case x of { 5 -> WR ; _ -> WI }-    let fg21 :: GenericQ PatNode-        fg21 = mkQ WR f21-#endif-    putStrLn $ show $ get21 $ forcepDyn fg21 exp21-#endif-#endif--#if 1-    -- Testing rnfpDyn again -- not working...-    putStrLn "\nTesting SOP/SYB rnfpDyn again.\n"-#if 0-#elif 1-    let exp22 = [[[__]],[[__,6],[7]]] :: [[[Int]]]--- These three should be exactly equivalent (same core produced)?---  let get22 xs = (((xs!!1)!!1)!!0)---  let get22 [_,[[_,n],_]] = n-    let get22 (_:((_:n:_):_):_) = n-    let f22a :: Int -> PatNode-        f22a _ = trace "Noo-A" $ WI-    let f22b :: [Int] -> PatNode-        f22b _ = trace "Noo-B" $ WI-    let f22c :: [[Int]] -> PatNode-        f22c _ = trace "Noo-C" $ WI-    let f22d :: [[[Int]]] -> PatNode  -- goes boom-        f22d _ = trace "Noo-D" $ WI-    let fg22 :: GenericQ PatNode-        fg22 = mkQ WR id---                                                              -- blows---                                                 `extQ` f22d  -- blows-                                       `extQ` f22c `extQ` f22d  -- FINE---                         `extQ` f22b `extQ` f22c `extQ` f22d  -- FINE---             `extQ` f22a `extQ` f22b `extQ` f22c              -- blows---             `extQ` f22a `extQ` f22b `extQ` f22c `extQ` f22d  -- FINE-#elif 0-    let exp22 = [[[__]],[[__,6],__,[7]]] :: [[[Int]]]-    let get22 xs = (((xs!!1)!!2)!!0)-    let f22 :: Int -> PatNode        -- goes boom---  let f22 :: [Int] -> PatNode      -- goes boom---  let f22 :: [[Int]] -> PatNode    -- goes boom---  let f22 :: [[[Int]]] -> PatNode  -- goes boom-        f22 _ = trace "Noo-A" $ WI-    let fg22 :: GenericQ PatNode-        fg22 = mkQ WR f22-#else-    let exp22 = (3.4, [[[__]],[[__,6],__,[7]]], __) :: (Float, [[[Int]]], Bool)---  let exp22 = (3.4, [[__],[[__,6],__,[7]]], __) :: (Float, [[[Int]]], Bool)-    let get22 (_,xs,_) = (((xs!!1)!!2)!!0)-    let f22_a :: [[Int]] -> PatNode-        f22_a _ = WI-    let f22_b :: Bool -> PatNode-        f22_b _ = WI-    let fg22 :: GenericQ PatNode-        fg22 = mkQ WR f22_a `extQ` f22_b---  let fg22 = mkQ WR f22_a `extQ` f22_b :: forall a. Data a => a -> PatNode---  let fg22 = mkQ WR f22_a `extQ` f22_b :: GenericQ PatNode-#endif-    putStrLn $ show $ get22 $ forcepDyn fg22 exp22-#endif--#if 1-#if __GLASGOW_HASKELL__ >= 708--- XXX This isn't working yet.--- And it won't work naively either, b/c SOP is *shallow*...--- Note:--- *Foo> :m +Generics.SOP--- *Foo Generics.SOP> datatypeInfo (Proxy :: Proxy [[Int]])--- ADT "GHC.Types" "[]" (Constructor "[]" :* (Infix ":" RightAssociative 5 :* Nil))--- So, as done in GNFDataP, we need to pattern-match in tandem on this,--- through the *S and *P SOP recursion auxilliaries...--- XXX I came back to this -- getting type errors, could probably--- get rid of by adding extra functions (as per GNFDataP.hs code),--- but remember, this is supposed to be API-user code ... if it's--- going to be that painful to write, we have a problem...--- (Still, can probably write friendlier wrapper functions.)-    -- Testing rnfpDyn' with SOP generic stop condition-    putStrLn "\nTesting SOP rnfpDyn' with SOP generic stop condition.\n"-#if 0-#elif 1-    putStrLn $ doit23-#elif 0-    let exp23 = [[[__]],[[__,6],__,[7]]] :: [[[Int]]]-    let get23 xs = (((xs!!1)!!2)!!0)-    let fg23 :: forall a. (Generic a, HasDatatypeInfo a) => a -> PatNode-        fg23 d | cname == "[[Int]]"  = WI-               | otherwise           = WR-          where-#if 1-           ADT mname tname (Constructor cname :* _) = dti---         ADT mname tname (Constructor cname :* _) = dti :: DatatypeInfo (Code a)---         (mname,tname,cname) = case dti of ...---         ADT mname tname (Constructor cname :* (Infix ":" RightAssociative 5 :* Nil)) = dti-#endif-           dti = datatypeInfo proxy_a-           proxy_a = Proxy :: Proxy a-           xrep = from d-    putStrLn $ show $ get23 $ forcepDyn' fg23 exp23-#endif-#endif-#endif--#if 1--- Gave up on the fully-SOP one, at least for now, b/c--- it seems like it's hard to write (much uglier than SYB one),--- and then writing a friendly wrapper looks tough as well.--- But here is a 3rd alternative, hybrid SOP/Typeable which--- is even simpler from the user perspective, only less efficient.-    putStrLn "Testing SOP rnfpDyn'' with Typeable generic stop condition\n"-    let exp24 = [[[__]],[[__,6],__,[7]]] :: [[[Int]]]-    let get24 xs = (((xs!!1)!!2)!!0)-    let fg24 :: forall a. Typeable a => a -> PatNode-        fg24 d | t == "[[[Int]]]"  = WI-               | t == "[[Int]]"    = WI-               | otherwise         = WR-         where t = show $ typeOf d-    -- This is a simple alternative to the SOP/SYB hybrid.-    -- If efficiency isn't prime concern, this would appear to be-    -- even simpler ... the above looks much more lucid to me than-    -- the usual SYB way of mkQ/extQ; here, just define one normal-    -- function, and away you go...-    putStrLn $ show $ get24 $ forcepDyn'' fg24 exp24-#endif--#endif--#endif--#if ! FOCUS_TEST--#if 1-    putStrLn "\nTesting Seqable class (tuple with list):\n"-    let test_patterns24 = [-           (1,  1, (3.4, [5, __, 7], False))                        -- okay-         , (2,  2, fP (3.4, fP (5 : fP (__ : fP (7 : []))), __))    -- okay-         , (2,  3, fP (3.4, fP (5 : fI (__ : fP (7 : []))), __))    -- okay-         , (1,  4, fI (3.4, fP (5 : fI (__ : fP (7 : []))), __))    -- XXX-         , (1,  5, fI (3.4, fI (5 : fI (__ : fP (7 : []))), __))    -- okay-         , (2,  6, fI (3.4, fI (5 : fP (__ : fP (7 : []))), __))    -- okay-         , (1,  7, fI (3.4, fP (5 : fI (__ : fP (7 : []))), True))  -- XXX-         , (1,  8, fP (3.4, fI (5 : fI (__ : fP (7 : []))), True))  -- XXX-         , (1,  9, fP (3.4, fI (5 : fI (__ : fI (7 : []))), True))  -- XXX-         ] :: [(Int,Int,(Float,[Int],Bool))]-    doit24 True test_patterns24-#endif--#if 1-    putStrLn "\nTesting Seqable class (nested tuples):\n"-    let test_patterns25 = [-           (1,  1, (3.4, (__, 7), False))       -- okay-         , (1,  2, fI (3.4 ,fI (__, 7) ,__))    -- okay-         , (2,  3, fP (3.4 ,fP (__, 7) ,__))    -- XXX-         , (2,  4, fP (3.4 ,fI (__, 7) ,__))    -- XXX-         , (2,  5, fI (3.4 ,fP (__, 7) ,__))    -- XXX-         , (1,  6, fI (3.4 ,fI (__, 7) ,True))  -- okay-         , (2,  7, fP (3.4 ,fP (__, 7) ,True))  -- XXX-         , (1,  8, fP (3.4 ,fI (__, 7) ,True))  -- okay-         , (2,  9, fI (3.4 ,fP (__, 7) ,True))  -- XXX-         ] :: [(Int,Int,(Float,(Bool,Int),Bool))]-    doit25 True test_patterns25-#endif--#if USE_SOP--#if 1-    putStrLn "\nTesting generic Seqable (tuple with list):\n"-    let test_patterns26 = [-           (1,  1, (3.4, [5, __, 7], False))                        -- okay-         , (2,  2, gP (3.4, gP (5 : gP (__ : gP (7 : []))), __))    -- okay-         , (2,  3, gP (3.4, gP (5 : gI (__ : gP (7 : []))), __))    -- okay-         , (1,  4, gI (3.4, gP (5 : gI (__ : gP (7 : []))), __))    -- XXX-         , (1,  5, gI (3.4, gI (5 : gI (__ : gP (7 : []))), __))    -- okay-         , (2,  6, gI (3.4, gI (5 : gP (__ : gP (7 : []))), __))    -- okay-         , (1,  7, gI (3.4, gP (5 : gI (__ : gP (7 : []))), True))  -- XXX-         , (1,  8, gP (3.4, gI (5 : gI (__ : gP (7 : []))), True))  -- XXX-         , (1,  9, gP (3.4, gI (5 : gI (__ : gI (7 : []))), True))  -- XXX-         ] :: [(Int,Int,(Float,[Int],Bool))]-    doit26 True test_patterns26-#endif--#if 1-    putStrLn "\nTesting generic Seqable (expTJ_*):\n"--- expTJ_1 = J2 ( 1, J4 ( J3, K3 K2 ( J1 4.5))) False     -- for ref.--- expTJ_2 = J2 ( 1, J4 ( J3, K3 __ ( J1 4.5))) False--- expTJ_3 = J2 ( 1, J4 ( __, K3 K2 ( J1 4.5))) False--- expTJ_4 = J2 ( 1, J4 ( __, K3 __ ( J1 4.5))) __        -- in use-    let test_patterns27 = [-           (1,  1, gI (J2 (gI ( 1, gI (J4 (gI ( __, gI (K3 __ ( gI (J1 4.5)))))))) __))-         , (2,  2, gP (J2 (gP ( 1, gP (J4 (gP ( __, gP (K3 __ ( gP (J1 4.5)))))))) __))-         , (1,  3, gI (J2 (gP ( 1, gP (J4 (gI ( __, gI (K3 __ ( gP (J1 4.5)))))))) __))-         , (2,  4, gP (J2 (gP ( 1, gP (J4 (gI ( __, gI (K3 __ ( gP (J1 4.5)))))))) __))-         , (2,  5, gI (J2 (gP ( 1, gP (J4 (gP ( __, gI (K3 __ ( gP (J1 4.5)))))))) __))-         , (2,  6, gI (J2 (gP ( 1, gP (J4 (gI ( __, gP (K3 __ ( gP (J1 4.5)))))))) __))-         ] :: [(Int,Int,TJ)]-    doit27 True test_patterns27-    putStrLn "\n"-#endif--#endif--#endif--    return 0-----------------------------------------------------------------------------------  hline :: String-  hline = "---------------------------------------------------\n"-  hdline :: String-  hdline = "===================================================\n"-----------------------------------------------------------------------------------  doit1 :: Int -> Int -> Int -> String -> IO String-  doit1 i j k acc-   -- this glitch (the exception that seemingly escapes my catch)-   -- happens just for these combos (and for all j):--- | i == 3 && k == 4  = doit1 (1+i) j k acc  -- trying to avoid a glitch...--- | i == 3 && k == 5  = doit1 (1+i) j k acc  -- trying to avoid a glitch...--- | i == 3 && j < 4 && k == 5  = doit1 (1+i) j k acc  -- trying to avoid a glitch...-   | k == 7  = return acc-   | j == 6  = doit1 1 1 (1+k) acc-   | i == 5  = doit1 1 (1+j) k acc-   | otherwise  = do-      fexp <- catch-               -- The semantics of the !'s here are not what they were,-               -- since forcing in some places. [?] But at least the-               -- first one seems definitely still needed...-               -- LATER: The second one is also needed, finally seen!-               -- (It is needed for a version of getE _ = "getee", only.)-               -- XXX I'm just not sure whether the second ! is better-               -- to leave in or leave out...-               ( return $! get $! forcen dep exp )-               (\e -> do let err = show (e :: ErrorCall)---             (\e -> do let err = show (e :: BottomedOut)-                         return err)---    doit1 (1+i) j k $! force $ acc-      doit1 (1+i) j k $! acc---    doit1 (1+i) j k $ acc-        ++ "( get" ++ show i ++ " $ forcen " ++ show dep ++ " expBase" ++ show k ++ " )  "-        ++ fexp ++ "\n"-   where-    exp = case k of-            1 -> expBase1-            2 -> expBase2-            3 -> expBase3-            4 -> expBase4-            5 -> expBase5-            6 -> expBase6-    get = case i of-           1 -> get1-           2 -> get2---         3 -> unsafePerformIO . get3  -- yeesh!...---         3 -> get3-           3 -> get3 (i,j,k)-           4 -> get4-    dep = j--  -- XXX All this fuss to deal with the case that the-  -- entire argument m is undefined (or whatever is going-  -- for "undefined" at the moment...) -- but, none of-  -- the expBase[1-5] have this! ch.-  myFromJust :: Maybe a -> IO (Either () a)-  myFromJust m = do-                    putStrLn "Boo!"-                    catch-                      (myFromJust' m)-                      (\e -> do putStrLn $! show (e::BottomedOut)-                                putStrLn "HERE!"-                                return $! Left ())-  myFromJust' :: Maybe a -> IO (Either () a)-  myFromJust' Nothing = do---                         throw BottomedOut-                           return $! Left ()-  myFromJust' (Just x) = return $! Right x---myFromJust _ = throw BottomedOut------------------------------------  doit2 :: Int -> Int -> Int -> String -> IO String-  doit2 i j k acc--- | k == 2  = {- trace (show (i,j,k)) $ -} return acc--- | k == 7  = return acc-   | k == 27  = return acc--- | k == 21  = return acc--- | k == 5  = return acc--- | j == 15  = doit2 1 0 (1+k) acc-   | j == 11  = {- trace (show (i,j,k)) $ -} doit2 1 0 (1+k) acc--- | j == 8  = {- trace (show (i,j,k)) $ -} doit2 1 0 (1+k) acc--- | j == 3  = {- trace (show (i,j,k)) $ -} doit2 1 0 (1+k) acc-#if USE_TRACE-   | i == 2  = trace ("End of " ++ show (i,j',k')) $ doit2 1 (1+j) k acc--- | i == 3  = trace ("End of " ++ show (i,j',k')) $ doit2 1 (1+j) k acc-#else-   | i == 2  = doit2 1 (1+j) k acc--- | i == 3  = doit2 1 (1+j) k acc-#endif-   | otherwise  = do-      fexp <- catch-               ( return $! get $! forcen dep exp )---             ( return $! get $! forcen dep exp )-               -- ErrorCall if use __ = undefined-               -- BottomedOut if use __ = throw BottomedOut-               (\e -> do let err = show (e :: ErrorCall)---             (\e -> do let err = show (e :: BottomedOut)-                         return err)-      doit2 (1+i) j k $! acc-        ++ "( getB_" ++ show i ++ " $ forcen " ++ show dep ++ (if dep < 10 then " " else "") ++ " expTB_" ++ show (k'-6) ++ " )  "---      ++ "( getB_" ++ show i ++ " $ forcen " ++ show dep ++ (if dep < 10 then " " else "") ++ " expBase" ++ show k' ++ " )  "-        ++ fexp ++ "\n"-   where-    exp = case k' of-            7 -> expBase7-            8 -> expBase8-            9 -> expBase9-            10 -> expBase10-            11 -> expBase11-            12 -> expBase12-            13 -> expBase13-            14 -> expBase14-            15 -> expBase15-            16 -> expBase16-            17 -> expBase17-            18 -> expBase18-            19 -> expBase19-            20 -> expBase20-            21 -> expBase20  -- fudge it!!-            22 -> expBase22-            23 -> expBase23-            24 -> expBase24-            25 -> expBase25-            26 -> expBase26-            27 -> expBase27-            28 -> expBase28-            29 -> expBase29-            30 -> expBase30-            31 -> expBase31-            32 -> expBase32-    get = case i of-           1 -> if k' >= 27 then getB_3 else getB_1-           2 -> getB_2-    dep = j'-    j' = j---  j' = j+11---  k' = k+26-    k' = k+6--  doit3 :: Int -> Int -> Int -> String -> IO String-  doit3 i j k acc-   | k == 2  = return acc-   | j == 8  = {- trace (show (i,j,k)) $ -} doit3 1 1 (1+k) acc-#if USE_TRACE-   | i == 2  = trace ("End of " ++ show (i,j',k')) $ doit3 1 (1+j) k acc-#else-   | i == 2  = doit3 1 (1+j) k acc-#endif-   | otherwise  = do-      fexp <- catch-               ( return $! get $! forcen dep exp )-               -- ErrorCall if use __ = undefined-               -- BottomedOut if use __ = throw BottomedOut-               (\e -> do let err = show (e :: ErrorCall)---             (\e -> do let err = show (e :: BottomedOut)-                         return err)-      doit3 (1+i) j k $! acc-        ++ "( getB_" ++ show i ++ " $ forcen " ++ show dep ++ " expBase" ++ show k' ++ " )  "-        ++ fexp ++ "\n"-   where-    exp = case k' of-            21 -> expBase21-    get = case i of-           1 -> getA-    dep = j'-    i' = i-    j' = j-    k' = k+20--  doit4 :: Int -> Int -> Int -> String -> IO String-  doit4 i j k acc--- | k == 2  = return acc-   | k == 4  = return acc-   | j == 8  = {- trace (show (i,j,k)) $ -} doit4 1 0 (1+k) acc-#if USE_TRACE-   | i == 2  = trace ("End of " ++ show (i,j',k')) $ doit4 1 (1+j) k acc-#else-   | i == 2  = doit4 1 (1+j) k acc-#endif-   | otherwise  = do-      fexp <- catch-               ( return $! get $! forcen dep exp )-               -- ErrorCall if use __ = undefined-               -- BottomedOut if use __ = throw BottomedOut-               (\e -> do let err = show (e :: ErrorCall)---             (\e -> do let err = show (e :: BottomedOut)-                         return err)-      doit4 (1+i) j k $! acc-        ++ "( getE $ forcen " ++ show dep ++ " expTE_" ++ show k' ++ " )  "-        ++ fexp ++ "\n"-   where-    exp = case k' of-            1 -> expTE_1-            2 -> expTE_2-            3 -> expTE_3-    get = case i of-           1 -> getE-    dep = j'-    i' = i-    j' = j-    k' = k-----------------------------------------------------------------------------------  doit5 :: Int -> Int -> Int -> String -> IO String-  doit5 i j k acc-   | k == 2  = return acc-   | j == 5  = {- trace (show (i,j,k)) $ -} doit5 1 0 (1+k) acc-#if USE_TRACE-   | i == 2  = trace ("End of " ++ show (i,j',k')) $ doit5 1 (1+j) k acc-#else-   | i == 2  = doit5 1 (1+j) k acc-#endif-   | otherwise  = do-      fexp <- catch-               ( return $! get $! forcen dep exp )-               -- ErrorCall if use __ = undefined-               -- BottomedOut if use __ = throw BottomedOut-               (\e -> do let err = show (e :: ErrorCall)---             (\e -> do let err = show (e :: BottomedOut)-                         return err)-      doit5 (1+i) j k $! acc-        ++ "forcen " ++ show dep ++ " expN_" ++ show k' ++ " `seq` ()  =  "-        ++ fexp ++ "\n"-   where-    exp = case k' of-            1 -> expN_1-    get = case i of-           1 -> getN_1-    dep = j'-    i' = i-    j' = j-    k' = k-----------------------------------------------------------------------------------  doit6 :: Int -> Int -> Int -> String -> IO String-  doit6 i j k acc-   | k == 2  = return acc-   | j == 5  = {- trace (show (i,j,k)) $ -} doit6 1 0 (1+k) acc-#if USE_TRACE-   | i == 2  = trace ("End of " ++ show (i',j',k')) $ doit6 1 (1+j) k acc-#else-   | i == 2  = doit6 1 (1+j) k acc-#endif-   | otherwise  = do-      fexp <- catch-               ( return $! get $! forcen dep exp )-               -- ErrorCall if use __ = undefined-               -- BottomedOut if use __ = throw BottomedOut-               (\e -> do let err = show (e :: ErrorCall)---             (\e -> do let err = show (e :: BottomedOut)-                         return err)-      doit6 (1+i) j k $! acc-        ++ "getN_" ++ show i' ++" $ forcen " ++ show dep ++ " expN_" ++ show k' ++ "  =  "-        ++ fexp ++ "\n"-   where-    exp = case k' of-            _ -> expN_2-    get = case i of-           _ -> getN_2-    dep = j'-    i' = i+1-    j' = j-    k' = k+1-----------------------------------------------------------------------------------  doit7 :: Int -> Int -> Int -> String -> IO String-  doit7 i j k acc-   | k == 2  = return acc-   | j == 5  = {- trace (show (i,j,k)) $ -} doit7 1 0 (1+k) acc-#if USE_TRACE-   | i == 2  = trace ("End of " ++ show (i',j',k')) $ doit7 1 (1+j) k acc-#else-   | i == 2  = doit7 1 (1+j) k acc-#endif-   | otherwise  = do-      fexp <- catch-               ( return $! get $! forcen dep exp )-               -- ErrorCall if use __ = undefined-               -- BottomedOut if use __ = throw BottomedOut-               (\e -> do let err = show (e :: ErrorCall)---             (\e -> do let err = show (e :: BottomedOut)-                         return err)-      doit7 (1+i) j k $! acc-        ++ "getN_" ++ show i' ++" $ forcen " ++ show dep ++ " expN_" ++ show k' ++ "  =  "-        ++ fexp ++ "\n"-   where-    exp = case k' of-            _ -> expN_3-    get = case i of-           _ -> getN_3-    dep = j'-    i' = i+2-    j' = j-    k' = k+2-----------------------------------------------------------------------------------  doit8 :: Int -> Int -> Int -> String -> IO String-  doit8 i j k acc-   | k == 2  = return acc-   | j == 5  = {- trace (show (i,j,k)) $ -} doit8 1 0 (1+k) acc-#if USE_TRACE-   | i == 2  = trace ("End of " ++ show (i',j',k')) $ doit8 1 (1+j) k acc-#else-   | i == 2  = doit8 1 (1+j) k acc-#endif-   | otherwise  = do-      fexp <- catch-               ( return $! get $! forcen dep exp )-               -- ErrorCall if use __ = undefined-               -- BottomedOut if use __ = throw BottomedOut-               (\e -> do let err = show (e :: ErrorCall)---             (\e -> do let err = show (e :: BottomedOut)-                         return err)-      doit8 (1+i) j k $! acc-        ++ "getN_" ++ show i' ++" $ forcen " ++ show dep ++ " expN_" ++ show k' ++ "  =  "-        ++ fexp ++ "\n"-   where-    exp = case k' of-            _ -> expN_4-    get = case i of-           _ -> getN_3-    dep = j'-    i' = i+2-    j' = j-    k' = k+3-----------------------------------------------------------------------------------#if 0--#if 0-  expP_1 = (3.4, [5,__,7], __) :: (Float, [Int], Bool)-  patP_1 = Node (TR [typeOf ((__,__,__)::(Float, [Int], Bool))])-             [ Node (TR [typeOf (__::Bool)]) []---           [ Node (TR [typeOf (__::Float)]) []---           [ Node (NTR [typeOf (__::Bool)]) []---           [ Node (NTR [typeOf (__::Float)]) []---           , Node WS []-             , Node (TW [typeOf ([__]::[Int])]) []---           , Node (TR [typeOf ([__]::[Int])]) []---           , Node (TR [typeOf ([__]::[Int])]) [ Node WS [], Node WS [] ]  -- why not?-             , Node WW []---           , Node I []-             ]-  getP_1 (_,xs,_) = show $ (xs!!2)-#endif--  doit9 :: IO String-  doit9 = do-#if 0-    putStrLn $ intercalate "\n"-     [ ""-     , "expP_1 = (3.4, [5,__,7], __) :: (Float, [Int], Bool)"-     , "patP_1 = Node (T [typeOf ((__,__,__)::(Float, [Int], Bool))])"-     , "           [ Node W []"-     , "           , Node (T [typeOf ([__]::[Int])]) []"-     , "           , Node I []"-     , "           ]"-     , "getP_1 (_,xs,_) = show $ (xs!!2)"-     ]-    putStrLn "getP_1 $ forcep patP_1 expP_1"-#endif-    s <- catch-             ( return $! getP_1 $! forcep patP_1 expP_1 )---           ( return $! getP_2 $! forcep patP_2 expP_2 )---           ( return $! getP_3 $! forcep patP_3 expP_3 )-             -- ErrorCall if use __ = undefined-             -- BottomedOut if use __ = throw BottomedOut-             (\e -> do let err = show (e :: ErrorCall)---           (\e -> do let err = show (e :: BottomedOut)-                       return err)-    return s--#endif-----------------------------------------------------------------------------------  doit10 :: Bool -> [(Int,String)] -> IO ()-  doit10 _ [] = do-                   putStrLn "--------------------------------------------------"-                   return ()-  doit10 b ((code,patstr):t) = do-    let expect = case code of-                  1 -> "7"-                  2 -> "Prelude.undefined"-                  3 -> "pattern-match failure"-                  4 -> "syntax error"-                  5 -> "7 (but \"# with subpattern\" warning)"-                  6 -> "7 (but \"constraint/subpattern arity mismatch\" warning)"-                  13 -> "7 (but with pattern-match failure warning)"-                  23 -> "Prelude.undefined (but with pattern-match failure warning)"-                  _ -> error $ "doit10: unexpected code " ++ show code-    s <- catch-           ( do-                let exp = (3.4, [5,__,7], __) :: (Float, [Int], Bool)-                let pat = compilePat patstr-                let get (_,xs,_) = show $ (xs!!2)-                if b-                then do-                  putStrLn "==================================================="-                  putStrLn "exp = (3.4, [5,__,7], __) :: (Float, [Int], Bool)"-                  putStrLn "get (_,xs,_) = show $ (xs!!2)"-                  putStrLn "? = get $ forcep patstr exp"-                  putStrLn "==================================================="-                else do-                  putStrLn "---------------------------------------------------"-                putStrLn $ "patstr                   = " ++ patstr-                if code > 4-                then putStrLn $  "expected value           = " ++ expect-                else return ()---              putStrLn $ "pat = " ++ show pat-                putStrLn $ "showPat.compilePat       = " ++ showPat pat-                if code <= 4-                then putStrLn $  "expected value           = " ++ expect-                else return ()-                s1 <- catch-                        ( return $! force $! get $! forcep patstr exp )-                        (\e -> do let err = show (e :: ErrorCall)---                      (\e -> do let err = show (e :: BottomedOut)-                                  return err)-                putStr "actual value             = "-                return $! s1-           )-           -- ErrorCall if use __ = undefined-           -- BottomedOut if use __ = throw BottomedOut-           (\e -> do let err = show (e :: ErrorCall)---         (\e -> do let err = show (e :: BottomedOut)-                     return err)-    putStrLn s-    doit10 False t-----------------------------------------------------------------------------------  doit11 :: Bool -> [(Int,String,String)] -> IO ()-  doit11 _ [] = do-                   putStrLn "--------------------------------------------------"-                   return ()-  doit11 b ((code,patstr1,patstr2):t) = do-    let expect = case code of-                  1 -> "7"-                  2 -> "Prelude.undefined"-                  3 -> "pattern-match failure"-                  4 -> "syntax error"-                  5 -> "7 (but \"# with subpattern\" warning)"-                  6 -> "7 (but \"constraint/subpattern arity mismatch\" warning)"-                  _ -> error $ "doit11: unexpected code " ++ show code-    s <- catch-           ( do-                let exp = (3.4, [5,__,7], __) :: (Float, [Int], Bool)-                let patstrU = showPat $ unionPats [compilePat patstr1, compilePat patstr2]-                let pat1 = compilePat patstr1-                let pat2 = compilePat patstr2-                let patU = unionPats [pat1,pat2]-                let get (_,xs,_) = show $ (xs!!2)-                if b-                then do-                  putStrLn "==================================================="-                  putStrLn "exp = (3.4, [5,__,7], __) :: (Float, [Int], Bool)"-                  putStrLn "get (_,xs,_) = show $ (xs!!2)"-                  putStrLn "? = get $ ( forcep patstr2 . forcep patstr1 ) exp"---                putStrLn "? = get $ ( forcep ( unionPatsStr [ patstr1, patstr2 ] ) ) exp"-                  putStrLn "? = get $! ( forcep_ ( unionPats [ pat1, pat2 ] ) ) exp"-                  putStrLn "(Results were more interesting with a previous semantics...)."-                  putStrLn "==================================================="-                else do-                  putStrLn "---------------------------------------------------"-                putStrLn $ "patstr1                     = " ++ patstr1-                putStrLn $ "patstr2                     = " ++ patstr2-                putStrLn $ "patstrU                     = " ++ patstrU-                if code > 4-                then putStrLn $  "expected value              = " ++ expect-                else return ()---              putStrLn $ "pat = " ++ show pat-                putStrLn $ "showPat.compilePat patstr1  = " ++ showPat pat1-                putStrLn $ "showPat.compilePat patstr2  = " ++ showPat pat2-                putStrLn $ "showPat.compilePat patstrU  = " ++ showPat patU-                if code <= 4-                then putStrLn $  "expected value              = " ++ expect-                else return ()-                putStr "actual value                = "-                let s1 = get $! ( forcep patstr2 . forcep patstr1 ) exp-                putStrLn s1-                putStr "actual value                = "-                let s2 = get $! forcep patstrU exp-#if 1-                let s3 = s2-#else-                putStrLn s2-                let s3 = get $! forcep_ ( unionPats [ pat1, pat2 ] ) exp-#endif-                return $! s3-           )-           -- ErrorCall if use __ = undefined-           -- BottomedOut if use __ = throw BottomedOut-           (\e -> do let err = show (e :: ErrorCall)---         (\e -> do let err = show (e :: BottomedOut)-                     return err)-    putStrLn s-    doit11 False t-----------------------------------------------------------------------------------  doit12 :: Bool -> [(Int,String,[Int],[(Int,String)])] -> IO ()---doit12 :: Bool -> [(Int,String,String,[(Int,String)])] -> IO ()-  doit12 _ [] = do-                   return ()-  doit12 b ((code,patstr1,path,isibs'):t) = do-    let expect = case code of-                  1 -> "7"-                  2 -> "Prelude.undefined"-                  3 -> "pattern-match failure"-                  4 -> "syntax error"-                  5 -> "7 (but \"# with subpattern\" warning)"-                  6 -> "7 (but \"constraint/subpattern arity mismatch\" warning)"-                  _ -> error $ "doit12: unexpected code " ++ show code-    s <- catch-           ( do-                let target = compilePat patstr1---              let path = compilePat patstr2-                let isibs = map (\ (x,y) -> (x,compilePat y)) isibs'-                if b-                then do-                  putStr hdline-                  putStrLn "Testing splicePats."-                  putStr hline-                else return ()-                putStrLn $ "target       " ++ patstr1-                putStrLn $ "path         " ++ show path---              putStrLn $ "path         " ++ patstr2-                putStrLn $ "isibs        " ++ show isibs'-                let s1 = force $ showPat $ splicePats target path isibs---              let s1 = showPat $! splicePats target path isibs---              let s1 = showPat $ splicePats target path isibs-                putStr "result       "-                return $! s1-           )-           -- ErrorCall if use __ = undefined-           -- BottomedOut if use __ = throw BottomedOut-           (\e -> do let err = show (e :: ErrorCall)---         (\e -> do let err = show (e :: BottomedOut)-                     return err)-    putStrLn s-    if null t then return () else putStr hline-    doit12 False t-----------------------------------------------------------------------------------  doit12b :: Bool -> [(Int,String,[Int],[Int])] -> IO ()-  doit12b _ [] = do-                   return ()-  doit12b b ((code,patstr1,path,isibs'):t) = do-    let expect = case code of-                  1 -> "7"-                  2 -> "Prelude.undefined"-                  3 -> "pattern-match failure"-                  4 -> "syntax error"-                  5 -> "7 (but \"# with subpattern\" warning)"-                  6 -> "7 (but \"constraint/subpattern arity mismatch\" warning)"-                  _ -> error $ "doit12b: unexpected code " ++ show code-    s <- catch-           ( do-                let target = compilePat patstr1-                let isibs = isibs'-                if b-                then do-                  putStr hdline-                  putStrLn "Testing elidePats."-                  putStr hline-                else return ()-                putStrLn $ "target       " ++ patstr1-                putStrLn $ "path         " ++ show path-                putStrLn $ "isibs        " ++ show isibs'-                let s1 = force $ showPat $ elidePats target path isibs-                putStr "result       "-                return $! s1-           )-           -- ErrorCall if use __ = undefined-           -- BottomedOut if use __ = throw BottomedOut-           (\e -> do let err = show (e :: ErrorCall)---         (\e -> do let err = show (e :: BottomedOut)-                     return err)-    putStrLn s-    if null t then return () else putStr hline-    doit12b False t-----------------------------------------------------------------------------------  -- This is the first recursive test [much later than "12" would suggest].-  doit12c :: Bool -> [(Int,String,[Int])] -> StdGen -> Int -> IO StdGen---doit12c :: Bool -> [(Int,String,[Int],Int)] -> StdGen -> IO StdGen---doit12c :: Bool -> [(Int,String,StdGen,[Int],Int)] -> IO StdGen---doit12c :: Bool -> [(Int,String,StdGen,[Int],Int)] -> IO ()-  doit12c _ [] g _ = do-                   return g---                 return ()-  doit12c b lst@((code,patstr1,path):t) g 0 = return g-  doit12c b lst@((code,patstr1,path):t) g nreps = do  -- but singleton expected?-    let expect = case code of-                  1 -> "7"-                  2 -> "Prelude.undefined"-                  3 -> "pattern-match failure"-                  4 -> "syntax error"-                  5 -> "7 (but \"# with subpattern\" warning)"-                  6 -> "7 (but \"constraint/subpattern arity mismatch\" warning)"-                  _ -> error $ "doit12c: unexpected code " ++ show code-    (s, g') <- catch---  s <- catch-           ( do-                let target = compilePat patstr1-                if b-                then do-                  putStr hdline-                  putStrLn "Testing erodePat."-                  putStr hline-                else return ()-                putStrLn $ "target       " ++ patstr1-                putStrLn $ "stdgen       " ++ show g-                putStrLn $ "path         " ++ show path-                let (rslt, g') = erodePat g path target-                let s1 = force $ showPat $ rslt---              let s1 = force $ showPat $ erodePat g path target-                putStr "result       "-                return $! (s1, g')---              return $! s1-           )-           -- ErrorCall if use __ = undefined-           -- BottomedOut if use __ = throw BottomedOut-           (\e -> do let err = show (e :: ErrorCall)---         (\e -> do let err = show (e :: BottomedOut)-                     return (err, g))---                   return err)-    putStrLn s-    putStr hline-    doit12c False lst g' (-1+nreps)---  doit12c False t g' (-1+nreps)-----------------------------------------------------------------------------------  doit13 :: Bool -> [(Int,[String],String)] -> IO ()-  doit13 _ [] = do-                   putStr hline-                   return ()-  doit13 b ((code,patstrlst,expectstr):t) = do-    s <- catch-           ( do-                s1 <- case code of--- Where were they done already?--- Oh, in doit11 and doit12 above...-                       1 -> error $ hline ++ "unionPats test already done test13-1!"---                     4 -> error $ hline ++ "unionPatsStr test already done test13-4!"-                       10 -> error $ hline ++ "splicePats test already done test13-10!"-                       11 -> error $ hline ++ "isPath test already done test13-11!"-    --  1    unionPats       :: [ Pat ] -> Pat-    --  2  * intersectPats   :: [ Pat ] -> Pat-    --  3  * subPat          :: Pat -> Pat -> Bool---  --  4    unionPatsStr    :: [ String ] -> String-    --  5  * emptyPat        :: Pat-    --  6  * mkPat           :: forall d. Data d => d -> Pat-    --  7  * growPat         :: forall d. Data d => Pat -> d -> Pat-    --  8  * shrinkPat       :: Pat -> Pat-    --  9  * liftPats        :: [ Pat ] -> Pat-    -- 10    splicePats      :: Pat -> Pat -> [(Int, Pat)] -> Pat-    -- 11    isPath          :: Pat -> Bool-                       2 -> do-                               let patA = patstrlst!!0-                               let patB = patstrlst!!1-                               putStr hline-                               putStrLn "Testing      intersectPats [patA, patB]"-                               putStrLn $ "patA         " ++ patA-                               putStrLn $ "patB         " ++ patB-                               putStr $ "result       "-                               let s1 = force $ showPat $ intersectPats [compilePat patA, compilePat patB]-                               return s1-                       3 -> do-                               let patA = patstrlst!!0-                               let patB = patstrlst!!1-                               putStr hline-                               putStrLn "Testing      subPat patA patB"-                               putStrLn $ "patA         " ++ patA-                               putStrLn $ "patB         " ++ patB-                               let s1 = force $ show $ subPat (compilePat patA) (compilePat patB)-                               if s1 /= expectstr-                               then do putStrLn $ "expect       " ++ expectstr-                                       putStr $ "result       "-                               else putStr $ "as expected  "-                               return s1-                       5 -> do-                               putStr hline-                               putStrLn "Testing      emptyPat"-                               putStr $ "result       "-                               let s1 = force $ showPat $ emptyPat-                               return s1-                       6 -> do-                               putStr hline-                               putStrLn "Testing      mkPat ([1,2,3],(False,\"foo\"))"-                               putStr $ "result       "-                               let s1 = force $ showPat $ mkPat ([1,2,3::Int],(False,"foo"))-                               return s1-                       7 -> do-                               let patA = patstrlst!!0-                               putStr hline-                               putStrLn "Testing      growPat patA ([1,2,3],(False,\"foo\"))"-                               putStrLn $ "patA         " ++ patA-                               putStr $ "result       "-                               let s1 = force $ showPat $ growPat (compilePat patA) ([1,2,3::Int],(False,"foo"))-                               return s1-                       8 -> do-                               let patA = patstrlst!!0-                               putStr hline-                               putStrLn "Testing      shrinkPat patA"-                               putStrLn $ "patA         " ++ patA-                               putStr $ "result       "-                               let s1 = force $ showPat $ shrinkPat (compilePat patA)-                               return s1-                       9 -> do-                               putStr hline-                               putStrLn "Testing      liftPats patstrlst"-                               putStrLn $ "patstrs      " ++ show patstrlst-                               putStr $ "result       "-                               let s1 = force $ showPat $ liftPats $ map compilePat patstrlst-                               return s1-    -- 12    mkPatN          :: Int -> Pat -> Bool-    -- 13    elidePats        :: Pat -> Pat -> [Int] -> Pat-    -- 14    erodePat        :: StdGen -> [Int] -> Pat -> (Pat, StdGen)-                       12 -> do-                               putStr hline-                               putStrLn "Testing      mkPatN 2 ([1,2,3],(False,\"foo\"))"-                               putStr $ "result       "-                               let s1 = force $ showPat $ mkPatN 2 ([1,2,3::Int],(False,"foo"))-                               return s1-                       _ -> error $ "doit13: unexpected code " ++ show code-                return $! s1-           )-           -- ErrorCall if use __ = undefined-           -- BottomedOut if use __ = throw BottomedOut-           (\e -> do let err = show (e :: ErrorCall)---         (\e -> do let err = show (e :: BottomedOut)-                     return err)-    putStrLn s-    doit13 False t-----------------------------------------------------------------------------------  doit14 :: Bool -> [(Int,String)] -> IO ()-  doit14 _ [] = do-                   putStrLn "--------------------------------------------------"-                   return ()-  doit14 b ((code,patstr):t) = do-    let expect = case code of-                  1 -> "7"-                  2 -> "Prelude.undefined"-                  3 -> "pattern-match failure"-                  4 -> "syntax error"-                  5 -> "7 (but \"# with subpattern\" warning)"-                  6 -> "7 (but \"constraint/subpattern arity mismatch\" warning)"-                  13 -> "7 (but with pattern-match failure warning)"-                  23 -> "Prelude.undefined (but with pattern-match failure warning)"-                  _ -> error $ "doit14: unexpected code " ++ show code-    s <- catch-           ( do-                let exp = (3.4, [5,__,7], __) :: (Float, [Int], Bool)-                let pat = compilePat patstr-                let get (_,xs,_) = show $ (xs!!2)-                if b-                then do-                  putStrLn "==================================================="-                  putStrLn "exp = (3.4, [5,__,7], __) :: (Float, [Int], Bool)"-                  putStrLn "get (_,xs,_) = show $ (xs!!2)"-                  putStrLn "? = get $ forcep patstr exp"-                  putStrLn "==================================================="-                else do-                  putStrLn "---------------------------------------------------"-                putStrLn $ "patstr                   = " ++ patstr-                if code > 4-                then putStrLn $  "expected value           = " ++ expect-                else return ()---              putStrLn $ "pat = " ++ show pat-                putStrLn $ "showPat.compilePat       = " ++ showPat pat-                if code <= 4-                then putStrLn $  "expected value           = " ++ expect-                else return ()-                s1 <- catch-                        ( return $! force $! get $! forcep patstr exp )-                        (\e -> do let err = show (e :: ErrorCall)---                      (\e -> do let err = show (e :: BottomedOut)-                                  return err)-                putStr "actual value             = "-                return $! s1-           )-           -- ErrorCall if use __ = undefined-           -- BottomedOut if use __ = throw BottomedOut-           (\e -> do let err = show (e :: ErrorCall)---         (\e -> do let err = show (e :: BottomedOut)-                     return err)-    putStrLn s-    doit14 False t-----------------------------------------------------------------------------------#if USE_SOP--  -- This is an adaptation of doit10 to user-defined datatypes,-  -- for testing GNFDataP, which is finally within reach thanks-  -- to SOP!-  doit15 :: Bool -> [(Int,String)] -> IO ()-  doit15 _ [] = do-                   putStrLn "--------------------------------------------------"-                   return ()-  doit15 b ((code,patstr):t) = do-    let expect = case code of-                  1 -> "7"-                  2 -> "Prelude.undefined"-                  3 -> "pattern-match failure"-                  4 -> "syntax error"-                  5 -> "7 (but \"# with subpattern\" warning)"-                  6 -> "7 (but \"constraint/subpattern arity mismatch\" warning)"-                  13 -> "7 (but with pattern-match failure warning)"-                  23 -> "Prelude.undefined (but with pattern-match failure warning)"-                  _ -> error $ "doit15: unexpected code " ++ show code-    s <- catch-           ( do-                let exp = expTG_5  -- ( G1, G2 5 __ 7, __ )---              let exp = expTG_4  -- ( G1, G2 5 6 7, __ )---              let exp = expTG_3  -- ( G1, G2 __ __ 7, __ )---              let exp = expTG_2  -- ( __, G2 __ __ 7, __ )---              let exp = expTG_1  -- ( G1, G2 5 6 7, True )---              let exp = (3.4, [5,__,7], __) :: (Float, [Int], Bool)-                let pat = compilePat patstr-                let get = getG---              let get (_,xs,_) = show $ (xs!!2)-                if b-                then do-                  putStrLn "==================================================="-                  putStrLn "exp = (G1, G2 5 __ 7, __) :: (TG, TG, Bool)"-                  putStrLn "get (_,(G2 _ _ n),_) = n"-                  putStrLn "? = get $ forcep patstr exp"-                  putStrLn "==================================================="-                else do-                  putStrLn "---------------------------------------------------"-                putStrLn $ "patstr                   = " ++ patstr-                if code > 4-                then putStrLn $  "expected value           = " ++ expect-                else return ()---              putStrLn $ "pat = " ++ show pat-                putStrLn $ "showPat.compilePat       = " ++ showPat pat-                if code <= 4-                then putStrLn $  "expected value           = " ++ expect-                else return ()-                s1 <- catch-                        ( return $! force $! get $! forcep patstr exp )-                        (\e -> do let err = show (e :: ErrorCall)---                      (\e -> do let err = show (e :: BottomedOut)-                                  return err)-                putStr "actual value             = "-                return $! s1-           )-           -- ErrorCall if use __ = undefined-           -- BottomedOut if use __ = throw BottomedOut-           (\e -> do let err = show (e :: ErrorCall)---         (\e -> do let err = show (e :: BottomedOut)-                     return err)-    putStrLn s-    doit15 False t-----------------------------------------------------------------------------------  doit16 :: Bool -> [(Int,String)] -> IO ()-  doit16 _ [] = do-                   putStrLn "--------------------------------------------------"-                   return ()-  doit16 b ((code,patstr):t) = do-    let expect = case code of-                  1 -> "7"-                  2 -> "Prelude.undefined"-                  3 -> "pattern-match failure"-                  4 -> "syntax error"-                  5 -> "7 (but \"# with subpattern\" warning)"-                  6 -> "7 (but \"constraint/subpattern arity mismatch\" warning)"-                  13 -> "7 (but with pattern-match failure warning)"-                  23 -> "Prelude.undefined (but with pattern-match failure warning)"-                  _ -> error $ "doit16: unexpected code " ++ show code-    s <- catch-           ( do-                let exp = expTG_6  -- G2 5 __ 7-                let pat = compilePat patstr-                let get = getG'-                if b-                then do-                  putStrLn "==================================================="-                  putStrLn "exp = G2 5 __ 7 :: TG"-                  putStrLn "get (G2 _ _ n) = n"-                  putStrLn "? = get $ forcep patstr exp"-                  putStrLn "==================================================="-                else do-                  putStrLn "---------------------------------------------------"-                putStrLn $ "patstr                   = " ++ patstr-                if code > 4-                then putStrLn $  "expected value           = " ++ expect-                else return ()---              putStrLn $ "pat = " ++ show pat-                putStrLn $ "showPat.compilePat       = " ++ showPat pat-                if code <= 4-                then putStrLn $  "expected value           = " ++ expect-                else return ()-                s1 <- catch-                        ( return $! force $! get $! forcep patstr exp )-                        (\e -> do let err = show (e :: ErrorCall)---                      (\e -> do let err = show (e :: BottomedOut)-                                  return err)-                putStr "actual value             = "-                return $! s1-           )-           -- ErrorCall if use __ = undefined-           -- BottomedOut if use __ = throw BottomedOut-           (\e -> do let err = show (e :: ErrorCall)---         (\e -> do let err = show (e :: BottomedOut)-                     return err)-    putStrLn s-    doit16 False t-----------------------------------------------------------------------------------  doit17 :: Bool -> [(Int,String)] -> IO ()-  doit17 _ [] = do-                   putStrLn "--------------------------------------------------"-                   return ()-  doit17 b ((code,patstr):t) = do-    let expect = case code of-                  1 -> "4.5"-                  2 -> "Prelude.undefined"-                  3 -> "pattern-match failure"-                  4 -> "syntax error"-                  5 -> "4.5 (but \"# with subpattern\" warning)"-                  6 -> "4.5 (but \"constraint/subpattern arity mismatch\" warning)"-                  13 -> "4.5 (but with pattern-match failure warning)"-                  23 -> "Prelude.undefined (but with pattern-match failure warning)"-                  _ -> error $ "doit17: unexpected code " ++ show code-    s <- catch-           ( do---              let exp = expTH_1  -- H2 1 [H1 2.3, H3, H4 (H3, I3 I2 (H1 4.5))] False---              let exp = expTH_2  -- H2 1 [H1 2.3, H3, H4 (__, I3 I2 (H1 4.5))] False---              let exp = expTH_3  -- H2 1 [H1 2.3, H3, H4 (__, I3 I2 (H1 4.5))] __-                let exp = expTH_4  -- H2 1 [H1 2.3, H3, H4 (__, I3 __ (H1 4.5))] __-                let pat = compilePat patstr-                let get = getH-                if b-                then do-                  putStrLn "==================================================="-                  putStrLn "exp = H2 1 [H1 2.3, H3, H4 (__, I3 I2 (H1 4.5))] __ :: TH"---                putStrLn "exp = H2 1 [H1 2.3, H3, H4 (H3, I3 I2 (H1 4.5))] False :: TH"-                  putStrLn "get = (H2 _ [_, _, H4 (_, I3 _ (H1 f))] _) = show f"-                  putStrLn "? = get $ forcep patstr exp"-                  putStrLn "==================================================="-                else do-                  putStrLn "---------------------------------------------------"-                putStrLn $ "patstr                   = " ++ patstr-                if code > 4-                then putStrLn $  "expected value           = " ++ expect-                else return ()---              putStrLn $ "pat = " ++ show pat-                putStrLn $ "showPat.compilePat       = " ++ showPat pat-                if code <= 4-                then putStrLn $  "expected value           = " ++ expect-                else return ()-                s1 <- catch-                        ( return $! force $! get $! forcep patstr exp )-                        (\e -> do let err = show (e :: ErrorCall)---                      (\e -> do let err = show (e :: BottomedOut)-                                  return err)-                putStr "actual value             = "-                return $! s1-           )-           -- ErrorCall if use __ = undefined-           -- BottomedOut if use __ = throw BottomedOut-           (\e -> do let err = show (e :: ErrorCall)---         (\e -> do let err = show (e :: BottomedOut)-                     return err)-    putStrLn s-    doit17 False t-----------------------------------------------------------------------------------  doit18 :: Bool -> [(Int,String)] -> IO ()-  doit18 _ [] = do-                   putStrLn "--------------------------------------------------"-                   return ()-  doit18 b ((code,patstr):t) = do-    let expect = case code of-                  1 -> "4.5"-                  2 -> "Prelude.undefined"-                  3 -> "pattern-match failure"-                  4 -> "syntax error"-                  5 -> "4.5 (but \"# with subpattern\" warning)"-                  6 -> "4.5 (but \"constraint/subpattern arity mismatch\" warning)"-                  13 -> "4.5 (but with pattern-match failure warning)"-                  23 -> "Prelude.undefined (but with pattern-match failure warning)"-                  _ -> error $ "doit18: unexpected code " ++ show code-    s <- catch-           ( do---              let exp = expTJ_1  -- J2 (1, J4 (J3, K3 K2 (J1 4.5))) False---              let exp = expTJ_2  -- J2 (1, J4 (J3, K3 __ (J1 4.5))) False-                let exp = expTJ_3  -- J2 (1, J4 (__, K3 K2 (J1 4.5))) False---              let exp = expTJ_4  -- J2 (1, J4 (__, K3 __ (J1 4.5))) __-                let pat = compilePat patstr-                let get = getJ-                if b-                then do-                  putStrLn "==================================================="---                putStrLn "exp = J2 (1, J4 (J3, K3 K2 (J1 4.5))) False"-                  putStrLn "exp = J2 (1, J4 (J3, K3 __ (J1 4.5))) False"---                putStrLn "exp = J2 (1, J4 (__, K3 K2 (J1 4.5))) False"---                putStrLn "exp = J2 (1, J4 (__, K3 __ (J1 4.5))) __"-                  putStrLn "get = (J2 (_, J4 (_, K3 _ (J1 f))) _) = show f"-                  putStrLn "? = get $ forcep patstr exp"-                  putStrLn "==================================================="-                else do-                  putStrLn "---------------------------------------------------"-                putStrLn $ "patstr                   = " ++ patstr-                if code > 4-                then putStrLn $  "expected value           = " ++ expect-                else return ()---              putStrLn $ "pat = " ++ show pat-                putStrLn $ "showPat.compilePat       = " ++ showPat pat-                if code <= 4-                then putStrLn $  "expected value           = " ++ expect-                else return ()-                s1 <- catch-                        ( return $! force $! get $! forcep patstr exp )-                        (\e -> do let err = show (e :: ErrorCall)---                      (\e -> do let err = show (e :: BottomedOut)-                                  return err)-                putStr "actual value             = "-                return $! s1-           )-           -- ErrorCall if use __ = undefined-           -- BottomedOut if use __ = throw BottomedOut-           (\e -> do let err = show (e :: ErrorCall)---         (\e -> do let err = show (e :: BottomedOut)-                     return err)-    putStrLn s-    doit18 False t-----------------------------------------------------------------------------------  doit18b :: Bool -> [(Int,String)] -> IO ()-  doit18b _ [] = do-                   putStrLn "--------------------------------------------------"-                   return ()-  doit18b b ((code,patstr):t) = do-    let expect = case code of-                  1 -> "1"-                  2 -> "Prelude.undefined"-                  3 -> "pattern-match failure"-                  4 -> "syntax error"-                  5 -> "1 (but \"# with subpattern\" warning)"-                  6 -> "1 (but \"constraint/subpattern arity mismatch\" warning)"-                  13 -> "1 (but with pattern-match failure warning)"-                  23 -> "Prelude.undefined (but with pattern-match failure warning)"-                  _ -> error $ "doit18b: unexpected code " ++ show code-    s <- catch-           ( do-                let exp = expTJ_5  -- J2 (1, J4 (__, K2)) False-                let pat = compilePat patstr-                let get = getJ'-                if b-                then do-                  putStrLn "==================================================="-                  putStrLn "exp = J2 (1, J4 (__, K2)) False"-                  putStrLn "get ~_ = show 1  -- seems to suffice?!?..."---                putStrLn "get (J2 (n, J4 (_, K2)) False) = show n"-                  putStrLn "? = get $ forcep patstr exp"-                  putStrLn "==================================================="-                else do-                  putStrLn "---------------------------------------------------"-                putStrLn $ "patstr                   = " ++ patstr-                if code > 4-                then putStrLn $  "expected value           = " ++ expect-                else return ()---              putStrLn $ "pat = " ++ show pat-                putStrLn $ "showPat.compilePat       = " ++ showPat pat-                if code <= 4-                then putStrLn $  "expected value           = " ++ expect-                else return ()-                s1 <- catch-                        ( return $! force $! get $! forcep patstr exp )-                        (\e -> do let err = show (e :: ErrorCall)---                      (\e -> do let err = show (e :: BottomedOut)-                                  return err)-                putStr "actual value             = "-                return $! s1-           )-           -- ErrorCall if use __ = undefined-           -- BottomedOut if use __ = throw BottomedOut-           (\e -> do let err = show (e :: ErrorCall)---         (\e -> do let err = show (e :: BottomedOut)-                     return err)-    putStrLn s-    doit18b False t-----------------------------------------------------------------------------------  doit18c :: Bool -> [(Int,String)] -> IO ()-  doit18c _ [] = do-                   putStrLn "--------------------------------------------------"-                   return ()-  doit18c b ((code,patstr):t) = do-    let expect = case code of-                  1 -> "1"-                  2 -> "Prelude.undefined"-                  3 -> "pattern-match failure"-                  4 -> "syntax error"-                  5 -> "1 (but \"# with subpattern\" warning)"-                  6 -> "1 (but \"constraint/subpattern arity mismatch\" warning)"-                  13 -> "1 (but with pattern-match failure warning)"-                  23 -> "Prelude.undefined (but with pattern-match failure warning)"-                  _ -> error $ "doit18c: unexpected code " ++ show code-    s <- catch-           ( do-                let exp = expTJ_6  -- J4 (__, K2)-                let pat = compilePat patstr-                let get = getJ6-                if b-                then do-                  putStrLn "==================================================="-                  putStrLn "exp = J4 (__, K2)"-                  putStrLn "get ~_ = show 1  -- seems to suffice?!?..."---                putStrLn "get (J4 (_, K2)) = show n"-                  putStrLn "? = get $ forcep patstr exp"-                  putStrLn "==================================================="-                else do-                  putStrLn "---------------------------------------------------"-                putStrLn $ "patstr                   = " ++ patstr-                if code > 4-                then putStrLn $  "expected value           = " ++ expect-                else return ()---              putStrLn $ "pat = " ++ show pat-                putStrLn $ "showPat.compilePat       = " ++ showPat pat-                if code <= 4-                then putStrLn $  "expected value           = " ++ expect-                else return ()-                s1 <- catch-                        ( return $! force $! get $! forcep patstr exp )-                        (\e -> do let err = show (e :: ErrorCall)---                      (\e -> do let err = show (e :: BottomedOut)-                                  return err)-                putStr "actual value             = "-                return $! s1-           )-           -- ErrorCall if use __ = undefined-           -- BottomedOut if use __ = throw BottomedOut-           (\e -> do let err = show (e :: ErrorCall)---         (\e -> do let err = show (e :: BottomedOut)-                     return err)-    putStrLn s-    doit18c False t-----------------------------------------------------------------------------------  doit18d :: Bool -> [(Int,String)] -> IO ()-  doit18d _ [] = do-                   putStrLn "--------------------------------------------------"-                   return ()-  doit18d b ((code,patstr):t) = do-    let expect = case code of-                  1 -> "1"-                  2 -> "Prelude.undefined"-                  3 -> "pattern-match failure"-                  4 -> "syntax error"-                  5 -> "1 (but \"# with subpattern\" warning)"-                  6 -> "1 (but \"constraint/subpattern arity mismatch\" warning)"-                  13 -> "1 (but with pattern-match failure warning)"-                  23 -> "Prelude.undefined (but with pattern-match failure warning)"-                  _ -> error $ "doit18d: unexpected code " ++ show code-    s <- catch-           ( do-                let exp = expTJ_7  -- (__, K2)-                let pat = compilePat patstr-                let get = getJ7-                if b-                then do-                  putStrLn "==================================================="-                  putStrLn "exp = (__, K2)"-                  putStrLn "get ~_ = show 1  -- seems to suffice?!?..."-                  putStrLn "? = get $ forcep patstr exp"-                  putStrLn "==================================================="-                else do-                  putStrLn "---------------------------------------------------"-                putStrLn $ "patstr                   = " ++ patstr-                if code > 4-                then putStrLn $  "expected value           = " ++ expect-                else return ()---              putStrLn $ "pat = " ++ show pat-                putStrLn $ "showPat.compilePat       = " ++ showPat pat-                if code <= 4-                then putStrLn $  "expected value           = " ++ expect-                else return ()-                s1 <- catch-                        ( return $! force $! get $! forcep patstr exp )-                        (\e -> do let err = show (e :: ErrorCall)---                      (\e -> do let err = show (e :: BottomedOut)-                                  return err)-                putStr "actual value             = "-                return $! s1-           )-           -- ErrorCall if use __ = undefined-           -- BottomedOut if use __ = throw BottomedOut-           (\e -> do let err = show (e :: ErrorCall)---         (\e -> do let err = show (e :: BottomedOut)-                     return err)-    putStrLn s-    doit18d False t-----------------------------------------------------------------------------------  doit18e :: Bool -> [(Int,String)] -> IO ()-  doit18e _ [] = do-                   putStrLn "--------------------------------------------------"-                   return ()-  doit18e b ((code,patstr):t) = do-    let expect = case code of-                  1 -> "1"-                  2 -> "Prelude.undefined"-                  3 -> "pattern-match failure"-                  4 -> "syntax error"-                  5 -> "1 (but \"# with subpattern\" warning)"-                  6 -> "1 (but \"constraint/subpattern arity mismatch\" warning)"-                  13 -> "1 (but with pattern-match failure warning)"-                  23 -> "Prelude.undefined (but with pattern-match failure warning)"-                  _ -> error $ "doit18e: unexpected code " ++ show code-    s <- catch-           ( do-                let exp = expTJ_8  -- __ :: TJ-                let pat = compilePat patstr-                let get = getJ8-                if b-                then do-                  putStrLn "==================================================="-                  putStrLn "exp = __ :: TJ"-                  putStrLn "get ~_ = show 1  -- seems to suffice?!?..."-                  putStrLn "? = get $ forcep patstr exp"-                  putStrLn "==================================================="-                else do-                  putStrLn "---------------------------------------------------"-                putStrLn $ "patstr                   = " ++ patstr-                if code > 4-                then putStrLn $  "expected value           = " ++ expect-                else return ()---              putStrLn $ "pat = " ++ show pat-                putStrLn $ "showPat.compilePat       = " ++ showPat pat-                if code <= 4-                then putStrLn $  "expected value           = " ++ expect-                else return ()-                s1 <- catch-                        ( return $! force $! get $! forcep patstr exp )-                        (\e -> do let err = show (e :: ErrorCall)---                      (\e -> do let err = show (e :: BottomedOut)-                                  return err)-                putStr "actual value             = "-                return $! s1-           )-           -- ErrorCall if use __ = undefined-           -- BottomedOut if use __ = throw BottomedOut-           (\e -> do let err = show (e :: ErrorCall)---         (\e -> do let err = show (e :: BottomedOut)-                     return err)-    putStrLn s-    doit18e False t-----------------------------------------------------------------------------------  doit18f :: Bool -> [(Int,String)] -> IO ()-  doit18f _ [] = do-                   putStrLn "--------------------------------------------------"-                   return ()-  doit18f b ((code,patstr):t) = do-    let expect = case code of-                  1 -> "okay"-                  2 -> "Prelude.undefined"-                  3 -> "pattern-match failure"-                  4 -> "syntax error"-                  5 -> "okay (but \"# with subpattern\" warning)"-                  6 -> "okay (but \"constraint/subpattern arity mismatch\" warning)"-                  13 -> "okay (but with pattern-match failure warning)"-                  23 -> "Prelude.undefined (but with pattern-match failure warning)"-                  _ -> error $ "doit18f: unexpected code " ++ show code-    s <- catch-           ( do-                let exp = (K5 (__::TJ))-                let pat = compilePat patstr-                let get _ = "okay"-                if b-                then do-                  putStrLn "==================================================="-                  putStrLn "exp = (K5 (__::TJ))"-                  putStrLn "get ~_ = show 1  -- seems to suffice?!?..."-                  putStrLn "? = get $ forcep patstr exp"-                  putStrLn "==================================================="-                else do-                  putStrLn "---------------------------------------------------"-                putStrLn $ "patstr                   = " ++ patstr-                if code > 4-                then putStrLn $  "expected value           = " ++ expect-                else return ()---              putStrLn $ "pat = " ++ show pat-                putStrLn $ "showPat.compilePat       = " ++ showPat pat-                if code <= 4-                then putStrLn $  "expected value           = " ++ expect-                else return ()-                s1 <- catch-                        ( return $! force $! get $! forcep patstr exp )-                        (\e -> do let err = show (e :: ErrorCall)---                      (\e -> do let err = show (e :: BottomedOut)-                                  return err)-                putStr "actual value             = "-                return $! s1-           )-           -- ErrorCall if use __ = undefined-           -- BottomedOut if use __ = throw BottomedOut-           (\e -> do let err = show (e :: ErrorCall)---         (\e -> do let err = show (e :: BottomedOut)-                     return err)-    putStrLn s-    doit18f False t------------------------------------------------------------------------------------  doit18g :: Bool -> [(Int,String)] -> IO ()-  doit18g _ [] = do-                   putStrLn "--------------------------------------------------"-                   return ()-  doit18g b ((code,patstr):t) = do-    let expect = case code of-                  1 -> "okay"-                  2 -> "Prelude.undefined"-                  3 -> "pattern-match failure"-                  4 -> "syntax error"-                  5 -> "okay (but \"# with subpattern\" warning)"-                  6 -> "okay (but \"constraint/subpattern arity mismatch\" warning)"-                  13 -> "okay (but with pattern-match failure warning)"-                  23 -> "Prelude.undefined (but with pattern-match failure warning)"-                  _ -> error $ "doit18g: unexpected code " ++ show code-    s <- catch-           ( do-#if TRY_THIS-                let exp = K3 (__::TK) J3-#else-                let exp = K3 K2 (__::TJ)-#endif-                let pat = compilePat patstr-                let get _ = "okay"-                if b-                then do-                  putStrLn "==================================================="-#if TRY_THIS-                  putStrLn "exp = K3 (__::TK) J3"-#else-                  putStrLn "exp = K3 K2 (__::TJ)"-#endif-                  putStrLn "get ~_ = show 1  -- seems to suffice?!?..."-                  putStrLn "? = get $ forcep patstr exp"-                  putStrLn "==================================================="-                else do-                  putStrLn "---------------------------------------------------"-                putStrLn $ "patstr                   = " ++ patstr-                if code > 4-                then putStrLn $  "expected value           = " ++ expect-                else return ()---              putStrLn $ "pat = " ++ show pat-                putStrLn $ "showPat.compilePat       = " ++ showPat pat-                if code <= 4-                then putStrLn $  "expected value           = " ++ expect-                else return ()-                s1 <- catch-                        ( return $! force $! get $! forcep patstr exp )-                        (\e -> do let err = show (e :: ErrorCall)---                      (\e -> do let err = show (e :: BottomedOut)-                                  return err)-                putStr "actual value             = "-                return $! s1-           )-           -- ErrorCall if use __ = undefined-           -- BottomedOut if use __ = throw BottomedOut-           (\e -> do let err = show (e :: ErrorCall)---         (\e -> do let err = show (e :: BottomedOut)-                     return err)-    putStrLn s-    doit18g False t-----------------------------------------------------------------------------------  doit19 :: Bool -> [(Int,String)] -> IO ()-  doit19 _ [] = do-                   putStrLn "--------------------------------------------------"-                   return ()-  doit19 b ((code,patstr):t) = do---  let expstr = "True"-    let expstr = "5.6"-    let expect = case code of-                  1 -> expstr-                  2 -> "Prelude.undefined"-                  3 -> "pattern-match failure"-                  4 -> "syntax error"-                  5 -> expstr ++ " (but \"# with subpattern\" warning)"-                  6 -> expstr ++ " (but \"constraint/subpattern arity mismatch\" warning)"-                  13 -> expstr ++ " (but with pattern-match failure warning)"-                  23 -> "Prelude.undefined (but with pattern-match failure warning)"-                  _ -> error $ "doit19: unexpected code " ++ show code-    s <- catch-           ( do---              let exp = expTL_1  -- L1 5.6 (M1 True)-                let exp = expTL_2  -- L1 5.6 (M1 __)---              let exp = expTL_3  -- L1 5.6 __---              let exp = expTL_4  -- L1 __ (M1 True)-                let pat = compilePat patstr-                let get = getL---              let get = getL'-                if b-                then do-                  putStrLn "==================================================="-                  putStrLn "exp = L1 5.6 (M1 __)"---                putStrLn "exp = L1 5.6 __"---                putStrLn "exp = L1 __ (M1 True)"-                  putStrLn "get (L1 f (M1 _)) = show f"---                putStrLn "get (L1 f _) = show f"---                putStrLn "get (L1 _ (M1 b)) = show b"-                  putStrLn "? = get $ forcep patstr exp"-                  putStrLn "==================================================="-                else do-                  putStrLn "---------------------------------------------------"-                putStrLn $ "patstr                   = " ++ patstr-                if code > 4-                then putStrLn $  "expected value           = " ++ expect-                else return ()---              putStrLn $ "pat = " ++ show pat-                putStrLn $ "showPat.compilePat       = " ++ showPat pat-                if code <= 4-                then putStrLn $  "expected value           = " ++ expect-                else return ()-                s1 <- catch-                        ( return $! force $! get $! forcep patstr exp )-                        (\e -> do let err = show (e :: ErrorCall)---                      (\e -> do let err = show (e :: BottomedOut)-                                  return err)-                putStr "actual value             = "-                return $! s1-           )-           -- ErrorCall if use __ = undefined-           -- BottomedOut if use __ = throw BottomedOut-           (\e -> do let err = show (e :: ErrorCall)---         (\e -> do let err = show (e :: BottomedOut)-                     return err)-    putStrLn s-    doit19 False t-----------------------------------------------------------------------------------  doit20 :: Bool -> [(Int,String)] -> IO ()-  doit20 _ [] = do-                   putStrLn "--------------------------------------------------"-                   return ()-  doit20 b ((code,patstr):t) = do-    let expect = case code of-                  1 -> "4.5"-                  2 -> "Prelude.undefined"-                  3 -> "pattern-match failure"-                  4 -> "syntax error"-                  5 -> "4.5 (but \"# with subpattern\" warning)"-                  6 -> "4.5 (but \"constraint/subpattern arity mismatch\" warning)"-                  13 -> "4.5 (but with pattern-match failure warning)"-                  23 -> "Prelude.undefined (but with pattern-match failure warning)"-                  _ -> error $ "doit20: unexpected code " ++ show code-    s <- catch-           ( do---              let exp = expTK_1  -- K3 K2 (J1 4.5)-                let exp = expTK_2  -- K3 __ (J1 4.5)-                let pat = compilePat patstr-                let get = getK-                if b-                then do-                  putStrLn "==================================================="---                putStrLn "exp = K3 K2 (J1 4.5)"-                  putStrLn "exp = K3 __ (J1 4.5)"-                  putStrLn "get = (K3 _ (J1 f)) = show f"-                  putStrLn "? = get $ forcep patstr exp"-                  putStrLn "==================================================="-                else do-                  putStrLn "---------------------------------------------------"-                putStrLn $ "patstr                   = " ++ patstr-                if code > 4-                then putStrLn $  "expected value           = " ++ expect-                else return ()---              putStrLn $ "pat = " ++ show pat-                putStrLn $ "showPat.compilePat       = " ++ showPat pat-                if code <= 4-                then putStrLn $  "expected value           = " ++ expect-                else return ()-                s1 <- catch-                        ( return $! force $! get $! forcep patstr exp )-                        (\e -> do let err = show (e :: ErrorCall)---                      (\e -> do let err = show (e :: BottomedOut)-                                  return err)-                putStr "actual value             = "-                return $! s1-           )-           -- ErrorCall if use __ = undefined-           -- BottomedOut if use __ = throw BottomedOut-           (\e -> do let err = show (e :: ErrorCall)---         (\e -> do let err = show (e :: BottomedOut)-                     return err)-    putStrLn s-    doit20 False t-----------------------------------------------------------------------------------#if __GLASGOW_HASKELL__ >= 708-  doit23 :: String-  doit23 = show $ fg23 exp23---doit23 = show $ get23 $ forcepDyn' fg23 exp23-   where-    exp23 = [[[__]],[[__,6],__,[7]]] :: [[[Int]]]-    get23 xs = (((xs!!1)!!2)!!0)-#if 0-    fg23 :: forall a. (Generic a, HasDatatypeInfo a) => a -> DatatypeInfo (Code a)-    fg23 d = dti-#else-    fg23 :: forall a. (Generic a, HasDatatypeInfo a, All2 Show (Code a), Typeable a) => a -> PatNode-#if 1-    fg23 d = doit23' dti proxy_a d (from d)-#else-    fg23 d | cname == "[[Int]]"  = WI-           | otherwise           = WR-#endif-#endif-     where---    ADT mname tname (Constructor cname :* _) = dti---    ADT mname tname (Constructor cname :* _) = dti :: DatatypeInfo (Code a)---    (mname,tname,cname) = case dti of ...---    ADT mname tname (Constructor cname :* (Infix ":" RightAssociative 5 :* Nil)) = dti-      dti = datatypeInfo proxy_a-      proxy_a = Proxy :: Proxy a-      xrep = from d--  doit23' :: forall a.-             (-               Generic a-             , HasDatatypeInfo a---           , All2 NFDataP (Code a)-             , All2 Show (Code a)-             , Typeable a---           , NFDataN a---           , NFDataP a-             ) =>-                     DatatypeInfo (Code a)-                  -> Proxy a-                  -> a-                  -> Rep a-                  -> PatNode-  doit23' (ADT     _ _ cs) proxy_a x xrep-   = doit23'' cs         proxy_a x xrep-  doit23' (Newtype _ _ c ) proxy_a x xrep-   = doit23'' (c :* Nil) proxy_a x xrep--  doit23'' :: forall a xss.-            (-              Generic a-            , HasDatatypeInfo a-            , All2 Show xss-            ) =>-                    NP ConstructorInfo xss-                 -> Proxy a-                 -> a-                 -> SOP I xss-                 -> PatNode-  doit23'' (m :* _) proxy_a x (SOP (Z xs))-   | tx == "[[Int]]"  = WI-   | otherwise        = WR-   where-    !_ = trace ("*** "++tx) $ ()-    tx | (Constructor n) <- m  = n-       | (Infix n _ _) <- m    = n-       | (Record n _) <- m     = n-  doit23'' (m :* ms) proxy_a x (SOP (S xss))-   = doit23'' ms proxy_a x (SOP xss)-  doit23'' _ _ _ _ = error "doit23'': unexpected case!!"-#endif-----------------------------------------------------------------------------------#endif--  doit24 :: Bool -> [(Int,Int,(Float,[Int],Bool))] -> IO ()-  doit24 _ [] = do-                   putStrLn "--------------------------------------------------"-                   return ()-  doit24 b ((code,ident,exp):t) = do-    let expect = case code of-                  1 -> "7"-                  2 -> "Prelude.undefined"-                  3 -> "pattern-match failure"-                  4 -> "syntax error"-                  5 -> "7 (but \"# with subpattern\" warning)"-                  6 -> "7 (but \"constraint/subpattern arity mismatch\" warning)"-                  13 -> "7 (but with pattern-match failure warning)"-                  23 -> "Prelude.undefined (but with pattern-match failure warning)"-                  _ -> error $ "doit24: unexpected code " ++ show code-    s <- catch-           ( do---              let exp = force_ Propagate (force_ Propagate 3.4, force_ Propagate (force_ Propagate 5 : (force_ Propagate __ : (force_ Propagate 7 : force_ Propagate []))), force_ Propagate __) :: (Float, [Int], Bool)---              let seq_exp = mkSeqableHarness exp---              let pat = compilePat patstr-                let get (_,xs,_) = show $ (xs!!2)-                if b-                then do-                  putStrLn "==================================================="-                  putStrLn "exp = <refer to test code>"-                  putStrLn "get (_,xs,_) = show $ (xs!!2)"-                  putStrLn "? = get $! exp"-                  putStrLn "==================================================="-                else do-                  putStrLn "---------------------------------------------------"---              putStrLn $ "patstr                   = " ++ patstr-                if code > 4-                then putStrLn $  show ident ++ " expected value           = " ++ expect-                else return ()---              putStrLn $ "pat = " ++ show pat---              putStrLn $ "showPat.compilePat       = " ++ showPat pat-                if code <= 4-                then putStrLn $  show ident ++ " expected value           = " ++ expect-                else return ()-                s1 <- catch-                        ( return $! force $! get $! exp )-                        (\e -> do let err = show (e :: ErrorCall)---                      (\e -> do let err = show (e :: BottomedOut)-                                  return err)-                putStr $ show ident ++ " actual value             = "-                return $! s1-           )-           -- ErrorCall if use __ = undefined-           -- BottomedOut if use __ = throw BottomedOut-           (\e -> do let err = show (e :: ErrorCall)---         (\e -> do let err = show (e :: BottomedOut)-                     return err)-    putStrLn s-    doit24 False t-----------------------------------------------------------------------------------  doit25 :: Bool -> [(Int,Int,(Float,(Bool,Int),Bool))] -> IO ()-  doit25 _ [] = do-                   putStrLn "--------------------------------------------------"-                   return ()-  doit25 b ((code,ident,exp):t) = do-    let expect = case code of-                  1 -> "7"-                  2 -> "Prelude.undefined"-                  3 -> "pattern-match failure"-                  4 -> "syntax error"-                  5 -> "7 (but \"# with subpattern\" warning)"-                  6 -> "7 (but \"constraint/subpattern arity mismatch\" warning)"-                  13 -> "7 (but with pattern-match failure warning)"-                  23 -> "Prelude.undefined (but with pattern-match failure warning)"-                  _ -> error $ "doit25: unexpected code " ++ show code-    s <- catch-           ( do---              let exp = force_ Propagate (force_ Propagate 3.4, force_ Propagate (force_ Propagate 5 : (force_ Propagate __ : (force_ Propagate 7 : force_ Propagate []))), force_ Propagate __) :: (Float, [Int], Bool)---              let seq_exp = mkSeqableHarness exp---              let pat = compilePat patstr-                let get (_,(_,x),_) = show x-                if b-                then do-                  putStrLn "==================================================="-                  putStrLn "exp = <refer to test code>"-                  putStrLn "get (_,(_,x),_) = show x"-                  putStrLn "? = get $! exp"-                  putStrLn "==================================================="-                else do-                  putStrLn "---------------------------------------------------"---              putStrLn $ "patstr                   = " ++ patstr-                if code > 4-                then putStrLn $  show ident ++ " expected value           = " ++ expect-                else return ()---              putStrLn $ "pat = " ++ show pat---              putStrLn $ "showPat.compilePat       = " ++ showPat pat-                if code <= 4-                then putStrLn $  show ident ++ " expected value           = " ++ expect-                else return ()-                s1 <- catch-                        ( return $! force $! get $! exp )-                        (\e -> do let err = show (e :: ErrorCall)---                      (\e -> do let err = show (e :: BottomedOut)-                                  return err)-                putStr $ show ident ++ " actual value             = "-                return $! s1-           )-           -- ErrorCall if use __ = undefined-           -- BottomedOut if use __ = throw BottomedOut-           (\e -> do let err = show (e :: ErrorCall)---         (\e -> do let err = show (e :: BottomedOut)-                     return err)-    putStrLn s-    doit25 False t-----------------------------------------------------------------------------------#if USE_SOP--  doit26 :: Bool -> [(Int,Int,(Float,[Int],Bool))] -> IO ()-  doit26 _ [] = do-                   putStrLn "--------------------------------------------------"-                   return ()-  doit26 b ((code,ident,exp):t) = do-    let expect = case code of-                  1 -> "7"-                  2 -> "Prelude.undefined"-                  3 -> "pattern-match failure"-                  4 -> "syntax error"-                  5 -> "7 (but \"# with subpattern\" warning)"-                  6 -> "7 (but \"constraint/subpattern arity mismatch\" warning)"-                  13 -> "7 (but with pattern-match failure warning)"-                  23 -> "Prelude.undefined (but with pattern-match failure warning)"-                  _ -> error $ "doit26: unexpected code " ++ show code-    s <- catch-           ( do---              let exp = force_ Propagate (force_ Propagate 3.4, force_ Propagate (force_ Propagate 5 : (force_ Propagate __ : (force_ Propagate 7 : force_ Propagate []))), force_ Propagate __) :: (Float, [Int], Bool)---              let seq_exp = mkSeqableHarness exp---              let pat = compilePat patstr-                let get (_,xs,_) = show $ (xs!!2)-                if b-                then do-                  putStrLn "==================================================="-                  putStrLn "exp = <refer to test code>"-                  putStrLn "get (_,xs,_) = show $ (xs!!2)"-                  putStrLn "? = get $! exp"-                  putStrLn "==================================================="-                else do-                  putStrLn "---------------------------------------------------"---              putStrLn $ "patstr                   = " ++ patstr-                if code > 4-                then putStrLn $  show ident ++ " expected value           = " ++ expect-                else return ()---              putStrLn $ "pat = " ++ show pat---              putStrLn $ "showPat.compilePat       = " ++ showPat pat-                if code <= 4-                then putStrLn $  show ident ++ " expected value           = " ++ expect-                else return ()-                s1 <- catch-                        ( return $! force $! get $! exp )-                        (\e -> do let err = show (e :: ErrorCall)---                      (\e -> do let err = show (e :: BottomedOut)-                                  return err)-                putStr $ show ident ++ " actual value             = "-                return $! s1-           )-           -- ErrorCall if use __ = undefined-           -- BottomedOut if use __ = throw BottomedOut-           (\e -> do let err = show (e :: ErrorCall)---         (\e -> do let err = show (e :: BottomedOut)-                     return err)-    putStrLn s-    doit26 False t-----------------------------------------------------------------------------------  doit27 :: Bool -> [(Int,Int,TJ)] -> IO ()-  doit27 _ [] = do-                   putStrLn "--------------------------------------------------"-                   return ()-  doit27 b ((code,ident,exp):t) = do-    let expect = case code of-                  1 -> "4.5"-                  2 -> "Prelude.undefined"-                  3 -> "pattern-match failure"-                  4 -> "syntax error"-                  5 -> "4.5 (but \"# with subpattern\" warning)"-                  6 -> "4.5 (but \"constraint/subpattern arity mismatch\" warning)"-                  13 -> "4.5 (but with pattern-match failure warning)"-                  23 -> "Prelude.undefined (but with pattern-match failure warning)"-                  _ -> error $ "doit27: unexpected code " ++ show code-    s <- catch-           ( do---              let exp = expTJ_1  -- J2 (1, J4 (J3, K3 K2 (J1 4.5))) False---              let exp = expTJ_2  -- J2 (1, J4 (J3, K3 __ (J1 4.5))) False---              let exp = expTJ_3  -- J2 (1, J4 (__, K3 K2 (J1 4.5))) False---              let exp = expTJ_4  -- J2 (1, J4 (__, K3 __ (J1 4.5))) __---              let pat = compilePat patstr-                let get = getJ-                if b-                then do-                  putStrLn "==================================================="---                putStrLn "exp = J2 (1, J4 (J3, K3 K2 (J1 4.5))) False"---                putStrLn "exp = J2 (1, J4 (J3, K3 __ (J1 4.5))) False"---                putStrLn "exp = J2 (1, J4 (__, K3 K2 (J1 4.5))) False"-                  putStrLn "exp = J2 (1, J4 (__, K3 __ (J1 4.5))) __"-                  putStrLn "get = (J2 (_, J4 (_, K3 _ (J1 f))) _) = show f"-                  putStrLn "? = get exp"-                  putStrLn "==================================================="-                else do-                  putStrLn "---------------------------------------------------"---              putStrLn $ "patstr                   = " ++ patstr-                if code > 4-                then putStrLn $  show ident ++ " expected value           = " ++ expect-                else return ()---              putStrLn $ "pat = " ++ show pat---              putStrLn $ "showPat.compilePat       = " ++ showPat pat-                if code <= 4-                then putStrLn $  show ident ++ " expected value           = " ++ expect-                else return ()-                s1 <- catch-                        ( return $! force $! get $! exp )-                        (\e -> do let err = show (e :: ErrorCall)---                      (\e -> do let err = show (e :: BottomedOut)-                                  return err)-                putStr $ show ident ++ " actual value             = "-                return $! s1-           )-           -- ErrorCall if use __ = undefined-           -- BottomedOut if use __ = throw BottomedOut-           (\e -> do let err = show (e :: ErrorCall)---         (\e -> do let err = show (e :: BottomedOut)-                     return err)-    putStrLn s-    doit27 False t-----------------------------------------------------------------------------------#endif-
tests/Tests.hs view
@@ -15,19 +15,10 @@    import System.IO.Unsafe ( unsafePerformIO ) -#if NEW_IMPROVED_PATTERN_GRAMMAR #if HASKELL98_FRAGMENT   import qualified Blah98 as Blah #else-  import qualified Blah   as Blah  -- better parallel with below---import qualified Blah-#endif-#else-#if HASKELL98_FRAGMENT-  import qualified Blah98_old_grammar as Blah-#else-  import qualified Blah_old_grammar   as Blah-#endif+  import qualified Blah   as Blah #endif  -------------------------------------------------------------------------------