我在互联网上搜寻这个关键词的实际用途。我看过的每一篇Haskell教程都只是随机开始使用它,从来没有解释过它的功能(我看过很多)。
这是来自Real World Haskell的一段基本代码,它使用Just
。我明白代码的作用,但我不明白Just
的目的或功能是什么。
lend amount balance = let reserve = 100
newBalance = balance - amount
in if balance < reserve
then Nothing
else Just newBalance
据我观察,它与也许
打字有关,但这几乎是我所能学到的全部。
如果您能很好地解释一下的意思,我们将不胜感激。
给定类型t
,值Just t
是类型t
的现有值,其中无
表示未能达到某个值,或者表示具有某个值将毫无意义。
在您的示例中,负平衡是没有意义的,因此如果发生这种情况,它将被“无”所取代。
例如,这可以用于除法,定义一个除法函数,它取a
和b
,如果b
为非零,则只返回a/b
,否则返回Nothing
。它通常是这样使用的,作为异常的方便替代,或者像您前面的示例一样,用来替换没有意义的值。
目前的大多数答案都是对Just
和朋友如何工作的高度技术性解释;我想我可以试着解释它的用途。
很多语言都有一个值,比如null
,可以用来代替实际值,至少对于某些类型是这样。这让很多人非常愤怒,并被广泛认为是一个糟糕的举动。尽管如此,有时使用null
这样的值来表示缺少某个东西还是很有用的。
Haskell解决了这个问题,它让你显式地标记出你可以拥有Nothing
(其版本为null
)。基本上,如果函数通常返回类型Foo
,那么它应该返回类型,可能是Foo
。如果要指示没有值,请返回Nothing
。如果要返回一个值bar
,则应该只返回bar
。
所以基本上,如果你不能什么都没有,你不需要,只要
。如果你什么都没有,你只需要
。
也许没有什么神奇之处;它是建立在哈斯克尔式系统上的。这意味着您可以使用所有常用的Haskell模式匹配技巧。
它实际上只是一个普通的数据构造函数,恰好是在Prelude中定义的,它是自动导入到每个模块中的标准库。
定义如下所示:
data Maybe a = Just a
| Nothing
该声明定义了一个类型,可能是a
,它由一个类型变量a
参数化,这意味着您可以将它与任何类型一起使用来代替a
。
该类型有两个构造函数,只有一个
和没有
。当一个类型有多个构造函数时,这意味着该类型的一个值必须仅由一个可能的构造函数构造。对于这种类型,值要么通过Just
构造,要么通过Nothing
构造,没有其他(非错误)可能性。
由于没什么
没有参数类型,当它用作构造函数时,它会命名一个常量值,该值是类型的成员,对于所有类型
a
。但是Just
构造函数确实有一个类型参数,这意味着当用作构造函数时,它的行为就像一个从a
类型到也许是
的函数,即它具有a-类型
因此,一个类型的构造函数构建一个该类型的值;另一方面,当你想使用这个值时,模式匹配就发挥了作用。与函数不同,构造函数可以在模式绑定表达式中使用,这是对属于多个构造函数类型的值进行案例分析的方式。
为了在模式匹配中使用
值,您需要为每个构造函数提供一个模式,如下所示:
case maybeVal of
Nothing -> "There is nothing!"
Just val -> "There is a value, and it is " ++ (show val)
在这种情况下,如果值是
没什么
,则第一个模式将匹配,如果值是使用Just
构造的,则第二个模式将匹配。如果第二个匹配,它还将名称val
绑定到构造您匹配的值时传递给Just
构造函数的参数。
也许你已经熟悉了它的工作原理;
也许
值并没有什么魔力,它只是一种普通的哈斯克尔代数数据类型(ADT)。但它被大量使用,因为它有效地“提升”或扩展了一个类型,比如示例中的Integer
,进入一个新的上下文,在这个上下文中,它有一个额外的值(Nothing
),表示缺少值!然后,类型系统要求您在获取可能存在的整数之前检查该额外值。这可以防止大量的错误。
今天,许多语言通过NULL引用来处理这种“无值”值。著名的计算机科学家托尼·霍尔(Tony Hoare)承认这是他的“十亿美元错误”。也许类型不是解决这个问题的唯一方法,但它已被证明是一种有效的方法。
将一种类型转换为另一种类型,以便对旧类型的操作也可以转换为对新类型的操作,这是Haskell类型类背后的概念,称为
Functor
,它可能有一个
的有用实例。
Functor
提供了一个名为fmap
的方法,它将范围超过基本类型(例如Intger
)的值的函数映射到范围超过提升类型的值的函数(例如也许整数
)。使用fmap
转换以处理也许
值的函数如下所示:
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
所以如果你有一个
可能是整数
值
mux
和一个Int-
我不确定你对a
Monad
的概念有多熟悉,但至少你以前使用过ioa
,而且类型签名ioa
看起来非常类似于可能是a
。虽然IO
的特殊之处在于它不会向您公开其构造函数,因此只能由Haskell运行时系统“运行”,但除了作为单子
之外,它还是一个函子
。事实上,单子
只是一种特殊的函子
,有一些额外的特性,这是一个重要的意义,但这里不是讨论这个问题的地方。
无论如何,像
IO
这样的Monad会将类型映射为表示“计算结果值”的新类型,您可以通过一个名为liftM
的类似fmap
的函数将函数提升为Monad
类型,该函数将常规函数转化为“计算结果是通过计算函数得到的值”
您可能已经猜到(如果您已经读到这里)
也许
也是一个Monad
。它表示“可能无法返回值的计算”。就像fmap
示例一样,这让您可以进行一大堆计算,而无需在每一步后显式检查错误。事实上,Monad
实例的构造方式,对也许
值的计算会在遇到无
时立即停止,因此它有点像计算过程中的立即中止或无价值返回。
就像我之前说过的,在语言语法或运行时系统中烘焙的
也许
类型没有任何固有的东西。如果Haskell默认不提供它,您可以自己提供它的所有功能!事实上,无论如何,您都可以自己重新编写它,使用不同的名称,并获得相同的功能。
希望您现在能理解
类型及其构造函数,但是如果还有什么不清楚的地方,请告诉我!
问题内容: 我已经和Lombok一起使用并积极使用了2个月。使用Java时,我会更加熟悉。但是,我第一次遇到了该语言的以下语法结构: 这是什么意思,如何编译? 问题答案: 这是一种实验性的Lombok语法,其创建目的是在引用多个注释时支持间接层,而不是使用。 语法有点奇怪;要使用这3种功能中的任何一种,您必须在中包装要应用于构造函数/方法/参数的注释。要应用多个注释,请使用。注释本身显然也可以具有
问题内容: 我使用PHP已有很长时间了,但是我看到的类似, 确切地说,我在PHP Mongo页面中看到了这一点: 那么,该怎么办?这是相当难与谷歌或像字符PHP文件中进行搜索,和。 问题答案: (美元大括号)被称为 复杂(卷曲)语法 : 之所以称其为“复杂”,是因为语法复杂,而是因为它允许使用复杂的表达式。 可以通过此语法包括具有字符串表示形式的任何标量变量,数组元素或对象属性。只需以与出现在字符
问题内容: 我遇到了以下我不认识的Java语法。 这部分很好: 但是,我没有得到: 这是什么? 问题答案: 这提供了该类的内联(匿名)子类。 从功能上讲,它与: 和 但是由于该类定义不在方法主体之外使用,因此可以将其定义为匿名。
在以下代码示例中,来自颤振文档:
我在这个Config::INI Perl中找到了一个tilde 我正在处理的文本中没有波浪号。我知道很重要,因为省略、和中的任何或所有内容都会使语法与我的文本不再匹配。 因为我知道我匹配的模式是什么,所以我改变了它,使方括号位于文本表达式周围,因此: 所以在我看来,实际上是说在这里匹配一个方括号,然后期待最后一个括号。 无论如何,我知道在正常的Perl中 不管怎样,我在留档中搜索了语法和正则表达式
问题内容: 我正在寻找有关Google Go语言的信息。在“ A Go of Go”中,他们具有以下代码: 但是什么和 意味着什么呢? 您可以在http://tour.golang.org/#14上查看所有代码 问题答案: 它们是按位移位运算符。表示 x ×2 y ,而表示 x ×2 -y 或等效地x÷2 y。这些运算符通常用于操作值的二进制表示形式,就像十进制的10的幂一样,乘或除以2的幂分别具