【问题标题】:Haskell function on list of tuples元组列表上的 Haskell 函数
【发布时间】:2019-09-08 20:31:24
【问题描述】:

任务(家庭作业):给定一个整数列表,返回一个元组列表,其中列表中的每个元组都具有 (int_val, val_freq) 的形式。不允许使用内置函数。允许的运算符::、++。

尝试1:

simplify :: [ Int ] -> [( Int , Int )]
simplify [] = []
simplify ((x:xs) ++ [(a, b)]) = 
  if x == a then (simplify xs ++ [(x, b + 1)])
  else  (simplify xs ++ [(x, 0)])

尝试2:

naive_enumerate :: [ Int ] -> [( Int , Int )]
naive_enumerate [] = []
naive_enumerate x:xs = 
  if x == y then [(y, 1)] ++ naive_enumerate xs

enumerate_tuple_list :: [( Int , Int )] -> [( Int , Int )]
enumerate_tuple_list [] = []
enumerate_tuple_list ((a, b):(c, d):rest) = 
  if (a == c) then (a, b+d):(enumerate_tuple_list rest)
  else (a, b+d):(enumerate_tuple_list rest)


simplify :: [ Int ] -> [( Int , Int )]
simplify some_list = enumerate_tuple_list (naive_enumerate some_list)

预期:例如[1, 2, 2, 3] 的输入 [(1,1), (2, 2), (3,1)] 的输出。 实际结果:在尝试 1 中,我在

处遇到错误

化简 ((x:xs) ++ [(a, b)]) =

在尝试 2 中,我的解析错误发生在

enumerate_tuple_list :: [( Int , Int )] -> [( Int , Int )]

问题:

  1. 迭代列表中的元组的正确语法是什么?

  2. 你能解释一下为什么我得到两个解析器错误吗?

  3. 为什么 Haskell 禁止如下代码:

    naive_enumerate x:xs = [(x, 1)] ++ naive_enumerate xs

更新:尝试 3:感谢到目前为止的建议,我现在有了

simplify :: [ Int ] -> [( Int , Int )]
simplify [] = []
simplify (x:xs) = let recursive_result = simplify xs
                  update n ((a, b):pairs) = 
                      if n == a then ((a, b + 1):pairs)
                      else ((n, 1):pairs)
                  in update x recursive_result

现在代码可以编译了,但出现以下错误:

例外:...函数更新中的非详尽模式

因此附加问题:

  1. 我缺少哪些案例?

  2. 是否可以在编译时捕获错误(调试/详细选项不起作用)?

【问题讨论】:

  • 一个完整的答案将比我现在需要的时间更长(但我相信其他人很快就会提供一个)。但是您在尝试 2 中的解析错误是因为您有一个 if ... then 语句而没有 else

标签: haskell


【解决方案1】:

您当前正在尝试迭代您的返回值,就好像它是一个参数一样。您需要先进行递归调用,然后更新结果

simplify [] = []
simplify (x:xs) = let recursive_result = simplify xs
                      update n pairs = ...
                  in update x recursive_result

... 是您尝试查找和替换已包含 x 的对,或添加新对的位置。

提示:内置的lookup 函数会有所帮助,如果你能说服你的老师让你使用它。

【讨论】:

    【解决方案2】:

    首先,感谢所有受访者。我将在这里回答我所有的问题,并在答案的最后提供一个(剧透)示例解决方案。

    1. 迭代列表中的元组的正确语法是什么?

    列表不应被迭代。要在这样的数据结构上编写函数,

    function_name ((element1, element2, ..., elementN):some_list) = 结果

    我的错误是我忽略了列表创建构造函数的绑定优先级:和函数应用程序。

    1. 您能解释一下为什么我会遇到两个解析器错误吗?

    已经回答了。

    1. 为什么 Haskell 禁止如下代码:

    由 chepner 解释。

    1. 我遗漏了哪些情况?

    存在 1-element-lists 的情况。

    1. 是否可以在编译时捕获错误?

    可以使用HTF

    剧透警告 我的尝试5来了:

    simplify :: [ Int ] -> [( Int , Int )]
    simplify [] = []
    simplify (x:xs) = let recursive_result = simplify xs
                      update n [] = [(n, 1)]
                      update n ((a, b):pairs) = 
                          if n == a then ((a, b + 1):pairs)
                          else (a, b):(update n pairs)
                  in update x recursive_result
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-01-05
      • 2022-12-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-24
      • 1970-01-01
      相关资源
      最近更新 更多