什么是Maybe类型,它是如何工作的?

时间:2015-04-05 11:34:16

标签: haskell maybe

我刚刚开始在Haskell中编程,我遇到了以下定义:

calculate :: Float -> Float -> Maybe Float

1 个答案:

答案 0 :(得分:11)

Maybe a是一种普通数据类型,定义为:

data Maybe a = Just a | Nothing

因此有两种可能性:或者您将a类型的值定义为Just a(如Just 3),或Nothing,以防查询无法回答。

它被定义为定义非总函数的输出的方法。

例如:假设您要定义sqrt。平方根仅为正整数定义,因此您可以将sqrt定义为:

sqrt x | x >= 0 = Just $ ...
       | otherwise = Nothing

使用...计算x的平方根。

有些人将Nothing与大多数编程语言中的“空指针”进行比较。默认情况下,您没有为您定义的数据类型实现空指针(如果这样做,所有这些“空”看起来都不同),通过添加Nothing,您有一个通用的空指针。

因此,使用Maybe表示可以无法计算输出是有用的。您当然也可以在小于0的值上出错:

sqrt x | x >= 0 = Just $ ...
       | otherwise = error "The value must be larger or equal to 0"

但是类型签名中通常没有提到错误,如果不考虑它们,编译器也没有任何问题。 Haskell也转向函数:最好总是尝试为所有可能的输入返回一个值(例如Nothing)。

如果您以后想要使用Maybe a的结果,您需要写一下:

succMaybe :: Maybe Int -> Maybe Int
succMaybe (Just x) = Just (x+1)
succMaybe _ = Nothing

但是,通过为第一个案例编写Just,您会以某种方式警告自己可能会发生Nothing。您还可以通过引入“默认”值来删除Maybe

justOrDefault :: a -> Maybe a -> a
justOrDefault _ (Just x) = x
justOrDefault d _ = d

内置maybe函数(注意小写)结合了前两个函数:

maybe :: b -> (a -> b) -> Maybe a -> b
maybe _ f (Just x) = f x
maybe z _ Nothing  = z

所以你指定一个b(默认值)和一个函数(a -> b)。如果Maybe aJust x,则会将该函数应用于该函数并返回,如果输入值为Nothing,则将使用默认值。

使用Maybe a可能很难,因为您总是需要考虑Nothing案例,为了简化这一点,您可以使用Maybe monad


Tom Schrijvers 还表明Maybe是类型代数中的后继函数:您为类型添加了一个额外的值(Either是一个加法和{{1} }是乘法的类型 - 代数等价物。