【发布时间】:2019-07-14 13:05:37
【问题描述】:
我一直在尝试学习 Haskell,目前正在尝试制作递归的“字典”或“翻译器”函数。 基本上它应该接收一个字符串数组和一个元组或字符串数组,并返回一个字符串数组,如果它与第一个匹配,则该数组的元素被元组的第二部分替换。 所以基本上来自
["a", "b", "zz"] [("a", "11"),("b","c")]
到
["11","c","zz"]
很难做到……这是我目前所拥有的:
aa (x:xs) (y:ys) = do
-- iterate through y
if ys == [] then return(x:xs) else aa (x:xs)(ys)
-- iterate through x
if xs == [] then return(x:xs) else aa (xs)(y:ys);
if x == fst(y)
then do
putStrLn("Yes");
return (snd(y):xs);
else return (x:xs);
适用于数组的第一个元素。 我似乎无法弄清楚如何让它通过。删除 putStrLn 也会导致错误“不匹配”括号,为什么?
在尝试解决的同时也尝试存储结果,但没有成功:
aa (x:xs) (y:ys) = do
if x == fst(y)
then result <- snd(y):xs
else result <- x:xs
return result;
导致错误“输入'
【问题讨论】:
-
一旦找到匹配项,就再也不会递归(调用 aa)。此外,一个更简单的实现是:将元组数组放入字典中,fst() 作为键,snd() 作为值。然后迭代列表(这可以是递归的或不递归的)和 foreach 元素,如果没有这样的键,则产生字典中该键的值或列表中的值(即 dict.getOrDefault(element, element))
-
如果
ys == []不应该检查整个 列表是否为空。话虽如此,您的代码看起来是命令式的,而不是功能性的,您也许应该先编写一个可以在字典中查找 single 值的函数,让自己更轻松。 -
你也使用了很多
return和dos。这些是Monad函数。通常你不会在纯函数中找到这些。 -
感谢您的建议。我会调查那些东西
-
return不会像您认为的那样做。一场比赛怎么样?永远不要输入return,忘记它的存在。每次您想键入它时,请键入pure并认为“我正在将此值提升到更丰富的计算环境中”。如果您不知道什么是 monad 或您所在的 monad,那么您甚至不需要输入“pure”。