(a) 일부 IO를 수행하고, (b) 찾아보기 테이블을 구성하며, (c) 찾아보기 테이블을 사용하는 IO 작업을 반환하는 절차가 있습니다. 그러나 -O
으로 컴파일하면 GHC (버전 6.12.1)가 룩업 테이블 구성을 인라인하기 때문에 IO 작업 호출마다 다시 평가됩니다.IO 작업에서 순수 표현의 반복적 인 평가
예 :
module Main where
import Data.Array
import Data.IORef
import Control.Monad
makeAction getX getY sumRef = do
x <- getX
let a = listArray (0, 1000) [x ..]
return $ do
y <- getY
modifyIORef sumRef (\sum -> sum + a ! y)
main = do
sumRef <- newIORef 0
action <- makeAction getX getY sumRef
replicateM_ 100000 action
n <- readIORef sumRef
putStrLn (show n)
where
getX = return (1 :: Int)
getY = return 0
이 문제는 표준 GHC-절대 안전한 해결 방법을 가질 정도로 잘 알려진 - 또는 반복적으로 할당되지 않는 a
있도록 어떻게이 프로그램을 조정할 것인가?
'{- # NOINLINE # -}'플러그 -를 시도 했습니까? – fuz
@FUZxxl 예,'{- # NOINLINE a # -}'는 로컬'a'에서 그것을하지 않습니다. – antonakos
룩업 테이블을 원하고 반복 된 액션들 사이에서 공유하고 싶다면 분명히 @ makeAction @ 함수에서 그것을 생성해야합니다. makeAction은 인라이닝에 관계없이 매번 배열을 만들 것 같습니다. 어쩌면 당신은 makeAction 기능에서 벗어난 IOArray를 사용해야 할 것입니다. –