-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
Update FAQ with some references for machinist, kind projector and simulacrum #1183
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,7 +16,7 @@ section: "faq" | |
* [What does `macro Ops` do? What is `cats.macros.Ops`?](#machinist) | ||
* [How can I help?](#contributing) | ||
|
||
## What imports do I need?<a id="what-imports" href="#what-imports"></a> | ||
## <a id="what-imports" href="#what-imports"></a>What imports do I need? | ||
|
||
The easiest approach to cats imports is to import everything that's commonly needed: | ||
|
||
|
@@ -28,15 +28,35 @@ import cats.implicits._ | |
|
||
This should be all that you need, but if you'd like to learn more about the details of imports than you can check out the [import guide](imports.html). | ||
|
||
## Why can't the compiler find implicit instances for Future?<a id="future-instances" href="#future-instances"></a> | ||
## <a id="future-instances" href="#future-instances"></a>Why can't the compiler find implicit instances for Future? | ||
|
||
If you have already followed the [imports advice](#what-imports) but are still getting error messages like `could not find implicit value for parameter e: cats.Monad[scala.concurrent.Future]` or `value |+| is not a member of scala.concurrent.Future[Int]`, then make sure that you have an implicit `scala.concurrent.ExecutionContext` in scope. The easiest way to do this is to `import scala.concurrent.ExecutionContext.Implicits.global`, but note that you may want to use a different execution context for your production application. | ||
|
||
## How can I turn my List of `<something>` into a `<something>` of a list?<a id="traverse" href="#traverse"></a> | ||
## <a id="traverse" href="#traverse"></a>How can I turn my List of `<something>` into a `<something>` of a list? | ||
|
||
It's really common to have a `List` of values with types like `Option`, `Xor`, or `Validated` that you would like to turn "inside out" into an `Option` (or `Xor` or `Validated`) of a `List`. The `sequence`, `sequenceU`, `traverse`, and `traverseU` methods are _really_ handy for this. You can read more about them in the [Traverse documentation]({{ site.baseurl }}/tut/traverse.html). | ||
|
||
## How can I help?<a id="contributing" href="#contributing"></a> | ||
## <a id="simulacrum" href="#simulacrum"></a>What does `@typeclass` mean? | ||
|
||
Cats defines and implements numerous type classes. Unfortunately, encoding these type classes in Scala can incur a large amount of boilerplate. To address this, [Simulacrum](https://github.com/mpilquist/simulacrum) introduces `@typeclass`, a macro annotation which generates a lot of this boilerplate. This elevates type classes to a first class construct and increases the legibility and maintainability of the code. Use of simulacrum also ensures consistency in how the type classes are encoded across a project. Cats uses simulacrum wherever possible to encode type classes, and you can read more about it at the [project page](https://github.com/mpilquist/simulacrum). | ||
|
||
Note that the one area where simulacrum is intentionally not used is in the `cats-kernel` module. The `cats-kernel` module is intended to be a shared dependency for a number of projects, and as such, it is important that it is both lightweight and very stable from a binary compatibility perspective. At some point there may be a transition from simulacrum to [typeclassic](https://github.com/typelevel/typeclassic), and the binary compatibility of moving between simulacrum and typeclassic is unclear at this point. Avoiding the dependency on simulacrum in `cats-kernel`, provides insulation against any potential binary compatibility problems in such a transition. | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
We have made a conscious decision not to use it within cats-kernel to ensure backwards compatibility. I'm not sure whether or not that's worth bringing up here. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good point, I'll add some text this evening for this. Were the backward compatibility concerns related to algebra origins of the code in kernel? I think context would be useful here related to this for reference so I'd like to be able to include something to that effect. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, the compatibility concerns are related to the algebra origins of cats-kernel. I agree that including context would be nice, but we probably don't need to bring in the historical context. I think we could just say something about how the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've incorporated your comment into the text. Let me know what you think! |
||
## <a id="kind-projector" href="#kind-projector"></a>What do types like `?` and `λ` mean? | ||
|
||
Cats defines a wealth of type classes and type class instances. For a number of the type class and instance combinations, there is a mismatch between the type parameter requirements of the type class and the type parameter requirements of the data type for which the instance is being defined. For example, the [Xor]({{ site.baseurl }}/tut/xor.html) data type is a type constructor with two type parameters. We would like to be able to define a [Monad]({{ site.baseurl }}/tut/monad.html) for `Xor`, but the `Monad` type class operates on type constructors having only one type parameter. | ||
|
||
**Enter type lambdas!** Type lambdas provide a mechanism to allow one or more of the type parameters for a particular type constructor to be fixed. In the case of `Xor` then, when defining a `Monad` for `Xor`, we want to fix one of the type parameters at the point where a `Monad` instance is summoned, so that the type parameters line up. As `Xor` is right biased, a type lambda can be used to fix the left type parameter and allow the right type parameter to continue to vary when `Xor` is treated as a `Monad`. The right biased nature of `Xor` is discussed further in the [`Xor` documentation]({{ site.baseurl }}/tut/xor.html). | ||
|
||
**Enter [kind-projector](https://github.com/non/kind-projector)!** kind-projector is a compiler plugin which provides a convenient syntax for dealing with type lambdas. The symbols `?` and `λ` are treated specially by kind-projector, and expanded into the more verbose definitions that would be required were it not to be used. You can read more about kind-projector at the [project page](https://github.com/non/kind-projector). | ||
|
||
## <a id="machinist" href="#machinist"></a>What does `macro Ops` do? What is `cats.macros.Ops`? | ||
|
||
`macro Ops` invokes the [Machinist](https://github.com/typelevel/machinist) Ops macro, and is used in cats in a number of places to enrich types with operations with the minimal possible cost when those operations are called in code. Machinist supports an extension mechanism where users of the macro can provide a mapping between symbolic operator names and method names. The `cats.macros.Ops` class uses this extension mechanism to supply the set of mappings that the cats project is interested in. | ||
|
||
More about the history of machinist and how it works can be discovered at the [project page](https://github.com/typelevel/machinist), or [this article on the typelevel blog](http://typelevel.org/blog/2013/10/13/spires-ops-macros.html). | ||
|
||
## <a id="contributing" href="#contributing"></a>How can I help? | ||
|
||
The cats community welcomes and encourages contributions, even if you are completely new to cats and functional programming. Here are a few ways to help out: | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I put the links at the end of the header because I added a bit of CSS that makes an anchor pop up with a link for each header and if it's on the left side, the header text shifts around which is a bit disorienting. This is something that isn't noticeable if you are just looking at the markdown view, but it will be noticeable once the FAQ is deployed on the site.
I'm definitely open to better options -- I was just looking for low-hanging fruit for easy FAQ links that I could implement with very limited CSS skills :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey @ceedubs - so the reason I switched the order, was that when I tested locally, when the anchor was defined after the text, I built locally and tested the page, and the problem was that clicking the link brought me to just after the heading. So, as the page is a bit larger now, that actually meant that the heading was not visible, and I had to scroll in reverse to see the heading. I thought this would be confusing for anyone who clicked a link not to be able to see the heading of the link they clicked on so I switched the anchor to earlier. I agree about the anchor, but I think it might actually be worse not to be able to see the heading.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mikejcurry ah I see. That makes sense. Let's go with your approach, and hopefully someone will be annoyed enough by the jumping text that they'll fix it for us :P
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My own CSS skills aren't particularly advanced, but if I get some time I'll come back to these links and see if I can find a better way.