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