在Haskell脚本中完成的任何操作都可以在GHCi会话中复制吗?

时间:2018-11-06 19:19:08

标签: haskell

我要运行功能

act :: IO(Char, Char)
act = do x <- getChar
         getChar
         y <- getChar
         return (x,y)
在GHCi会话中互动地

。我在其他地方看到过,您可以使用分号代替换行符来在会话中定义函数。但是,当我写

act :: IO(Char, Char); act = do x <- getChar; getChar; y <- getChar; return (x,y)

它不能编译,说

parse error on input ‘;’

我在其他地方看到:{ ... }:可用于多行命令,但键入

:{ act :: IO(Char, Char)

,然后按Enter键会导致错误-也许是我误会了如何使用它们。

除了使这种特殊情况起作用之外,是否还有一种通用的方式来获取将在Haskell脚本中运行的代码并使之在交互式会话中运行?

2 个答案:

答案 0 :(得分:6)

您不能 just 插入分号来替换每个换行符。在一行上执行操作意味着选择退出layout rule,因此您必须插入自己的分号和大括号。这意味着您需要知道在没有布局规则的情况下需要那些花括号和分号。尤其是在这种情况下,每个do块都需要在整个块周围加上大括号,并且每个操作之间需要分号。布局规则通常会根据缩进为您插入这些内容。

因此,可以将这一特定示例写在一行上,您可以这样做:

let act :: IO(Char, Char); act = do {x <- getChar; getChar; y <- getChar; return (x,y)}

在足够新版本的ghci上,您也可以省略let

对于足够简单的do块,您甚至可以省去括号。在您的示例中,{}可能只有一个地方,因此即使您在一行上完成所有操作,GHCI也会插入它们。但是对于具有多个do块或其他多行构造的表达式,如果要在一行上显示它们,则需要显式插入它们。

答案 1 :(得分:0)

关于更广泛的问题:

  

除了使这种特殊情况起作用之外,是否还有一种通用的方式来获取将在Haskell脚本中运行的代码并使之在交互式会话中运行?

我所知道的最接近的事情是使用multiline delimiters,“ :{:}(它们各自以一行显示)”。他们几乎可以处理您可以扔给他们的任何东西。它们不能处理导入(GHCi确实支持完整的导入语法,但是每个导入必须单独一行)和编译指示(唯一的选择是:set,这也需要一行一行),这意味着您不免将它们与其余代码分开并事先输入。

(您始终可以将代码保存在某个位置,并用:l加载文件,这通常是更方便的选择。不过,我对:{和{ {1}}-如果我只想尝试六行无上下文的即兴代码,我倾向于打开文本编辑器窗口,编写小片段并将其直接粘贴到GHCi中。)