[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