Skip to content

Commit 72a9350

Browse files
author
Abhijit Sarkar
committed
Complete ch04
1 parent bc4c7f9 commit 72a9350

File tree

4 files changed

+120
-1
lines changed

4 files changed

+120
-1
lines changed

.scalafmt.conf

+4-1
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,7 @@ version = "3.8.3"
22
align.preset = more
33
maxColumn = 120
44
runner.dialect = scala3
5-
assumeStandardLibraryStripMargin = true
5+
assumeStandardLibraryStripMargin = true
6+
project.excludePaths = [
7+
"glob:**/ch04/src/**.scala"
8+
]

ch04/src/Cat.scala

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package ch04
2+
3+
final case class Cat(name: String, age: Int, color: String)
4+
5+
object Cat:
6+
given catDisplay: Display[Cat]:
7+
def display(cat: Cat): String =
8+
val name = Display.display(cat.name)
9+
val age = Display.display(cat.age)
10+
val color = Display.display(cat.color)
11+
s"$name is a $age year-old $color cat."

ch04/src/Display.scala

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package ch04
2+
3+
trait Display[A]:
4+
def display(value: A): String
5+
6+
7+
object Display:
8+
given stringDisplay: Display[String]:
9+
def display(input: String): String = input
10+
11+
given intDisplay: Display[Int]:
12+
def display(input: Int): String = input.toString
13+
14+
def display[A](input: A)(using p: Display[A]): String =
15+
p.display(input)
16+
17+
def print[A](input: A)(using Display[A]): Unit =
18+
println(display(input))
19+
20+
object DisplaySyntax:
21+
extension [A](value: A)(using p: Display[A])
22+
def display: String = p.display(value)
23+
def print: Unit = Display.print(value)

ch04/src/ch04.sc

+82
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
import ch04.DisplaySyntax.*
2+
import ch04.Display
3+
4+
/*
5+
components that make up a type class:
6+
7+
- A trait, which is the type class
8+
- Type class instances, which are given instances.
9+
- Type class usage, which uses using clauses.
10+
11+
Type classes can be composed from components using type class composition.
12+
We can view type classes as marrying codata with tools to select and compose implementations based on type.
13+
We can also view type classes as shifting implementation from the definition site to the call site.
14+
Finally, can see type classes as a mechanism for ad-hoc polymorphism,
15+
allowing us to define common functionality for otherwise unrelated types.
16+
*/
17+
given Display[ch04.Cat] with
18+
def display(cat: ch04.Cat): String =
19+
val name = cat.name.display
20+
val age = cat.age.display
21+
val color = cat.color.display
22+
s"$name is a $age year-old $color cat."
23+
24+
ch04.Cat("Garfield", 41, "ginger and black").display
25+
26+
trait Animal
27+
trait Cat extends Animal
28+
trait DomesticShorthair extends Cat
29+
30+
trait Inv[A]:
31+
def result: String
32+
33+
object Inv:
34+
given Inv[Cat] with
35+
def result = "Invariant"
36+
37+
def apply[A](using instance: Inv[A]): String =
38+
instance.result
39+
40+
trait Co[+A]:
41+
def result: String
42+
43+
object Co:
44+
given Co[Cat] with
45+
def result = "Covariant"
46+
47+
def apply[A](using instance: Co[A]): String =
48+
instance.result
49+
50+
trait Contra[-A]:
51+
def result: String
52+
53+
object Contra:
54+
given Contra[Cat] with
55+
def result = "Contravariant"
56+
57+
def apply[A](using instance: Contra[A]): String =
58+
instance.result
59+
60+
// Works!
61+
Inv[Cat]
62+
// res1: String = "Invariant"
63+
Co[Animal]
64+
// res2: String = "Covariant"
65+
Co[Cat]
66+
// res3: String = "Covariant"
67+
Contra[DomesticShorthair]
68+
// res4: String = "Contravariant"
69+
Contra[Cat]
70+
// res5: String = "Contravariant"
71+
72+
// Don't work!
73+
74+
// With invariance any type that is not Cat will fail.
75+
// Inv[Animal]
76+
// Inv[DomesticShorthair]
77+
78+
// Covariance fails for any subtype of the type for which the instance is declared.
79+
// Co[DomesticShorthair]
80+
81+
// Contravariance fails for any supertype of the type for which the instance is declared.
82+
// Contra[Animal]

0 commit comments

Comments
 (0)