我對一個編程問題的兩個提交僅在一個運算式中有所不同(其中anchors是一個非空串列并且(getIntegrals n)是一個狀態 monad):

沒有行內:

在這里,我們兩次查看對應的內容,第一個實體是行內部分,第二個實體是對replicateM 的實際呼叫。
readRest = replicateM (length anchors - 1) (getIntegrals n)
現在有趣的一點是,在行內代碼中,黃色突出顯示的行在 的每個回圈中運行replicateM,而在非行內部分,它們在傳遞給 的 lambda 抽象之外計算一次replicateM。
但他們在做什么?ds核心中呼叫了多個變數,但是這個是指這個:

這又對應于
solve = do
n <- getIntegral
所以我認為正在發生的是,它不是運行getIntegral一次并保存結果,而是保存了它的起始狀態,并且在回圈的每一次通過時都以這種狀態重新運行。確實將這一行更改為以下內容(需要 BangPatterns 語言擴展)修復所有版本(提交)。
solve = do
!n <- getIntegral
我仍然不確定,但這是我最好的猜測。
Here are the two core dumps for reference: Inline, Noinline
This is crazy
Well yes, but I feel that the underlying problem here is your use of lazy IO and lazy State. Using the strict State transformer Haskell probably would have figured out to not keep old state around (I have no idea, just a guess), however we can not use strict State here, because of your reliance on lazy IO, i.e. getting all the input at the beginning using getContents and lazyly forcing it while making sure to provide output before forcing too much. Instead it would be a lot safer to explicitely read the input line by line. I.e. replace the StateT [ByteString] with IO or something more fancy like a Conduit or Pipe.
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/355869.html
