Coming from OOP this seems like alien code to me.
I don't understand why type of runIdentity is a function :
runIdentity :: Identity a -> a ? I specified to be runIdentity :: a
newtype Identity a = Identity {runIdentity :: a} deriving Show
instance Monad Identity where
return = Identity
Identity x >>= k = k x
instance Functor Identity where
fmap f (Identity x) = Identity (f x)
instance Applicative Identity where
pure = Identity
Identity f <*> Identity v = Identity (f v)
wrapNsucc :: Integer -> Identity Integer
wrapNsucc = Identity . succ
Calling runIdentity :
runIdentity $ wrapNsucc 5 -- gives 6 as output
You're right that runIdentity is but a simple field of type a. But the type of runIdentity is Identity a -> a, since runIdentity is a function to extract that field out of a Identity a. You can't get the runIdentity out of a value without supplying which value to get it from, after all.
Edit: To expand a little on that OOP-analogy in the comments, think of a class
class Identity<T> {
public T runIdentity;
}
This is the Identity monad, loosely translated to OOP code. The template argument T basically is your a; as such, runIdentity is of type T. To get that T from your object, you'd probably do something like
Identity<int> foo = new Identity<int>();
int x = foo.runIdentity;
You see runIdentity as something of type T, but it's not really. You can't just do
int x = runIdentity; // Nope!
because - where to get the runIdentity from? Instead, think of this like doing
Identity<int> foo = new Identity<int>();
int x = runIdentity(foo);
This shows what actually happens when you're calling a member; you have a function (your runIdentity) and supply it an object to use - IIRC this is what Python does with def func(self). So instead of being plainly of type T, runIdentity is actually taking an Identity<T> as argument to return a T.
Thus, it's of type Identity a -> a.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With