Re: [Haskell-cafe] Maybe use advice

2011-06-07 Thread John Lato
Is it necessary (helpful) to use 'rewrite'?  Nearly every time I've tried
it, in the end 'transform' has been a better choice.  Then you wouldn't need
the 'Just's at all, and it should work fine.

John


 From: Lyndon Maydwell maydw...@gmail.com

 (missed including cafe)

 f :: [Modification] - Maybe [Modification]
 and
 f _ = Just $ f ...
 are incompatible

 I managed to get the behaviour I'm after with the use of Either, but
 this really is messy:


 -- Sets of changes
 o (Modifier (Changes [])  i) = Just $ i
 o (Modifier (Changes [c]) i) = Just $ Modifier c i
 o (Modifier (Changes l)   i) = g (f (Left l))
  where
g (Right l) = Just $ Modifier (Changes l) i
g (Left  l) = Nothing

f (Left  (Scale x y : Scale x' y' : l)) =
f $ Right $ Scale (x*x') (y*y') : h (f $ Left l)
f (Left  (Translate x y : Translate x' y' : l)) =
f $ Right $ Translate (x+x') (y+y') : h (f $ Left l)
f (Left  (Rotatex   : Rotatex': l)) =
f $ Right $ Rotate(x+x'): h (f $ Left l)
f x = x

h (Left  l) = l
h (Right l) = l


 On Tue, Jun 7, 2011 at 3:11 AM, Maciej Marcin Piechotka
 uzytkown...@gmail.com wrote:
  On Mon, 2011-06-06 at 23:38 +0800, Lyndon Maydwell wrote:
  I'm writing an optimisation routine using Uniplate. Unfortunately, a
  sub-function I'm writing is getting caught in an infinite loop because
  it doesn't return Nothing when there are no optimisations left.
 
  I'd like a way to move the last Just into f, but this makes recursion
  very messy. I was wondering if there was a nice way to use something
  like the Monad or Applicative instance to help here.
 
  -- Sets of changes
  o (Modifier (Changes []) ?i) = Just $ i
  o (Modifier (Changes [c]) i) = Just $ Modifier c i
  o (Modifier (Changes l) ? i) = Just $ Modifier (Changes (f l)) i
  ? where
  ? ? f (Scale ? ? x y : Scale ? ? x' y' : l) = f $ Scale ? ? (x*x')
 (y*y') : f l
  ? ? f (Translate x y : Translate x' y' : l) = f $ Translate (x+x')
 (y+y') : f l
  ? ? f (Rotate ? ?x ? : Rotate ? ?x' ? ?: l) = f $ Rotate ? ?(x+x') ? ? ?
 ?: f l
  ? ? f l = l
 
 
  Any ideas?
 
  Something like:
 
  ...
  f (Rotate ? ?x ? : Rotate ? ?x' ? ?: l)
  ? ?= Just $ f (Rotate (x+x') : fromMaybe l (f l))
  f l = Nothing -- As far as I understend
 
  Regards
 
  ___

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Maybe use advice

2011-06-07 Thread Lyndon Maydwell
The fixpoint nature of rewrite catches some cases that transform might
not if I'm interpreting it correctly.

(Changes [Translate 1 1, Scale 1 1, Translate 1 1]) could be rewritten
as (Translate 2 2), but I'm not sure that it could be translated as
such if it matches against (Changes [Translate _ _, Translate _ _])
first.

I have the code on github at
https://github.com/sordina/Diagrams-AST/blob/master/src/Graphics/Rendering/Diagrams/AST/Optimize.hs
if you're interested.

At the moment I'm not worrying about speed as I really just wrote this
optimisation function as a demo of why an AST interface to Diagrams
might be useful.

On Tue, Jun 7, 2011 at 5:06 PM, John Lato jwl...@gmail.com wrote:
 Is it necessary (helpful) to use 'rewrite'?  Nearly every time I've tried
 it, in the end 'transform' has been a better choice.  Then you wouldn't need
 the 'Just's at all, and it should work fine.
 John


 From: Lyndon Maydwell maydw...@gmail.com

 (missed including cafe)

 f :: [Modification] - Maybe [Modification]
 and
 f _ = Just $ f ...
 are incompatible

 I managed to get the behaviour I'm after with the use of Either, but
 this really is messy:


 -- Sets of changes
 o (Modifier (Changes [])  i) = Just $ i
 o (Modifier (Changes [c]) i) = Just $ Modifier c i
 o (Modifier (Changes l)   i) = g (f (Left l))
  where
    g (Right l) = Just $ Modifier (Changes l) i
    g (Left  l) = Nothing

    f (Left  (Scale     x y : Scale     x' y' : l)) =
        f $ Right $ Scale     (x*x') (y*y') : h (f $ Left l)
    f (Left  (Translate x y : Translate x' y' : l)) =
        f $ Right $ Translate (x+x') (y+y') : h (f $ Left l)
    f (Left  (Rotate    x   : Rotate    x'    : l)) =
        f $ Right $ Rotate    (x+x')        : h (f $ Left l)
    f x = x

    h (Left  l) = l
    h (Right l) = l


 On Tue, Jun 7, 2011 at 3:11 AM, Maciej Marcin Piechotka
 uzytkown...@gmail.com wrote:
  On Mon, 2011-06-06 at 23:38 +0800, Lyndon Maydwell wrote:
  I'm writing an optimisation routine using Uniplate. Unfortunately, a
  sub-function I'm writing is getting caught in an infinite loop because
  it doesn't return Nothing when there are no optimisations left.
 
  I'd like a way to move the last Just into f, but this makes recursion
  very messy. I was wondering if there was a nice way to use something
  like the Monad or Applicative instance to help here.
 
  -- Sets of changes
  o (Modifier (Changes []) ?i) = Just $ i
  o (Modifier (Changes [c]) i) = Just $ Modifier c i
  o (Modifier (Changes l) ? i) = Just $ Modifier (Changes (f l)) i
  ? where
  ? ? f (Scale ? ? x y : Scale ? ? x' y' : l) = f $ Scale ? ? (x*x')
  (y*y') : f l
  ? ? f (Translate x y : Translate x' y' : l) = f $ Translate (x+x')
  (y+y') : f l
  ? ? f (Rotate ? ?x ? : Rotate ? ?x' ? ?: l) = f $ Rotate ? ?(x+x') ? ?
  ? ?: f l
  ? ? f l = l
 
 
  Any ideas?
 
  Something like:
 
  ...
  f (Rotate ? ?x ? : Rotate ? ?x' ? ?: l)
  ? ?= Just $ f (Rotate (x+x') : fromMaybe l (f l))
  f l = Nothing -- As far as I understend
 
  Regards
 
  ___


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Maybe use advice

2011-06-07 Thread John Lato
If I'm interpreting your code properly, it's not currently catching that
case anyway.

The problem is that you've got two sets of modifiers that both should be
optimized, explicit Modifier constructors in the Image, and a list contained
in Changes.  Since 'Changes' is just a list of Modifiers, and not an Image,
neither rewrite nor transform will descend on it.  You get around this by
explicitly calling rewrite on the modifiers in 'deBlank', but then the rules
from 'optimize' aren't applied.  You can't really use the biplate functions
either because they only match on a single element at a time.  What you
really want to do is be able to express each rule exactly once, which isn't
possible in the current form of your code.

One solution is to move a lot of the reductions of the form 'Modifier x'
from 'optimize' into 'deBlank'.  Then you would have something like this:

 deBlank :: [Modifier] - [Modifier]
 deBlank = db

 db (Scale 1 1 : l)   = db l
 db (Rotate x : Rotate x' : l) = db (Rotate (x+x') : l)
 db (Scale  x y : Scale x' y' : l) = db (Scale (x*x') (y*y') : l)
 db (Translate x y : Translate x' y' : l) = db (Translate (x+x') (y+y') :
l)
 db xs = xs

I actually don't think uniplate gets you anything in this particular
function.

Now deBlank will produce a list of modifiers which is as reduced as possible
(at least by the rules you've provided), and you can use it within a
two-pass optimize:

 optimize = transform o2 . transform o

 o (Modifier _ Blank) = Blank
 o (Modifier (Scale 0 _) _i) = Blank
 -- similar cases omitted

 o (Modifier m2 (Modifier m1 i)) = Modifier (m1 `mappend` m2) i
 o i@(Modifier (Changes _c) _i) = i
 o (Modifier m i) = Modifier (Changes [m]) i
 o i = i

 o2 (Modifier (Changes c) i) = case deBlank c of
  [] - i
  [x] - Modifier x i
  xs - Modifier (Changes c) i
 o2 i = i

Transformations like Scale 0 _ have remained in the Image traversal,
however all other modifications are combined into a single Changes list,
which is then reduced by deBlank in the second pass.  Note that in the first
pass, even single modifications are encapsulated in a Changes; this makes
the logic of the second pass much simpler because then all the reductions of
multiple modifiers are located in the 'deBlank' function instead of split
between there and 'o'.

This presumes there's an appropriate Monoid instance for Modifiers, but if
it doesn't exist it can be written easily enough.

On second thought, I think it would be good to break it up even more, and
keep the reductions of the form

 o (Modifier _ Blank) = Blank
 o (Modifier (Scale 0 _) _i) = Blank

as a third pass, because it's possible some of them could get lost in this
form.  Then  the first pass would just combine terms, the second would apply
'deBlank' and reduce, then the third would be as above.

There are two alternatives which may be simpler:

1)  Expand Changes c into explicit modifications and do all your
reductions on the resulting Image.

2)   Implement a general matrix transform for Diagrams and rewrite
everything in terms of that.  This would be useful for shear transforms
anyway, which I believe are currently inexpressible in Diagrams.

John Lato

On Tue, Jun 7, 2011 at 10:12 AM, Lyndon Maydwell maydw...@gmail.com wrote:

 The fixpoint nature of rewrite catches some cases that transform might
 not if I'm interpreting it correctly.

 (Changes [Translate 1 1, Scale 1 1, Translate 1 1]) could be rewritten
 as (Translate 2 2), but I'm not sure that it could be translated as
 such if it matches against (Changes [Translate _ _, Translate _ _])
 first.

 I have the code on github at

https://github.com/sordina/Diagrams-AST/blob/master/src/Graphics/Rendering/Diagrams/AST/Optimize.hs
 if you're interested.

 At the moment I'm not worrying about speed as I really just wrote this
 optimisation function as a demo of why an AST interface to Diagrams
 might be useful.

 On Tue, Jun 7, 2011 at 5:06 PM, John Lato jwl...@gmail.com wrote:
  Is it necessary (helpful) to use 'rewrite'?  Nearly every time I've
tried
  it, in the end 'transform' has been a better choice.  Then you wouldn't
need
  the 'Just's at all, and it should work fine.
  John
 
 
  From: Lyndon Maydwell maydw...@gmail.com
 
  (missed including cafe)
 
  f :: [Modification] - Maybe [Modification]
  and
  f _ = Just $ f ...
  are incompatible
 
  I managed to get the behaviour I'm after with the use of Either, but
  this really is messy:
 
 
  -- Sets of changes
  o (Modifier (Changes [])  i) = Just $ i
  o (Modifier (Changes [c]) i) = Just $ Modifier c i
  o (Modifier (Changes l)   i) = g (f (Left l))
   where
 g (Right l) = Just $ Modifier (Changes l) i
 g (Left  l) = Nothing
 
 f (Left  (Scale x y : Scale x' y' : l)) =
 f $ Right $ Scale (x*x') (y*y') : h (f $ Left l)
 f (Left  (Translate x y : Translate x' y' : l)) =
 f $ Right $ Translate (x+x') (y+y') : h (f $ Left l)
 f (Left  (Rotatex   : Rotatex': l)) =

Re: [Haskell-cafe] Maybe use advice

2011-06-07 Thread Lyndon Maydwell
I was considering using a matrix optimisation but things are out of
control enough already :)

Converting all Changes constructors to nested regular constructors may
be the easiest approach. It would certainly eliminate the mess of list
manipulations.

On Tue, Jun 7, 2011 at 6:21 PM, John Lato jwl...@gmail.com wrote:
 If I'm interpreting your code properly, it's not currently catching that
 case anyway.
 The problem is that you've got two sets of modifiers that both should be
 optimized, explicit Modifier constructors in the Image, and a list contained
 in Changes.  Since 'Changes' is just a list of Modifiers, and not an Image,
 neither rewrite nor transform will descend on it.  You get around this by
 explicitly calling rewrite on the modifiers in 'deBlank', but then the rules
 from 'optimize' aren't applied.  You can't really use the biplate functions
 either because they only match on a single element at a time.  What you
 really want to do is be able to express each rule exactly once, which isn't
 possible in the current form of your code.
 One solution is to move a lot of the reductions of the form 'Modifier x'
 from 'optimize' into 'deBlank'.  Then you would have something like this:

 deBlank :: [Modifier] - [Modifier]
 deBlank = db

 db (Scale 1 1 : l)   = db l
 db (Rotate x : Rotate x' : l) = db (Rotate (x+x') : l)
 db (Scale  x y : Scale x' y' : l) = db (Scale (x*x') (y*y') : l)
 db (Translate x y : Translate x' y' : l) = db (Translate (x+x') (y+y') :
 l)
 db xs = xs

 I actually don't think uniplate gets you anything in this particular
 function.
 Now deBlank will produce a list of modifiers which is as reduced as possible
 (at least by the rules you've provided), and you can use it within a
 two-pass optimize:
 optimize = transform o2 . transform o

 o (Modifier _ Blank) = Blank
 o (Modifier (Scale 0 _) _i) = Blank
 -- similar cases omitted

 o (Modifier m2 (Modifier m1 i)) = Modifier (m1 `mappend` m2) i
 o i@(Modifier (Changes _c) _i) = i
 o (Modifier m i) = Modifier (Changes [m]) i
 o i = i

 o2 (Modifier (Changes c) i) = case deBlank c of
      [] - i
      [x] - Modifier x i
      xs - Modifier (Changes c) i
 o2 i = i
 Transformations like Scale 0 _ have remained in the Image traversal,
 however all other modifications are combined into a single Changes list,
 which is then reduced by deBlank in the second pass.  Note that in the first
 pass, even single modifications are encapsulated in a Changes; this makes
 the logic of the second pass much simpler because then all the reductions of
 multiple modifiers are located in the 'deBlank' function instead of split
 between there and 'o'.
 This presumes there's an appropriate Monoid instance for Modifiers, but if
 it doesn't exist it can be written easily enough.
 On second thought, I think it would be good to break it up even more, and
 keep the reductions of the form
 o (Modifier _ Blank) = Blank
 o (Modifier (Scale 0 _) _i) = Blank
 as a third pass, because it's possible some of them could get lost in this
 form.  Then  the first pass would just combine terms, the second would apply
 'deBlank' and reduce, then the third would be as above.
 There are two alternatives which may be simpler:
 1)  Expand Changes c into explicit modifications and do all your
 reductions on the resulting Image.
 2)   Implement a general matrix transform for Diagrams and rewrite
 everything in terms of that.  This would be useful for shear transforms
 anyway, which I believe are currently inexpressible in Diagrams.
 John Lato
 On Tue, Jun 7, 2011 at 10:12 AM, Lyndon Maydwell maydw...@gmail.com wrote:

 The fixpoint nature of rewrite catches some cases that transform might
 not if I'm interpreting it correctly.

 (Changes [Translate 1 1, Scale 1 1, Translate 1 1]) could be rewritten
 as (Translate 2 2), but I'm not sure that it could be translated as
 such if it matches against (Changes [Translate _ _, Translate _ _])
 first.

 I have the code on github at

 https://github.com/sordina/Diagrams-AST/blob/master/src/Graphics/Rendering/Diagrams/AST/Optimize.hs
 if you're interested.

 At the moment I'm not worrying about speed as I really just wrote this
 optimisation function as a demo of why an AST interface to Diagrams
 might be useful.

 On Tue, Jun 7, 2011 at 5:06 PM, John Lato jwl...@gmail.com wrote:
  Is it necessary (helpful) to use 'rewrite'?  Nearly every time I've
  tried
  it, in the end 'transform' has been a better choice.  Then you wouldn't
  need
  the 'Just's at all, and it should work fine.
  John
 
 
  From: Lyndon Maydwell maydw...@gmail.com
 
  (missed including cafe)
 
  f :: [Modification] - Maybe [Modification]
  and
  f _ = Just $ f ...
  are incompatible
 
  I managed to get the behaviour I'm after with the use of Either, but
  this really is messy:
 
 
  -- Sets of changes
  o (Modifier (Changes [])  i) = Just $ i
  o (Modifier (Changes [c]) i) = Just $ Modifier c i
  o (Modifier (Changes l)   i) = g (f (Left l))
   where
     g (Right l) = Just 

Re: [Haskell-cafe] Maybe use advice

2011-06-06 Thread Maciej Marcin Piechotka
On Mon, 2011-06-06 at 23:38 +0800, Lyndon Maydwell wrote:
 I'm writing an optimisation routine using Uniplate. Unfortunately, a
 sub-function I'm writing is getting caught in an infinite loop because
 it doesn't return Nothing when there are no optimisations left.
 
 I'd like a way to move the last Just into f, but this makes recursion
 very messy. I was wondering if there was a nice way to use something
 like the Monad or Applicative instance to help here.
 
 -- Sets of changes
 o (Modifier (Changes [])  i) = Just $ i
 o (Modifier (Changes [c]) i) = Just $ Modifier c i
 o (Modifier (Changes l)   i) = Just $ Modifier (Changes (f l)) i
   where
 f (Scale x y : Scale x' y' : l) = f $ Scale (x*x') (y*y') : f 
 l
 f (Translate x y : Translate x' y' : l) = f $ Translate (x+x') (y+y') : f 
 l
 f (Rotatex   : Rotatex': l) = f $ Rotate(x+x'): f 
 l
 f l = l
 
 
 Any ideas?

Something like:

...
f (Rotatex   : Rotatex': l)
= Just $ f (Rotate (x+x') : fromMaybe l (f l))
f l = Nothing -- As far as I understend

Regards


signature.asc
Description: This is a digitally signed message part
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Maybe use advice

2011-06-06 Thread Lyndon Maydwell
(missed including cafe)

f :: [Modification] - Maybe [Modification]
and
f _ = Just $ f ...
are incompatible

I managed to get the behaviour I'm after with the use of Either, but
this really is messy:


-- Sets of changes
o (Modifier (Changes [])  i) = Just $ i
o (Modifier (Changes [c]) i) = Just $ Modifier c i
o (Modifier (Changes l)   i) = g (f (Left l))
  where
g (Right l) = Just $ Modifier (Changes l) i
g (Left  l) = Nothing

f (Left  (Scale x y : Scale x' y' : l)) =
f $ Right $ Scale (x*x') (y*y') : h (f $ Left l)
f (Left  (Translate x y : Translate x' y' : l)) =
f $ Right $ Translate (x+x') (y+y') : h (f $ Left l)
f (Left  (Rotatex   : Rotatex': l)) =
f $ Right $ Rotate(x+x'): h (f $ Left l)
f x = x

h (Left  l) = l
h (Right l) = l


On Tue, Jun 7, 2011 at 3:11 AM, Maciej Marcin Piechotka
uzytkown...@gmail.com wrote:
 On Mon, 2011-06-06 at 23:38 +0800, Lyndon Maydwell wrote:
 I'm writing an optimisation routine using Uniplate. Unfortunately, a
 sub-function I'm writing is getting caught in an infinite loop because
 it doesn't return Nothing when there are no optimisations left.

 I'd like a way to move the last Just into f, but this makes recursion
 very messy. I was wondering if there was a nice way to use something
 like the Monad or Applicative instance to help here.

 -- Sets of changes
 o (Modifier (Changes [])  i) = Just $ i
 o (Modifier (Changes [c]) i) = Just $ Modifier c i
 o (Modifier (Changes l)   i) = Just $ Modifier (Changes (f l)) i
   where
     f (Scale     x y : Scale     x' y' : l) = f $ Scale     (x*x') (y*y') : 
 f l
     f (Translate x y : Translate x' y' : l) = f $ Translate (x+x') (y+y') : 
 f l
     f (Rotate    x   : Rotate    x'    : l) = f $ Rotate    (x+x')        : 
 f l
     f l = l


 Any ideas?

 Something like:

 ...
 f (Rotate    x   : Rotate    x'    : l)
    = Just $ f (Rotate (x+x') : fromMaybe l (f l))
 f l = Nothing -- As far as I understend

 Regards

 ___
 Haskell-Cafe mailing list
 Haskell-Cafe@haskell.org
 http://www.haskell.org/mailman/listinfo/haskell-cafe



___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Maybe use advice

2011-06-06 Thread Maciej Piechotka
On Tue, 2011-06-07 at 04:09 +0800, Lyndon Maydwell wrote:
 (missed including cafe)
 
 f :: [Modification] - Maybe [Modification]
 and
 f _ = Just $ f ...
 are incompatible
 


My bad:

f ... = let cs' = (Rotate (x+x') : fromMaybe cs (f cs))
in fromMaybe cs (f cs)

Or refactoring it:

g l = fromMaybe l (f l)

f (Rotatex   : Rotatex': cs) = g (Rotate (x+x') : g cs)

Regards

 I managed to get the behaviour I'm after with the use of Either, but
 this really is messy:
 
 
 -- Sets of changes
 o (Modifier (Changes [])  i) = Just $ i
 o (Modifier (Changes [c]) i) = Just $ Modifier c i
 o (Modifier (Changes l)   i) = g (f (Left l))
   where
 g (Right l) = Just $ Modifier (Changes l) i
 g (Left  l) = Nothing
 
 f (Left  (Scale x y : Scale x' y' : l)) =
 f $ Right $ Scale (x*x') (y*y') : h (f $ Left l)
 f (Left  (Translate x y : Translate x' y' : l)) =
 f $ Right $ Translate (x+x') (y+y') : h (f $ Left l)
 f (Left  (Rotatex   : Rotatex': l)) =
 f $ Right $ Rotate(x+x'): h (f $ Left l)
 f x = x
 
 h (Left  l) = l
 h (Right l) = l
 
 
 On Tue, Jun 7, 2011 at 3:11 AM, Maciej Marcin Piechotka
 uzytkown...@gmail.com wrote:
  On Mon, 2011-06-06 at 23:38 +0800, Lyndon Maydwell wrote:
  I'm writing an optimisation routine using Uniplate. Unfortunately, a
  sub-function I'm writing is getting caught in an infinite loop because
  it doesn't return Nothing when there are no optimisations left.
 
  I'd like a way to move the last Just into f, but this makes recursion
  very messy. I was wondering if there was a nice way to use something
  like the Monad or Applicative instance to help here.
 
  -- Sets of changes
  o (Modifier (Changes [])  i) = Just $ i
  o (Modifier (Changes [c]) i) = Just $ Modifier c i
  o (Modifier (Changes l)   i) = Just $ Modifier (Changes (f l)) i
where
  f (Scale x y : Scale x' y' : l) = f $ Scale (x*x') (y*y') 
  : f l
  f (Translate x y : Translate x' y' : l) = f $ Translate (x+x') (y+y') 
  : f l
  f (Rotatex   : Rotatex': l) = f $ Rotate(x+x')
  : f l
  f l = l
 
 
  Any ideas?
 
  Something like:
 
  ...
  f (Rotatex   : Rotatex': l)
 = Just $ f (Rotate (x+x') : fromMaybe l (f l))
  f l = Nothing -- As far as I understend
 
  Regards
 
  ___
  Haskell-Cafe mailing list
  Haskell-Cafe@haskell.org
  http://www.haskell.org/mailman/listinfo/haskell-cafe
 
 




signature.asc
Description: This is a digitally signed message part
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Maybe use advice

2011-06-06 Thread Lyndon Maydwell
Thanks Maciej!

An additional Just was required in the refactored version of f:

f (Rotatex   : Rotatex': cs) = Just $ g (Rotate (x+x') : g cs)

This is much cleaner than what I was doing.


On Tue, Jun 7, 2011 at 4:14 AM, Maciej Piechotka uzytkown...@gmail.com wrote:
 On Tue, 2011-06-07 at 04:09 +0800, Lyndon Maydwell wrote:
 (missed including cafe)

 f :: [Modification] - Maybe [Modification]
 and
 f _ = Just $ f ...
 are incompatible



 My bad:

 f ... = let cs' = (Rotate (x+x') : fromMaybe cs (f cs))
        in fromMaybe cs (f cs)

 Or refactoring it:

 g l = fromMaybe l (f l)

 f (Rotate    x   : Rotate    x'    : cs) = g (Rotate (x+x') : g cs)

 Regards

 I managed to get the behaviour I'm after with the use of Either, but
 this really is messy:


 -- Sets of changes
 o (Modifier (Changes [])  i) = Just $ i
 o (Modifier (Changes [c]) i) = Just $ Modifier c i
 o (Modifier (Changes l)   i) = g (f (Left l))
   where
     g (Right l) = Just $ Modifier (Changes l) i
     g (Left  l) = Nothing

     f (Left  (Scale     x y : Scale     x' y' : l)) =
         f $ Right $ Scale     (x*x') (y*y') : h (f $ Left l)
     f (Left  (Translate x y : Translate x' y' : l)) =
         f $ Right $ Translate (x+x') (y+y') : h (f $ Left l)
     f (Left  (Rotate    x   : Rotate    x'    : l)) =
         f $ Right $ Rotate    (x+x')        : h (f $ Left l)
     f x = x

     h (Left  l) = l
     h (Right l) = l


 On Tue, Jun 7, 2011 at 3:11 AM, Maciej Marcin Piechotka
 uzytkown...@gmail.com wrote:
  On Mon, 2011-06-06 at 23:38 +0800, Lyndon Maydwell wrote:
  I'm writing an optimisation routine using Uniplate. Unfortunately, a
  sub-function I'm writing is getting caught in an infinite loop because
  it doesn't return Nothing when there are no optimisations left.
 
  I'd like a way to move the last Just into f, but this makes recursion
  very messy. I was wondering if there was a nice way to use something
  like the Monad or Applicative instance to help here.
 
  -- Sets of changes
  o (Modifier (Changes [])  i) = Just $ i
  o (Modifier (Changes [c]) i) = Just $ Modifier c i
  o (Modifier (Changes l)   i) = Just $ Modifier (Changes (f l)) i
    where
      f (Scale     x y : Scale     x' y' : l) = f $ Scale     (x*x') (y*y') 
  : f l
      f (Translate x y : Translate x' y' : l) = f $ Translate (x+x') (y+y') 
  : f l
      f (Rotate    x   : Rotate    x'    : l) = f $ Rotate    (x+x')        
  : f l
      f l = l
 
 
  Any ideas?
 
  Something like:
 
  ...
  f (Rotate    x   : Rotate    x'    : l)
     = Just $ f (Rotate (x+x') : fromMaybe l (f l))
  f l = Nothing -- As far as I understend
 
  Regards
 
  ___
  Haskell-Cafe mailing list
  Haskell-Cafe@haskell.org
  http://www.haskell.org/mailman/listinfo/haskell-cafe
 
 




___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Maybe use advice

2011-06-06 Thread Stephen Tetley
Hi Lyndon

Are you just coalescing adjacent elements (if they are the same constructor)?

As it seems you have a list here rather than a tree, I'd step out of
Uniplate at this point and just do a list traversal with direct
recursion.

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe