私はWriterTとState(それはadvent of code day 15です)を使ってHaskellの練習問題を解決しようとしている概念を理解しようとしています。何らかの理由で、私はメモリの負荷を使用して終了し、私のノートブック(ちょうど4Gラム)が停止に終わることを理解していない。WriterT Stateになぜメモリが必要なのですか?
私の最初のアイデアは、厳密さを使い、周りに振りかけることでしたが、問題は解決しません。
誰かが私がどこに間違っていたのか説明できますか?ここで
は、コードをクリーンアップしています:
{-# LANGUAGE BangPatterns #-}
module Main where
import Control.Monad.State.Strict
import Control.Monad.Writer.Strict
main = do
let generators = (Generator 65 16807, Generator 8921 48271)
res1 = compute generators (4*10^7)
putStrLn "Answer 1"
print res1
data Generator = Generator { _value :: Int
, _factor :: Int
}
deriving Show
newtype Value = Value Int
deriving (Show, Eq)
newtype Counter = Counter Int
deriving (Show, Eq)
instance Monoid Counter where
mempty = Counter 0
mappend (Counter !a) (Counter !b) = Counter (a+b)
generate :: Generator -> (Value, Generator)
generate (Generator v f) = (Value newval, Generator newval f)
where newval = (v * f) `mod` 2147483647
agree (Value a) (Value b) = (a `mod` mf) == (b `mod` mf)
where mf = 2^16
oneComp :: State (Generator, Generator) Bool
oneComp = do
(!ga, !gb) <- get
let (va, gan) = generate ga
(vb, gbn) = generate gb
!ag = agree va vb
put (gan, gbn)
pure ag
counterStep :: WriterT Counter (State (Generator, Generator))()
counterStep = do
!ag <- lift oneComp
when ag $ tell (Counter 1)
afterN :: Int -> WriterT Counter (State (Generator, Generator))()
afterN n = replicateM_ n counterStep
compute s0 n = evalState (execWriterT (afterN n)) s0
私はスタックでそれをコンパイルします。徒党ファイルのエントリは次のとおりです。
executable day15
hs-source-dirs: app
main-is: day15.hs
ghc-options: -threaded -rtsopts -with-rtsopts=-N
build-depends: base
, advent
, hspec
, mtl
default-language: Haskell2010
更新
私はもう少し時間があったし、発電機は厳密にする提案を行いました。しかし、まだ何かがあまりにも多くのメモリを使用しています。
これは私が関連しているかもしれないと思うprofファイルの部分です。
Fri Dec 15 16:28 2017 Time and Allocation Profiling Report (Final)
day15 +RTS -N -p -RTS
total time = 71.66 secs (71662 ticks @ 1000 us, 1 processor)
total alloc = 17,600,423,088 bytes (excludes profiling overheads)
COST CENTRE MODULE SRC %time %alloc
afterN Main app/day15.hs:79:1-36 41.1 20.0
mappend Main app/day15.hs:51:3-51 31.0 3.6
oneComp Main app/day15.hs:(64,1)-(71,9) 9.2 49.1
generate.(...) Main app/day15.hs:55:9-42 8.5 14.5
学習するために明示的に 'WriterT'と' State'を使用しているのであれば意味がありますが、その特定のパズルは 'unfoldr'と' zip'で解決できます。 FWIW、ここに私の解決策があります:https://github.com/ploeh/advent-of-code-2017/blob/master/Day15/Solution.hs –
私がそれ以上のことを知らなかったら、作者のモナドに関するものではなく、 '生成する'ものである。しかし、本当に、私はあなたが実際にスペースを取っている場所を見つけるために実際にプロファイルする必要があると思います。 – MathematicalOrchid
@MathematicalOrchidあなたは正しいことが重く表示されます。それを軽くするための提案はありますか? – bdecaf