λ
Scala
JS
zygoHistoPrepro
:: (Unfoldable t, Foldable t)
=> (Base t b -> b)
-> (forall c. Base t c -> Base t c)
-> (Base t (EnvT b (Stream (Base t)) a) -> a)
-> t
-> a
zygoHistoPrepro f g t =
gprepro (distZygoT f distHisto) g t
-- unless you want
-- a generalized zygomorphism.
bête et méchant
val x = if(yolo) {
swag()
} else {
moreRegularOutfit()
}
val x = foo match {
case Yolo(swag) => yoloSwag(swag)
case NotYolo => notYoloSwag()
}
val c = ("Clément", 26)
case class User(name: String, age: Int)
val cc = User("Clément", 26)
val (name, age) = ("Clément", 26)
val User(name, age) = User("Clément", 26)
// 2 * 2 = 4
(true, true)
(true, false)
(false, true)
(false, false)
data JsonElem = JsonNull
| JsonBoolean Bool
| JsonString String
| JsonNumber Double
| JsonArray [JsonElem]
| JsonObject (Map String JsonElem)
sealed trait JsonElem
case object JsonNull
extends JsonElem
case class JsonBoolean(v: Boolean)
extends JsonElem
case class JsonString(v: String)
extends JsonElem
case class JsonNumber(v: Double)
extends JsonElem
case class JsonArray(v: Seq[JsonElem])
extends JsonElem
case class JsonObject(v: Map[String, JsonElem])
extends JsonElem
def stringify(json: JsonValue) =
jsonValue match {
case JsonNull => "null"
case JsonBoolean(v) => v.toString
…
case JsonArray(v) =>
v.map(stringify(_))
.mkString("[", ",", "]")
}
<console>:9: warning: match may not be exhaustive.
It would fail on the following input: JsonString
def stringify(json: JsonValue) = json match {
^
stringify: (json: JsonValue)String
case class
JsonArray(v: Seq[JsonElem])
extends JsonElem with JsonValue
case class
JsonObject(v: Map[String, JsonElem])
extends JsonElem with JsonValue
("Clément", 26)
User(name = "Clément", age = 26)
val v: Either[String, Int] =
Left("error")
sealed trait MyEither
case class MyLeft(v: String)
extends MyEither
case class MyRight(v: Int)
extends MyEither
a*1 <=> a
a+0 <=> a
(a*b)*c <=> a*(b*c) <=> a*b*c
(a+b)+c <=> a+(b+c) <=> a+b+c
a*(b+c) <=> (a*b)+(a*c)
x+x+…+x <=> n*x
c^(a+b) <=> c^a * c^b
(): Unit
void: Void
a*1 <=> a
(A,Unit) <=> A
a+0 <=> a
A | Void <=> A
(a*b)*c <=>
a*(b*c)
a*b*c
(("Clément", 26), "Éol")
("Clément", (26, "Éol))
("Clément", 26, "Éol")
(User("Clément", 26), Pet("Éol"))
UserWithPet("Clément", 26, "Éol")
(a+b)+c <=>
a+(b+c)
a+b+c
c match {
case Left(a) => "Left " + a
case Right(Left(a)) => "Middle " + a
case Right(Right(a)) => "Right " + a
}
c match {
case Left(a) => "Left " + a
case Middle(a) => "Middle " + a
case Right(a) => "Right " + a
}
a*(b+c) <=> (a*b)+(a*c)
("X", Left("Y"))
("X", Right(42))
Left(("X", "Y"))
Right(("X", 42))
x+x+…+x <=> n*x
sealed trait X
case class Bad(v: String) extends X
case class Good(v: String) extends X
case class Y(v: String, isGood: Bool)
c^(a+b) <=> c^a * c^b
Either[String, A]
sealed trait InputError
case class MissingUsername
extends InputError
case class InvalidEmail
extends InputError
val a: Either[InputError, User] = ???
a match {
case Right(user) => ???
case Left(MissingUsername) => ???
case Left(InvalidEmail) => ???
}
for {
a <- Right("operation 1 ok").right
b <- Left("operation 2 failed").right
c <- Left("operation 3 failed").right
} yield c
res8: scala.util.Either[String,String] =
Left(operation 2 failed)
scala> Option("test").fold(Left("error"))(Right.apply)
<console>:10: error: polymorphic expression
cannot be instantiated to expected type;
found : [A, B](b: B)scala.util.Right[A,B]
required: String => scala.util.Left[String,Nothing]
Option("test").fold(Left("error"))(Right.apply)
scala> Option("test").toRight("error")
res1:
Product
with Serializable
with scala.util.Either[String,String] =
Right(test)
cats.Xor
for {
a <- "ok".right
b <- "error 1".left
c <- "error 2".left
} yield c
cats.Xor
res16: cats.Xor[String,String] =
Left(error 1)
for {
a <- Left("error")
b <- Right(a)
} yield b
scala> Option("test").toRight("error")
res10: scala.util.Either[String,String] = Right(test)
def validateEmail(value: String):
ValidatedNel[String, String] = {
value.validNel
// or
"error".invalidNel
}
val user = (
validateEmail(email) |@|
validateUsername(username)) {
case (e, u) =>
User(e, u)
}
Valid(User(email, username))
Invalid(
NonEmptyList(
"invalid username"))
Valid(
NonEmptyList(
"invalid email",
"invalid username"))
(associatively)
(left & right identity)
trait Monoid {
def combine(o: Monoid): Monoid
}
class MyClass extends Monoid {
def combine(o: Monoid) = ???
}
zero
?trait Monoid[A] {
def mzero: A
def mappend(a: A, b: A): A
}
val stringMonoid = new Monoid[String] {
def mzero = ""
def mappend(a: String, b: String) =
a + b
}
def mconcat[A]
(elems: Seq[A])
(ev: Monoid[A]) = {
elems.foldLeft(ev.mzero)(ev.mappend)
}
mconcat(Seq("1", "2", "3"))(stringMonoid)
// "123"
mconcat(Seq(1, 2, 3, 4))(addIntMonoid)
// 10
mconcat(Seq(1, 2, 3, 4))(multIntMonoid)
// 24
implicit val stringMonoid =
new Monoid[String] {
def mzero = ""
def mappend(a: String, b: String) =
a + b
}
def mconcat[A]
(elems: Seq[A])
(implicit ev: Monoid[A]) = {
elems.foldLeft(ev.mzero)(ev.mappend)
}
def mconcat[A: Monoid](elems: Seq[A]) = {
val ev = implicitly[Monoid[A]]
elems.foldLeft(ev.mzero)(ev.mappend)
}
mconcat(Seq("1", "2", "3"))
// "123"
mconcat(Seq(1, 2, 3))
// ???
import simulacrum._
@typeclass trait Semigroup[A] {
@op("|+|") def append(x: A, y: A): A
}
trait ToJson[A] {
def toJson(v: A): JsonElem
}
implicit def mapToJson[A: ToJson]() =
new ToJson[Map[String, A]] {
val ev = implicitly[ToJson[A]]
def toJson(vs: Map[String, A]) =
JsonObject(
vs.mapValues(ev.toJson _)
)
}
∃
« there exists »
∀
« for all »
property("substring") =
forAll { (
a: String,
b: String,
c: String) =>
(a+b+c)
.substring(
a.length,
a.length+b.length) == b
}
case class AddUser(user: User)
case class TransferAmount(
to: User,
from: User,
amount: Money)
devoxxroxx2016