manipulating Map for music application

I have a Haskell program that computes music compositions. A composition consists of sounds that happen at locations. A location is data type Loc. At each location is a list of chords. A chord is data type Chord. Each chord contains some chord-specific data and a list of notes. A note is data type Note. So we have data Note = Note ... data Chord = Chord ChordSpecificData [Note] type Composition = Map Loc [Chord] I would like to write a few different functions that operate over all the notes. The following function breaks out all the notes, tupling them with the associated Locs and Chords: compositionToList :: Composition -> [(Loc,Chord,Note)] The following function transforms Notes, keeping only the Just results. If a Chord gets all its notes eliminated, that Chord is removed. If a Loc has all its Chords removed, that Loc is removed from the Map. mapNotesMaybe :: (Loc -> Chord -> Note -> Maybe Note) -> Composition -> Composition Any advice for concise code appreciated. Dennis What's a concise way of doing this? Another useful function would be used for mapping Dennis

This is a bit tricky but mapMaybeWithKey is clearly the tool for the job :
mapMaybeWithKey :: (k -> a -> Maybe https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Maybe.html#t:Mayb... b) -> Map https://hackage.haskell.org/package/containers-0.5.6.3/docs/Data-Map-Lazy.ht... k a -> Map https://hackage.haskell.org/package/containers-0.5.6.3/docs/Data-Map-Lazy.ht... k b
So :
mapNotesMaybe :: (Loc -> Chord -> Note -> Maybe Note) -> Composition ->
Composition
mapNotesMaybe f compo = mapMaybeWithKey go compo
where
go loc chords = mconcat . map (gogo loc) $ chords
gogo loc chord = mconcat . map (fmap pure . f loc chord) $ chord
This should work.
--
Chaddaï
Le sam. 7 nov. 2015 à 07:07, Dennis Raddle
I have a Haskell program that computes music compositions. A composition consists of sounds that happen at locations. A location is data type Loc. At each location is a list of chords. A chord is data type Chord. Each chord contains some chord-specific data and a list of notes. A note is data type Note.
So we have
data Note = Note ... data Chord = Chord ChordSpecificData [Note] type Composition = Map Loc [Chord]
I would like to write a few different functions that operate over all the notes.
The following function breaks out all the notes, tupling them with the associated Locs and Chords: compositionToList :: Composition -> [(Loc,Chord,Note)]
The following function transforms Notes, keeping only the Just results. If a Chord gets all its notes eliminated, that Chord is removed. If a Loc has all its Chords removed, that Loc is removed from the Map. mapNotesMaybe :: (Loc -> Chord -> Note -> Maybe Note) -> Composition -> Composition
Any advice for concise code appreciated. Dennis
What's a concise way of doing this?
Another useful function would be used for mapping
Dennis
_______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners

Ooops forgot that Chords are not just lists of Notes :
mapNotesMaybe f compo = mapMaybeWithKey go compo
where
go loc chords = mconcat . map (fmap (:[]) . gogo loc) $ chords
gogo loc chord@(Chord d notes) = fmap (Chord d) . mconcat . map (fmap
(:[]) . f loc chord) $ notes
Le sam. 7 nov. 2015 à 18:41, Chaddaï Fouché
This is a bit tricky but mapMaybeWithKey is clearly the tool for the job :
mapMaybeWithKey :: (k -> a -> Maybe https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Maybe.html#t:Mayb... b) -> Map https://hackage.haskell.org/package/containers-0.5.6.3/docs/Data-Map-Lazy.ht... k a -> Map https://hackage.haskell.org/package/containers-0.5.6.3/docs/Data-Map-Lazy.ht... k b
So :
mapNotesMaybe :: (Loc -> Chord -> Note -> Maybe Note) -> Composition -> Composition mapNotesMaybe f compo = mapMaybeWithKey go compo where go loc chords = mconcat . map (gogo loc) $ chords gogo loc chord = mconcat . map (fmap pure . f loc chord) $ chord
This should work.
-- Chaddaï
Le sam. 7 nov. 2015 à 07:07, Dennis Raddle
a écrit : I have a Haskell program that computes music compositions. A composition consists of sounds that happen at locations. A location is data type Loc. At each location is a list of chords. A chord is data type Chord. Each chord contains some chord-specific data and a list of notes. A note is data type Note.
So we have
data Note = Note ... data Chord = Chord ChordSpecificData [Note] type Composition = Map Loc [Chord]
I would like to write a few different functions that operate over all the notes.
The following function breaks out all the notes, tupling them with the associated Locs and Chords: compositionToList :: Composition -> [(Loc,Chord,Note)]
The following function transforms Notes, keeping only the Just results. If a Chord gets all its notes eliminated, that Chord is removed. If a Loc has all its Chords removed, that Loc is removed from the Map. mapNotesMaybe :: (Loc -> Chord -> Note -> Maybe Note) -> Composition -> Composition
Any advice for concise code appreciated. Dennis
What's a concise way of doing this?
Another useful function would be used for mapping
Dennis
_______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners

Thanks! I'm a Haskell beginner and will relish the opportunity to learn
more by studying your code.
On Sat, Nov 7, 2015 at 9:47 AM, Chaddaï Fouché
Ooops forgot that Chords are not just lists of Notes :
mapNotesMaybe f compo = mapMaybeWithKey go compo where go loc chords = mconcat . map (fmap (:[]) . gogo loc) $ chords gogo loc chord@(Chord d notes) = fmap (Chord d) . mconcat . map (fmap (:[]) . f loc chord) $ notes
Le sam. 7 nov. 2015 à 18:41, Chaddaï Fouché
a écrit : This is a bit tricky but mapMaybeWithKey is clearly the tool for the job :
mapMaybeWithKey :: (k -> a -> Maybe https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Maybe.html#t:Mayb... b) -> Map https://hackage.haskell.org/package/containers-0.5.6.3/docs/Data-Map-Lazy.ht... k a -> Map https://hackage.haskell.org/package/containers-0.5.6.3/docs/Data-Map-Lazy.ht... k b
So :
mapNotesMaybe :: (Loc -> Chord -> Note -> Maybe Note) -> Composition -> Composition mapNotesMaybe f compo = mapMaybeWithKey go compo where go loc chords = mconcat . map (gogo loc) $ chords gogo loc chord = mconcat . map (fmap pure . f loc chord) $ chord
This should work.
-- Chaddaï
Le sam. 7 nov. 2015 à 07:07, Dennis Raddle
a écrit : I have a Haskell program that computes music compositions. A composition consists of sounds that happen at locations. A location is data type Loc. At each location is a list of chords. A chord is data type Chord. Each chord contains some chord-specific data and a list of notes. A note is data type Note.
So we have
data Note = Note ... data Chord = Chord ChordSpecificData [Note] type Composition = Map Loc [Chord]
I would like to write a few different functions that operate over all the notes.
The following function breaks out all the notes, tupling them with the associated Locs and Chords: compositionToList :: Composition -> [(Loc,Chord,Note)]
The following function transforms Notes, keeping only the Just results. If a Chord gets all its notes eliminated, that Chord is removed. If a Loc has all its Chords removed, that Loc is removed from the Map. mapNotesMaybe :: (Loc -> Chord -> Note -> Maybe Note) -> Composition -> Composition
Any advice for concise code appreciated. Dennis
What's a concise way of doing this?
Another useful function would be used for mapping
Dennis
_______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
_______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
participants (2)
-
Chaddaï Fouché
-
Dennis Raddle