守卫,'ma'对'm()'

aXq*_*Xqd 2 monads haskell

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

Prelude Control.Monad> :t mzero
mzero :: (MonadPlus m) => m a
Run Code Online (Sandbox Code Playgroud)

在False分支中guard,类型为mzerois m a,但返回类型guard已被指定为m ().因此我不太明白为什么编译器不会抱怨这个.

我的意思是如果mzero返回一个键入的值Maybe Int,当然,这是不同的Maybe (),对吗?

ken*_*ytm 6

编译器不会抱怨,因为它m a是一个超集m ().

  • 换句话说,`mzero`必须能够为_CALLER_选择的任何`a`返回`ma`.这是因为像"a"这样的"自由"类型变量具有隐含的"for all"a`",而在Java/C++传统中,类似"Object"的类型具有隐含的"存在某种类型`t`,是`Object`"的子类,它实际上是哪种类型是提供该对象的人的选择.多态性的默认"意义"在Haskell中与在更多"面向对象"语言中的相反. (7认同)