【问题标题】:Any way to add patterns, type signature, to a function in GHCi?有什么方法可以向 GHCi 中的函数添加模式、类型签名?
【发布时间】:2014-07-27 03:41:10
【问题描述】:

^-- 不,不完全是。我的问题涉及以交互方式添加模式和类型签名......这显然是不可能的。

你可能在早期教程中尝试做的最基本的事情在 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

第二个“let”覆盖了第一个“let”。省略 let 不是一种选择。如果你输入像foo :: [a] -&gt; [a] 这样的表达式,它也不喜欢它。

教程似乎回避了这一点,并让您快速将代码放入文件中。如果您不想制作文件并希望以交互方式工作怎么办?有哪些选择?

【问题讨论】:

  • @IonuțG.Stan 我读过。那不是同一个问题。并且“让”语句将与它之后的所有内容组合在一起的知识是一个非常特殊的奇怪现象。所以基本上,如果我有一个充满教程定义的文件,我会说一次“让”,随后的内容是什么并不重要?

标签: haskell ghci


【解决方案1】:

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

就此而言,您也不应该将其视为在源代码中逐行“添加”。这只是一种符号方便。因此,当您查看“多行”定义时:

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重新定义。

【讨论】:

    【解决方案2】:

    使用多行输入:

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

    【讨论】:

    • 有没有办法指定N个pattern,试一下,遇到问题,调整一下,不用多行输入再指定所有pattern?
    • @HostileFork,目前没有。有一个建议是可以从输入历史中恢复整个多行输入,但尚未实现。
    • 嗯。似乎无法将 foo 的模式与穿插的其他定义分开 (例如 foo [] = [] 后跟 bar = 3 然后 foo (x:xs) = x : foo xs 所以即使你在源代码中输入它们,它们瞬间就被有效地定义了......所以即使在那里也没有“逐行”。对吗?
    • @HostileFork 一个函数/变量的所有方程必须是连续的,与文件中的相同。从let 到空行的所有内容都被一次性解析为let 块。 (在这种情况下,GHCi 不要求对块项目进行额外的缩进。)
    • @HostileFork BTW 在 GHCi(和 lambdabot)中我倾向于使用显式的 ; 和非常偶尔的 {} 大括号(不像你想象的那样经常需要)而不是多行。大部分是旧习惯,但这确实有一个优势,我可以通常一次重新编辑整行。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-25
    • 1970-01-01
    • 2021-05-14
    • 2012-04-10
    • 2020-09-28
    相关资源
    最近更新 更多