How best to do this?

I have built a library for using the Hexwax expandIO-USB chip and I have now got some code to drive a stepper motor: doOption :: HWHandle -> Flag -> IO () doOption dev (Backward n) = do putStrLn $ "> STEP BACKWARD " ++ (show n) let x = [ stepBit b | b <- [3..0]] return () where stepBit p b = setBit p b 0 >> setBit p b 1 where setBit p b s = HW.setPortBit dev p b s >> stepDelay It feels a little smelly... if I don't assign the result of the list comprehension to "x" the return type blows at me hence the return(), to get past the door steward type checker... so what would be the "ideal" way to just execute my LC to step the bits and then return. I thought of using "liftIO" but I think that would be "backwards" here if you catch my drift. I am already in the IO monad as it is, so that has confused me because liftIO lifts something "into" the IO monad and I am already there... this project is making me work harder at my Haskell and I think that once I've completed it I will be much further advanced with it... So, if anybody cares to suggest more elegant and Haskell like ways to re-factor the above code I am more than happy to know about it! All the best, Sean.

forM_ [0..3] \b -> stepBit b .... ?
On 29 Apr 2013 15:01, "emacstheviking"
I have built a library for using the Hexwax expandIO-USB chip and I have now got some code to drive a stepper motor:
doOption :: HWHandle -> Flag -> IO () doOption dev (Backward n) = do putStrLn $ "> STEP BACKWARD " ++ (show n) let x = [ stepBit b | b <- [3..0]] return () where stepBit p b = setBit p b 0 >> setBit p b 1 where setBit p b s = HW.setPortBit dev p b s >> stepDelay
It feels a little smelly... if I don't assign the result of the list comprehension to "x" the return type blows at me hence the return(), to get past the door steward type checker... so what would be the "ideal" way to just execute my LC to step the bits and then return.
I thought of using "liftIO" but I think that would be "backwards" here if you catch my drift. I am already in the IO monad as it is, so that has confused me because liftIO lifts something "into" the IO monad and I am already there... this project is making me work harder at my Haskell and I think that once I've completed it I will be much further advanced with it...
So, if anybody cares to suggest more elegant and Haskell like ways to re-factor the above code I am more than happy to know about it!
All the best, Sean.
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners

Benjamin, I am sure I tried that but I was hell bent on using a list
comprehension...if it comes to it though I will do it!
On 29 April 2013 15:07, Benjamin Edwards
forM_ [0..3] \b -> stepBit b .... ? On 29 Apr 2013 15:01, "emacstheviking"
wrote: I have built a library for using the Hexwax expandIO-USB chip and I have now got some code to drive a stepper motor:
doOption :: HWHandle -> Flag -> IO () doOption dev (Backward n) = do putStrLn $ "> STEP BACKWARD " ++ (show n) let x = [ stepBit b | b <- [3..0]] return () where stepBit p b = setBit p b 0 >> setBit p b 1 where setBit p b s = HW.setPortBit dev p b s >> stepDelay
It feels a little smelly... if I don't assign the result of the list comprehension to "x" the return type blows at me hence the return(), to get past the door steward type checker... so what would be the "ideal" way to just execute my LC to step the bits and then return.
I thought of using "liftIO" but I think that would be "backwards" here if you catch my drift. I am already in the IO monad as it is, so that has confused me because liftIO lifts something "into" the IO monad and I am already there... this project is making me work harder at my Haskell and I think that once I've completed it I will be much further advanced with it...
So, if anybody cares to suggest more elegant and Haskell like ways to re-factor the above code I am more than happy to know about it!
All the best, Sean.
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners

Benjamin,
I have managed to reduce it all to this for which I thank you, it feels
much neater now...
doOption dev (Forward n) = do
putStrLn $ "> STEP FORWARD " ++ (show n)
forM_ [3..0] (\b -> stepBit dev ioPORTA b)
doOption dev (Backward n) = do
putStrLn $ "> STEP BACKWARD " ++ (show n)
forM_ [0..3] (\b -> stepBit dev ioPORTA b)
stepBit :: HWHandle -> Word8 -> Word8 -> IO ()
stepBit dev p b = setBit p b 0 >> setBit p b 1
where
setBit p b s = HW.setPortBit dev p b s >> stepDelay
I think I will also try to use "forEach_" as well which means I can then
compose is something that passes in [0..3] or [3..0] to the composition...
I may even learn something in the process!
God I love the way that Haskell makes you *want* to reduce things to their
most succint form, even if it hurts along the way.
Only Lisp ever (ha, still does!) made me feel like Haskell does, aka a
total n00b after 28 years in the business! LMAO
Thanks list.
On 29 April 2013 15:07, Benjamin Edwards
forM_ [0..3] \b -> stepBit b .... ? On 29 Apr 2013 15:01, "emacstheviking"
wrote: I have built a library for using the Hexwax expandIO-USB chip and I have now got some code to drive a stepper motor:
doOption :: HWHandle -> Flag -> IO () doOption dev (Backward n) = do putStrLn $ "> STEP BACKWARD " ++ (show n) let x = [ stepBit b | b <- [3..0]] return () where stepBit p b = setBit p b 0 >> setBit p b 1 where setBit p b s = HW.setPortBit dev p b s >> stepDelay
It feels a little smelly... if I don't assign the result of the list comprehension to "x" the return type blows at me hence the return(), to get past the door steward type checker... so what would be the "ideal" way to just execute my LC to step the bits and then return.
I thought of using "liftIO" but I think that would be "backwards" here if you catch my drift. I am already in the IO monad as it is, so that has confused me because liftIO lifts something "into" the IO monad and I am already there... this project is making me work harder at my Haskell and I think that once I've completed it I will be much further advanced with it...
So, if anybody cares to suggest more elegant and Haskell like ways to re-factor the above code I am more than happy to know about it!
All the best, Sean.
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners

-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On 29/04/13 15:37, emacstheviking wrote:
Benjamin, I have managed to reduce it all to this for which I thank you, it feels much neater now...
doOption dev (Forward n) = do putStrLn $ "> STEP FORWARD " ++ (show n) forM_ [3..0] (\b -> stepBit dev ioPORTA b)
doOption dev (Backward n) = do putStrLn $ "> STEP BACKWARD " ++ (show n) forM_ [0..3] (\b -> stepBit dev ioPORTA b)
stepBit :: HWHandle -> Word8 -> Word8 -> IO () stepBit dev p b = setBit p b 0 >> setBit p b 1 where setBit p b s = HW.setPortBit dev p b s >> stepDelay
I think I will also try to use "forEach_" as well which means I can then compose is something that passes in [0..3] or [3..0] to the composition... I may even learn something in the process! God I love the way that Haskell makes you *want* to reduce things to their most succint form, even if it hurts along the way. Only Lisp ever (ha, still does!) made me feel like Haskell does, aka a total n00b after 28 years in the business! LMAO
Thanks list.
The next step would be to factor out that horrible repetition. Maybe something like this: doOption dev x = case x of (Backward n) -> stepper "FORWARD" (Forward n) -> stepper "BACKWARD" where stepper w = do putStrLn $ "> STEP " ++ w ++ (show n) forM_ [0 .. 3] (\b -> stepBit dev ioPORTA b) I think this should work. It's also easier to introduce more options this way. - -- Mateusz K. -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.19 (GNU/Linux) iQIcBAEBAgAGBQJRfomiAAoJEM1mucMq2pqXpc8P/1X+snuFWZkprraX0UAZ95e7 pvCGelnxxW2rN1iUolzM5rD6MYBKTBhEMBp+SALrdQ3xUIYk/EP1yRfKnxJITe1g CN08XqUcX47QMtmxQPvngKITT1L+voAL0DSei225ohT/lMIwetfbJuXub9iKzZ/G YwLenR3R2E6iznys/Z/93Kk9tP5fXrOEkAFurqhe+xYTQnvDTMClv9cYEAj4xB1f 6x9gfqt5MbvJSyJ4PrGkJtXmS4RGSrysR5Eccf2p9CETlbBEo3uBHpzAPmqGXDFs nfeuBoWxMb/X1w9ABim/i0pITR25S+XHG9HAlQNZ3jikY057Ict9YIr7xYkFjsPh PEwVPlbf3QOTJW3IBXMbVTjA7yPiJnjG/tgAB3b8NYQnVfgPAQ/g7bw77pfm9W6X ajbXgQ9slPADhG4vEKr7ktT8CD+DlOcm/iBYockQe3h6RoFSsRFSSoCOCM8ogPUl xWp7wlZeRnP4AGB+R5vSHd06Fzk60L7D7vJvgTLINjqvhWGNrcVhvkEsCm9MWXEM /rdqnbPBuUM3qz0MQnxWHvLeXgAIP5SzYxv2FthXlF+00/1Emqr1vk2F27mppDfZ Xy/PUDjYTSHLCgPNvHVLyE9xfyVAPyqM2TarBrn8jyvi5Bx7WDn++4POD5B39MvM TD57PLQJLg0oVrrLFnYQ =Mbcq -----END PGP SIGNATURE-----

On Mon, Apr 29, 2013 at 02:59:29PM +0100, emacstheviking wrote:
I have built a library for using the Hexwax expandIO-USB chip and I have now got some code to drive a stepper motor:
doOption :: HWHandle -> Flag -> IO () doOption dev (Backward n) = do putStrLn $ "> STEP BACKWARD " ++ (show n) let x = [ stepBit b | b <- [3..0]] return () where stepBit p b = setBit p b 0 >> setBit p b 1 where setBit p b s = HW.setPortBit dev p b s >> stepDelay
The other posted solutions are good, but I also want to make a very important comment about the above code: it does not actually step any bits! All it does is print some stuff. x is simply a name for a list of IO actions; it is never used so it just gets garbage collected and the IO actions are never run. -Brent

damn that lazy evaluation! LMAO ...a good point brent and yuo have no
doubt saved me hours of head scratching this evening when I try out the
"new improved software". Oh dear oh dear oh dear...
doOption dev (Forward n) = do
putStrLn $ "> STEP FORWARD " ++ (show n)
stepBits dev ioPORTA [3..0]
doOption dev (Backward n) = do
putStrLn $ "> STEP BACKWARD " ++ (show n)
stepBits dev ioPORTA [0..3]
stepBits dev port = mapM_ stepIt
where stepIt bit = mapM_ (\s -> HW.setPortBit dev port bit s >>
stepDelay) [0,1]
I now have the above as my current "final" implementation... hopefully that
*does* do what I think it does because mapM_ is driving it and will cause
evaluation of the actions?
On 29 April 2013 15:56, Brent Yorgey
On Mon, Apr 29, 2013 at 02:59:29PM +0100, emacstheviking wrote:
I have built a library for using the Hexwax expandIO-USB chip and I have now got some code to drive a stepper motor:
doOption :: HWHandle -> Flag -> IO () doOption dev (Backward n) = do putStrLn $ "> STEP BACKWARD " ++ (show n) let x = [ stepBit b | b <- [3..0]] return () where stepBit p b = setBit p b 0 >> setBit p b 1 where setBit p b s = HW.setPortBit dev p b s >> stepDelay
The other posted solutions are good, but I also want to make a very important comment about the above code: it does not actually step any bits! All it does is print some stuff. x is simply a name for a list of IO actions; it is never used so it just gets garbage collected and the IO actions are never run.
-Brent
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners

One other gotcha. I don't know why it is this way, but [3..0]
evaluates to []. I have no idea why reverse notation is not allowed.
But you can just manually reverse it or you can go [3,2..0].
On Mon, Apr 29, 2013 at 11:26 AM, emacstheviking
damn that lazy evaluation! LMAO ...a good point brent and yuo have no doubt saved me hours of head scratching this evening when I try out the "new improved software". Oh dear oh dear oh dear...
doOption dev (Forward n) = do putStrLn $ "> STEP FORWARD " ++ (show n) stepBits dev ioPORTA [3..0]
doOption dev (Backward n) = do putStrLn $ "> STEP BACKWARD " ++ (show n) stepBits dev ioPORTA [0..3]
stepBits dev port = mapM_ stepIt where stepIt bit = mapM_ (\s -> HW.setPortBit dev port bit s >> stepDelay) [0,1]
I now have the above as my current "final" implementation... hopefully that *does* do what I think it does because mapM_ is driving it and will cause evaluation of the actions?
On 29 April 2013 15:56, Brent Yorgey
wrote: On Mon, Apr 29, 2013 at 02:59:29PM +0100, emacstheviking wrote:
I have built a library for using the Hexwax expandIO-USB chip and I have now got some code to drive a stepper motor:
doOption :: HWHandle -> Flag -> IO () doOption dev (Backward n) = do putStrLn $ "> STEP BACKWARD " ++ (show n) let x = [ stepBit b | b <- [3..0]] return () where stepBit p b = setBit p b 0 >> setBit p b 1 where setBit p b s = HW.setPortBit dev p b s >> stepDelay
The other posted solutions are good, but I also want to make a very important comment about the above code: it does not actually step any bits! All it does is print some stuff. x is simply a name for a list of IO actions; it is never used so it just gets garbage collected and the IO actions are never run.
-Brent
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners

ROFLCOPTER indeed Batman!
I had no idea of that... I just *assumed* (usual rules apply I guess) that
[3..0] was the "opposite" of [0..3] but sure enough a wuicj ghci session
reveals the bitter truth!
Thanks again... i can see that it's not just me that is too lazy at times.
I guess writing [3,2..0] will do for now but is that a bug or is there some
other reasoning behind it?
We live and learn, well, I live anyway...
:)
On 29 April 2013 16:37, David McBride
One other gotcha. I don't know why it is this way, but [3..0] evaluates to []. I have no idea why reverse notation is not allowed. But you can just manually reverse it or you can go [3,2..0].
damn that lazy evaluation! LMAO ...a good point brent and yuo have no doubt saved me hours of head scratching this evening when I try out the "new improved software". Oh dear oh dear oh dear...
doOption dev (Forward n) = do putStrLn $ "> STEP FORWARD " ++ (show n) stepBits dev ioPORTA [3..0]
doOption dev (Backward n) = do putStrLn $ "> STEP BACKWARD " ++ (show n) stepBits dev ioPORTA [0..3]
stepBits dev port = mapM_ stepIt where stepIt bit = mapM_ (\s -> HW.setPortBit dev port bit s >> stepDelay) [0,1]
I now have the above as my current "final" implementation... hopefully
On Mon, Apr 29, 2013 at 11:26 AM, emacstheviking
wrote: that *does* do what I think it does because mapM_ is driving it and will cause evaluation of the actions?
On 29 April 2013 15:56, Brent Yorgey
wrote: On Mon, Apr 29, 2013 at 02:59:29PM +0100, emacstheviking wrote:
I have built a library for using the Hexwax expandIO-USB chip and I
have
now got some code to drive a stepper motor:
doOption :: HWHandle -> Flag -> IO () doOption dev (Backward n) = do putStrLn $ "> STEP BACKWARD " ++ (show n) let x = [ stepBit b | b <- [3..0]] return () where stepBit p b = setBit p b 0 >> setBit p b 1 where setBit p b s = HW.setPortBit dev p b s >> stepDelay
The other posted solutions are good, but I also want to make a very important comment about the above code: it does not actually step any bits! All it does is print some stuff. x is simply a name for a list of IO actions; it is never used so it just gets garbage collected and the IO actions are never run.
-Brent
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners

I think it is because that syntax is desugared directly to enumFromTo
x y and enumFromTo 3 0 is []. Random things would probably blow up if
you make that function work in reverse. But I would love it if ghc
just checked whether the first was lower than the second and swapped
them as a convenience.
On Mon, Apr 29, 2013 at 11:44 AM, emacstheviking
ROFLCOPTER indeed Batman!
I had no idea of that... I just *assumed* (usual rules apply I guess) that [3..0] was the "opposite" of [0..3] but sure enough a wuicj ghci session reveals the bitter truth!
Thanks again... i can see that it's not just me that is too lazy at times. I guess writing [3,2..0] will do for now but is that a bug or is there some other reasoning behind it?
We live and learn, well, I live anyway...
:)
On 29 April 2013 16:37, David McBride
wrote: One other gotcha. I don't know why it is this way, but [3..0] evaluates to []. I have no idea why reverse notation is not allowed. But you can just manually reverse it or you can go [3,2..0].
On Mon, Apr 29, 2013 at 11:26 AM, emacstheviking
wrote: damn that lazy evaluation! LMAO ...a good point brent and yuo have no doubt saved me hours of head scratching this evening when I try out the "new improved software". Oh dear oh dear oh dear...
doOption dev (Forward n) = do putStrLn $ "> STEP FORWARD " ++ (show n) stepBits dev ioPORTA [3..0]
doOption dev (Backward n) = do putStrLn $ "> STEP BACKWARD " ++ (show n) stepBits dev ioPORTA [0..3]
stepBits dev port = mapM_ stepIt where stepIt bit = mapM_ (\s -> HW.setPortBit dev port bit s >> stepDelay) [0,1]
I now have the above as my current "final" implementation... hopefully that *does* do what I think it does because mapM_ is driving it and will cause evaluation of the actions?
On 29 April 2013 15:56, Brent Yorgey
wrote: On Mon, Apr 29, 2013 at 02:59:29PM +0100, emacstheviking wrote:
I have built a library for using the Hexwax expandIO-USB chip and I have now got some code to drive a stepper motor:
doOption :: HWHandle -> Flag -> IO () doOption dev (Backward n) = do putStrLn $ "> STEP BACKWARD " ++ (show n) let x = [ stepBit b | b <- [3..0]] return () where stepBit p b = setBit p b 0 >> setBit p b 1 where setBit p b s = HW.setPortBit dev p b s >> stepDelay
The other posted solutions are good, but I also want to make a very important comment about the above code: it does not actually step any bits! All it does is print some stuff. x is simply a name for a list of IO actions; it is never used so it just gets garbage collected and the IO actions are never run.
-Brent
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners

I like / don't like the "Random things would probably blow" because this is
driving hardware as well!
Scary stuff!
Thanks again.
On 29 April 2013 16:57, David McBride
I think it is because that syntax is desugared directly to enumFromTo x y and enumFromTo 3 0 is []. Random things would probably blow up if you make that function work in reverse. But I would love it if ghc just checked whether the first was lower than the second and swapped them as a convenience.
ROFLCOPTER indeed Batman!
I had no idea of that... I just *assumed* (usual rules apply I guess)
[3..0] was the "opposite" of [0..3] but sure enough a wuicj ghci session reveals the bitter truth!
Thanks again... i can see that it's not just me that is too lazy at times. I guess writing [3,2..0] will do for now but is that a bug or is there some other reasoning behind it?
We live and learn, well, I live anyway...
:)
On 29 April 2013 16:37, David McBride
wrote: One other gotcha. I don't know why it is this way, but [3..0] evaluates to []. I have no idea why reverse notation is not allowed. But you can just manually reverse it or you can go [3,2..0].
On Mon, Apr 29, 2013 at 11:26 AM, emacstheviking
wrote: damn that lazy evaluation! LMAO ...a good point brent and yuo have no doubt saved me hours of head scratching this evening when I try out the "new improved software". Oh dear oh dear oh dear...
doOption dev (Forward n) = do putStrLn $ "> STEP FORWARD " ++ (show n) stepBits dev ioPORTA [3..0]
doOption dev (Backward n) = do putStrLn $ "> STEP BACKWARD " ++ (show n) stepBits dev ioPORTA [0..3]
stepBits dev port = mapM_ stepIt where stepIt bit = mapM_ (\s -> HW.setPortBit dev port bit s >> stepDelay) [0,1]
I now have the above as my current "final" implementation... hopefully that *does* do what I think it does because mapM_ is driving it and will cause evaluation of the actions?
On 29 April 2013 15:56, Brent Yorgey
wrote: On Mon, Apr 29, 2013 at 02:59:29PM +0100, emacstheviking wrote:
I have built a library for using the Hexwax expandIO-USB chip and I have now got some code to drive a stepper motor:
doOption :: HWHandle -> Flag -> IO () doOption dev (Backward n) = do putStrLn $ "> STEP BACKWARD " ++ (show n) let x = [ stepBit b | b <- [3..0]] return () where stepBit p b = setBit p b 0 >> setBit p b 1 where setBit p b s = HW.setPortBit dev p b s >> stepDelay
The other posted solutions are good, but I also want to make a very important comment about the above code: it does not actually step any bits! All it does is print some stuff. x is simply a name for a
On Mon, Apr 29, 2013 at 11:44 AM, emacstheviking
wrote: that list of IO actions; it is never used so it just gets garbage collected and the IO actions are never run.
-Brent
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners

But then \x y -> [x .. y] would have to have the type (Ord a, Enum a) => [a] whereas now it just has the Enum constraint. Either that or else the notation would work differently for literals vs. expressions but that would be just awful. -Brent On Mon, Apr 29, 2013 at 11:57:38AM -0400, David McBride wrote:
I think it is because that syntax is desugared directly to enumFromTo x y and enumFromTo 3 0 is []. Random things would probably blow up if you make that function work in reverse. But I would love it if ghc just checked whether the first was lower than the second and swapped them as a convenience.
On Mon, Apr 29, 2013 at 11:44 AM, emacstheviking
wrote: ROFLCOPTER indeed Batman!
I had no idea of that... I just *assumed* (usual rules apply I guess) that [3..0] was the "opposite" of [0..3] but sure enough a wuicj ghci session reveals the bitter truth!
Thanks again... i can see that it's not just me that is too lazy at times. I guess writing [3,2..0] will do for now but is that a bug or is there some other reasoning behind it?
We live and learn, well, I live anyway...
:)
On 29 April 2013 16:37, David McBride
wrote: One other gotcha. I don't know why it is this way, but [3..0] evaluates to []. I have no idea why reverse notation is not allowed. But you can just manually reverse it or you can go [3,2..0].
On Mon, Apr 29, 2013 at 11:26 AM, emacstheviking
wrote: damn that lazy evaluation! LMAO ...a good point brent and yuo have no doubt saved me hours of head scratching this evening when I try out the "new improved software". Oh dear oh dear oh dear...
doOption dev (Forward n) = do putStrLn $ "> STEP FORWARD " ++ (show n) stepBits dev ioPORTA [3..0]
doOption dev (Backward n) = do putStrLn $ "> STEP BACKWARD " ++ (show n) stepBits dev ioPORTA [0..3]
stepBits dev port = mapM_ stepIt where stepIt bit = mapM_ (\s -> HW.setPortBit dev port bit s >> stepDelay) [0,1]
I now have the above as my current "final" implementation... hopefully that *does* do what I think it does because mapM_ is driving it and will cause evaluation of the actions?
On 29 April 2013 15:56, Brent Yorgey
wrote: On Mon, Apr 29, 2013 at 02:59:29PM +0100, emacstheviking wrote:
I have built a library for using the Hexwax expandIO-USB chip and I have now got some code to drive a stepper motor:
doOption :: HWHandle -> Flag -> IO () doOption dev (Backward n) = do putStrLn $ "> STEP BACKWARD " ++ (show n) let x = [ stepBit b | b <- [3..0]] return () where stepBit p b = setBit p b 0 >> setBit p b 1 where setBit p b s = HW.setPortBit dev p b s >> stepDelay
The other posted solutions are good, but I also want to make a very important comment about the above code: it does not actually step any bits! All it does is print some stuff. x is simply a name for a list of IO actions; it is never used so it just gets garbage collected and the IO actions are never run.
-Brent
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners

Couldn't it just use fromEnum and compare the integers you get and
figure out which is bigger?
On Mon, Apr 29, 2013 at 2:17 PM, Brent Yorgey
But then \x y -> [x .. y] would have to have the type
(Ord a, Enum a) => [a]
whereas now it just has the Enum constraint. Either that or else the notation would work differently for literals vs. expressions but that would be just awful.
-Brent
On Mon, Apr 29, 2013 at 11:57:38AM -0400, David McBride wrote:
I think it is because that syntax is desugared directly to enumFromTo x y and enumFromTo 3 0 is []. Random things would probably blow up if you make that function work in reverse. But I would love it if ghc just checked whether the first was lower than the second and swapped them as a convenience.
On Mon, Apr 29, 2013 at 11:44 AM, emacstheviking
wrote: ROFLCOPTER indeed Batman!
I had no idea of that... I just *assumed* (usual rules apply I guess) that [3..0] was the "opposite" of [0..3] but sure enough a wuicj ghci session reveals the bitter truth!
Thanks again... i can see that it's not just me that is too lazy at times. I guess writing [3,2..0] will do for now but is that a bug or is there some other reasoning behind it?
We live and learn, well, I live anyway...
:)
On 29 April 2013 16:37, David McBride
wrote: One other gotcha. I don't know why it is this way, but [3..0] evaluates to []. I have no idea why reverse notation is not allowed. But you can just manually reverse it or you can go [3,2..0].
On Mon, Apr 29, 2013 at 11:26 AM, emacstheviking
wrote: damn that lazy evaluation! LMAO ...a good point brent and yuo have no doubt saved me hours of head scratching this evening when I try out the "new improved software". Oh dear oh dear oh dear...
doOption dev (Forward n) = do putStrLn $ "> STEP FORWARD " ++ (show n) stepBits dev ioPORTA [3..0]
doOption dev (Backward n) = do putStrLn $ "> STEP BACKWARD " ++ (show n) stepBits dev ioPORTA [0..3]
stepBits dev port = mapM_ stepIt where stepIt bit = mapM_ (\s -> HW.setPortBit dev port bit s >> stepDelay) [0,1]
I now have the above as my current "final" implementation... hopefully that *does* do what I think it does because mapM_ is driving it and will cause evaluation of the actions?
On 29 April 2013 15:56, Brent Yorgey
wrote: On Mon, Apr 29, 2013 at 02:59:29PM +0100, emacstheviking wrote: > I have built a library for using the Hexwax expandIO-USB chip and I > have > now got some code to drive a stepper motor: > > doOption :: HWHandle -> Flag -> IO () > doOption dev (Backward n) = do > putStrLn $ "> STEP BACKWARD " ++ (show n) > let x = [ stepBit b | b <- [3..0]] > return () > where > stepBit p b = setBit p b 0 >> setBit p b 1 > where setBit p b s = HW.setPortBit dev p b s >> stepDelay
The other posted solutions are good, but I also want to make a very important comment about the above code: it does not actually step any bits! All it does is print some stuff. x is simply a name for a list of IO actions; it is never used so it just gets garbage collected and the IO actions are never run.
-Brent
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners

Oh, yes, I suppose it could. In any case, I am still in favor of the existing semantics -- it is simple and consistent (and sometimes even useful). "Do what I mean"-style semantics with special cases end up generating more pain than they solve. -Brent On Mon, Apr 29, 2013 at 02:29:43PM -0400, David McBride wrote:
Couldn't it just use fromEnum and compare the integers you get and figure out which is bigger?
On Mon, Apr 29, 2013 at 2:17 PM, Brent Yorgey
wrote: But then \x y -> [x .. y] would have to have the type
(Ord a, Enum a) => [a]
whereas now it just has the Enum constraint. Either that or else the notation would work differently for literals vs. expressions but that would be just awful.
-Brent
On Mon, Apr 29, 2013 at 11:57:38AM -0400, David McBride wrote:
I think it is because that syntax is desugared directly to enumFromTo x y and enumFromTo 3 0 is []. Random things would probably blow up if you make that function work in reverse. But I would love it if ghc just checked whether the first was lower than the second and swapped them as a convenience.
On Mon, Apr 29, 2013 at 11:44 AM, emacstheviking
wrote: ROFLCOPTER indeed Batman!
I had no idea of that... I just *assumed* (usual rules apply I guess) that [3..0] was the "opposite" of [0..3] but sure enough a wuicj ghci session reveals the bitter truth!
Thanks again... i can see that it's not just me that is too lazy at times. I guess writing [3,2..0] will do for now but is that a bug or is there some other reasoning behind it?
We live and learn, well, I live anyway...
:)
On 29 April 2013 16:37, David McBride
wrote: One other gotcha. I don't know why it is this way, but [3..0] evaluates to []. I have no idea why reverse notation is not allowed. But you can just manually reverse it or you can go [3,2..0].
On Mon, Apr 29, 2013 at 11:26 AM, emacstheviking
wrote: damn that lazy evaluation! LMAO ...a good point brent and yuo have no doubt saved me hours of head scratching this evening when I try out the "new improved software". Oh dear oh dear oh dear...
doOption dev (Forward n) = do putStrLn $ "> STEP FORWARD " ++ (show n) stepBits dev ioPORTA [3..0]
doOption dev (Backward n) = do putStrLn $ "> STEP BACKWARD " ++ (show n) stepBits dev ioPORTA [0..3]
stepBits dev port = mapM_ stepIt where stepIt bit = mapM_ (\s -> HW.setPortBit dev port bit s >> stepDelay) [0,1]
I now have the above as my current "final" implementation... hopefully that *does* do what I think it does because mapM_ is driving it and will cause evaluation of the actions?
On 29 April 2013 15:56, Brent Yorgey
wrote: > > On Mon, Apr 29, 2013 at 02:59:29PM +0100, emacstheviking wrote: > > I have built a library for using the Hexwax expandIO-USB chip and I > > have > > now got some code to drive a stepper motor: > > > > doOption :: HWHandle -> Flag -> IO () > > doOption dev (Backward n) = do > > putStrLn $ "> STEP BACKWARD " ++ (show n) > > let x = [ stepBit b | b <- [3..0]] > > return () > > where > > stepBit p b = setBit p b 0 >> setBit p b 1 > > where setBit p b s = HW.setPortBit dev p b s >> stepDelay > > The other posted solutions are good, but I also want to make a very > important comment about the above code: it does not actually step any > bits! All it does is print some stuff. x is simply a name for a list > of IO actions; it is never used so it just gets garbage collected and > the IO actions are never run. > > -Brent > > _______________________________________________ > Beginners mailing list > Beginners@haskell.org > http://www.haskell.org/mailman/listinfo/beginners _______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners

@Brent: By reading your mails I got an idea... how about generating a compiler warning when someone types a literal like [5..2]. "Foo.hs:32: Warning: Literal list [5..2] evaluates to [] because 5 > 2 and the default step size is +1. Replace the literal with the empty list or with [5,4..2] to suppress this warning." That would be a really beginner-friendly warning. But I also think that we shouldn't catch this kind of mistake at runtime, because it may be the expected behavior in many cases. Michael Am 29.04.2013 um 23:54 schrieb Brent Yorgey:
Oh, yes, I suppose it could.
In any case, I am still in favor of the existing semantics -- it is simple and consistent (and sometimes even useful). "Do what I mean"-style semantics with special cases end up generating more pain than they solve.
-Brent
On Mon, Apr 29, 2013 at 02:29:43PM -0400, David McBride wrote:
Couldn't it just use fromEnum and compare the integers you get and figure out which is bigger?
On Mon, Apr 29, 2013 at 2:17 PM, Brent Yorgey
wrote: But then \x y -> [x .. y] would have to have the type
(Ord a, Enum a) => [a]
whereas now it just has the Enum constraint. Either that or else the notation would work differently for literals vs. expressions but that would be just awful.
-Brent

What about a new compiler flag to highlight all such potential gotchas?
--n00b
;)
Would help me out no end...
On 1 May 2013 11:35, Michael Peternell
@Brent: By reading your mails I got an idea...
how about generating a compiler warning when someone types a literal like [5..2].
"Foo.hs:32: Warning: Literal list [5..2] evaluates to [] because 5 > 2 and the default step size is +1. Replace the literal with the empty list or with [5,4..2] to suppress this warning."
That would be a really beginner-friendly warning.
But I also think that we shouldn't catch this kind of mistake at runtime, because it may be the expected behavior in many cases.
Michael
Am 29.04.2013 um 23:54 schrieb Brent Yorgey:
Oh, yes, I suppose it could.
In any case, I am still in favor of the existing semantics -- it is simple and consistent (and sometimes even useful). "Do what I mean"-style semantics with special cases end up generating more pain than they solve.
-Brent
On Mon, Apr 29, 2013 at 02:29:43PM -0400, David McBride wrote:
Couldn't it just use fromEnum and compare the integers you get and figure out which is bigger?
On Mon, Apr 29, 2013 at 2:17 PM, Brent Yorgey
wrote: But then \x y -> [x .. y] would have to have the type
(Ord a, Enum a) => [a]
whereas now it just has the Enum constraint. Either that or else the notation would work differently for literals vs. expressions but that would be just awful.
-Brent
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners

Ah, yes, a warning for literals like [5..2] sounds like an excellent idea. Why don't you file a feature request at http://hackage.haskell.org/trac/ghc/ ? -Brent On Wed, May 01, 2013 at 12:35:36PM +0200, Michael Peternell wrote:
@Brent: By reading your mails I got an idea...
how about generating a compiler warning when someone types a literal like [5..2].
"Foo.hs:32: Warning: Literal list [5..2] evaluates to [] because 5 > 2 and the default step size is +1. Replace the literal with the empty list or with [5,4..2] to suppress this warning."
That would be a really beginner-friendly warning.
But I also think that we shouldn't catch this kind of mistake at runtime, because it may be the expected behavior in many cases.
Michael
Am 29.04.2013 um 23:54 schrieb Brent Yorgey:
Oh, yes, I suppose it could.
In any case, I am still in favor of the existing semantics -- it is simple and consistent (and sometimes even useful). "Do what I mean"-style semantics with special cases end up generating more pain than they solve.
-Brent
On Mon, Apr 29, 2013 at 02:29:43PM -0400, David McBride wrote:
Couldn't it just use fromEnum and compare the integers you get and figure out which is bigger?
On Mon, Apr 29, 2013 at 2:17 PM, Brent Yorgey
wrote: But then \x y -> [x .. y] would have to have the type
(Ord a, Enum a) => [a]
whereas now it just has the Enum constraint. Either that or else the notation would work differently for literals vs. expressions but that would be just awful.
-Brent
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners

Just to note: This sounds like a special case of http://hackage.haskell.org/trac/ghc/ticket/7870 Cheers, Ozgur.

On Wed, May 01, 2013 at 07:18:36PM +0100, Ozgur Akgun wrote:
Just to note: This sounds like a special case of http://hackage.haskell.org/trac/ghc/ticket/7870
Well, perhaps if #7870 were implemented, one could easily add this warning message without changing CHG. But I think adding a warning for literal expressions like [5..2] is a good idea regardless. -Brent

Ok, I filed a feature request at http://hackage.haskell.org/trac/ghc/ticket/7881 -Michael Am 01.05.2013 um 13:33 schrieb Brent Yorgey:
Ah, yes, a warning for literals like [5..2] sounds like an excellent idea. Why don't you file a feature request at
http://hackage.haskell.org/trac/ghc/
?
-Brent
On Wed, May 01, 2013 at 12:35:36PM +0200, Michael Peternell wrote:
@Brent: By reading your mails I got an idea...
how about generating a compiler warning when someone types a literal like [5..2].
"Foo.hs:32: Warning: Literal list [5..2] evaluates to [] because 5 > 2 and the default step size is +1. Replace the literal with the empty list or with [5,4..2] to suppress this warning."
That would be a really beginner-friendly warning.
But I also think that we shouldn't catch this kind of mistake at runtime, because it may be the expected behavior in many cases.
Michael
Am 29.04.2013 um 23:54 schrieb Brent Yorgey:
Oh, yes, I suppose it could.
In any case, I am still in favor of the existing semantics -- it is simple and consistent (and sometimes even useful). "Do what I mean"-style semantics with special cases end up generating more pain than they solve.
-Brent
On Mon, Apr 29, 2013 at 02:29:43PM -0400, David McBride wrote:
Couldn't it just use fromEnum and compare the integers you get and figure out which is bigger?
On Mon, Apr 29, 2013 at 2:17 PM, Brent Yorgey
wrote: But then \x y -> [x .. y] would have to have the type
(Ord a, Enum a) => [a]
whereas now it just has the Enum constraint. Either that or else the notation would work differently for literals vs. expressions but that would be just awful.
-Brent
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
participants (7)
-
Benjamin Edwards
-
Brent Yorgey
-
David McBride
-
emacstheviking
-
Mateusz Kowalczyk
-
Michael Peternell
-
Ozgur Akgun