lines.tri (2170B)
1 !import io_v2 as IO 2 !import io_v2_text as Text 3 !import base as B 4 !import native_math as N 5 !export collect 6 !export count 7 !export first 8 !export stdinLines 9 !export cancelled 10 !export closed 11 12 -- Collection is only a test/demo convenience; count discards each line instead. 13 walk cursor limit events = IO.bind (Text.readLine cursor limit) (reply : case reply of 14 ((t t), ([event next], t)) = case event of 15 ["eof"] = IO.pure (B.ok (B.reverse events) t) 16 _ = walk next limit (B.pair event events) 17 (t, (cause, t)) = IO.pure (B.err [(B.reverse events) cause] t) 18 _ = IO.fail "Invalid line Result") 19 force t next = next t 20 force (t bit rest) next = case bit of 21 t = force rest next 22 (t t) = force rest next 23 _ = IO.fail "Invalid count" 24 force _ _ = IO.fail "Invalid count" 25 countLoop cursor limit n = force n (_ : IO.require (Text.readLine cursor limit) (reply : case reply of 26 [["eof"] _] = IO.pure n 27 [_ next] = case N.add n 1 of 28 number = countLoop next limit number 29 _ = IO.fail "Invalid line Result")) 30 collect path limit = IO.io (IO.scope (owner : IO.require (IO.openReader owner path) 31 (reader : walk (Text.lineCursor reader) limit []))) 32 count path limit = IO.io (IO.scope (owner : IO.require (IO.openReader owner path) 33 (reader : countLoop (Text.lineCursor reader) limit 0))) 34 first path limit = IO.io (IO.scope (owner : IO.require (IO.openReader owner path) 35 (reader : IO.bind (Text.readLine (Text.lineCursor reader) limit) (reply : case reply of 36 ((t t), ([event _], t)) = IO.pure (B.ok event t) 37 _ = IO.pure reply)))) 38 stdinLines limit = IO.io (IO.require IO.stdin (reader : walk (Text.lineCursor reader) limit [])) 39 cancelled = IO.io (IO.scope (_ : do IO.require 40 reader <- IO.stdin 41 spawned <- IO.spawn 1 1 [] (_ : Text.readLine (Text.lineCursor reader) 4096) 42 case spawned of 43 [task ticket] = do IO.require 44 IO.sleepMilliseconds 50 45 IO.cancel task "line-stop" 46 outcome <- IO.join ticket 47 IO.pure outcome 48 _ = IO.fail "Invalid line task")) 49 closed path limit = IO.io (IO.bind (IO.scope (owner : IO.require (IO.openReader owner path) 50 (reader : IO.pure (Text.lineCursor reader)))) (cursor : Text.readLine cursor limit))