Haskell:99个问题#1:第一个解决方案不能在GHCi中运行

时间:2013-04-19 06:02:18

标签: haskell

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

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

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

为什么这不起作用?

2 个答案:

答案 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文件来使此设置保持不变。在那里输入你的功能定义。保存文件。然后使用

将其加载到 ghci
Prelude> :load file.hs

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