summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAditya Naik2022-02-17 00:38:32 -0800
committerAditya Naik2022-02-17 00:38:32 -0800
commite8c92aea4e21e957597fc1c01e9a0544180393d6 (patch)
tree6ef3289067d25c8c7e4547d498ba6ef7f8185692
parent8da1bd8492bb606713dc22635458b13859290e28 (diff)
implicit magicHEADmaster
-rw-r--r--playground.scala62
1 files changed, 53 insertions, 9 deletions
diff --git a/playground.scala b/playground.scala
index 290c54c..603ed08 100644
--- a/playground.scala
+++ b/playground.scala
@@ -1,12 +1,11 @@
-
import shapeless.Generic
class Playground {
- class ScalaStdlibTypes {
+ class ScalaStdlibTypes { // Motivation
class ScalaConcreteTypesWithTypes {
- type Rect = (Int, Int)
+ type Rect = (Int, Int) // this is a Product (AND relation)
type Circle = Int
- type Shape = Either[Rect, Circle]
+ type Shape = Either[Rect, Circle] // either implies a Coproduct (OR relation)
def area(s: Shape) = s match {
case Left((a, b)) => a*b
@@ -75,14 +74,59 @@ class Playground {
}
val employees = List(Employee("a", 1), Employee("b", 2))
println(writeCSV(employees))
- }
- val generic_csv_encoder = new GenericCSVEncoder
- class ShapelessCSVEncoder {
- trait CSVEncoder[A] {
- def encode(s: A): List[String]
+ /** compiler searches for (i.e. resolves )an implicit encoder function matching
+ * the given type
+ *
+ * needs an implicit encoder function in the context for both the types
+ */
+ implicit def pairEncoder[A, B] (
+ implicit
+ aEncoder: CSVEncoder[A],
+ bEncoder: CSVEncoder[B]
+ ): CSVEncoder[(A, B)] =
+ new CSVEncoder[(A, B)] {
+ def encode(pair: (A, B)): List[String] = {
+ val (a, b) = pair
+ aEncoder.encode(a) ++ bEncoder.encode(b)
+ }
+ }
+ implicit val icecreamEncoder: CSVEncoder[IceCream] = {
+ new CSVEncoder[IceCream] {
+ def encode(e: IceCream): List[String] = List(e.a, e.b.toString)
+ }
}
+ case class IceCream(a: String, b: Int)
+ val icecream = List(IceCream("a", 1), IceCream("b", 2))
+ println(writeCSV(employees zip employees))
+
+ // Standard patterns with companion objects
+
+ trait CsvEncoder2[T] {
+ def encode(k: T): List[String]
+ }
+ /** Demonsrates a standard pattern for generic typeclass companion objects
+ *
+ * apply performs implicit compiler resolution, while
+ * instance wraps a HOF into the encode function defined by the trait
+ */
+ object CsvEncoder2 {
+ // "Summoner" method
+ def apply[A](implicit enc: CSVEncoder[A]): CSVEncoder[A] = enc
+
+ // "Constructor" method
+ def instance[A](func: A => List[String]): CSVEncoder[A] =
+ new CSVEncoder[A] {
+ def encode(value: A): List[String] =
+ func(value)
+ }
+ }
+ // with the new companion object, encode for ice cream can be:
+ // implicit val icecreamEncoder2: CsvEncoder2[IceCream] =
+ // instance(x => List(x.a, x.b.toString))
+
}
+ val generic_csv_encoder = new GenericCSVEncoder
}
object main {