Created
October 4, 2011 22:11
-
-
Save kevinwright/1262988 to your computer and use it in GitHub Desktop.
Pimpin' + on a T => Either[ERR,T] for easy chaining
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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