我已经在互联网上搜索了有关此关键字作用的实际解释。我看过的每个 Haskell 教程都是随机开始使用它的,从来没有解释过它的作用(我看过很多)。

这是来自 Real World Haskell 的一段基本代码,它使用 Just 。我明白代码的作用,但我不明白 Just 的目的或功能是什么。

lend amount balance = let reserve    = 100
                      newBalance = balance - amount
                  in if balance < reserve
                     then Nothing
                     else Just newBalance

根据我的观察,它与 Maybe 打字有关,但这几乎是我设法学习的全部内容。

非常感谢 Just 的含义的一个很好的解释。

最佳答案

它实际上只是一个普通的数据构造函数,恰好在 Prelude 中定义,它是自动导入每个模块的标准库。

也许是什么,结构上

定义看起来像这样:

data Maybe a = Just a
             | Nothing

该声明定义了一个类型 Maybe a ,它由类型变量 a 参数化,这意味着您可以将它与任何类型一起使用来代替 a

build 与破坏

该类型有两个构造函数, Just aNothing 。当一个类型有多个构造函数时,这意味着该类型的值必须只用一个可能的构造函数构造。对于这种类型,值是通过 JustNothing 构造的,没有其他(非错误)可能性。

由于 Nothing 没有参数类型,因此当它用作构造函数时,它会命名一个常量值,该值是 Maybe a 类型的成员,适用于所有类型 a 。但是 Just 构造函数确实有一个类型参数,这意味着当用作构造函数时,它的作用就像一个从类型 aMaybe a 的函数,即它的类型为 0x251134122

因此,一个类型的构造函数构建了一个该类型的值;事情的另一面是当您想使用该值时,这就是模式匹配发挥作用的地方。与函数不同,构造函数可用于模式绑定(bind)表达式,这是您可以对属于具有多个构造函数的类型的值进行大小写分析的方式。

为了在模式匹配中使用 a -> Maybe a 值,您需要为每个构造函数提供一个模式,如下所示:
case maybeVal of
    Nothing   -> "There is nothing!"
    Just val  -> "There is a value, and it is " ++ (show val)

在这种情况下,如果值为 Maybe a ,则第一个模式将匹配,如果该值是用 Nothing 构造的,则第二个模式将匹配。如果第二个匹配,它还会将名称 Just 绑定(bind)到在构造您要匹配的值时传递给 val 构造函数的参数。

可能意味着什么

也许您已经熟悉这是如何工作的; Just 值并没有什么神奇之处,它只是一个普通的 Haskell 代数数据类型 (ADT)。但是它被使用了很多,因为它有效地“提升”或扩展了一个类型,例如 Maybe 从你的例子中,到一个新的上下文中,它有一个额外的值( Integer )表示缺乏值(value)!然后类型系统要求您检查该额外值,然后才能获得可能存在的 Nothing。这可以防止大量错误。

今天许多语言通过 NULL 引用处理这种“无值”值。杰出的计算机科学家托尼·霍尔(Tony Hoare)(他发明了 Quicksort 并且是图灵奖获得者),将其命名为 "billion dollar mistake" 。也许类型不是解决这个问题的唯一方法,但它已被证明是一种有效的方法。

也许作为仿函数

将一种类型转换为另一种类型,以便对旧类型的操作也可以转换为对新类型进行操作的想法是 Haskell 类型类背后的概念,称为 Integer ,其中 Functor 有一个有用的实例。
Maybe a 提供了一个名为 Functor 的方法,该方法将范围从基本类型(例如 fmap )范围内的值的函数映射到范围从提升类型(例如 0x2311341 )范围内的值的函数。使用 Integer 转换为处理 Maybe Integer 值的函数的工作方式如下:
case maybeVal of
  Nothing  -> Nothing         -- there is nothing, so just return Nothing
  Just val -> Just (f val)    -- there is a value, so apply the function to it

所以,如果你有一个fmapMaybeMaybe Integer功能m_x,你可以做Int -> Int直接应用这些功能ffmap f m_x无需担心,如果它实际上有一个值与否。事实上,您可以将一整条提升的 f 函数链应用于 Maybe Integer 值,并且只需在完成后明确检查 Integer -> Integer 一次即可。

也许作为一个 Monad

我不确定你对 Maybe Integer 的概念有多熟悉,但你之前至少使用过 Nothing,并且类型签名 Monad 看起来非常类似于 0x251813141111尽管 IO a 的特殊之处在于它不会向您公开其构造函数,因此只能由 Haskell 运行时系统“运行”,但它仍然是 IO a 除了是 Maybe a 之外。事实上,有一个重要的意义,即 IO 只是 Functor 的一种特殊类型,具有一些额外的功能,但这不是进入的地方。

无论如何,像 Monad 这样的 Monad 将类型映射到表示“产生值的计算”的新类型,你可以通过一个非常类似于 Monad 的函数将函数提升为 Functor 类型,该函数称为 0x23138通过评估函数获得。”

您可能已经猜到(如果您已经阅读到这里) IO 也是 Monad 。它代表“可能无法返回值的计算”。就像 fmap 示例一样,这使您可以进行大量计算,而无需在每一步之后明确检查错误。事实上,按照 liftM 实例的构造方式,当遇到 Maybe 时,对 Monad 值的计算就会停止,所以它有点像立即中止或无值(value)的计算返回。

你可能写过

就像我之前说的,语言语法或运行时系统中没有任何固有的 fmap 类型。如果 Haskell 默认没有提供它,你可以自己提供它的所有功能!事实上,您无论如何都可以自己重新编写它,使用不同的名称,并获得相同的功能。

希望您现在了解 Monad 类型及其构造函数,但如果仍有不清楚的地方,请告诉我!

关于haskell - Haskell 中的 "Just"语法是什么意思?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/18808258/

10-13 03:21