[英]How does Haskell infer correct type classes in MaybeT implementation?
Haskell如何知道每个return
表达式的哪个是正确的monad实例?
newtype MaybeT m a = MaybeT { runMaybeT :: m (Maybe a) }
instance Monad m => Monad (MaybeT m) where
return = MaybeT . return . return
它推断出所需的类型。
从我们试图定义的instance
定义的含义可以清楚地看出
returnMaybeT :: Monad m => a -> MaybeT m a
returnMaybeT x = MaybeT (return (return x))
由于MaybeT :: m (Maybe a) -> MaybeT a
(作为函数),我们知道return
s的内部堆栈必须具有类型
return (return x) :: Monad m => a -> m (Maybe a)
现在,我们知道return
是一个多态函数,它有类似的类型
return :: a -> n a
任何 Monad
n
。 在第一次return
的情况下, Monad m =>
约束告诉我们m
是Monad
,因此我们可以使用它的return定义。 这让我们可以一直到内部return
return x :: a -> Maybe a
因为我们知道Maybe
有一个Monad
实例,所以我们可以使用它的return
。
最终,所有编译器必须做的就是试图确定每次return
所需的类型。 在确定所需类型后,它必须检查它是否知道该类型的Monad
实例。 这是简单的Maybe
,因为它是具体的,而多了几分难以看到的m
,因为它只是一个变量。
m
工作原因是因为我们已经将变量约束为某种实例化Monad
类型。
它实际上与上下文无关。
让我们玩typechecker,
-- From the signature
MaybeT . return . return :: a -> MaybeT a
-- From the type of MaybeT
return . return :: a -> m (Maybe a)
-- From the type of `.`
(return :: Maybe a -> m a) . (return :: a -> Maybe a)
一旦我们得到每个return
的类型,“实例选择算法”将正确选择第一个使用m
s return
,第二个选择为Maybe
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.