Scala variable scope in object - scala

I'm looking at http://hseeberger.wordpress.com/2010/11/25/introduction-to-category-theory-in-scala/ and there's a bit of code that I can't understand how it works:
object Functor {
def fmap[A, B, F[_]](as: F[A])(f: A => B)(implicit functor: Functor[F]): F[B] =
functor.fmap(as)(f)
implicit object ListFunctor extends Functor[List] {
def fmap[A, B](f: A => B): List[A] => List[B] =
as => as map f
}
}
Specifically, how is ListFunctor.fmap accessing as when the definition of as is in the scope of Functor.fmap and (as far as I can tell) inaccessible to ListFunctor.fmap?
(related with a twist) There's a previous iteration to the above code that's defined:
trait Functor[F[_]] extends GenericFunctor[Function, Function, F] {
final def fmap[A, B](as: F[A])(f: A => B): F[B] =
fmap(f)(as)
}
object ListFunctor extends Functor[List] {
def fmap[A, B](f: A => B): List[A] => List[B] = as => as map f
}
But again, as seems to be magically accessible to ListFunctor. I guess if I understand one of these, I'll understand the other.

It is not the same as, just the same name is (probably not quite) accidentally used in two places. The as => as map f is a function definition, and the as before the arrow is a declaration of a parameter for this very function.
It would be completely equivalent if written as x => x map f.

Related

How can I define an HKT for instance (over object) methods in Scala?

How do you define an HKT in Scala to provide methods, such as map, as methods on instances instead of functions on objects?
I know you can
trait M[F[_]] {
def map[A, B](f: F[A])(fn: A => B): F[B]
}
object Q extends M[Q] {
def map[A, B](f: Q[A])(fn: A => B) = new Q(fn(f.e))
}
class Q[A](val e: A)
Q.map(new Q(1))(_.toDouble)
However, I want to use map on instances instead. I haven't seen any literature that does this, so I've written the following.
trait M[A, F[A]] {
def map[B](f: A => B): F[B]
}
class Q[A](val e: A) extends M[A, Q] {
def map[B](f: A => B) = new Q(f(e))
}
new Q(1).map(_.toDouble)
Is it idiomatic Scala? Does it do what map should do? Are there limitations compared with the object version above? (An aside, with extends M[A, Q[A]] it won't compile - why?)
I have seen
trait M[A] {
def map[B](f: A => B): M[B]
}
but then Q's map could return a class R[A] extends M[A] which isn't desired.
There's a library specifically for this: https://github.com/mpilquist/simulacrum
You can also do it yourself. The typical pattern is to define a corresponding implicit MOps class or whatever:
trait M[F[_]] {
def map[A, B](f: F[A])(fn: A => B): F[B]
}
implicit class MOps[F[_] : M, A](x: F[A]) {
def map[B](f: A => B): F[B] = implicitly[M[F]].map(x)(f)
}
Then example usage:
case class Box[A](a: A)
implicit val BoxM = new M[Box] {
def map[A, B](f: Box[A])(fn: A => B): Box[B] = Box(fn(f.a))
}
Box(2).map(_.toString)
But it's a lot of boilerplate, so simulacrum does it all for you (and more).

Understanding FoldLeft in ScalaZ

I'm reading some articles about ScalaZ and have a question about understanding it. In this article, we generalize the sum function, to abstract away the type to be summed.
def sum[T](xs: List[T])(implicit m: Monoid[T]) = //...
Where
trait Monoid[A] is defined as follows:
trait Monoid[A] {
def mappend(a1: A, a2: A): A
def mzero: A
}
Yes, this is pretty clear. Monoid here corresponds to the algebraic monoid structure. Now in this article it abstracts over lists. To do this we define the following trait:
trait FoldLeft[F[_]] {
def foldLeft[A, B](xs: F[A], b: B, f: (B, A) => B): B
}
object FoldLeft {
implicit val FoldLeftList: FoldLeft[List] = new FoldLeft[List] {
def foldLeft[A, B](xs: List[A], b: B, f: (B, A) => B) = xs.foldLeft(b)(f)
}
}
So now we can define the sum function as follows:
def sum[M[_]: FoldLeft, A: Monoid](xs: M[A]): A = {
val m = implicitly[Monoid[A]]
val fl = implicitly[FoldLeft[M]]
fl.foldLeft(xs, m.mzero, m.mappend)
}
I'm not a theory category expert, but it looks like Applicative functor to me. Is that correct? Can we provide such similarity to category theory.
Applicative functor is a type class with two operations: A => F[A] and F[A => B] => F[A] => F[B]. None of operations you mentioned has such signature. FoldLeft is more like Foldable. It's a different type class, a parent of Traversable (aka Traverse). And Traversable is connected with Applicative.
trait Functor[F[_]] {
def fmap[A, B](f: A => B)(fa: F[A]): F[B]
}
trait Applicative[F[_]] extends Functor[F] {
def pure[A](a: A): F[A]
def ap[A, B](ff: F[A => B])(fa: F[A]): F[B]
override def fmap[A, B](f: A => B)(fa: F[A]): F[B] = ap(pure(f))(fa)
}
trait Foldable[T[_]] {
def foldr[A, B](op: A => B => B)(seed: B)(ta: T[A]): B =
(foldMap(op)(ta) _)(seed)
def foldMap[A, M](f: A => M)(ta: T[A])(implicit monoid: Monoid[M]): M =
foldr[A, M](a => m => monoid.append(f(a), m))(monoid.empty)(ta)
}
trait Traversable[T[_]] extends Functor[T] with Foldable[T] {
def traverse[F[_]: Applicative, A, B](k: A => F[B])(ta: T[A]): F[T[B]] =
sequence[F, B](fmap[A, F[B]](k)(ta))
def sequence[F[_]: Applicative, A](tfa: T[F[A]]): F[T[A]] =
traverse[F, F[A], A](fa => fa)(tfa)
override def fmap[A, B](f: A => B)(ta: T[A]): T[B] = traverse[Id, A, B](f)(ta)
override def foldr[A, B](op: A => B => B)(seed: B)(ta: T[A]): B =
(traverse[Const[B => B]#λ, A, B](op)(ta) _)(seed)
override def foldMap[A, M: Monoid](f: A => M)(ta: T[A]): M =
traverse[Const[M]#λ, A, M](f)(ta)
}
type Id[A] = A
trait Const[C] {
type λ[A] = C
}
Type class Functor means you have a "container" F[_] and you know how to apply function f: A => B inside this container. Type class Applicative means you know how to pack a value a: A inside this container and how to apply a "function" F[A => B] to a "value" F[A]. Foldable means you know how to fold your container using binary operation A => B => B and starting value B and receiving result B. Traversable means you know how to traverse your container executing applicative effect A => F[B] in every "node".

Making my own Functor typeclass in Scala

So I wanted to make my own Functor to play around with typeclassing. However I ran into a bunch of issues.
The endgoal is to be able to say something like Seq(1,2,3).fmap(2*_).
I came up with this trait which all my Google searches (kind of) agree on:
trait Functor[F[_]] {
def fmap[A, B](r: F[A], f: A => B): F[B]
}
I'm assuming there's no easy way to link the A to the F[_], i.e. "F[A]".
But I'm having serious trouble creating an implicit to connect to Seq. Here's one try:
implicit class SeqFunctorOps[A](xs: Seq[A]) {
def fmap[B](f: A => B) = xs map f
}
But that doesn't fit into my Functor, so let's extend it:
implicit class SeqFunctorOps[A](xs: Seq[A]) extends Functor[Seq] {
def fmap[A, B](f: A => B) = xs map f
}
But that doesn't work because in fmap[A, B]..., the A is a new generic type, and doesn't tie in with xs: Seq[A].
Is there a way to tie them in?
However, it also seems to me that implicit class is not the way to go, considering that other online resources have pointed to using the companion object, but I just can't seem to make it work.
object Functor {
implicit def SeqFunctor: Functor[Seq] = new Functor[Seq] {
def fmap[A, B](r: Seq[A], f: A => B) = r map f
}
}
implicit class SeqFunctorOps[A](xs: Seq[A])(implicit F: Functor[Seq]) {
def fmap[B](f: A => B) = F.fmap(xs, f)
}
This kind of seems to work, but looks off.
Is there a general pattern to use when trying to do something like this?
Glory be to #drexin, this seems to be good enough:
trait Functor[F[_]] {
def fmap[A, B](r: F[A], f: A => B): F[B]
}
object Functor {
implicit def SeqFunctor: Functor[Seq] = new Functor[Seq] {
def fmap[A, B](r: Seq[A], f: A => B) = r map f
}
implicit class Ops[A, F[_]: Functor](xs: F[A]) {
def fmap[B](f: A => B) = implicitly[Functor[F]].fmap(xs, f)
}
}

Scala: deferring a trait method to an implicit class in parent trait's object

Specifically, I'm trying to extend my Functor typeclass with Applicative.
trait Functor[F[_]] {
def fmap[A, B](r: F[A], f: A => B): F[B]
}
object Functor {
implicit class FunctorOps[A, F[_]: Functor](xs: F[A]) {
def fmap[B](f: A => B): F[B] = implicitly[Functor[F]].fmap(xs, f)
}
implicit def SeqFunctor: Functor[Seq] = new Functor[Seq] {
def fmap[A, B](r: Seq[A], f: A => B) = r map f
}
}
trait Applicative[F[_]] extends Functor[F] {
// What I want to do, but this *does not* work.
def fmap[A, B](r: F[A], f: A => B): F[B] = Functor.FunctorOps[A, F](r).fmap(f)
def pure[A](x: A): F[A]
def fapply[A, B](r: F[A], f: F[A => B]): F[B]
}
object Applicative {
implicit class ApplicativeOps[A, F[_]](a: F[A])(implicit F: Applicative[F]) {
def fapply[B](f: F[A => B]): F[B] = F.fapply(a, f)
}
implicit def SeqApplicative: Applicative[Seq] = new Applicative[Seq] {
def pure[A](x: A) = Seq(x)
def fapply[A, B](xs: Seq[A], fs: Seq[A => B]): Seq[B] = xs.flatMap(x => fs.map(_(x)))
}
}
The gist of it is I have to implement fmap for all Applicatives, but it should really be the same method as defined in my FunctorOps class. How do I do this in the cleanest way possible?
You got the Applicative[F] <: Functor[F] part right, but you should really think about what that means. It means that an instance of Applicative[F] also provides the methods for Functor[F]. That is, you can't have both implicit val listFunctor: Functor[List]; implicit val listApplicative: Applicative[List], because then the compiler is confused when you ask for implicit param: Functor[List]. You should only have the latter. What you're trying to do is then nonsensical, because you're defining the Functor instance for F in terms of itself (because the Applicative[F] should be the Functor[F]), and you end up with two Functor[Seq]s regardless.
What you can do is implement fmap in terms of pure and fapply:
trait Applicative[F[_]] extends Functor[F] {
override def fmap[A, B](r: F[A], f: A => B): F[B] = fapply(r, pure(f))
def pure[A](x: A): F[A]
def fapply[A, B](r: F[A], f: F[A => B]): F[B]
}
Then remove the Functor[Seq] instance and keep your Applicative[Seq] the way it is (or override fmap if you want). You have a different problem now, being that implicit search gets a bit turned around, as the Functor[Seq] instance is actually in object Applicative, but fixing implicit resolution is less onerous than enforcing the consistency of separate Functor and Applicative instances. In this case, where Seq is a type whose companion object you cannot control, cats, at least, does something like
package instances {
trait SeqInstances {
implicit val seqFunctor: Functor[Seq] = ???
}
package object seq extends SeqInstances
package object all extends SeqInstances
with AAAInstances
with BBBInstances
with ...
}
FYI: I suggest currying your typeclass methods
def fmap[A, B](r: F[A])(f: A => B): F[B]
def fapply[A, B](r: F[A])(f: F[A => B]): F[B]
and it may be nice to have a flip fapply in ApplicativeOps
def ylppaf[I, B](f: F[I])(implicit ev: A =:= (I => B))
: F[B] = F.fapply(a.fmap(ev))(f)

Reader monad - how does it conform to Monad interface?

I'm learning category theory.
I understand the concept of reader monad, it's even pretty easy to implement:
case class Reader[DEP, A](g: DEP => A) {
def apply(dep: DEP): A = g(dep)
def map[B](f: A => B): Reader[DEP, B] = Reader(dep => f(apply(dep)))
def flatMap[B](f: A => Reader[DEP, B]): Reader[DEP, B] = Reader(dep => f(apply(dep)) apply dep)
}
However, I have problems implementing it with constraint to some generic Monad interface, i.e
trait Monad[A] {
def pure(a: A): Monad[A]
def map[B](f: A => B): Monad[B]
def flatMap[B](f: A => Monad[B]): Monad[B]
}
let's forgot for a second that there's an applicative or functor and let's just put these 3 methods here.
Now, having this interface I have problems implementing ReaderMonad.
map method is pretty straighforward, but what about pure and flatMap?
What does it even mean to have pure on Reader?
To implement flatMap, I need to have a function from A to Reader[DEP, B], but I have A => Monad[B], thus I'm not possible to access apply.
case class Reader[DEP, A](g: DEP => A) extends Monad[A] {
def apply(dep: DEP): A = g(dep)
override def pure(a: A): Reader[DEP, A] = Reader(_ => a) // what does it even mean in case of Reader
override def map[B](f: (A) => B): Reader[DEP, B] = Reader(dep => f(apply(dep)))
override def flatMap[B](f: (A) => Monad[B]): Reader[DEP, B] = ??? // to implement it, I need f to be (A) => Reader[DEP, B], not (A) => Monad[B]
}
Is it possible to implement it this way in scala? I tried to play around with self bound types, but it didn't work either.
I know libraries like scalaz or cats uses typeclasses to implement these types, but this is just for educational purpose.
As you've discovered when trying to implement flatMap, the problem with declaring the Monad trait as you have is you lose the particular monad type you're defining when chaining operations. The usual way of defining the Monad trait is to parameterise it by the type constructor the monad instance is being defined for e.g.
trait Monad[M[_]] {
def pure[A](a: A): M[A]
def map[A, B](f: A => B, m: M[A]): M[B]
def flatMap[A, B](f: A => M[B], m : M[A]): M[B]
}
So M is a unary type constructor such as List or Option. You can think of a Reader[DEP, A] as being a computation which depends on some environment type DEP which returns a value of type A. Since this has two type parameters you need to fix the environment parameter type when defining the monad instance:
case class Reader[DEP, A](g: DEP => A)
class ReaderMonad[DEP]() extends Monad[({type t[X] = Reader[DEP, X]})#t] {
def pure[A](a: A) = Reader[DEP, A](_ => a)
def map[A, B](f: A => B,m: Reader[DEP,A]): Reader[DEP,B] = Reader(env => f(m.g(env)))
def flatMap[A, B](f: A => Reader[DEP,B],m: Reader[DEP,A]): Reader[DEP,B] = Reader(env => f(m.g(env)).g(env))
}
({type t[X] = Reader[DEP, X]})#t is a type lambda used to partially apply one of the two parameters for Reader[DEP, A].
Now pure returns a Reader which ignores the environment and returns the given value directly.
flatMap constructs a Reader which when run will run the inner computation, use the result to construct the next computation and run it with the same environment.