ãã¦ãæ°åãå¤ã㦠ArrowLoop ãããã¾ããè«æã«æ¸ãã¦ãã
loop f b = let (c,d) = f (b,d) in c
ã®æå³ãå ¨ãåãããªã㦠Arrow ã®åå¼·ãä¸ã¶æè¿ãåæ»ãã¦ããã®ã§ãããid:MaD ãããç´ æ´ããã解説 http://d.hatena.ne.jp/MaD/20070818 ãæ¸ããã¦ããã®ã§èªåãªãã«åçµãã¾ããloop ã使ã£ã¦æ®éã®ã«ã¼ããä½ãã«ã¯ãå¼æ°ã¨ãã¦é¢æ°ãä¸ã¤ä¸ãã¾ããé¢æ°ã®å㯠(b,d) -> (c,d) ã®ãããªå ¥åºåã¨ãã¿ãã«ã¨ãã¾ããããããå³ã§ç¤ºãã¨ãã¿ãã«ã®å¾ãã®å¼æ°ããããã¨å ¥åã«ç¹ãããå½¢ããã¦ãã¾ãã
import Control.Arrow nonsense (b, d) = (b + 1, d * 2) -- *Main> loop nonsense 1 -- 2 -- ãã®ããããç¡ãä¾ã§ã¯ãb + 1 ã ããå®è¡ããã¦ãd * 2 ã«ã¯ä½ã®å¹æ -- ãç¡ãããã§ããããã§ã¯ãããã«è©°ã¾ããªãã®ã§ãb 㨠d ãå ¥ãæ¿ã㦠-- "ããããã"ã«ãã¦ã¿ã¾ãã nonsense' (b, d) = (d + 1, b * 2) -- *Main> loop nonsense' 1 -- 3 -- å¼æ° 1 -> b * 2 -> d + 1 -> çã 3 ã®é ã«å®è¡ããã¦ããããã§ãã -- Haskell ã¯éæ£æ ¼ãªã®ã§ãå®éã¯ã -- * çãã欲ããï¼ -- * d + 1 ã欲ããï¼ (loop ã®å®ç¾©ãããnonsense' ã®ã²ã¨ã¤ãã®è§£) -- * d ã欲ããï¼ -- * b * 2 ã欲ããï¼ (loop ã®å®ç¾©ãããnonsense' ã®ãµãã¤ãã®è§£) -- * b ã欲ããï¼ -- * b ã« 1 ãä¸ãããã -- ã¨éã«å¼ã£å¼µãããããã«å®è¡ããã¦ããã¾ãããã®éã«å¼ã£å¼µãããæ -- ãã¯å¦ã«æããã¾ãããè¦ããã« Excel ã®ã»ã«è¨ç®ã®è¦é ã¨åãã§ãã -- 次㫠1, 1, 1,... ã¨ç¡éã«ããæ°åãåºãæ¹æ³ã§ãã rep (b, d) = (d, b:d) -- Main> take 5 (loop rep 1) -- [1,1,1,1,1] -- * d ã欲ãã (loop ã®å®ç¾©ãããrep ã®ã²ã¨ã¤ãã®è§£) -- * b:d ã欲ãã (d = b:d ãªã®ã§) -- * b:d 㯠1,1,1,1,... (ããéè¦ï¼) -- * d 㯠1,1,1,1,... -- ãªã d = b:d ã¨ããå®ç¾©ãå¯è½ã§ãããã 1,1,1,... ãçãã®ãã¨ãã -- ã®ã¯å¤§åãªè©±ãªã®ã§ãtake 5 d where d = 1:d ãªã©ãå³ãããªããèãã -- ã¨è¯ãã§ããçµå±ãé¢æ°ã®äºçªç®ã®è§£ã工夫ããã°ã«ã¼ããæ¸ããäºãå -- ããã¾ãã次㯠3, 2, 1, 0 ã§ãã countdown (x, f) = (f x, cd) where cd 0 = [0] cd n = n : f (n - 1) -- *Main> loop countdown 3 -- [3,2,1,0] -- ããã¯çãããã«æ¿ããåããã«ããã®ã§ãã£ããå³ããã¾ããããäºçª -- ç®ã® Arrow ã«å¤ã§ã¯ãªãé¢æ°ã渡ãã¦ãã¾ããèªåèªèº«ãåç §ããäºç¡ã -- å帰ãå®ç¾©ãã Y ã³ã³ããã¼ã¿ã¨ãããã¤ã§ããããã¯ä»¥ä¸ã®åç´ãªå帰 -- é¢æ°ãå¤å½¢ãã¦ä½ãã¾ãããå³è¾ºã® down ã f ã«å¤ããã ãã§ãã down 0 = [0] down n = n : down (n - 1) -- ç·´ç¿ã¨ãã¦ãæ«å°¾å帰çããã£ã¦ã¿ã¾ãããæ®éãå帰çã«é¢æ°ãå®ç¾©ã -- ãã¨ãæåã®ä¾ã§ã¯[3,2,1,0] ã®ãããªæ°åãæ±ããããã«ä»¥ä¸ã®ããã« -- ã¹ã¿ãã¯ãæãé²ãã¦åãã¦è¡ããããªä½æ¥ã«ãªãã¾ãã -- down 3 = 3 : down 2 -- æãé²ãã -- = 3 : (2 : down 1) -- æãé²ãã -- = 3 : (2 : (1 : down 0)) -- æãé²ãã -- = 3 : (2 : (1 : [0])) -- çªå µçºè¦ -- = 3 : (2 : [1, 0]) -- åæ -- = 3 : [2, 1, 0] -- åæ -- = [3, 2, 1, 0] -- åæ -- ããã¯ç°¡æ½ã«è¨è¿°åºæ¥ãä¸æ¹ã§æ°ãå¢ããã¨å¤§å¤ç¡é§ãªè©±ã§ã(Haksell 㧠-- ã¯çå±ãéãã¨ã©ããã§èãã¾ããããæ£ãã話ã¯å¿ãã¾ãã)ãæ«å°¾å帰 -- ã使ãã¨ã¹ãã¬ã¼ãã«çããå¾ãäºãåºæ¥ã¾ããæ«å°¾å帰ãä½ãã«ã¯ãåª -- ä»å¤æ°ãä¸ã¤ä½è¨ã«å¿ è¦ã«ãªãã¾ãã down_tail n = down_tail' n [0] down_tail' 0 xs = xs down_tail' n (x:xs) = down_tail' (n - 1) (x + 1:x:xs) -- down_tail 3 = down_tail' 3 [0] -- = down_tail' 2 [1, 0] -- = down_tail' 1 [2, 1, 0] -- = down_tail' 0 [3, 2, 1, 0] -- çªå µçºè¦ -- = [3, 2, 1, 0] countdown_tail (x, f) = (f x [0], cd) where cd 0 xs = xs cd n (x:xs) = f (n - 1) (x + 1:x:xs) -- *Main> loop countdown_tail 3 -- [3,2,1,0] -- MaD ããã®ä¾ã§ã¯ããã«ã©ãã©ããã¤ã³ãããªã¼ã«å¤å½¢ãã¦è¡ãã®ã§çä¼¼ -- ãã¦countdown ãå¤å½¢ãã¦ã¿ã¾ããå¿ä½ç¡ãã§ãããã¿ã¼ã³ããããå±éã -- ä¸å¯§ã«åãã¤ããªãã確èªãã¦è¡ãã¾ãã countdown_arrow' :: (Int, Int -> [Int]) -> ([Int], Int -> [Int]) countdown_arrow' = \(x, f) -> (f x, \n -> if n == 0 then [0] else n : f (n - 1)) -- å ¥åã (x, f) ã®ã¿ãã«ãåºåãã¿ãã«ã§ãããã¿ãã«ã® fst ã«æ³¨ç®ãã¾ -- ããarrow åããã¨ãapp ã使ã£ã¦æ¬¡ã®ããã«ãªãã¾ãã countdown_answer :: (Int, Int -> [Int]) -> [Int] countdown_answer = snd &&& fst >>> app -- *Main> countdown_answer (1, (:[0])) -- [1,0] -- 次ã«ã¿ãã«ã® snd ã® \(x, f) -> \n -> n : f (n - 1) ã arrow åãã¾ãã -- (n - 1) => pred 1 -- f (n - 1) => pred >>> f -- n : f (n - 1) => id &&& pred >>> f >>> uncurry (:) -- f ãçãä¸ãªã®ãå ¥åã«æã£ã¦ãã¾ãã countdown_recursion :: (Int, Int -> [Int]) -> Int -> [Int] countdown_recursion = snd >>> (pred >>>) >>> (id &&&) >>> (>>> uncurry (:)) -- æ¡ä»¶æ㯠arrow ã«ç¡ãã®ã§èªä½ãã¾ãã ifzero 0 = Left 0 ifzero x = Right x -- ã¨ããäºã§ \(x, f) -> \n -> if n == 0 then [0] else n : f (n - 1) -- ã® arrow å countdown_function :: (Int, Int -> [Int]) -> Int -> [Int] countdown_function = snd >>> (pred >>>) >>> (id &&&) >>> (>>> uncurry (:)) >>> (const [0] |||) >>> (ifzero >>>) -- ãã£ã¤ãã countdown_arrow'' :: (Int, Int -> [Int]) -> ([Int], Int -> [Int]) countdown_arrow'' = countdown_answer &&& countdown_function -- åèã¾ã§ã«ãå±éãã㨠countdown_arrow :: (Int, Int -> [Int]) -> ([Int], Int -> [Int]) countdown_arrow = (snd &&& fst >>> app) &&& (snd >>> (pred >>>) >>> (id &&&) >>> (>>> uncurry (:)) >>> (const [0] |||) >>> (ifzero >>>)) -- *Main> loop countdown_arrow 3 -- [3,2,1,0] -- ææ³: è¶ ããã©ãããããããç²ãã¦ä½ãæ¸ããããªãããå¦æ³ã¢ã¼ã㧠-- ããããäºãã£ã¦ãæ義ãæ¸ããã«ã¼ããæç¶ãçãé¢æ°çã«æ¸ãæ¹ãç°¡ -- åã§åãããããã®ã«ãä½æ ãããªäºãã£ã¦ãã®ã§ããããï¼ãã®å ã«ä½ -- ãè¦ããã®ã§ããããï¼ç§ã¯ãã®å ã«ã«ã¼ãã®æ¬å½ã®å§¿ãããã¨æãã¾ãã -- æç¶ãçã«ã«ã¼ããæ¸ãã®ã¯å¤©å説ã®ãããªç©ã§ããã¤ã¾ãããããã£ã¦ -- 欲ãã姿ã¨ãæ¬å½ã®å§¿ãåãéãã¦ããã天å説ã¯ãæ®æ®µã®ç©ºã®åããè¨ -- è¿°ããã®ã«å åã§ããã天å説ã«åãããäºã§æ¬å½ã®çãã®å¦¨ãã«ãªã£ã¦ -- ãã¾ãã¾ãã -- ã«ã¼ãã®ãããªäººå·¥çãªæ¦å¿µã«ããæ¬å½ã®å§¿ããããã¨ããããããã¯ã¡ã㣠-- ã¨æå¤ãªäºã§ãåãå ¥ããããç©ããç¥ãã¾ãããããããã§ã«ç§ãã¡ã¯ -- 確çãéåã§ãç´æã¨æ°å¦çãªäºå®ããã¿åããªãäºãããç¥ã£ã¦ãã¾ãã -- arrow ã¯(ã¨ãããã³ã³ããã¼ã¿ã¯)ç§ãã¡ã®ç¥ã£ã¦ããæ¦å¿µãæå°ã®åå -- ã«ã¾ã§å解ãã¦åæ§æãã¾ããå ¨ç¶å¥ã ã¨æã£ã¦ããäºå®ã«æå¤ãªå ±éç¹ -- ãè¦ã¤ããè¯ãæ¹æ³ã§ãããã®éç¨ã§ã«ã¼ãããæ¬å½ã¯ãã£ã¨åºãæ¦å¿µã® -- ä¸é¨ã ã¨ãããã©ãã§ãããããJoy ã®ã«ã¼ãã dup ã ãã§æ¸ããã¦ãã -- ã®ãè¦ãæã«ãã«ã¼ããç§ã®å ¨ç¶ç¥ããªã姿ããã¦ããäºã«ã³ã£ãããã -- ã®ã§ããã«ã¼ããæç¶ãçã«ã ãè¦ãã®ã¯ã鯨ãéã¨æããããªè¡¨é¢ç㪠-- èãã§ããã³ã³ããã¼ã¿ã®ååã«å解ããã¨ããã£ã¨é¢ç½ãã¦å½¹ã«ç«ã¤ä¸ -- çãåºãã£ã¦ãã¾ããçãã¦ã¦è¯ãã£ãã