【问题标题】:Replacing element in a list of lists in Haskell替换 Haskell 列表中的元素
【发布时间】:2012-11-08 16:38:02
【问题描述】:

我有一个这样的列表:

[["BBBBBBBB",
  "BWFFFPFGB", 
  "BWFFFPFGB",
  "BWFFMPFGB",
  "BWFFFPF_B",
  "BWFFFPF6B",
  "BBBBBBB"]]

我做了一些研究,发现了如何使用!! 运算符访问单个元素。但是在搜索某个元素'M' 时,我不知道该怎么做。我的朋友说我需要在列表中使用 (x:xs):xss 之类的东西,但是当我在 WinGHCi haskell 程序中尝试这个时,我得到了这个。

Prelude> let list =    [["BBBBBBBB",
  "BWFFFPFGB", 
  "BWFFFPFGB",
  "BWFFMPFGB",
  "BWFFFPF_B",
  "BWFFFPF6B",
  "BBBBBBB"]]


Prelude> head(x:xs):xss
<interactive>:192:2: Not in scope: `x'
<interactive>:192:4: Not in scope: `xs'
<interactive>:192:8: Not in scope: `xss'

我知道我将名称声明为 list 而不是 x:xs,但即使我将其声明为 x:xs,我仍然会收到错误消息。我可能对haskell还有些陌生,无法真正理解该怎么做,所以我可能会以这种方式错误。

我在这里查看Replace individual list elements in Haskell?,因为最终我想用不同的东西替换M ,但我不完全确定我将如何实现它。

感谢任何帮助/指导,谢谢!

【问题讨论】:

  • 我建议Learn You a Haskell 以便您了解基本语法。在你阅读了前几章之后,你应该能够弄清楚你想要什么。
  • head(x:xs):xss 没有意义。

标签: list search haskell


【解决方案1】:

首先让我们看看如何将W 替换为M

charWM :: Char -> Char
charWM 'W' = 'M'  -- If you see W, put M.
charWM x  =  x   -- If you see anything else, put it back as is.

您可以通过添加其他字母转换以您喜欢的方式重写该函数。

现在让我们通过一个列表来处理它。有一个很棒的函数 map :: (a -&gt;b) -&gt; [a] -&gt; [b] 可以让你对列表中的每个元素应用一个函数。

stringWM :: String -> String
stringWM xs = map charWM xs  -- do charWM to everything in xs.

例如stringWM "QWERTY WILL WIN" = "QMERTY MILL MIN"

接下来我们可以对列表列表执行此操作:

lolWM :: [String] -> [String]
lolWM xss = map stringWM xss

String[Char] 的类型同义词。)
让我们在 ghci 中测试一下:

*Main> list'
["BBBBBBBB","BWFFFPFGB","BWFFFPFGB","BWFFMPFGB","BWFFFPF_B","BWFFFPF6B","BBBBBBB"]
*Main> lolWM list'
["BBBBBBBB","BMFFFPFGB","BMFFFPFGB","BMFFMPFGB","BMFFFPF_B","BMFFFPF6B","BBBBBBB"]

一切都好。

你的例子不完全是list',它是[list'],它有1个元素,所以要处理它,我们需要map lolWM。通常我们不会费心写stringWMlolWM 而是直接转到列表列表,如果这是我们需要的话:

lololWM = (map.map.map) charWM

map.map.map表示地图地图地图。您可以让它让您大吃一惊,或者您可以只说 Char 列表列表的列表,因此 map map map - 每个列表级别一张地图。


将来,您可能希望将W 替换为字符串而不是字符。

rewriteChar :: Char -> String
rewriteChar 'W' = "--^--"
rewriteChar  x  = [x] -- put x in a list to make it a string

这一次,地图还不够:map rewriteChar "QWERTY WILL WIN"给了

["Q","--^--","E","R","T","Y"," ","--^--","I","L","L"," ","--^--","I","N"]

我们可以在上面使用concat 将其扁平化为一个列表,但这样做更有趣

rewriteString = concatMap rewriteChar

所以现在rewriteString "QWERTY WILL WIN" 给我们"Q--^--ERTY --^--ILL --^--IN"

如需更多令人兴奋的尝试,请访问 "QWERTY WILL WIN" &gt;&gt;= rewriteChar"Hello Mum" &gt;&gt;= \x -&gt; [x,x,x]

【讨论】:

  • 谢谢,这正是我想要的。我的一个问题是我将如何修改它以使其中的 1 个字符串将 'M' 替换为 'W'?
【解决方案2】:

首先,Haskell 中几乎所有的“变量”都是不可变的,所以没有“更改列表”,只有修改后的副本。

其次,你需要通过一些标准来找到一个元素。为此,您需要遍历一个列表。 - 这可以使用递归来完成。过滤可以使用作为遍历函数的参数传递的函数来完成(这个函数必须接受一个元素并返回一个布尔值)。

尝试将以上内容放在一起并制作自己的功能。从类型签名开始,它显示了您想要做什么:获取 Char 列表(最好泛化为泛型类型)和一个可能更改元素并返回修改后列表的函数:

replaceFunc :: (Char -> Char) -> String -> String

另外,阅读 http://www.haskell.org/haskellwiki/How_to_work_on_lists ,这里有一个提示如何将某些功能仅应用于特定元素。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-08-16
    • 1970-01-01
    • 2021-05-19
    • 1970-01-01
    • 1970-01-01
    • 2012-01-18
    • 1970-01-01
    相关资源
    最近更新 更多