Skip to content

Instantly share code, notes, and snippets.

@kana-sama
Last active April 6, 2022 19:11
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 kana-sama/66bd3365b7a8835ebf91da0dcc6aad9e to your computer and use it in GitHub Desktop.
Save kana-sama/66bd3365b7a8835ebf91da0dcc6aad9e to your computer and use it in GitHub Desktop.
{-# LANGUAGE BlockArguments #-}
{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE LambdaCase #-}
import Control.Monad (ap)
import System.IO (Handle, IOMode (ReadMode, WriteMode), hGetLine, hPutStrLn, stdin, stdout, withFile)
data MyIO a
= Pure a
| GetLine {handle :: Handle, next_getLine :: String -> MyIO a}
| PutStrLn {handle :: Handle, str_putStrLn :: String, next_putStrLn :: MyIO a}
deriving stock (Functor)
instance Applicative MyIO where
pure = Pure
(<*>) = ap
instance Monad MyIO where
Pure x >>= f = f x
GetLine h k >>= f = GetLine h \s -> k s >>= f
PutStrLn h s k >>= f = PutStrLn h s (k >>= f)
myGetLine :: MyIO String
myGetLine = GetLine stdin Pure
myPutStrLn :: String -> MyIO ()
myPutStrLn str = PutStrLn stdout str (Pure ())
run :: MyIO a -> IO a
run = \case
Pure x -> pure x
GetLine h k -> hGetLine h >>= run . k
PutStrLn h s k -> hPutStrLn h s >> run k
main :: IO ()
main = do
withFile "package.yaml" ReadMode \h1 ->
withFile "test" WriteMode \h2 -> run do
x <- myGetLine
y <- myGetLine {handle = h1}
myPutStrLn y
(myPutStrLn x) {handle = h2}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment