1 haskell functional-programming list
我是Haskell的新手和一般的函数式编程.我正在尝试实现一个函数来获取这样的列表
["abc", "def", "ghi"]
Run Code Online (Sandbox Code Playgroud)
并希望能够替换第y个元素中的第x个字符
replaceChar 1 2 'd' arr
Run Code Online (Sandbox Code Playgroud)
会产生
["abc", "ded", "ghi"]
Run Code Online (Sandbox Code Playgroud)
所以基本上第一个参数是元素,第二个是字符串的位置,第三个是字符,最后一个是[String].
此函数的签名如下所示:
replaceChar :: Int -> Int -> Char -> [String] -> [String]
Run Code Online (Sandbox Code Playgroud)
任何帮助,将不胜感激.谢谢!
首先要注意:虽然你的签名完全没问题,但你真的不会使用你正在处理字符串的事实,它也可以是任何其他类型的列表.通过使用完全通用的类型变量(小写字母)而不是:在您的签名中显示它通常是一个好主意1:Char
replaceAtXY :: Int -> Int -> a -> [[a]] -> [[a]]
Run Code Online (Sandbox Code Playgroud)
接下来,请注意,基本上问题可以简化为修改普通(非嵌套)列表的第n个元素.在外部列表中,修改y -th子列表,即在该子列表中修改x -th元素.
那么"修改"在Haskell中意味着什么?我们不能改变课程2的元素.我们需要一个获取列表并返回另一个列表的函数,并根据对列表中单个元素进行操作的函数执行此操作.
modifyNth :: Int -> (a->a) -> [a]->[a]
Run Code Online (Sandbox Code Playgroud)
注意这与标准功能有些类似map :: (a->b) -> [a]->[b].
一旦有了这个功能,就可以轻松实现
modifyXY :: Int -> Int -> (a->a) -> [[a]]->[[a]]
modifyXY x y f nList = modifyNth y (modifyNth x f) nList
Run Code Online (Sandbox Code Playgroud)
(BTW nList参数不需要写,你可以η-减少它).
1 至于为什么这是一个好主意:显然,它允许你在更一般的设置中使用该功能.但更重要的是,它为类型检查器提供了额外的信息,您不会对包含的元素本身做任何事情.这实际上有助于在更复杂的应用程序中捕获大量错误!
2 实际上你可以在ST monad中使用相当不错的语义.