mzero如何匹配守卫类型签名?
How does mzero match guard type signature?
我无法理解 guard
的工作原理。为什么要进行类型检查?是不是 mzero
能够返回一些 m a
where a /= ()
?
guard :: (MonadPlus m) => Bool -> m ()
guard True = return ()
guard False = mzero
mzero :: m a
是的,mzero
能够返回一些 m a
,其中 a /= ()
。但它也能够返回 m ()
。 guard
在第二种情况下使用它。
类似这样:
n :: Int
n = 5
5
可以是 Float
或 Double
,但也可以是 Int
。编译器在类型检查期间选择 5
所需的解释。
类似地,编译器在类型检查期间为原始示例中的 mzero
选择了正确的类型。更准确地说,它看到需要 m ()
,所以它选择了那个类型。
这里重要的一点是
mzero :: MonadPlus m => m a
其实就是
mzero :: forall m a . MonadPlus m => m a
表示 mzero
的 caller 可以选择 m
和 a
的实际值(只要 m
是一个 MonadPlus
)。因此,调用者可以选择 a=()
来进行类型检查。这个选择可以由用户通过类型注释做出,否则编译器将在类型检查期间尝试推断正确的选择。
我无法理解 guard
的工作原理。为什么要进行类型检查?是不是 mzero
能够返回一些 m a
where a /= ()
?
guard :: (MonadPlus m) => Bool -> m ()
guard True = return ()
guard False = mzero
mzero :: m a
是的,mzero
能够返回一些 m a
,其中 a /= ()
。但它也能够返回 m ()
。 guard
在第二种情况下使用它。
类似这样:
n :: Int
n = 5
5
可以是 Float
或 Double
,但也可以是 Int
。编译器在类型检查期间选择 5
所需的解释。
类似地,编译器在类型检查期间为原始示例中的 mzero
选择了正确的类型。更准确地说,它看到需要 m ()
,所以它选择了那个类型。
这里重要的一点是
mzero :: MonadPlus m => m a
其实就是
mzero :: forall m a . MonadPlus m => m a
表示 mzero
的 caller 可以选择 m
和 a
的实际值(只要 m
是一个 MonadPlus
)。因此,调用者可以选择 a=()
来进行类型检查。这个选择可以由用户通过类型注释做出,否则编译器将在类型检查期间尝试推断正确的选择。