typelevel/cats-mtl

Reconsider the `MonadState => ApplicativeAsk` and `FunctorTell` implication.

LukaJCB opened this issue · 1 comments

Right now we have two instances that give you an ApplicativeAsk[F, E] if there's a MonadState[F, E] instance in scope, and a FunctorTell[F, L] instance when MonadState[F, L] is in scope.

These instances are probably useful and lawful, but it still doesn't quite feel right for me.
I kind of expect the environment parameter E in ApplicativeAsk to be immutable and never change, whereas if I have a StateT[F, E], it can change with each flatMap.
I'm not sure if this is a problem or not, but wanted to see what others think about this. :)

Btw, this can lead to ambiguities when importing from cats.mtl.implicits._ as can be seen in this fiddle: https://scalafiddle.io/sf/eybd1uY/0

import cats.mtl._
import cats.implicits._
import cats.mtl.implicits._

def strToInt = (s: String) => s.length

def foo[F[_]](implicit F: ApplicativeAsk[F, String], S: MonadState[F, String]): F[Int] =
  strToInt.reader[F]

I recommend removing these very soon, I'll try to come up with a PR ASAP.