Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

code review of birthday paradox, "no instance for" help

56 views
Skip to first unread message

jjared...@gmail.com

unread,
Sep 16, 2011, 9:30:54 PM9/16/11
to
Commenting out the definitions of birthdayparadox as well as test suppress all errors. I've tried to do add type annotations (Floating a) => a -> a, but truthfully I just want someone to point me in the right direction, because I know I'm just not able to read the error properly. I'm on day 2 Haskell learning so I just haven't absorbed enough of how Haskell infers types, or even the machinery of what types do. Thanks for any help.

https://gist.github.com/1223492

birthdayparadox.hs:3:17:
No instance for (Floating (a0 -> c0))
arising from a use of `logBase'
Possible fix: add an instance declaration for (Floating (a0 -> c0))
In the expression: logBase (1 - pShare) (1 - p)
In an equation for `uniquePairs':
uniquePairs p = logBase (1 - pShare) (1 - p)

birthdayparadox.hs:26:26:
No instance for (Num (a0 -> c0))
arising from the literal `1'
Possible fix: add an instance declaration for (Num (a0 -> c0))
In the second argument of `(-)', namely `1'
In the expression: 2 * x - 1
In the expression: \ x -> 2 * x - 1

birthdayparadox.hs:27:6:
No instance for (Ord (a0 -> c0))
arising from a use of `newtonRaphson'
Possible fix: add an instance declaration for (Ord (a0 -> c0))
In the expression: newtonRaphson f f' a0 1.0e-3
In the expression:
let
a0 = sqrt . uniquePairs p
f n = arcp n p
f' = \ x -> ...
in newtonRaphson f f' a0 1.0e-3
In an equation for `birthdayparadox':
birthdayparadox p
= let
a0 = sqrt . uniquePairs p
f n = arcp n p
....
in newtonRaphson f f' a0 1.0e-3

birthdayparadox.hs:29:24:
No instance for (Fractional (a0 -> c0))
arising from the literal `0.5'
Possible fix:
add an instance declaration for (Fractional (a0 -> c0))
In the first argument of `birthdayparadox', namely `0.5'
In the expression: birthdayparadox 0.5
In an equation for `test': test = birthdayparadox 0.5

Dirk Thierbach

unread,
Sep 17, 2011, 4:01:01 AM9/17/11
to
jjared...@gmail.com wrote:

> Commenting out the definitions of birthdayparadox as well as test suppress
> all errors. I've tried to do add type annotations (Floating a) => a -> a,
> but truthfully I just want someone to point me in the right direction,
> because I know I'm just not able to read the error properly.

"No instance for Floating (x -> y)" means that the compiler tries to
use a function type as some (floating point) number. That usually
means you've forgotten to apply an argument to a function somewhere,
you need to add parenthesis, or you made a typo.

> https://gist.github.com/1223492

The program is shorter than the error message, so why don't post it?

> pShare = 1 / 365
>
> uniquePairs p = logBase (1 - pShare) (1 - p)
> arcp n p = n^2 - n - uniquePairs p
>
> newtonRaphsonStep f f' ai = ai - f ai / f' ai
>
> newtonRaphson f f' ai epsilon =
> let ai' = newtonRaphsonStep f f' ai
> in if abs (ai' - ai) < epsilon then ai' else newtonRaphson f f' ai' epsilon
>
> birthdayparadox p =
> let a0 = sqrt . uniquePairs p
> f n = arcp n p
> f' = \x -> 2 * x - 1
> in newtonRaphson f f' a0 0.001
>
> test = birthdayparadox 0.5

I debugged this by commenting out the offending code, and then I used :t
in the toplevel to give my the types inferred by the compiler. Then I added
those in the source (which also means they serve as documentation for future
readers).

I got:

pShare :: Double
uniquePairs :: Double -> Double
arcp :: Double -> Double -> Double
newtonRaphson :: (Ord a, Fractional a) => (a -> a) -> (a -> a) -> a -> a -> a

So I can see that in birthdayparadox, a0 is supposed to be a Double (you
could specialize newtonRaphson to Double if you want, or keep it as it is
if you want to use it in other contexts, too).

However, (.) has a different binding priority than you think:

*Main> :t sqrt . uniquePairs 0.5
<interactive>:1:8:
Couldn't match expected type `a0 -> c0' with actual type `Double'
In the return type of a call of `uniquePairs'

Either add parenthesis:

*Main> :t (sqrt . uniquePairs) 0.5
(sqrt . uniquePairs) 0.5 :: Double

or use ($) instead:

*Main> :t sqrt $ uniquePairs 0.5
sqrt $ uniquePairs 0.5 :: Double

After that change, it compiles successfully.

HTH,

- Dirk

jjared...@gmail.com

unread,
Sep 17, 2011, 10:37:05 AM9/17/11
to Dirk Thierbach
Oooooooooooooooh!

Thanks so much. I kept seeing a0 -> c0, and I couldn't understand why it wasn't something like a0 -> b0. But it is because uniquePairs is a->b then sqrt is b->c.

Excellent, very helpful.
0 new messages