```package scalaz

sealed trait MAB[M[_, _], A, B] extends PimpedType[M[A, B]] with MA[({type λ[X]=M[A,X]})#λ, B] {
def asMAB: MAB[M, A, B] = this

def :->[D](g: B => D)(implicit b: Bifunctor[M]): M[A, D] = b.bimap(value, identity[A], g)

def <-:[C](f: A => C)(implicit b: Bifunctor[M]): M[C, B] = b.bimap(value, f, identity[B])

def >>>[C](k: M[B, C])(implicit c: Category[M]): M[A, C] = c compose (k, value)

def ⋙[C](k: M[B, C])(implicit c: Category[M]): M[A, C] = c compose (k, value)

def <<<[C](k: M[C, A])(implicit c: Category[M]): M[C, B] = c compose (value, k)

def ⋘[C](k: M[C, A])(implicit c: Category[M]): M[C, B] = c compose (value, k)

def first[C](implicit a: Arrow[M]): M[(A, C), (B, C)] = a first value

def second[C](implicit a: Arrow[M]): M[(C, A), (C, B)] = a second value

def ***[C, D](k: M[C, D])(implicit a: Arrow[M]): M[(A, C), (B, D)] = a.category.compose(a.second[C, D, B](k), first[C])

def &&&[C](k: M[A, C])(implicit a: Arrow[M]): M[A, (B, C)] = a.category.compose(***(k), a.arrow(a => (a, a)))

def product(implicit a: Arrow[M]): M[(A, A), (B, B)] = this *** value

def ^>>[C](f: C => A)(implicit a: Arrow[M]): M[C, B] = a.category.compose(value, a.arrow(f))

def >>^[C](f: B => C)(implicit a: Arrow[M]): M[A, C] = a.category.compose(a.arrow(f), value)

def <<^[C](f: C => A)(implicit a: Arrow[M]): M[C, B] = a.category.compose(value, a.arrow(f))

def ^<<[C](f: B => C)(implicit a: Arrow[M]): M[A, C] = a.category.compose(a.arrow(f), value)
}

trait MABLow {
implicit def mab[M[_, _], A, B](a: M[A, B]): MAB[M, A, B] = new MAB[M, A, B] {
val value = a
}
}

trait MABs extends MABLow {
implicit def KleisliMAB[M[_], A, B](k: Kleisli[M, A, B]) = mab[({type λ[α, β]=Kleisli[M, α, β]})#λ, A, B](k)

implicit def CokleisliMAB[M[_], A, B](k: Cokleisli[M, A, B]) = mab[({type λ[α, β]=Cokleisli[M, α, β]})#λ, A, B](k)

implicit def Const2MAB[M, A, B](k: Const2[M,A,B]) = mab[({type λ[α, β]=Const2[M, α, β]})#λ, A, B](k)
}

```