我已经在网上搜索了这个关键字的实际解释.我看过的每个Haskell教程都是随机开始使用它,而不是解释它的作用(我看过很多).
这是Real World Haskell使用的基本代码Just.我理解代码的作用,但我不明白它的目的或功能Just是什么.
lend amount balance = let reserve = 100
newBalance = balance - amount
in if balance < reserve
then Nothing
else Just newBalance
Run Code Online (Sandbox Code Playgroud)
从我所观察到的,它与Maybe打字有关,但这几乎是我所学到的.
Just非常感谢对什么方法的一个很好的解释.
Lev*_*son 197
它实际上只是普通类型构造函数,恰好在Prelude中定义,Prelude是自动导入每个模块的标准库.
定义看起来像这样:
data Maybe a = Just a
| Nothing
Run Code Online (Sandbox Code Playgroud)
该声明定义了一个类型,Maybe a它由一个类型变量参数化a,这意味着你可以用任何类型代替它a.
该类型有两个构造函数,Just a和Nothing.当一个类型有多个构造函数时,这意味着必须仅使用一个可能的构造函数构造该类型的值.对于这种类型,值是通过Just或构造的Nothing,没有其他(非错误)可能性.
由于Nothing没有参数类型,当它用作构造函数时,它命名一个常量值,该值是Maybe a所有类型的类型成员a.但Just构造函数确实有一个类型参数,这意味着当用作构造函数时,它就像一个函数从类型a到Maybe a,即它具有类型a -> Maybe a
因此,类型的构造函数构建该类型的值; 事情的另一面是你想要使用那个值,那就是模式匹配的用武之地.与函数不同,构造函数可用于模式绑定表达式,这是您可以对属于具有多个构造函数的类型的值进行大小写分析的方法.
为了Maybe a在模式匹配中使用值,您需要为每个构造函数提供一个模式,如下所示:
case maybeVal of
Nothing -> "There is nothing!"
Just val -> "There is a value, and it is " ++ (show val)
Run Code Online (Sandbox Code Playgroud)
在该情况表达式中,如果值为,则第一个模式将匹配Nothing,如果使用该值构造,则第二个模式将匹配Just.如果第二个匹配,它还会将名称绑定val到在Just构造匹配的值时传递给构造函数的参数.
也许你已经熟悉它是如何工作的; 它没有真正的Maybe价值观,它只是一个普通的Haskell代数数据类型(ADT).但是它使用了很多,因为它有效地"提升"或扩展了一个类型,例如Integer从你的例子中扩展到一个新的上下文,在这个上下文中它有一个额外的值(Nothing)代表缺乏价值!那么该类型的系统要求您检查额外的价值之前,它会让你在Integer这可能是在那里.这可以防止大量的错误.
今天,许多语言通过NULL引用处理这种"无值"值.Tony Hoare是一位杰出的计算机科学家(他发明了Quicksort,并且是图灵奖获得者),他将此视为"十亿美元的错误".Maybe类型不是修复此问题的唯一方法,但事实证明它是一种有效的方法.
将一种类型转换为另一种类型的想法使得旧类型上的操作也可以转换为对新类型起作用是Haskell类型类背后的概念Functor,它Maybe a具有一个有用的实例.
Functor提供了一个名为的方法fmap,它将范围超出基本类型(例如Integer)的值的函数映射到范围超过提升类型(例如Maybe Integer)的值的函数.转换fmap为处理Maybe值的函数如下所示:
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
Run Code Online (Sandbox Code Playgroud)
因此,如果你有一个Maybe Integer值m_x和一个Int -> Int函数f,你可以直接fmap f m_x将函数应用f到它Maybe Integer而不用担心它是否真的有值.实际上,您可以将一整套提升Integer -> Integer函数应用于Maybe Integer值,并且只需要担心Nothing在完成时显式检查一次.
我不确定你对a的概念有多熟悉Monad,但你至少IO a在之前使用过,而且类型签名IO a看起来非常相似Maybe a.虽然IO它的特殊之处在于它不会向你展示它的构造函数,因此只能由Haskell运行时系统"运行",它仍然Functor是一个Monad.事实上,有一个重要的意义,即a Monad只是一种特殊的Functor有一些额外的功能,但这不是进入它的地方.
无论如何,Monads喜欢将IO地图类型表示为表示"产生值的计算"的新类型,并且您可以Monad通过一个非常类似fmap的函数将函数提升为类型,该函数 liftM将常规函数转换为"计算结果,通过评估得到的值功能."
你可能已经猜到了(如果你已经读过这篇文章)那Maybe也是一个Monad.它表示"可能无法返回值的计算".与fmap示例一样,这使您可以执行一大堆计算,而无需在每个步骤后显式检查错误.事实上,Monad构造实例的方式,一旦遇到a,Maybe值的计算就会停止Nothing,因此它有点像在计算过程中立即中止或无值返回.
就像我之前说的那样,Maybe语言语法或运行时系统中没有任何固有的类型.如果Haskell默认不提供它,您可以自己提供所有功能!实际上,无论如何,您可以自己再次编写它,使用不同的名称,并获得相同的功能.
希望您Maybe现在了解其类型及其构造函数,但如果仍有任何不清楚的地方,请告诉我们!
Bre*_*don 37
目前大多数答案都是关于如何Just和朋友工作的高度技术性解释; 我想我可以尝试解释它的用途.
许多语言具有类似的值null,可以使用而不是实际值,至少对于某些类型.这让很多人非常生气,被广泛认为是一个不好的举动.尽管如此,有时候有一个值null可以表明没有东西.
Haskell通过明确标记可以拥有Nothing(其版本为a null)的位置来解决此问题.基本上,如果你的函数通常会返回类型Foo,那么它应该返回类型Maybe Foo.如果您想表明没有价值,请返回Nothing.如果要返回值bar,则应返回Just bar.
所以基本上,如果你不能拥有Nothing,你就不需要了Just.如果你有Nothing,你需要Just.
没有什么神奇之处Maybe; 它建立在Haskell类型系统上.这意味着您可以使用所有常用的Haskell 模式匹配技巧.
qap*_*hla 13
给定一个类型t,值Just t是类型的现有值t,其中Nothing表示无法达到值,或者具有值无意义的情况.
在你的例子中,负平衡是没有意义的,所以如果发生这样的事情,它将被替换为Nothing.
再举一个例子,这可以用于除法,定义一个取a和的除法函数,如果非零则b返回,否则返回.它通常像这样使用,作为异常的替代方法,或者像前面的例子一样,替换没有意义的值.Just a/bbNothing