Created
December 9, 2013 09:52
-
-
Save mmitou/7869852 to your computer and use it in GitHub Desktop.
状態をQueueで管理するモナド
instance化する際に、型パラメータを使いたい場合には、FlexibleInstancesを使わなければならない。
instance化する際に、型シノニムを指定したい場合には、TypeSynonymInstancesを使わなければならない。
型シノニムに型パラメータを持たせて宣言した場合に、型シノニムを型として使う箇所では全てのパラメータを埋めなければならない。
例えば以下のように宣言した場合には、
type QueueT e m a = StateT [e] m a
このように
instance HogeClass e (QueueT e m a)
のようにQueueTには必ず3つパラメータを指定する必要がある。
パラメータを3つ指定するのが都合…
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| {-# LANGUAGE MultiParamTypeClasses #-} | |
| {-# LANGUAGE FunctionalDependencies #-} | |
| {-# LANGUAGE TypeSynonymInstances #-} | |
| {-# LANGUAGE FlexibleInstances #-} | |
| import Prelude hiding (head) | |
| import Control.Monad.Trans | |
| import Control.Monad.Trans.State | |
| type QueueT e m = StateT [e] m | |
| runQueueT = runStateT | |
| class Monad m => MonadQueue e m | m -> e where | |
| head :: m (Maybe e) | |
| push :: e -> m () | |
| pop :: m (Maybe e) | |
| instance Monad m => MonadQueue e (QueueT e m) where | |
| head = do | |
| q <- get | |
| case q of | |
| [] -> return Nothing | |
| (x:_) -> return $ Just x | |
| push e = modify (e:) | |
| pop = do | |
| h <- head | |
| case h of | |
| Nothing -> return Nothing | |
| x@(Just _) -> modify tail >> return x | |
| test :: (MonadIO m, Monad m) => QueueT String m String | |
| test = do | |
| push "hello" | |
| push "world" | |
| push "!" | |
| x <- pop | |
| liftIO $ putStrLn $ show x | |
| pop | |
| pop | |
| pop | |
| return "hello" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment