Let's say I have a list of twelve musical notes (which have their own data type), and I want a function that returns a list of notes starting with a given note and looping around.
data Note = C | CsDb | D | DsEb | E | F | FsGb | G | GsAb | A | AsBb | B deriving (Read, Eq, Ord, Enum, Bounded)
getNotes :: Note -> [Note]
getNotes root = take 12 $ doSomething root $ cycle noteList
where noteList :: [Note]
noteList = [minBound..maxBound]
such that
ghci> getNotes E
[E, F, FsGb, G, GsAb, A, AsBb, B, C, CsDb, D, DsEb]
I can think of a few sloppy ways to do this, but it feels like there should be an obvious, very Haskellian way. Any recommendations?
The smallest change you can make that works is to use dropWhile
:
getNotes :: Note -> [Note]
getNotes root = take 12 . dropWhile (/= root) . cycle $ [minBound .. maxBound]