I'm working with this code:
case class State[S, +A](run: S => (A, S)) {
...
def flatMap[B](f: A => State[S, B]): State[S, B] = State(s => {
val (a, s1) = run(s)
f(a).run(s1)
})
...
}
This is an abstraction for working with purely functional state, from §6 of FP in Scala. run is function parameter that takes a state and emits a tuple of a value and the new state.
My question is around the syntax s => in this section:
... B] = State(s => { ...
This appears to be using the State 'constructor' (ie apply) to build a new State object. But what does the s represent? Is it an 'anonymous' State, representing any State instance? If so, how is it different from this? Or does s correspond to the input parameter of run ie the S from:
... (run: S => ....
And why would I be using a constructor for a function definition? Notice that the last symbol of the flatMap definition is a ) not a }, that is closing the State apply constructor.
This scenario is a bit different than the standard
case class Person(name: String)
scenario, so I thought I'd ask...
Your second assumption is correct, s corresponds to the input parameter of run function, ie the S, which represents an actual state passing through the chain. So s => {...} is just a lambda definition of type S => (A, S). Lambdas and functions in Scala are first-class citizens (values), so you can pass them as parameters to hold inside some another type (including some monad).
Here the function, which produces new raw state S (and new result A), is wrapped (see return operation) to the monad State, which is implemented as case class. We need it to define flatMap operation (see bind) over the monad.
To make it more clear about the passing function as parameter, the code may be rewritten to:
case class State[S, +A](run: S => (A, S)) {
def flatMap[B](f: A => State[S, B]): State[S, B] = {
def newState(s: S) = {
val (a, s1) = run(s)
f(a).run(s1)
}
State(newState _)
}
}
So, according to the monad definition:
State[S, +A] is a type constructor which takes two plain types (S and covariant A) and returns monadic type State
State.apply(run: S => (A, S)) function takes a plain function and returns (lifts into) monadic container State, so it is a "return" operator of the monad
State.flatMap[B](f: A => State[S, B]): State[S, B] is corresponding to the "bind" operator
Case class is used just to have explicit "return" function (apply) instead of using new operator.
Related
I am trying Cats for the first time and am using Scala 3, and I am trying to implement a set of parser combinators for self-pedagogy, however; I am stuck on the definition of the tailRecM function for Monad. I have managed Functor and Applicative just fine.
I have defined my type in question as a function such that:
type Parser[A] = (input: List[Token]) => ParseResult[A]
with corresponding return types as:
type ParseResult[A] = Success[A] | Failure
case class Success[A](value: A, tokens: List[Token])
case class Failure(msg: String, tokens: List[Token])
My current definition of tailRecM is as follows:
#annotation.tailrec
def tailRecM[A, B](init: A)(fn: A => Parser[Either[A, B]]): Parser[B] =
(input: List[Token]) =>
fn(init)(input) match {
case f: Failure => f
case s: Success[Either[A, B]] => s.value match {
case Right(b) => Success(b, s.tokens)
case Left(a) => tailRecM(a)(fn) // won't compile
}
}
If I attempt to build I get "Found: Parsing.Parser[B] Required: Parsing.ParseResult[B]" for tailRecM(a)(fn)
The issue as far as I can tell stems from the fact that my type in question Parser[A] is a function type and not simply a value type? I attempted to ameliorate the issue by modifying the tailRecM recursive call to tailRecM(a)(fn)(input) but then this is obviously not stack safe, and also will not compile.
How can I resolve this issue, and more broadly, how can I implement the Monad typeclass for function types in general?
It's not possible to make tailRecM itself tail-recursive; you need to define a tail-recursive helper method
Here's how the cats library implements tailRecM for Function1
def tailRecM[A, B](a: A)(fn: A => T1 => Either[A, B]): T1 => B =
(t: T1) => {
#tailrec
def step(thisA: A): B =
fn(thisA)(t) match {
case Right(b) => b
case Left(nextA) => step(nextA)
}
step(a)
}
This is because monadic recursion is a form of mutual tail-recursion, where two methods flip back and forth calling each other. The scala compiler can't optimize that. So instead we inline the definition of the monadic part rather than calling flatMap or another method
You need to pass the input again to the tailRecM call
tailRecM(a)(fn)(input)
because tailRecM(a)(fn) returns a Parser, but you need the ParserResult from that returned Parser, as you already did in all other cases.
//this class holds method run that let us give a state and obtain from it an
//output value and next state
case class State[S, +A](run: S => (A, S)) {
//returns a state for which the run function will return (b,s) instead of (a,s)
def map[B](f: A => B): State[S, B] =
flatMap(a => unit(f(a)))
//returns a state for which the run function will return (f(a,b),s)
def map2[B, C](sb: State[S, B])(f: (A, B) => C): State[S, C] =
flatMap(a => sb.map(b => f(a, b)))
def flatMap[B](f: A => State[S, B]): State[S, B] =
State(s => {
val (a, s1) = run(s)
val sB = f(a)
sB.run(s1)
})
}
I am new to functional programming and I am dizzied by this code, I tried to understand what does flatMap really does but it looks very abstract to me that I couldn't understand it. For example here we defined map in terms of flatMap, but I can't understand how can we explain the implementation I mean how does it work?
This chapter is about pure functional state, and describes how the state is being updated in a sequence of operations in a functional way, that is to say, by means of functional composition. So you don´t have to create a global state variable that is mutated by a sequence of method executions, as you probably would do in a OOP fashion.
Having said that, this wonderful book explains each concept declaring an abstraction to represent an effect, and some primitives which are going to be used to build more complex functions. In this chapter, the effect is the State. It is represented as a function that takes a previous state and yields a value and a new state, as you can see with the run function declaration. So if you want to compose functions that propagate some state in a pure functional fashion, all of them need to return a new functional State.
With flatMap, which is a primitive of the State type, you can compose functions and, at the same time, propagate some internal state.
For example, if you have two functions:
case class Intermediate(v: Double = 0)
def execute1(a: Int): State[Int, Intermediate] = {
State { s =>
/** Do whatever */
(Intermediate(a * a), s + 1)
}
}
def execute2(a: Int): State[Int, Intermediate] = {
State { s =>
/** Do whatever */
(Intermediate(a * a), s + 1)
}
}
As you can see each function consist in a State function that takes a previous state, executes some logic, and returns a tuple of Int, which is going to be used to track the number of functions that have been executed, and a Intermediate value that we use to yield the execution of every function.
Now, if you apply flat map to execute both functions sequentially:
val result: State[Int, Intermediate] =
execute1(2) flatMap (r => execute2(r.v.toInt))
the result val is another State that you can see as the point of entry to run the pipeline:
/** 0 would be the initial state **/
result.run(0)
the result is:
(Intermediate(16.0),2)
How this works under the hood:
First you have the first function execute1. This function returns a State[Intermediate, Int]. I will use Intermediate to store the result of each execution, that would be the yielded value, and an Int to count the number of functions that are going to be executed in the flatMap sequential composition.
Then I apply flatMap after the function call, which is the flatMap of the State type.
Remember the definition:
def flatMap[B](f: A => State[S, B]): State[S, B] =
State(s => {
/* This function is executed in a State context */
val (a, s1) = run(s)
val sB = f(a)
sB.run(s1)
})
The execution is inside a state context(note that the flatMap function is inside the State type) which is be the first state function of the execute1 function. Maybe this representation is easier:
val st1 = execute1(2)
st1.flatMap(r => execute2(r.v.toInt))
So when run(s) is executed, it actually executes the function state returned by the execute1(2) function. It gives the first (a, s1) result.
Then you have to execute the second function, execute2. You can visualize this function as the input parameter of the flatMap function. This function is executed with the yielded value of the execute1(2) function (the Intermediate type, left side of the tuple). This execution returns another state function that uses the state(right value of the tuple) of the execution1, to create the final tuple with the resulting yielded value of the execute2 function and the int corresponding to the number of executions. Note, that in each function we increment the internal state in one unit.
Note that the result is another State. This has a run method that waits for the initial state.
I have tried to explain the workflow of function calls... it is a little bit hard if you are not used to think in a functional style, but it is only functional composition, it becomes familiar after a while.
I had a query about what is the difference between parameterising the class vs parameterising the function.
I have provided implementation of a Functor as follows:
trait Functor[F[_],A,B] {
def map(fa: F[A]) (f: A => B) : F[B]
}
and the other where the function is parameterised as follows:
trait Functor[F[_]] {
def map[A,B](fa: F[A]) (f: A => B) : F[B]
}
Where are the cases where we should use one over another?
Another follow up question:
Why do we pass the argument to functor as F[_] and not as F[A] or F[B]. What cases arise when we use either F[A] or F[B]?
Always prefer the second one. With the first one you can implement instances as nonsensical as:
trait WrongFunctor[F[_],A,B] {
def map(fa: F[A])(f: A => B) : F[B]
}
case class notEvenRemotelyAFunctor[A]() extends WrongFunctor[List,A,Int] {
def map(fa: List[A])(f: A => Int) : List[Int] =
if(f(fa.head) < 4) List(3) else List(4)
}
type Id[X] = X
case object ILikeThree extends WrongFunctor[Id, Int, Int] {
def map(fa: Int)(f: Int => Int): Int = if(fa == 3) 3 else f(fa)
}
Even if you do things right, you'd need for a fixed functor implementation one object per different types at which you want to use fmap. But the important point is that the second one at least makes it harder to write that kind of wrong "functors"; less non-functors will slip by:
trait Functor[F[_]] {
def map[A,B](fa: F[A])(f: A => B) : F[B]
}
case object ILikeThreeAgain extends Functor[Id] {
def map[A,B](fa: A)(f: A => B) : B =
??? // how do I write the above here?
}
The keywords here are parametricity and parametric polymorphism. The intuition is that if something is defined generically, you can derive properties it will satisfy just from the types involved. See for example Bartosz Milewski blog - Parametricity: Money for Nothing and Theorems for Free for a good explanation, or the canonical Theorems for free paper.
Follow-up question
Another follow up question: Why do we pass the argument to functor as F[_] and not as F[A] or F[B]. What cases arise when we use either F[A] or F[B]?
Because that's part of what a functor is; it is a "constructor":
for each input type A it gives you as output another type F[A]
and for each function f: A => B, another function fmap(f): F[A] => F[B] satisfying fmap(id[A]) == id[F[A]] and fmap(f andThen g) == fmap(f) andThen fmap(g)
So for 1. you need a way of representing functions on types; and that's what F[_] is.
Note that having a map method like in your signature is in this case equivalent to fmap:
trait Functor[F[_]] {
def map[A,B](fa: F[A])(f: A => B) : F[B]
def fmap[A,B](f: A => B): F[A] => F[B] =
{ fa => map(fa)(f) }
def mapAgain[A,B](fa: F[A])(f: A => B) : F[B] =
fmap(f)(fa)
}
Now for how this links with real category theory:
Instances of your Functor[F[_]] trait above are meant to represent Scala-enriched functors
F: Scala → Scala
Let's unpack this.
There's a (usually implicitly defined) category Scala with objects types, and morphisms functions f: A ⇒ B. This category is cartesian closed, where the internal hom is the type A ⇒ B, and the product (A,B). We can work then with Scala-enriched categories and functors. What's a Scala-enriched category? basically one that you can define using Scala the language: you have
a set of objects (which you'd need to represent as types)
for each A,B a type C[A,B] with identities id[X]: C[X,Y] and composition andThen[X,Y,Z]: (C[X,Y], C[Y,Z]) => C[X,Z] satisfying the category axioms
Enriched functors F: C → D are then
a function from the objects of C to those of D, A -> F[A]
for each pair of objects A,B: C a morphism in Scala i.e. a function fmap: C[A,B] => C[F[A], F[B]] satisfying the functor laws fmap(id[A]) == id[F[A]] and fmap(f andThen g) == fmap(f) andThen fmap(g)
Scala is naturally enriched in itself, with Scala[X,Y] = X => Y, and enriched functors F: Scala → Scala are what instances of your Functor[F[_]] trait are meant to represent.
Of course this needs all sort of qualifications about how Scala breaks this and that, morphism equality etc. But the moral of the story is: your base language L (like Scala in this case) is likely trying to be a cartesian-closed (or at least symmetric monoidal-closed) category, and functors definable through it correspond to L-enriched functors.
(It seems like I ask too many basic questions, but Scala is very difficult, especially when it comes to the language feature or syntactic sugar, and I come from a Java background..)
I am watching this video: Scalaz State Monad on YouTube. The lecturer wrote these code:
trait State[S, +A] {
def run(initial: S):(S, A)
def map[B](f: A=>B): State[S, B] =
State { s =>
val (s1, a) = run(s)
(s1, f(a))
}
He said the State on the forth line is a "lambda" expression (I may have misheard). I'm a bit confused about this. He did have an object State, which looks like this:
Object State {
def apply[S, A](f: S=>(S, A)): State[S, A] =
new State[S, A] {
def run(i: S) = f(i)
}
}
The lecturer said he was invoking the apply method of Object State by invoking like that, and yes he did pass in a function that returns a correct tuple, but what is that { s=>? Where the hell did he get the s and is this about the implicit mechanism in Scala?
Also the function that is passed in map function changes A to B already, how can it still pass the generics check (from [S, A] to [S, B] assuming A and B are two different types, or are they the same type?If true, why use B not A in map function?)?
The video link is here and is set to be at 18:17
http://youtu.be/Jg3Uv_YWJqI?t=18m17s
Thank you (Monad is a bit daunting to anyone that's not so familiar with functional programming)
You are on right way here.
He passes the function as parameter, but what is the function in general? Function takes argument and return a value. Returned value here is tuple (s1, f(a)), but also we need to reffer to function argument. s in your example is function argument.
It is same as
def map[B](f: A=>B): State[S, B] = {
def buildState(s: S) = {
val (s1, a) = run(s)
(s1, f(a))
}
State(buildState)
}
But, since we dont need this function anywhere else we just inline it in apply call.
Is there any quick way to use as a concrete function (of type, say, (A) => B) as a PartialFunction[A, B]? The most concise syntax I know of is:
(a: A) => a match { case obj => func(obj) }
Is there an implicit conversion anywhere, something like:
implicit def funcAsPartial[A, B](func: A => B) = new PartialFunction[A, B] {
def isDefinedAt(a: A) = true
def apply(a: A) = func(a)
}
I guess I just wrote what I was looking for, but does this already exist in the Scala libraries?
Doing this with an implicit conversion is dangerous, for the same reason that (A) => B should not inherit from PartialFunction[A, B]. That is, the contract of PartialFunction guarantees that you can safely* call apply wherever isDefinedAt returns true. Function1's contract provides no such guarantee.
Your implicit conversion will result in a PartialFunction that violates its contract if you apply it to a function that is not defined everywhere. Instead, use a pimp to make the conversion explicit:
implicit def funcAsPartial[A, B](f: A => B) = new {
/** only use if `f` is defined everywhere */
def asPartial(): PartialFunction[A, B] = {
case a => f(a)
}
def asPartial(isDefinedAt: A => Boolean): PartialFunction[A, B] = {
case a if isDefinedAt(a) => f(a)
}
}
// now you can write
val f = (i: Int) => i * i
val p = f.asPartial // defined on all integers
val p2 = f.asPartial(_ > 0) // defined only on positive integers
* As discussed in the comments, it may not be entirely clear what "safety" means here. The way I think about it is that a PartialFunction explicitly declares its domain in the following precise sense: if isDefinedAt returns true for a value x, then apply(x) can be evaluated in a way that is consistent with the intent of the function's author. That does not imply that apply(x) will not throw an exception, but merely that the exception was part of the design of the function (and should be documented).
No, I tried to find one a few months ago and ended up writing my own that's essentially the same as yours.