19
psp-std a nonstandard library github.com/paulp/psp-std

Brief tour of psp-std

Embed Size (px)

Citation preview

Page 1: Brief tour of psp-std

psp-stda nonstandard library

github.com/paulp/psp-std

Page 2: Brief tour of psp-std

Things I like.• -Yno-imports -Yno-predef• -Yno-adapted-args• consistency• correctness• convenience• no dependencies

Page 3: Brief tour of psp-std

A consciously constructed namespace.// This is only a sliver.type Any = scala.Anytype GTOnce[+A] = sc.GenTraversableOnce[A]type tailrec = scala.annotation.tailrectype sciList[+A] = sci.List[A]type sciMap[K, +V] = sci.Map[K, V]type IOException = jio.IOException

Page 4: Brief tour of psp-std

Size, not lies./** The Size hierarchy is: * Size * / \ * Atomic Bounded * / \ * Infinite Precise */

Page 5: Brief tour of psp-std

Julia! Lua! Over here!final class Vindex[Base] private[std](val indexValue: Long) extends AnyValtype Index = Vindex[Zero.type]type Nth = Vindex[One.type]

psp> 1 to 3 apply 1Main.scala:1004: type mismatch; found : Int(1) required: psp.std.all.Vdex

psp> 1 to 3 apply 1.indexres3: Int = 2

psp> 1 to 3 apply 1.nthres4: Int = 1

Page 6: Brief tour of psp-std

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}

Page 7: Brief tour of psp-std

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 = emptyValuex: Index = -1

Page 8: Brief tour of psp-std

Empty's gonna emptypsp> view[String]().zheadres18: String = ""

// as opposed topsp> view[Int]().zheadError: could not find implicit Empty[Int]

psp> view("a", "b") zreducel (_ append _)res20: String = ab

psp> some(5.index).zgetres21: Index = 5

psp> none[Index]().zgetres22: Index = -1

Page 9: Brief tour of psp-std

Repent, then convertpsp> view(1 -> 2).toMap[jMap]res8: jMap[Int, Int] = {1=2}

psp> view(1 -> 2).toMap[sciMap]res9: sciMap[Int, Int] = Map(1 -> 2)

psp> view(1 -> 2).to[sciVector]res10: sciVector[(Int, Int)] = Vector(1 -> 2)

psp> view(1 -> 2).to[Vec]res11: Vec[(Int, Int)] = [ 1 -> 2 ]

Page 10: Brief tour of psp-std

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 ]

Page 11: Brief tour of psp-std

Handful of better methodspsp> 1 to 20 splitAfter 10.sizeres16: Split[Int] = [ 1, 2, 3, ... ] / [ 11, 12, 13, ... ]

// Requires a Show[Int] instancepsp> 1 to 40 grep """(\d)\1""".rres17: View[Int] = [ 11, 22, 33 ]

psp> 1 to 7 splitAround 3.nthres3: Split[Int] = [ 1, 2 ] / [ 4, 5, 6, 7 ]

// span plus onepsp> 2.andUp takeToFirst (_ % 5 == 0)res4: View[Long] = [ 2, 3, 4, 5 ]

Page 12: Brief tour of psp-std

Predicate algebrapsp> def divBy(n: Long): ToBool[Long] = _ % n == 0Ldefined function divBy

psp> 0.andUp filter divBy(7)res24: View[Long] = [ 0, 7, 14, ... ]

psp> 0.andUp filter divBy(7) && divBy(3)res25: View[Long] = [ 0, 21, 42, ... ]

Page 13: Brief tour of psp-std

Binary relation algebrapsp> val xs = 1 to 100 zipTailxs: Zip[Int, Int] = [ 1 -> 2, 2 -> 3, 3 -> 4, ... ]

psp> val p1: Pred2[Int] = (_ > 8 && _ < 12)p1: (Int, Int) => Bool = <function2>

psp> xs filter p1res39: Zip[Int, Int] = [ 9 -> 10, 10 -> 11 ]

psp> xs filter p1 && (_ + _ == 19)res41: Zip[Int, Int] = [ 9 -> 10 ]

Page 14: Brief tour of psp-std

Pairness awarenesspsp> val xs = 1 to 100 zipTailxs: Zip[Int, Int] = [ 1 -> 2, 2 -> 3, 3 -> 4, ... ]

psp> xs filter (_ > 8 && _ < 12)res30: Zip[Int, Int] = [ 9 -> 10, 10 -> 11 ]

psp> (1 to 10).zipTail forall (_ + 1 == _)res31: Boolean = true

Page 15: Brief tour of psp-std

Fitter splitterpsp> 1 to 10 span (_ <= 5)res2: Split[Int] = [ 1, 2, 3, 4, 5 ] / [ 6, 7, 8, 9, 10 ]

psp> 1 to 10 span (_ <= 5) mapRight (_.reverseView take 2) joinres3: View[Int] = [ 1, 2, 3, 4, 5, 10, 9 ]

psp> 1 to 6 splitAfter 3.size collateres4: View[Int] = [ 1, 4, 2, 5, 3, 6 ]

Page 16: Brief tour of psp-std

Fair trade collectionspsp> val xs = scala.collection.immutable.BitSet(1, 2, 3)xs: sciBitset = BitSet(1, 2, 3)

psp> xs o (_ map (_ + 1 toChar))Error: could not find implicit Makes[Char, BitSet]

psp> xs o (_ map (_ + 1 toChar) map (_.toInt))res2: sciBitset = BitSet(2, 3, 4)

Page 17: Brief tour of psp-std

To infinity... and no furtherpsp> def primes = mpartition(2L.andUp)(xs => _ % xs.head === 0)defined function primes

psp> println(primes take 7 map (_ take 5))2 4 6 8 103 9 15 21 275 25 35 55 657 49 77 91 11911 121 143 187 20913 169 221 247 29917 289 323 391 493

Page 18: Brief tour of psp-std

Products via type class.// Pattern matching Java map entriespsp> javaMap(1 -> 2, 3 -> 4) collect { case 1 -> n => n }res2: View[Int] = [ 2 ]

psp> javaMap(1 -> 2, 3 -> 4) zfirst { case 3 -> n => some(n) }res3: Option[Int] = 4

psp> javaMap(1 -> 2, 3 -> 4) zfirst { case 5 -> n => some(n) }res4: Option[Int] = -

// And get a java map backpsp> javaMap(1 -> 2, 3 -> 4) o (_ collect { case a->b => b->a } )res5: jMap[Int, Int] = {2=1, 4=3}

Page 19: Brief tour of psp-std

Invariant leaf collections.// "You saved me, Capt. Invariance!"psp> vec(1, 2, 3) :+ 4L found : Long(4L) required: Int

// For contrast.scala> Vector(1, 2, 3) :+ 4Lres1: scala.collection.immutable.Vector[AnyVal] = Vector(1, 2, 3, 4)