I've decided that I should get to learn more about Haskell, because (from what
totherme,
michiexile and Duncan say) it sounds like it's got much cooler since I last touched it. So today I sat down to write a program to generate valid Siteswaps for juggling patterns. A siteswap is a list of throw heights: "5" means that you throw a ball sufficiently high that the
(
Read more... )
Comments 18
-- newtype SiteSwap = SS [Int] deriving (Show, Read, Eq, Ord)
-- this just turned out to be a hassle
That's because, of the 3 ways in haskell to declare new data types, you've picked the wrong one :)
The three ways are: ["data", "type", "newtype"]
data actually creates a new data structure, using the sort of syntax you were aiming for there. Like "data Tree x = Leaf x | Branch (Tree x, Tree x)" etc...
This is great if you're doing something genuinely new, but there, you weren't. You actually just wanted a list of Ints, but you wanted to refer to them as something else. For that, we have type synonyms. To make your programme do what you want, add the line:
type SiteSwap = [Int]
And do a s/[Int]/SiteSwap/ over the rest of the code. I just tried it in my copy - it works. (there's no need for all the deriving stuff there - the new type has all the properties of the old one, including the ones you were trying to derive)
As for newtype - I believe it does something useful, but I've not yet sat down and read what ;)
Reply
http://www.cs.auckland.ac.nz/references/haskell/haskell-intro-html/moretypes.html
All of this works using a data declaration instead of a newtype declaration. However, the data declaration incurs extra overhead...
So, I feel justified in not bothering about them for the most part ;)
Reply
To clarify, I'm not (yet) criticizing Haskell's type system, just my own understanding of it. Things are improving: I'm starting to remember some of the common pitfalls and avoiding them.
Reply
To clarify, I'm not (yet) criticizing Haskell's type system
Good, good ;)
Just thinking about that though - it might be worth, when you get what appears to be a spurious type error, taking a copy of the code that produced the error, hiding it, and getting on with your debugging. Then, when you have a working programme, see if the code actually meant what you were thinking at the time - or if real runtime bugs were caught.
Of course, that would have been fairly pointless in this case, since a bug in constructing a type is genuinely one you can avoid by not having types ;)
Reply
There's only one style point I think I noticed while I was playing, and that's the advance function. Do you really need it? It seems to me that all it does is aggregate one common argument of two distinct 2-arg functions. You could probably do:
where newfalling = advanceFalling s falling
newfallen = advanceFallen falling fallen
...instead. I dunno - doing without advance saves about 1 line in this particular file - if you were using it somewhere else too, the saving would go the other way. Meh :)
As for the rest, it's just knowing what libraries are out there :)
Take a look at Data.List - it contains the function inits, which allows you to refactor prefixes into prefixes = drop 1 . inits - which is pretty cool. It also contains findIndices, which allows us to render prefixes and isRepeated obsolete by redefining:
isRepetitive [] = False ( ... )
Reply
cyclicPerms xs = take n $ map (take n) $ iterate tail $ cycle xs
where n = length xs
(from memory)
Unfortunately, this wasn't as serious as the other bug I found - most of the patterns generated aren't actually juggleable! I think my test needs to be made stricter, but I'm not quite sure how :-(
Reply
Ideally, with an explaination as to why they're not juggleable ;)
Reply
I'm guessing that the pattern 4100 isn't juggleable, since:
Since hands alternate, odd-numbered throws send the ball to the other hand, while even-numbered throws send the ball to the same hand.
So, in the pattern 4100, starting with the left, the left hand would always be throwing to itself, and the right hand would always be throwing to the left. So where do the balls come from? And since twice as many balls land in the left as are thrown by it, where do they go?
In my copy of the programme, 4100 passes the isJuggleable test - because it only checks for colisions, not resourcing.
I suppose that might be fixable by crossing your arms at appropriate points to even out the resourcing, but at that stage, my grip on the rules of our model get shakey ;)
Reply
Reply
Reply
Reply
Reply
Leave a comment