Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add piecemeal import guide #1756

Merged
merged 4 commits into from
Sep 12, 2017
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 37 additions & 1 deletion docs/src/main/tut/typeclasses/imports.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,40 @@ val o: Option[String] = None
o.orEmpty
```

**Note**: if you import `cats.implicits._` (the preferred method), you should _not_ also use imports like `cats.syntax.option._` or `cats.instances.either._`. This can result in ambiguous implicit values that cause bewildering compile errors.
If you'd like to import à la carte, you can do so, by importing from `cats.instances` for the type class instances and `cats.syntax` for syntax enrichment.
For example, if you'd like to import the `Monoid` instance for `String` and the corresponding syntax:
```tut:book
import cats.instances.string._
import cats.syntax.monoid._
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was surprised this actually worked and we didn't need import cats.syntax.semigroup._, but it seems that MonoidSyntax extends SemigroupSyntax.

It seems that all the kernel syntax extends their "super syntax traits", which is another inconsistency between cats-kernel and cats-core (even though this syntax is in cats-core).


"Hello, " |+| "World!"
```
The first import pulls the `Semigroup` instance for String into the scope, while the second import adds the `|+|` syntax.

You can also import all syntax or all instances by importing `cats.syntax.all._` or `cats.instances.all._` respectively.

For data types included in cats (i.e. data structure from the `cats.data` package), all type class instances are bundled with their implementation and therefore do not need to be imported separately.
For example, if we wanted to import `NonEmptyList` from the `cats.data` package and use it's `SemigroupK` instance, we would not need to specifically import the instance:

```tut:book
import cats.data.NonEmptyList
import cats.syntax.semigroupk._

NonEmptyList.of(1,2) <+> NonEmptyList.of(3,4)
```


**Note**: Beware that if you import a type class instance or its syntax twice, you will receive conflicting implicits with a less than helpful error message.
This usually happens when importing different type classes in the same hierarchy or when importing syntax enrichment for all type classes using `cats.syntax.all._` or `cats.implicits._` together with a more specific import like `cats.syntax.option._` or `cats.instances.either._`.
Below is an example of this phenomenon:
```tut:silent
import cats.instances.all._
import cats.syntax.semigroup._
val x = -2 |+| 1

//now we also need access to isEmpty from Monoid
import cats.syntax.monoid._
(x |+| 1).isEmpty //error: value |+| is not a member of Int
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If MonoidSyntax didn't extend SemigroupSyntax, we wouldn't have this issue.

You would only have this issue when you use cats.implicits._ or cats.xxx.all._ in combination with an a la carte import.

```

Compilation fails on the second invocation of `|+|` because we now have conflicting implicits from `Monoid` and `Semigroup`.