doug/Doug/Basic.lean
qwjyh e2003d0898
Some checks are pending
Lean Action CI / build (push) Waiting to run
rewrite with Monad transformer
2024-10-22 17:02:57 +09:00

85 lines
2.3 KiB
Text
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

def hello := "world"
structure Config where
useASCII : Bool := false
currentPrefix : String := ""
abbrev ConfigIO (α : Type) : Type := ReaderT Config IO α
#check read
#print ConfigIO
#check (Monad ConfigIO)
#check MonadLift
#check MonadWithReader
#check outParam
def currentConfig : ConfigIO Config :=
fun cfg => pure cfg
def usage : String :=
"Usage: doug [--ascii]
Options:
\t--ascii\tUse ASCII characters to display the directry structure"
def configFromArgs : List String → Option Config
| [] => some {}
| ["--ascii"] => some {useASCII := true}
| _ => none
inductive Entry where
| file : String → Entry
| dir : String → Entry
def toEntry (path : System.FilePath) : IO (Option Entry) := do
match path.components.getLast? with
| none => pure (some (.dir ""))
| some "." | some ".." => pure none
| some name =>
pure (some (if (← path.isDir) then .dir name else .file name))
def Config.preFile (cfg : Config) :=
if cfg.useASCII then "|--" else "├──"
def Config.preDir (cfg : Config) :=
if cfg.useASCII then "| " else "│ "
/--
Modify `cfg` on entering a directory.
-/
def Config.inDirectory (cfg : Config) : Config :=
{cfg with currentPrefix := cfg.preDir ++ " " ++ cfg.currentPrefix}
def showFileName (file : String) : ConfigIO Unit := do
IO.println s!"{(← read).currentPrefix}{(← read).preFile} {file}"
def showDirName (dir : String) : ConfigIO Unit := do
IO.println s!"{(← read).currentPrefix}{(← read).preDir} {dir}/"
def doList [Applicative f] : List α → (α → f Unit) → f Unit
| [], _ => pure ()
| x :: xs, action =>
action x *>
doList xs action
partial def dirTree (path : System.FilePath) : ConfigIO Unit := do
match ← toEntry path with
| none => pure ()
| some (.file name) => showFileName name
| some (.dir name) =>
showDirName name
let contents ← path.readDir
withReader (·.inDirectory)
(doList contents.toList fun d =>
dirTree d.path)
def main (args : List String) : IO UInt32 := do
match configFromArgs args with
| some config =>
(dirTree (← IO.currentDir)).run config
pure 0
| none =>
IO.eprintln s!"Didn't understand argument(s) {" ".intercalate args}\n"
IO.eprintln usage
pure 1