^ - 不,它并不完全。我的问题包括添加模式和交互式签名...这显然是不可能的。
你可以尝试从早期教程中做的最基本的事情在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]
这样的表达式,它也不喜欢它。
教程似乎回避了这一点,并迅速将您的代码放入文件中。如果您不想创建文件并希望以交互方式工作,该怎么办?有什么选择?
答案 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]