Haskell如何在MaybeT实现中推断出正确的类型类?

时间:2014-07-20 15:38:20

标签: haskell types monads type-inference monad-transformers

Haskell如何知道每个return表达式的哪个是正确的monad实例?

newtype MaybeT m a = MaybeT { runMaybeT :: m (Maybe a) }

instance Monad m => Monad (MaybeT m) where
    return  = MaybeT . return . return

2 个答案:

答案 0 :(得分:4)

它推断出所需的类型。

instance定义的含义可以清楚地看出,我们正试图定义

returnMaybeT :: Monad m => a -> MaybeT m a
returnMaybeT x = MaybeT (return (return x))

MaybeT :: m (Maybe a) -> MaybeT a(作为函数)我们知道return的内部堆栈必须具有类型

return (return x) :: Monad m => a -> m (Maybe a)

现在,我们知道return是一个多态函数,其类型为

return :: a -> n a

任何 Monad n。对于第一个returnMonad m =>约束告诉我们mMonad,因此我们可以使用其返回定义。这让我们可以一直到内部return

return x :: a -> Maybe a

由于我们知道Maybe有一个Monad个实例,我们可以使用return


最终,所有编译器必须做的就是试图确定每个return所需的类型。确定所需类型后,必须检查它是否知道该类型的Monad实例。这对于Maybe来说很简单,因为它是具体的,但m更难看,因为它只是一个变量。

m的作用原因是因为我们已将变量约束为某些类型,该类型实例化Monad

答案 1 :(得分:4)

这实际上与上下文无关。

让我们玩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 }。