TRANSLATIONã®2çªç®ã®éšåã¯ãHaskellã®çããŠé£ãã玹ä»ã§ãã æåã®ãã®ã¯
ããããå
¥æã§ã
ãŸãããªãªãžãã«ã¯
ãã¡ãããããŒãéšå
ããã§ãšãããããŸãïŒ ããªãã¯æ¬åœã«é ãã«è¡ããŸããã
ãããŠä»ããŽããå»æ£ç©ããœãããŒãå§ãŸããŸã:)ã
ããªããšç§ã䌌ãŠãããªããããªãã¯ãã§ã«æ©èœçãªã¹ã¿ã€ã«ã«å°ãåããŠããŸãã ããªãã¯æ lazãããã©ã«ãã§äžããå©ç¹ãç解ããŠããŸãã ããããããªãã¯æ¬åœã«ããªããæ¬åœã«æçšãªããã°ã©ã ãæžãããšãã§ããæ¹æ³ããŸã ããç解ããŠããŸããã ç¹ã«ïŒ
- å¯äœçšãã©ããããïŒ
- å
¥åºåïŒIOïŒãæäœããããã«ããªããã®ãããªå¥åŠãªæ§æãå¿
èŠãªã®ã§ããïŒ
æºåãããŠãã ãããçãã¯æãåçŽã§ã¯ãªããããããŸããã
ãããããã®å©ç¹ã¯åŠå®ã§ããŸããã
03_å°ç/ 01_IO / 01_progressive_io_example.lhsIOãæ±ã
tl; dr ïŒ
IO
ã§åäœããå
žåçãªé¢æ°ã¯ãåœä»€åããã°ã©ã ã®ããã«èŠããŸãã
f :: IO a f = do x <- action1 action2 x y <- action3 action4 xy
- ãªããžã§ã¯ãã«å€ãå²ãåœãŠãã«ã¯ã
<-
ã䜿çšããŸãã - ãã®äŸã§ã¯ãåè¡ã®åŒã®ã¿ã€ãã¯
IO *
ã§ãã
action1 :: IO b
action2 x :: IO ()
action3 :: IO c
action4 xy :: IO a
x :: b
ã y :: c
- ããã€ãã®ãªããžã§ã¯ãã¯
IO a
åã§ãã
ãã®ãããªãªããžã§ã¯ãã§ã¯ãçŽç²ãªé¢æ°ã䜿çšã§ããŸããã
çŽç²ãªé¢æ°ã䜿çšããã«ã¯ã action2 (purefunction x)
ãå®è¡ããå¿
èŠããããŸãã
ãã®ã»ã¯ã·ã§ã³ã§ã¯ãIOã®äœ¿çšæ¹æ³ã瀺ããŸãããåäœæ¹æ³ã¯ç€ºããŸããã
Haskellãããã°ã©ã ã®ã¯ãªãŒã³ãªéšåãšå¯äœçšã®ããéšåãã©ã®ããã«åé¢ããããããããŸãã
æ§æã®è©³çŽ°ãå°ãç解ã§ããªãå Žåã§ããåæ¢ããªãã§ãã ããã
次ã®ã»ã¯ã·ã§ã³ã§ãããã«æ»ããŸãã
äœãååŸãããã§ããïŒ
ãŠãŒã¶ãŒããçªå·ã®ãªã¹ããååŸããŸãã éé¡ãå°å·ãã
toList :: String -> [Integer] toList input = read ("[" ++ input ++ "]") main = do putStrLn " ( ):" input <- getLine print $ sum (toList input)
ãã®ããã°ã©ã ã®åäœã¯æããã§ãã
ããããåã詳ããèŠãŠã¿ãŸãããã
putStrLn :: String -> IO () getLine :: IO String print :: Show a => a -> IO ()
do
ãããã¯å
ã®ãã¹ãŠã®åŒã
IO a
åã§ããããšã«æ°ã¥ããŸã
IO a
ãïŒ
main = do putStrLn " ... " :: IO () getLine :: IO String print Something :: IO ()
<-
æåã®åäœã«ã泚æããŠãã ããã
do x <- something
something :: IO a
å Žåã
x :: a
ã
IO
䜿çšã«é¢ããéèŠãªæ³šæã doãããã¯å
ã®ãã¹ãŠã®è¡ã¯ã次ã®2ã€ã®æ¹æ³ã®ããããã§èŠãå¿
èŠããããŸãã
action1 :: IO a
ãŸãã¯
value <- action2
ãããã®2ã€ã®ãšã³ããªã¯ãã¢ã¯ã·ã§ã³ãèšè¿°ããããŸããŸãªæ¹æ³ã«å¯Ÿå¿ããŠããŸãã 次ã®ã»ã¯ã·ã§ã³ã®çµãããŸã§ã«ããã®ææ¡ã«å®å
šã«æ°ä»ãã§ãããã
03_å°ç/ 01_IO / 01_progressive_io_example.lhs
03_å°ç/ 01_IO / 02_progressive_io_example.lhsãã®ããã°ã©ã ã®åäœãèŠãŠã¿ãŸããããããšãã°ããŠãŒã¶ãŒãäœãå¥åŠãªãã®ãå
¥åããå Žåã¯ã©ããªããŸããïŒ
ç§éã¯è©Šã¿ãŸãïŒ
% runghc 02_progressive_io_example.lhs Enter a list of numbers (separated by comma): foo Prelude.read: no parse
ããïŒ æªéã®ãããªãšã©ãŒã¡ãã»ãŒãžãšããã°ã©ã ã®ã¯ã©ãã·ã¥ïŒ
次ã«ããšã©ãŒã¡ãã»ãŒãžãèªã¿ãããããã«ãæåã®ã¹ããããå®è¡ããå¿
èŠããããŸãã
ãããè¡ãã«ã¯ãäœããããŸããããªãã£ãããšãç解ããå¿
èŠããããŸãã
1ã€ã®æ¹æ³ã¯ã
Maybe
ã¿ã€ãã䜿çšããããšã§ãã
ãã®ã¿ã€ãã¯Haskellããã°ã©ã ã§éåžžã«ãã䜿çšãããŸãã
import Data.Maybe
ããã¯äœã§ããïŒ
Maybe
ããã¯1ã€ã®ãã©ã¡ãŒã¿ãåãã¿ã€ãã§ãã 圌ã®å®çŸ©ã¯æ¬¡ã®ãšããã§ãã
data Maybe a = Nothing | Just a
ããã¯ãå€ãäœæãŸãã¯èšç®ããããšããŠãšã©ãŒãçºçãããã©ãããç解ããããã®è¯ãæ¹æ³ã§ãã
maybeRead
é¢æ°ã¯ããã®ã¢ãããŒãã®åªããäŸã§ãã
ãã®é¢æ°ã¯ã
read
é¢æ°ïŒJSONæååãåŠçããjavascripté¢æ°
eval
ã«éåžžã«äŒŒãŠããŸãïŒã«äŒŒãŠããŸãã
ããããäœããããŸããããªãå Žåãçµæã¯
Nothing
ãŸãã
çµæãæ£ããå Žåã
Just <>
ãè¿ã
Just <>
ã
ãã®æ©èœãæ·±ãæãäžããªãã§ãã ããã
ãã®äžã®ã³ãŒãã¯
read
ãããäœãã§ãã ã
maybeRead :: Read a => String -> Maybe a maybeRead s = case reads s of [(x,"")] -> Just x _ -> Nothing
ã³ãŒããèªã¿ããããªã£ãã®ã§ã次ã®æ©èœãäœæããŸãã
æååã®åœ¢åŒãééã£ãŠããå Žåã
Nothing
ãè¿ããŸãã
ä»ã®å Žåãããšãã°ã1,2,3ãã®å Žåã
Just [1,2,3]
ãè¿ããŸãã
getListFromString :: String -> Maybe [Integer] getListFromString str = maybeRead $ "[" ++ str ++ "]"
次ã«ãmainé¢æ°ã䜿çšããŠã³ãŒãããã¹ãããŸãã
main :: IO () main = do putStrLn " , :" input <- getLine let maybeList = getListFromString input in case maybeList of Just l -> print (sum l) Nothing -> error " . ."
ãšã©ãŒãçºçããå ŽåãçŽ æŽããããšã©ãŒã¡ãã»ãŒãžã衚瀺ãããŸãã
ãã®å Žåãã¡ã€ã³é¢æ°ã®doãããã¯å
ã®ååŒã®ã¿ã€ãã¯
IO a
ãŸãŸã§ãã
å¯äžã®å¥åŠãªããšã¯
error
ã§ãã
error msg
é¢æ°ã¯ãããããã¿ã€ãã®å
¥åïŒãã®å Žåã¯
IO ()
ãåçŽã«åãå
¥ããŸãã
éåžžã«éèŠãªããšã«æ³šæããŠãã ãã-ãã¹ãŠã®é¢æ°ã®ã¿ã€ãã¯äºåå®çŸ©ãããŠããŸãã
ã¿ã€ã
IO
ãšãããæã€é¢æ°ã¯ã
main
ã§ãã
ããã¯ãmainãçŽç²ãªé¢æ°ã§ã¯ãªãããšãæå³ããŸãã
ãã ããçŽç²ãª
getListFromString
é¢æ°ã䜿çšããŸãã
宣èšãããé¢æ°åãèŠãã ãã§ãçŽç²ãªé¢æ°ãšå¯äœçšã®ããé¢æ°ãåºå¥ã§ããŸãã
ãªãçŽç²ãªæ©èœãéèŠãªã®ã§ããïŒ
ããã€ãã®ããšãå¿ããããšãã§ããŸãããäž»ãªçç±ã¯3ã€ãããŸãã
- ã¯ãªãŒã³ãªã³ãŒãã¯è§£æãã¯ããã«ç°¡åã§ãã
- æž
æœãã¯ãå¯äœçšã«é¢é£ããè€éã§åçŸå¯èœãªãšã©ãŒããããªããå®ããŸãã
- çŽç²ãªé¢æ°ã¯ãä»»æã®é åºã§ããŸãã¯ãªã¹ã¯ãªãã§äžŠåã«èšç®ã§ããŸãã
ãããã®çç±ã«ãããã¯ãªãŒã³ãªé¢æ°ã§ã¯ã§ããã ãå€ãã®ã³ãŒããä¿æããå¿
èŠããããŸãã
03_å°ç/ 01_IO / 02_progressive_io_example.lhs
03_å°ç/ 01_IO / 03_progressive_io_example.lhs次ã®ã¹ãããã¯ããŠãŒã¶ãŒãæ£ããçããå
¥åãããŸã§åžžã«ãŠãŒã¶ãŒãããŒãªã³ã°ããããšã§ãã
æåã®éšåã¯å€æŽãããŸããã
import Data.Maybe maybeRead :: Read a => String -> Maybe a maybeRead s = case reads s of [(x,"")] -> Just x _ -> Nothing getListFromString :: String -> Maybe [Integer] getListFromString str = maybeRead $ "[" ++ str ++ "]"
ãããŠãæ°åã®ãªã¹ããèŠæ±ããé¢æ°ãäœæããå
¥åãããæå¹ãªãªã¹ããåãåããŸã§çµäºããŸããã
askUser :: IO [Integer] askUser = do putStrLn " , :" input <- getLine let maybeList = getListFromString input in case maybeList of Just l -> return l Nothing -> askUser
ãã®é¢æ°ã®ã¿ã€ãã¯
IO [Integer]
ã§ãã
ããã¯ãIOã¢ã¯ã·ã§ã³ã䜿çšããŠ
[Integer]
ãããªçµæãåŸãããšãæå³ããŸãã
äžéšã®äººã
ã¯ããããã®ããã«èª¬æããŸãïŒ
ãããã¯IO
å
ã®[Integer]
ã
I / Oã¡ã«ããºã ã®å
éšæ§é ãç解ãããå Žåã¯ã次ã®ã»ã¯ã·ã§ã³ããèªã¿ãã ããã
ããããå®éã«ã¯ãåã«IOã
䜿çšããå Žåã¯ãåçŽãªããã°ã©ã ãããã€ãäœæããåã«ã€ããŠèããããšãå¿ããªãã§ãã ããã
ãã®çµæãã¡ã€ã³é¢æ°ã¯ã¯ããã«ã·ã³ãã«ã«ãªããŸããã
main :: IO () main = do list <- askUser print $ sum list
ããã§
IO
玹ä»ã¯çµããã§ãã ãã¹ãŠãéåžžã«éãé²ã¿ãŸããã èŠããŠãããŠã»ããããšã¯æ¬¡ã®ãšããã§ãã
do
ãããã¯ã§ã¯ãååŒã¯IO a
åã§ããå¿
èŠããããŸãã
å¯èœãªè¡šçŸã®ã»ããã¯ããªãéãããŠããŸãïŒ
getLine
ã print
ã putStrLn
ãªã©- çŽç²ãªæ©èœãæ倧éã«æŽ»çšããŸãã
- ã¿ã€ã
IO a
ã¯ãã¿ã€ãa
çµæãè¿ãåŸç¶ã®IO ã¢ã¯ã·ã§ã³ãæå³ããŸãã
ã¢ã¯ã·ã§ã³ãè¡šãããIO
ã¿ã€ãIO a
ã¯é¢æ°ã®ã¿ã€ãã§ãã
ãŸã èå³ãããå Žåã¯ã次ã®ã»ã¯ã·ã§ã³ããèªã¿ãã ããã
å°ãç·Žç¿ããã°ã
IO
ã
䜿çšããŠãåé¡ã¯ãããŸããã
æŒç¿ ïŒ
- ãã¹ãŠã®åŒæ°ãèŠçŽããããã°ã©ã ãäœæããŸãã ãã³ãïŒ
getArgs
é¢æ°ã䜿çšããŸãã
03_å°ç/ 01_IO / 03_progressive_io_example.lhsIOããªãã¯ã®èª¬æ
tl; dr ïŒ
çŽç²ãªæ©èœãåºå¥ããããã«ã
main
ãäžçã®ç¶æ
ãå€ããé¢æ°ãšããŠå®çŸ©ãããŸã
main :: World -> World
ãã®ã¿ã€ãã®é¢æ°ã«ã¯ãå¯äœçšãããããšãä¿èšŒãããŠããŸãã å
žåçãªã¡ã€ã³é¢æ°ãèŠãŠãã ããïŒ
main w0 = let (v1,w1) = action1 w0 in let (v2,w2) = action2 v1 w1 in let (v3,w3) = action3 v2 w2 in action4 v3 w3
ãã®äŸã«ã¯å€ãã®æéå€ããããŸãïŒ w1
ã w2
ããã³w3
ïŒ
次ã®ã¹ãããã«ããŒã¿ã転éããããã«äœ¿çšãããŸãã
bind
ãŸãã¯(>>=)
é¢æ°ãäœæããŠããŸãã bind
ãããã§bind
ååä»ãã®äžæçãªå€ã¯å¿
èŠãªããªããŸããã
main = action1 >>= action2 >>= action3 >>= action4
ããŸãïŒHaskellã«ã¯æ§æã·ã¥ã¬ãŒããããŸãïŒ
main = do v1 <- action1 v2 <- action2 v1 v3 <- action3 v2 action4 v3
ãªããã®ãããªå¥åŠãªæ§æãå¿
èŠãªã®ã§ããïŒ
IO
ã®ã¿ã€ãã¯äœã§ããïŒ ããã¯ãã¹ãŠäœããã®éæ³ã®ããã«èŠããŸããã
ãã°ããã®éãçŽç²ãªé¢æ°ã«ã€ããŠã¯å¿ããŸãããã å¯äœçšã«çŠç¹ãåœãŠãïŒ
askUser :: IO [Integer] askUser = do putStrLn " , :" input <- getLine let maybeList = getListFromString input in case maybeList of Just l -> return l Nothing -> askUser main :: IO () main = do list <- askUser print $ sum list
ãŸãããã®ã³ãŒãã¯ãŸãã§éåžžã®åœä»€åèšèªã§æžãããŠãããã®ããã«èŠããŸãã
Haskellã¯ããµã€ãã¢ã¯ã·ã§ã³ã³ãŒããäžå¯æ¬ ã«èŠããã»ã©ã¯ãŒã«ã§ãã
å¿
èŠã«å¿ããŠãHaskellã§
while
ã¢ããã°ãäœæã§ããŸãã
å®éã«ã¯ã
IO
ã§äœæ¥ããå Žåãåœä»€åã®ã¹ã¿ã€ã«ãããé©ããŠããŸãã
ããããããªãã¯ããããé²é³ãããçããããšã«æ°ã¥ããã§ãããã ããã§ãçç±ã®è©³çŽ°ãªèª¬æã«è¡ããŸããã
ã»ãšãã©ã®èšèªã§ã¯ãäžçã®ç¶æ
ã¯å€§ããªæé»ã®ã°ããŒãã«å€æ°ãšèããããšãã§ããŸãã ãã®æé»çãªå€æ°ã¯ãããã°ã©ã ã®ã©ãããã§ãã¢ã¯ã»ã¹ã§ããŸãã ããšãã°ãä»»æã®é¢æ°ã§ãã¡ã€ã«ãã\ãèªã¿åãããšãã§ããŸãã äžæ¹ããã¡ã€ã«ã®æç¡ã¯ãäžçã®ããŸããŸãªç¶æ
ãšèŠãªãããšãã§ããŸãã
Haskellã§ã¯ãäžçã®ç¶æ
ã¯æ瀺çã«èšå®ãããŸãã
main
æ©èœãäžçã®ç¶æ
ãå€ããå¯èœ
æ§ãããããšãæ確ã«è¿°ã¹ãŠããŸãã ãããŠããã®ã¿ã€ãã¯æ¬¡ã®ããã«ãªããŸãã
main :: World -> World
ãã ãããã®å€æ°ã¯ãã¹ãŠã®æ©èœã§äœ¿çšã§ããããã§ã¯ãããŸããã
ãã®å€æ°ã䜿çšããé¢æ°ã¯ã¯ãªãŒã³ã§ã¯ãããŸããã
ããã䜿çšããªãé¢æ°ã¯çŽç²ã§ãïŒãã®èŠåã«ã¯
å±éºãªäŸå€ããããŸããããããå®éã®ããã°ã©ã ã§ã¯ãããã¯å¿
èŠãããŸããã詳现ãªãããã°ã®å Žåãé€ããŸãïŒã
Haskellã¯ãäžçã¯
main
é¢æ°ãžã®å
¥åãã©ã¡ãŒã¿ãŒã§ãããšèããŠããŸãã
ãããããã®é¢æ°ã®å®éã®åã¯æ¬¡ã®ãããªãã®ã§ã
main :: World -> ((),World)
ïŒèå³ã®ããæ¹ã¯ãåŒã®ã¿ã€ãã¯
data IO a = IO {unIO :: State# RealWorld -> (# State# RealWorld, a #)}
ã§ãããã¹ãŠã®
#
ã¯æé©åã«é¢é£ããŠããããã®äŸã§ã¯ããã€ãã®ãã£ãŒã«ããå
¥ãæ¿ããŸãããããããå
šäœçã«ã¯ãèãæ¹ã¯å€ãã£ãŠããŸãããïŒ
ã¿ã€ã
()
ã¯ç©ºã®ã¿ã€ãã§ãã
空èã
次ã®ããšãå¿ããã«ãé¢æ°ãæžãçŽããŸãããã
main w0 = let (list,w1) = askUser w0 in let (x,w2) = print (sum list,w1) in x
ãŸããå¯äœçšã®ãããã¹ãŠã®é¢æ°ã«ã¯ç¹å®ã®åãå¿
èŠã§ãã
World -> (a,World)
a
ã¯çµæã®ã¿ã€ãã§ãã
ããšãã°ã
getChar
é¢æ°ã®ã¿ã€ãã¯
World -> (Char,World)
ãªããã°ãªããŸããã
å¥ã®éèªæãªããšã¯ãé¢æ°ãèšç®ãããé åºã§ãã
Haskellã§ã¯ã
fab
ãèšç®ããããšãããšãããã€ãã®ãªãã·ã§ã³ããããŸãïŒ
a
ã b
ã fab
é ã«èšç®a
fab
- æåã«
b
èšç®ãã次ã«b
èšç®a
ãæåŸã«fab
èšç®ãfab
ã a
ãšb
ã䞊åã«èšç®ãa
ããfab
èšèªã¯æ©èœçã«çŽç²ã§ããããããã®ãããªããªãã¯ã¯çŸå®çã§ãã
ã¡ã€ã³é¢æ°ãããèŠããšãæåã®è¡ã¯2çªç®ã®è¡ã®ãã©ã¡ãŒã¿ãŒãèšç®ããå¿
èŠããããããæåã®è¡ã2çªç®ã®è¡ã®åã«èšç®ããå¿
èŠãããããšã¯æããã§ãã
ãã®ããªãã¯ã¯ããŸãæ©èœããŸãã
èšç®ã®åã¹ãããã§ãã³ã³ãã€ã©ã¯æ°ããå€æŽãããäžçãžã®ãã€ã³ã¿ãæž¡ããŸãã
å
éšã§ã¯ã
print
ã¯æ¬¡ã®ããã«æ©èœããŸãã
- ç»é¢ã«äœããå°å·ãã
- äžçIDãå€æŽãã
- çµæãšããŠè¿ã
((),__)
ã
ä»ã¡ã€ã³ã¯ã²ã©ãèŠããŸãã askUseré¢æ°ã§ãåãããšãããŸãããïŒ
askUser :: World -> ([Integer],World)
ã«
askUser :: IO [Integer] askUser = do putStrLn " :" input <- getLine let maybeList = getListFromString input in case maybeList of Just l -> return l Nothing -> askUser
åŸ
askUser w0 = let (_,w1) = putStrLn "Enter a list of numbers:" in let (input,w2) = getLine w1 in let (l,w3) = case getListFromString input of Just l -> (l,w2) Nothing -> askUser w2 in (l,w3)
äžèŠããããbutãã ãããã®äžåšçšãª
w*
å€æ°ãèŠãŠãã ããã
ç§ãã¡ãåŠãã æèšã¯ãæ©èœçã«çŽç²ãªèšèªã§ã®I / Oã®çŽ æŽãªå®è£
ã¯ã²ã©ãããã«èŠããããšã§ãã
幞ããªããšã«ããã®åé¡ã解決ããããã®ããçŽæ¥çãªã¢ãããŒãããããŸãã ãã¿ãŒã³ãèŠããŸãã åè¡ã¯æ¬¡ã®ããã«è¡šãããŸãã
let (y,w') = action xw in
æåã®ãã©ã¡ãŒã¿ãŒ
x
äžèŠãªå Žåã§ããçµæã¯ã«ããã«
(answer, newWorldValue)
ãŸãã åé¢æ°
f
ã¯ã次ã®ãããªåãå¿
èŠã§ãã
f :: World -> (a,World)
ããã«ããããã®é¢æ°ã®äœ¿çšæ¹æ³ãéåžžã«äŒŒãŠããããšã«ãæ°ä»ããŸããã
let (y,w1) = action1 w0 in let (z,w2) = action2 w1 in let (t,w3) = action3 w2 in ...
åã¢ã¯ã·ã§ã³ã¯ã0ãnåã®ãã©ã¡ãŒã¿ãŒã䜿çšã§ããŸãã ãŸããç¹ã«ãåã¢ã¯ã·ã§ã³ã¯å
¥åãšããŠåã®è¡ã®çµæãåãããšãã§ããŸãã
ããšãã°ã次ã®ããã«æžãããšãã§ããŸãã
let (_,w1) = action1 x w0 in let (z,w2) = action2 w1 in let (_,w3) = action3 xz w2 in ...
ãããŠããã¡ããã
actionN w :: (World) -> (a,World)
ã
éèŠïŒ 泚æãå¿
èŠãªãã¿ãŒã³ã¯2ã€ã ãã§ãã
let (x,w1) = action1 w0 in let (y,w2) = action2 x w1 in
ãããŠ
let (_,w1) = action1 w0 in let (y,w2) = action2 w1 in
ãããŠä»ãã¡ãã£ãšããããªãã¯ããããŸãã
äžçã®ç¶æ
ãä¿æããå€æ°ããæ¶æ»
ããããŸãã 2ã€ã®æååã
bind
ãŸãã ãããè¡ãããã«ã
bind
é¢æ°ãäœæããŸãã
圌女ã®ã¿ã€ãã¯æåã¯å¥åŠã«èŠããŸãïŒ
bind :: (World -> (a,World)) -> (a -> (World -> (b,World))) -> (World -> (b,World))
(World -> (a,World))
ã¯IOã¢ã¯ã·ã§ã³ã®ã¿ã€ãã§ããããšãå¿ããªãã§ãã ããã
ç°¡åã«ããããã«ååãå€æŽããŸãããïŒ
type IO a = World -> (a, World)
ããã€ãã®äŸïŒ
getLine :: IO String print :: Show a => a -> IO ()
getLine
ã¯ããã©ã¡ãŒã¿ãšããŠã¯ãŒã«ããåãããã¢
(String,World)
ãè¿ãIOã¢ã¯ã·ã§ã³ã§ãã
getLine
åã¯
IO String
ãªããšèšããŸãã
ãŸãããIOã§å²ãŸãããæååãè¿ãIOã¢ã¯ã·ã§ã³ãšããŠèªèããããšãã§ããŸãã
print
æ©èœãéåžžã«èå³æ·±ãã§ãã å
¥åãã©ã¡ãŒã¿ãŒãåãåãã衚瀺ããŸãã ããããå®éã«ã¯2ã€ã®ãã©ã¡ãŒã¿ãŒãå¿
èŠã§ãã æåã®ãã©ã¡ãŒã¿ãŒã¯è¡šç€ºãããå€ã§ããã2çªç®ã¯äžçã®ç¶æ
ã§ãã çµæãšããŠããã¢
((),World)
è¿ããŸãã ã€ãŸããäžçã®ç¶æ
ãå€æŽããŸãããããŒã¿ãè¿ããŸããã
ãã®åã¯ã
bind
é¢æ°ã®åå®çŸ©ãç°¡çŽ åããŸãã
bind :: IO a -> (a -> IO b) -> IO b
bind
ã¯åŒæ°ãšããŠ2ã€ã®IOã¢ã¯ã·ã§ã³ãåããå¥ã®IOã¢ã¯ã·ã§ã³ãè¿ããŸãã
次ã«ãããã€ãã®
éèŠãªãã¿ãŒã³ãæŽæ°ããŸãã æåã¯ãã®ãããªãã®ã§ããïŒ
let (x,w1) = action1 w0 in let (y,w2) = action2 x w1 in (y,w2)
ã¿ã€ãã«æ³šæããŠãã ããã
action1 :: IO a action2 :: a -> IO b (y,w2) :: IO b
ããªãã¿ã§ããã
(bind action1 action2) w0 = let (x, w1) = action1 w0 (y, w2) = action2 x w1 in (y, w2)
åºæ¬çãªèãæ¹ã¯ããã®é¢æ°ã䜿çšããŠWorldãã©ã¡ãŒã¿ãŒãé衚瀺ã«ããããšã§ãã è¡ããïŒ ååŸããããã®ã®äžéšã次ã«ç€ºããŸãã
let (line1,w1) = getLine w0 in let ((),w2) = print line1 in ((),w2)
ãããŠä»ããã€ã³ãé¢æ°ã䜿çšããŸãïŒ
(res,w2) = (bind getLine (\l -> print l)) w0
printã¯
(World -> ((),World))
ã§ããããã
res = ()
ïŒnullåïŒã§ããããšãããããŸãã
ããã«ç¹å¥ãªã¹ããªãŒãããžãã¯ã衚瀺ãããªãå Žåã¯ã3è¡ã®ããã°ã©ã ãäœæããŠã¿ãŠãã ããã
let (line1,w1) = getLine w0 in let (line2,w2) = getLine w1 in let ((),w3) = print (line1 ++ line2) in ((),w3)
次ã®ãããªãã®ã§ãïŒ
(res,w3) = bind getLine (\line1 -> bind getLine (\line2 -> print (line1 ++ line2)))
æ°ã¥ããïŒ
ã¯ãããã以äžWorldäžæå€æ°ã¯ãããŸããïŒ
ããã¯
MAã§ãã
GI ç§ã¯ããããå¥ã®æ§æã䜿çšã§ããŸãã
bind
ã
(>>=)
眮ãæããŸãããã
(>>=)
ããã¯äžçœ®é¢æ°ã§ããã
(+)
; ãªã³ãŒã«
3 + 4 â (+) 3 4
(res,w3) = getLine >>= \line1 -> getLine >>= \line2 -> print (line1 ++ line2)
ã»ã»ã»ïŒ æããŸããŠããã§ãšãããããŸãïŒ Haskellã«ã¯æ§æã·ã¥ã¬ãŒããããŸãïŒ
do x <- action1 y <- action2 z <- action3 ...
次ã®ãã®ã«çœ®ãæããããšãã§ããŸãã
action1 >>= \x -> action2 >>= \y -> action3 >>= \z -> ...
action2
ã§
x
ã䜿çšãã
action2
ã§
x
ã
y
ãšãšãã«äœ¿çšã§ããŸãã
ãããã
<-
䜿çšããªãæååã¯ã©ãã§ããããïŒ
ç°¡åïŒ
blindBind
é¢æ°ããããŸãïŒ
blindBind :: IO a -> IO b -> IO b blindBind action1 action2 w0 = bind action (\_ -> action2) w0
ç§ã¯ãã®è¡šçŸãæå³çã«åçŽåããŸããã§ããã
ãã¡ãããã³ãŒããããã·ã³ãã«ã«ãããå Žåã¯ãæŒç®å
(>>)
䜿çšã§ããŸãã
ãããŠãã
do action1 action2 action3
ã«å€ãã
action1 >> action2 >> action3
ã¡ãªã¿ã«ããã1ã€ã®éåžžã«äŸ¿å©ãªæ©èœã次ã«ç€ºããŸãã
putInIO :: a -> IO a putInIO x = IO (\w -> (x,w))
ããã¯ãçŽç²ãªå€ããIOã³ã³ããã¹ããã«ããã·ã¥ããæšæºçãªæ¹æ³ã§ãã
éåžžã
putInIO
ã¯
putInIO
ãšåŒã°ããŸãã
HaskellãåŠç¿ãããšãããã®é¢æ°åã¯éåžžã«ãããã«ãããã®ã§ãã
return
ä»ã®èšèªã®ãã¢
return
倧ããç°ãªããŸãã
03_å°ç/ 01_IO / 21_Detailled_IO.lhsæåŸã«ãäŸãæžãæããŠã¿ãŸãããã
askUser :: IO [Integer] askUser = do putStrLn " , :" input <- getLine let maybeList = getListFromString input in case maybeList of Just l -> return l Nothing -> askUser main :: IO () main = do list <- askUser print $ sum list
次ã®ããã«æžãæããããšãã§ããŸãã
import Data.Maybe maybeRead :: Read a => String -> Maybe a maybeRead s = case reads s of [(x,"")] -> Just x _ -> Nothing getListFromString :: String -> Maybe [Integer] getListFromString str = maybeRead $ "[" ++ str ++ "]" askUser :: IO [Integer] askUser = putStrLn " , :" >> getLine >>= \input -> let maybeList = getListFromString input in case maybeList of Just l -> return l Nothing -> askUser main :: IO () main = askUser >>= \list -> print $ sum list
ããã§ããã®ã³ãŒããã³ã³ãã€ã«ããŠãæ©èœããããšã確èªã§ããŸãã
ãããŠã
(>>)
ãš
(>>=)
ãªãã§ãããã©ã®ããã«èŠãããæ³åããŠã¿ãŸãããã
03_å°ç/ 01_IO / 21_Detailled_IO.lhs
03_å°ç/ 02_Monads / 10_Monads.lhsã¢ãã
次ã«ãç§å¯ãæããã«ããŸããã
IO
ã¯
ã¢ããã§ãã
ã¢ããã䜿çšãããšãæ§æç³è¡£èšæ³ã䜿çšã§ããããšãæå³ããŸãã
ããããæãéèŠãªã®ã¯ãã¶ã€ã³ãã¿ãŒã³ã§ããããã«ãããããã¯ãªãŒã³ã§ç解ããããã³ãŒããèšè¿°ã§ããŸãã
éèŠãªæ³šæ ïŒ
- ã¢ããã¯å¿
ãããå¯äœçšã«é¢é£ä»ããããŠããããã§ã¯ãããŸããïŒ
å€ãã®çŽç²ãªã¢ããããããŸãã - ã¢ããã®æ¬è³ªã¯èšç®ã®æ§æã«ãããŸã
Haskellèšèªã«é¢ããŠã¯ã
Monad
ã¯åã¯ã©ã¹ã§ãã
ãã®ã¯ã©ã¹ã®ã€ã³ã¹ã¿ã³ã¹ã«ãªãã«ã¯ãé¢æ°
(>>=)
ããã³
return
ãå®çŸ©ããå¿
èŠããããŸãã
é¢æ°
(>>)
ã¯
(>>=)
åºã¥ããŠèªåçã«äœæãããŸãã
Monad
ã¯ã©ã¹ã®ïŒã»ãŒå®å
šãªïŒå®çŸ©ã次ã«ç€ºããŸãã
class Monad m where (>>=) :: ma -> (a -> mb) -> mb return :: a -> ma (>>) :: ma -> mb -> mb f >> g = f >>= \_ -> g
åèïŒ
ãã¶ãã¢ãã
Monad
ã€ã³ã¹ã¿ã³ã¹ã«ã¯å€ãã®ã¿ã€ãããããŸãã
æãç°¡åãªäŸã¯
Maybe
ã§ãã
Maybe
å€ã®ã»ãããããå Žåãã¢ããã䜿çšããŠããããæäœã§ããŸãã ç¹ã«ããã¹ãããã
if..then..else..
ãåãé€ããšäŸ¿å©ã§ã
if..then..else..
è€éãªéè¡æ¥åãæ³åããŠãã ããããã€ãã¹ã«å
¥ããã«ååŒã®å±¥æŽãããå Žåã«ã®ã¿ã700ãŠãŒãã®ããŒãã¹ãè«æ±ã§ããŸãã
deposit value account = account + value withdraw value account = account - value eligible :: (Num a,Ord a) => a -> Bool eligible account = let account1 = deposit 100 account in if (account1 < 0) then False else let account2 = withdraw 200 account1 in if (account2 < 0) then False else let account3 = deposit 100 account2 in if (account3 < 0) then False else let account4 = withdraw 300 account3 in if (account4 < 0) then False else let account5 = deposit 1000 account4 in if (account5 < 0) then False else True main = do print $ eligible 300
03_å°ç/ 02_Monads / 10_Monads.lhs
03_å°ç/ 02_ã¢ãã/ 11_Monads.lhsãããŠãMaybeãšãã®Monadãšã³ãã£ãã£ã䜿çšããŠããã®ã³ãŒãã§ç©äºãæŽçããŸãããã
deposit :: (Num a) => a -> a -> Maybe a deposit value account = Just (account + value) withdraw :: (Num a,Ord a) => a -> a -> Maybe a withdraw value account = if (account < value) then Nothing else Just (account - value) eligible :: (Num a, Ord a) => a -> Maybe Bool eligible account = do account1 <- deposit 100 account account2 <- withdraw 200 account1 account3 <- deposit 100 account2 account4 <- withdraw 300 account3 account5 <- deposit 1000 account4 Just True main = do print $ eligible 300
03_å°ç/ 02_ã¢ãã/ 11_Monads.lhs
03_å°ç/ 02_ã¢ãã/ 12_Monads.lhsãã§ã«æªãã¯ãããŸããããããã«æ¹åããããšãã§ããŸãïŒ
deposit :: (Num a) => a -> a -> Maybe a deposit value account = Just (account + value) withdraw :: (Num a,Ord a) => a -> a -> Maybe a withdraw value account = if (account < value) then Nothing else Just (account - value) eligible :: (Num a, Ord a) => a -> Maybe Bool eligible account = deposit 100 account >>= withdraw 200 >>= deposit 100 >>= withdraw 300 >>= deposit 1000 >> return True main = do print $ eligible 300
ããã§ãã¢ãããã³ãŒãããããšã¬ã¬ã³ãã«ããããšãã§ããããšã蚌æããŸããã
äžè¬çã«ã
Maybe
åæ§ã®äœ¿çšã¯ãã»ãšãã©ã®åœä»€åèšèªã§æ©èœããŸãã
ããã¯ããªãèªç¶ãªãã¶ã€ã³ã§ãã
éèŠãªæ³šæïŒ
çµæãNothing
ã§ããæåã®èšç®ã¯ã以éã®èšç®ããã¹ãŠåæ¢ããŸãã
ã€ãŸãããã¹ãŠã®ã³ãŒããå®è¡ãããããã§ã¯ãããŸããã
ãŸãããã®æé©åã¯ãèšèªã®é
延ã®ãããã§ãå®å
šã«ç¡æã§å©çšã§ããŸãã
Maybe
å®çŸ©
(>>=)
ã䜿çšããŠããã®ã³ãŒããæžãæããããšãã§ããŸã
Maybe
ïŒ
instance Monad Maybe where (>>=) :: Maybe a -> (a -> Maybe b) -> Maybe b Nothing >>= _ = Nothing (Just x) >>= f = fx return x = Just x
Maybe
ããã®ãããªå°ããªäŸã§ãã¢ããã¯ãã®äŸ¡å€ã蚌æãã
Maybe
ã
IO
ã¢ããã®äœ¿çšã確èªããŸããã ãããããã£ãšèå³æ·±ãäŸããããŸã-ãªã¹ãã
03_å°ç/ 02_ã¢ãã/ 12_Monads.lhs
03_Hell / 02_Monads / 13_Monads.lhsãªã¹ãã¢ãã
ãªã¹ãã¢ããã䜿çšãããšãé決å®çãªèšç®ãã¢ãã«åã§ããŸãã
äŸïŒ
import Control.Monad (guard) allCases = [1..10] resolve :: [(Int,Int,Int)] resolve = do x <- allCases y <- allCases z <- allCases guard $ 4*x + 2*y < z return (x,y,z) main = do print resolve
MA GIãI .: [(1,1,7),(1,1,8),(1,1,9),(1,1,10),(1,2,9),(1,2,10)]
ãªã¹ãã¢ããçšã®æ§æç³è¡£ããããŸãïŒ print $ [ (x,y,z) | x <- allCases, y <- allCases, z <- allCases, 4*x + 2*y < z ]
ã¢ããã®å®å
šãªãªã¹ãã¯æäŸããŸãããããããã¯ãããããããŸããã¢ããã䜿çšãããšãå€ãã®ã¿ã¹ã¯ãç°¡çŽ åã§ããŸããç¹ã«ãã¢ããã¯æ¬¡ã®å Žåã«éåžžã«äŸ¿å©ã§ãã- IO
- é決å®çã³ã³ãã¥ãŒãã£ã³ã°ã
- æ¬äŒŒä¹±æ°ã®çæã
- æ§æã¹ãã¬ãŒãž
- ç¶æ
ã§åäœããŸã
- ...
ãã®å Žæã«çããããããã§ãšãããããŸãïŒããã§ã«ã³ããŒã¢ãããããããŸããïŒïŒãã¡ããããããã«æ
£ããã«ã¯ç·Žç¿ãå¿
èŠã§ããèªåã§æžããŠãã ãããããããããªãã¯ãã§ã«ãã®æ¹åã«å€§ããªäžæ©ãèžã¿åºããŠããŸãïŒ03_Hell / 02_Monads / 13_Monads.lhsã¢ããª
ãã®ã»ã¯ã·ã§ã³ã¯Haskellã®ç 究ã«ã¯çŽæ¥é©çšãããŸãããäžéšã®è©³çŽ°ã«ã®ã¿æ³šæãæã£ãŠããŸãã
04_ä»é²/ 01_More_on_infinite_trees / 10_Infinite_Trees.lhsç¡éã®æšã«ã€ããŠããäžã€
Infinite Structuresã»ã¯ã·ã§ã³ã§ã¯ãããã€ãã®åçŽãªç¡éæ§é ãèŠãŠããŸãããæ®å¿µãªãããããªãŒã«ã¯2ã€ã®ããããã£ããããŸããã- ããªãŒããŒãã«éè€ã¯ãããŸãã
- æŽç¶ãšããæš
ãã®ã»ã¯ã·ã§ã³ã§ã¯ãæåã®ããããã£ãæ±ããŸãã2çªç®ã«ã€ããŠã¯ãå°ã匱ããŸãããã§ããã ãçæ³ã«è¿ã¥ããããã«ããŸãããŸããäžé£ã®ç䌌乱æ°ãããªã¹ããäœæããŸãããã shuffle = map (\x -> (x*3123) `mod` 4331) [1..]
ã¡ã¢ãªãæŽæ°ããã«ã¯ãå®è£
ãè€è£œããŸã treeFromList
treeFromList :: (Ord a) => [a] -> BinTree a treeFromList [] = Empty treeFromList (x:xs) = Node x (treeFromList (filter (<x) xs)) (treeFromList (filter (>x) xs))
ããã³treeTakeDepth
ïŒ treeTakeDepth _ Empty = Empty treeTakeDepth 0 _ = Empty treeTakeDepth n (Node x left right) = let nl = treeTakeDepth (n-1) left nr = treeTakeDepth (n-1) right in Node x nl nr
çµæãèŠãŠã¿ãŸãããïŒ main = do putStrLn "take 10 shuffle" print $ take 10 shuffle putStrLn "\ntreeTakeDepth 4 (treeFromList shuffle)" print $ treeTakeDepth 4 (treeFromList shuffle)
% runghc 02_Hard_Part/41_Infinites_Structures.lhs take 10 shuffle [3123,1915,707,3830,2622,1414,206,3329,2121,913] treeTakeDepth 4 (treeFromList shuffle) < 3123 : |
ãã£ãïŒ
皌ãã ïŒãã ãããã©ã³ãã«è¿œå ãããã®ãããå Žåã«ã®ã¿æ©èœããŸããäŸïŒ
treeTakeDepth 4 (treeFromList [1..])
ç¡éã«å®è¡ãããŸããããã¯ãã³ãŒããåŒã®å
é ãååŸããããšããŠããããfilter (<1) [2..]
ã§ãããããfilter
ãåŒã®çµæã空ã®ãªã¹ãã§ããããšãç解ããã»ã©è³¢ãã¯ãããŸããããã ããããã¯éå³æ Œãªããã°ã©ã ãã§ããããšã®è¯ãäŸã§ããèªè
ã®ããã®ç·Žç¿ïŒ- æ°ãããããšã蚌æç¡éã«ãŒãã«é¥ã£ããã
n
treeTakeDepth n (treeFromList shuffle)
- ã®äžéãèŠã€ããŸã
n
ã - ãã®ãããª
shuffle
ãªã¹ãããªãããšã蚌æããã©ã¡ããå®è¡ããããšã«ãããããã°ã©ã ã¯çµäºããŸãã
04_ä»é²/ 01_More_on_infinite_trees / 10_Infinite_Trees.lhs
04_ä»é²/ 01_More_on_infinite_trees / 11_Infinite_Trees.lhsDavateã¯ãããã«å€æŽãããŠtreeFromList
ããshuffle
ããã®åé¡ãåãé€ãããã«äœæãããŠããŸããæåã®åé¡ã¯ç§ãã¡ã®å®è£
ã«ãããä¹±æ°ã®äžè¶³ã§ãshuffle
ãç°ãªãæ°å€ã®ã¿ãçæããŸãã4331
ãæ©èœãæ¹åããŸãshuffle
ã shuffle = map rand [1..] where rand x = ((px) `mod` (x+c)) - ((x+c) `div` 2) px = m*x^2 + n*x + o
ãã®ããŒãžã§ã³ã®é¢æ°ã¯ãå€ã«äžéãšäžéããªãã®ã§ïŒç§ã¯å¿ããé¡ã£ãŠããŸãïŒåªããŠããŸããããããã·ã£ããã«ã®æ¹åã¯ãç¡éã«ãŒããåé¿ããã®ã«ååã§ã¯ãããŸãããå³å¯ã«èšãã°ããªã¹ãã空ãã©ããã¯ããããŸããfilter (<x) xs
ããã®åé¡ã解決ããããã«ããã€ããªããªãŒã®å®è£
ãå°ãå£ããŸããæ°ããå®è£
ã§ã¯ãäžéšã®ããŒãã§æ¬¡ã®æ¡ä»¶ãæºããããŸãããå·Šã®èŠçŽ ïŒãŸãã¯å³ïŒã¯ââãããªãŒã®ã«ãŒãã®å€ãããå³å¯ã«å°ããïŒãŸãã¯å€§ããïŒå¿
èŠããããŸãã
ãã®å ŽåãããªãŒã¯å®è³ªçã«é åºä»ãããããŸãŸã«ãªããŸããããã«ãããªãŒãäœæãã段éã§ãããŒãã®äžææ§ã確ä¿ããŸããæ°ããããŒãžã§ã³ã§treeFromList
ã¯ãåã«ã«çœ®ãæããŸãfilter
ãsafefilter
ã treeFromList :: (Ord a, Show a) => [a] -> BinTree a treeFromList [] = Empty treeFromList (x:xs) = Node x left right where left = treeFromList $ safefilter (<x) xs right = treeFromList $ safefilter (>x) xs
ãã®é¢æ°ã¯safefilter
ã»ãŒåãã§ãfilter
ããç¡éããªãŒãåŠçãããšãã«ç¡éã«ãŒãã«é¥ãããšã¯ãããŸããã10,000ã¹ãããã§é©åãªã¢ã€ãã ãèŠã€ãããªãå Žåãæ€çŽ¢ãäžæ¢ããŸãã safefilter :: (a -> Bool) -> [a] -> [a] safefilter fl = safefilter' fl nbTry where nbTry = 10000 safefilter' _ _ 0 = [] safefilter' _ [] _ = [] safefilter' f (x:xs) n = if fx then x : safefilter' f xs nbTry else safefilter' f xs (n-1)
ããã°ã©ã ãå®è¡ããŠåã¶ïŒ main = do putStrLn "take 10 shuffle" print $ take 10 shuffle putStrLn "\ntreeTakeDepth 8 (treeFromList shuffle)" print $ treeTakeDepth 8 (treeFromList $ shuffle)
ç°ãªãå€ã®è¡šç€ºéã®é
延ãåãã§ã¯ãªãããšã«æ°ã¥ãããããããŸãããããã¯ãHaskellãå¿
èŠã«å¿ããŠåå€ãèšç®ããããã§ãããã®å Žåãçªå·ãç»é¢ã«è¡šç€ºããããšãã«å¿
èŠã«ãªããŸããæ€çŽ¢ã®æ·±ãããã8
ã«å¢ãããŠã100
ããã®é¢æ°ã¯æ©èœããŸãããåæã«ãã¹ãŠã®RAMãæ¶è²»ããããšã¯ãããŸããïŒèªè
ã®ããã®ç·Žç¿ïŒ treeFromList' [] n = Empty treeFromList' (x:xs) n = Node x left right where left = treeFromList' (safefilter' (<x) xs (fn) right = treeFromList' (safefilter' (>x) xs (fn) f = ???
04_Appendice/01_More_on_infinite_trees/ 11_Infinite_Trees.lhs( , )
ããããšã/r/haskell
ãš/r/programming
ãããªãã®ã³ã¡ã³ãã¯éåžžã«è²Žéã§ããç¹ã«ãè±èªã®ããã¹ãã®æŽæ°ã«è²»ãããæéã«ã€ããŠãEmmã« 1000åæè¬ããŸããããããšãããããŸã