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

K..*_*... 5 haskell maybe

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

calculate :: Float -> Float -> Maybe Float
Run Code Online (Sandbox Code Playgroud)

Wil*_*sem 13

Maybe a 是一种普通的数据类型,定义如下:

data Maybe a = Just a | Nothing
Run Code Online (Sandbox Code Playgroud)

因此有两种可能性:或者将类型的值定义aJust a(like Just 3),或者Nothing在查询没有答案的情况下.

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

例如:说你要定义sqrt.平方根仅为正整数定义sqrt,因此可以定义为:

sqrt x | x >= 0 = Just $ ...
       | otherwise = Nothing
Run Code Online (Sandbox Code Playgroud)

...一种方法来计算平方根x.

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

因此,用于Maybe表示可以不计算输出是有用的.您当然也可以在小于的值上出现错误0:

sqrt x | x >= 0 = Just $ ...
       | otherwise = error "The value must be larger or equal to 0"
Run Code Online (Sandbox Code Playgroud)

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

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

succMaybe :: Maybe Int -> Maybe Int
succMaybe (Just x) = Just (x+1)
succMaybe _ = Nothing
Run Code Online (Sandbox Code Playgroud)

但是通过写Just第一个案例,你以某种方式警告自己可能Nothing会发生.您还可以Maybe通过引入"默认"值来摆脱它:

justOrDefault :: a -> Maybe a -> a
justOrDefault _ (Just x) = x
justOrDefault d _ = d
Run Code Online (Sandbox Code Playgroud)

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

maybe :: b -> (a -> b) -> Maybe a -> b
maybe _ f (Just x) = f x
maybe z _ Nothing  = z
Run Code Online (Sandbox Code Playgroud)

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

使用Maybe a's'可能很难,因为你总是需要考虑这个Nothing案例,为了简化这个,你可以使用Maybe monad.


Tom Schrijvers还表明,它Maybe是类型代数中的后继函数:为类型添加一个额外的值(Either是一个加法,(,)是乘法的类型 - 代数等价物).