{"id":138,"date":"2016-01-03T14:48:44","date_gmt":"2016-01-03T05:48:44","guid":{"rendered":"http:\/\/mitsuji.org\/?p=138"},"modified":"2016-01-05T18:57:17","modified_gmt":"2016-01-05T09:57:17","slug":"state%e3%83%a2%e3%83%8a%e3%83%89%e3%81%ae%e4%bd%bf%e3%81%84%e9%81%93-%e7%b4%94%e7%b2%8b%e9%96%a2%e6%95%b0%e5%86%85%e3%81%a7%e7%8a%b6%e6%85%8b%e3%82%92%e6%89%b1%e3%81%86","status":"publish","type":"post","link":"https:\/\/mitsuji.org\/?p=138","title":{"rendered":"State\u30e2\u30ca\u30c9\u306e\u4f7f\u3044\u9053 \u7d14\u7c8b\u95a2\u6570\u5185\u3067\u72b6\u614b\u3092\u6271\u3046"},"content":{"rendered":"<p>System.Random \u306b\u3064\u3044\u3066\u8abf\u3079\u308b\u30b3\u30fc\u30c9\u3092\u8003\u3048\u3066\u307f\u3088\u3046\u3002<br \/>\n0\u304b\u30899\u307e\u3067\u306e\u30e9\u30f3\u30c0\u30e0\u306a\u6574\u6570\u3092\u7e70\u308a\u8fd4\u3057\u751f\u6210\u3059\u308b\u3068\u304d\u3001\u6700\u521d\u306b5\u304c\u73fe\u308c\u308b\u306e\u304c\u4f55\u56de\u76ee\u304b\u77e5\u308a\u305f\u3044\u3068\u3059\u308b\u3002<\/p>\n<p>System.Random \u306b\u306f randomRs \u3068\u3044\u3046\u95a2\u6570\u304c\u3042\u308a\u3001\u578b\u3068\u7bc4\u56f2\u3068\u4e71\u6570\u751f\u6210\u5668\u3092\u6307\u5b9a\u3059\u308b\u3068\u3001\u30e9\u30f3\u30c0\u30e0\u306a\u5024\u306e\u7121\u9650\u30ea\u30b9\u30c8\u306b\u8a55\u4fa1\u3055\u308c\u308b\u3002<br \/>\n\u3053\u306e\u95a2\u6570\u3068\u30ea\u30b9\u30c8\u3092\u64cd\u4f5c\u3059\u308b\u95a2\u6570\u3092\u4f7f\u3048\u3070\u3001\u4e0b\u8a18\u306e\u3088\u3046\u306b\u3059\u3063\u304d\u308a\u8a18\u8ff0\u3067\u304d\u308b\u3002<\/p>\n<p>\u5834\u5408\u306b\u3088\u3063\u3066\u306f\u3053\u308c\u3067\u5341\u5206\u3060\u308d\u3046\u3002\u305f\u3060\u3001\u51e6\u7406\u52b9\u7387\u3084\u53ef\u8aad\u6027\u306e\u9762\u3067\u3001\u3088\u308a\u624b\u7d9a\u304d\u578b\u306b\u8fd1\u3044\u8a18\u8ff0\u306b\u3057\u305f\u3044\u5834\u9762\u304c\u3042\u308a\u305d\u3046\u3060\u3002<\/p>\n<pre class=\"lang:haskell\">\ncount :: R.RandomGen g => g -> Int -> Int\ncount g n = length $ takeWhile (\/=n) $ R.randomRs (0::Int,9) g\n\n--\n-- trace version\n--\ncount' :: R.RandomGen g => g -> Int -> Int\ncount' g n = length $ takeWhile (\\x -> trace (\"x: \" ++ show x) (x\/=n)) $ R.randomRs (0::Int,9) g\n\n\n<\/pre>\n<h2>\u65b9\u6cd51. State\u30e2\u30ca\u30c9\u3092\u4f7f\u3046<\/h2>\n<p>System.Random \u306b\u306f randomR \u3068\u3044\u3046\u95a2\u6570\u304c\u3042\u308a\u3001\u578b\u3068\u7bc4\u56f2\u3068\u4e71\u6570\u751f\u6210\u5668\u3092\u6307\u5b9a\u3059\u308b\u3068\u3001\u30e9\u30f3\u30c0\u30e0\u306a\u5024\u3068\u65b0\u3057\u3044\u4e71\u6570\u751f\u6210\u5668\u306e\u7d44\u306b\u8a55\u4fa1\u3055\u308c\u308b\u3002randomRs \u306e\u5358\u767a\u7248\u3067\u3042\u308b\u3002<\/p>\n<p>execState \u306f\u521d\u671f\u72b6\u614b\u3068 State\u30e2\u30ca\u30c9\u3092\u4f7f\u7528\u3059\u308b\u95a2\u6570\u3092\u6307\u5b9a\u3059\u308b\u3068\u3001\u7d42\u4e86\u72b6\u614b\u306b\u8a55\u4fa1\u3055\u308c\u308b\u95a2\u6570\u3060\u3002<br \/>\nState\u30e2\u30ca\u30c9\u306f\u3001\u526f\u4f5c\u7528\u3092\u6271\u3046\u3068\u3044\u3046\u70b9\u3067\u306fIO\u30e2\u30ca\u30c9\u3068\u4f3c\u3066\u3044\u308b\u304c\u3001\u7d14\u7c8b\u95a2\u6570\u5185\u306b\u9589\u3058\u8fbc\u3081\u3089\u308c\u308b\u70b9\u304c\u7570\u306a\u308b\u3002<br \/>\nState\u30e2\u30ca\u30c9\u5185\u3067\u73fe\u5728\u306e\u72b6\u614b\u3092\u5f97\u308b\u306b\u306fget\u3092\u3001\u72b6\u614b\u3092\u66f4\u65b0\u3059\u308b\u306b\u306fput\u3092\u4f7f\u7528\u3059\u308b\u3002<\/p>\n<pre class=\"lang:haskell\">\n\ncountState :: R.RandomGen g => g -> Int -> Int\ncountState g n = snd $ execState loop (g,0)\n  where\n    loop :: R.RandomGen g => State (g,Int) ()\n    loop = do\n      (g,i) <- get\n      let (x,g') = R.randomR (0::Int,9) g\n      when (x\/=n) $ put (g',i+1) >> loop -- n \u3068\u540c\u3058\u5024\u304c\u51fa\u308b\u307e\u3067\u3001\u72b6\u614b\u3092\u66f8\u304d\u63db\u3048\u3066\u7e70\u308a\u8fd4\u3059\n\n--\n-- trace version\n--\ncountState' :: R.RandomGen g => g -> Int -> Int\ncountState' g n = snd $ execState loop (g,0)\n  where\n    loop :: R.RandomGen g => State (g,Int) ()\n    loop = do\n      (g,i) <- get\n      let (x,g') = R.randomR (0::Int,9) g\n      when (trace (\"x: \" ++ show x) (x\/=n)) $ put (g',i+1) >> loop\n\n<\/pre>\n<h2>\u65b9\u6cd52. ST\u30e2\u30ca\u30c9\u3092\u4f7f\u3046<\/h2>\n<p>\u307e\u305f\u3001IO\u30e2\u30ca\u30c9\u304b\u3089\u5165\u51fa\u529b\u306b\u95a2\u3059\u308b\u6a5f\u80fd\u3092\u53d6\u308a\u9664\u304d\u3001\u7d14\u7c8b\u95a2\u6570\u5185\u3067\u8a55\u4fa1\u3067\u304d\u308b\u3088\u3046\u306b\u3057\u305f\u3001ST\u30e2\u30ca\u30c9\u3082\u4f7f\u7528\u3067\u304d\u308b\u3002<br \/>\nIO\u30e2\u30ca\u30c9\u5185\u3067 IORef \u3092\u4f7f\u7528\u3059\u308b\u611f\u899a\u3067 ST\u30e2\u30ca\u30c9\u5185\u3067\u4f7f\u7528\u3067\u304d\u308b STRef\u3068\u3044\u3046\u578b\u304c\u3042\u308a\u3001\u72b6\u614b\u3092\u4fdd\u6301\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u308b\u3002<br \/>\nSTRef \u306f \u8907\u6570\u4f5c\u6210\u3057\u3066\u3082\u826f\u3044\u306e\u3067\u72b6\u614b\u306e\u7ba1\u7406\u304c\u8907\u96d1\u306a\u3068\u304d\u306f\u4fbf\u5229\u304b\u3082\u3057\u308c\u306a\u3044\u3002<\/p>\n<pre class=\"lang:haskell\">\n\ncountST :: R.RandomGen g => g -> Int -> Int\ncountST g n = runST $ do\n  ref <- newSTRef (g,0)\n  loop ref\n  (_,i) <- readSTRef ref -- \u7e70\u308a\u8fd4\u3057\u305f\u56de\u6570\u3092\u53d6\u308a\u51fa\u3057\u3066\u5831\u544a\n  return i\n    where\n      loop :: R.RandomGen g => STRef s (g,Int) -> ST s ()\n      loop ref = do\n        (g,i) <- readSTRef ref\n        let (x,g') = R.randomR (0::Int,9) g\n        when (x\/=n) $ writeSTRef ref (g',i+1) >> loop ref -- n \u3068\u540c\u3058\u5024\u304c\u51fa\u308b\u307e\u3067\u3001\u72b6\u614b\u3092\u66f8\u304d\u63db\u3048\u3066\u7e70\u308a\u8fd4\u3059\n\n--\n-- trace version\n--\ncountST' :: R.RandomGen g => g -> Int -> Int\ncountST' g n = runST $ do\n  ref <- newSTRef (g,0)\n  loop ref\n  (_,i) <- readSTRef ref\n  return i\n    where\n      loop :: R.RandomGen g => STRef s (g,Int) -> ST s ()\n      loop ref = do\n        (g,i) <- readSTRef ref\n        let (x,g') = R.randomR (0::Int,9) g\n        when (trace (\"x: \" ++ show x) (x\/=n)) $ writeSTRef ref (g',i+1) >> loop ref\n\n<\/pre>\n<p>\u5168\u90e8\u306e\u305b\u3066\u304a\u304f\u3002<\/p>\n<pre class=\"lang:haskell\">\nimport qualified System.Random as R\nimport Debug.Trace (trace)\n\nimport Control.Monad (when)\nimport Control.Monad.State(State,execState,get,put)\nimport Control.Monad.ST(ST,runST)\nimport Data.STRef(STRef,newSTRef,readSTRef,writeSTRef)\n\n\nmain = do\n  g <- R.newStdGen\n  print $ count g 5\n  print $ countState g 5\n  print $ countST g 5\n  print $ count' g 5\n  print $ countState' g 5\n  print $ countST' g 5\n\n\n\ncount :: R.RandomGen g => g -> Int -> Int\ncount g n = length $ takeWhile (\/=n) $ R.randomRs (0::Int,9) g\n\n--\n-- trace version\n--\ncount' :: R.RandomGen g => g -> Int -> Int\ncount' g n = length $ takeWhile (\\x -> trace (\"x: \" ++ show x) (x\/=n)) $ R.randomRs (0::Int,9) g\n\n\n\ncountState :: R.RandomGen g => g -> Int -> Int\ncountState g n = snd $ execState loop (g,0)\n  where\n    loop :: R.RandomGen g => State (g,Int) ()\n    loop = do\n      (g,i) <- get\n      let (x,g') = R.randomR (0::Int,9) g\n      when (x\/=n) $ put (g',i+1) >> loop\n\n--\n-- trace version\n--\ncountState' :: R.RandomGen g => g -> Int -> Int\ncountState' g n = snd $ execState loop (g,0)\n  where\n    loop :: R.RandomGen g => State (g,Int) ()\n    loop = do\n      (g,i) <- get\n      let (x,g') = R.randomR (0::Int,9) g\n      when (trace (\"x: \" ++ show x) (x\/=n)) $ put (g',i+1) >> loop\n      \n\n\ncountST :: R.RandomGen g => g -> Int -> Int\ncountST g n = runST $ do\n  ref <- newSTRef (g,0)\n  loop ref\n  (_,i) <- readSTRef ref\n  return i\n    where\n      loop :: R.RandomGen g => STRef s (g,Int) -> ST s ()\n      loop ref = do\n        (g,i) <- readSTRef ref\n        let (x,g') = R.randomR (0::Int,9) g\n        when (x\/=n) $ writeSTRef ref (g',i+1) >> loop ref\n\n--\n-- trace version\n--\ncountST' :: R.RandomGen g => g -> Int -> Int\ncountST' g n = runST $ do\n  ref <- newSTRef (g,0)\n  loop ref\n  (_,i) <- readSTRef ref\n  return i\n    where\n      loop :: R.RandomGen g => STRef s (g,Int) -> ST s ()\n      loop ref = do\n        (g,i) <- readSTRef ref\n        let (x,g') = R.randomR (0::Int,9) g\n        when (trace (\"x: \" ++ show x) (x\/=n)) $ writeSTRef ref (g',i+1) >> loop ref\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>System.Random \u306b\u3064\u3044\u3066\u8abf\u3079\u308b\u30b3\u30fc\u30c9\u3092\u8003\u3048\u3066\u307f\u3088\u3046\u3002 0\u304b\u30899\u307e\u3067\u306e\u30e9\u30f3\u30c0\u30e0\u306a\u6574\u6570\u3092\u7e70\u308a\u8fd4\u3057\u751f\u6210\u3059\u308b\u3068\u304d\u3001\u6700\u521d\u306b5\u304c\u73fe\u308c\u308b\u306e\u304c\u4f55\u56de\u76ee\u304b\u77e5\u308a\u305f\u3044\u3068\u3059\u308b\u3002 System.Random \u306b\u306f randomRs \u3068\u3044 &hellip; <a href=\"https:\/\/mitsuji.org\/?p=138\" class=\"more-link\">\u7d9a\u304d\u3092\u8aad\u3080 <span class=\"screen-reader-text\">State\u30e2\u30ca\u30c9\u306e\u4f7f\u3044\u9053 \u7d14\u7c8b\u95a2\u6570\u5185\u3067\u72b6\u614b\u3092\u6271\u3046<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[6],"tags":[3,5],"_links":{"self":[{"href":"https:\/\/mitsuji.org\/index.php?rest_route=\/wp\/v2\/posts\/138"}],"collection":[{"href":"https:\/\/mitsuji.org\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mitsuji.org\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mitsuji.org\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/mitsuji.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=138"}],"version-history":[{"count":4,"href":"https:\/\/mitsuji.org\/index.php?rest_route=\/wp\/v2\/posts\/138\/revisions"}],"predecessor-version":[{"id":142,"href":"https:\/\/mitsuji.org\/index.php?rest_route=\/wp\/v2\/posts\/138\/revisions\/142"}],"wp:attachment":[{"href":"https:\/\/mitsuji.org\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=138"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mitsuji.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=138"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mitsuji.org\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=138"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}