Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/9.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.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而言,scanr的定义是如何工作的?_Haskell_Fold - Fatal编程技术网

Haskell 就foldr而言,scanr的定义是如何工作的?

Haskell 就foldr而言,scanr的定义是如何工作的?,haskell,fold,Haskell,Fold,Haskell Wikibook第102页的练习1要求“编写您自己的scanr定义,首先使用递归,然后使用foldr。”我编写了一个递归定义: myscan f acc [] = [acc] myscan f acc (x:xs) = val : rest where val = f x (head rest) rest = myscan f acc xs …但无法找到foldr版本。我最终在谷歌上找到了这个答案: myscan2 f acc xs = foldr f

Haskell Wikibook第102页的练习1要求“编写您自己的scanr定义,首先使用递归,然后使用foldr。”我编写了一个递归定义:

myscan f acc []     = [acc]
myscan f acc (x:xs) = val : rest where
    val  = f x (head rest)
    rest = myscan f acc xs
…但无法找到foldr版本。我最终在谷歌上找到了这个答案:

myscan2 f acc xs = foldr f' [acc] xs where
    f' x xs = (f x (head xs)) : xs
很明显,它是有效的,但对我来说没有意义。使用参数

(+) 0 [1,2,3]
…它变成这样:

myscan2 (+) 0 [1,2,3] = foldr f' [0] [1,2,3] where
    f' [0] [1,2,3] = ((+) [0] (head [1,2,3])) : [1,2,3]

…但是(+)[0](头[1,2,3])部分与(+)的类型不兼容。但是,该函数可以正常工作,因此,我读取或转换的内容不正确吗?

您发现的函数问题是:

  • myscan2 f acc xs=foldr f'[acc]xs上的
    xs

    f'xxs=(fx(头xs)):xs
  • 他们完全不同。如果它看起来像是:

    myscanr f acc xs = foldr f' [acc] xs
         where f' b a = (f b (head a)) : a
    

    它所做的是,将累加器更改为一个列表,因为scanl accumlate但它保留了通过原始列表的所有路径。因此,
    f'
    cons(:)
    将函数
    f
    应用于列表的实际元素和累加器的
    head

    这是一个简单的转换错误,可能是由于它们的哑参数名。它应该是
    (+)3(头[0]):[0]
    。累加器是
    foldr
    函数的第二个输入,但出于某种疯狂的原因,它们调用累加器参数
    xs
    。显然,您必须应用
    reverse
    ,因为返回的列表是向后的。我不认为它是向后的。毕竟,这是一次正确的扫描。另外,您将
    x
    重命名为
    b
    ,我认为将其保留为
    x
    会更有意义。您是对的。我弄错了:/its
    scanr
    ,但我重新命名了两者,以表明,
    f'
    myscanl f acc xs=foldr f'[acc]xs
    上的变量没有直接关系(当然,它们可以根据您的意愿命名),它的好名字是
    b
    as
    x
    ,创造了更多的语义。如果它是
    scaner
    ,我就不会叫它
    myscanl
    !谢谢你。我可以在纸上追踪工作,即使我还不能在心里摸索。期待当它不再是高深莫测的异族象征意义的时候。:)