
Hello all, in my program, I have to keep track of the State of a Guitar, i.e. where the fingers are on the fretboard and which strings are currently playing. Thus I need to associate some information to each of the 6 strings. I started out with assoc lists and hashmaps. However, I found it diffiult to ensure that all 6 GuitarString have a something attached and found myself messing with Maybes. In the real world, there is no way a GuitarString can have "no state at all", while the HashMap approach would provide this option. Then I thought, hey I really just need a function from GuitarString to something, so why not make that function the state? That was certainly doable, but I still have my doubts whether this is the correct way of doing such things. What is particularly worrying is that a state change will most likely affect a single GuitarString only. So I need to create a new function which answers the new something for that particular GuitarString and calls the old function for strings whose state hasn't changed. So with many state changes, I will get a deep call hierarchy. Though in the real world this is unlikely to cause problems, it makes me worry. What do you think?

Hi Martin, On Sun, Apr 06, 2014 at 03:20:14PM +0200, martin wrote:
I started out with assoc lists and hashmaps. However, I found it diffiult to ensure that all 6 GuitarString have a something attached and found myself messing with Maybes. In the real world, there is no way a GuitarString can have "no state at all", while the HashMap approach would provide this option.
I would start by designing the data structures that represent your possible states. That way you can also ensure that there can't be any non representable states. I really don't now what makes sense in your case, but something like: data StringState = Resting | Oscillating ... data Guitar = Guitar { string1 :: StringState , string2 :: StringState ... } If you have worked out the right data structures, then writing the surrounding code can become quite naturally. Greetings, Daniel

Am 04/06/2014 04:05 PM, schrieb Daniel Trstenjak:
data StringState = Resting | Oscillating ...
data Guitar = Guitar { string1 :: StringState , string2 :: StringState ... }
Yes this, and also the information on which fret the finger is. The problem with this approach is that I end up with two representations of GuitarString. One is the accessor functions above, but there is also a datatype GuitarString which I need to express things like "put your finger on the nth fret of the mth string". I found myself mapping between these two representations, which is not hard to do, but it impairs clarity.

On Sun, Apr 6, 2014, at 09:28 AM, martin wrote:
The problem with this approach is that I end up with two representations of GuitarString. One is the accessor functions above, but there is also a datatype GuitarString which I need to express things like "put your finger on the nth fret of the mth string".
You could try using an array: data StringIndex = S1 | S2 | S3 | S4 | S5 | S6 deriving (Eq, Ord, Enum, Bounded, Read, Show) type Guitar = Array StringIndex StringState http://hackage.haskell.org/package/array-0.5.0.0/docs/Data-Array.html The Enum and Bounded constraints on StringIndex let you do fun things like: allStrings = [minBound .. maxBound] -Karl

Am 04/06/2014 07:39 PM, schrieb Karl Voelker:
On Sun, Apr 6, 2014, at 09:28 AM, martin wrote:
The problem with this approach is that I end up with two representations of GuitarString. One is the accessor functions above, but there is also a datatype GuitarString which I need to express things like "put your finger on the nth fret of the mth string".
You could try using an array:
data StringIndex = S1 | S2 | S3 | S4 | S5 | S6 deriving (Eq, Ord, Enum, Bounded, Read, Show)
type Guitar = Array StringIndex StringState
http://hackage.haskell.org/package/array-0.5.0.0/docs/Data-Array.html
The Enum and Bounded constraints on StringIndex let you do fun things like:
allStrings = [minBound .. maxBound]
Thanks Karl, this tidies up my code quite a bit. BTW: I named the StringIndexes E6 | A | D | G | B | E1 which reflects the way a guitar is tuned. Way cool.

On Mon, Apr 7, 2014, at 12:00 PM, Kim-Ee Yeoh wrote: On Tue, Apr 8, 2014 at 1:43 AM, martin <[1]martin.drautzburg@web.de> wrote: BTW: I named the StringIndexes E6 | A | D | G | B | E1 which reflects the way a guitar is tuned. Way cool. Nice :) This n-tuple as Array trick is something I missed. Thanks, Karl. Do you know where it's been used? The last time I used this technique was when I needed to represent the state of a mancala board. I may have seen it done somewhere else, but I don't remember. -Karl References 1. mailto:martin.drautzburg@web.de
participants (4)
-
Daniel Trstenjak
-
Karl Voelker
-
Kim-Ee Yeoh
-
martin