julian
06/21/2020, 2:13 AMstreetsofboston
06/21/2020, 3:44 AMsimon.vergauwen
06/21/2020, 10:21 AMdata class class Foo(val name: String, val age: Int)
generates hashCode
, equals
and toString
from its properties.
But in Haskell, you do that separately since there is no inheritance.
*data* Person = Person String Int
here we define a record
Person
with String
& Int
properties.
By changing it to data Person = Person String Int deriving(Eq, Show, Hash)
we now tell the compiler to automatically add an instance for the Eq, Show & Hash
typeclass. Which is the equivalent of toString
, hashCode
& equals
.
This behavior goes much further, but as you can see it allows you to implement behavior outside of a class instead of using inheritance.
Similar to how Comporator
and Comparable
work in Java. ad-hoc vs inheritance based polymorphism.
This goes much further than just Eq
, Show
& Hash
of course.julian
06/21/2020, 4:39 PMjulian
06/21/2020, 4:47 PMsimon.vergauwen
06/21/2020, 5:48 PMOOP
land and still get benefits from typeclasses! Or exclusively use them.julian
06/21/2020, 10:40 PMjulian
06/21/2020, 11:41 PMsimon.vergauwen
06/22/2020, 7:50 AMjulian
06/22/2020, 7:03 PMprivate
access modifier on a data class field and still use typeclasses to operate on the field?simon.vergauwen
06/22/2020, 7:09 PMcompanion object
.
class Person(private val name: String, private val age: Int) {
companion object {
fun eq(): Eq<Person> =
Eq { a, b -> a.name == b.name && a.age == a.age }
}
}
julian
06/22/2020, 7:11 PMmax.cruz
06/22/2020, 7:35 PMThe primary reason why use of typeclasses (and co.) is more prevalent in FP than OO is that typeclasses are difficult-to-impossible to use when state is encapsulated i.e. when access is restricted in order to protect mutable state.