Skip to content

Instantly share code, notes, and snippets.

@kevinwright
Created October 4, 2011 22:11
Show Gist options
  • Star 8 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kevinwright/1262988 to your computer and use it in GitHub Desktop.
Save kevinwright/1262988 to your computer and use it in GitHub Desktop.
Pimpin' + on a T => Either[ERR,T] for easy chaining
class Filters[T] {
//Some boilerplate-busting aliases
type FilterResult = Either[Rejection, T]
type FilterFunc = (T) => FilterResult
//Handy helpers
//Rejection can carry as much info as you wish;
// Filter name, value in error, an exception, etc.
case class Rejection(input: T, msg: String)
def pass(x: T): FilterResult = Right(x)
def reject(x: T, msg: String): FilterResult = Left(Rejection(x, msg))
//The awesome pimp!
class Chainable(fn: FilterFunc) {
def +(other: FilterFunc): FilterFunc = (input: T) => fn(input).right flatMap other
}
implicit def filterFuncIsChainable(fn: FilterFunc) = new Chainable(fn)
}
object StringFilters extends Filters[String] {
val rejectNonAlphaNumeric: FilterFunc = (input: String) =>
if (input.matches(".*[0-9a-zA-z].*")) pass(input)
else reject(input, "didn't containin any alphanumeric characters")
val rejectSingleChar: FilterFunc = (input: String) =>
if (input.length >= 2) pass(input)
else reject(input, "was a mere single character")
val convertToUppercase: FilterFunc = (input: String) => pass(input.toUpperCase)
def rejectOverLength(maxLength: Int): FilterFunc = (input: String) =>
if (input.length < maxLength) pass(input)
else reject(input, "was over " + maxLength + " characters long")
}
import StringFilters._
//And now... All the juicy magic goodness makes it trivial to use :)
val processor = rejectNonAlphaNumeric + rejectSingleChar + rejectOverLength(20) + convertToUppercase
processor("hello world")
// Right(HELLO WORLD)
processor("x")
// Left(Rejection(x,was a mere single character))
processor("22")
// Right(22)
processor("_")
// Left(Rejection(_,was a mere single character))
processor("__")
// Right(__)
processor("''")
// Left(Rejection('',didn't containin any alphanumeric characters))
processor("abcdefghijklmnopqrstuvwxyz")
// Left(Rejection(abcdefghijklmnopqrstuvwxyz,was over 20 characters long))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment