第一个问题是编写一个函数来获取列表中的最后一个元素。
解决方案部分提供的第一个解决方案是:
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
为什么这不起作用?
答案 0 :(得分:5)
它无效,因为您在GHCi中使用let
是错误的。
let myLast [a] = a
这定义了一个仅对一个元素的列表进行操作的函数myLast
。
let myLast (_:xs) = mylast xs
这定义了一个新函数myLast
,从上面的行中过度隐藏旧的和不相关的函数。这个新函数会抛出任何输入的异常(或者无法终止)。
您应该输入:
:{
let myLast [x] = x
myLast (_:xs) = myLast xs
:}
或者只是在文件而不是repl中输入您的代码。我强烈建议你避免使用除了单行或交互式实验之外的任何内容。
答案 1 :(得分:3)
当您在解释器中使用let
时,这实际上是IO
monad中的let,例如在do-block中
do
...
let x = ...
...
如果你想从 ghci 里面定义一个递归函数你可以做
Prelude> :edit file.hs
然后文件file.hs
将在编辑器中打开(例如,在 linux 中将选择通过环境变量EDITOR
指定的编辑器;通常你可以设置来自 ghci 内部的使用编辑器:set editor editor-name
;您可以通过将此设置添加到~/.ghci
文件来使此设置保持不变。在那里输入你的功能定义。保存文件。然后使用
Prelude> :load file.hs
现在file.hs
的定义将在范围内。