This document summarizes a nonstandard library called psp-std that provides consistency, correctness, and convenience without dependencies. It includes:
- A consciously constructed namespace that reexports common Scala types with consistent names.
- Support for empty values through type classes like Empty, providing default empty values when collections are converted.
- Additional collection methods like splitAfter, grep, splitAround for filtering, splitting, and matching patterns in collections.
- Predicate algebra for filtering collections based on boolean combinations of predicates.
- Support for pairness awareness when working with paired data like zipped collections.
- Fair trade collections that allow type-safe mapping and other operations across different collection types.
2. Things I like.
• -Yno-imports -Yno-predef
• -Yno-adapted-args
• consistency
• correctness
• convenience
• no dependencies
3. A consciously constructed
namespace.
// This is only a sliver.
type Any = scala.Any
type GTOnce[+A] = sc.GenTraversableOnce[A]
type tailrec = scala.annotation.tailrec
type sciList[+A] = sci.List[A]
type sciMap[K, +V] = sci.Map[K, V]
type IOException = jio.IOException
4. Size, not lies.
/** The Size hierarchy is:
* Size
* /
* Atomic Bounded
* /
* Infinite Precise
*/
5. Julia! Lua! Over here!
final class Vindex[Base] private[std](val indexValue: Long) extends AnyVal
type Index = Vindex[Zero.type]
type Nth = Vindex[One.type]
psp> 1 to 3 apply 1
Main.scala:1004: type mismatch;
found : Int(1)
required: psp.std.all.Vdex
psp> 1 to 3 apply 1.index
res3: Int = 2
psp> 1 to 3 apply 1.nth
res4: Int = 1
6. Type classes, not for show
(Except for Show)
trait Eq[-A] extends Any {
def eqv(x: A, y: A): Bool
}
trait Hash[-A] extends Any {
def hash(x: A): Long
}
trait Order[-A] extends Any {
def less(x: A, y: A): Bool
}
trait Show[-A] extends Any {
def show(x: A): String
}
trait Empty[+A] extends Any {
def empty: A
}
7. Empty.
implicit def emptyFromCanBuild[A, R](implicit z: CanBuild[A, R]): Empty[R] = Empty(z().result)
implicit def emptyFromMakes[A, R](implicit z: Makes[A, R]): Empty[R] = Empty(elems())
implicit def emptyJavaSet[A]: Empty[jSet[A]] = Empty(new jHashSet[A])
// which provides us e.g.
psp> emptyValue[String]
res19: String = ""
psp> val x: Index = emptyValue
x: Index = -1
8. Empty's gonna empty
psp> view[String]().zhead
res18: String = ""
// as opposed to
psp> view[Int]().zhead
Error: could not find implicit Empty[Int]
psp> view("a", "b") zreducel (_ append _)
res20: String = ab
psp> some(5.index).zget
res21: Index = 5
psp> none[Index]().zget
res22: Index = -1
10. You may be specific.
psp> 'a' to 'g'
res12: CharRange = [a..g]
psp> ('a' to 'g').force[String]
res13: String = abcdefg
psp> ('a' to 'g').force[Vec[Char]]
res14: Vec[Char] = [ a, b, c, d, e, f, g ]
psp> ('a' to 'g').force[sciList[Char]]
res15: sciList[Char] = List(a, b, c, d, e, f, g)
psp> ('a' to 'g').to[Array]
res16: Array[Char] = [ a, b, c, d, e, f, g ]