了解haskell中的“可能”

时间:2017-03-25 15:29:04

标签: haskell types functional-programming maybe

所以说我们有一个函数sqrt的例子,它给我们一个浮点数的平方根,但不会在负输入上中止。那么sqrt的类型是什么。

我被告知答案是:

sqrt :: Maybe Float -> Float

然而我不明白Maybe会做什么,它只是意味着我们可以提供任何输入或者它意味着什么。

2 个答案:

答案 0 :(得分:6)

Maybe是一个具有简单定义的类型构造函数:

data Maybe a 
    = Just a  
    | Nothing

此语法读作“创建一个名为Maybe的新类型构造函数,它接受一个类型参数。它有两个值构造函数:Just,它采用类型为a的单个参数,或者Nothing“。

当我们编写接受Maybe参数的函数时,我们可以对其进行模式匹配以处理这两种情况。

foo :: Maybe String -> String
foo (Just str) = str
foo Nothing = "There was nothing!"

如果函数没有对所有输入有意义的定义,那么我们可以使用Maybe来表示。例如,Prelude中的sqrt会返回NaN的负值。我们可以编写一个返回Maybe的不同版本:

import qualified Prelude
import Prelude hiding (sqrt)

sqrt :: Float -> Maybe Float
sqrt x
    | x < 0     = Nothing
    | otherwise = Just (Prelude.sqrt x)  

我们可能会将这种类型读作“如果你给我一个浮点数,那么我可以返回浮点数。”

答案 1 :(得分:0)

我已经撤回了我的近距离投票,虽然对另一个问题的最佳答案或多或少地回答了这个问题,但这本身并不是一个骗局。

首先,让我们谈谈参数化类型。

如果我说(语言不可知)

Array<String>

我们有一个字符串数组。字符串数组["foo", "bar"] 的类型为 Array<String>。 'Array'本身并不是一个完整的类型*,我们有一个 的数组。换句话说,我们会使用类型Array参数化String

Maybe也是这样的,你有一个(在这种情况下)一个Maybe Float,可以是Just FloatNothing。现在,就像编译器不会让你将int列表传递给一个带有int的函数一样,它不允许你将Maybe T传递给一个类型为T的函数。您必须处理Nothing案例,类型系统会阻止忽略处理失败案例。所以你的sqrt函数应该有签名

sqrt :: Float -> Maybe Float

要反映这样一个事实:尽管你可以传入任何浮点数,但如果参数为负数,结果可能不存在。

*为了讨论的目的。