如果你在一个小集团文件中声明库+可执行部分,而避免了图书馆的双重编译通过把图书馆变成一个hs-source-dirs目录下,你不能用通常运行项目ghci和runhaskell了,特别是如果可执行文件有辅助模块本身.
什么是推荐的项目布局
runhaskell不幸的是cabal-dev ghci在这个项目中不起作用,我收到一个错误:
Loading package download-0.3.2 ... linking ...
ghc: /home/stulli/haskell/ifdl/cabal-dev//lib/download-0.3.2/ghc-7.4.1/HSdownload-0.3.2.o: unknown symbol `stat64'
ghc: unable to load package `download-0.3.2'
Run Code Online (Sandbox Code Playgroud)
所以我尝试runhaskell,但它使用随cabal而不是cabal-dev安装的软件包因此失败.
更新:runhaskell产生相同的错误:
$ runhaskell -isrc:src/test -package-conf=cabal-dev/packages-7.4.1.conf src/test/Test.hs
Test.hs: /home/stulli/haskell/ifdl/cabal-dev//lib/download-0.3.2/ghc-7.4.1/HSdownload-0.3.2.o: unknown symbol `stat64'
Test.hs: Test.hs: unable to load package `download-0.3.2'
Run Code Online (Sandbox Code Playgroud)
另一方面,cabal-dev安装没有问题.
我偶然发现了一件我不理解的事情.
如果我使用GHCi并使用getLine我得到以下内容
Prelude> a <- getLine
Test<Backspace>oo<CR> -- the Backspace action results in a '^?'
Prelude> a
"Test\DELoo"
Run Code Online (Sandbox Code Playgroud)
如果我在Haskell文件中写相同的
module Main where
main :: IO ()
main = do a <- getLine
putStrLn a
Run Code Online (Sandbox Code Playgroud)
并使用runhaskell运行脚本并输入相同的输入,退格按预期删除't'.
为什么会有区别?
函数timeout和getchHaskell中使用的ncurses库有一个奇怪的问题.当我从GHCi或runhaskell使用它们时,它们按预期工作 - getch等待给定的毫秒数timeout然后返回,即使没有给出输入.但是当我使用GHC 编译同一个文件时,getch立即返回.
我为Haskell尝试了两个ncurses绑定; hscurses:
import UI.HSCurses.Curses
main = do
initCurses
timeout 1000
c <- getch
endWin
print c
Run Code Online (Sandbox Code Playgroud)
并且ncurses:
import UI.NCurses
main = do
e <- runCurses $ do
win <- defaultWindow
getEvent win $ Just 1000
print e
Run Code Online (Sandbox Code Playgroud)
两者都表现出与之前描述的相同的奇怪方式.
我也试过C中的等价程序:
#include <ncurses.h>
int main()
{
initscr();
wtimeout(stdscr,1000);
int c = getch();
endwin();
printf("%d\n", c);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这个按预期工作.
所以我的问题是:当使用解释后的终端和编译的Haskell时,有什么能够产生差异?runhaskell和ghci修改了一些微妙的终端设置吗?或者编译后的代码是否以不同的方式加载库?
添加:
我试图使用FFI从编译的Haskell调用C程序,它立即返回(这是不正确的).我认为这意味着问题不在库中,而是在GHC运行时的某个地方.
我在haskell中编写了一个testscript用以下代码命名的脚本:
#!/usr/bin/env runhaskell
main = putStrLn "hello"
Run Code Online (Sandbox Code Playgroud)
使脚本可执行后,我可以使用它来运行它./testscript.但是,当我尝试使用ghci(即with :l testscript)加载脚本时,我收到错误
target `testscript' is not a module name or a source file
Run Code Online (Sandbox Code Playgroud)
如果我重新命名testscript到testscript.hs,并尝试与ghci的加载一遍,我得到的错误
testscript.hs:1:0: error: invalid preprocessing directive #!
phase `C pre-processor' failed (exitcode = 1)
Run Code Online (Sandbox Code Playgroud)
如果我删除shebang线它工作正常.然而,每次我想在ghci中尝试.hs脚本时,必须为脚本添加扩展,删除顶行,然后删除.hs扩展并添加shebang行是很繁琐的(这在每次我想要进行更改时都很常见它).有更简单的方法吗?
我在Mac OS X 10.6.8下使用ghc版本7.0.3
我正在尝试理解在运行程序时观察到的性能异常runhaskell.
该计划是:
isFactor n = (0 ==) . (mod n)
factors x = filter (isFactor x) [2..x]
main = putStrLn $ show $ sum $ factors 10000000
Run Code Online (Sandbox Code Playgroud)
当我运行它时,需要1.18秒.
但是,如果我重新定义isFactor为:
isFactor n f = (0 ==) (mod n f)
Run Code Online (Sandbox Code Playgroud)
然后该程序需要17.7秒.
这是性能上的巨大差异,我希望程序是等效的.有人知道我在这里缺少什么吗?
注意:在GHC下编译时不会发生这种情况.
我建立简单的脚本runhaskell,我尝试使用FastString的ghc-7.10.2.只是:
import FastString
main = putStrLn "Hello SO"
Run Code Online (Sandbox Code Playgroud)
运行它runhaskell Main.hs导致错误:
Main.hs:1:8:
Could not find module ‘FastString’
It is a member of the hidden package ‘ghc-7.10.2’.
Use -v to see a list of the files searched for.
Run Code Online (Sandbox Code Playgroud)
我知道我可以构建它cabal并指定ghc为依赖,但我真的需要这样做runhaskell.
我怎样才能取消隐藏ghc库runhaskell?
我试图用ghci 检查这个stackoverflow的答案,并得到以下错误:
> import Data.List
> let m = head . sort
> m [2,3,4]
<interactive>:5:4:
No instance for (Num ()) arising from the literal `2'
Possible fix: add an instance declaration for (Num ())
In the expression: 2
In the first argument of `m', namely `[2, 3, 4]'
In the expression: m [2, 3, 4]
Run Code Online (Sandbox Code Playgroud)
不幸的是我无法在写入的haskell文件中重现错误:
-- file.hs
import Data.List
main = do
let m = head . sort
putStrLn $ show $ m [2,3,4]
Run Code Online (Sandbox Code Playgroud)
运行此文件runhaskell …
许多人.ghci在其haskell项目中包含文件,以包含加载模块所需的选项ghci.这是一个例子:
:set -isrc -itest -iexamples -packagehspec2
Run Code Online (Sandbox Code Playgroud)
然而试图运行包含文件时,main通过runhaskell一个具有重复所有这些选项,如:
runhaskell -isrc -itest -iexamples -packagehspec2 test/Spec.hs
Run Code Online (Sandbox Code Playgroud)
有没有一种好方法可以runhaskell从.ghci文件中选择选项?
继承我的代码:
factorial :: Integer -> Integer
factorial n = product [1..n]
main = print(factorial 50)
Run Code Online (Sandbox Code Playgroud)
我没有编译任何错误,但是当我运行编译的代码时
runhaskell test
Run Code Online (Sandbox Code Playgroud)
我收到此错误:
test:1:1: lexical error at character '\DEL'
Run Code Online (Sandbox Code Playgroud)
是什么造成的?我该如何解决这个问题?
更新
我做了一个文件的hexdump:
$ hexdump -x test.hs
Run Code Online (Sandbox Code Playgroud)
得到了
0000000 6166 7463 726f 6169 206c 3a3a 4920 746e
0000010 6765 7265 2d20 203e 6e49 6574 6567 0a72
0000020 6166 7463 726f 6169 206c 206e 203d 7270
0000030 646f 6375 2074 315b 2e2e 5d6e 6d0a 6961
0000040 206e 203d 7270 6e69 2874 6166 7463 726f
0000050 6169 …Run Code Online (Sandbox Code Playgroud)