Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.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
Haskell 在foldr和foldl'中实施或使用;在数据列表中_Haskell - Fatal编程技术网

Haskell 在foldr和foldl'中实施或使用;在数据列表中

Haskell 在foldr和foldl'中实施或使用;在数据列表中,haskell,Haskell,以下是Prelude中或函数的声明 or = foldr (||) False 如果列表字段至少包含一个True 如果列表包含所有False,则可能发生溢出,我们必须减少到最后一个元素 下面是使用foldl的实现 or = foldl' (||) False 尽管在这里它效率很低,因为它必须减少到列表的最后一个元素,而不管list参数的内容如何。但我们保证不会遇到溢流 所以问题是为什么不使用更安全的foldl'版本 如果列表包含所有False,那么[…]我们必须减少到最后一个元素 这是正确的

以下是Prelude中
函数的声明

or = foldr (||) False
如果列表字段至少包含一个
True
如果列表包含所有
False
,则可能发生溢出,我们必须减少到最后一个元素

下面是使用foldl的实现

or = foldl' (||) False
尽管在这里它效率很低,因为它必须减少到列表的最后一个元素,而不管list参数的内容如何。但我们保证不会遇到溢流

所以问题是为什么不使用更安全的
foldl'
版本

如果列表包含所有
False
,那么[…]我们必须减少到最后一个元素

这是正确的

如果列表包含所有
False
,则可能发生溢出[…]

那不是。除了像
(+)
这样的函数外,
(| |)
在两个参数中都不严格。它仅与左侧的模式匹配:

(||) :: Bool -> Bool -> Bool
(||) True _ = True
(||) _    x = x
因此,如果我们对列表使用
foldr
的定义,我们得到:

foldr (||) False [False,False])
  = False || (foldr (||) False [False]) -- use: False || x = x
  = foldr (||) False [False]
  = False || (foldr (||) False [])      -- use: False || x = x
  = foldr (||) False []
  = False
但是,如果我们使用一个函数,其中两个参数都需要完全求值,那么我们就会遇到问题:

foldr (+) 0 [1,2]
  = 0 + (foldr (+) 1 [2])  -- cannot reduce (+), since it needs right hand side
  = 0 + (1 + (foldr (+) 2 []))
  = 0 + (1 + (2))
  = 0 + (3)
  = 3
这就是为什么在本例中应该使用
foldl'
。但是对于像
(| |)
(:)
这样的右惰性函数,
foldr
是非常好的

如果列表包含所有
False
,那么[…]我们必须减少到最后一个元素

这是正确的

如果列表包含所有
False
,则可能发生溢出[…]

那不是。除了像
(+)
这样的函数外,
(| |)
在两个参数中都不严格。它仅与左侧的模式匹配:

(||) :: Bool -> Bool -> Bool
(||) True _ = True
(||) _    x = x
因此,如果我们对列表使用
foldr
的定义,我们得到:

foldr (||) False [False,False])
  = False || (foldr (||) False [False]) -- use: False || x = x
  = foldr (||) False [False]
  = False || (foldr (||) False [])      -- use: False || x = x
  = foldr (||) False []
  = False
但是,如果我们使用一个函数,其中两个参数都需要完全求值,那么我们就会遇到问题:

foldr (+) 0 [1,2]
  = 0 + (foldr (+) 1 [2])  -- cannot reduce (+), since it needs right hand side
  = 0 + (1 + (foldr (+) 2 []))
  = 0 + (1 + (2))
  = 0 + (3)
  = 3

这就是为什么在本例中应该使用
foldl'
。但是对于像
(| |)
(:)
这样的正确的惰性函数,
foldr
非常好。

您所说的“溢出可能发生”是什么意思。是否应该或应该遍历整个列表以查看是否有任何内容为真?如果list参数包含all
False
,则需要遍历整个列表以进行检查。我错了吗?@utdemir说得对,你必须检查它直到最后一个元素,如果所有的previus元素都是False@user634615,是的,否则你永远不会知道最后一个元素是true@user634615:不,关于遍历,您是正确的。但是
(| |)
的参数并不严格,比如说
(+)
,你可能会遇到问题。因此,堆栈溢出不会发生在
中。您所说的“溢出可能发生”是什么意思。是否应该或应该遍历整个列表以查看是否有任何内容为真?如果list参数包含all
False
,则需要遍历整个列表以进行检查。我错了吗?@utdemir说得对,你必须检查它直到最后一个元素,如果所有的previus元素都是False@user634615,是的,否则你永远不会知道最后一个元素是true@user634615:不,关于遍历,您是正确的。但是
(| |)
的参数并不严格,比如说
(+)
,你可能会遇到问题。因此,堆栈溢出不会在
中发生。明白了。我没有注意(| |)
foldr strictOr
在常量空间中运行的定义(没有“溢出”)<可以通过模式匹配或简单地
\x y->x`seq`y`seq`x | | y
来定义code>strictOr
。也许这里正在进行一些超级特殊的优化,但我认为此属性是由于
foldr
本身造成的。@user2407038:IIRC,GHC不使用上述
foldr
实现,而是基于构建器的实现。也就是说,
foldr strictOr
在GHCi中对大型列表(如
replicate(10^9)False
)进行解释时失败。我不确定优化规则(也就是可能的建设者)是否能解决这个问题。明白了。我没有注意(| |)
foldr strictOr
在常量空间中运行的定义(没有“溢出”)<可以通过模式匹配或简单地
\x y->x`seq`y`seq`x | | y
来定义code>strictOr
。也许这里正在进行一些超级特殊的优化,但我认为此属性是由于
foldr
本身造成的。@user2407038:IIRC,GHC不使用上述
foldr
实现,而是基于构建器的实现。也就是说,
foldr strictOr
在GHCi中对大型列表(如
replicate(10^9)False
)进行解释时失败。我不确定优化规则(也称为可能的构建器)是否会消除这种情况。