【问题标题】:find last element of a list in haskell在haskell中查找列表的最后一个元素
【发布时间】:2017-12-20 03:53:56
【问题描述】:

我编写了以下代码来查找haskell中列表的最后一个元素:

myLast (x:xs) = do
    ret <- if xs == [] then x else (myLast xs)
    return ret

这个想法是遍历列表,直到我们到达一个以空列表作为下一个元素的元素。当我们找到它时,我们将ret 设置为该元素。 这对我来说很有意义,但是当我在交互式 shell 中运行代码时,我收到以下错误:

<interactive>:1:1: error:
    • No instance for (Num (m0 b0)) arising from a use of ‘it’
    • In a stmt of an interactive GHCi command: print it

编辑 1

我使用do 的原因是因为我看到该模式在某处也用于遍历列表,所以我想我可以在这里做同样的事情。我暂时避免使用图书馆以适应这种语言。 我编写了避免使用 do 关键字的函数,现在它可以工作了:

myLast(x:xs) = if xs == [] then x else (myLast xs)

现在只有空列表案例存在问题。如何在 haskell 中解决这个问题?

【问题讨论】:

  • 您为什么使用do 表示法?你认为你使用的是什么 Monad?
  • 请不要使用do 表示法,除非你确信你需要monads(你在这里不需要这些),而且同样适用于return .
  • == 是一个库函数(实际上是一个类方法)。尽管通常没有理由避免使用库函数,但您实际上希望在此处避免使用 ==,因为按照您的方式使用它会对列表的元素施加 Eq 约束。您可以将xs == [] 替换为null xs 来解决问题,但是做更多的模式匹配似乎更好一些。
  • 我认为你应该检查return 的实际作用。 not 会返回你从其他语言中知道的内容。在 Haskell 中你应该把它理解为“回归 monad”,所以return :: a -&gt; [a]

标签: list haskell functional-programming


【解决方案1】:

让我们从函数的签名开始

myLast :: [a] -> a

现在,对于一个空列表输入,可以预期什么作为输出?如何构成任意类型a 的实例?

或者,您可以将丢失最后一个元素的处理推迟到函数的调用者。

myLast :: [a] -> Maybe a

【讨论】:

    【解决方案2】:

    你想要

    myLast (x:xs) =
    

    等于

                    if xs == [] then x else (myLast xs)
    

    太好了,xs == [],让我们把它放回去:

    myLast (x:[]) =                  x 
    

    但是else 部分呢?好吧,让我们为此添加另一个等式,

    myLast (_:xs) =                          myLast xs
    

    我们是金子。

    如果我们用一个空列表[] 来调用它呢?没有定义案例会匹配,我们会得到某种运行时错误。好吧,内置函数 last 也会发生同样的事情,所以我们在这里并不比 Haskell 本身更好,也不差

    你问我提到的那个 match 是什么?这就是 Haskell 函数被调用的方式。每个函数定义可以有多个子句,以函数名开头,每个预期参数包含一个模式

    在等式的左边,

    • (x:[]) 是一个模式,匹配任何单例列表。也可以写成[x]x 将引用列表的唯一元素,如果用于等式的右侧。

    • [] 是一个模式,匹配任何空列表。

    • (x:xs) 是一个模式,匹配任何非空列表。 x 将引用列表的 head(即第一个)元素,如果用于等式的右侧;而xs 将引用列表中元素的rest(这也是一个列表——也称为它的tail)。

    但是等等,你问。 both 子句 match 不会用于单例列表,第一个用于模式 [x],第二个用于(_:xs)xs空列表[]?

    为什么是的,它们确实匹配; (x:[])(_:xs)互斥的。

    但这没关系,因为在 Haskell 中,如果第一个子句匹配,就是这样 - that 是被执行的子句,并且没有其他任何其他模式匹配和子句选择的尝试制作。

    那就是 Prolog,完全是另一种语言。

    【讨论】:

      猜你喜欢
      • 2015-02-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-11
      • 2017-07-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多