我无法理解guard
的工作原理。为什么要打字检查?不能mzero
能够将某些m a
归还a /= ()
吗?
guard :: (MonadPlus m) => Bool -> m ()
guard True = return ()
guard False = mzero
mzero :: m a
答案 0 :(得分:11)
是的,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
的来电者可以选择m
和a
的实际值(只要m
是MonadPlus
)。因此,调用者可以选择a=()
来进行类型检查。用户可以通过类型注释进行此选择,否则编译器将尝试在类型检查期间推断正确的选择。