snippetModerate
Using Fibonacci sequence to generate musical melodies
Viewed 0 times
melodiesmusicalfibonaccisequencegenerateusing
Problem
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:
I'm just running ghci and asking it to return
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 -> 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
outputSolution
fibofibo 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.divBy7divBy7 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.calcNumscalcNums 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.returnNotereturnNote 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.
Code Snippets
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)"Context
StackExchange Code Review Q#129843, answer score: 11
Revisions (0)
No revisions yet.