I'm having a bit of trouble with my types lining up in this code:
distance :: (Floating a) => (a, a) -> (a, a) -> a
distance (x1, y1) (x2, y2) = sqrt $ (x2 - x1)**2 + (y2 - y1)**2
gravitation :: (Num a, Floating a) => (a,a) -> (a,a) -> a
gravitation = ((**) (-1.0)) . ((**) 2.0) . distance
I was under the impression that since distance returns a Floating variables, I could pipe it into the ((**) 2.0). Is there a fix for this whilst keeping the code relatively elegant?
The error I get is:
Main.hs:13:16:
Could not deduce (Floating ((a, a) -> a))
arising from a use of `**'
from the context (Num a, Floating a)
bound by the type signature for
gravitation :: (Num a, Floating a) => (a, a) -> (a, a) -> a
at Main.hs:12:16-57
Possible fix:
add an instance declaration for (Floating ((a, a) -> a))
In the first argument of `(.)', namely `((**) (- 1.0))'
In the expression: ((**) (- 1.0)) . ((**) 2.0) . distance
In an equation for `gravitation':
(.)really only works to compose functions of one (remaining) argument; you can do tricks to get more but it gets more complex. - luqui(a,a) -> ainto((**) 2.0)instead of my desired double? - Tombert:t ((**) 2.0) . distancein GHCi, it'll derive a type for you, but it'll be nonsensical withFloating ((a, a) -> a)as a constraint. Try:t (. distance), the type it'll return will be all sorts of crazy. Then try:t \x -> ((**) 2.0) . distance x, the type will now make sense and look like you want it to. - bheklilrf x = h $ g xtof = h . g, but you can't reducef x y = h $ g x ytof x = h . g xtof = h . g, since in the second example you reduce the$to.with theyparameter. That's essentially what's happening here, and why a new combinator is needed. - bheklilr