Consider, you have the Nel of states (Nel stands for NonEmptyList, to make things shorter),
and you want to combine the States to one State, using some function f, for left part of the state and
g for the right part of the state.
So you want something like this:
def foldStatesG[S, A](in: NonEmptyList[State[S, A]])(f: (A, A) => A)(g: (S, S) => S): State[S, A] = {
in.foldLeft1((s1, s2) => State(e => {
val ss1 = s1(e)
val ss2 = s2(e)
g(ss1._1, ss2._1) -> f(ss1._2, ss2._2)
}))
}
I am sure, that I am inventing the bicycle, and such thing already exists, probably in a more general way. But, looking through scalaz I failed to find or recognize it. Would appreciate of any help on this topic.
The second question, describes how I came to such problem. I wanted to make a small simulation, when you have an Enemy (consider it's just a Double), and all possible spells which might hit him Nel[Spell]. So basically I want to generate all possible sequences. For example, if Nel[Spell] = ($, #), then given an enemy E, progression would look like
E -> (), then Nel(E -> $, E -> #), then Nel(E -> $$, E -> ##, E -> $#, E-> #$) etc.. (pseudo code)
Without going too much into details I need something like this:
def combineS(variations: NonEmptyList[Spell]): State[NonEmptyList[(Enemy, List[Spell])], Boolean]
In other words, you provide it with all possible moves, and it simulates all possible states. You can consider it as a kind of decision tree, which branches off every step.
Hence I defined, how to proceed with one spell.
def combineS1(spell: Spell): State[(NonEmptyList[(Enemy, List[Spell])]), Boolean]
// some logic
The problem is, that I can not implement it via simple traverse:
def combineS(variations: NonEmptyList[Spell]): State[NonEmptyList[(Enemy, List[Spell])], Boolean] = {
val x = variations traverse combine1 // State[Nel[..], Nel[Boolean]
x map { _.suml1(conjunction)}
}
Because in traverse, the Nels are not appended to each other, but discarded.
That's why I came up with this solution:
def combineS(variations: NonEmptyList[Spell]): State[NonEmptyList[(Enemy, List[Spell])], AllDead] = {
val x: NonEmptyList[State[NonEmptyList[(Enemy, List[Spell])], Boolean]] = variations map combineS
foldStates(x)(_ && _)(append)
}
That code is actually working, but I feel like there's a way to traverse it, without additional foldState.
What would be other functional approaches to do such simulations (in terms of concepts at least). I can write it simply functional, without using high level concepts, but the purpose of this exercise was exactly to learn advanced stuff.
(May be it is exactly the job for Writer Monad? or Comonad?)
Also, if stackoverflow is not the best place for such questions, please, point out, where such questions are supposed to be asked?
Well, to answer the first part of that, if we were in an alternative universe where Scalaz already had a Biapplicative type class, we could use it as follows:
def foldStatesG[S, A](states: NonEmptyList[State[S, A]], s: (S, S) ⇒ S, a: (A, A) ⇒ A): State[S, A] =
states.foldLeft1(IndexedStateT.indexedStateTBiapplicative[Id, S].bilift2(s, a))
But we don't, so we'd need something like the following (n.b. I haven't ensured this does anything sane law-wise):
trait Biapplicative[F[_, _]] extends Bifunctor[F] {
def bipure[A, B](a: ⇒ A, b: ⇒ B): F[A, B]
def biapply[A, B, C, D](fab: ⇒ F[A, B])(f: ⇒ F[A ⇒ C, B ⇒ D]): F[C, D]
def bilift2[A, B, C, D, E, G](fab: (A, B) ⇒ C, fde: (D, E) ⇒ G): (F[A, D], F[B, E]) ⇒ F[C, G] =
(fad: F[A, D], fbe: F[B, E]) ⇒
biapply(fbe)(bimap[A, D, B ⇒ C, E ⇒ G](fad)(fab.curried, fde.curried))
}
object Biapplicative {
implicit def indexedStateTBiapplicative[F[_], S1](implicit F: Applicative[F]) =
new Biapplicative[IndexedStateT[F, S1, ?, ?]] {
def bipure[A, B](a: ⇒ A, b: ⇒ B) =
StateT.constantIndexedStateT(b)(a)
def biapply[A, B, C, D]
(fab: ⇒ IndexedStateT[F, S1, A, B])
(f: ⇒ IndexedStateT[F, S1, A ⇒ C, B ⇒ D]) =
new IndexedStateT[F, S1, C, D] {
def apply(initial: S1): F[(C, D)] =
F.ap(fab(initial))(F.map(f(initial)) {
case (a2c, b2d) ⇒ Bifunctor[Tuple2].bimap(_)(a2c, b2d)
})
}
}
}
Related
I have several generic functions with the same signature:
def f1[A, B](v: A, f: (A, B) => B): B = ...
def f2[A, B](v: A, f: (A, B) => B): B = ...
And I need to define a function g that can accept any of these functions (f1 f2):
def g(f: ????) = ...
g internally uses multiple argument types, so I can not parameterize it like that:
def g[A, B](f: (A, (A, B) => B) => B) = ...
There isn't really a much better way to do it in Scala 2. Although your solution is a bit strange because FunctionHolder's apply method will return a function object and doesn't accept any arguments itself – that's a bit more complicated than it needs to be. So you can do this instead:
trait FunctionHolder {
def apply[A, B](v: A, f: (A, B) => B): B
}
def g(f: FunctionHolder) = …
But this isn't really all that much better.
In Scala 3, there are polymorphic function types to do this in a cleaner way:
def g(f: [A, B] => (A, (A, B) => B) => B) = …
That said, I'm not convinced that that type signature is really what you want. Remember, when you define a function with type parameters, it needs to work for all possible type parameters that the user might supply. This can't be done for this signature…
def f1[A, B](v: A, f: (A, B) => B): B
… because when I have a function like that, I can easily write an expression of type Nothing:
f1[Unit, Nothing]((), (a: Unit, b: Nothing) => b)
and it's not possible to write an expression of type Nothing unless you cheat (e. g. throw an exception or enter an infinite loop or something like that). So the type signature tells me you're cheating 😉
If you want to know more about this kind of reasoning, search for “Theorems for free!”
After wandering a bit, come up with following:
g(new FunctionHolder {
def apply[A, B](): (A, (A, B) => B) => B = f1
})
def g(f: FunctionHolder) = f()(..., (a, b) => ...)
abstract class FunctionHolder {
def apply[A, B](): (A, (A, B) => B) => B
}
But that just does not look right.
Hope there are more concise ways to do that
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))
I've the written the following Haskell function which accepts two monadic values and combine them into a single monadic value (it's just to illustrate the degree of genericity (or generic-ness) that Haskell type-system could support).
combine x y = do
a <- x
b <- y
return (a, b)
and I tested it with three different monads:
main = do
putStrLn $ show $ combine (Just 10) (Just 20) -- Maybe a
putStrLn $ show $ combine [100] [10, 20] -- [] a
a <- combine getLine getLine -- IO a
putStrLn $ show a
And it works great as expected. Now, I want to know if Scala's type-system could allow me to write the above function without compromising the genericity. But I don't know Scala enough (though I wish to explore it). So could anyone help me convert this code into Scala?
I think this is the equivalent:
import cats._
import cats.implicits._
def combine[T, F[_]: Monad](fa: F[T], fb: F[T]) = for {
a <- fa
b <- fb
} yield (a, b)
Where Monad is from a library (cats or scalaz).
combine(Option(10), Option(20)) produces Some((10,20)) and combine(List(100), List(10, 20)) produces List((100,10), (100,20)).
EDIT: The above version is over-constrained, since it requires the two argument types to be the same. def combine[A, B, F[_]: Monad](fa: F[A], fb: F[B]) fixes that.
Your combine function is equivalent to the Scala code
for { a <- x; b <- y } yield (a,b)
So you might try defining a function:
def combine[M[_],A,B](x: M[A], y: M[B]): M[(A,B)] =
for { a <- x; b <- y } yield (a,b)
And the compiler will complain that flatMap is not a member of M[A] and map is not a member of M[B].
The thing with for is that it is a bit of compiler magic that will accept any type that implements functions called map, flatMap, and withFilter. This is in contrast to Haskell in which we can add (or let the compiler infer) a Monad constraint to let do notation work.
To expand on the answer #JoePallas gave, it is possible to make this work. In fact, the following implementation is essentially how GHC implements typeclasses. The cats and scalaz libraries provide all this stuff for you, but this is how the sausage is made:
First define the interface we need:
trait For[M[_]] {
def map[A,B](ma: M[A], f: A => B): M[B]
def flatMap[A,B](ma: M[A],f: A => M[B]): M[B]
def withFilter[A](ma: M[A],q: A => Boolean): M[A]
}
(I'm using the name For and using a slightly different interface than Monad.)
Then we provide an implicit implementation of this trait for every data type we want to support. Here's an example for Option:
implicit val optionFor = new For[Option] {
def map[A,B](ma: Option[A], f: A => B): Option[B] = ma.map(f)
def flatMap[A,B](ma: Option[A],f: A => Option[B]): Option[B] = ma.flatMap(f)
def withFilter[A](ma: Option[A],q: A => Boolean): Option[A] = ma.withFilter(q).map(a => a)
}
Then we provide an implicit conversion to a type that can apply these operations:
implicit class ForOps[M[_], A](val ma: M[A]) extends AnyVal {
def map[B](f: A => B)(implicit m: For[M]): M[B] = m.map(ma,f)
def flatMap[B](f: A => M[B])(implicit m: For[M]): M[B] = m.flatMap(ma, f)
def withFilter(q: A => Boolean)(implicit m: For[M]): M[A] = m.withFilter(ma,q)
}
And finally, we can define combine:
def combine[M[_]: For, A, B](ma: M[A], mb: M[B]): M[(A, B)] =
for { a <- ma; b <- mb } yield (a, b)
The syntax
def f[T: TC] = ???
is sugar for
def f[T](implicit unutterableName: TC[T]) = ???
An implicit argument list, if not given explicitly at the call site, will be automatically filled in by searching for values/functions with the correct types, as long as those are themselves implicit. In this case, we look for a proof that M is a monad. In the body, this value is implicit, and it has no name to access it. Implicit search can still find it. ForOps allows the 3 for operations to automagically appear on the values by using that Monad.
This is really an explicit version of how GHC implements typeclasses. In the simplest case of no optimization:
class Applicative m => Monad m where
return :: a -> m a
(>>=) :: m a -> (a -> m b) -> m b
compiles to
data Monad m = Monad {
monadSubApplicative :: Applicative m
return :: forall a. a -> m a
(>>=) :: forall a. m a -> (a -> m b) -> m b
}
and
instance Monad [] where
return = _
(>>=) = _
becomes
monadList :: Monad []
monadList = Monad {
monadSubApplicative = applicativeList
, return = _
, (>>=) = _
}
You will often hear the word "dictionary" be used to describe the underlying data type and values. And combine is
combine :: Monad m -> m a -> m b -> m (a, b)
combine (Monad _ return (>>=)) ma mb = ma >>= \a -> mb >>= \b -> return (a, b)
However, GHC applies a bunch of restrictions to the system that makes it more predictable and performs more optimization. Scala sacrifices this to allow the programmer to perform more interesting acrobatics.
For good measure, an instance like this:
newtype Compose f g a = Compose { unCompose :: f (g a) }
instance (Functor f, Functor g) => Functor (Compose f g) where
fmap f (Compose fga) = Compose $ fmap (fmap f) fga
would be done like this in Scala (using an implicit def, not a val):
trait Functor[F[_]] { def map[A, B](fa: F[A])(f: A => B): F[B] }
final case class Compose[F[_], G[_], A](val get: F[G[A]]) extends AnyVal
object Compose {
// you usually put these implicits in the associated companions
// because implicit search is picky about where it looks
implicit def functor[F[_], G[_]](implicit
functorF: Functor[F],
functorG: Functor[G]
// type lambda: use a type projection on a refinement type
// to create an anonymous type-level function
// it's universally accepted as a horrendous abuse of syntax
// you can use the kind-projector plugin to avoid writing them (directly)
) : Functor[({type L[X] = Compose[F, G, X]})#L]
= new Functor[({type L[X] = Compose[F, G, X]})#L] {
override def map[A, B](cfga: Compose[F, G, A])(f: A => B): Compose[F, G, B] =
Compose(functorF.map(cfga.get) { ga => functorG.map(ga)(f) })
}
}
Making all this stuff explicit is a bit ugly, but it works quite well.
In functional programming (and programming in general) it is good practice to use the least powerful abstraction you can find. In the example you gave, you actually don't need the power of a monad. The combine function is liftA2 from the applicative type class. Example:
import Data.Maybe
import Control.Applicative
z= Just 1
y= Just 2
liftA2 (,) z y
> Just (1,2)
In Scala you have something similar. An example from the Scalaz library which uses the same abstraction:
import scalaz._, Scalaz._
(Option(1) |#| Option(2))(Tuple2.apply)
> res3: Option[(Int, Int)] = Some((1, 2))
The reason you don't need the monad abstraction is that the values are independent of each other.
I think I understand what Free monad is. I hope I understand also that functors compose but monads do not, i.e. if M1 and M2 are monads then M1[M2] is not necessarily a monad.
My questions are:
Do Free monads compose ?
Suppose we have functors F1 and F2 and their composition F1[F2]. Suppose also we have Free1 and Free2 -- Free monads for F1 and F2. Can we define a Free monad for F1[F2] with just Free1 and Free2 ?
Hopefully I can answer your question:
Do Free monads compose?
No. For the same reasons as "normal" monads don't. To write monadic bind we need to know something about the underlying monad, or about the underlying functor in a free monad case.
Hopefully the Haskell syntax doesn't scare you too much:
type X f g a = Free f (Free g a)
bind :: X f g a -> (a -> X f g b) -> X f g b
bind (Pure (Pure x)) k = k x
bind (Pure (Free f)) k = error "not implemented"
bind _ = error "we don't even consider other cases"
In the second case we have f :: g (Free g a) and k :: a -> Free f (Free g b). We could fmap, as it's the only thing we can do:
bind (Pure (Free f)) k = let kf = fmap (fmap k) f -- fmapping inside g ∘ Free g
in = error "not implement"
The type of kf will be: g (Free g (Free f (Free g b))), when we'd need Free f (Free g b). You'll arrive at the same problem as when writing a monad instance for any Compose m1 m2, we'd need to reorder "bind layers" from g-g-f-g to f-g-g-g, and to do that commutation we need to know more about f and g.
Please comment, if you want to see the Scala version of above. It will be much more obscure though :(
Can we define a Free monad for F1[F2] with just Free1 and Free2
In other words given:
type Free1[A] = Free[F1, A]
type Free2[A] = Free[F2, B]
type FreeDist[A] = Free1[Free2[A]] = Free[F1, Free[F2, A]]
type FreeComp[A] = Free[F1[F2[_]], A]
Could we write a monad homomorphism (a good mapping) from FreeDist[A] to FreeComp[A]? We can't, for the same reasons as in a previous part.
Scala version
Scalaz has private definitions of subclasses of Free, so I have to implement Free myself to have an "runnable" example. Some of the code scrapped from http://eed3si9n.com/learning-scalaz/Free+Monad.html
First simplest definition of Free in Scala:
import scala.language.higherKinds
trait Functor[F[_]] {
def map[A, B](x: F[A])(f: A => B): F[B]
}
sealed trait Free[F[_], A] {
def map[B](f: A => B)(implicit functor: Functor[F]): Free[F, B]
def flatMap[B](f: A => Free[F, B])(implicit functor: Functor[F]): Free[F, B]
}
case class Pure[F[_], A](x: A) extends Free[F, A] {
def map[B](f: A => B)(implicit functor: Functor[F]): Free[F, B] = Pure[F, B](f(x))
def flatMap[B](f: A => Free[F, B])(implicit functor: Functor[F]): Free[F, B] = f(x)
}
case class Bind[F[_], A](x: F[Free[F, A]]) extends Free[F, A] {
def map[B](f: A => B)(implicit functor: Functor[F]): Free[F, B] = Bind {
functor.map[Free[F,A], Free[F,B]](x) { y => y.map(f) }
}
// omitted
def flatMap[B](f: A => Free[F, B])(implicit functor: Functor[F]): Free[F, B] = ???
}
Using that we can translate the Haskell example into Scala:
type X[F[_], G[_], A] = Free[F, Free[G, A]]
// bind :: X f g a -> (a -> X f g b) -> X f g b
def xFlatMap[F[_], G[_], A, B](x: X[F, G, A], k: A => X[F, G, B])(implicit functorG: Functor[G]): X[F, G, B] =
x match {
case Pure(Pure(y)) => k(y)
case Pure(Bind(f)) => {
// kf :: g (Free g (Free f (Free g b)))
val kf: G[Free[G, Free[F, Free[G, B]]]] = functorG.map(f) { y => y.map(k) }
// But we need Free[F, Free[G, B]]
???
}
// we don't consider other cases
case _ => ???
}
The result is the same, we can't make types match, We'd need transform Free[G, Free[F, A]] into Free[F, Free[G, A]] somehow.
Say you have an EitherT that looks something like this:
type StateListOfString[+T] = State[List[String], T]
type MyEitherT = EitherT[StateListOfString, Int, Boolean]
If you have a for-comprehension that could return a left:
my computation = for {
a <- thingThatCouldReturnLeft
b <- otherThingThatCouldReturnLeft
} yield b
How can you follow up with a for-comprehension that manipulates state before itself returning the left?
I think I want something very close to orElse, but orElse doesn't have access to the value of the left:
def orElse[AA >: A, BB >: B](x: => EitherT[F, AA, BB])(implicit F: Bind[F]): EitherT[F, AA, BB] = {
If it took something like (x: => Int => EitherT[F, AA, BB]) instead of just (x: => EitherT[F, AA, BB]), it would work.
I had tried starting with:
for {
a <- myComputation.isLeft
// OK, now I have something sensible, and I can follow up with something like
// a leftMap
But if I start by calling isLeft, it looks like the computation is run at least twice, once for the isLeft, and again when I call something like leftMap.
What's the right thing to use here?
Looking at the sources of orElse it seems that it can be naturally generalized as
import scala.language.higherKinds
def onLeft[F[+_],A,B](x: => EitherT[F, A, B])
(y: A => EitherT[F, A, B])
(implicit F: Bind[F]): EitherT[F, A, B] =
{
val g = x.run
EitherT(F.bind(g) {
case -\/(l) => y(l).run
case \/-(_) => g
})
}
This is basically the same thing as swapping left/right and then using monadic binding
def onLeft1[F[+_],A,B](x: => EitherT[F, A, B])
(y: A => EitherT[F, A, B])
(implicit F: Monad[F]): EitherT[F, A, B] =
x.swap.flatMap((a: A) => y(a).swap).swap
but of course the first variant is more efficient (and also a bit more general in F).