我有以下目录结构:
大部分(当然不是全部)代码是用全局脚本编写的,并由 Haskell 程序 hsgs2hs 转换为 Haskell。
因此,gsi 和 gs2hs 中的代码都依赖于 libgs 中的模块。
由于我的代码组织有些草率,gs2hs 中的编译器还依赖于 gsi 目录中的前端模块(解析器、类型检查器等)。
撇开法律不谈:如果重要的话:我的代码可以在线免费获得,但不是开源的,并且其许可证不允许通过Hackage 重新分发。结束合法性。
我可以通过运行使这个目录结构工作
ghc --make -i../libgs gsi.hs -o gsi
Run Code Online (Sandbox Code Playgroud)
在 gsi 目录中,以及
ghc --make -i../libgs -i ../gsi gs2hs.hs -o gs2hs
Run Code Online (Sandbox Code Playgroud)
在 gs2hs 目录中。
这有一个问题,每次我按顺序进行两个构建时,GHC 都会重新编译 libgs 目录中的每个模块以及 gsi 目录中的每个共享模块,告诉我“标志已更改”。
我想,好吧,我可能应该在 Haskell 中使用包来重用代码,对吗?所以我将 libgs 转换为包:
cabal install --lib --package-env $REPO_ROOT/package.env …我正在尝试编写一个 Functor 实例:
\nmodule TreeN where\n\ndata TreeN a = LeafN a | ParentN a [TreeN a] deriving (Eq, Show)\n\ninstance Functor TreeN where\n\nfmap f (LeafN x) = LeafN (f x)\nfmap f (ParentN x children) = (ParentN (f x) (TreeN.fmap f children))\n\nRun Code Online (Sandbox Code Playgroud)\n我收到此错误:
\nsrc/TreeN.hs:7:1: error:\n \xe2\x80\xa2 Couldn't match type \xe2\x80\x98TreeN t\xe2\x80\x99 with \xe2\x80\x98[TreeN t]\xe2\x80\x99\n Expected type: (t -> a) -> [TreeN t] -> [TreeN a]\n Actual type: (t -> a) -> TreeN t -> TreeN a\n \xe2\x80\xa2 Relevant bindings …Run Code Online (Sandbox Code Playgroud) Haskell 中 IO (a) 和 IO a 有什么区别?
例如:
IO (String)与IO String
IO (Int)与IO Int
我见过的大多数书籍都将类型放在括号中,然后将其放在 IO 之后,但对我来说,它们是否是同一件事并不明显。
我正在使用 Replit 网站使用 GHC 运行 Haskell 程序。我在编辑器中输入代码并使用“运行”按钮运行它,而不仅仅是使用 GHCi 运行代码行。getLine每当我使用该函数时,即使在极其简单的程序中,我也会遇到奇怪的输出问题。例如,运行程序
main = do ans <- getLine
putStrLn ans
Run Code Online (Sandbox Code Playgroud)
hi在输入提示处键入会打印hi两次而不是一次:
cabal v1-run
Preprocessing executable 'Cabal-example' for Cabal-example-0.1.0.0..
Building executable 'Cabal-example' for Cabal-example-0.1.0.0..
[1 of 1] Compiling Main ( Main.hs, dist/build/Cabal-example/Cabal-example-tmp/Main.o )
Linking dist/build/Cabal-example/Cabal-example ...
Running Cabal-example...
hi
hi
hi
Run Code Online (Sandbox Code Playgroud)
当我尝试禁用函数中的输入/输出缓冲时,问题变得更加奇怪main(我需要为我正在开发的更大的程序执行此操作):
cabal v1-run
Preprocessing executable 'Cabal-example' for Cabal-example-0.1.0.0..
Building executable 'Cabal-example' for Cabal-example-0.1.0.0..
[1 of 1] Compiling Main ( Main.hs, dist/build/Cabal-example/Cabal-example-tmp/Main.o )
Linking dist/build/Cabal-example/Cabal-example ...
Running …Run Code Online (Sandbox Code Playgroud) 抱歉,如果这是一个常见问题,我找不到类似的问题,但我可能太缺乏经验,不知道正确的词汇。
以下是 GHCi 中基本问题的示例:
-- foo is something relatively expensive to compute, but it's lazy so it's instantaneous
*Main> foo = (foldl (++) [] (take 5000 $ repeat [10, 123, 323, 33, 11, 345, 23, 33, 23, 11, 987]))
(0.00 secs, 62,800 bytes)
-- bar is a result that uses foo, but it's also lazy so it's not computed yet
*Main> bar = last foo
(0.00 secs, 62,800 bytes)
-- Now let's use bar
*Main> bar
987
(1.82 secs, 11,343,660,560 …Run Code Online (Sandbox Code Playgroud) 有一次我问为什么简单的“times 2”程序的 Haskell 二进制文件这么大(例如 C++)?,但这被欺骗了用 GHC 编译成巨大的二进制文件的小型 Haskell 程序。
\n我决定问一个类似的问题,但重点是代码的实际作用,因此是它的汇编形式,而不是二进制文件。我还没有找到我的问题的现有答案。
\n所以不,这不能回答我的问题。
\n这是 C++(实际上是 C)的哑程序,它假设给出了 1 个表示数字的命令行参数,将其转换为 anint并将return其乘以 2 作为可执行文件的退出代码(是的,我可以\不超过 255)
int main(int argc, char * argv[]) {\n int r{0};\n int c{0};\n while (argv[1][c] != \'\\0\') {\n r *= 10;\n r += argv[1][c++] - \'0\';\n }\n return r*2;\n}\nRun Code Online (Sandbox Code Playgroud)\n\nmain: # @main\n mov rcx, qword ptr [rsi + 8]\n movzx …Run Code Online (Sandbox Code Playgroud) 我有一个 Haskell 程序,主要有两行代码:
putStrLn $ "Day11: part1: " ++ show (sum $ bigManhattan 1 galaxies <$> pairs)
putStrLn $ "Day11: part2: " ++ show (sum $ bigManhattan 999999 galaxies <$> pairs)
Run Code Online (Sandbox Code Playgroud)
如果我注释掉其中任何一个,程序将在 0.01 秒内运行。由于两者都存在,该程序需要 90 秒的时间。
我想知道有人有什么想法吗?他们是否会竞争查看数据并互相妨碍?
编译器选项 - 我不知道其中大多数是做什么的......
ghc-options:
- -Wall
- -Wcompat
- -Widentities
- -Wincomplete-record-updates
- -Wincomplete-uni-patterns
- -Wmissing-export-lists
- -Wmissing-home-modules
- -Wpartial-fields
- -Wredundant-constraints
- -O2
Run Code Online (Sandbox Code Playgroud)
代码:
module Day11(day11) where
import Data.List ((\\))
import Data.Maybe (catMaybes)
type Coord = (Int, Int)
manhattan :: …Run Code Online (Sandbox Code Playgroud) 我正在研究第二个Euler的问题,但是现在我只是试图定义Fibonacci序列.目前,我将我的Fib功能定义为
Fib 0 = 0
Fib 1 = 1
Fib x = Fib (x - 1) + Fib (x - 2)
Run Code Online (Sandbox Code Playgroud)
因为我希望程序依赖于我的键盘输入,所以我使用了
main = do
putStrLn "Enter desired Fibonacci index: "
"index" <- getLine
putStrLn Fib x
Run Code Online (Sandbox Code Playgroud)
并将x定义为 x = read "index"
我很确定我弄乱了缩进和语法.根据我修改代码的方式,运行"ghc /dir/file.hs会让我感觉不到"不在范围内:数据构造函数`Fib'"或"解析错误(可能是错误的缩进)".我真的,真的不喜欢我知道我在做什么,特别是关于如何设置.hs以便编译友好.我已经阅读了大约7个关于使用GHC进行编译的教程,但他们似乎都跳过他们解释的部分编译的基本要求.
如果有帮助,请告诉我如何更具体.我认为我试图理解的两件事是整个"主要"事物是如何与编译相关的,以及如何让它被识别我已经将Fib定义为函数,即使它说它不在范围内.
PS:我无法弄清楚这里的缩进,Stack似乎想把所有东西放在一行,所以我必须把它全部分开.抱歉.
我如何在Haskell中使用列表推导中的任意输入集?
我会举一个例子说明我所追求的:
generate :: [[[Integer]]] -> [[[Integer]]]
generate a = [ result |
i1 <- a !! 0,
i2 <- a !! 1,
i3 <- a !! 2,
i4 <- a !! 3,
...
i99 <- a !! 99,
let result = [i1,i2,i3,i4, ..., i99],
isCorrect result
]
Run Code Online (Sandbox Code Playgroud) ghc ×10
haskell ×10
cabal ×2
assembly ×1
c ×1
compilation ×1
functor ×1
gcc ×1
ghci ×1
io ×1
parsing ×1
performance ×1
replit ×1
strictness ×1
type-theory ×1