A bit of library clean-up
This commit is contained in:
@@ -10,39 +10,7 @@ bytesTail = matchList nothing (_ r : just r)
|
|||||||
byteEq? = equal?
|
byteEq? = equal?
|
||||||
bytesLength = length
|
bytesLength = length
|
||||||
bytesAppend = append
|
bytesAppend = append
|
||||||
|
bytesTake = take
|
||||||
bytesTake_ = y (self remaining n i :
|
bytesDrop = drop
|
||||||
matchList
|
bytesSplitAt = splitAt
|
||||||
t
|
bytesEq? = equal?
|
||||||
(h r :
|
|
||||||
matchBool
|
|
||||||
t
|
|
||||||
(pair h (self r n (succ i)))
|
|
||||||
(equal? i n))
|
|
||||||
remaining)
|
|
||||||
|
|
||||||
bytesTake = n bytes : bytesTake_ bytes n 0
|
|
||||||
|
|
||||||
bytesDrop_ = y (self remaining n i :
|
|
||||||
matchList
|
|
||||||
t
|
|
||||||
(_ r :
|
|
||||||
matchBool
|
|
||||||
remaining
|
|
||||||
(self r n (succ i))
|
|
||||||
(equal? i n))
|
|
||||||
remaining)
|
|
||||||
|
|
||||||
bytesDrop = n bytes : bytesDrop_ bytes n 0
|
|
||||||
|
|
||||||
bytesSplitAt = n bytes : pair (bytesTake n bytes) (bytesDrop n bytes)
|
|
||||||
|
|
||||||
bytesEq? = y (self xs ys :
|
|
||||||
matchList
|
|
||||||
(matchList true (_ _ : false) ys)
|
|
||||||
(xh xt :
|
|
||||||
matchList
|
|
||||||
false
|
|
||||||
(yh yt : and? (byteEq? xh yh) (self xt yt))
|
|
||||||
ys)
|
|
||||||
xs)
|
|
||||||
|
|||||||
22
lib/io.tri
22
lib/io.tri
@@ -91,8 +91,8 @@ onResult_ = action errCase okCase :
|
|||||||
-- Convenience helpers
|
-- Convenience helpers
|
||||||
-- ---------------------------------------------------------------------------
|
-- ---------------------------------------------------------------------------
|
||||||
|
|
||||||
print = s : bind (putStr s) (_ : pure t)
|
print = s : void (putStr s)
|
||||||
putStrLn = s : bind (putStr (append s "\n")) (_ : pure t)
|
putStrLn = s : void (putStr (append s "\n"))
|
||||||
|
|
||||||
-- ---------------------------------------------------------------------------
|
-- ---------------------------------------------------------------------------
|
||||||
-- Result-aware file helpers
|
-- Result-aware file helpers
|
||||||
@@ -117,18 +117,12 @@ writeFileOrPrintError = (path contents okCase :
|
|||||||
okCase)
|
okCase)
|
||||||
|
|
||||||
copyFile = (src dst :
|
copyFile = (src dst :
|
||||||
bind (readFile src)
|
onResult (readFile src)
|
||||||
(result :
|
(err rest : putStrLn (append "Read failed: " err))
|
||||||
matchResult
|
(contents rest :
|
||||||
(err rest : putStrLn (append "Read failed: " err))
|
onResult (writeFile dst contents)
|
||||||
(contents rest :
|
(err rest : putStrLn (append "Write failed: " err))
|
||||||
bind (writeFile dst contents)
|
(_ _ : pure t)))
|
||||||
(wr :
|
|
||||||
matchResult
|
|
||||||
(err rest : putStrLn (append "Write failed: " err))
|
|
||||||
(ok rest : pure t)
|
|
||||||
wr))
|
|
||||||
result))
|
|
||||||
|
|
||||||
-- ---------------------------------------------------------------------------
|
-- ---------------------------------------------------------------------------
|
||||||
-- Resource-safe combinators
|
-- Resource-safe combinators
|
||||||
|
|||||||
10
lib/list.tri
10
lib/list.tri
@@ -157,8 +157,6 @@ partition_ = y (self pred xs trues falses :
|
|||||||
|
|
||||||
partition = pred xs : partition_ pred xs t t
|
partition = pred xs : partition_ pred xs t t
|
||||||
|
|
||||||
partition = pred xs : partition_ pred xs t t
|
|
||||||
|
|
||||||
strLength = length
|
strLength = length
|
||||||
strAppend = append
|
strAppend = append
|
||||||
strEq? = equal?
|
strEq? = equal?
|
||||||
@@ -191,11 +189,11 @@ contains? = y (self needle haystack :
|
|||||||
|
|
||||||
lines_ = y (self str :
|
lines_ = y (self str :
|
||||||
matchList
|
matchList
|
||||||
(acc current : append acc [(reverse current)])
|
(acc current : snoc (reverse current) acc)
|
||||||
(h r :
|
(h r :
|
||||||
acc current :
|
acc current :
|
||||||
matchBool
|
matchBool
|
||||||
(self r (append acc [(reverse current)]) t)
|
(self r (snoc (reverse current) acc) t)
|
||||||
(self r acc (pair h current))
|
(self r acc (pair h current))
|
||||||
(equal? h 10))
|
(equal? h 10))
|
||||||
str)
|
str)
|
||||||
@@ -213,14 +211,14 @@ words_ = y (self str :
|
|||||||
(acc current :
|
(acc current :
|
||||||
matchBool
|
matchBool
|
||||||
acc
|
acc
|
||||||
(append acc [(reverse current)])
|
(snoc (reverse current) acc)
|
||||||
(emptyList? current))
|
(emptyList? current))
|
||||||
(h r :
|
(h r :
|
||||||
acc current :
|
acc current :
|
||||||
matchBool
|
matchBool
|
||||||
(matchBool
|
(matchBool
|
||||||
(self r acc current)
|
(self r acc current)
|
||||||
(self r (append acc [(reverse current)]) t)
|
(self r (snoc (reverse current) acc) t)
|
||||||
(emptyList? current))
|
(emptyList? current))
|
||||||
(self r acc (pair h current))
|
(self r acc (pair h current))
|
||||||
(equal? h 32))
|
(equal? h 32))
|
||||||
|
|||||||
@@ -1,262 +0,0 @@
|
|||||||
# Standard Library TODO / Expansion Plan
|
|
||||||
|
|
||||||
> Foundational expansions that improve safety, composability, and ergonomics across the entire tricu ecosystem.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 1. Extract a `maybe.tri` / Option layer
|
|
||||||
|
|
||||||
**Motivation:** `head`, `tail`, `last`, `nth`, `bytesHead`, and `bytesTail` currently return `t` on failure, which is ambiguous because `t` is also a valid tree value. A proper option layer makes all of these APIs safer and self-describing.
|
|
||||||
|
|
||||||
**Additions:**
|
|
||||||
|
|
||||||
```tricu
|
|
||||||
nothing = t
|
|
||||||
just = x : t x
|
|
||||||
|
|
||||||
matchMaybe = nothingCase justCase maybe :
|
|
||||||
triage
|
|
||||||
nothingCase
|
|
||||||
justCase
|
|
||||||
(_ _ : nothingCase)
|
|
||||||
maybe
|
|
||||||
|
|
||||||
maybe = default f m : matchMaybe default f m
|
|
||||||
maybeMap = f m : matchMaybe nothing (x : just (f x)) m
|
|
||||||
maybeBind = m f : matchMaybe nothing f m
|
|
||||||
maybeOr = default m : matchMaybe default id m
|
|
||||||
maybe? = matchMaybe false (_ : true)
|
|
||||||
```
|
|
||||||
|
|
||||||
**Then update existing list/bytes primitives:**
|
|
||||||
|
|
||||||
```tricu
|
|
||||||
headMaybe
|
|
||||||
lastMaybe
|
|
||||||
nthMaybe
|
|
||||||
bytesHead
|
|
||||||
bytesTail
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 2. Move `Result` combinators from `binary.tri` into `base.tri`
|
|
||||||
|
|
||||||
**Motivation:** `Result` is defined in `base.tri`, but `mapResult` and `bindResult` currently live in `binary.tri`. This makes them unavailable to IO, socket, and file helpers unless every consumer imports binary parsing.
|
|
||||||
|
|
||||||
**Move / add to `base.tri`:**
|
|
||||||
|
|
||||||
```tricu
|
|
||||||
mapResult = f result :
|
|
||||||
matchResult
|
|
||||||
(code rest : err code rest)
|
|
||||||
(value rest : ok (f value) rest)
|
|
||||||
result
|
|
||||||
|
|
||||||
bindResult = result f :
|
|
||||||
matchResult
|
|
||||||
(code rest : err code rest)
|
|
||||||
(value rest : f value rest)
|
|
||||||
result
|
|
||||||
|
|
||||||
resultOr = default result :
|
|
||||||
matchResult
|
|
||||||
(_ _ : default)
|
|
||||||
(value _ : value)
|
|
||||||
result
|
|
||||||
|
|
||||||
resultMapErr = f result :
|
|
||||||
matchResult
|
|
||||||
(code rest : err (f code) rest)
|
|
||||||
(value rest : ok value rest)
|
|
||||||
result
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 3. Add basic numeric comparison and arithmetic
|
|
||||||
|
|
||||||
**Motivation:** Without comparison and arithmetic, list slicing, parser limits, counters, socket loops, and CLI utilities are awkward or impossible.
|
|
||||||
|
|
||||||
**Priority order:**
|
|
||||||
|
|
||||||
1. `isZero?`
|
|
||||||
2. `add`
|
|
||||||
3. `sub`
|
|
||||||
4. `lt?`
|
|
||||||
5. `lte?`
|
|
||||||
6. `mul`
|
|
||||||
|
|
||||||
Even simple Peano / binary-tree versions unlock a huge amount of functionality.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 4. Expand `list.tri` with safer and more complete primitives
|
|
||||||
|
|
||||||
**Motivation:** `reverse` currently uses `append` recursively, which is quadratic. Many common operations (`take`, `drop`, `concatMap`) are missing entirely.
|
|
||||||
|
|
||||||
**High-impact additions:**
|
|
||||||
|
|
||||||
```tricu
|
|
||||||
take
|
|
||||||
drop
|
|
||||||
splitAt
|
|
||||||
concatMap
|
|
||||||
find
|
|
||||||
partition
|
|
||||||
zipWith
|
|
||||||
```
|
|
||||||
|
|
||||||
**Performance fix:**
|
|
||||||
|
|
||||||
```tricu
|
|
||||||
reverse_ = y (self xs acc :
|
|
||||||
matchList
|
|
||||||
acc
|
|
||||||
(h r : self r (pair h acc))
|
|
||||||
xs)
|
|
||||||
|
|
||||||
reverse = xs : reverse_ xs t
|
|
||||||
```
|
|
||||||
|
|
||||||
This is low-effort, high-impact because `reverse` is already used by `binary.tri` and `conversions.tri`.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 5. Add string aliases / helpers
|
|
||||||
|
|
||||||
**Motivation:** IO and CLI programs almost always need line/string manipulation. Socket protocols are also easier with canonical string utilities.
|
|
||||||
|
|
||||||
**Highest value:**
|
|
||||||
|
|
||||||
```tricu
|
|
||||||
startsWith?
|
|
||||||
contains?
|
|
||||||
lines
|
|
||||||
unlines
|
|
||||||
```
|
|
||||||
|
|
||||||
Also consider:
|
|
||||||
|
|
||||||
```tricu
|
|
||||||
strLength
|
|
||||||
strAppend
|
|
||||||
strEq?
|
|
||||||
strEmpty?
|
|
||||||
words
|
|
||||||
unwords
|
|
||||||
endsWith?
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 6. Expand `binary.tri` into a small parser-combinator layer
|
|
||||||
|
|
||||||
**Motivation:** `binary.tri` already has `readU8`, `readBytes`, `expectBytes`, etc. A thin combinator layer makes binary parsing much more ergonomic and reusable for protocols/file formats.
|
|
||||||
|
|
||||||
**Suggested additions:**
|
|
||||||
|
|
||||||
```tricu
|
|
||||||
pureParser = value bs : ok value bs
|
|
||||||
failParser = code bs : err code bs
|
|
||||||
|
|
||||||
mapParser = mapResult
|
|
||||||
bindParser = bindResult
|
|
||||||
thenParser = p q : bindResult p (_ : q)
|
|
||||||
orParser = p q bs :
|
|
||||||
matchResult
|
|
||||||
(_ _ : q bs)
|
|
||||||
(value rest : ok value rest)
|
|
||||||
(p bs)
|
|
||||||
```
|
|
||||||
|
|
||||||
Then common parsers:
|
|
||||||
|
|
||||||
```tricu
|
|
||||||
readWhile
|
|
||||||
readUntil
|
|
||||||
readRemaining
|
|
||||||
peekU8
|
|
||||||
eof?
|
|
||||||
expectAscii
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 7. Add endian / int conversion helpers
|
|
||||||
|
|
||||||
**Motivation:** `readU16BEBytes` and `readU32BEBytes` return raw byte lists. Either rename them or add actual numeric decoding.
|
|
||||||
|
|
||||||
**Suggested additions:**
|
|
||||||
|
|
||||||
```tricu
|
|
||||||
u16BE
|
|
||||||
u16LE
|
|
||||||
u32BE
|
|
||||||
u32LE
|
|
||||||
|
|
||||||
readU16BE
|
|
||||||
readU16LE
|
|
||||||
readU32BE
|
|
||||||
readU32LE
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 8. Add resource-safe IO helpers
|
|
||||||
|
|
||||||
**Motivation:** Sockets, files, and process-like resources need predictable cleanup.
|
|
||||||
|
|
||||||
```tricu
|
|
||||||
finally = action cleanup :
|
|
||||||
bind action (result :
|
|
||||||
bind cleanup (_ :
|
|
||||||
pure result))
|
|
||||||
|
|
||||||
bracket = acquire release use :
|
|
||||||
bind acquire (resource :
|
|
||||||
bind (use resource) (result :
|
|
||||||
bind (release resource) (_ :
|
|
||||||
pure result)))
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 9. Add socket server loops
|
|
||||||
|
|
||||||
**Motivation:** Almost every socket example repeats the same `forever` + `withAccepted_` scaffolding.
|
|
||||||
|
|
||||||
```tricu
|
|
||||||
serveForever = server handler :
|
|
||||||
forever
|
|
||||||
(withAccepted_ server
|
|
||||||
(err : pure t)
|
|
||||||
(client peer :
|
|
||||||
fork (handler client peer)))
|
|
||||||
```
|
|
||||||
|
|
||||||
Also consider:
|
|
||||||
|
|
||||||
```tricu
|
|
||||||
connectTo = addr port :
|
|
||||||
onOk_ socket (client :
|
|
||||||
onOk_ (connect client addr port) (_ :
|
|
||||||
pure (ok client)))
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 10. Add a curated `prelude.tri`
|
|
||||||
|
|
||||||
**Motivation:** As libraries grow, users need a stable starting point.
|
|
||||||
|
|
||||||
```tricu
|
|
||||||
!import "base.tri" !Local
|
|
||||||
!import "maybe.tri" !Local
|
|
||||||
!import "list.tri" !Local
|
|
||||||
!import "bytes.tri" !Local
|
|
||||||
!import "conversions.tri" !Local
|
|
||||||
```
|
|
||||||
|
|
||||||
This gives a standard baseline without importing IO / socket / binary by default.
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user