Question about functors (or maybe not...)

Hi, I'm writing a music library and have the following types and functions: data Note = C | D | E | F | G | A | B | Sharp Note | Flat Note raise C = Sharp C data Quality = Major | Minor data Chord = Chord Quality Note -- Note is the root data Scale = Scale Quality Note -- Note is the tonic What I would like to do is to be able to lift the raise function and apply it to Chords and Scales. Something like this: fmap raise (Chord Major C) = Chord Major (Sharp C) But these are not functors as it doesn't seem to make sense for them to be polymorphic. A chord can't really made of anything except Notes. Does anybody have any ideas? Patrick -- ===================== Patrick LeBoutillier Rosemère, Québec, Canada

On Sat, Mar 19, 2011 at 2:00 AM, Patrick LeBoutillier
Hi,
I'm writing a music library and have the following types and functions:
data Note = C | D | E | F | G | A | B | Sharp Note | Flat Note raise C = Sharp C
data Quality = Major | Minor
data Chord = Chord Quality Note -- Note is the root data Scale = Scale Quality Note -- Note is the tonic
What I would like to do is to be able to lift the raise function and apply it to Chords and Scales. Something like this:
fmap raise (Chord Major C) = Chord Major (Sharp C)
But these are not functors as it doesn't seem to make sense for them to be polymorphic. A chord can't really made of anything except Notes.
You can write your own plain old functions: mapChord :: (Note -> Note) -> Chord -> Chord mapChord f (Chord q n) = Chord q (f n) mapScale :: (Note -> Note) -> Scale -> Scale mapScale f (Scale q n) = Scale q (f n) You can also create your own type class, if that's convenient for you class NoteMap a where noteMap :: (Note -> Note) -> a -> a instance NoteMap Chord where noteMap = mapChord instance NoteMap Scale where noteMap = mapScale HTH, =) -- Felipe.

Hi Patrick, You probably have already looked at http://www.haskell.org/haskellwiki/Haskore Regards, Kashyap

Felipe,
You can write your own plain old functions:
mapChord :: (Note -> Note) -> Chord -> Chord mapChord f (Chord q n) = Chord q (f n)
mapScale :: (Note -> Note) -> Scale -> Scale mapScale f (Scale q n) = Scale q (f n)
You can also create your own type class, if that's convenient for you
class NoteMap a where noteMap :: (Note -> Note) -> a -> a
instance NoteMap Chord where noteMap = mapChord instance NoteMap Scale where noteMap = mapScale
Initially I didn't realize how powerful this approach could be, but once you have noteMap then most of the functions for altering Notes can then be used on the other types, *without* having to make them (the functions I mean) be part of the typeclass definition. This seems obvious but I hadn't really noticed it until now... Thanks a lot, Patrick
HTH, =)
-- Felipe.
-- ===================== Patrick LeBoutillier Rosemère, Québec, Canada
participants (3)
-
C K Kashyap
-
Felipe Almeida Lessa
-
Patrick LeBoutillier