Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell中isNothing和(=Nothing)之间的区别?_Haskell_Maybe - Fatal编程技术网

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

Haskell中isNothing和(=Nothing)之间的区别?,haskell,maybe,Haskell,Maybe,我不明白为什么下面两个不涉及任何内容的函数是不同的: coalesce m1 m2 = if isNothing m1 then m2 else m1 coalesce' m1 m2 = if (m1 == Nothing) then m2 else m1 第一种类型为: λ> :t coalesce coalesce :: Maybe a -> Maybe a -> Maybe a 正如所料。但第二个问题是: λ> :t coalesce' coalesce

我不明白为什么下面两个不涉及任何内容的函数是不同的:

coalesce  m1 m2 = if  isNothing m1 then m2 else m1

coalesce' m1 m2 = if  (m1 == Nothing) then m2 else m1
第一种类型为:

λ> :t coalesce
coalesce :: Maybe a -> Maybe a -> Maybe a
正如所料。但第二个问题是:

λ> :t coalesce'
coalesce' :: Eq a => Maybe a -> Maybe a -> Maybe a
为什么使用
(==Nothing)
会引入
Eq a
约束


(GHC 8.2.2)

因为
=
的类型是

(==) :: (Eq a) => a -> a -> Bool
第二个定义(
coalesce'
)使用
=
,因此它继承了
=
对其参数的
Eq
约束


严格来说,
coalesce'
对类型为
的值使用
=
,可能是a
,但有一个实例

instance (Eq a) => Eq (Maybe a) where ...

因此,
Eq(可能是a)
约束变成了
Eq a
,因为这是在
上支持
=
所需要的,可能a
=
是一个函数
Eq a=>a->Bool
。您正在使它的一个操作数
Nothing
,因此
a
对于某些类型
b
可能b
,但是
Eq a
限制仍然适用–
可能b
必须有一个
Eq
实例
Maybe b
包括这样一个实例的定义–
Eq(Maybe b)
–用于所有
Eq b

换句话说,
==
只是一个函数,它事先不知道您正在提供
什么也不提供
作为参数。它只知道它是某个
可能是一个
,如果它恰好是一个
只是…
,它需要能够比较相等

换句话说,这里是如何定义已经存在于
==
,可能是
的:

equals a b = case a of
    Nothing -> isNothing b
    Just x -> case b of
        Nothing -> False
        Just y -> x == y

注意
x==y
是如何出现的,这意味着
x
y
类型必须有一个
Eq
实例,让我们首先设计一个
(==)
函数覆盖
值。通常,如果两个事物具有相同的数据构造函数,并且参数都是相等的,则我们认为两个事物是相同的。因此,我们考虑<代码> f x1 x2 x3和<代码> g y1 y2 y3 < /c> >相同,如果<代码> f>代码>和<代码> g>代码>是相同的数据构造函数,并且<代码> x1==y1 ,<代码> x2==y2< /代码>,和<代码> x3==y3 < /p>
因此,如果我们为
Maybe
实现这一点,则有两种情况是相等的:两个
Nothing
s和两个
Just
s,其中
Just
s封装的值相同,因此:

instance Eq a => Eq (Maybe a) where
    (==) Nothing Nothing = True
    (==) (Just x) (Just y) = x == y
    (==) _ _ = False
是实现
Eq
实例的最合乎逻辑的方法,例如
可能是a
。在实现中,我们使用
x==y
,因此我们添加了
Eq a
类型约束

现在Haskell将函数概念上看作是黑盒。对于
Maybe
,它因此将
(==)
视为
(==)::Eq a=>Maybe a->Maybe a->Bool
。如果因此使用此
(==)
函数,则无论特定用途是否需要此类型约束来执行
x==y
检查,它都将始终需要类型约束
Eq a
。如果您编写
(==Nothing)
,那么我们会看到,第二个子句(
(==)(仅x)(仅y)
)将永远不会被使用,但是由于Haskell将函数视为黑盒,因此不知道在什么情况下类型约束是相关的

仅检查值是否为
Nothing
,如果它是
Just
,则它始终为
False
,无论
Just
构造函数包装的值是什么,它的实现方式如下:

isNothing :: Maybe a -> Bool
isNothing Nothing = True
isNothing _ = False
因此,我们不需要这里的
Eq a
类型约束:我们不检查元素
的相等性,只检查
构造函数的换行。同样,如果我们使用它,Haskell只检查类型签名,注意到不涉及
Eq a
类型约束,因此不会将其添加到使用该函数的函数中

请注意,您在此处实现的实际上已经在
控件.Applicative
模块中实现,例如:

Prelude> import Control.Applicative
Prelude Control.Applicative> (<|>) Nothing Nothing
Nothing
Prelude Control.Applicative> (<|>) Nothing (Just 3)
Just 3
Prelude Control.Applicative> (<|>) (Just 3) Nothing
Just 3
Prelude Control.Applicative> (<|>) (Just 3) (Just 2)
Just 3
Prelude>导入控制。应用程序
前奏曲控件。应用>()无
没有什么
前奏曲控件。应用>()无(仅3)
只有3个
前奏曲控件。应用程序>()(仅3)无
只有3个
前奏曲控件.Applicative>()(仅3)(仅2)
只有3个

可能值得明确指出的是,这种差异是非常重要的:有些东西(通常是函数)不能有
Eq
实例。所以
coalesce
可以很好地处理这些问题,但是
coalesce'
不行。