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
import lombok.EqualsAndHashCode; | |
import lombok.ToString; | |
import java.util.NoSuchElementException; | |
import java.util.function.BiFunction; | |
import java.util.function.Consumer; | |
import java.util.function.Function; | |
import java.util.function.Supplier; | |
public abstract class Either<L,R> { |
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
object HipsterRules { | |
import com.covariantblabbering.builder.ApplicativeStyleWithMultipleMessages.SmartBuilderOps._ | |
def facialHairStyle(hair: String) = { | |
if(hair.toLowerCase.contains("beard")) hair.success | |
else "You need to make vikings envious with any bushy or scraggly beard".failure | |
} | |
def tshirt(style: String) = { |
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
object SmartBuilderOps | |
{ | |
implicit val applicative = applicativeBuilder[String] | |
implicit def toSmartBuilderOps[E,A,B](s: BuildStep[E,A => B])=new SmartBuilderOps(s) | |
implicit def smartify[E,A,B,C](target: Curryable[A,B,C])(implicit applicative: Applicative[({type f[x] = BuildStep[E, x]})#f]) = toSmartBuilderOps(applicative.unit(target.curried)) | |
implicit def toValidationOps[T](v: T) = new ValidationOps(v) | |
} |
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
sealed trait BuildStep[+E, +A]{ | |
def toEither: Either[E,A] | |
} | |
final case class Continue[A](v: A) extends BuildStep[Nothing,A] { | |
def toEither = Right(v) | |
} | |
final case class Failure[E](e: List[E]) extends BuildStep[List[E], Nothing] { | |
def toEither = Left(e) | |
} |
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
object HipsterRules { | |
import com.covariantblabbering.builder.ApplicativeStyleWithExceptions._ | |
def facialHairStyle(hair: String) = { | |
if(hair.toLowerCase.contains("beard")) Continue(hair) | |
else Failure(new Exception("You need to make vikings envious with any bushy or scraggly beard")) | |
} | |
def tshirt(style: String) = { |
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
case class Hipster(facialHair: String, shirt: String, band: String, hobbie: String) |
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
final class SmartBuilder[A,B](val f: BuildStep[Throwable,A => B]) | |
{ | |
def @> [E <: Throwable](step: BuildStep[E,A])(implicit applicative: Applicative[({type f[x] = BuildStep[Throwable, x]})#f]) = { | |
applicative.apply(f)(step) | |
} | |
} | |
object SmartBuilderOps | |
{ | |
def <<= [A](f: BuildStep[Throwable, A]) = f match { |
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
def applicativeBuilder[E] = new Applicative[({type f[x] = BuildStep[E, x]})#f] { | |
def unit[A](a: A) = Continue(a) | |
override def map2[A, B, C](fa: BuildStep[E, A], fb: BuildStep[E, B])(f: (A, B) => C) = { | |
(fa, fb) match{ | |
case (Continue(a), Continue(b)) => Continue(f(a,b)) | |
case (Failure(e1), Failure(e2)) => Failure(e1) | |
case (f @ Failure(_), _) => f | |
case (_, f @ Failure(_)) => f |
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
trait Functor[F[_]]{ | |
def map[A,B](fa: F[A])(f: A => B): F[B] | |
} | |
trait Applicative[F[_]] extends Functor[F] | |
{ | |
def map2[A,B,C](fa: F[A], fb: F[B])(f: (A,B) => C): F[C] = { | |
apply(map(fa)(a => f(a,_:B)))(fb) | |
} |
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
trait BuildStep[+E, +A] | |
case class Continue[T](v: T) extends BuildStep[Nothing, T] | |
case class Failure[E](e: E) extends BuildStep[E, Nothing] |