
Michael Mossey wrote:
I want to write a function that converts the first way of organizing the information into the second. I tried writing types like
type Chord = ... type Time = Double type Name = String
type TimedChord = (Time,Chord) type Staff = [(Time,Chord)] type NamedStaff = (Name,Staff) type NamedChord = (Name,Chord) type Vertical = [NamedChord] type TimedVertical = (Time,Vertical)
The function I want is
convert :: [NamedStaff] -> [TimedVertical]
As you can imagine, this is a confusing mess, with all these variants on named and timed things. I thought it might help to create functors called Named and Timed, which might help abstracting operations on named and timed things. For example,
datatype Named a = Named { namedName :: Name, namedData :: a }
instance Functor Named = name a :: Name name a = namedName a x `fmap` f = Named { namedName = namedName x, namedData = f $ namedData x }
Any other suggestions?
Functors sounds good to me. data Named a = N Name a data Timed a = T Time a instance Functor Named where ... instance Functor Timed where ... convert :: Named [Timed Chord] -> Timed [Named Chord] But you can also use plain type synonyms type Named a = (Name,a) type Timed a = (Time,a) and write your own record selectors by hand name :: Named a -> Name name = fst time :: Timed a -> Time time = fst value :: (b,a) -> a value = snd Regards, apfelmus -- http://apfelmus.nfshost.com