Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
空列表vs可能表示Haskell中失败的计算_Haskell_Maybe - Fatal编程技术网

空列表vs可能表示Haskell中失败的计算

空列表vs可能表示Haskell中失败的计算,haskell,maybe,Haskell,Maybe,在会议上,Erik Meijer反复声明,对于失败的计算,使用Maybe类型是不应该做的;相反,我们应该使用空列表 我的理解是,也许类型是一件好事,我们应该使用它。然而,一个列表似乎可以模拟一切,也许可以模拟更多。。。那么,我们为什么需要类型呢 然而,一个列表似乎可以模拟所有可能可以模拟的东西,甚至更多 “和更多”是使用可能的一个很好的理由。作为列表的使用者,您需要能够处理零、一个或多个值。作为的消费者,您只需要能够处理零或一个值。因此,在多个值没有意义的情况下,最好使用也许,以便静态地知道不会

在会议上,Erik Meijer反复声明,对于失败的计算,使用
Maybe
类型是不应该做的;相反,我们应该使用空列表

我的理解是,
也许
类型是一件好事,我们应该使用它。然而,一个列表似乎可以模拟一切,
也许可以模拟更多。。。那么,我们为什么需要
类型呢

然而,一个列表似乎可以模拟所有可能可以模拟的东西,甚至更多


“和更多”是使用
可能
的一个很好的理由。作为列表的使用者,您需要能够处理零、一个或多个值。作为
的消费者,您只需要能够处理零或一个值。因此,在多个值没有意义的情况下,最好使用
也许
,以便静态地知道不会得到无意义的值。

列表可以模拟任意数量的结果。另一方面,
可能只对一个结果建模,或者根本不建模

考虑以下功能:

f1 :: A -> [B]
f2 :: B -> [C]
f3 :: C -> [D]
f4 :: D -> [E]
不清楚返回的元素有多少。那么,如果你给它们排序,会发生什么呢

f  :: A -> [E]
f s = f1 s >>= f2 >>= f3 >>= f4
结果应该包含多少个元素?一个?零?我们是否意外地创建了一个包含n^n(n~输入长度)元素的列表

但是,如果计算只返回一个值或根本不返回任何值,则正确的类型会立即为我们提供所有必要的信息:

f1 :: A -> Maybe B
f2 :: B -> Maybe C
f3 :: C -> Maybe D
f4 :: D -> Maybe E

f  :: A -> Maybe E
f s = f1 s >>= f2 >>= f3 >>= f4
就这样。现在回到Meijer的声明:

Erik Meijer反复声明,对于失败的计算,使用Maybe类型是不应该做的;相反,我们应该使用空列表


没有任何额外的客观推理,这只是个人偏好。我可以告诉大家,
fmap
map
好,这是我们应该做的事情。在这一点上,你要么相信我,要么问问题。如果他在演讲中没有说清楚,直接问他。

另一个有价值的观点是,这只是错误处理单子的最简单的例子,可以用一种方便一致的方式来表示和组成“可破坏的”计算(另一个例子是或者纯粹的例外).列表单子在语义上是不同的(它表示非确定性计算),并且只有在空/单例情况下才具有类似的行为,如上所示。

支持列表:

  • 额外的值不是问题。当有多个结果时,客户端可以选择忽略列表的其余部分

  • 仅使用列表避免了在必须混合使用Maybe和list时在Maybe和list之间进行繁琐的转换。无需使用
    listToMaybe
    maybeToList

  • 只变成
    concat
    (或
    join

一个可能的问题是,对列表monad重复使用
(>>=)
,可能会创建非常大的列表。但是,Haskell很懒惰。如果我们只使用第一个元素,则不会计算列表的其余部分

>>> head (let xs = [1..1000000] in xs >>= \_ -> xs >>= \_ -> xs)
1

我想我会加入唱诗班,说我不能评价梅杰的建议,除非我得到他支持的所有细节。对我来说,这似乎很简单:

  • 对于返回0或1结果的函数,可以使用
  • 对于返回0或更多结果的函数,请使用
    []
  • 如果您需要在做出不同选择的函数之间进行混合和匹配,一个选项是使用类似于
    listToMaybe::[a]->maybeToList和
    maybeToList::maybeToList::maybeToList->[a]
    from这样的函数来调整以一种样式编写的函数,使其在另一种样式下工作
  • 如果您想延迟选择是否使用
    可能
    []
    ,您可以使用
    备选方案
    MonadPlus
  • 第4点示例:

    import Control.Applicative(纯,可选(…)
    safeDiv::(备选方案f,分数a,等式a)=>a->a->f a
    safeDiv_u0=空
    安全分区x y=纯(x/y)
    {-
    >>>safeDiv 5 2::可能是浮动的
    只有2.5
    >>>safeDiv 5 0::可能是浮动的
    没有什么
    >>>safeDiv 5 2::[浮动]
    [2.5]
    >>>safeDiv 5 0::[浮动]
    []
    -}
    bothSqrt::(备选方案f,浮动a)=>a->f a
    bothSqrt x=设x'=sqrt x
    纯x'纯(-x')
    {-
    >>>可能是浮动的
    只有2.236068
    >>>两个QRT 5::[浮动]
    [2.236068,-2.236068]
    >>>bothSqrt 5>>=翻转safeDiv 2::可能是浮动
    只有1.118034
    >>>>bothSqrt 5>>=翻转安全分区2::[Float]
    [1.118034,-1.118034]
    -}
    
    一个例子能说明千言万语。另外,你提到的课程的链接也很好。@Jubobs:可能:。@Zeta当然可以,但添加链接的责任在OP:)对于那些非常成功的计算,列表是一个很好的选择,它们返回多个值:-)这是一个我没有想到的好点。但是作为一些人e使用一个接受列表的函数,如果它丢掉了尾部,我想我会有点惊讶。例如,想象一下如果
    map
    被实现为
    map f[]=[];map f(x:xs)=[fx]
    import Control.Applicative (pure, Alternative(..))
    
    safeDiv :: (Alternative f, Fractional a, Eq a) => a -> a -> f a
    safeDiv _ 0 = empty
    safeDiv x y = pure (x / y)
    
    {-
    
    >>> safeDiv 5 2 :: Maybe Float
    Just 2.5
    
    >>> safeDiv 5 0 :: Maybe Float
    Nothing
    
    >>> safeDiv 5 2 :: [Float]
    [2.5]
    
    >>> safeDiv 5 0 :: [Float]
    []
    
    -}
    
    bothSqrt :: (Alternative f, Floating a) => a -> f a
    bothSqrt x = let x' = sqrt x
                 in pure x' <|> pure (-x')
    
    {-
    
    >>> bothSqrt 5 :: Maybe Float
    Just 2.236068
    
    >>> bothSqrt 5 :: [Float]
    [2.236068,-2.236068]
    
    >>> bothSqrt 5 >>= flip safeDiv 2 :: Maybe Float
    Just 1.118034
    
    >>>> bothSqrt 5 >>= flip safeDiv 2 :: [Float]
    [1.118034,-1.118034]
    
    -}