-2
私は州のモナドとキューで遊んでいます。現時点では私は、次のコードを持っている:State Monad Loopを終了
{-# LANGUAGE ViewPatterns, FlexibleContexts #-}
module Main where
import Criterion.Main
import Control.Monad.State.Lazy
import Data.Maybe (fromJust)
import Data.Sequence ((<|), ViewR ((:>)))
import qualified Data.Sequence as S
--------------------------------------------------------
data Queue a = Queue { enqueue :: [a], dequeue :: [a] }
deriving (Eq, Show)
-- adds an item
push :: a -> Queue a -> Queue a
push a q = Queue (a:enqueue q) (dequeue q)
pop :: Queue a -> Maybe (a, Queue a)
pop q = if null (dequeue q) then
go $ Queue [] (reverse (enqueue q))
else
go q
where go (Queue _ []) = Nothing
go (Queue en (x:de)) = Just (x, Queue en de)
queueTst :: Int -> Queue Int -> Queue Int
queueTst 0 q = q
queueTst n q | even n = queueTst (n - 1) (push (100 + n) q)
| otherwise = queueTst (n - 1)
(if popped == Nothing then q
else snd (fromJust popped))
where popped = pop q
-------------------------------------------------------------
pushS :: a -> S.Seq a -> S.Seq a
pushS a s = a <| s
pushS' :: a -> State (S.Seq a) (Maybe a)
pushS' a = do
s <- get
put (a <| s)
return Nothing
pushS'' :: a -> State (S.Seq a) (Maybe a)
pushS'' a = get >>= (\g -> put (a <| g)) >> return Nothing
popS :: S.Seq a -> Maybe (a, S.Seq a)
popS (S.viewr -> S.EmptyR) = Nothing
popS (S.viewr -> s:>r) = Just (r,s)
popS' :: State (S.Seq a) (Maybe a)
popS' = do
se <- get
let sl = popS'' se
put $ snd sl
return $ fst sl
where popS'' (S.viewr -> S.EmptyR) = (Nothing, S.empty)
popS'' (S.viewr -> beg:>r) = (Just r, beg)
queueTstS :: Int -> S.Seq Int -> S.Seq Int
queueTstS 0 s = s
queueTstS n s | even n = queueTstS (n - 1) (pushS (100 + n) s)
| otherwise = queueTstS (n - 1)
(if popped == Nothing then s
else snd (fromJust popped))
where popped = popS s
queueTstST :: Int -> State (S.Seq Int) (Maybe Int)
queueTstST n =
if (n > 0) then
if even n then
pushS' (100 + n) >> queueTstST (n - 1)
else
popS' >> queueTstST (n - 1)
else return Nothing
main :: IO()
main = defaultMain
[ bench "Twin Queue" $ whnf (queueTst 550) (Queue [500,499..1] [])
, bench "Sequence Queue" $ whnf (queueTstS 550) (S.fromList [500,499..1])
, bench "State Queue" $ whnf
(runState (queueTstST 550)) (S.fromList [500,499..1])
]
コードのビットですが、本当にここに関連する唯一の機能はmain
とqueueTstST
していること。 queueTstST
を終了する方法はありますが、最後の "Maybe value"を "Nothing"ではなく保持していますか?
これは本当に正解ではありません。 2番目の最後のループがpushS 'だった場合、正解は 'Nothing'になるためです。それがpopS 'ならば、その特定のpopSの 'Just'値であり、これは後続のpopSではありません。 – user1897830
はい - あなたの権利。しかし、最後のループからの値を使ってループを終了する方法があるかどうかは疑問でした。あなたが天気を知らなかった場合、2番目の最後のループはオッズであった。 – user1897830
しかし、もともと、2番目の最後のループは常にpopS 'なので、n = 1であり、ここでは、n = 1ループからの値を返します。 – Gurkenglas