ããã¨ãã®åãããããçãä¸ãã£ã¦ããï¼ï¼ï¼ããªããç¹ã«先日入れたツッコミ以éãã²ãããªã®éåã®åã¨ããã¨ãã®åã®å¯¾å¿ãèãã¦ã¦ãµã¨ãããã¢ããã«ãªãããããï¼ãã¨æãç«ã¡ã¾ããã
以ä¸åèï¼
ã¨ãããã¨ã§ãããããã«Haskellã§æ¸ãã¦ã¿ãâ¦ãã©ãçµæ§ææããé ã®ä¸ã§ã¯åè«ããã¯ã«ç´°ããã¨ããã§ããããèãã¦ãããããã§ãããã³ã¼ãããã¾ãã«ã大éæã§ã詳細ãªå
容ã対å¿ããªãã®ã§ã説æãã¾ããï¼ãã¼
ã¨ãããããä½ã£ã¦åããã¦ã¿ãããã£ã¦ãã¨ã§ã
â» æéã«è¿½ããã¦å¤å°æ¸ããªãã£ãã®ã§ãèªã¿ã«ããã£ããããã¾ãããæ¥æ¬èªã¯å¾ã§ã¡ããã¡ããä¿®æ£ããããã
å®è¡ä¾
å®è£ ã®ä¸èº«ã¯ãã¨ã¾ããã«ãã¦ãã¾ãã¯å®è¡ä¾ã
ããã¨ãã®åã§ããã¨ããã«å° ããããããããããããããã«ç¸å½ããé¢æ° aa, ai, iuãã¢ããã£ãã¯ã«å®ç¾©ãã¾ããæ¥æ¬èªä½¿ãã®ããã©ãããã£ããã§ããã¼ãåã§ä»£ç¨ã§ãããã¨ãæ»ãå¤ã¯ããå°»ã®æåã¨ãé¢æ°ãæã¤æååã®ãã¢ãè¿ãããã«ãªã£ã¦ã¾ãã
aa, ai, iu :: Char -> Shiritori Char aa 'a' = Writer ('a', Srtr "aa") aa _ = sError ai 'a' = Writer ('i', Srtr "ai") ai _ = sError iu 'i' = Writer ('u', Srtr "iu") iu _ = sError
ãããã®é¢æ°ããåæãããã¨ãããã¨ãã«ãªãã¾ãã
Main> display $ unit 'a' "a" *Main> display $ unit 'a' >>= ai "ai" *Main> display $ unit 'a' >>= ai >>= iu "aiu" *Main> display $ unit 'a' >>= aa >>= ai >>= iu "aaiu"
unitã¯ãã®åã®éããã¢ããã®ãåä½ãã§ããããã¨ãã®åã§ã®æçå°ã«ç¸å½ãããã®ãä½ãã¾ããHaskellã§ã¯ãæ¬å½ã¯ããã«ç¸å½ããreturnã£ã¦é¢æ°ããããã§ããã©ãé½åæªãã®ã§ä»åã¯ä½¿ã£ã¦ã¾ããï¼ããã¼
ä¸ã®ï¼ã¤ãã¨ï¼ã¤ãã®å®è¡ä¾ãããããã代æ°ã¹ã¿ã¤ã«ï¼ã§ããã®ããªï¼ï¼ã«æ¸ãç´ãã¨ããããªæãã§ã
Main> display $ unit ... (fmap ai) ... join $ 'a' "ai" *Main> display $ unit ... (fmap ai) ... (fmap (fmap iu)) ... join ... join $ 'a' "aiu" *Main> display $ unit ... (fmap ai) ... join ... (fmap iu) ... join $ 'a' "aiu"
ä¸2ã¤ã®å®è¡çµæã¯åãã«ãªãã¾ãã
ããã§ã使ã£ã¦ãåé¢æ°ã®èª¬æããã®ã¢ããã <T, η, μ> ã¨ããã¨ããηï¼unit, μï¼joinï¼Haskellã®æ¨æºé¢æ°ï¼ ã«ç¸å½ã(...) ã¯ç§ãããããé¢æ°ã®åæã§ãf...g 㯠f ãã£ã¦ gã
æ¬å½ã¯f;g ã£ã¦æ¸ãããã£ããã©ãã»ãã³ãã³ä½¿ããªãã£ããã§ã
fmapã¯Haskellã®æ¨æºé¢æ°ã§ãã¢ãããä¸åä¸ä¹ãããä½ç¨ãããã¾ããf: X â TY, g: Y â TZ ãªãf, gããã£ãã¨ãã¦ãfã¨gããåæããããããã«ãTg : TY â T(TZ)ã¨ãã¦ãf;Tg: X â T(TZ) ã¨ãã¡ããã®ã§ãããã®ãg ã«å¯¾ã㦠Tg ãä½ãå¹æãfmapã¯æä¾ãã¦ã¾ãã
â» æ¬å½ã¯fmapãããªãã¦ãã¢ããç¨ã«liftMã£ã¦é¢æ°ããããã§ããã©ãé½åæªããã§ä»åã¯ä½¿ã£ã¦ã¾ããï¼ãããã¼
ãã§ãã£ã¦ãä¸ä¹ãããã¦ï¼éã«ãªã£ãã¢ãããï¼åã«ã¾ã¨ãã¡ãããã¨ãã§ããã®ããjoinãªã®ã§ãã
ãã®è¾ºã®è©±ã¯ãåã§è¦ãã¨ããããããããã§ãã
Main> :t unit unit :: Char -> Shiritori Char *Main> :t unit ... (fmap ai) unit ... (fmap ai) :: Char -> Writer SString (Shiritori Char)
<T, η, μ> ã§ãã T ï¼ Shiritori ã§ããã»ã¼ã
ãã¨å®è£
ã³ã¼ãè¦ãã°ãããã¾ãããWriter SString ï¼ Shiritori ã§ããããã«æ³¨æããã¨ã unit ... (fmap ai) ã®åã¯
Char -> Shiritori (Shiritori Char)
ã¨ãªãã¾ãã
ã§ãããã®å¾ã« join ãåæããã¨ï¼
Main> :t unit ... (fmap ai) ... join unit ... (fmap ai) ... join :: Char -> Writer SString Char
åã Char -> Shiritori Char ã«ãªã£ã¦ãã®ããããã¾ããèªç¶å¤æμã®å¹æã
ã§ã以ä¸ã®ï¼ã¤ã¯åãçµæã«ãªãã¾ãã
Main> :t unit ... (fmap ai) ... (fmap (fmap iu)) ... join ... join unit ... (fmap ai) ... (fmap (fmap iu)) ... join ... join :: Char -> Writer SString Char *Main> :t unit ... (fmap ai) ... join ... (fmap iu) ... join unit ... (fmap ai) ... join ... (fmap iu) ... join :: Char -> Writer SString Char
å®è£
ä¸ã§ãæ¸ãã¾ããããå®è£
ã¯çµæ§ææãã
Haskellã®æ¨æºã¢ããã§ããWriterã¢ããã使ã£ã¦ã¾ãã
import Control.Monad.Writer -- ããã¨ãæåå newtype SString = Srtr String instance Show SString where show (Srtr s) = s -- ããã¨ãæååã¯ã¢ãã¤ã instance Monoid SString where -- åä½å ï¼ä»åã¯ä½¿ããªãã®ã§ãæªå®ç¾©ï¼ mempty = undefined -- æååä¸ã®ã¢ãã¤ãæ¼ç®åï¼ããã¨ãï¼ã¡ãã£ã¨ææãï¼ mappend (Srtr xs) (Srtr ys) = Srtr $ mappend xs $ drop 1 ys -- ããã¨ãã¢ãã ãWriterã¢ããã使ã£ã¦å®ç¾© type Shiritori = Writer SString unit :: Char -> Shiritori Char unit = \x -> Writer (x, Srtr [x]) -- ã¢ããã£ãã¯ãªé¢æ° ãããããããããããããã aa, ai, iu :: Char -> Shiritori Char aa 'a' = Writer ('a', Srtr "aa") aa _ = sError ai 'a' = Writer ('i', Srtr "ai") ai _ = sError iu 'i' = Writer ('u', Srtr "iu") iu _ = sError -- utilities sError = error "Shiritori failure." (...) :: (a -> b) -> (b -> c) -> a -> c f ... g = g . f display :: Shiritori Char -> String display m = let (a, w) = runWriter m in show w