2

第一个问题是编写一个函数来获取列表中的最后一个元素。

解决方案部分提供的第一个解决方案是:

myLast :: [a] -> a
myLast [x] = x
myLast (_:xs) = myLast xs

所以在 GHCi 我做了:

Prelude> let myLast [a] = a
Prelude> let myLast (_:xs) = myLast xs
Prelude> myLast [1,2,3]

这给了我一个例外:

*** Exception: <interactive>:12:5-29: Non-exhaustive patterns in function myLast

为什么这不起作用?

4

2 回答 2

5

它不起作用,因为您let在 GHCi 中的使用是错误的。

let myLast [a] = a

这定义了一个myLast只对一个元素的列表进行操作的函数。

let myLast (_:xs) = mylast xs

这定义了一个新函数 ,myLast覆盖了上面一行中旧的和不相关的函数。这个新函数会为任何输入抛出异常(或无法终止)。

你应该输入:

:{
let myLast [x] = x
    myLast (_:xs) = myLast xs
:}

或者,只需在文件中输入您的代码,而不是 repl。我强烈建议您避免将 repl 用于单行或交互式实验之外的任何内容。

于 2013-04-19T06:07:53.030 回答
3

当您let在解释器中使用时,这实际上是IOmonad 中的一个 let,例如在 do-block 中

do
  ...
  let x = ...
  ...

如果你想从ghci内部定义一个递归函数,你可以这样做

Prelude> :edit file.hs

然后文件file.hs将在编辑器中打开(例如,在linuxEDITOR中,将选择通过环境变量指定的编辑器;通常,您可以从ghci内部设置使用的编辑器:set editor editor-name;您可以通过将其添加到~/.ghci文件中来使此设置持久)。在此处输入您的函数定义。保存文件。然后将其加载到ghci

Prelude> :load file.hs

现在来自的定义file.hs将在范围内。

于 2013-04-19T06:09:11.350 回答