Using Fibonacci sequence to generate musical melodies I recently started picking up the Haskell programming language. I've managed to learn other languages rather quickly, but I'm still having a difficult time grasping some of the basics of Haskell.

I decided to practice and wrote a program that calculates the Fibonacci Sequence (original, I know) a certain amount of times and adds the results to a list, then divides each number in the list by 7 and creates a new list of the remainders of that division. It then assigns a musical note letter based in A minor (A, B, C, D, E, F, and G), and prints out each letter. The idea was to give me new ideas for writing melodies.

The program works, but with how efficient Haskell is I feel like it's way too long for what it does. How would you guys suggest re-writing this and what are some shortcuts I can use to write better code?

Here's the program:

import Data.List
import System.IO

fibo a b = a:fibo b (a+b)
divBy7 x = x `mod` 7
calcNums = take 16 $ map divBy7(fibo 0 1)
returnNote :: Int -&gt; String
returnNote n
  | (n == 0) = "A"
  | (n == 1) = "B"
  | (n == 2) = "C"
  | (n == 3) = "D"
  | (n == 4) = "E"
  | (n == 5) = "F"
  | (n == 6) = "G"
-- the number will never be higher than 6 due to the pisano period

output = map returnNote(calcNums)


I'm just running ghci and asking it to return output
fibo

fibo is a fine function, but I would suggest a more complete name like fibonacci just to make it 100% clear that it returns fibonacci numbers to someone that did not read your plaintext introduction.

divBy7

divBy7 is not a good function: it is trivial and most importantly does not do what it says. It returns the remainder of dividing by 7, not the result of dividing by 7. I would delete this function.

calcNums

calcNums is not general enough, I feel no need for the take 16 at the start of it, this function has the potential to calculate as many fibonacci mod 7 as you want, let the caller decide how many to take.

Incidentally fibonacciMod7 is a better name for the function as it says what it does: calcNums was way too general.

returnNote

returnNote is too verbose and fails badly (= with no meaningful error message) if I pass it anything bigger than 6.

returnNote n 
  | n `elem` [0..6] = "ABCDEFG" !! n
  | otherwise = error "n will never be higher than 6 due to the pisano period. (And it must be positive)"


This implementation is more concise and incorporates the comment into the code so that it can be shown to the user when he uses the function incorrectly.