我尝试按列表中的索引实现自己的安全搜索元素。 我想,我的功能必须有这个签名:
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的直觉是错误的。
答案 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
,foldr
,foldr 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)
想一想。
init_val
应该使用哪种类型?
您需要对g
做什么? g
是此代码中最棘手的部分。如果您已经了解了继续传递风格,您应该将init_val
和g
视为延续。
x
代表什么?你需要做什么?
前段时间我写了explanation关于foldl
在foldr
方面的定义是如何工作的。你可能会发现它很有帮助。
答案 2 :(得分:-1)
我建议使用标准foldr
模式,因为当您使用标准函数时,它更容易阅读和理解代码:
foldr
的类型为foldr :: (a -> b -> b) -> [a] -> b -> [b]
,
其中第三个参数b
是列表acc
元素的累加器[a]
。[a]
添加列表acc
的元素。然后,您获取结果列表head
的{{1}},从而获得列表[b]
的所需元素。 [a]
的{{1}}个元素,您需要将n
个xs
元素添加到累加器length xs - n
,从列表末尾开始计算。 xs
函数来提高代码的可读性,那么在何处使用迭代器?我们可以在累加器中使用它,将其表示为元组acc
。我们从每个回合中foldr
减去(acc, iterator)
我们从初始列表1
添加元素到iterator
并停止向xs
添加元素acc
1}}当我们的xs
相等acc
时。 iterator
应用于我们的0
函数的结果,以获取初始列表head . fst
的所需元素,并用foldr
构造函数包装它。 xs
的{{1}}小于所需元素Just
的索引,则整个函数length - 1
的结果将为{{ 1}}。 以下是函数xs
的代码:
n