我很难理解guard的工作原理。为什么要输入检查? mzero不能在m a处返回一些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可以是FloatDouble,但也可以是Int。编译器在类型检查期间选择所需的5解释。

类似地,在类型检查期间,编译器在原始示例中为mzero选择了正确的类型。更确切地说,它看到需要m (),因此选择该类型。

这里重要的一点是
mzero :: MonadPlus m => m a

实际上意味着
mzero :: forall m a . MonadPlus m => m a

它指出mzero的调用者可以选择ma的实际值(只要mMonadPlus)。因此,调用者可以选择a=()进行内容类型检查。用户可以通过类型注释做出选择,否则编译器将在类型检查期间尝试推断正确的选择。

10-08 12:37