1 # files: an effect service: a file's text by path, where Base lives, and 2 # the working directory a relative path is read against. 3 import Base 4 5 # effect service: a file's text, where Base is, and the working directory 6 type Files is Type: 7 Files{read: String -> IO(Maybe<&2, String>), base_path: Unit -> IO(String), cwd: Unit -> IO(String)} 8 9 # None when the file cannot be read 10 def read(ff: Files, path: String) -> IO(Maybe<&2, String>): 11 Files{r, _b, _c} = ff 12 r(path) 13 14 # the path of Base, from a files service 15 def base_path(ff: Files) -> IO(String): 16 Files{_r, b, _c} = ff 17 b(Unit{}) 18 19 # the working directory, from the root; "" when it cannot be named 20 def cwd(ff: Files) -> IO(String): # noqa: L001 effect accessor 21 Files{_r, _b, c} = ff 22 c(Unit{}) 23 24 # every path read, in order (a missing file is a None) 25 def read_all(~ff: Files, paths: List<&2, String>) -> IO(List<&2, Maybe<&2, String>>): # noqa: L001 effect accessor 26 match paths: 27 case Nil{}: 28 IO.pure(List<&2, Maybe<&2, String>>, []) 29 case Con{p, rest}: 30 do IO>>: 31 r : Maybe<&2, String> <- read(ff, p) 32 more : List<&2, Maybe<&2, String>> <- read_all(~ff, rest) 33 return r <> more