为什么我不能在 Haskell 中执行 `null (Just 5)`?

Why can't I do `null (Just 5)` in Haskell?

Maybe 的 Hackage 文档将 Foldable 列为 Maybe 的类型类之一。它还列出了以下函数:

null :: Maybe a -> Bool

它甚至链接到这个函数的实现(来自Foldable):

null :: t a -> Bool
null = foldr (\_ _ -> False) True

...这似乎很合理。它也有效:如果我 import qualified Data.Foldable,我可以对 Maybe 值使用 foldr

但是,当我尝试在 Maybe 上调用 null 时,Haskell 认为我想使用为列表设计的 null:

Prelude> :t null
null :: [a] -> Bool
Prelude> null Nothing
<interactive>:3:6:
    Couldn't match expected type `[a0]' with actual type `Maybe a1'
    In the first argument of `null', namely `Nothing'
    In the expression: null Nothing
    In an equation for `it': it = null Nothing

我知道有 isJust,我只是想知道如何为任何 Foldable 调用像 null 这样的函数。

有多个函数称为 null。您在 ghci 中获得的那个来自 Prelude,它是 null :: [a] -> Bool。发生这种情况的原因是 Prelude 中的所有内容都是隐式导入的。

要得到正确的,您需要 import Data.Foldable (Foldable(null))*,而要防止错误的歧义,您需要 import Prelude hiding (null)。像这样显式地重新导入 Prelude 可以防止否则会发生的隐式导入。

*或import Data.Foldable (Foldable(..))获取Foldable的所有方法。

事实证明,我是 运行 旧版本的 GHC(我的 OS 的默认版本),而文档是针对最新版本的(当然)。

至少在 GHC 7.10.2 中,您从 Prelude 中得到的 null 无需导入任何东西即可支持 Foldables(如 Maybe):

GHCi, version 7.10.2: http://www.haskell.org/ghc/  :? for help
Prelude> :t null
null :: Foldable t => t a -> Bool