mzero如何匹配防护型签名?

sev*_*evo 2 monads haskell

我很难理解它是如何guard工作的.为什么要打字检查?是不是mzero能够回到m a哪里a /= ()

guard           :: (MonadPlus m) => Bool -> m ()
guard True      =  return ()
guard False     =  mzero

mzero :: m a 
Run Code Online (Sandbox Code Playgroud)

chi*_*chi 11

是的,mzero 能够返回的一些m a地方a /= ().但它也有能力回归m ().guard在第二种情况下使用它.

它与此类似:

n :: Int
n = 5
Run Code Online (Sandbox Code Playgroud)

5可以是FloatDouble,但也可以是Int.编译器5在类型检查期间选择所需的解释.

类似地,编译器mzero在类型检查期间在原始示例中选择正确的类型.更准确地说,它看到需要a m (),所以它选择那种类型.

这里重要的是

mzero :: MonadPlus m => m a
Run Code Online (Sandbox Code Playgroud)

实际意味着

mzero :: forall m a . MonadPlus m => m a
Run Code Online (Sandbox Code Playgroud)

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