0

我想定义一个safeIndex适用于Foldable类型的函数

safeIndex :: (Foldable t, Integral i) => t a -> i -> Maybe a
safeIndex = foldr step (const Nothing)
  where
    step :: Integral i => a -> (i -> Maybe a) -> i -> Maybe a
    step x f i = if i == 0
               then Just x
               else f (i - 1)

但它不适用于无限列表。为了foldr在中间停止,我认为我们必须确定它是否应该只用 的第一个参数停止step,这似乎是不可能的。

是否可以修复该功能以使其适用于无限结构?如果不是,我们应该限制哪些类型类t

4

2 回答 2

1

实际上,问题描述中的定义已经适用于无限内置列表。是其他一些错误让我认为它不能;)(见评论。)

于 2017-07-17T12:40:33.563 回答
1

如果您不介意依赖依赖,Gabriel Gonzalez 的foldl提供indexgenericIndex折叠适合您的目的。

例如,你可以写

safeIndex :: (Foldable f, Integral a) => a -> f b -> Maybe b
safeIndex = fold . genericIndex

除此之外,您发布的代码似乎符合您的意图。

编辑:我间隔了“无限列表”位。

这将适用于无限列表,但我不知道是否有一种明智的方法可以为所有Foldables 定义它。

safeIndex' :: Int -> [a] -> Maybe a
safeIndex' n = listToMaybe . foldr (.) id (replicate n (drop 1))

编辑2:

从头开始,您在原始帖子中获得的内容应该适用于任何Foldable.

于 2017-07-17T12:29:49.917 回答