I wrote a little haskell program that just counts how many ones there are in a number (Int). When I try to execute it haskell complains about ambigous variable constraints.
I know that it comes from the use of floor. I also read some of the answers on stackoverflow. But I didn’t really find a way around that.
Here’s my code:
count_ones = count_ones' 0
count_ones' m 0 = m
count_ones' m n | n-10*n_new == 1 = count_ones' (m+1) n_new
| otherwise = count_ones' m n_new
where n_new = floor (n/10)
Any advice?
In the first line, you compare
n - 10*n_newto the fractional literal0.1, so the type ofnandn_newmust be a member of theFractionalclass.In the
whereclause, you bindn_new = floor (n/10), so the type ofn_newmust be a member of theIntegralclass.Since no standard type is a member of both classes (for good reasons), the compiler can’t resolve the constraint
when the function is called.
If you give type signatures to your functions, the compiler can often generate more helpful error messages.
The simplest fix for your problem is to change the binding of
n_newtoConsidering that in the comments you said that the
0.1was a mistake and you should have used1instead, you probably want to useIntegraltypes only and the closest transcription of your code would bebut it might be clearer to replace the condition
n - 10*n_new == 1withn `mod` 10 == 1.However, that would require two divisions per step, which probably is less efficient. Using
divModshould give you the quotient and remainder of the division with only one division instruction,and if you can guarantee that you will only call the function with non-negative
n, usequotandremresp.quotReminstead ofdivandmodresp.divMod. The former functions use the results of the machine division instruction directly, while the latter need some post-processing to ensure that the result ofmodis non-negative, soquotand friends are more efficient thandivand company.