【问题标题】:Is there a function in the Haskell standard library that replaces an item in a list?Haskell 标准库中是否有替换列表中项目的函数?
【发布时间】:2019-06-26 14:31:11
【问题描述】:

我想要一个函数f :: Int -> a -> [a] -> [a],其中返回值是第三个参数,第一个参数给出的索引处的项目被第二个参数替换。

所以

f 1 42 [1, 2, 3] == [1, 42, 3]

我在 Hoogle 上查找具有该签名的函数,但没有找到与我要查找的函数匹配的函数。

在 Haskell 标准库中是否有一个函数可以满足我的需求?

【问题讨论】:

  • 我觉得base没有这样的功能。你可以定义它:f i x = zipWith (\j y -> if i == j then x else y) [0..].
  • splitAt 非常接近。

标签: haskell


【解决方案1】:

不,没有这样的功能。此外,想要这是一个不好的迹象。如果您经常需要索引,请考虑使用比列表更合适的数据结构。

【讨论】:

  • 您能否详细说明为什么您认为想要这是一个不好的信号?如果它有所作为,我的列表的长度将始终为 2、3 或 4。
  • @TW80000 索引很慢;在您提议的更改后重建列表很慢。对于小名单,也许这没什么大不了的;但即便如此,如果你知道你的列表总是大小为 2、3 或 4,我认为惯用的方法是创建一个体现该不变量的新类型。
【解决方案2】:

由于您的列表很短,因此重复索引可能具有可容忍的性能。

一个在给定索引处替换一个值并立即退出的函数,重用列表的其余部分,可以简单地编写

replix :: Int -> a -> [a] -> [a]
replix i x xs | i >= 0 = let (h,_:t) = splitAt i xs
                         in h ++ [x] ++ t

使用内置的splitAt :: Int -> [a] -> ([a], [a])

【讨论】:

    【解决方案3】:

    使用lens 库:

    import Control.Lens
    
    f :: Int -> a -> [a] -> [a]
    f i = set (ix i)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-27
      • 1970-01-01
      • 1970-01-01
      • 2012-02-24
      • 1970-01-01
      • 2019-12-02
      • 2016-07-17
      • 2018-03-31
      相关资源
      最近更新 更多