[reiner.pope@gmail.com: [Haskellcafe] SpecConstr difficulties]
Simon PeytonJones
simonpj at microsoft.com
Wed Jul 22 01:48:53 EDT 2009
Thanks. You've found a bug in 6.10, which is happily fixed in the HEAD and in the upcoming 6.12. Here's the code for g2:
Test.$s$wg2 =
\ (sc_soL :: GHC.Prim.Int#) (sc1_soM :: GHC.Prim.Int#) >
case GHC.Prim.># sc_soL 10 of _ {
GHC.Bool.False >
case GHC.Prim.<=# sc1_soM sc_soL of _ {
GHC.Bool.False > Test.$s$wg2 (GHC.Prim.+# sc_soL 1) sc1_soM;
GHC.Bool.True > Test.$s$wg2 (GHC.Prim.+# sc_soL 1) sc_soL
};
GHC.Bool.True > Test.Just @ GHC.Types.Int (GHC.Types.I# sc1_soM)
}
Simon
 Original Message
 From: glasgowhaskellusersbounces at haskell.org [mailto:glasgowhaskell
 usersbounces at haskell.org] On Behalf Of Don Stewart
 Sent: 20 July 2009 17:38
 To: glasgowhaskellusers at haskell.org
 Subject: [reiner.pope at gmail.com: [Haskellcafe] SpecConstr difficulties]

 Something for SimonPJ

  Forwarded message from Reiner Pope <reiner.pope at gmail.com> 

 Date: Mon, 20 Jul 2009 22:09:09 +0930
 From: Reiner Pope <reiner.pope at gmail.com>
 To: Haskell Cafe mailing list <haskellcafe at haskell.org>
 Subject: [Haskellcafe] SpecConstr difficulties

 Hi everyone,

 I've been having some trouble getting SpecConstr to work as I want it
 to. The following example (see end of email) came up in some code I
 was playing around with. The loops g1 and g2 both compute the same
 thing: the maximum element of the "list" (which has been fused away)
 of numbers from 1 to 10.

 Since 'maximum' is a foldl1 not a foldl, I use a strict Maybe type as
 an accumulator. The Maybe gets filled after the first element is seen,
 so the Maybe is a Just for almost the entire running of the loop.

 It would be good to have this recognised by SpecConstr, to create an
 optimised loop for the Just case. This does indeed happen for g1, but
 not for g2.

 My difficulty is that I am only able to produce code similar to g2,
 i.e. where the pattern matching is in a separate function, 'expose',
 because the 'expose' function is implemented in a typeclass, like in
 streamfusion. Is there some way to keep the SpecConstr while leaving
 the 'expose' as a separate function?

 Here is the code:

 > {# LANGUAGE BangPatterns #}
 >
 > module Test(ans1,ans2) where
 >
 > import Prelude hiding(Maybe(..))
 >
 > data Maybe a = Just !a  Nothing
 >
 > Nothing `mapp` Just b = Just b
 > Just a `mapp` Just b = Just (max a b)
 >
 > ans1 = g1 Nothing (0::Int)
 >
 > g1 m !n = case m of
 > Nothing > if n > 10 then m else g1 (m `mapp` Just n) (n+1)
 > Just x > if n > 10 then m else g1 (m `mapp` Just n) (n+1)
 >
 > ans2 = g2 Nothing (0::Int)
 >
 > g2 m !n = expose m (if n > 10 then m else g2 (m `mapp` Just n) (n+1))
 > expose Nothing b = b
 > expose (Just a) b = a `seq` b

 On a similar note, when I was having difficulties with this problem, I
 started to wonder if it would be possible to come up with a more
 direct way to tell GHC, "do SpecConstr on this variable". From reading
 the source code of the streamfusion package, it seems that the
 current way of doing this is with 'expose' functions like I wrote
 below. Could we instead have a {# SPECCONSTR #} pragma, to be used
 on function arguments, like:

 foo {# SPECCONSTR #} x y {# SPECCONSTR #} z = ...

 This pragma should say to the GHC something like "ignore conditions
 H2, H5 and H6 of the SpecConstr paper, for this function and this
 argument".

 Cheers,
 Reiner
 _______________________________________________
 HaskellCafe mailing list
 HaskellCafe at haskell.org
 http://www.haskell.org/mailman/listinfo/haskellcafe

  End forwarded message 
 _______________________________________________
 Glasgowhaskellusers mailing list
 Glasgowhaskellusers at haskell.org
 http://www.haskell.org/mailman/listinfo/glasgowhaskellusers
More information about the Glasgowhaskellusers
mailing list