scalaz/scalaz — pull request #153 by eed3si9n (2012-09-19 12:36:28+00:00)
Title: adds implicits to Unapply to unpack A into [α]A

### steps

currently `Int => Int` cannot be passed into `traverseU`. `Int` is indirectly available as `Applicative` via `Monoid[Int].applicative`, which is `Applicative[[α]Int]`.

```scala
scala> Applicative[({type λ[α] = Int})#λ]
res0: scalaz.Applicative[[α]Int] = scalaz.Monoid$$anon$1@26b0207f

scala> List(1, 2, 3) traverseU {_ + 1}
:14: error: Unable to unapply type `Int` into a type constructor of kind `M[_]` that is classified by the type class `scalaz.Applicative`
1) Check that the type class is defined by compiling `implicitly[scalaz.Applicative[]]`.
2) Review the implicits in object Unapply, which only cover common type 'shapes'
(implicit not found: scalaz.Unapply[scalaz.Applicative, Int])
List(1, 2, 3) traverseU {_ + 1}
^
```

### what this changes

I added `unapplyA` as the lowest priority implicit, which unpacks A into [α]A.

```scala
trait Unapply_3 {
// /** Unpack a value of type `A0` into type `[a]A0`, given a instance of `TC` */
implicit def unapplyA[TC[_[_]], A0](implicit TC0: TC[({type λ[α] = A0})#λ]): Unapply[TC, A0] {
type M[X] = A0
type A = A0
} = new Unapply[TC, A0] {
type M[X] = A0
type A = A0
def TC = TC0
def apply(ma: M[A0]) = ma
}
}
```

With this, `traverseU` works as follows:

```scala
scala> List(1, 2, 3) traverseU {_ + 1}
res0: Int = 9
```