【问题标题】:Haskell: problems with function prototype to find the position of an element within a listHaskell:函数原型的问题,用于在列表中查找元素的位置
【发布时间】:2020-10-24 22:34:25
【问题描述】:

谁能帮忙。

我不是 Haskell 程序员,我只知道一点点语言,很少。我已经在 Stack overflow 和其他地方查看了几篇帖子,尽管了解实际发生的情况,但我无法解决发生的问题。

我正在开发有关函数式编程的基本教学材料。在本材料中,除了 Haskell 之外,我还使用了另一种语言(非常简单)。在代码中,我遇到了 Haskell 中的数据类型问题。我使用的示例必须保持在相同级别的配置和操作难度,如下所示。

首先,代码必须尽可能简单,不使用语言函数或库,不使用otherwisewhere,因为材料中使用的语言只是对所介绍的函数式编程理论的说明。

以下是可以工作的函数,但在有问题的函数中直接或间接使用。

my_reverse :: (Num a) => [a] -> [a]
my_reverse [] = []
my_reverse (x : xs) = my_reverse xs ++ [x]

my_size :: (Num a) => [a] -> Int
my_size [] = 0
my_size (x : xs) = 1 + my_size xs

my_getpos :: (Eq a, Num a) => a -> [a] -> Int
my_getpos _ [] = error "element does not exist in the list"
my_getpos n (x : xs) = if n == x then my_size xs else my_getpos n xs

我想要的是获取元素在列表中的位置。当我在 Haskell 提示符处执行语句时:

my_getpos 4 (my_reverse [1,2,3,4,5])

我得到了结果 3,这确实是意料之中的。此尝试出现问题。

my_find :: (Num a) => a -> [a] -> Int
my_find n (x : xs) = my_getpos n (my_reverse x : xs)

出现我无法更正的错误消息。 my_find n (x: xs) = my_getpos n (my_reverse x: xs) 行恰好发生 my_getpos 4 (my_reverse [1,2,3,4,5])强>。

my_find函数中,我使用了与my_getpos函数相同的原型,即=> a -> [a] -> Int

我得到的信息是:

<interactive>:26:46: error:
    * Couldn't match expected type `[Integer]' with actual type `a'
      `a' is a rigid type variable bound by
        the type signature for:
          my_find :: forall a. Num a => a -> [a] -> Int
        at <interactive>:25:1-37
    * In the first argument of `my_reverse', namely `x'
      In the first argument of `(:)', namely `my_reverse x'
      In the second argument of `my_getpos', namely `(my_reverse x : xs)'
    * Relevant bindings include
        xs :: [a] (bound at <interactive>:26:16)
        x :: a (bound at <interactive>:26:12)
        n :: a (bound at <interactive>:26:9)
        my_find :: a -> [a] -> Int (bound at <interactive>:26:1)

有Haskell经验的人可以帮助我吗?

提前感谢您抽出宝贵的时间来解答我的问题。

【问题讨论】:

  • 看起来你只是漏掉了一些括号:my_reverse x : xs 应该是 my_reverse (x : xs)
  • 请注意,您可以将其简化为简单的my_find n xs = my_getpos n (reverse xs),因为您没有使用在模式匹配中解构的任何部分。然后,如果您想“排除”xs 参数并写入my_find n = (my_getpos n) . reverse,则可以
  • 你好,罗宾·齐格蒙德。首先,我感谢您能提供帮助并快速回复我的问题。你给了我两句话:第一,我怎么看不懂。我已经更改了括号位置无济于事。第二个使用“反向”功能,正如我在帖子中所说,我需要一个独立于内部语言功能的解决方案。目标是用最少的语言资源编写足够高的算法。
  • 抱歉使用reverse,你可以用你的my_reverse 替换它(它做同样的事情),我只是打字太快了。我不确定您对我的第一条评论有什么误解,这非常明确。我承认我没有详细检查您的代码,可能还有其他问题,但是将这些括号放入是必要的第一步。请使用添加后遇到的错误来编辑您的问题。
  • my_find n (x: xs) = my_getpos n (my_reverse (x: xs))。我保证这将使您发布的错误消失。这就是您通过使用我在第一条评论中提出的确切建议更改代码所得到的。 (我还在第二条评论中以简化的形式发布了上述内容。)

标签: list haskell functional-programming position


【解决方案1】:

在这篇文章发布几分钟后,Robin Zigmond 花了一些时间在我的注意力上帮助我并给了我答案。非常感谢。分享解决方案。

my_find :: (Eq a, Num a) => a -> [a] -> Int
my_find n (x : xs) = my_getpos n (my_reverse (x: xs))

曹。

【讨论】:

  • 您可能没有注意到您的 find 函数是不必要的部分:它不接受空列表。 (正如 Zigmond 已经指出的,并且没有在这个答案中更正。)真的没有理由在列表中进行模式匹配。如果这种偏袒是意料之中的,您可能不希望使其成为非详尽的模式匹配。 (使用-Wall 你会看到警告。)相反,在空列表上进行模式匹配并显式出错。顺便说一句,您的反向函数以平方时间运行,其中线性时间和尾递归实现是可能的并且众所周知。
  • 你好,克兰茨。我要感谢您在回答我的问题和需要并提供指导方面的时间和时间。我知道我做出的解决方案不是最好的,但它符合将要讨论该主题的活动的目标。我在代码中插入了指令 my_find _ [] = error "invalid list"。该事件是关于函数式编程逻辑的活动,其中代码(有疑问的原因)只是与其他函数式语言进行比较的一个说明。
【解决方案2】:

我用 Haskell 和另一种函数式语言做了一些测试,只是为了测试逻辑。一个看似合适的解决方案,即使它不是最好的方法,如下所示:

my_find :: (Eq a, Num a) => a -> [a] -> Int
my_find _ [] = error "invalid list"
my_find n (x : xs) = my_getpos n (my_reverse (x: xs))

【讨论】:

    猜你喜欢
    • 2013-03-24
    • 1970-01-01
    • 2015-02-07
    • 1970-01-01
    • 2010-12-02
    • 2015-12-24
    • 2021-12-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多