[Haskell-beginners] data constructors
Daniel Fischer
daniel.is.fischer at web.de
Sun Apr 19 20:52:48 EDT 2009
Am Montag 20 April 2009 02:10:42 schrieb Michael Mossey:
> Some additional thoughts:
>
> Here is something I'm struggling with. Let's say a piece of music is
> several staves filled with chords. Staves have names. Each chord in a staff
> has a time.
>
> In informal notation:
>
> staff "fred": (time 1.0, chord 1), (time 1.5, chord 2), (time 2.0, chord
> 3) staff "bob" : (time 1.0, chord 4), (time 2.0,
> chord 5)
>
> When laying out music, I need to find "verticals", which are chords located
> on different staves which happen to coincide in time. For instance, the
> above has three verticals:
>
> time 1.0: ("fred", chord 1), ("bob", chord 4)
> time 1.5: ("fred", chord 2)
> time 2.0: ("fred", chord 3), ("bob", chord 5)
>
> 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]
What about
import Data.Function (on)
import Data.List
convert namedStaffs = map timeVertical verticals
where
nameTimedChords (name,tcs) = [(time,name,chord) | (time, chord) <- tcs]
timedNamedChords = sort . foldr merge [] . map nameTimedChords $ namedStaffs
fst3 (x,_,_) = x
verticals = groupBy ((==) `on` fst3) timedNamedChords
timeVertical v@((t,_,_):_) = (t,[(name,chord) | (_,name,chord) <- v])
?
>
> 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?
> Thanks,
> Mike
>
More information about the Beginners
mailing list