ä»ã®ã¨ããæ¯è¼çç°¡åãªã¢ããã®ä½ãæ¹
æºå
ã¢ãããä½ãã«ã¯ãã©ããªã¢ãããä½ããããèãããã¢ããã¯ä¸è¬ã«ãã©ã®ãããªã¢ã¯ã·ã§ã³ã使ãããã«ãã£ã¦ç¹å¾´ä»ããããããã®ç¹ã§ã¯ãªãã¸ã§ã¯ãæåã«ãããã¤ã³ã¿ã¼ãã§ã¤ã¹ã¨ããä¼¼ã¦ããã
ã§ã¯ãfoo :: String -> M Bool
ã¨bar :: M Int
ã¨ããäºç¨®é¡ã®ã¢ã¯ã·ã§ã³ãæã¤ã¢ãããä½ãã¨ããããã¾ããã©ããªã¢ã¯ã·ã§ã³ã使ãããã表ããã¼ã¿åãå®ç¾©ããã
{-# LANGUAGE GADTs #-} data MBase x where Foo :: String -> MBase Bool Bar :: MBase Int
GADT(ä¸è¬å代æ°çãã¼ã¿å)ã®åãã¼ã¿ã³ã³ã¹ãã©ã¯ã¿ãã¢ã¯ã·ã§ã³ã«å¯¾å¿ãããGADTsã使ã£ããã¨ããªãã¦ãå¿é ãã¦ã¯ãããªãã弿°ã®åã¨çµæã®åã«çç®ãããã
ã¢ããã«ãã
monad-skeletonãã¤ã³ã¹ãã¼ã«ããã
$ stack install monad-skeleton
ã¢ã¸ã¥ã¼ã«ãã¤ã³ãã¼ãããå
ã»ã©ã®MBaseã使ããMãå®ç¾©ãããbone :: t a -> Skeleton t a
ã§MBase
ã®å¤ãM
ã®å¤ã«ããã
{-# LANGUAGE GADTs #-} import Control.Monad.Skeleton data MBase x where Foo :: String -> MBase Bool Bar :: MBase Int type M = Skeleton MBase foo = bone . Foo bar = bone Bar
Mã¯ãããã¢ããã«ãªã£ã¦ãããæåæãããã»ã©ç°¡åã ã
:t bar >>= foo . show bar >>= foo . show :: Skeleton MBase Bool
ã¢ããã使ã
ä½ã£ã¦ã使ããªããã°æå³ããªã -- 誰ã
ã¢ã¯ã·ã§ã³ã«debone :: Skeleton t a -> MonadView t (Skeleton t) a
ãé©ç¨ããã¨ãMonadViewã¨ãããã¼ã¿åã®å¤ãå¾ãããã
data MonadView t m x where Return :: a -> MonadView t m a (:>>=) :: t a -> (a -> m b) -> MonadView t m b
Return a
ã¯ãã®ã¢ã¯ã·ã§ã³ãå®è³ªçã«return a
ã§ãããã¨ãt :>>= k
ã¯æåã«å®è¡ãã¹ãã¢ã¯ã·ã§ã³ãt
ã§ãããã¨ãæå³ãããk
ã«t
ã®çµæã渡ãã¨ããã®æ¬¡ã«å®è¡ãã¹ãã¢ã¯ã·ã§ã³ãå¾ãããããããã使ãã¨ãMãå®éã«è§£éãã颿°ãå®ç¾©ã§ãããããã§ã¯ãfoo
ããä¸ããããæååã®é·ããããå¤ããçããå¤å®ããããbar
ããå¤å®åºæºãè¿ãããã®ã¨ãã¦å®ç¾©ãã¦ããããåããåãã°å®éã¯ãªãã§ããããä¸ã¤ã®M
ã«å¯¾ãã¦è¤æ°ã®è§£éãä¸ãããã¨ããå¯è½ã ã
runM :: Int -> M a -> a runM n m = case debone m of Foo str :>>= k -> runM n $ k $ length str <= n Bar :>>= k -> runM n $ k n Return a -> a
monad-skeletonã¯DSL(ãã¡ã¤ã³ç¹åè¨èª)ãä½ãã®ã«é©ãã¦ãããä½ãããç°¡åã«ä½¿ããã®ã売ããªã®ã§ãåå¿è ã«ãããããã ã
runMã®ãããªãã¢ãããè§£éãã颿°ãã«å é¨ç¶æ ãæãããããã便å©ãªã®ã«ãã¨æã人ããããããããªããå®ã¯ããã«ãæ¢ã«è§£æ±ºæ³ãããã®ã§ãæ¬¡ã®æ©ä¼ã«ç´¹ä»ãããã