rewrite with custom Monad (without monad transformer)
Some checks failed
Lean Action CI / build (push) Has been cancelled

This commit is contained in:
qwjyh 2024-10-21 22:27:06 +09:00
parent 3124f2bf78
commit 8d6fc4d214

View file

@ -4,6 +4,31 @@ structure Config where
useASCII : Bool := false useASCII : Bool := false
currentPrefix : String := "" currentPrefix : String := ""
def ConfigIO (α : Type) : Type :=
Config → IO α
instance : Monad ConfigIO where
pure x := fun _ => pure x
bind result next := fun cfg => do
let v ← result cfg
next v cfg
#print ConfigIO
#check (Monad ConfigIO)
#check Monad.mk
def ConfigIO.run (action : ConfigIO α) (cfg : Config) : IO α :=
action cfg
def currentConfig : ConfigIO Config :=
fun cfg => pure cfg
def locally (change : Config → Config) (action : ConfigIO α) : ConfigIO α :=
fun cfg => action (change cfg)
def runIO (action : IO α) : ConfigIO α :=
fun _ => action
def usage : String := def usage : String :=
"Usage: doug [--ascii] "Usage: doug [--ascii]
Options: Options:
@ -43,11 +68,11 @@ Modify `cfg` on entering a directory.
def Config.inDirectory (cfg : Config) : Config := def Config.inDirectory (cfg : Config) : Config :=
{cfg with currentPrefix := cfg.preDir ++ " " ++ cfg.currentPrefix} {cfg with currentPrefix := cfg.preDir ++ " " ++ cfg.currentPrefix}
def showFileName (cfg : Config) (file : String) : IO Unit := do def showFileName (file : String) : ConfigIO Unit := do
IO.println (cfg.fileName file) runIO (IO.println ((← currentConfig).fileName file))
def showDirName (cfg : Config) (dir : String) : IO Unit := do def showDirName (dir : String) : ConfigIO Unit := do
IO.println (cfg.dirName dir) runIO (IO.println ((← currentConfig).dirName dir))
def doList [Applicative f] : List α → (α → f Unit) → f Unit def doList [Applicative f] : List α → (α → f Unit) → f Unit
| [], _ => pure () | [], _ => pure ()
@ -55,21 +80,21 @@ def doList [Applicative f] : List α → (α → f Unit) → f Unit
action x *> action x *>
doList xs action doList xs action
partial def dirTree (cfg : Config) (path : System.FilePath) : IO Unit := do partial def dirTree (path : System.FilePath) : ConfigIO Unit := do
match ← toEntry path with match ← runIO (toEntry path) with
| none => pure () | none => pure ()
| some (.file name) => showFileName cfg name | some (.file name) => showFileName name
| some (.dir name) => | some (.dir name) =>
showDirName cfg name showDirName name
let contents ← path.readDir let contents ← runIO path.readDir
let newConfig := cfg.inDirectory locally (·.inDirectory)
doList contents.toList fun d => (doList contents.toList fun d =>
dirTree newConfig d.path dirTree d.path)
def main (args : List String) : IO UInt32 := do def main (args : List String) : IO UInt32 := do
match configFromArgs args with match configFromArgs args with
| some config => | some config =>
dirTree config (← IO.currentDir) (dirTree (← IO.currentDir)).run config
pure 0 pure 0
| none => | none =>
IO.eprintln s!"Didn't understand argument(s) {" ".intercalate args}\n" IO.eprintln s!"Didn't understand argument(s) {" ".intercalate args}\n"