purescript / purescript-record

Functions for working with records and polymorphic labels
BSD 3-Clause "New" or "Revised" License
70 stars 31 forks source link

Builder API #10

Closed paf31 closed 7 years ago

paf31 commented 7 years ago

Fixes #8.

Operations are safe since all arguments are used linearly and copied in build. Crucially, the Builder constructor is not exported.

Compare this to my linear DSLs blog post or purescript-substructural by @rightfold.

This should make it simpler to write certain RowList-based operations, like mapping over, zipping or traversing records.

paf31 commented 7 years ago

Any objection to merging this one or the ST PR?

hdgarrood commented 7 years ago

None from me!

paf31 commented 7 years ago

Thanks!

rightfold commented 7 years ago

An alternative would be an "askless reader", which is like Reader but lacks ask so you can mutate the environment without anybody seeing it. Here's an example with StringBuilder in Scala:

case class Build[A](run: StringBuilder => A) extends AnyClass {
  def map[B](f: A => B): Build[B] =
    Build(s => f(run(s)))

  def flatMap[B](f: A => Build[B]): Build[B] =
    Build(s => f(run(s)).run(s))
}

object Build {
  def run[A](b: Build[A]): (String, A) = {
    val s = new StringBuilder()
    val r = b.run(s)
    (s.toString(), r)
  }
}

With an IxMonad you could alter the type of the record. The benefit of this approach is that you get an indexed monad and can use all the available indexed monad APIs.

paf31 commented 7 years ago

Not a bad idea :)