Reputation: 33
I have a task that requires implementing a looped version of FizzBuzz utilizing command line arguments, comparing 2 divisors to a number, printing Fizz if upBound is divisible by div1, Buzz if upBound is divisible by div2 and the upBound if it isn't divisible by either. I've constructed the function and am able to use that independent of the main function, but in order to compile, I obviously need the main function, which I've tried implementing below
module Main( main ) where
import System.Environment
fizzBuzz div1 div2 upBound = do if (upBound - 1) > 1
then fizzBuzz div1 div2 (upBound - 1)
else print "";
if mod (upBound - 1) div1 > 0 && mod (upBound - 1) div2 > 0
then print (upBound - 1)
else
print ((if mod (upBound - 1) div1 == 0 then "Fizz" else []) ++ (if mod (upBound - 1) div2 == 0 then "Buzz" else []))
main = do
[div1,div2,upBound] <- getArgs
fizzBuzz div1 div2 upBound
I've scoured every tutorial and help site I can find and I just don't know enough about Haskell and it's syntax to determine exactly what is wrong. Currently I get the following error when attempting to compile:
"fizzbuzz.hs:14:9: No instance for (Integral String) arising from a use of 'fizzBuzz'"
My expected output for an example is something like
fizzbuzz 2 4 6
is
1
Fizz
3
FizzBuzz
5
Fizz
Unfortunately I can't seem to locate the right help resources to figure out how to fix the issue and am hoping someone can point me in the right direction.
Thank you in advance.
Upvotes: 0
Views: 444
Reputation: 4984
When you get stuck like this, it's best to look at the types involved:
The fizzBuzz function takes 3 numbers and returns an IO () action
The getArgs function has type getArgs :: IO [String]
This means that in main
, div1
has type String
; div2
has type String
; and upBound
has type String
. You are passing them directly to fizzBuzz
, but recall it is expecting numeric arguments! This is why you get the error about (Integral String)
; because numeric arguments can be any one of a class of types, it's telling you it can't find evidence of String
being a member of the numeric class it's expecting.
You need to somehow interpret the strings from your command line into numbers. The easiest way to do this is the read
method, which has type Read a => String -> a
. This means that if the type you would like to parse from the string is a member of the "readable" class of types, it can take a String
and give you an instance of that type.
Upvotes: 1