You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Logan McGrath e8d33b2aff Updating readme 9 months ago
console Fixing imports.scala 9 months ago
project Moving things around 9 months ago
src Using implicit scope instead of lexical scope for functor instances 9 months ago
.gitignore Allowing console to run without import warnings and turning off warnings as errors, upgrading scala to 2.13.8 10 months ago
.scalafmt.conf Moving things around 9 months ago Updating readme 9 months ago
build.sbt Allowing console to run without import warnings and turning off warnings as errors, upgrading scala to 2.13.8 10 months ago

Embracing Nondeterminism

This code accompanies a blog series covering functional programming idioms for managing nondeterminism and unknown states in production code. Please follow the series for a full explanation of the concepts represented by the code in this repository:

  1. Part 1: Contexts and Effects
  2. Part 2: Permitting or Halting Computation
  3. Part 3: Imperative Computation

Structure of the repository

Scala packages under src/main/scala:green.thisfieldwas.embracingnondeterminism

  • data contains commonly-used contexts that Scala defines in its own Standard Library, such as Either, List, and Option and includes Id and NonEmptyList. These code examples demonstrate different encodings of presence as the effects of operations and stand to illustrate how idioms in the series may be implemented across varying types. The Functor typeclass is found here as well.
  • extractables contains illustrations of abstraction over presence using subtype polymorphism with abbreviated definitions of the classes defined in the data package. These exist to highlight the value in using Functor as a design pattern.

Scala packages under src/test/scala:green.thisfieldwas.embracingnondeterminism

  • data contains specs for each of the effect types as well as "laws" tests which assert that the associated effect type is well-defined for particular typeclasses, such as Functor.
  • extractables contains specs and property checks for the extractables classes to illustrate how they work and how their abstractions break down.
  • stdlib contains property checks to illustrate how classes in the Scala Standard Library conform to typeclass laws themselves, and highlight that you, the reader of this series, have been using some of these concepts for some time.
  • util contains utility classes to aid in testing.

Using code and navigating imports

Import the effect you wish to use:


In order to use NonEmptyList as a Functor import both Functor and NonEmptyList's instances:

import{Functor, NonEmptyList}

Functor[NonEmptyList].map(NonEmptyList(1, 2, 3))(x => x * 2) // => NonEmptyList(1, 4, 6)

If you wish to use object-oriented syntax, import Functors extension methods:

import{Functor, NonEmptyList}

NonEmptyList(1, 2, 3).map(x => x * 2) // => NonEmptyList(1, 4, 6)

Using sbt console

Import all project definitions by loading the following script after launching the console:

scala> :load console/imports.scala

This will pull all classes and implicits into scope so that you can work with them directly in the console and experiment with them yourself.