【问题标题】:Automatically reloading variable state into GHCi when re-loading a file重新加载文件时自动将变量状态重新加载到 GHCi
【发布时间】:2015-06-27 10:54:09
【问题描述】:

当我在 haskell 中开发一些数据分析管道时,在加载时将变量状态预加载到 GHCi 中通常很有用。

我现在最终做的是在 emacs 中逐行复制和粘贴脚本的一部分,只是为了测试和检查一些中间处理的输出。我什至不能批量复制粘贴代码,因为换行符没有被传输(至少在 emacs Interactive-Haskell 模式下)

有没有办法做到这一点?

编辑:简单地加载/重新加载 .hs 文件并不能解决问题,因为 afaik 无法在顶层使用“

【问题讨论】:

  • 为什么不把它变成一个函数/表达式并加载它呢?或者把它打包成一个普通的模块,然后把它加载到 ghci 中?
  • 因为我想使用 ghci 对函数内的变量进行交互式分析/测试。
  • 你能举个例子吗?我不认为我理解正确 - 通常您可以将您使用的所有内容打包到 .hs 文件中,然后将其加载到 ghci
  • 这可能适用于纯代码 - 我可以有一个“伪脚本”,在其中从 do 块中的等效代码中删除“let”语句。我将如何处理具有绑定的不纯代码,例如使用“
  • 我不确定我是否理解您要执行的操作。但是,您可以在 GHCi 中键入的任何内容,您也可以将其放入当前目录中名为 .ghci 的文件中,它会在您启动 GHCi 时自动运行。这对你有帮助吗?

标签: haskell emacs read-eval-print-loop ghci


【解决方案1】:

我建议你看看foreign-store。它允许您通过数字引用变量,这些变量通过重新加载持续存在。这是一个例子:

λ: :set -XScopedTypeVariables 
λ: import Foreign.Store
λ: st <- newStore "example"
Loading package foreign-store-0.2 ... linking ... done.
λ: readStore st
"example"
λ: st
Store 0
λ: :r
Ok, modules loaded: none.
λ: st
<interactive>:8:1:
    Not in scope: ‘st’
    Perhaps you meant ‘fst’ (imported from Prelude)
λ: Just (st :: Store String) <- lookupStore 0
λ: readStore st
"example"

或者,您也可以将所有定义放在一个 hs 文件中,然后仅重新加载该文件。您可以使用 unsafePerformIO 绕过不能在顶层使用 &lt;- 的限制。我认为在这种情况下没问题,因为无论如何您只能将它用于交互:

module Example where

import System.IO.Unsafe

example :: String 
example = "example"

file :: String
file = unsafePerformIO $ readFile "/tmp/example.hs"

【讨论】:

  • 是的,我只是为此目的使用unsafePerformIO。缺点是每次重新加载时都必须重新计算变量;如果计算非常昂贵,那么外国商店的方法可能会更好。
  • @ReidBarton 是的,你甚至可以将 unsafePerformIO 与 foreign-store 结合起来:创建一个外部存储,执行昂贵的操作,并使用 unsafePerformIO 来做文件中的 lookupStore。
【解决方案2】:

有两种主要方法可以做到这一点:

  • 使用:l [filename] GHCi 命令在不退出 GHCi 的情况下重新加载文件。
  • 将变量写入您的~/.ghci 文件中,该文件将在打开 GHCi 时加载。

如果您不知道在 ~/.ghci 中添加什么,这就是我的内容:

:set prompt "\955 "
:set prompt2 "| "

:def hoogle \x -> return $ ":!hoogle --info \"" ++ x ++ "\""

let f `on` x = \a b -> (f a) `x` (f b)
let break (f,g) = \a -> (f a, f g)

【讨论】:

  • 重新加载文件并不能解决问题。据我所知,我无法使用“
  • &lt;- 确实在交互模式下工作。例如:您可以在 ghci 中输入 str &lt;- getLine,它会运行 getLine 并将您输入的任何内容绑定到 str
猜你喜欢
  • 1970-01-01
  • 2015-10-05
  • 1970-01-01
  • 2015-12-30
  • 2012-08-25
  • 2011-01-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多