当重新加载文件时,自动重新加载变量状态到GHCi中

3
当我在Haskell中开发一些数据分析流水线时,预加载变量状态到GHCi中常常是很有用的。目前我所做的是逐行地将脚本复制并粘贴到emacs中,以测试和检查某些中间处理的输出。我甚至无法批量复制粘贴代码,因为换行符不会被传输(至少在emacs Interactive-Haskell模式中是这样)。有没有什么办法可以解决这个问题呢?注意:仅仅加载/重新加载.hs文件并不能解决问题,因为据我所知,在顶层没有"<-"绑定的方法。

为什么不将其制作成一个函数/表达式并加载它呢?或者将其打包成一个普通模块,然后只需将其加载到ghci中即可。 - Random Dev
因为我想使用GHCI对函数内的变量进行交互式分析/测试。 - daj
你能给个例子吗?我觉得我没理解正确 - 通常你可以把你使用的所有东西打包到一个 .hs 文件中,然后只需将其加载到 ghci 中。 - Random Dev
可能适用于纯代码 - 我可以有一个“伪脚本”,其中我从do块中的等效代码中剥离“let”语句。对于具有绑定的不纯代码,例如使用“<-”,我该如何处理? - daj
2
我不确定我理解你想做什么。但是,任何你可以在 GHCi 中输入的内容,你也可以将其放入名为 .ghci 的文件中,该文件位于当前目录中,每次启动 GHCi 时都会自动运行。这对你有帮助吗? - mhwombat
显示剩余2条评论
2个回答

3

我建议您查看 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来解决无法在顶层使用<-的限制。我认为在这种情况下这是可以的,因为您只是用它进行交互:

module Example where

import System.IO.Unsafe

example :: String 
example = "example"

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

是的,我只是为了这个目的使用 unsafePerformIO。缺点是每次重新加载都必须重新计算变量;如果计算过程相当昂贵,则外部存储方法可能更好。 - Reid Barton
@ReidBarton 是的,你甚至可以将 unsafePerformIO 与 foreign-store 结合使用:创建一个 foreign store,执行昂贵的操作,然后使用 unsafePerformIO 在文件中进行 lookupStore。 - bennofs

0

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

  • 使用:l [文件名] 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)

1
重新加载文件行不通。据我观察,我无法在顶层使用“<-”进行绑定。.ghci 文件可以正常工作。我在使用 Emacs 时注意到的一个有趣的事情是,我可以将任何带有 .ghci 扩展名的文件(例如 currWork.ghci)通过 C-c 和 C-l 加载到解释器中,它就像复制粘贴的脚本一样运行。这样,我可以按任务为每个小型交互状态加载程序(而不是将所有内容都倾倒到单个全局使用的 .ghci 文件中)。 - daj
1
在交互模式下<-会起作用。例如,您可以在ghci中键入str <- getLine,然后它将运行getLine并将您键入的任何内容绑定到str - Jeremy List

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接