替换Haskell中列表列表中的元素

时间:2012-11-08 16:38:03

标签: list search haskell

我有一个列表如下:

[["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,我仍然会收到错误。我可能还是有点新手让哈克尔真正明白该做什么,所以我可能会走错路。

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

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

2 个答案:

答案 0 :(得分:2)

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

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

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

replaceFunc ::(Char - &gt; Char) - &gt;字符串 - &gt;串

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

答案 1 :(得分:2)

首先,让我们看看如何用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 ->b) -> [a] -> [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列表列表的列表,因此映射地图图 - 每个列表级别一个地图。


将来,您可能希望用字符串替换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" >>= rewriteChar"Hello Mum" >>= \x -> [x,x,x]