ã¢ããã¨ã¯ã¢ããã§ãã
ãã®è¨äºãèªãåã«ã絶対ã«çè§£åºæ¥ãªãã¢ãããã¥ã¼ããªã¢ã«ã«ä¸åº¦ç®ãéãã¦ã¿ã¦ã»ãããã¢ãããçè§£ãã¦ããä¸ã§ãã¨ã¦ãéè¦ãªãã¨ãæ¸ããã¦ããã
æ¹ãã¦è¨ãããã¢ããã¯ã¢ããã ãã³ã³ããã ã¨ãããã°ã©ããã«ã»ãã³ãã³ã ã¨ãã説æã§ã¯ãã¢ããã®ãã¹ã¦ãæ£ç¢ºã«è¡¨ããã¨ã¯è¨ãé£ããã§ã¯ãã¢ãããéä¸è¶³ãªã説æã§ãããã¢ãã以å¤ã®è¨èã¯ããã®ãï¼
å®ã¯ãã¢ããã表ç¾ãããã¤ã¢ããã§è¡¨ç¾ãããè¨èã¯åå¨ããããã®ä¸ã¤ã¯æç¶ãã§ãããæç¶ãåè¨èªã®ãæç¶ããã ã
æç¶ãã¨ã¯ä½ã
æç¶ãã¯çµæãæã¤
ãããããã¹ã¦ã®æç¶ãã¯ä½ããã®çµæãæã¤ãHaskellã®()ãCè¨èªã®voidãPythonã®NoneãRubyã®nilãªã©ãçµæã®ä¸ç¨®ã ãçµæãåºãªãã¨ãããããã®ããã°ã©ã ã¯åæ¢ããªãããéä¸ã§ç°å¸¸çµäºããã ããã
æç¶ãã«ã¯æå°åä½ãåå¨ãã
å¦çç³»ãæ±ã£ã¦ãã以ä¸ãæç¶ããééãªãåè§£ã§ããã¨ãããã¨ã¯ããå¾ãªããæ½è±¡çãªæèãªãããæåãåºåãããã®ãæå°åä½ã¨è¦ã¦ããã ããã
ãæç¶ãAãå®è¡ãã徿ç¶ãBãå®è¡ãããã¨ãã£ããã®ãæç¶ãã§ãã
å½ããåã ãã大äºãªæ§è³ªã ãããã«ãã£ã¦æç¶ããçµã¿åããã大ããªããã°ã©ã ãä½ããã¨ãã§ããã
ãä½ãããªããã®ãæç¶ãã§ãã
ä½ãããªãã¦ãæç¶ãã«ãªãããªããªãã¨è²ã ã¨å°ãããã ãããçµæãæã¤ãã¨ããæ§è³ªã¯æºãããªããã°ãªããªãã
ãã¦ãæç¶ãã®4ã¤ã®æ§è³ªã確èªãããã以ä¸ã®ãããªçåãæ®ãã
- ãAãå®è¡ããå¾Bãå®è¡ãããã¨ããAã®çµæã¯ã©ãã«è¡ãã®ï¼
å¤ãã®æç¶ãåè¨èªã§ã¯ä»£å ¥æ§æã使ã£ã¦æç¶ãã®çµæãä¿åãã¦ãããPythonãªããããªæãã ã
s = raw_input()
ããããçµæãå©ç¨ããããã ãã«å¤æ°ã®ä»çµã¿ãæã¡åºãã®ã¯ç¾ãããªããã夿°ãªãã¦ã©ã®è¨èªã§ãåãã¦ããã ããã¨æããããããªãããä»åã¯ããã§ã¯ãªãã®ã ãããã§ãã颿°ãã使ããã
- ãAãå®è¡ãããã®çµæãæç¶ããè¿ã颿°ã«æ¸¡ããããã¦ãè¿ã£ã¦ããæç¶ãBãå®è¡ãããã
è¦ããã«ããç¾å¨ã®ã¹ã³ã¼ãã«çµæããããã¨ããæ¡ä»¶ãæºããã°ããã
Haskellã§æç¶ãã表ç¾ãã
以ä¸ã®ç¹ãè¸ã¾ãã¦ãHaskellã§æç¶ãã表ç¾ããæ¹æ³ãèãã¦ã¿ããã
æç¶ãã¯ãçµæããæã¤ã
çµæã®åãaã¨ããã¨ãå°ãªãã¨ãæç¶ãã®åã¯T aã®ããã«ãªããåãªãå¤ã¨åºå¥ããªãã¨ä½ãæå³ããªãã
æç¶ãã«ã¯æå°åä½ãåå¨ãã
ã¨ããããã以ä¸ã®ãã®ãæå°åä½ã¨ãã¦ã¿ããã
Helloworld :: T () -- Hello, worldã表示ããã GetLine :: T String -- æååãå ¥åããã PutStrLn :: String -> T () -- æååã弿°ã«åãããã®æååã表示ããã¨ããæç¶ããè¿ãã
ã¡ãã£ã¨å¾ ã£ãï¼HelloworldãMyGetLineã¯ã³ã³ã¹ãã©ã¯ã¿ãªã®ã«(ã³ã³ã¹ãã©ã¯ã¿ã¯å¤§æåã§å§ã¾ã)ãèªç±ã«åãæå®ãããã¨ãã§ããã®ãï¼
ã§ããããããGADTãªãããGHCã®GADTsæ¡å¼µã使ãã¨ãã³ã³ã¹ãã©ã¯ã¿ã¨ãã®åãåæãã¦ä»£æ°çãã¼ã¿åãå®ç¾©ã§ããã
{-# LANGUAGE GADTs #-} data T x where Helloworld :: T () -- Hello, worldã表示ããã GetLine :: T String -- æååãå ¥åããã PutStrLn :: String -> T () -- æååã弿°ã«åãããã®æååã表示ããã¨ããæç¶ããè¿ãã
GADTã¯ã¨ã¦ã便å©ãªæ©è½ã ã以éã®æ§è³ªããGADTã使ã£ã¦è¡¨ç¾ãããã
ãAãå®è¡ãããã®çµæãæç¶ããè¿ã颿°ã«æ¸¡ããããã¦ãè¿ã£ã¦ããæç¶ãBãå®è¡ãããã
ãããå®ç¾ããã«ã¯ãæç¶ãAã¨ãçµæãåãåã颿°ãã³ã³ã¹ãã©ã¯ã¿ã®å¼æ°ã«å«ã¾ãã¦ããã°ããã
infixl 1 :>>= data T x where Helloworld :: T () GetLine :: T String PutStrLn :: String -> T () (:>>=) :: T r -> (r -> T a) -> T a
(:>>=)ã¨ããæ¼ç®åã¯ãªã«ãã«ä¼¼ã¦ããæ°ãããããä»ã¯èããªãã§ã»ããã
ãä½ãããªããã®ãæç¶ãã§ãã
ãã çµæãä¿æããã ãã®ã³ã³ã¹ãã©ã¯ã¿ã追å ããã
data T x where Helloworld :: T () GetLine :: T String PutStrLn :: String -> T () (:>>=) :: T r -> (r -> T a) -> T a Return :: a -> T a
ããã§ãæåãå ¥åºåããã¨ããæä½ãã§ãããæç¶ãã®æ çµã¿ãã§ãããã§ã¯ã使ã£ã¦ã¿ããã
Return 42 :: T Int -- 42ãè¿ã Helloworld :>>= \_ -> Return 42 -- Hello, world!ããå¾42ãè¿ã GetLine :>>= PutStrLn -- å ¥åããæååããã®ã¾ã¾è¿ã GetLine :>>= PutStrLn . reverse -- å ¥åããæååãé転ããã¦è¿ã
確ãã«è¡¨ç¾åã¯ãããå®ã¯ããããã¢ããã ã
æ£ä½
ã¢ããã¯ãä¸ã§å®ç¾©ãã4ã¤ã®æ§è³ªã®ãã¡ããçµæãæã¤ããåæã§ããããä½ãããªãããä¿è¨¼ãããæ§é ã ã
Haskellã®å¼·åãªä»çµã¿ã§ããåã¯ã©ã¹ã使ãã¨ããã®ããã«è¡¨ç¾ã§ããã
class Monad m where return :: a -> m a (>>=) :: m a -> (a -> m b) -> m b
ä¸ã§å®ç¾©ããTã¯ãç´æ¥Monadã®ã¤ã³ã¹ã¿ã³ã¹ã«ã§ããã
instance Monad T where return = Return (>>=) = (:>>=)
Monadã®ã¤ã³ã¹ã¿ã³ã¹ã«ããã¨ãããããåºã¦ããæ§ã ãªã¢ããããreturnã¨(>>=)ã¨ããäºã¤ã®é¢æ°ã§çµ±ä¸çã«æ±ãããããããdoè¨æ³ã¨ããHaskellã®é常ã«ä¾¿å©ãªæ©è½ã使ããããã«ãªãã
doè¨æ³ãç¨ããã¨ãããªããæç¶ãåè¨èªã®ããã«æç¶ããè¨è¿°ãããã¨ãã§ããããããdoèªä½ãæç¶ãåè¨èªã§ããã¨è¨ã£ãæ¹ãè¯ãã ããã
echoReversed = do s <- GetLine PutStrLn (reverse s)
ãã£ã¨æ§ã ãªæç¶ããæ¸ããããã°ãTã«æ°ããªã³ã³ã¹ãã©ã¯ã¿ã追å ããã°ãããã¢ããã¯ãå®ã¯ã¨ã¦ãç°¡åã«ä½ãããã®ãªã®ã ã
ãã£ã¨ç°¡åã«
(:>>=)ã¨Returnã¯ã¢ããã«å¿ ãå¿ è¦ãªããããã®é¨åã ããåãåºããæ§é ãä½ãã°ãããç°¡åã«ã¢ãããä½ãããã ã
data Program x where (:>>=) :: Program r -> (r -> Program a) -> Program a Return :: a -> Program a
ã¨ããããããã ãã ã¨æç¶ãã®æå°åä½ããªãããæå³ããªããæç¶ãã®æå°åä½ã®ããã®åãå¥ã«ä½ãããã«ãã¦ã¿ããã
data Program t x where Unit :: t a -> Program t a (:>>=) :: Program t r -> (r -> Program t a) -> Program t a Return :: a -> Program t a data MyActions x where Helloworld :: MyActions () GetLine :: MyActions String PutStrLn :: String -> MyActions () type T = Program MyActions x
ãããã¦å¾ãããTããã¯ãã¢ããã«ãªããæ©è½ãæ¡å¼µãããã¨ãã¯ãProgramãå¤ããã«ãMyActionsã夿´ããã°å¤§ä¸å¤«ã
ãã®ãããªãæ©è½ã®æå°åä½ã®éã¾ãããã¢ãããä½ãä»çµã¿ã¯ãOperationalã¢ããã¨å¼ã°ãã¦ãããããããã®Haskellããã°ã©ãã³ã°ã§ãé常ã«å¤§ããªå½¹å²ãæããã ããã
IOã®ä¸ç
ä»ã¾ã§ã¢ãããèªä½ãã¦ããããHaskellã§ã¯IOã¢ããã¨ããé常ã«éè¦ãªã¢ããããããããå®ç¾©ããã¦ããããªãã¨ãIOã¢ããã¯ãå¦çç³»ãã¢ãããåè§£ãã¦ãç¾å®ä¸çã«å¯¾ããå¯ä½ç¨ã«å¤æã§ããã®ã ï¼
IOã¢ããã¨ãã¦è¡¨ç¾ãããæç¶ããmainã¨ãã¦å®ç¾©ããã¨ãå¦çç³»ããããè§£éãã¦ã³ã³ãã¥ã¼ã¿ã«å¯ä½ç¨ãçºçããããããã«ãããHaskellã®ããã°ã©ã ã¯ä½¿ããããã«ãªãã
main = putStrLn "Hello, world!"
ãããå®è¡ããã°ãããªãã®ã¿ã¼ããã«ã«ã¯Hello, world!ã¨è¡¨ç¤ºãããã ãããç¥ç§çã â¦
IOã¢ããã®ä¸èº«ãããã°ã©ã ãææ¡ãããã¨ã¯ã§ããªãããOperationalã¢ããã®ä¸èº«ãææ¡ãããã¨ã¯å¯è½ã ãããã¯ãå¦çç³»ãç¾å®ä¸çã®ä¸èº«ãææ¡ã§ããªãã¦ããIOã¢ããã®ä¸èº«ãææ¡ã§ããã®ã¨ä¼¼ã¦ãããã¨ãããã¨ã¯ãOperationalã¢ãããè§£éãã¦IOã«å½±é¿ãåã¼ãå¦çç³»ãä½ããã®ã§ã¯ãªãã ãããï¼â¦â¦ä½ããã
toIO :: Program MyActions a -> IO a toIO (Unit HelloWorld) = putStrLn "Hello, world!" toIO (Unit (PutStrLn str)) = putStrLn str toIO (Unit GetLine) = getLine toIO (Return a) = return a toIO (m :>>= k) = toIO m >>= toIO . k
ãããã¾ãã«è¨èªã¨å¦çç³»ã®é¢ä¿ãOperationalã¢ããã¯ãä¸ã¤ã®æç¶ãåè¨èªããå½ä»¤ã®ä¸è¦§ããèªåçæãã¦ãã¾ãã¢ãããªã®ã ãããããIOãªã©ã®ç¹å®ã®
ããã§ä½ã£ãOperationalã¢ããã¯ãããæ´ç·´ãããå®è£ ããããå®ç¨ããéã¯ãã¡ãã使ããã
ããã§ç´¹ä»ãã以å¤ã«ããHaskellã®ä¸çã«ã¯æ§ã ãªã¢ããããããã¢ããã®å ã¤ã®ç³»çµ±ãã¢ããã®ãã¹ã¦ãåèã«ãæ§ã ãªã¢ããã使ã£ã¦ãããã¦ä½ã£ã¦ã¿ã¦ã»ããã