-1

我有一个这样的列表列表:

[["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 用不同的东西替换它,但我不完全确定我将如何实现它。

任何帮助/指导表示赞赏,谢谢!

4

2 回答 2

2

首先让我们看看如何将 a 替换WM

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. 如果这是我们需要的,我们通常不会费心编写stringWM或直接进入列表列表的列表:lolWM

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" >>= rewriteChar还有"Hello Mum" >>= \x -> [x,x,x]

于 2012-11-09T00:36:56.200 回答
2

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

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

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

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

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

于 2012-11-08T17:10:54.283 回答