Skip to content

Instantly share code, notes, and snippets.

@7shi
Created August 19, 2015 02:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save 7shi/d2951a7f40be7e827c2f to your computer and use it in GitHub Desktop.
Save 7shi/d2951a7f40be7e827c2f to your computer and use it in GitHub Desktop.
[Haskell] 継続モナドによる脱出をEitherモナドで模倣
import Data.Char
import Control.Monad.Cont
fun :: Int -> String
fun n = (`runCont` id) $ do
str <- callCC $ \exit1 -> do -- "exit1" を定義
when (n < 10) $ exit1 $ show n
let ns = map digitToInt $ show $ n `div` 2
n' <- callCC $ \exit2 -> do -- "exit2" を定義
when (length ns < 3) $ exit2 $ length ns
when (length ns < 5) $ exit2 n
when (length ns < 7) $ do
let ns' = map intToDigit $ reverse ns
exit1 $ dropWhile (== '0') ns' -- escape 2 levels
return $ sum ns
return $ "(ns = " ++ show ns ++ ") " ++ show n'
return $ "Answer: " ++ str
fun' n = -- Either で模倣
let str = either id id $ do
let exit1 = Left -- "exit1" を定義
when (n < 10) $ exit1 $ show n
let ns = map digitToInt $ show $ n `div` 2
n' <- either id id $ do
let return = Right . Right -- "return" を再定義
exit1 = Left . Left -- "exit1" を再定義
exit2 = Left . Right -- "exit2" を 定義
when (length ns < 3) $ exit2 $ length ns
when (length ns < 5) $ exit2 n
when (length ns < 7) $ do
let ns' = map intToDigit $ reverse ns
exit1 $ dropWhile (== '0') ns' -- escape 2 levels
return $ sum ns
return $ "(ns = " ++ show ns ++ ") " ++ show n'
in "Answer: " ++ str
main = do
forM_ [0..7] $ \i -> do
let n = 5 * 10 ^ i
f1 = fun n
f2 = fun' n
print (i, n, f1 == f2, f1)
@7shi
Copy link
Author

7shi commented Aug 19, 2015

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment