Scalaz Bind[Seq] typeclass

monads, scala, scalaz, typeclass

Solution

The collections library does backflips to accommodate subtyping: when you use `map` on a specific collection type (list, map, etc.), you'll (usually) get the same type back. It manages this through the use of an extremely complex inheritance hierarchy together with type classes like `CanBuildFrom`. It gets the job done (at least arguably), but the complexity doesn't feel very principled. It's a mess. Lots of people hate it.

The complexity is generally pretty easy to avoid as a library user, but for a library designer it's a nightmare. If I provide a monad instance for `Seq`, that means all of my users' types get bumped up the hierarchy to `Seq` every type they use a monadic operation.

Scalaz folks tend not to like subtyping very much, anyway, so for the most part Scalaz stays around the leaves of the hierarchy—`List`, `Vector`, etc. You can see some discussion of this decision on the mailing list, for example.

When I first started using Scalaz I wrote a lot of utility code that tried to provide instances for `Seq`, etc. and make them usable with `CanBuildFrom`. Then I stopped, and now I tend to follow Scalaz in only ever using `List`, `Vector`, `Map`, and `Set` in my own code. If you're committed to "Scalaz style", you should do that as well (or even adopt Scalaz's own `IList`, `ISet`, `==>>`, etc.). You're not going to find clear agreement on best practices more generally, though, and both approaches can be made to work, so you'll just need to experiment to find which you prefer.

Problem

I'm currently porting some code from traditional Scala to Scalaz style. It's fairly common through most of my code to use the Seq trait in my exposed API signatures rather than a concrete type (i.e. List, Vector) directly. However, this poses some problem with Scalaz, since it doesn't provide an implementation of a Bind[Seq] typeclass. i.e. This will work correctly. ``` List(1,2,3,4) >>= bindOperation ``` But this will not ``` Seq(1,2,3,4) >>= bindOperation ``` failing with the error `could not find implicit value for parameter F0: scalaz.Bind[Seq]` I assume this is an intentional design decision in Scalaz - however am unsure about intended/best practice on how to precede. Should I instead write my code directly to List/Vector as appropriate instead of using the more flexible Seq interface? Or should I simply define my own Bind[Seq] typeclass?

Original source

Related problems