In Haskell, liftM2 can be defined as:
liftM2 :: (Monad m) => (a1 -> a2 -> r) -> m a1 -> m a2 -> m r
liftM2 f m1 m2 = do
x1 <- m1
x2 <- m2
return $ f x1 x2
I'd like to translate this to Scala. My first attempt was the following:
def liftM2[T1, T2, R, M[_]](f: (T1, T2) => R)(ma: M[T1], mb: M[T2]) : M[R] = for {
a <- ma
b <- mb
} yield f(a, b)
This fails in what I guess is the most obvious way possible: "value flatMap is not a member of type parameter M[T1]". Right, I haven't indicated that M[_] is some kind of monad. So the next thing I tried was to define some structural type like:
type Monad[A] = {
def flatMap[B](f: (A) => Monad[B]): Monad[B]
}
... and to have M[A] <: Monad[A]. But that doesn't work, because Scala doesn't have recursive structural types.
So the next few things I tried involved gyrations similar to M[A] <: FilterMonadic[A, _]. Those all failed, probably because I wasn't able to figure out the right implicit-fu for CanBuildFrom.
The most closely-related question I could find here on StackOverflow was this one, touching both on recursive structural types and how to mimic Haskell's typeclasses in Scala. But that approach requires defining an implicit conversion from each type you care about to the trait defining the typeclass, which seems terribly circular in this case...
Is there any good way to do what I'm trying to do?
The usual way to encode type classes in Scala turns out to follow Haskell pretty closely: List doesn't implement a Monad interface (as you might expect in an object-oriented language), but rather we define the type class instance in a separate object.
trait Monad[M[_]] {
def point[A](a: => A): M[A]
def bind[A, B](ma: M[A])(f: A => M[B]): M[B]
def map[A, B](ma: M[A])(f: A => B): M[B] = bind(ma)(a => point(f(a)))
}
implicit object listMonad extends Monad[List] {
def point[A](a: => A) = List(a)
def bind[A, B](ma: List[A])(f: A => List[B]) = ma flatMap f
}
This idea is introduced in Poor Man's Type Classes and explored more deeply in Type Classes as Objects and Implicits. Notice that the point method could not have been defined in an object-oriented interface, as it doesn't have M[A] as one of it's arguments to be converted to the this reference in an OO encoding. (Or put another way: it can't be part of an interface for the same reason a constructor signature can't be represented in an interface.)
You can then write liftM2 as:
def liftM2[M[_], A, B, C](f: (A, B) => C)
(implicit M: Monad[M]): (M[A], M[B]) => M[C] =
(ma, mb) => M.bind(ma)(a => M.map(mb)(b => f(a, b)))
val f = liftM2[List, Int, Int, Int](_ + _)
f(List(1, 2, 3), List(4, 5)) // List(5, 6, 6, 7, 7, 8)
This pattern has been applied extensively in Scalaz. Version 7, currently in development, includes an index of the type classes.
In addition to providing type classes and instances for standard library types, it provides a 'syntactic' layer that allows the more familiar receiver.method(args) style of method invocation. This often affords better type inference (accounting for Scala's left-to-right inference algorithm), and allows use of the for-comprehension syntactic sugar. Below, we use that to rewrite liftM2, based on the map and flatMap methods in MonadV.
// Before Scala 2.10
trait MonadV[M[_], A] {
def self: M[A]
implicit def M: Monad[M]
def flatMap[B](f: A => M[B]): M[B] = M.bind(self)(f)
def map[B](f: A => B): M[B] = M.map(self)(f)
}
implicit def ToMonadV[M[_], A](ma: M[A])
(implicit M0: Monad[M]) =
new MonadV[M, A] {
val M = M0
val self = ma
}
// Or, as of Scala 2.10
implicit class MonadOps[M[_], A](self: M[A])(implicit M: Monad[M]) {
def flatMap[B](f: A => M[B]): M[B] = M.flatMap(self)(f)
def map[B](f: A => B): M[B] = M.map(self)(f)
}
def liftM2[M[_]: Monad, A, B, C](f: (A, B) => C): (M[A], M[B]) => M[C] =
(ma, mb) => for {a <- ma; b <- mb} yield f(a, b)
Update
Yep, its possible to write less generic version of liftM2 for the Scala collections. You just have to feed in all the required CanBuildFrom instances.
scala> def liftM2[CC[X] <: TraversableLike[X, CC[X]], A, B, C]
| (f: (A, B) => C)
| (implicit ba: CanBuildFrom[CC[A], C, CC[C]], bb: CanBuildFrom[CC[B], C, CC[C]])
| : (CC[A], CC[B]) => CC[C] =
| (ca, cb) => ca.flatMap(a => cb.map(b => f(a, b)))
liftM2: [CC[X] <: scala.collection.TraversableLike[X,CC[X]], A, B, C](f: (A, B) => C)(implicit ba: scala.collection.generic.CanBuildFrom[CC[A],C,CC[C]], implicit bb: scala.collection.generic.CanBuildFrom[CC[B],C,CC[C]])(CC[A], CC[B]) => CC[C]
scala> liftM2[List, Int, Int, Int](_ + _)
res0: (List[Int], List[Int]) => List[Int] = <function2>
scala> res0(List(1, 2, 3), List(4, 5))
res1: List[Int] = List(5, 6, 6, 7, 7, 8)
Related
I've tried
exstension[A] (f: Iterator[Iterator[A]){
def mapInner[B](f: A => B): Iterator[Iterator[B]
but this loses type information since if I give it a list[list[Int]] I get back Iterator[Iterator[Int]
Try functors and friends:
trait Functor[F[_]]:
extension [A](fa: F[A]) def fmap[B](fmap: A => B): F[B]
object Functor:
given Functor[List] with
extension [A](fa: List[A]) def fmap[B](fmap: A => B): List[B] =
fa.map(fmap)
given [F[_], G[_]](using F: Functor[F], G: Functor[G]): Functor[[x] =>> F[G[x]]] with
extension [A](fa: F[G[A]]) def fmap[B](fmap: A => B): F[G[B]] =
F.fmap(fa)(ga => G.fmap(ga)(fmap))
import Functor.given
val xs = List(1, 2, 3, 4)
val xss = xs.map(x => List(x, x))
val fxss = summon[Functor[[x] =>> List[List[x]]]]
println(fxss.fmap(xss)((a: Int) => a * 2))
It's a lot of setup but likely you don't have to do it yourself and use a library like scalaz or cats where all these things are already defined.
The theory of how a state monad looks like I borrow from Philip Wadler's Monads for Functional Programming:
type M a = State → (a, State)
type State = Int
unit :: a → M a
unit a = λx. (a, x)
(*) :: M a → (a → M b) → M b
m * k = λx.
let (a, y) = m x in
let (b, z) = k a y in
(b, z)
The way I would like to use a state monad is as follows:
Given a list L I want different parts of my code to get this list and update this list by adding new elements at its end.
I guess the above would be modified as:
type M = State → (List[Data], State)
type State = List[Data]
def unit(a: List[Data]) = (x: State) => (a,x)
def star(m: M, k: List[Data] => M): M = {
(x: M) =>
val (a,y) = m(x)
val (b,z) = k(a)(y)
(b,z)
}
def get = ???
def update = ???
How do I fill in the details, i.e.?
How do I instantiate my hierarchy to work on a concrete list?
How do I implement get and update in terms of the above?
Finally, how would I do this using Scala's syntax with flatMap and unit?
Your M is defined incorrectly. It should take a/A as a parameter, like so:
type M[A] = State => (A, State)
You've also missed that type parameter elsewhere.
unit should have a signature like this:
def unit[A](a: A): M[A]
star should have a signature like this:
def star[A, B](m: M[A], k: A => M[B]): M[B]
Hopefully, that makes the functions more clear.
Your implementation of unit was pretty much the same:
def unit[A](a: A): M[A] = x => (a, x)
However, in star, the parameter of your lambda (x) is of type State, not M, because M[B] is basically State => (A, State). The rest you got right:
def star[A, B](m: M[A])(k: A => M[B]): M[B] =
(x: State) => {
val (a, y) = m(x)
val (b, z) = k(a)(y)
(b, z)
}
Edit: According to #Luis Miguel Mejia Suarez:
It would probably be easier to implement if you make your State a class and define flatMap inside it. And you can define unit in the companion object.
He suggested final class State[S, A](val run: S => (A, S)), which would also allow you to use infix functions like >>=.
Another way to do it would be to define State as a type alias for a function S => (A, S) and extend it using an implicit class.
type State[S, A] = S => (A, S)
object State {
//This is basically "return"
def unit[S, A](a: A): State[S, A] = s => (a, s)
}
implicit class StateOps[S, A](private runState: S => (A, S)) {
//You can rename this to ">>=" or "flatMap"
def *[B](k: A => State[S, B]): State[S, B] = s => {
val (a, s2) = runState(s)
k(a)(s2)
}
}
If your definition of get is
set the result value to the state and leave the state unchanged
(borrowed from Haskell Wiki), then you can implement it like this:
def get[S]: State[S, S] = s => (s, s)
If you mean that you want to extract the state (in this case a List[Data]), you can use execState (define it in StateOps):
def execState(s: S): S = runState(s)._2
Here's a terrible example of how you can add elements to a List.
def addToList(n: Int)(list: List[Int]): ((), List[Int]) = ((), n :: list)
def fillList(n: Int): State[List[Int], ()] =
n match {
case 0 => s => ((), s)
case n => fillList(n - 1) * (_ => addToList(n))
}
println(fillList(10)(List.empty)) gives us this (the second element can be extracted with execState):
((),List(10, 9, 8, 7, 6, 5, 4, 3, 2, 1))
For learning purposes, I am trying to define a wrapper class called DoubleMap which provides the method mapBoth. It essentially takes two functions f and g, where the domain of g is the co-domain of f. The composition of this function (g o f) should then be mapped of the container wrapped by DoubleMap
This is my current code:
implicit class DoubleMap
[A, B, C, F[X] <: List[X]] // just List for now
(xs: F[A])(implicit cbf: CanBuildFrom[F[A], C, F[C]]) {
def mapBoth(f: A => B)(g: B => C): F[C] =
xs.map(f andThen g).to[F]
}
However, when I want to use the method like this:
List(true, false, false).mapBoth(!_)(!_)
I get a cryptical error message about the type mismatch between the (found) type CanBuildFrom[List[_], Nothing, List[Nothing]] and the (required) type CanBuildFrom[List[Boolean], C, List[C]]
Why does the compiler infer the first type?
Your call expands to
DoubleMap(xs).mapBoth(!_)(!_)
so all of DoubleMap's type parameters and cbf need to be inferred before the mapBoth call is handled. To fix it, just move these parameters to mapBoth:
implicit class DoubleMap
[A, F[X] <: List[X]] // just List for now
(xs: F[A]) {
def mapBoth[B, C](f: A => B)(g: B => C)(implicit cbf: CanBuildFrom[F[A], C, F[C]]): F[C] =
xs.map(f andThen g).to[F]
}
Then B and C are determined from f and g, and cbf from F, A and C.
If you wish to not be tied to List, consider Functor from Cats
implicit class DoubleMap[F[_]: Functor, A](xs: F[A]) {
def mapBoth[B, C](f: A => B)(g: B => C): F[C] =
xs.map(f andThen g)
}
or vanilla Scala 2.13 approach (inspired by Luis' 2.12 implementation)
implicit class DoubleMap[F[x] <: IterableOnce[x], A](xs: F[A]) {
def mapBoth[B, C](f: A => B)(g: B => C)(implicit bf: BuildFrom[F[A], C, F[C]]): F[C] =
bf.fromSpecific(xs)(xs.iterator.map(f andThen g))
}
which both output
List(true, false, false).mapBoth(!_)(!_)
Vector(true, false, false).mapBoth(!_)(!_)
res1: List[Boolean] = List(true, false, false)
res2: Vector[Boolean] = Vector(true, false, false)
Looking through the haskell free package (http://hackage.haskell.org/package/free-3.4.2) there's a few types that seem simple and useful, that I see almost no literature on outside of haskell, the type I'm interested in now is the Free Applicative.
Now I think that the free applicative builds up chains of function applications as data and maps them (out-of / over) G, (I think...)
where I'm at ...
trait Functor[F[_]] {
def map[A, B](f: A => B): F[A] => F[B]
}
trait Applicative[F[_]] extends Functor[F] {
def ap[A, B](f: F[A => B]): F[A] => F[B]
def apF[A, B](f: F[A])(x: F[A => B]): F[B]
}
trait FreeAp[F[_], A] {
def map[B](f: A => B): FreeAp[F, B] = {
this match {
case Pure(x) => Pure(f(x))
case Ap(x, y) => Ap(x, { y.map(f.compose _) })
}
}
def runAp[G[_]](phi: F ~> G, fa: FreeAp[F, A])(implicit G: Applicative[G]): G[A] = {
fa match {
case Pure(x) => G.pure(x)
case Ap(f, x) => G.apF(phi(f)) { G.map(id[A])(runAp(phi, x)) }
}
}
def runApM[B, M](phi: F ~> ({ type l[x] = M })#l, x: FreeAp[F, B])(implicit M: Monoid[M]): M = {
???
}
}
case class Pure[F[_], A](x: A) extends FreeAp[F, A]
case class Ap[F[_], A, B](x: F[A], y: FreeAp[F, A => B]) extends FreeAp[F, B]
what I'm asking for: the runAp looks so simple in haskell but I've been having some trouble translating... I need a shove in the right direction
runAp :: Applicative g => (forall x. f x -> g x) -> Ap f a -> g a
runAp _ (Pure x) = pure x
runAp u (Ap f x) = flip id <$> u f <*> runAp u x
Ideally I'd like a gentle walk through the free applicative and some help with at least the runAp implementation (but really get into it and spare no detail)
update: so I've been working with this myself and I tried implementing map and I get a variance error, the second case expression gives an error unless FreeAp is contravariant in A, but the first case expression gives an error unless FreeAp isn't contravariant in A...
Any Ideas ?
update: I added the variance annotations from #Cirdec's answer and it didn't suddenly work but I played around and added a annotation [Any, B] to the Ap construction in map and now that definition type checks. so far though no luck with runAp...
update: this is the type error I'm getting on the Ap branch of the runAp pattern match ...
type mismatch; found : core01.FreeAp[F,Any => A] required: core01.FreeAp[F,A]
////
trait Forall[P[_]] {
def apply[A]: P[A]
}
trait ~>[F[_], G[_]] {
def apply[A](x: F[A]): G[A]
}
UPDATE
reading:
http://ro-che.info/articles/2013-03-31-flavours-of-free-applicative-functors.html,
Free Applicative Functors by Paolo Capriotti
//// including the Functor & Applicative definitions above
trait FreeAp[F[_], A] { self =>
def map[B](f: A => B): FreeAp[F, B] = {
this match {
case Pure(x) => Pure(f(x))
case ap: Ap[F, α, _] => Ap(ap.x.map(f.compose(_: α => A)), ap.y)
}
}
}
case class Pure[F[_], A](x: A) extends FreeAp[F, A]
case class Ap[F[_], A, B](x: FreeAp[F, A => B], y: F[A]) extends FreeAp[F, B]
def liftAp[F[_], A](x: F[A]): FreeAp[F, A] = Ap[F, A, A](Pure(id), x)
def runAp[F[_], G[_], A](implicit G: Applicative[G]): (F ~> G) => FreeAp[F, A] => G[A] = {
(u: F ~> G) =>
(fa: FreeAp[F, A]) => fa match {
case Pure(x) => G.pure(x)
case ap: Ap[F, α, _] => {
val gf: G[(α => A) => A] = G.map(curry(flip(id[α => A])))(u(ap.y))
val gx: G[α => A] = runAp(G)(u)(ap.x)
G.ap(gf)(gx)
}
}
}
trait FreeApFunctor[F[_]] extends Functor[({ type l[x] = FreeAp[F, x] })#l] {
final override def map[A, B](f: A => B): FreeAp[F, A] => FreeAp[F, B] = _ map f
}
trait FreeApSemiapplicative[F[_]] extends Apply[({ type l[x] = FreeAp[F, x] })#l] with FreeApFunctor[F] {
final def ap[A, B](f: => FreeAp[F, A => B]): FreeAp[F, A] => FreeAp[F, B] = {
(fa: FreeAp[F, A]) => f match {
case Pure(x) => map(x)(fa)
case a: Ap[F, α, _] => Ap(ap{ map(flip[α, A, B])(a.x) }(fa), a.y)
}// ^^^
// type mismatch; found : core01.FreeAp[F,α => _] required: core01.FreeAp[F,(α, A) => B]
}
}
Traits
First, you'll need to get what Applicative and Functor are correct. Let's start with Functor. I'm going to use the Haskell names and argument orders for everything, where I can:
class Functor f where
fmap :: (a -> b) -> f a -> f b
trait Functor[F[+_]] {
def fmap[A,B]: (A => B) => F[A] => F[B]
}
Now Applicative. Your Applicative is missing that an Applicative first must be a Functor and that an Applicative has a way to make one from a value. The type for apF also seems to be incorrect; it should allow you to apply a function that is stuck inside the functor to a value that is also stuck inside the functor.
class Functor f => Applicative f where
pure :: a-> f a
(<*>) :: f (a -> b)-> f a -> f b
trait Applicative[F[+_]] extends Functor[F] {
def pure[A]: A => F[A]
def apF[A,B]: F[A => B] => F[A] => F[B]
}
I'd suggest you make something else that's applicative before jumping all the way to free applicative, perhaps the Identity functor and its applicative instance. Hopefully this will help you understand what you need to be making for the free applicative instance.
Data Types and Variance
Now we need the data types.
data Ap f a where
Pure :: a -> Ap f a
Ap :: f a -> Ap f (a -> b) -> Ap f b
In Scala, these are represented by case classes:
sealed abstract class FreeAp[F[+_],+A]
case class Pure[F[+_], +A](a: A) extends FreeAp[F, A]
case class Ap[F[+_], A, +B](x: F[A], fg: FreeAp[F,A=>B]) extends FreeAp[F, B]
In order for Scala's variant types to work, we annotated these with variance, and marked the variance correctly on our traits as well. This is normal in languages with variant type systems, a similar interface in c# would require in and out annotation to be generally useful and match the expectations of programmers using libraries. If you really hate variance, you can remove all the variance annotations from my answer, and it still works - you just won't have variant interfaces.
Instances
We can start porting the instances for Functor and Applicative:
instance Functor (Ap f) where
fmap f (Pure a) = Pure (f a)
fmap f (Ap x y) = Ap x ((f .) <$> y)
instance Applicative (Ap f) where
pure = Pure
Pure f <*> y = fmap f y
Ap x y <*> z = Ap x (flip <$> y <*> z)
Functor and Applicative Instances
A functor instance in Scala is difficult to write, due to the fact that there aren't really universally quantified types. With universally quantified types, flip and compose could both be used below without explicit types. We can get around this by binding a type variable, a, in pattern matching, which is done by the pattern ap: Ap[F,a,_]. The type variable is used to provide the explicit types .compose(_ : a => A) and flip[a,A,B].
class FreeApInstances[F[+_]] {
implicit object FreeApApplicativeInstance extends Applicative[({type f[+x] = FreeAp[F, x]})#f] {
// Functor
final def fmap[A,B]: (A=>B) => FreeAp[F,A] => FreeAp[F,B] =
(f: A=>B) => (fa: FreeAp[F,A]) => fa match {
case Pure(a) => Pure(f(a))
case ap: Ap[F, a, _] => Ap(ap.x, fmap(f.compose(_ : a => A))(ap.fg))
}
// Applicative
final def pure[A]: A => FreeAp[F,A] =
(a: A) => Pure(a)
final def apF[A, B]: FreeAp[F,A=>B] => FreeAp[F,A] => FreeAp[F,B] =
(ff: FreeAp[F,A=>B]) => (fa: FreeAp[F,A]) => ff match {
case Pure(f) => fmap(f)(fa)
case ap: Ap[F, a, _] => Ap(ap.x, apF(fmap(flip[a,A,B])(ap.fg))(fa))
}
}
}
flip, which is needed for Applicative, just flips the order of two arguments:
def flip[A,B,C]: (A => B => C) => B => A => C =
(f: (A => B => C)) => (b: B) => (a: A) => f(a)(b)
runAp
Finally, we can port runAp:
-- | Given a natural transformation from #f# to #g#, this gives a canonical monoidal natural transformation from #'Ap' f# to #g#.
runAp :: Applicative g => (forall x. f x -> g x) -> Ap f a -> g a
runAp _ (Pure x) = pure x
runAp u (Ap f x) = flip id <$> u f <*> runAp u x
This requires a universal quantification for forall x. f x -> g x. We can satisfy this one with the usual trick for languages with generics - add a generic member to something; the member can then provide something for all types, though we will need to be able to explicitly provide the type. You have clearly already found a Scala type for natural transformations:
trait ~>[F[_],G[_]] { def apply[B](f: F[B]): G[B] }
Again, we'll bind a type variable a from the pattern ap: Ap[F, a _] to get the type that Scala can't infer, id: (a=>A) => a => A.
def runAp[F[_],G[_],A](implicit g: Applicative[G]):
(F ~> G) => FreeAp[F,A] => G[A] =
(u: F ~> G) => (fa: FreeAp[F,A]) => fa match {
case Pure(x) => g.pure(x)
case ap: Ap[F, a, _] => {
val gf: G[(a=>A)=>A] = g.fmap(flip(id[a=>A]))(u.apply(ap.x))
val gx: G[a=>A] = runAp(g)(u)(ap.fg)
g.apF(gf)(gx)
}
}
id is just the identity function:
def id[A]: A => A =
(x:A) => x
I have a monad that is very similar to a collection monad. I'm currently trying to implement a monad transformer for it, but I'm failing.
I've looked at the ListT implementation in Scalaz 6 and 7, but I cannot understand how it works. It uses some additional type Step, whose purpose is unclear to me.
So can someone please explain to me how to implement a list monad transformer, either by explaining the Scalaz approach or using a different implementation?
I am not quite sure, what the Step means in scalaz, but implementing a ListT is pretty straight forward. Depending on how many operations you want to put on it, it can be a little work, but the basic monad operations can be implemented as follows.
First we need typeclasses for monad and functor (we could also add applicative, but that is not necessary for this example):
trait Functor[F[_]] {
def map[A,B](fa: F[A])(f: A => B): F[B]
}
trait Monad[F[_]] extends Functor[F] {
def flatMap[A,B](fa: F[A])(f: A => F[B]): F[B]
def pure[A](x: A): F[A]
}
object Monad {
implicit object ListMonad extends Monad[List] {
def map[A,B](fa: List[A])(f: A => B) = fa map f
def flatMap[A,B](fa: List[A])(f: A => List[B]) = fa flatMap f
def pure[A](x: A) = x :: Nil
}
implicit object OptionMonad extends Monad[Option] {
def map[A,B](fa: Option[A])(f: A => B) = fa map f
def flatMap[A,B](fa: Option[A])(f: A => Option[B]) = fa flatMap f
def pure[A](x: A) = Some(x)
}
def apply[F[_] : Monad]: Monad[F] = implicitly[Monad[F]]
}
Once we have those, we can create the transformer, which basically just wraps the F[List[A]] and forwards the call to its map and flatMap function to the list by calling map on the containing functor and then calling map or flatMap resp. on the contained List/s.
final case class ListT[F[_] : Monad, A](fa: F[List[A]]) {
def map[B](f: A => B) = ListT(Monad[F].map(fa)(_ map f))
def flatMap[B](f: A => ListT[F, B]) = ListT(Monad[F].flatMap(fa) { _ match {
case Nil => Monad[F].pure(List[B]())
case list => list.map(f).reduce(_ ++ _).run
}})
def ++(that: ListT[F,A]) = ListT(Monad[F].flatMap(fa) { list1 =>
Monad[F].map(that.run)(list1 ++ _)
})
def run = fa
}
Once we are done with modifying, we can get the resulting object by calling the run method on the ListT object. If you want, you can also add other list specific operations like in scalaz. This should be pretty straight forward. For example a :: could look as follows:
def ::(x: A) = ListT(Monad[F].map(fa)(x :: _))
Usage:
scala> ListT(Option(List(1,2,3)))
res6: ListT[Option,Int] = ListT(Some(List(1, 2, 3)))
scala> res6.map(_+45)
res7: ListT[Option,Int] = ListT(Some(List(46, 47, 48)))
scala> 13 :: res7
res8: ListT[Option,Int] = ListT(Some(List(13, 46, 47, 48)))
scala> res8.run
res10: Option[List[Int]] = Some(List(13, 46, 47, 48))
I think scalaz.ListT is incorrect in scalaz 7.0.x and 7.1.x.
https://github.com/scalaz/scalaz/issues/921
6.x version is correct. but it is same as StreamT.