The definition of the Bind
class in the Prelude is:
class Apply m <= Bind m where
bind :: forall a b. m a -> (a -> m b) -> m b
It can be read as a function taking two input parameters, a value in a monadic context (m a
) and a function (a -> m b
) and returning a value in a monadic context (m b
).
The instance of Bind
for partially-applied function is defined as:
instance bindFn :: Bind ((->) r) where
bind m f x = f (m x) x
Which is a function taking three parameters. How does that typecheck?
If I try to replace m a
by a more concrete type I get (correct me if I am wrong):
(((->) ??) a) -> (a -> (((->) ??) b)) -> (((->) ??) b)
which is equivalent to
(?? -> a) -> (a -> (?? -> b)) -> (?? -> b)
Assuming the variable m
is bound to (?? -> a
), f
would get bound to a -> ?? -> b
, and x
to the second ??
.
Is my reasoning correct?
To add to what swizard said (which is correct), one way to check what the type signature of a type class function is once it's been specialized to a particular instance is to write it out and see if psci agrees:
> :type bind :: forall r a b. (r -> a) -> (a -> r -> b) -> (r -> b)
forall r a b. (r -> a) -> (a -> r -> b) -> r -> b
So your reasoning is indeed correct. If we'd written out an incorrect type, we would have been given a type error:
> :type bind :: forall r. r -> r
Error found:
[...]
Could not match type [...] with [...]
[...]
Also, just in case you weren't already aware, the function type constructor ->
is right-associative, so a -> (r -> b)
is the same as a -> r -> b
.