Reputation: 31
I'm new to Haskell and having trouble with the type system. I have the following function:
threshold price qty categorySize
| total < categorySize = "Total: " ++ total ++ " is low"
| total < categorySize*2 = "Total: " ++ total ++ " is medium"
| otherwise = "Total: " ++ total ++ " is high"
where total = price * qty
Haskell responds with:
No instance for (Num [Char])
arising from a use of `*'
Possible fix: add an instance declaration for (Num [Char])
In the expression: price * qty
In an equation for `total': total = price * qty
In an equation for `threshold':
... repeats function definition
I think the issue is that I need to somehow tell Haskell the type of total, and maybe associate it with the type class Show, but I don't know how to accomplish that. Thanks for any help.
Upvotes: 3
Views: 339
Reputation: 26117
The problem appears to be that you need to explicitly convert between strings and numbers. Haskell will not automatically coerce strings to numbers or vice versa.
To convert a number for display as a string, use show
.
To parse a string into a number, use read
. Since read
actually applies to many types, you may need to specify the type of the result, as in:
price :: Integer
price = read price_input_string
Upvotes: 3
Reputation: 3542
The problem is you define total
as the result of a multiplication, which forces it to be a Num a => a
and then you use it as an argument to ++
with strings, forcing it to be [Char]
.
You need to convert total
to a String
:
threshold price qty categorySize
| total < categorySize = "Total: " ++ totalStr ++ " is low"
| total < categorySize*2 = "Total: " ++ totalStr ++ " is medium"
| otherwise = "Total: " ++ totalStr ++ " is high"
where total = price * qty
totalStr = show total
Now, that will run, but the code looks a little repetitive. I would suggest something like this:
threshold price qty categorySize = "Total: " ++ show total ++ " is " ++ desc
where total = price * qty
desc | total < categorySize = "low"
| total < categorySize*2 = "medium"
| otherwise = "high"
Upvotes: 10