Haskell中isNothing和(== Nothing)之间的区别?

tin*_*lyx 10 haskell maybe

我很困惑为什么下面涉及的两个函数Nothing是不同的:

coalesce  m1 m2 = if  isNothing m1 then m2 else m1

coalesce' m1 m2 = if  (m1 == Nothing) then m2 else m1
Run Code Online (Sandbox Code Playgroud)

第一个有类型:

?> :t coalesce
coalesce :: Maybe a -> Maybe a -> Maybe a
Run Code Online (Sandbox Code Playgroud)

正如所料.但第二个有:

?> :t coalesce'
coalesce' :: Eq a => Maybe a -> Maybe a -> Maybe a
Run Code Online (Sandbox Code Playgroud)

为什么使用(==Nothing)引入Eq a约束?

(GHC 8.2.2)

Ry-*_*Ry- 14

==是一个功能Eq a => a -> a -> Bool.你正在制作它的一个操作数Nothing,所以aMaybe b某种类型的b,但这种Eq a限制仍然适用 - Maybe b必须有一个Eq实例.Maybe b包括这样一个实例的定义Eq (Maybe b)- 为所有人Eq b.

换句话说,==它只是一个函数而且它并不提前知道你提供Nothing的参数.它只知道它是一些 Maybe a,它需要能够比较相等,如果碰巧是一个Just ….

换句话说,这里是你如何定义==已经存在的Maybes:

equals a b = case a of
    Nothing -> isNothing b
    Just x -> case b of
        Nothing -> False
        Just y -> x == y
Run Code Online (Sandbox Code Playgroud)

注意如何x == y出现,这意味着必须有一个Eq类型为x和的实例y.


mel*_*ene 6

因为类型==

(==) :: (Eq a) => a -> a -> Bool
Run Code Online (Sandbox Code Playgroud)

你的第二个定义(coalesce')使用==,所以它从Eq它的参数继承约束==.


严格来说,coalesce'使用==类型的值Maybe a,但有一个实例

instance (Eq a) => Eq (Maybe a) where ...
Run Code Online (Sandbox Code Playgroud)

所以Eq (Maybe a)约束变为Eq a,因为那是什么需要支持==Maybe a.