来自OOP这对我来说似乎是外星代码.
我不明白为什么类型runIdentity
是一个函数:
runIdentity :: Identity a -> a
?我指定是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
Run Code Online (Sandbox Code Playgroud)
致电runIdentity
:
runIdentity $ wrapNsucc 5 - 输出6作为输出
Phi*_*ner 10
你是对的,这runIdentity
只是一个简单的类型领域a
.但类型的runIdentity
是Identity a -> a
,既然runIdentity
是一个函数,以提取出现场的Identity a
.runIdentity
毕竟,在没有提供值的情况下,你无法获得价值.
编辑:要在评论中稍微扩展一下OOP类比,请考虑一个类
class Identity<T> {
public T runIdentity;
}
Run Code Online (Sandbox Code Playgroud)
这是Identity
monad,松散地翻译成OOP代码.模板参数T
基本上是你的a
; 因此,runIdentity
属于类型T
.要从T
你的对象那里得到它,你可能会做类似的事情
Identity<int> foo = new Identity<int>();
int x = foo.runIdentity;
Run Code Online (Sandbox Code Playgroud)
你认为runIdentity
它是一种类型T
,但事实并非如此.你不能这样做
int x = runIdentity; // Nope!
Run Code Online (Sandbox Code Playgroud)
因为 - runIdentity
从哪里获得?相反,想到这就像做
Identity<int> foo = new Identity<int>();
int x = runIdentity(foo);
Run Code Online (Sandbox Code Playgroud)
这显示了当你打电话给会员时实际发生的事情; 你有一个函数(你的runIdentity
)并提供一个使用的对象 - IIRC这是Python的功能def func(self)
.因此T
,runIdentity
实际上不是明确的类型,而是Identity<T>
作为参数返回a T
.
因此,它的类型Identity a -> a
.