score:2

Accepted answer

if i understood

but the f[_] declared at the instance level shadows the f[_] declared at the test method (i want them to be the same f)

correctly, you want your instance for sometypeclass[target[...]] to fix the f[_] parameter of test. but that's simply not possible with this test type signature. once you have (for example)

val inst = implicitly[sometypeclass[target[...]]

you can call

val res1 = inst.test[list, ...]
val res2 = inst.test[option, ...]

type lambdas don't offer a way around this problem. you need to either move f[_] parameter to sometypeclass or implement

implicit def instance[f[_]]: sometypeclass[target[f, *, *]] = new sometypeclass[target[f, *, *]] {
  override def test[g[_], s, t, a, b](f: (a => g[b]) => s => g[t])
                                     (pab: target[f, a, b])
                                     (implicit ev: strong[target[f, *, *]],
                                      ev2: choice[target[f, *, *]],
                                      ev3: applicative[g]): target[g, s, t] = ???
}

which i expect is impossible as you can't pass pab.f to f.

edit: the type of wander

class (choice p, strong p) => traversing p where
  traverse' :: traversable f => p a b -> p (f a) (f b)
  traverse' = wander traverse

  wander :: (forall f. applicative f => (a -> f b) -> s -> f t) -> p a b -> p s t
  wander f pab = dimap (\s -> baz $ \afb -> f afb s) sold (traverse' pab)

is a rank-2 type which aren't supported in scala directly; instead you need to introduce a helper (which can't just be a type alias as it is in control.lens.type)

trait traversal[s, t, a, b] {
  def apply[f[_]: applicative](f: a => f[b]): s => f[t]
}

then

trait traversing[p[_, _]] extends strong[p] with choice[p] {
  def wander[s, t, a, b](t: traversal[s, t, a, b], pab: p[a, b]): p[s, t]
}

implicit def instance[f[_]: applicative]: traversing[target[f, *, *]] = new traversing[target[f, *, *]] {
  def wander[s, t, a, b](t: traversal[s, t, a, b], pab: target[f, a, b]): target[f, s, t] = target(t(pab.f))
  // define strong and choice methods too
}

should work. (though i am not sure this is the cats way to deal with strong and choice requirements.)


Related Query

More Query from same tag