我目前正在和Hutton教授的"Haskell编程"一起学习Haskell,我发现了一些奇怪的关于Maybe的定义作为Applicative类的一个实例.
在GHC.Base,实例Applicative Maybe定义如下:
instance Applicative Maybe where
pure = Just
Just f <*> m = fmap f m
Nothing <*> _m = Nothing
Run Code Online (Sandbox Code Playgroud)
这是定义的值线Nothing <\*> _作为Nothing困扰我.Nothing是类型Maybe a,操作符<*>实际上需要f (a -> b)(在这种情况下Maybe (a -> b))作为其第一个参数的类型.因此,这是一种类型不匹配,Haskell应该抱怨.但是,这被接受为默认定义,因此Haskell不会在我认为应该的地方抱怨它.
我错过了什么?
我发现了Haskell的怪异特征,这使我相信我在错误地思考。我认为在Haskell中,应该有一些“不存在”的 monad。这是由于以下原因。
Prelude> return 1
1
Prelude> return 1 >>= \x -> if even x then return True else return False
False
Run Code Online (Sandbox Code Playgroud)
>>=是类型的m a -> (a -> m b) -> m b,其中m可以是任何单子。我的理论是这样的:由于return 1评估仅是1,return 1可以认为是1提升为包裹在“不存在”单子内部的值。Haskell抓住了这一事实并评估了整个表达式
return 1 >>= \x -> if even x then return True else return False
Run Code Online (Sandbox Code Playgroud)
到False,因为它必须产生一个“不存在False”,其仅是一个False。
但是,我以前从未听说过这种“不存在”的单子。
我确信我用错误的方式对其进行了理论化,因为如果“不存在1” …