使用foldr查找列表的第K个元素

时间:2015-04-02 00:23:26

标签: haskell fold

我尝试按列表中的索引实现自己的安全搜索元素。 我想,我的功能必须有这个签名:

safe_search :: [a] -> Int -> Maybe a
safe_search xs n = foldr iteration init_val xs n
iteration = undefined
init_val = undefined

我对迭代的实现有问题。我想,它必须看起来像这样:

safe_search :: [a] -> Int -> Maybe a
safe_search xs n = foldr iteration init_val xs n
    where
    iteration :: a -> (Int -> [a]) -> Int -> a
    iteration x g 0 = []
    iteration x g n = x (n - 1)
    init_val :: Int -> a
    init_val = const 0

但它有很多错误。我对haskell的直觉是错误的。

3 个答案:

答案 0 :(得分:5)

你有

safe_search :: [a] -> Int -> Maybe a
safe_search xs n = foldr iteration init_val xs n

如果null xs成立,foldr iteration init_val [] => init_val,所以

init_val n

必须有意义。什么都没有回来,所以

             = Nothing

是我们可以在这里做的,以适应返回类型。

因此init_val是一个函数:: Int -> Maybe a。根据{{​​1}}的定义,这也是"递归"组合函数的参数是,#34;来自右边":

foldr

然后这个调用也必须返回这样一个函数本身(再次,通过iteration x r foldrfoldr f z [a,b,c,...,n] == f a (f b (f c (...(f n z)...)))的定义,即它必须返回一个相同类型的值它得到了它的第二个参数),所以

f :: a -> b -> b

这很容易,第0个元素是手头的元素, n | n==0 = Just x ;如果x怎么办?

n > 0

右?再过一步就可以让你自己做了...... :)它不是 | n>0 = ... (n-1) (列表的元素)那里的点;它必须是一个功能。我们已经收到了这样的功能,作为一个论点......

要查看此处发生了什么,当输入是单元素列表时,检查案例可能会有所帮助,首先,

x

并有两个要素,

safe_search [x] n = foldr iteration init_val [x] n
                  = iteration x init_val n

希望现在很清楚。

答案 1 :(得分:1)

想一想。

  1. init_val应该使用哪种类型?

  2. 您需要对g做什么? g是此代码中最棘手的部分。如果您已经了解了继续传递风格,您应该将init_valg视为延续。

  3. x代表什么?你需要做什么?

  4. 前段时间我写了explanation关于foldlfoldr方面的定义是如何工作的。你可能会发现它很有帮助。

答案 2 :(得分:-1)

我建议使用标准foldr模式,因为当您使用标准函数时,它更容易阅读和理解代码:

  1. foldr的类型为foldr :: (a -> b -> b) -> [a] -> b -> [b], 其中第三个参数b是列表acc元素的累加器[a]
  2. 在您添加了列表中所需的元素后,您需要停止向[a]添加列表acc的元素。然后,您获取结果列表head的{​​{1}},从而获得列表[b]的所需元素。
  3. 要获取列表[a]的{​​{1}}个元素,您需要将nxs元素添加到累加器length xs - n,从列表末尾开始计算。
  4. 但是如果我们想使用标准xs函数来提高代码的可读性,那么在何处使用迭代器?我们可以在累加器中使用它,将其表示为元组acc。我们从每个回合中foldr减去(acc, iterator)我们从初始列表1添加元素到iterator并停止向xs添加元素acc 1}}当我们的xs相等acc时。
  5. 然后我们将iterator应用于我们的0函数的结果,以获取初始列表head . fst的所需元素,并用foldr构造函数包装它。
  6. 当然,如果我们的初始列表xs的{​​{1}}小于所需元素Just的索引,则整个函数length - 1的结果将为{{ 1}}。
  7. 以下是函数xs的代码:

    n