私はMaybe-Stateモナドトランスを実装しようとしており、それを使って単純なスタックマシンを実装しています。 状態モナドの定義は多分正しいはずです。スタックが空の場合、それはそれ以外の場合は、Just <popped stack>
を返し、何も返さないようにするためMonadトランス:MaybeT(State Stack)を使用したスタックマシンの実装
pop :: MaybeT (State Stack) Int
:今、私はポップを実装しようとしています。 これは私がこれまで持っているものです。
pop :: MaybeT (State Stack) Int
pop = guard True (do (r:rs) <- get
put rs
return r)
(もちろんTrue
は単なるダミーのプレースホルダです - 今、私は右の他の部分を取得したいために、私は、後で条件を実装します)。
私のコードで何が問題になっていますか?私の理解から、guard
は条件付き(True
)と関数fをとります。条件が成立する場合は、pure f
となります。私の場合は
、
pure = MaybeT . return . Just
は、だから私の関数fはちょうどState Stack Int
を返すべきではないのですか?
はここMaybeT
とState
の私の実装では、完全なコードです:あなたのスタックが空の場合、すべての
import Control.Applicative (Alternative(..))
import Control.Monad (liftM, ap, guard)
import Control.Monad.Trans.Class (MonadTrans(lift))
main :: IO()
main = return()
-- State Monad
--------------
newtype State s a = MakeState { runState :: s -> (a, s) }
instance Functor (State s) where
fmap = liftM
instance Applicative (State s) where
pure a = MakeState $ \s -> (a, s)
(<*>) = ap
instance Monad (State s) where
return a = MakeState $ \s -> (a, s)
m >>= k = MakeState $ \s -> let (x, s') = runState m s
in runState (k x) s'
get :: State s s
get = MakeState $ \s -> (s, s)
put :: s -> State s()
put s = MakeState $ \_ -> ((), s)
modify :: (s -> s) -> State s()
modify f = MakeState $ \s -> ((), f s)
-- MaybeT MonadTransformer
---------------------------
newtype MaybeT m a = MaybeT { runMaybeT :: m (Maybe a) }
instance Monad m => Functor (MaybeT m) where
fmap a x = MaybeT $ do e <- runMaybeT x
return $ fmap a e
instance Monad m => Applicative (MaybeT m) where
pure = MaybeT . return . Just
(<*>) a b = MaybeT $ do e <- runMaybeT a
f <- runMaybeT b
return $ e <*> f
instance Monad m => Monad (MaybeT m) where
return = pure
a >>= b = MaybeT $ do aa <- runMaybeT a
maybe (return Nothing) (runMaybeT . b) aa
instance Monad m => Alternative (MaybeT m) where
empty = MaybeT $ return Nothing
a <|> b = MaybeT $ do aa <- runMaybeT a
bb <- runMaybeT b
return $ aa <|> bb
instance MonadTrans MaybeT where
-- "herwrappen" van het argument
lift x = MaybeT $ do r <- x
return $ Just r
-- Stack Manipulation
---------------------
type Stack = [Int]
-- plaats het argument bovenop de stack
push :: Int -> State Stack()
push x = do r <- get
put (x:r)
-- geef de grootte van de stack terug
size :: State Stack Int
size = do r <- get
return $ length r
-- neem het eerste element van de stack, als het aanwezig is
-- (hint: hoogle naar `guard`)
pop :: MaybeT (State Stack) Int
pop = guard (True) (do (r:rs) <- get
put rs
return r)
エラーは何ですか? 'guard'は' MaybeT(State Stack)Int'を必要とする間に 'MaybeT(State Stack)()'を返します。 – Lee