【问题标题】:Haskell recursive dictionary function problemsHaskell递归字典函数问题
【发布时间】: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 值的函数,让自己更轻松。
  • 你也使用了很多returndos。这些是Monad 函数。通常你不会在纯函数中找到这些。
  • 感谢您的建议。我会调查那些东西
  • return 不会像您认为的那样做。一场比赛怎么样?永远不要输入return,忘记它的存在。每次您想键入它时,请键入 pure 并认为“我正在将此值提升到更丰富的计算环境中”。如果您不知道什么是 monad 或您所在的 monad,那么您甚至不需要输入“pure”。

标签: haskell recursion


【解决方案1】:

如果我们分解它,这不是一个很难解决的问题。首先,我们需要一个函数,它接受一个元组列表和一个键,如果该键存在于列表中,则返回该键的值。

幸运的是,这已经为我们定义好了,lookup

它返回一个 Maybe 值。如果我们没有找到它,那么我们不需要替换它,所以我们可以简单地返回原始值。 fromMaybe 为我们做了这个,它接受一个默认值和一个可能的值,如果可能的值是 Just,它会返回 just 中的值。

现在我们只需要对列表进行映射,对于每个项目,如果存在关联列表中的项目,则将其替换为关联列表中的项目,如果不存在,则将其替换为自身。

这是代码:

import Data.Maybe (fromMaybe)

translator xs ys = map replace xs
    where replace x = fromMaybe x (lookup x ys)

您的代码存在一些问题,您似乎在尝试使用 do 表示法,而实际上并不需要它。当您是初学者时,通常您应该只在使用 IO 的函数中使用 do 表示法。如果你想定义一些东西来防止一切都是一个长语句,你可以使用 where 或 let。

λ> translator ["a", "b", "zz"] [("a", "11"),("b","c")]
["11","c","zz"]
λ> 

【讨论】:

    猜你喜欢
    • 2011-02-14
    • 2019-02-28
    • 1970-01-01
    • 2021-08-17
    • 2015-01-27
    • 1970-01-01
    • 2017-01-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多