當我完全按照這個 Criterion 教程所說的開始做時,我得到一個錯誤。我究竟做錯了什么?教程錯了嗎?如果是這樣,有沒有地方可以讓我學習使用 Criterion 的正確方法?
具體來說,正如教程所說,我在命令列中運行了以下命令:
cabal update
cabal install -j --disable-tests criterion
這運行沒有錯誤。然后我完全復制了教程中的示例程式:
import Criterion.Main
-- The function we're benchmarking.
fib m | m < 0 = error "negative!"
| otherwise = go m
where
go 0 = 0
go 1 = 1
go n = go (n-1) go (n-2)
-- Our benchmark harness.
main = defaultMain [
bgroup "fib" [ bench "1" $ whnf fib 1
, bench "5" $ whnf fib 5
, bench "9" $ whnf fib 9
, bench "11" $ whnf fib 11
]
]
我將它放入一個名為 benchTest.hs 的檔案中,然后我使用命令列完全按照教程中的說明編譯程式,但使用 benchTest 代替了他們所說的 Fibber。具體來說,我在命令列中運行了以下內容:
ghc -O --make benchTest
這導致了這個錯誤:
benchTest.hs:1:1: error:
Could not load module `Criterion.Main'
It is a member of the hidden package `criterion-1.5.13.0'.
You can run `:set -package criterion' to expose it.
(Note: this unloads all the modules in the current scope.)
It is a member of the hidden package `criterion-1.5.13.0'.
You can run `:set -package criterion' to expose it.
(Note: this unloads all the modules in the current scope.)
Use -v (or `:set -v` in ghci) to see a list of the files searched for.
|
1 | import Criterion.Main
| ^^^^^^^^^^^^^^^^^^^^^
uj5u.com熱心網友回復:
陰謀集團進化史
縱觀其歷史,Cabal 的作業方式發生了巨大轉變,通常被稱為v1-命令與v2-命令;例如,從 Cabal 2 開始,您可以說cabal v1-install或cabal v2-install。當你說cabal install的只是取決于 Cabal 版本時會發生什么:
v1-install默認情況下,Cabal 2 將使用,而 Cabal 3 將使用v2-install. 默認值的變化反映了首選的操作模式。如此之多,v1已基本無人維護。我不希望它很快被洗掉,因為有一群老方法的堅定支持者。但我個人認為,首先,新的方式(有趣的事實,你可以使用cabal new-install作為同義詞)在技術上是優越的,其次,新手應該使用它,因為它有更好的檔案記錄,并且您可以更幸運地獲得幫助(在許多情況下,由于上述優勢,更容易獲得幫助)
為什么v1被v2(簡而言之)所包含
您可能遇到的主要問題v1是多個專案之間的依賴關系不兼容。想象一下,您從事的專案A依賴于X
version 的包,42同時您開始的專案B也依賴于Xversion 的包43。你猜怎么著:你不能v1-build在同一臺機器上的兩個專案不清除cabal其間的快取。這就是它在黑暗時代(從 2000 年代中期到 2010 年代)的運作方式。
在那之后,陰謀集團的沙盒到來了。它們允許您構建我們想象中的專案A,B并且不那么麻煩,但界面不是很好,更重要的是,每個沙箱都是獨立的,因此擁有大量重復的二進制檔案;例如A,并且B還可以依賴于Y相同的版本13,因此理論上不需要構建和存盤Y兩次,但這正是 cabal 沙箱所做的。
Cabalv2于 2010 年代后期到來,并帶來了確切的結果:通過稱為環境檔案的(也是最近的)GHC 功能隔離專案,并通過Cabal 存盤共享構建工件(這樣您就不會存盤同一事物的許多副本)。
環境和v2-install
您可以通過以下方式為每個專案( 、 等)創建一個單獨A的B環境
cabal v2-install --lib X-42 --package-env=.
在相應專案的目錄中。關于語法的幾個注釋:
v2-在 Cabal 3 中可以省略,因為它是默認設定;只要
install緊隨其后,標志的順序并不重要cabal;--lib很重要,因為默認情況下您只獲得可執行檔案(這就是發生的情況criterion:包包含可執行檔案);--package-env=.意思是:在當前目錄下創建一個 GHC 環境檔案(因此.)。如果命令成功,您會注意到當前目錄中有一個新的(在 Linux 上為“隱藏”)檔案,名為.ghc.environment.x86_64-linux-9.0.2. 這個檔案告訴這個目錄中所有對 GHC 的后續呼叫在哪里搜索由 Cabal 編譯并存盤在…… Cabal 存盤中的庫(在 Linux 上它是~/.cabal/store默認目錄)。原則上,您可以為環境使用非.值,如果該值不對應于路徑,它將是一個命名環境。Cabal 參考手冊中的更多詳細資訊……在實踐中,我發現 99.99% 的案例完全由--package-env=..X-42表示X版本的包42應該添加到新創建的環境中。你可以省略版本(你會得到“一些兼容的版本”),你可以列出多個包。
cabal v2-install --lib如果沒有指定環境意味著什么
它意味著環境default。有一個名為
default. 它有同樣的問題v1(見上文)。因此,在實踐中它可以作業,但它會非常脆弱,特別是如果您進入上述“專案A和專案B”的情況。即使您現在只處理一個專案,我也建議您使用,--package-env因為它是未來的證明。
為什么最初的錯誤
正如您所說,您使用的是 Cabal 2,因此v1-install最初看到了可怕的“隱藏包”錯誤——這是什么原因?老實說,我不知道。而且我懷疑如果不回滾到舊的陰謀集團版本并進行更多實驗,這很容易理解。正如我上面所說的,v1它不再真正被維護了,即使它看起來像 Cabal 中的一個錯誤(這完全有可能,尤其是在 Cabal 2 線的早期版本中),沒有人可能會為此煩惱。
舊教程不再起作用了,這不是很可悲嗎?
這是。不幸的是,軟體技術必須發展以使世界變得更美好(v2再次參見上面的原因)。有時這種開發必須打破向后兼容性。理想情況下,我們會去更新所有教育材料和手冊以反映變化,但這幾乎是不可能的。嘆。Haskell 的新用戶必須小心和創造性v1地v2轉換并嘗試盡早獲得基本的了解,v2并嘗試將其應用到仍然存在的好但舊的教程中。
環境是最好的方法嗎?
一些設計者和支持者v2認為環境檔案是一個過于微妙的功能。作為(“適當的”)替代方案,他們建議為您開始的每個專案創建一個成熟的 cabal 包。這相當于呼叫
cabal init,它將<project-name>.cabal在當前目錄中創建一個檔案,并維護該.cabal檔案,包括那里的包依賴項串列;您還將cabal v2-build用于構建專案(而不是直接呼叫 GHC)。
雖然更強大,但毫不奇怪,這個想法并沒有讓許多使用 Haskell 嘗試許多獨立的小東西的人睡得很好:每次都創建一個完整的“包”感覺很糟糕。好吧,實際上它只是一個額外的檔案,如果你將它與我上面描述的基于環境的方法進行比較,它甚至不是額外的,它也維護一個額外的檔案,但在這種情況下你不需要編輯它手(與
.cabal檔案不同)。總而言之,在“嘗試一件小事”的場景中,我發現基于環境的方法更適合我。但與基于包的方法相比,它確實有其局限性,特別是,很難弄清楚
如何在環境中獲取依賴項的分析版本。但這是另一天的故事……
您可以在Cabal issue中找到更多關于如何cabal v2-install --lib改進的討論。
如果你想遵循官方祝福的做事方式(即通過一個包),請花一點時間閱讀Cabal 手冊的入門部分——它非常清楚,并且準確地顯示了一個簡單應用程式的示例,它依賴于一個外部包。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/474329.html
