如何在GHCi中导入一个Haskell模块?

36
我正在尝试从书《Learn You A Haskell for Great Good》中自学Haskell。我已经学到第七章的最后一节(模块),其中讲述了如何创建自己的模块。我复制并粘贴了该节开头提供的Geometry模块。文件名为Geometry.hs,就像书中建议的那样,文件位于ghci的bin目录中,在那里我以前曾成功地使用:l为另一个.hs文件进行过加载。
当我在GHCi中输入以下命令时:
import Geometry

我遇到了以下错误:

无法找到模块“Geometry”,它既不是当前程序中的模块,也不在任何已知包中。

我肯定犯了什么明显的错误,但我想不出来是什么。


1
你的意思不是指第七章吗? - Zeta
2
我只能加载已安装的模块和当前工作目录中的模块来使用ghci(如果你在Windows上可以尝试运行:!cd来查看ghci的当前工作目录)。 - luqui
5
据我所知,除非本地文件被一个:l命令加载的文件使用,否则GHCi不会将其识别为模块。创建一个额外的文件,在其中导入Geometry模块,然后加载该文件即可。 - Zeta
2
@Zeta 这对我来说听起来像是一个答案(虽然我猜你可以直接加载Geometry本身而不创建包装模块)。 - Daniel Wagner
@DanielWagner:我不确定如何把它写下来。另外,在报告中我没有找到关于模块路径的任何内容,如果可能的话,我喜欢引用我的答案来源。 - Zeta
显示剩余2条评论
3个回答

30

当您在GHCi中使用import ModuleName时,它的工作方式(大多数情况下)与import Data.List相同: GHC会检查本地软件包数据库中的模块,加载它,并将其(导出的)内容引入范围。

但是,Geometry不是使用ghc-pkg安装的软件包的模块。因此,GHC根本不知道该模块存在。交互式变体GHCi也是如此。

但是,如果您:load一个程序,情况就会改变。 GHC将考虑其使用的模块:

-- Foo.hs
module Foo where

foo :: IO ()
foo = putStrLn "Hello from foo!"
-- Main.hs
module Main where
import Foo (foo)

main :: IO ()
main = foo
$ cd /path/to/your/files
$ ghci
GHCi, version 7.10.2: http://www.haskell.org/ghc/  :? for help
Prelude> import Foo

<no location info>:
    Could not find module ‘Foo’
    It is not a module in the current program, or in any known package.
Prelude> :l Main.hs [1 of 2] Compiling Foo ( Foo.hs, interpreted ) [2 of 2] Compiling Main ( Main.hs, interpreted ) Ok, modules loaded: Main, Foo. *Main> :l Main.hs *Main> foo Hello from foo! *Main> import Foo *Main Foo> -- module now loaded

可以看到,首先导入 Foo 失败了。但是,当我们实际加载使用 Foo 的程序后,在 GHCi 中就能够成功使用 import Foo

所以如果你想在 GHCi 中使用 import,请确保 GHC 能够找到你的模块,要么将其包含在一个包装器中,要么安装它。如果只想加载模块本身,请使用 :load 命令。


谢谢大家。我找到了问题所在。PDF文件中有一行代码延续到了下一行文本。与导入相比,:load命令的错误消息更加有用。 - user1153980
1
谢谢你的回答。有没有办法让ghc全局知道一个自定义模块(这样你就不需要导航到它所在的目录了)? - Chris
@Chris,我错过了那个评论。你在此期间找到答案了吗? - Zeta
@Zeta 不是很确定,但我被建议不要这样做,而是使用沙盒。 - Chris
1
@exchange 这个回答相当老了;Cabal 1.10.x 是最近的版本,而 --lib 变体在那时还不可用。请随意提供一个更为现代化的用法回答 :) - Zeta
显示剩余2条评论

3
TLDR: 《Learn you a Haskell》这本书没有提到你需要首先 :load Geometry.hs 文件。然后使用 :m 返回 Prelude,再使用 import Geometry
注:该内容为技术性翻译,如有本专业领域相关问题,建议向相应领域专家寻求帮助。

0
现在安装包时也可以添加lib标志,即运行cabal install --lib packagename,然后直接在GHCi中导入相应的包。例如,在这种情况下,cabal install --lib hgeometry将有助于从this geometry package导入模块。

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