packages feed

deepseq-bounded 0.7.0.2 → 0.8.0.0

raw patch · 17 files changed

+416/−142 lines, 17 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ Control.DeepSeq.Bounded.Compile: instance IsString Pattern
- Control.DeepSeq.Bounded.NFDataP: deepseqp :: NFDataP a => String -> a -> b -> b
+ Control.DeepSeq.Bounded.NFDataP: deepseqp :: NFDataP a => Pattern -> a -> b -> b
- Control.DeepSeq.Bounded.NFDataP: forcep :: NFDataP a => String -> a -> a
+ Control.DeepSeq.Bounded.NFDataP: forcep :: NFDataP a => Pattern -> a -> a

Files

HTML/deepseq-bounded.html view
@@ -37,16 +37,16 @@ The <a href="http://hackage.haskell.org/package/deepseq-bounded"><span class="nowrap">deepseq-bounded</span></a> package provides two means of forcing a Haskell expression to an arbitrary but bounded depth, <tt>deepseqn</tt> and <tt>deepseqp</tt>. As compared with plain <tt>seq</tt> (incremental forcing) and the beloved <tt>deepseq</tt> (full forcing), the bounded versions bridge the gap between these extremes. <p>-Artificially forcing evaluation can be useful to relieve space leak, measure and tune performance, influence exception behaviour, make lazy I/O happen in a timely manner, and assure threads don't accidentally pass unevaluated computations to other threads (<span class="nowrap">"time leak"</span>).-Bounded forcing (what this package offers) is necessary <span class="nowrap">to work</span> with streams, and other "infinite" data structures, where plain <tt>rnf</tt>/<tt>deepseq</tt>/<tt>force</tt> will diverge.+Artificially forcing evaluation can be useful to relieve space leak, measure and tune performance, influence exception behaviour, make lazy I/O happen in a timely manner, and assure threads don&rsquo;t accidentally pass unevaluated computations to other threads (<span class="nowrap">&ldquo;time leak&rdquo;</span>).+Bounded forcing (what this package offers) is necessary <span class="nowrap">to work</span> with streams, and other &ldquo;infinite&rdquo; data structures, where plain <tt>rnf</tt>/<tt>deepseq</tt>/<tt>force</tt> will diverge. <p> <a id="dig03s" class="dig-toggle-show" href='javascript:toggle("dig03");' style="margin-left: 0px;">Show</a> <div id="dig03" class="digression" style="margin-left: 0px;"> <a id="dig03h" style="margin-bottom: -16px;" class="dig-toggle-hide" href='javascript:toggle("dig03");'>Hide</a><p style="margin-bottom: 0px;"> My particular motivation for <tt><span class="nowrap">deepseq-bounded</span></tt> is to support tool building for space leak characterisation (and provisional alleviation). Readers interested in those aspects might like to have a look at <a href="http://hackage.haskell.org/package/seqaid">seqaid</a> and <a href="http://hackage.haskell.org/package/leaky">leaky</a>.-Space leak is still an Achilles' heel of Haskell, they're often fatally severe, and can be as hard to debug as anything you see in other languages.-With the present tools in use, it's fair to say Haskell space leak is more difficult to diagnose than pointer bugs in C/C++, being perhaps on a par with concurrent programming bugs (probably the most difficult class of bugs in all of contemporary computing).+Space leak is still an Achilles&rsquo; heel of Haskell, they&rsquo;re often fatally severe, and can be as hard to debug as anything you see in other languages.+With the present tools in use, it&rsquo;s fair to say Haskell space leak is more difficult to diagnose than pointer bugs in C/C++, being perhaps on a par with concurrent programming bugs (probably the most difficult class of bugs in all of contemporary computing). People talk about strict-by-default Haskell in the future, but it remains there, and anyway, laziness has its charm and strengths and is attractive to many. </div> @@ -61,7 +61,7 @@ Additional functions <tt>deepseqn</tt> and <tt>forcen</tt> are provided, like in <tt>NFData</tt>. <tt>NFDataP</tt> also follows this design. <p>-The <tt>NFDataN</tt> module is straightforward; the familiar method and functions of <tt>DeepSeq</tt> have an '<tt>n</tt>' appended to their names, and take an integer first argument which is the minimum depth, in levels of recursion of constructor applications, to which to force evaluation.+The <tt>NFDataN</tt> module is straightforward; the familiar method and functions of <tt>DeepSeq</tt> have an &lsquo;<tt>n</tt>&rsquo; appended to their names, and take an integer first argument which is the minimum depth, in levels of recursion of constructor applications, to which to force evaluation. <pre> rnfn      :: NFDataN a =&gt; Int -&gt; a -&gt; () deepseqn  :: NFDataN a =&gt; Int -&gt; a -&gt; b -&gt; b@@ -76,6 +76,7 @@ One feature of <tt>NFDataP</tt> is the ability to <a href="#order">control order</a> of evaluation. <p> Usually a user of this library will prefer to compile their patterns from a string in the embedded pattern DSL, but the <tt>Pattern</tt> constructors can be worked with directly.+Better yet, <tt>-XOverloadedStrings</tt> is now supported, so you can write a String literal <tt><em>str</em></tt> as shorthand for <tt>compilePat <em>str</em></tt>.  <p> <a id="dig04s" class="dig-toggle-show" href='javascript:toggle("dig04");' style="margin-left: 0px;">Show</a>@@ -83,20 +84,20 @@ <a id="dig04h" style="margin-bottom: -16px;" class="dig-toggle-hide" href='javascript:toggle("dig04");'>Hide</a><p style="margin-bottom: 0px;"> <pre> <!--pre style="width: 800px;"-->-rnfp      :: NFDataP a =&gt; Pattern -&gt; a -&gt; ()-deepseqp_ :: NFDataP a =&gt; Pattern -&gt; a -&gt; b -&gt; b-forcep_   :: NFDataP a =&gt; Pattern -&gt; a -&gt; a+rnfp     :: NFDataP a =&gt; Pattern -&gt; a -&gt; ()+deepseqp :: NFDataP a =&gt; Pattern -&gt; a -&gt; b -&gt; b+forcep   :: NFDataP a =&gt; Pattern -&gt; a -&gt; a  data Pattern = Node PatNode [Pattern] data PatNode = WR | WS | WW | ... -deepseqp  :: NFDataP a =&gt; String -&gt; a -&gt; b -&gt; b-forcep    :: NFDataP a =&gt; String -&gt; a -&gt; a--deepseqp = deepseqp_ . compilePat -forcep   = forcep_ . compilePat - compilePat :: String -&gt; Pattern+showPat :: Pattern -&gt; String++-- <b>"foo"</b> in a Pattern context automatically interpreted as <b>compilePat "foo"</b>+-- (which compilation would fail as <b>"foo"</b> is not a valid pattern string,+-- but you get the idea)+instance IsString Pattern where fromString = compilePat </pre>  <p>@@ -144,7 +145,7 @@                   &or;  &forall; patC &sup; patB .  forcep patC  =  forcep patB </pre> <p>-where <tt>f &#8827; g</tt> says "<tt>f</tt> causes deeper evaluation than <tt>g</tt>".+where <tt>f &#8827; g</tt> says &ldquo;<tt>f</tt> causes deeper evaluation than <tt>g</tt>&rdquo;.  <p> Only strict monotonicity is interesting, since non-decreasing monotonicity <tt>&#8829;</tt> is axiomatic:@@ -155,11 +156,11 @@  <p> Here is one example to illustrate the use of <tt>NFDataP</tt>.-There is no essential dependence on <tt>rnf</tt> (from <tt>DeepSeq</tt>), but it is available as <tt>*</tt> and it's familiarity helps to concoct an example.+There is no essential dependence on <tt>rnf</tt> (from <tt>DeepSeq</tt>), but it is available as <tt>*</tt> and it&rsquo;s familiarity helps to concoct an example.  <p> So, suppose the following expression occurs in your code, and you have need (for whatever reason) to force the evaluation of <tt>exp_A</tt> and <tt>exp_B</tt>.-However, the total expression also contains some things you mustn't force, represented here by <tt>undefined</tt> and an infinite list.+However, the total expression also contains some things you mustn&rsquo;t force, represented here by <tt>undefined</tt> and an infinite list.  <pre>   expr = (   undefined :: SomeType@@ -167,8 +168,9 @@            , exp_B          ) -  forcep "(.(*.)*)" expr<div style="margin: 0px; padding:0px; clear: both; height: 8px">&nbsp;</div>= forcep_ ( compilePat "(.(*.)*)" ) expr<div style="margin: 0px; padding:0px; clear: both; height: 8px">&nbsp;</div>= forcep_ (Node WR [Node WI [],Node WR [Node WW [],Node WI []],Node WW []]) expr+  forcep "(.(*.)*)" expr                   <span class="dcmnt">-- -XOverloadedStrings</span><div style="margin: 0px; padding:0px; clear: both; height: 8px">&nbsp;</div>= forcep ( compilePat "(.(*.)*)" ) expr<div style="margin: 0px; padding:0px; clear: both; height: 8px">&nbsp;</div>= forcep (Node WR [Node WI [],Node WR [Node WW [],Node WI []],Node WW []]) expr </pre>+<!--  forcep "(.(*.)*)" expr<div style="margin: 0px; padding:0px; clear: both; height: 8px">&nbsp;</div>= forcep ( compilePat "(.(*.)*)" ) expr<div style="margin: 0px; padding:0px; clear: both; height: 8px">&nbsp;</div>= forcep (Node WR [Node WI [],Node WR [Node WW [],Node WI []],Node WW []]) expr-->  <p> which can be (almost) translated as@@ -192,6 +194,16 @@ This final translation is actually not quite correct &mdash; <tt>forcep</tt> forces the spine of the paths from <tt>expr</tt> to the substructures we want to hammer with <tt>rnf</tt>, but this translation does not. In particular, the pair constructor <tt>(,)</tt> for <tt>( exp_A, [2,4..] )</tt> is forced by <tt>forcep</tt>, but not by this translation. [Is this true?...]+<p>+Also, it has to be admitted, the API has changed since this was written, and the final line using the raw constructors would (rather less conveniently) read:+<pre>+= forcep_ (let a = emptyPatNodeAttrs in+             Node (WR a) [Node (WI a) []+                         ,Node (WR a) [Node (WW a) []+                                      ,Node (WI a) []]+                         ,Node (WW a) []])+          expr+</pre> <!-- <p> This has no semantic impact, because it only concerns interior nodes, never leaves, and bottoms are always leaves.@@ -205,7 +217,7 @@  <p> -It's worth emphasising that pattern-matching requires forcing constructors along the way.+It&rsquo;s worth emphasising that pattern-matching requires forcing constructors along the way. That is to say, every node in the path from the root to a node being pattern-matched is already forced. So the shape of these forcing functions is always a rooted tree, with the root node corresponding to the outermost redex of the expression being forced. @@ -225,7 +237,7 @@            , exp_B          ) -  forcep "(.(=*.)*)" expr<div style="margin: 0px; padding:0px; clear: both; height: 8px">&nbsp;</div>= forcep_ ( compilePat "(.(=*.)*)" ) expr<div style="margin: 0px; padding:0px; clear: both; height: 8px">&nbsp;</div>= forcep_ (Node WR [Node WI [],Node WR [Node PW [],Node WI []],Node WW []]) expr+  forcep "(.(=*.)*)" expr                  <span class="dcmnt">-- -XOverloadedStrings</span><div style="margin: 0px; padding:0px; clear: both; height: 8px">&nbsp;</div>= forcep ( compilePat "(.(=*.)*)" ) expr<div style="margin: 0px; padding:0px; clear: both; height: 8px">&nbsp;</div>= forcep (Node WR [Node WI [],Node WR [Node PW [],Node WI []],Node WW []]) expr </pre>  <p>@@ -249,7 +261,7 @@  <h3>Controlling Evaluation Order</h3> -We've noted that <tt>seq</tt> makes no guarantees about order of evaluation of its arguments.+We&rsquo;ve noted that <tt>seq</tt> makes no guarantees about order of evaluation of its arguments. This is concisely explained in the <a href="http://hackage.haskell.org/package/parallel-3.2.0.5/docs/Control-Parallel.html">Control.Parallel</a> API document. Plain <tt>seq</tt> is strict in its second argument, so the evaluation semantics for <tt>x `seq` y</tt> amount to no guarantees at all about the order in which <tt>x</tt> and <tt>y</tt> are evaluated. Evaluation of <tt>x</tt> and <tt>y</tt> is probably interleaved, in general.@@ -272,8 +284,8 @@   in          rnf x1   `pseq` rnf x2                       <span class="dcmnt">-- note `pseq` (not `seq`)</span>-  `seq`  (   undefined :: SomeType-          , ( x1, [2,4..] )+  `seq`  (   undefined :: SomeType    <span class="dcmnt">-- maybe this should also be `pseq`...</span>+           , ( x1, [2,4..] )            , x2          ) </pre>@@ -332,14 +344,14 @@    Probable fix: add an INLINE[n] or NOINLINE[n] pragma on `.' </pre> <p>-and it's not clear to me how to put an <tt>INLINE</tt> pragma+and it&rsquo;s not clear to me how to put an <tt>INLINE</tt> pragma on base composition. <p> <a id="dig01s" class="dig-toggle-show" href='javascript:toggle("dig01");' style="margin-left: 0px;">Show</a> <div id="dig01" class="digression" style="margin-left: 0px;"> <a id="dig01h" style="margin-bottom: -16px;" class="dig-toggle-hide" href='javascript:toggle("dig01");'>Hide</a><p style="margin-bottom: 0px;">-There haven't been many cases of pattern composition coming up so far, except those deliberately written for the tests.-Also, given the amount of pattern-matching required by unionPat, it's far from certain that this rule will improve performance.+There haven&rsquo;t been many cases of pattern composition coming up so far, except those deliberately written for the tests.+Also, given the amount of pattern-matching required by unionPat, it&rsquo;s far from certain that this rule will improve performance. If the union could be computed once at compile-time (for static patterns only, of course) it would make a lot more sense. This could be useful, since <tt>seqaid</tt> is going to output optimised, static patterns for ancillary use in subsequent builds. But then seqaid might as well also compute and output the union itself.@@ -473,7 +485,7 @@ <h3>Pattern Utilities</h3>  In the course of developing <tt>NFDataP</tt>, several utility functions were written for creating, modifying and combining patterns.-They've been collected in the <tt>PatUtil</tt> module.+They&rsquo;ve been collected in the <tt>PatUtil</tt> module.  <pre style="padding-top: 20px;">   module Control.DeepSeq.Bounded.PatUtil   -- implicitly imports Pattern also@@ -594,7 +606,7 @@  <p> Oops, never finished this section...-And that's a pretty silly example, although it illustrates the distinction.+And that&rsquo;s a pretty silly example, although it illustrates the distinction. Best to refer to the tests for examples, or just play around.  <p>@@ -668,7 +680,7 @@ <p> It seems possible to simplify the lexical syntax of the pattern DSL. <ul>-<li> If the <tt>PatNode</tt> is <tt>WR</tt>, don't show the dot!+<li> If the <tt>PatNode</tt> is <tt>WR</tt>, don&rsquo;t show the dot! <li> For <tt>PR</tt>, show <tt>=</tt><em style="font-size: 85%;">subpats</em><tt></tt> instead of <tt>=.</tt><em style="font-size: 85%;">subpats</em><tt></tt> <li> For <tt>TR</tt>, show <tt>:</tt><em style="font-size: 85%;">type subpats</em><tt></tt> instead of <tt>.:</tt><em style="font-size: 85%;">type subpats</em><tt></tt> </ul>@@ -694,8 +706,8 @@ </pre>  <p>-It'll require quite a few changes, and a major version bump, but I've filed the <a href="http://fremissant.net/seqaid/trac#20141223-01">ticket</a>.-This didn't really get much attention, since my main thrust is toweard <a href="http://hackage.haskell.org/package/seqaid">seqaid</a> automation.+It&rsquo;ll require quite a few changes, and a major version bump, but I&rsquo;ve filed the <a href="http://fremissant.net/seqaid/trac#20141223-01">ticket</a>.+This didn&rsquo;t really get much attention, since my main thrust is toweard <a href="http://hackage.haskell.org/package/seqaid">seqaid</a> automation.  <p> Later: And now the changes were made, and the concrete syntax is slightly different (refer to the <a href="grammar.html">grammar</a>):@@ -718,9 +730,9 @@ </pre>  <p>-It's nice to see this in the reverse sequence, as a "growth strategy"-to arrive at the big pattern. As a bonus, I've added whitespace padding-to emphasise the structural relationships &mdash; this can't be done+It&rsquo;s nice to see this in the reverse sequence, as a &ldquo;growth strategy&rdquo;+to arrive at the big pattern. As a bonus, I&rsquo;ve added whitespace padding+to emphasise the structural relationships &mdash; this can&rsquo;t be done automatcially yet, although whitespace is accepted by the parser.  <pre>@@ -742,7 +754,7 @@ <p> Oops! I see my tree shape was more monotonous than intended (although this is the most common texture seen in the wild, namely, right-biased binary trees). <p>-I've fainted some parentheses, because, while I hesitate to obliterate them, they just take up space.+I&rsquo;ve fainted some parentheses, because, while I hesitate to obliterate them, they just take up space. <p> Now, if only we could just write <tt>"3"</tt> instead of <tt>"*3"</tt>! @@ -784,14 +796,14 @@ </pre>  <p>-If I were going to be doing a lot of manual work with patterns, and didn't need <tt>NFDataN</tt> facilities deeper than 19, I would probably go with this.+If I were going to be doing a lot of manual work with patterns, and didn&rsquo;t need <tt>NFDataN</tt> facilities deeper than 19, I would probably go with this. <p> However, the default must remain <tt>"*23"</tt> as it is unambiguous in the general case. <p>-I'll offer a <tt>.cabal</tt> flag to enable the short version, why not.... This flag must absolutely be <tt>False</tt> by default. It is at the user's risk that they adopt non-default syntax...+I&rsquo;ll offer a <tt>.cabal</tt> flag to enable the short version, why not.... This flag must absolutely be <tt>False</tt> by default. It is at the user&rsquo;s risk that they adopt non-default syntax...  <p>-And this one's even better (because unambiguous), though it can only express <tt>*N</tt> nodes up to a depth of nine:+And this one&rsquo;s even better (because unambiguous), though it can only express <tt>*N</tt> nodes up to a depth of nine:  <pre>  .@@ -828,17 +840,17 @@  <h4 style="margin-bottom: 20px;">"I can has data family?..."</h4> -I'm not normally big on type extensions, and rarely stray beyond the precincts of H98 in my own code, but type families allured me.+I&rsquo;m not normally big on type extensions, and rarely stray beyond the precincts of H98 in my own code, but type families allured me. I am hoping to use it to express things about forcing functions in general (<em>e.g.</em> commutativity of composition).  <p> The data family certainly packs a whollop, making an extremely concise summary of <tt>deepseq-bounded</tt>.-I don't know how to use it yet, but it compiles. :)-Thought I'd throw it in, since Haskellers like their type extensions.+I don&rsquo;t know how to use it yet, but it compiles. :)+Thought I&rsquo;d throw it in, since Haskellers like their type extensions. <!-- The actual evaluation order of <tt>&phi; &kappa;<sub>1</sub> &middot; &phi; &kappa;<sub>2</sub></tt> is probably interleaved, and could easily be in parallel.-So, if it <em>did</em> matter what order the forcings occurred, we'd likely be noticing.-Still, it's possible to miss the pockets of observable nondeterminacy.+So, if it <em>did</em> matter what order the forcings occurred, we&rsquo;d likely be noticing.+Still, it&rsquo;s possible to miss the pockets of observable nondeterminacy. -->  <pre>
HTML/grammar.html view
@@ -67,22 +67,24 @@ <tt class="virgin"> <span class="bmeta">{</span></tt>&hellip;<tt><span class="bmeta">}</span> </tt>-means "zero or more repetitions of the enclosed".+means &ldquo;zero or more repetitions of the enclosed&rdquo;. <li> <tt class="virgin"> <span class="bmeta">[</span></tt>&hellip;<tt><span class="bmeta">]</span> </tt> -means "zero or one occurrence of the enclosed".+means &ldquo;zero or one occurrence of the enclosed&rdquo;. <li> <tt class="virgin"> </tt>&hellip;<tt><span class="ameta">|</span></tt>&hellip;<tt> </tt>  signifies a group of two or more alternatives, exactly one of which must be selected. This important metasyntax is more brightly tinted, to help it stand out.+<!-- <li> <tt class="virgin"> <span class="bmeta">(</span></tt>&hellip;<tt><span class="bmeta">)</span> </tt>  groups meta-expressions, useful for nested alternation.+--> </ul>  <p>@@ -90,7 +92,7 @@ anyplace there is space shown in the grammar above).  <p>-Semicolons never need escaping, because they're already illegal+Semicolons never need escaping, because they&rsquo;re already illegal as part of any Haskell type name.  <p>@@ -98,7 +100,7 @@ <a href="http://hackage.haskell.org/package/deepseq-bounded-0.6.0.0/docs/Control-DeepSeq-Bounded-Pattern.html#t:PatNode">PatNode</a> and <a href="http://hackage.haskell.org/package/deepseq-bounded-0.6.0.0/docs/Control-DeepSeq-Bounded-Pattern.html#t:PatNodeAttrs">PatNodeAttrs</a>-documentation, as well as informally in the <a href="http://hackage.haskell.org/package/deepseq-bounded-0.6.0.0/docs/Control-DeepSeq-Bounded-Pattern.html#t:setPatternPatNodeUniqueIDs">examples</a>, and through the project <a href="http://www.fremissant.net/deepseq-bounded">homepage</a>.+documentation, as well as informally in the <a href="http://hackage.haskell.org/package/deepseq-bounded-0.6.0.0/docs/Control-DeepSeq-Bounded-Pattern.html#t:PatNodeAttrs">examples</a> just below that, and through the project <a href="http://www.fremissant.net/deepseq-bounded">homepage</a>.  <hr class="hrule" style="margin-top: 40px;"/> @@ -134,7 +136,7 @@ These may or may not end up in 0.7.  <ul>-<li> the <a href="http://hackage.haskell.org/package/deepseq-bounded-0.6.0.0/docs/Control-DeepSeq-Bounded-Pattern.html#v:WS">WS</a> pattern node was almost removed from the language, since it is expressible as <tt>*1</tt>, but it is too convenient in testing and examples to sacrifice a single-character designation+<li> the <a href="http://hackage.haskell.org/package/deepseq-bounded-0.6.0.0/docs/Control-DeepSeq-Bounded-Pattern.html#v:WS">WS</a> pattern node was almost removed from the language, since it is expressible as <span class="conc"><tt>*1</tt></span>, but it is too convenient in testing and examples to sacrifice a single-character designation <li> the <a href="http://hackage.haskell.org/package/deepseq-bounded-0.6.0.0/docs/Control-DeepSeq-Bounded-Pattern.html#v:TI">T*</a> pattern nodes are probably going to get absorbed by  <a href="http://hackage.haskell.org/package/deepseq-bounded-0.6.0.0/docs/Control-DeepSeq-Bounded-Pattern.html#t:PatNodeAttrs">PatNodeAttrs</a> in a way analogous to what happened to <span class="nowrap">the <span class="conc">=</span>@@ -151,6 +153,16 @@ The rest of this page details earlier versions of the grammar, and discusses some rationales behind the changes leading to the above, present syntax.  <p>+One additional bit of metasyntax is used below:+<ul>+<li>+<tt class="virgin">+<span class="bmeta">(</span></tt>&hellip;<tt><span class="bmeta">)</span>+</tt> +groups meta-expressions, useful for nested alternation.+</ul>++<p> First, we have the grammar for all versions of <tt>deepseq-bounded</tt> up to and including 0.5.5:  <p style="margin-bottom: 30px;">@@ -166,7 +178,7 @@ </pre>  <p style="margin-top: 45px;">-And below is a simpler variant of the language that I'm in the process of changing over to, starting at the upcoming <tt>deepseq-bounded-0.6.0.0</tt>.+And below is a simpler variant of the language that I&rsquo;m in the process of changing over to, starting at the upcoming <tt>deepseq-bounded-0.6.0.0</tt>. It has less verbose concrete syntax, so the pattern strings are more concise with higher information density.  <p>@@ -175,7 +187,7 @@ <p> This could even be useful, since a single node might represent an expensive computation, so if we wanted to force this node, it might pay to parallelise the forcing. And <span class="conc">=#</span> might make sense to measure parallelisation overhead.-Essentially, there's no use complicating the language by constraining it:+Essentially, there&rsquo;s no use complicating the language by constraining it: there are always possible uses just beyond the horizon of consideration.  <a id="new-grammar"></a>@@ -233,20 +245,20 @@ <a id="dig02h" style="margin-bottom: -16px;" class="dig-toggle-show" href='javascript:toggle("dig02");'>Hide</a><p style="margin-bottom: -10px;"> <p> It would be possible to keep single-colon type qualification designators in all cases, if we required * and # to be written *{} and #{}.-That is very tempting, except it feels harsh to give up the plain simplicity and symmetry of the bare symbols, and the {}'s are, after all, completely perfunctory and, far from conveying useful meaning, actually falsely suggest we are matching only unary nodes. (In the * case this is not logically a likely idea, but in the # case it can be.)+That is very tempting, except it feels harsh to give up the plain simplicity and symmetry of the bare symbols, and the {}&rsquo;s are, after all, completely perfunctory and, far from conveying useful meaning, actually falsely suggest we are matching only unary nodes. (In the * case this is not logically a likely idea, but in the # case it can be.) And you have to consider also, what part of the syntax are you making less elegant, in exchange for more elegant type constraint syntax?-Because I haven't seen a huge motivation to use type-constrained pattern nodes yet!...+Because I haven&rsquo;t seen a huge motivation to use type-constrained pattern nodes yet!... <p> Yet another, comparatively menial consideration which led to a last-minute concrete syntax change today: (Re)using colon as type list separator (was whitespace before).-This is preferable to whitespace, for the simple reason that whitespace is more common in type rep strings ("Maybe Int", etc.) than is colon, so the more common symbol (whitespace) should be allowed un-escaped.+This is preferable to whitespace, for the simple reason that whitespace is more common in type rep strings (<tt>Maybe Int</tt>, etc.) than is colon, so the more common symbol (whitespace) should be allowed un-escaped. Colon is the most economical choice (even including whitespace!) since semantically, colon is already being used exclusively to signal the beginning of such a type list! <p>-Note that, in any case (and this wasn't appreciated before), when you're parsing a type list for a constraint, the parsing context is specific to that, and you can treat things differently -- you're only waiting for the stop character (or separator, or escape). So in particular, whitespace could have reserved special meaning within type constraints, and yet be used freely (say for verical alignment of constant pattern strings for visual HCI convenience) to space the other characters in the pattern.+Note that, in any case (and this wasn&rsquo;t appreciated before), when you&rsquo;re parsing a type list for a constraint, the parsing context is specific to that, and you can treat things differently -- you&rsquo;re only waiting for the stop character (or separator, or escape). So in particular, whitespace could have reserved special meaning within type constraints, and yet be used freely (say for verical alignment of constant pattern strings for visual HCI convenience) to space the other characters in the pattern. <p>-Yes, I'd like that about the whitespace in.+Yes, I&rsquo;d like that about the whitespace in. <p>-This does mean the [currently enabled!]&nbsp;&nbsp;'<tt> </tt>'-for-'#'&nbsp;&nbsp;thing must go...+This does mean the [currently enabled!]&nbsp;&nbsp;&lsquo;<tt> </tt>&rsquo;-for-&lsquo;#&rsquo;&nbsp;&nbsp;thing must go... (I do like it faded to light grey in the HTML docs though; keep that.)  </div>
HTML/tests.html view
@@ -1,6 +1,7 @@ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head>+<title>deepseq-bounded test output</title> <meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" /> <meta http-equiv="Pragma" content="no-cache" /> <meta http-equiv="Expires" content="0" />
HTML/transition-5-6-7.html view
@@ -1,7 +1,7 @@ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head>-<title>Pattern DSL for deepseq-bounded</title>+<title>deepseq-bounded v.0.5 6 7 transition</title> <meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" /> <meta http-equiv="Pragma" content="no-cache" /> <meta http-equiv="Expires" content="0" />@@ -24,8 +24,6 @@ (Refer to the <a href="http://hackage.haskell.org/package/deepseq-bounded-0.6.0.0/changelog">changelog</a> and <a href="http://www.fremissant.net/deepseq-bounded">homepage</a> documents for more information, in addition to more specific documents cited below.) <p> Nobody seems to care at the moment (just as well in flux of nascency), but I feel somehow morally obligated to provide this library, and ill-documented software is shoddy, how ever-miraculously the fancy types fit together. <b><tt style="letter-spacing: -5px;">`^</tt><tt style="letter-spacing: -4px;">&#546;(</tt></b>-<!--(If they really only fit together in one way that makes sense, there should be one exposed function, one entrypoint to this inevitable confluence of the puzzle pieces you call an API. If there are multiple ways, it's certainly time for individual verbal explanations, <em>i.e.</em> documentation.)--><!--not really; and no library in particular; but I'm sure many people feel this way regularly in the "Haskell Ecosystem"-->- <p> API breaking changes consist of module renamings, pattern DSL syntax tweaks, and <tt>PatNode</tt> data type changes. Also there are some new flags, and the roles of certain flags have changed slightly.@@ -38,8 +36,8 @@  <p> Finally a mention is in order, that at least fifteen new modules were necessary to organise the support for both old and new grammars and <tt>PatNode</tt> definitions.-It seems I've managed not to expose any in the API however!-(Wasn't the case in the first draft of this paragraph; come to think of it, it was this paragraph that spurred me to un-expose the three that were still exposed...).+It seems I&rsquo;ve managed not to expose any in the API however!+(Wasn&rsquo;t the case in the first draft of this paragraph; come to think of it, it was this paragraph that spurred me to un-expose the three that were still exposed...). These transient internal modules will be gone in 0.7.  <h3 style="margin-top: 30px;">API breaking changes in 0.5.5 -&gt; 0.6.0.0</h3>@@ -66,13 +64,13 @@ <li> The backwards compatibility flag <tt>NEW_IMPROVED_PATTERN_GRAMMAR</tt> will be removed, and only the new grammar will remain available. <li> Also, the module structure will become simpler in consequence. At present, there are at lest fifteen extra modules, just to organise the support for both old and new grammars and <tt>PatNode</tt> definitions. <li> The flag <tt>PARALLELISM_EXPERIMENT</tt> is only used in the old grammar code, and will be removed as well (<tt>USE_PAR_PATNODE</tt> is the equivalent in the new grammar, along with a half dozen other new capabilities).-<li> Type-constrained <tt>PatNode</tt>'s, and the type-reflective <tt>NFDataPDyn</tt> facilities, will become stabilised -- at present, these are quite experimental, and haven't recevied much attention because <a href="http://hackage.haskell.org/package/seqaid">seqaid</a> provides a more powerful approach. But if the features are to stay in deepseq-bounded at all, they should be finished properly...-<li> In particular, the type-constrained <tt>PatNode</tt>'s <tt>TI</tt>, <tt>TR</tt>, <tt>TN</tt> and <tt>TW</tt> will be obsoleted, with type constraints being handled just like any other attribute (<tt>PatNodeAttrs</tt>) of the <tt>PatNode</tt>. The urge to do this will probably be the main push bumping to 0.7, but the refactoring is a big one and I don't want to rush it for 0.6 (which already feels overdue to me).+<li> Type-constrained <tt>PatNode</tt>&rsquo;s, and the type-reflective <tt>NFDataPDyn</tt> facilities, will become stabilised -- at present, these are quite experimental, and haven&rsquo;t recevied much attention because <a href="http://hackage.haskell.org/package/seqaid">seqaid</a> provides a more powerful approach. But if the features are to stay in deepseq-bounded at all, they should be finished properly...+<li> In particular, the type-constrained <tt>PatNode</tt>&rsquo;s <tt>TI</tt>, <tt>TR</tt>, <tt>TN</tt> and <tt>TW</tt> will be obsoleted, with type constraints being handled just like any other attribute (<tt>PatNodeAttrs</tt>) of the <tt>PatNode</tt>. The urge to do this will probably be the main push bumping to 0.7, but the refactoring is a big one and I don&rsquo;t want to rush it for 0.6 (which already feels overdue to me). <li> <span class="red">As of 0.6.1.0, we now have an H98 parser for the new grammar.</span> Also, 0.6.0.*, if built with <tt>HASKELL98_FRAGMENT</tt> True, lacks pattern DSL facilities (except <tt>showPat</tt>). This is because attoparsec is not H98. There will be an H98 alternative parser again soon, probably by version 0.6.1.0. </ul>  <p>-There will be other changes for 0.7 (probably a few API breaking), but whatever they will be, they're probably independent of the changes we're focused on for the bump 0.5 &rarr; 0.6.  Possibly this document will be evolved to cover those changes too, as well as non-API-breaking changes that are ongoing...+There will be other changes for 0.7 (probably a few API breaking), but whatever they will be, they&rsquo;re probably independent of the changes we&rsquo;re focused on for the bump 0.5 &rarr; 0.6.  Possibly this document will be evolved to cover those changes too, as well as non-API-breaking changes that are ongoing...  <div class="footer" style="margin-top: 30px;"> Andrew Seniuk
changelog.txt view
@@ -1,4 +1,46 @@ +** 0.7.0.2 -> 0.8.0.0+ - this is API-breaking because the semantics of forcep have changed+    - (see [Note] below these, earlier explanations)+ - IsString instance (-XOverloadedStrings)+ - how could I not have thought of this before?+     > ghci+     >> import Control.DeepSeq.Bounded+     >> let x = ( 'a' , ( undefined::Bool , 0xC ) ) :: (Char,(Bool,Int))+ - before:+     >> rnfp (compilePat ".(..)") x+     ()+     >> rnfp (compilePat ".(!.)") x+     *** Exception: Prelude.undefined+ - now (but the above still works of coure):+     >> rnfp ".(..)" x+     ()+     >> rnfp ".(!.)" x+     *** Exception: Prelude.undefined+ - required no code change, just addition of this instance:+     instance IsString Pattern where fromString = compilePat+ - hahaha!!+ - I guess this is something you'd definitely want to do with+   any DSL having a concrete syntax+---------+ [Note]+ - (not as a necessary consequence of OverloadedStrings, but+   as an obvious type change which they make practical)+ - the new semantics are neither a superset nor a subset of the previous+ - also, forcep_ is a little stronger+    - domain of definition is a superset of the previous+ - and in fact forcep and forcep_ are now synonymous (i.e. forcep_ = forcep)+ - the underscore version is deprecated for removal in 0.9+ - this applies to deepseqp/deepseqp_ likewise+ - the specific change to semantics is:+    - forcep used to accept only String first argument (literal or variable)+    - but now it accepts Pattern first argument, or String literal+    - and forcep_ used to accept only Pattern first arg.+    - but now accepts that, or String literal+ - the only function in the new API still accepting a String variable+   argument (representing a pattern) is compilePat (hopefully)+    - that has a tidiness about it+ 0.7.0.1 -> 0.7.0.2  - still trying to decide on policy regarding cpphs  - this is all motivated by one pesky rogue anonymous build spammer
cpphs.sh view
@@ -13,7 +13,8 @@ # add an annotation).  I could have been doing something # constructive with this time. -env PATH=$PATH:$HOME/.cabal/bin:.cabal-sandbox/bin:/home/builder/hackage-server/build-cache/tmp-install/bin cpphs --cpp $*+# (Still not enough, if you build in the sandbox with multiple GHC versions?)+env PATH=.cabal-sandbox/bin:$HOME/.cabal/bin:/home/builder/hackage-server/build-cache/tmp-install/bin:$PATH cpphs --cpp $*  if [ 0 ]; then 
deepseq-bounded-seqaid-leaky.html view
@@ -1,7 +1,7 @@ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head>-<title>Seqaid : Space leak diagnostic and remedial tool</title>+<title>ANN : deepseq-bounded, seqaid, leaky</title> <meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" /> <meta http-equiv="Pragma" content="no-cache" /> <meta http-equiv="Expires" content="0" />
deepseq-bounded.cabal view
@@ -2,7 +2,7 @@ -------------------------------------------------------------------------------  name:		deepseq-bounded-version:        0.7.0.2+version:        0.8.0.0 synopsis:       Bounded deepseq, including support for generic deriving license:	BSD3 license-file:	LICENSE@@ -39,22 +39,22 @@     Also, bounded forcing bridges the theoretical axis between shallow seq     and full deepseq.     .-    We provide two new classes <http://hackage.haskell.org/package/deepseq-bounded-0.7.0.0/docs/Control-DeepSeq-Bounded-NFDataN.html#t:NFDataN NFDataN> and <http://hackage.haskell.org/package/deepseq-bounded-0.7.0.0/docs/Control-DeepSeq-Bounded-NFDataP.html#t:NFDataP NFDataP>.+    We provide two new classes <http://hackage.haskell.org/package/deepseq-bounded-0.8.0.0/docs/Control-DeepSeq-Bounded-NFDataN.html#t:NFDataN NFDataN> and <http://hackage.haskell.org/package/deepseq-bounded-0.8.0.0/docs/Control-DeepSeq-Bounded-NFDataP.html#t:NFDataP NFDataP>.     Instances of these provide bounded deep evaluation for arbitrary polytypic terms:     .-    * <http://hackage.haskell.org/package/deepseq-bounded-0.7.0.0/docs/Control-DeepSeq-Bounded-NFDataN.html#t:NFDataN rnfn> bounds the forced evaluation by depth of recursion.+    * <http://hackage.haskell.org/package/deepseq-bounded-0.8.0.0/docs/Control-DeepSeq-Bounded-NFDataN.html#t:NFDataN rnfn> bounds the forced evaluation by depth of recursion.     .-    * <http://hackage.haskell.org/package/deepseq-bounded-0.7.0.0/docs/Control-DeepSeq-Bounded-NFDataP.html#t:NFDataP rnfp> forces based on patterns (static or dynamic).+    * <http://hackage.haskell.org/package/deepseq-bounded-0.8.0.0/docs/Control-DeepSeq-Bounded-NFDataP.html#t:NFDataP rnfp> forces based on patterns (static or dynamic).     .-    Instances of <http://hackage.haskell.org/package/deepseq-bounded-0.7.0.0/docs/Control-DeepSeq-Bounded-NFDataN.html NFDataN> and <http://hackage.haskell.org/package/deepseq-bounded-0.7.0.0/docs/Control-DeepSeq-Bounded-NFDataP.html NFDataP> can be automatically derived via <http://hackage.haskell.org/package/generics-sop/docs/Generics-SOP.html Generics.SOP>, backed by the <http://hackage.haskell.org/package/deepseq-bounded-0.7.0.0/docs/Control-DeepSeq-Bounded-Generic-GNFDataN.html GNFDataN> and <http://hackage.haskell.org/package/deepseq-bounded-0.7.0.0/docs/Control-DeepSeq-Bounded-Generic-GNFDataP.html GNFDataP> modules.-    <http://hackage.haskell.org/package/deepseq-bounded-0.7.0.0/docs/Control-DeepSeq-Bounded-NFDataN.html NFDataN> can optionally be derived by the standard <http://downloads.haskell.org/~ghc/7.8.3/docs/html/libraries/base-4.7.0.1/GHC-Generics.html GHC.Generics> facility (but not so for <http://hackage.haskell.org/package/deepseq-bounded-0.7.0.0/docs/Control-DeepSeq-Bounded-NFDataP.html NFDataP>).+    Instances of <http://hackage.haskell.org/package/deepseq-bounded-0.8.0.0/docs/Control-DeepSeq-Bounded-NFDataN.html NFDataN> and <http://hackage.haskell.org/package/deepseq-bounded-0.8.0.0/docs/Control-DeepSeq-Bounded-NFDataP.html NFDataP> can be automatically derived via <http://hackage.haskell.org/package/generics-sop/docs/Generics-SOP.html Generics.SOP>, backed by the <http://hackage.haskell.org/package/deepseq-bounded-0.8.0.0/docs/Control-DeepSeq-Bounded-Generic-GNFDataN.html GNFDataN> and <http://hackage.haskell.org/package/deepseq-bounded-0.8.0.0/docs/Control-DeepSeq-Bounded-Generic-GNFDataP.html GNFDataP> modules.+    <http://hackage.haskell.org/package/deepseq-bounded-0.8.0.0/docs/Control-DeepSeq-Bounded-NFDataN.html NFDataN> can optionally be derived by the standard <http://downloads.haskell.org/~ghc/7.8.3/docs/html/libraries/base-4.7.0.1/GHC-Generics.html GHC.Generics> facility (but not so for <http://hackage.haskell.org/package/deepseq-bounded-0.8.0.0/docs/Control-DeepSeq-Bounded-NFDataP.html NFDataP>).     .-    Another approach is <http://hackage.haskell.org/package/deepseq-bounded-0.7.0.0/docs/Control-DeepSeq-Bounded-Seqable.html Seqable>, which is similar to <http://hackage.haskell.org/package/deepseq-bounded-0.7.0.0/docs/Control-DeepSeq-Bounded-NFDataN.html NFDataN>,+    Another approach is <http://hackage.haskell.org/package/deepseq-bounded-0.8.0.0/docs/Control-DeepSeq-Bounded-Seqable.html Seqable>, which is similar to <http://hackage.haskell.org/package/deepseq-bounded-0.8.0.0/docs/Control-DeepSeq-Bounded-NFDataN.html NFDataN>,     but optimised for use as a dynamically-reconfigurable forcing harness     in the <http://hackage.haskell.org/package/seqaid seqaid> auto-instrumentation tool.     .-    Recent developments supporting parallelisation control (in <http://hackage.haskell.org/package/deepseq-bounded-0.7.0.0/docs/Control-DeepSeq-Bounded-Pattern.html Pattern>-    and <http://hackage.haskell.org/package/deepseq-bounded-0.7.0.0/docs/Control-DeepSeq-Bounded-Seqable.html Seqable> modules) may justify renaming this library to+    Recent developments supporting parallelisation control (in <http://hackage.haskell.org/package/deepseq-bounded-0.8.0.0/docs/Control-DeepSeq-Bounded-Pattern.html Pattern>+    and <http://hackage.haskell.org/package/deepseq-bounded-0.8.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 (now deprecated) 0.5.* releases, particularly as regards NFDataP. /@@ -129,6 +129,12 @@ --Default: False   Manual: True +Flag OVERLOADED_STRINGS+  Description: Use the OverloadedStrings syntax extension, so never need to call compilePat explicitly. This gives the feeling of "bringing the DSL right into Haskell", and makes ghci experiments a lot less of a headache! Wish I'd had this in since the first release. I guess really nobody is experimenting with this at all, or surely they'd have clamoured for this!+  Default: True+--Default: False+  Manual: True+ Flag USE_PAR_SEQABLE   Description: This flag (now) only affects Seqable. (Refer to USE_PAR_PATNODE for a comparable flag affecting NFDataP.) USE_PAR_SEQABLE = True depends on parallel, and permits (dynamically configurable) sparking of Sequable recursive demand propagation.   Default: True@@ -207,13 +213,8 @@ --Default: False   Manual: True --- This does indeed work for me (it is auto-toggled when cpphs is unavailable).--- Default to False, since it seems more likely there's a native cpp, than--- that a cpphs installation works smoothly.--- Later: Defaulting to True, since found some tricks...--- (Not even going to let this be manual:false anymore.) Flag USE_CPPHS-  Description: Non-manual flag to allow the build system to try cpphs first, and if that fails, then to try system-wide cpp (typically GNU). I've actually toggled the default, so the build system will try for a system-wide cpp first, and failing that, will try to use cpphs, installing it if necessary. I prefer cpp. I am not getting my most invaluable -Wundef option with cpphs using -optP-Wundef -optP--cpp in my ghc-options. Does cpphs implement it? Not sure...+  Description: The original intention was to make this a non-manual flag, to allow the build system to try cpphs first, and if that fails, then to try system-wide cpp (typically GNU). Due to path problems, when the build client installs cpphs in the course of installing, it turns out to be better to use a shell script to delegate which cpp runs, jimmy options, etc. --Default: False   Default: True --Manual: False@@ -257,6 +258,10 @@ --if impl(ghc >= 7.2) --  other-extensions: Safe +  if ! flag(HASKELL98_FRAGMENT)+    if flag(OVERLOADED_STRINGS)+      default-extensions:  OverloadedStrings+   exposed-modules:       Control.DeepSeq.Bounded     , Control.DeepSeq.Bounded.Seqable@@ -284,21 +289,11 @@    ghc-options: -optP-Wundef -fno-warn-overlapping-patterns -  -- -ags+ 20150202---cpp-options: PATH=$PATH:.cabal-sandbox/bin:$HOME/.cabal/bin:/home/builder/hackage-server/build-cache/tmp-install/bin cpphs---cpp-options: PATH={$PATH}:{$HOME}/.cabal/bin:.cabal-sandbox/bin:/home/builder/hackage-server/build-cache/tmp-install/bin cpphs---cpp-options: PATH=${PATH}:${HOME}/.cabal/bin:.cabal-sandbox/bin:/home/builder/hackage-server/build-cache/tmp-install/bin cpphs---cpp-options: PATH=$PATH:~/.cabal/bin:.cabal-sandbox/bin:/home/builder/hackage-server/build-cache/tmp-install/bin cpphs---cpp-options: PATH=$PATH:~/.cabal/bin:.cabal-sandbox/bin:/home/builder/hackage-server/build-cache/tmp-install/bin cpphs --cpp-   if flag(USE_CPPHS)+     -- the only reliable way to get equiv. of -pgmP"env PATH=$PATH:blah cpphs"      ghc-options: -pgmP./cpphs.sh-     -- -ags+ 20150202---   ghc-options: -pgmPenv -optP--cpp---   ghc-options: -pgmPenv --else --   ghc-options: -cpp---ghc-options: -pgmP/usr/bin/cpp    build-depends: @@ -340,6 +335,14 @@   else      cpp-options: -DUSE_WW_DEEPSEQ=0 +  if flag(HASKELL98_FRAGMENT)+     cpp-options: -DOVERLOADED_STRINGS=0+  else+     if flag(OVERLOADED_STRINGS)+        cpp-options: -DOVERLOADED_STRINGS=1+     else+        cpp-options: -DOVERLOADED_STRINGS=0+   if flag(USE_CURLY_BRACE_INSTEAD_OF_PAREN_FOR_SUBPATTERNS)      cpp-options: -DUSE_CURLY_BRACE_INSTEAD_OF_PAREN_FOR_SUBPATTERNS=1   else@@ -509,6 +512,10 @@    default-extensions:  CPP +  if ! flag(HASKELL98_FRAGMENT)+    if flag(OVERLOADED_STRINGS)+      default-extensions:  OverloadedStrings+   ghc-options: -optP-Wundef -fno-warn-overlapping-patterns  --ghc-options:         -Wall -fenable-rewrite-rules -O -ddump-rules -ddump-simpl-stats -ddump-rule-firings@@ -516,21 +523,11 @@ --ghc-options:         -fenable-rewrite-rules -O --ghc-options:         -fenable-rewrite-rules -O2 -  -- -ags+ 20150202---cpp-options: PATH=$PATH:.cabal-sandbox/bin:$HOME/.cabal/bin:/home/builder/hackage-server/build-cache/tmp-install/bin cpphs---cpp-options: "PATH=${PATH}:${HOME}/.cabal/bin:.cabal-sandbox/bin:/home/builder/hackage-server/build-cache/tmp-install/bin" cpphs---cpp-options: PATH=$PATH:~/.cabal/bin:.cabal-sandbox/bin:/home/builder/hackage-server/build-cache/tmp-install/bin cpphs---cpp-options: PATH=$PATH:~/.cabal/bin:.cabal-sandbox/bin:/home/builder/hackage-server/build-cache/tmp-install/bin cpphs --cpp-   if flag(USE_CPPHS)+     -- the only reliable way to get equiv. of -pgmP"env PATH=$PATH:blah cpphs"      ghc-options: -pgmP./cpphs.sh-     -- -ags+ 20150202---   ghc-options: -pgmPenv---   ghc-options: -pgmPenv -optP--cpp --else --   ghc-options: -cpp---ghc-options: -pgmP/usr/bin/cpp----  ghc-options: -pgmPcpphs -optP--cpp    build-depends:       base == 4.*@@ -593,6 +590,14 @@      cpp-options: -DWARN_PATTERN_MATCH_FAILURE=1   else      cpp-options: -DWARN_PATTERN_MATCH_FAILURE=0++  if flag(HASKELL98_FRAGMENT)+     cpp-options: -DOVERLOADED_STRINGS=0+  else+     if flag(OVERLOADED_STRINGS)+        cpp-options: -DOVERLOADED_STRINGS=1+     else+        cpp-options: -DOVERLOADED_STRINGS=0    if flag(USE_CURLY_BRACE_INSTEAD_OF_PAREN_FOR_SUBPATTERNS)      cpp-options: -DUSE_CURLY_BRACE_INSTEAD_OF_PAREN_FOR_SUBPATTERNS=1
src/Control/DeepSeq/Bounded.hs view
@@ -193,7 +193,11 @@    instance FF Pattern where            -- NFDataP     data F Pattern v = FPattern v+#if OVERLOADED_STRINGS+    phi k (FPattern m) = forcep k m+#else     phi k (FPattern m) = forcep_ k m+#endif  #if 0   instance (FF Pattern, FF a) => FF (Pattern,a) where
src/Control/DeepSeq/Bounded/Compile.hs view
@@ -3,6 +3,11 @@    {-  LANGUAGE CPP #-} +#if OVERLOADED_STRINGS+{-# LANGUAGE FlexibleInstances #-}+{-  LANGUAGE TypeSynonymInstances #-}+#endif+ #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@@ -113,6 +118,23 @@   import qualified Control.DeepSeq.Generics as DSG   import qualified GHC.Generics as GHC ( Generic ) #endif+#endif++-- Want it in Pattern with other Pattern instances, but it+-- makes a cyclical dependency and we all know that is more+-- trouble than it's worth in GHC (and other Haskell compilers+-- I've known)...+#if OVERLOADED_STRINGS+  import GHC.Exts( IsString(..) )+#endif++-------------------------------------------------------------------------------++-- (See note at import of IsString; this instance should be in Pattern.hs.)+#if OVERLOADED_STRINGS+--instance IsString (Rose PatNode) where+  instance IsString Pattern where+    fromString = compilePat  -- aahhhh..... (20150204) #endif  -------------------------------------------------------------------------------
src/Control/DeepSeq/Bounded/Generic.hs view
@@ -11,9 +11,9 @@ -- Portability :  GHC -- -- Support for generic deriving (via <http://hackage.haskell.org/package/generics-sop/docs/Generics-SOP.html Generics.SOP>) of--- <http://hackage.haskell.org/package/deepseq-bounded-0.7.0.1/docs/Control-DeepSeq-Bounded-NFDataN.html#t:NFDataN NFDataN> and--- <http://hackage.haskell.org/package/deepseq-bounded-0.7.0.1/docs/Control-DeepSeq-Bounded-NFDataP.html#t:NFDataP NFDataP> instances.--- Also, @SOP@ generic functions implementing <http://hackage.haskell.org/package/deepseq-bounded-0.7.0.1/docs/Control-DeepSeq-Bounded-Seqable.html Seqable> without a class and instances.+-- <http://hackage.haskell.org/package/deepseq-bounded-0.8.0.0/docs/Control-DeepSeq-Bounded-NFDataN.html#t:NFDataN NFDataN> and+-- <http://hackage.haskell.org/package/deepseq-bounded-0.8.0.0/docs/Control-DeepSeq-Bounded-NFDataP.html#t:NFDataP NFDataP> instances.+-- Also, @SOP@ generic functions implementing <http://hackage.haskell.org/package/deepseq-bounded-0.8.0.0/docs/Control-DeepSeq-Bounded-Seqable.html Seqable> without a class and instances. -- -- This metaboilerplate is standard for using the generic deriving facilities of <http://downloads.haskell.org/~ghc/latest/docs/html/libraries/base/GHC-Generics.html 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. --
src/Control/DeepSeq/Bounded/Generic/GSeqable.hs view
@@ -39,7 +39,7 @@ -- Stability   :  provisional -- Portability :  GHC ----- Generic function version of <http://hackage.haskell.org/package/deepseq-bounded-0.7.0.1/docs/Control-DeepSeq-Bounded-Seqable.html Seqable> (via <http://hackage.haskell.org/package/generics-sop/docs/Generics-SOP.html Generics.SOP>).+-- Generic function version of <http://hackage.haskell.org/package/deepseq-bounded-0.8.0.0/docs/Control-DeepSeq-Bounded-Seqable.html Seqable> (via <http://hackage.haskell.org/package/generics-sop/docs/Generics-SOP.html Generics.SOP>). -- -- Probably, a "GHC.Generics" variant would also be possible. --@@ -143,7 +143,7 @@   --   -- /I can see how this would be useful at compile-time, but how can we use this if seqharn only runs post-compilation?  Or is it just analogous to forcep?.../   ---  -- /Also: How exactly to/ dynamically configure  /this?.../+  -- /Also: How exactly to/ dynamically configure /this?.../      seqharn :: Generic a => a -> a -- hliftA f xs = hpure (fn f) ` hap ` xs
src/Control/DeepSeq/Bounded/NFDataN.hs view
@@ -125,10 +125,10 @@   -- it doesn't care about any details of the shape of the term   -- it's forcing, it only cares about stratifying levels of   -- recursion depth.-  -- (I would say \"as contrasted with <http://hackage.haskell.org/package/deepseq-bounded-0.7.0.1/docs/Control-DeepSeq-Bounded-NFDataP.html NFDataP>\" but cannot, because-  -- <http://hackage.haskell.org/package/deepseq-bounded-0.7.0.1/docs/Control-DeepSeq-Bounded-NFDataP.html NFDataP>+  -- (I would say \"as contrasted with <http://hackage.haskell.org/package/deepseq-bounded-0.8.0.0/docs/Control-DeepSeq-Bounded-NFDataP.html NFDataP>\" but cannot, because+  -- <http://hackage.haskell.org/package/deepseq-bounded-0.8.0.0/docs/Control-DeepSeq-Bounded-NFDataP.html NFDataP>   -- was extended to include-  -- <http://hackage.haskell.org/package/deepseq-bounded-0.7.0.1/docs/Control-DeepSeq-Bounded-NFDataN.html NFDataN>+  -- <http://hackage.haskell.org/package/deepseq-bounded-0.8.0.0/docs/Control-DeepSeq-Bounded-NFDataN.html NFDataN>   -- syntax\/capabilities, precisely to ammend this deficiency.)    deepseqn :: NFDataN a => Int -> a -> b -> b
src/Control/DeepSeq/Bounded/NFDataP.hs view
@@ -115,11 +115,11 @@ -- barring further measures. -- / (This behaviour can also now be changed with 'PatNodeAttrs'.) / ----- See also <http://hackage.haskell.org/package/deepseq-bounded-0.7.0.1/docs/Control-DeepSeq-Bounded-NFDataPDyn.html NFDataPDyn> for another approach, which dynamically+-- See also <http://hackage.haskell.org/package/deepseq-bounded-0.8.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.7.0.1/docs/Control-DeepSeq-Bounded-NFDataPDyn.html NFDataPDyn> /should get attention.) /+-- <http://hackage.haskell.org/package/deepseq-bounded-0.8.0.0/docs/Control-DeepSeq-Bounded-NFDataPDyn.html NFDataPDyn> /should get attention.) / --  -------------------------------------------------------------------------------@@ -127,6 +127,13 @@   module Control.DeepSeq.Bounded.NFDataP   ( +#if OVERLOADED_STRINGS++       deepseqp, forcep    -- take Pattern arg or String **literal**+     , deepseqp_, forcep_  -- aliases to the aforegoing (for compatability)++#else+      -- * Pattern-bounded analogues of 'deepseq' and 'force'         deepseqp, forcep    -- take String arg (pattern DSL)@@ -139,6 +146,8 @@       , deepseqp_, forcep_  -- take Pattern structure arg +#endif+      -- * A custom exception, raised by choice 'PatNode's, that can be caught in the caller  #if USE_PING_PATNODE@@ -275,6 +284,46 @@  ------------------------------------------------------------------------------- +#if OVERLOADED_STRINGS++  {-# DEPRECATED deepseqp_, forcep_ "OverloadedStrings is in effect for pattern strings (since 0.8), so you can use deepseqp and forcep with either a Pattern or a String literal as first argument. To work with String variables, write your own wrapper function calling compilePat (or build with OVERLOEADED_STRINGS flag False). These underscore versions will be removed in 0.9 (mere days from now...)." #-}+  -- For compatibility with prior, non-OVERLOADED_STRINGS API.+  -- I can actually upload this without a major version bump,+  -- even though it very much has the feel of one.  That's+  -- extension magic for ya!+  ------+  -- It seems the signatures are needed, unfortunately.+#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+  deepseqp_ = deepseqp+  -- | 'deepseqp_' and 'forcep_' are merely aliases to the+  -- non-underscored functions.  They are vestigial and+  -- retained for compatibility until the next major+  -- version bump.  Then it seems safe to remove them,+  -- since can always build with @OVERLOADED_STRINGS@ flag+  -- set @False@ if their absence is a problem (or define+  -- the aliases yourself). So, DEPRECATED, and slated+  -- for removal in 0.8.+#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+  forcep_ = forcep+ -- 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.@@ -283,9 +332,107 @@   --   -- \"<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). /   --+  -- 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.)+{--}+  -- [No longer true, but discussing doPseq here is too much, so tacit.]   -- / 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.+{--}+-- 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+  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++-------------------------------------------------------------------------------++#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.\" /+  --+  -- 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 What about fusion of mixed applications?...+-- XXX LATER: This is "flawed" for # at root of pattern. (See deepseqp.)+#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+  forcep pat x = deepseqp pat x x+  {-# RULES+    "forcep/composition"    forall p1 p2 x.  (.) (forcep p2) (forcep p1) x = forcep ( unionPats [p1, p2] ) x+      #-}++#else+-- else not OVERLOADED_STRINGS++-- 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). /+  --+  -- Composition fuses (see 'deepseqp_').+{--}+  -- [No longer true, but discussing doPseq here is too much, so tacit.]+  -- / 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. (See deepseqp_.)+#if ( ! HASKELL98_FRAGMENT ) && ( __GLASGOW_HASKELL__ >= 710 )   deepseqp :: NFDataP_ictx a => String -> a -> b -> b --deepseqp :: NFDataP_cctx a => String -> a -> b -> b #else@@ -320,8 +467,8 @@   --   -- (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+-- 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@@ -378,7 +525,7 @@   -- Composition fuses (see 'forcep_'). {--} -- XXX What about fusion of mixed applications?...--- XXX LATER: This is flawed for # at root of pattern.+-- XXX LATER: This is "flawed" for # at root of pattern. (See deepseqp_.) #if ( ! HASKELL98_FRAGMENT ) && ( __GLASGOW_HASKELL__ >= 710 )   forcep :: NFDataP_ictx a => String -> a -> a --forcep :: NFDataP_cctx a => String -> a -> a@@ -430,7 +577,7 @@   --   -- (Other fusion rules, not yet documented, may also be in effect.) {--}--- XXX LATER: This is flawed for # at root of pattern.+-- XXX LATER: This is "flawed" for # at root of pattern. (See deepseqp_.) #if ( ! HASKELL98_FRAGMENT ) && ( __GLASGOW_HASKELL__ >= 710 )   forcep_ :: NFDataP_ictx a => Pattern -> a -> a --forcep_ :: NFDataP_cctx a => Pattern -> a -> a@@ -449,6 +596,9 @@     "forcep_/composition"    forall p1 p2 x.  (.) (forcep_ p2) (forcep_ p1) x = forcep_ ( unionPats [p1, p2] ) x       #-} #endif++#endif+-- of if OVERLOADED_STRINGS else  ------------------------------------------------------------------------------- 
src/Control/DeepSeq/Bounded/PatUtil.hs view
@@ -985,19 +985,24 @@   growPat pat x = growPat' pat $ shapeOf x   growPat' :: Pattern -> Shape -> Pattern   growPat' (Node pas cs) (Node q ds)-#if 1+#if 0+#elif 1    | null cs    = let subleaf = Node (WI $ getPatNodeAttrs pas) [] in-                       let pas2 = WR $ getPatNodeAttrs pas in-                            Node pas2 $ map (const subleaf) ds-#else+                       let pas' = WR $ getPatNodeAttrs pas in+                            Node pas' $ map (const subleaf) ds+#elif 0    | null cs    = let subleaf = Node (WI $ getPatNodeAttrs pas) []-#if 1-                      pas2 = WR $ getPatNodeAttrs pas in-                        Node pas2 $ map (const subleaf) ds-#else+                      pas' = WR $ getPatNodeAttrs pas in+                        Node pas' $ map (const subleaf) ds+#elif 0+   -- Mysteriously stopped working; parse error on = in second def.+   -- How many bizillion times have I used this layout without a problem?+   -- And many times compiled in the last week even. Now I'm worried+   -- about a hundred unknown sites in other code that use this.+   -- This has been one of the worst days of my life in some ways.+   | null cs    = let subleaf = Node (WI $ getPatNodeAttrs pas) []                       pas' = WR $ getPatNodeAttrs pas                   in Node pas' $ map (const subleaf) ds-#endif #endif    | otherwise  = Node pas $ zipWith growPat' cs ds #endif
src/Control/DeepSeq/Bounded/Pattern.hs view
@@ -131,37 +131,37 @@      --      -- @\"__(...)__\"@ will match any ternary constructor.      ---     -- @<http://hackage.haskell.org/package/deepseq-bounded-0.7.0.1/docs/Control-DeepSeq-Bounded-NFDataP.html#t:NFDataP rnfp> \"__(!!!)__\" expr@ will force evaluation of @expr@ to a depth of two,+     -- @<http://hackage.haskell.org/package/deepseq-bounded-0.8.0.0/docs/Control-DeepSeq-Bounded-NFDataP.html#t:NFDataP 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 @<http://hackage.haskell.org/package/deepseq-bounded-0.7.0.1/docs/Control-DeepSeq-Bounded-NFDataP.html#t:NFDataP rnfp> \"__.__\" expr@ (/i.e./ do nothing).+     -- as @<http://hackage.haskell.org/package/deepseq-bounded-0.8.0.0/docs/Control-DeepSeq-Bounded-NFDataP.html#t:NFDataP rnfp> \"__.__\" expr@ (/i.e./ do nothing).      ---     -- @<http://hackage.haskell.org/package/deepseq-bounded-0.7.0.1/docs/Control-DeepSeq-Bounded-NFDataP.html#t:NFDataP rnfp> \"__(...)__\" expr@ will force it to only a depth of one. That is,-     -- @<http://hackage.haskell.org/package/deepseq-bounded-0.7.0.1/docs/Control-DeepSeq-Bounded-NFDataP.html#t:NFDataP rnfp> \"__(...)__\" expr =-     -- <http://hackage.haskell.org/package/deepseq-bounded-0.7.0.1/docs/Control-DeepSeq-Bounded-NFDataP.html#t:NFDataP rnfp>+     -- @<http://hackage.haskell.org/package/deepseq-bounded-0.8.0.0/docs/Control-DeepSeq-Bounded-NFDataP.html#t:NFDataP rnfp> \"__(...)__\" expr@ will force it to only a depth of one. That is,+     -- @<http://hackage.haskell.org/package/deepseq-bounded-0.8.0.0/docs/Control-DeepSeq-Bounded-NFDataP.html#t:NFDataP rnfp> \"__(...)__\" expr =+     -- <http://hackage.haskell.org/package/deepseq-bounded-0.8.0.0/docs/Control-DeepSeq-Bounded-NFDataP.html#t:NFDataP rnfp>      -- \"__!__\" expr@ when the head of @expr@      -- is a ternary constructor; otherwise it won't perform any evaluation.      ---     -- @<http://hackage.haskell.org/package/deepseq-bounded-0.7.0.1/docs/Control-DeepSeq-Bounded-NFDataP.html#t:NFDataP rnfp> \"__*__\" expr = <http://hackage.haskell.org/package/deepseq/docs/Control-DeepSeq.html#t:NFData rnf> expr@.+     -- @<http://hackage.haskell.org/package/deepseq-bounded-0.8.0.0/docs/Control-DeepSeq-Bounded-NFDataP.html#t:NFDataP rnfp> \"__*__\" expr = <http://hackage.haskell.org/package/deepseq/docs/Control-DeepSeq.html#t:NFData rnf> expr@.      ---     -- @<http://hackage.haskell.org/package/deepseq-bounded-0.7.0.1/docs/Control-DeepSeq-Bounded-NFDataP.html#t:NFDataP rnfp> \"__(***)__\" expr@ will <http://hackage.haskell.org/package/deepseq/docs/Control-DeepSeq.html#t:NFData rnf> (deep) any ternary constructor, but+     -- @<http://hackage.haskell.org/package/deepseq-bounded-0.8.0.0/docs/Control-DeepSeq-Bounded-NFDataP.html#t:NFDataP rnfp> \"__(***)__\" expr@ will <http://hackage.haskell.org/package/deepseq/docs/Control-DeepSeq.html#t:NFData rnf> (deep) any ternary constructor, but      -- will not touch any constructor of other arity.      ---     -- @<http://hackage.haskell.org/package/deepseq-bounded-0.7.0.1/docs/Control-DeepSeq-Bounded-NFDataP.html#t:NFDataP rnfp> \"__(.(*.).)__\" expr@ will match any ternary constructor, then+     -- @<http://hackage.haskell.org/package/deepseq-bounded-0.8.0.0/docs/Control-DeepSeq-Bounded-NFDataP.html#t:NFDataP 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 (<http://hackage.haskell.org/package/deepseq/docs/Control-DeepSeq.html#t:NFData rnf>), but not the right.      ---     -- @<http://hackage.haskell.org/package/deepseq-bounded-0.7.0.1/docs/Control-DeepSeq-Bounded-NFDataP.html#t:NFDataP rnfp> \"__(!:T:*.)__\" expr@ will unwrap (shallow 'seq') the first+     -- @<http://hackage.haskell.org/package/deepseq-bounded-0.8.0.0/docs/Control-DeepSeq-Bounded-NFDataP.html#t:NFDataP 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 (<http://hackage.haskell.org/package/deepseq/docs/Control-DeepSeq.html#t:NFData rnf>), but otherwise it won't be touched.      ---     -- @<http://hackage.haskell.org/package/deepseq-bounded-0.7.0.1/docs/Control-DeepSeq-Bounded-NFDataP.html#t:NFDataP rnfp> \"__(=**)__\" expr@ will spark the /parallel/ complete evaluation of+     -- @<http://hackage.haskell.org/package/deepseq-bounded-0.8.0.0/docs/Control-DeepSeq-Bounded-NFDataP.html#t:NFDataP 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).+     -- of the RTS, as usual.)      ---     -- @<http://hackage.haskell.org/package/deepseq-bounded-0.7.0.1/docs/Control-DeepSeq-Bounded-NFDataP.html#t:NFDataP rnfp> \"__(>ba(+*+*)=*)__\" expr@ matches a binary constructor, whose first parameter is also a binary constructor. This identifies three main AST branches -- serendipitously symbolised by asterisks -- making up the expression: which branches we'll call __A__, __B__ and __C__. So this example will perform <http://hackage.haskell.org/package/deepseq/docs/Control-DeepSeq.html#t:NFData rnf>, but in a controlled manner: __A__ and __B__ are forced in parallel with __C__, and furthermore, __B__ is forced before __A__. A traceline will be printed at the beginning of the forcing of __B__ and then another traceline will be printed at the beginning of the forcing of __A__. Note that \"__(=>ba(+*+*)*)__\" would be a legal equivalent.+     -- @<http://hackage.haskell.org/package/deepseq-bounded-0.8.0.0/docs/Control-DeepSeq-Bounded-NFDataP.html#t:NFDataP rnfp> \"__(>ba(+*+*)=*)__\" expr@ matches a binary constructor, whose first parameter is also a binary constructor. This identifies three main AST branches -- serendipitously symbolised by asterisks -- making up the expression: which branches we'll call __A__, __B__ and __C__. So this example will perform <http://hackage.haskell.org/package/deepseq/docs/Control-DeepSeq.html#t:NFData rnf>, but in a controlled manner: __A__ and __B__ are forced in parallel with __C__, and furthermore, __B__ is forced before __A__. A traceline will be printed at the beginning of the forcing of __B__ and then another traceline will be printed at the beginning of the forcing of __A__. Note that \"__(=>ba(+*+*)*)__\" would be a legal equivalent.      --      -- I make no claims as to the usefulness of the examples, they are here just to explain the semantics of the DSL.      --@@ -286,6 +286,15 @@    import Control.Monad.State as ST +-- Can't do it here, due to cyclical imports. (Surely this+-- could be handled better by the tools...).+#if 0+#if OVERLOADED_STRINGS+  import GHC.Exts( IsString(..) )+  import Control.DeepSeq.Bounded.Compile ( compilePat )+#endif+#endif+ -------------------------------------------------------------------------------  #if DO_TRACE@@ -331,6 +340,15 @@ #endif #endif +-- (See note at import of IsString; this instance is in Compile.hs.)+#if 0+#if OVERLOADED_STRINGS+  instance IsString (Rose PatNode) where+--instance IsString Pattern where+    fromString = compilePat  -- aahhhh..... (20150204)+#endif+#endif+ -------------------------------------------------------------------------------  -- XXX@@ -400,7 +418,7 @@   -- 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.7.0.1/docs/Control-DeepSeq-Bounded-PatUtil.html#v:growPat growPat>, the added nodes would all have \"uniqueID\" of 0.+               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.8.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). /(This is not an attribute, it's a displaced mandatory parameter, specific to these two node types.)/              , 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').@@ -718,7 +736,7 @@          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.7.0.1/docs/Control-DeepSeq-Bounded-NFDataN.html#t:NFDataN rnfn> n@ the branch under this node.+       | WN !PatNodeAttrs  -- ^ (/__N__ (depth)/, __*__n ) &#8195; @<http://hackage.haskell.org/package/deepseq-bounded-0.8.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@@ -742,7 +760,7 @@        | 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.7.0.1/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'.+       | TN !PatNodeAttrs  -- ^ @<http://hackage.haskell.org/package/deepseq-bounded-0.8.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
tests/Blah.hs view
@@ -28,6 +28,10 @@  {-# LANGUAGE CPP #-} +#if OVERLOADED_STRINGS+#error Please build with OVERLOADED_STRINGS flag set False, in order to run the tests.+#endif+ -------------------------------------------------------------------------------  #define FOCUS_TEST 0