What • Don't stress yourself on low-level details. Just sit- back and relax ! • You may keep your mics on " (Silence is intimidating than FPH) / ! @GopalAkshintala " overfullstack.github.io 3
Changes the way you think about coding. • Code like Maths equations and deravations. • These are Design patterns too. • Concise • High Quality (Bug free) • Expressive • Shared Vocab / ! @GopalAkshintala " overfullstack.github.io 4
algorithms? • Comparator<T> 8 It's a typeclass • What is the connection between a DataType and a Typeclass? / ! @GopalAkshintala " overfullstack.github.io 8
AddableT, b: AddableT): AddableT 8 AddableT type should be a member of AdderTC type class by implementing all its methods. fun addAll(addables: List<AddableT>) = addables.reduce { acc, i C add(acc, i) } } / ! @GopalAkshintala " overfullstack.github.io 10
= if (email.contains("@", false)) { if (email.length B 250) { Unit.right() } else { ValidationError.EmailMaxLength(250).left() } } else { ValidationError.DoesNotContain("@").left() } This is stuck with Fail fast / ! @GopalAkshintala " overfullstack.github.io 15
of this algorithm? • The Effect of being Valid/Invalid • The Effect of combining all validation errors • How to abstract them out? / ! @GopalAkshintala " overfullstack.github.io 17
function inside a box? • You can do some interesting things, to combine two wrapped values, using an operation called product. / ! @GopalAkshintala " overfullstack.github.io 33
: Option<String> = Option("firstName") fun getLastName(userName: String) : Option<String> = Option("lastName") fun getFullName(userName: String) = getFirstName(userName).product(getLastName(userName)) .map { names: Tuple2<String, String> C "${names.a} ${names.b}" } G H Some(firstName lastName) product internally calls apply, by converting its wrapped argument to a wrapped function, but let's not get into details now. / ! @GopalAkshintala " overfullstack.github.io 34
Ya it has a raiseError(e: E) method. Either.applicativeError<String>().raiseError<Unit>("Dark") : < Left(Dark) Option.applicativeError().raiseError<Unit>(Unit) : < None • applicativeError() is just a companion method on the DataType to get ApplicativeInstance • When raiseError(e) is called, the Datatype transitions into the dark side. / ! @GopalAkshintala " overfullstack.github.io 37
raiseError() can help our validation? • The Effect of being Valid/Invalid - This can be taken care by the Left and Right states and raiseError takes care of the transition. • The Effect of combining all validation errors - This can be taken care by the product. • But what about Strategy switching between Fail-Fast and Error- Accumulation? / ! @GopalAkshintala " overfullstack.github.io 38
strategies: EitherApplicativeError<L> : ApplicativeError<EitherPartialOf<L>, L> ValidatedApplicativeError<E> : ApplicativeError<ValidatedPartialOf<E>, E> • Again, let's not get into the details, but let's understand the more important HOW? • Hint: product implementation in both these typeclasses is going to make the difference / ! @GopalAkshintala " overfullstack.github.io 39