有没有办法在GHCi中为一个函数添加模式,签名?

时间:2014-07-27 03:41:11

标签: haskell ghci

^ - 不,它并不完全。我的问题包括添加模式和交互式签名...这显然是不可能的。

你可以尝试从早期教程中做的最基本的事情在GHCi中不起作用:

foo [] = []
foo (x:xs) = x : foo xs

如果您将其放入foo.hs并在GHCi提示符下输入:load foo.hs,则该方法有效。然后,您可以在列表上调用foo并返回列表。

Google早期搜索告诉您,在GHCi中,您需要let声明。但在这种情况下(使用多个模式定义的函数)它将无法工作:

Prelude> let foo [] = []
Prelude> let foo (x:xs) = x : foo xs
Prelude> foo [1, 2, 3]
[1,2,3*** Exception: <interactive>:3:5-27: Non-exhaustive patterns 
    in function foo

第二个“让”覆盖第一个“让”。放弃让出不是一种选择。如果你输入像foo :: [a] -> [a]这样的表达式,它也不喜欢它。

教程似乎回避了这一点,并迅速将您的代码放入文件中。如果您不想创建文件并希望以交互方式工作,该怎么办?有什么选择?

2 个答案:

答案 0 :(得分:3)

没有。在运行在评估程序中定义它的语句后,无法为GHCi中的函数添加新模式或类型签名。

就此而言,您不应该将其视为&#34;添加&#34;在源代码中逐行进行。它只是一种符号方便。所以,当你看到一条&#34;多线&#34;定义如:

foo :: [a] -> [a]
foo [] = []
foo (x:xs) = x : foo xs

这些foo定义必须全部绑定在一起。你不能将它们分开......例如,这会导致错误:

foo :: [a] -> [a]
foo [] = []

bar = 3

foo (x:xs) = x : foo xs

(注意:类型签名可能会分开。有关可以分开多远的详细信息,请参阅How is 'block' granularity in Haskell defined?

要将组合在一起,您可以在GHCi中使用多行输入。或者你可以用分号在一行上完成所有操作:

let foo :: [a] -> [a] ; foo [] = [] ; foo (x:xs) = x : xs

但是您无法输入输入,测试输入,然后修补单个模式,然后重新测试。每个let重新定义整个函数。

答案 1 :(得分:2)

使用多行输入:

Prelude> :set +m
Prelude> let
Prelude| foo [] = []
Prelude| foo (x:xs) = x : foo xs
Prelude| 
Prelude> foo [1,2,3]
[1,2,3]