I'm implementing the List type in Scala when following a book.
Here's the definition of my List type:
sealed trait List[+A]
case object Nil extends List[Nothing]
case class Cons[+A](head: A, tail: List[A]) extends List[A]
All the later mentioned functions are defined in the companion object List in the same file
object List
I wrote foldLeft and foldRight as the following
def foldLeft[A,B](l: List[A], z: B)(f: (B, A) => B): B = l match {
case Nil => z
case Cons(x, xs) => foldLeft(xs, f(z, x))(f)
}
def foldRight[A,B](l: List[A], z: B)(f: (A, B) => B): B = l match {
case Nil => z
case Cons(x, xs) => f(x, foldRight(xs, z)(f))
}
There's an exercise on the book, which is to implement foldLeft using foldRight. Here's my initial implementation
def foldLeftWithRight[A,B](l: List[A], z: B)(f: (B, A) => B): B = {
foldRight(l, z)((a: A, b: B) => f(b, a))
}
Then I think I should write another function to do the reverse arguments if I'm to implement foldRight using foldLeft. As follows:
def reverseArgs[A,B](f: (A, B) => B): (B, A) => B = {
(b: B, a: A) => f(a, b)
}
So I changed code of foldLeftWithRight to the following:
def foldLeftWithRight[A,B](l: List[A], z: B)(f: (B, A) => B): B = {
foldRight(l, z)(reverseArgs(f))
}
And IntelliJ is complaining about reverseArgs(f):
Type mismatch: expected (A, B) => B, actual (B, B) => B
When I try to compile the code, the error is the following:
Error:(21, 37) type mismatch;
found : (B, A) => B
required: (B, Any) => Any
foldRight(l, z)(reverseArgs(f))
An interesting observation is that when I use the reverseArgs on foldRightWithLeft, there's no problem at all:
def foldRightWithLeft[A,B](l: List[A], z: B)(f: (A, B) => B): B = {
foldLeft(l, z)(reverseArgs(f))
}
What is going on here?
If you rename type parameters of your reverseArgs function to X and Y, you'll get something like
def reverseArgs[X ,Y](f: (X, Y) => Y): (Y, X) => Y = ???
Type of f in foldLeftWithRight is (B, A) => B. Passing that to reverseArgs means that:
X = B
Y = A
Y = B
I guess Intellij infers from here that A = B and this is why it's complaining that (B, B) => B isn't (A, B) => B. Scalac decides that Y = Any instead, because it's the least upper bound of two potentially unrelated types.
Good solution here is to generalize more. Return type of reversed function does not have to be one of parameter types, so you can introduce another generic type for that:
def reverseArgs[X ,Y, Z](f: (X, Y) => Z): (Y, X) => Z = {
(b: Y, a: X) => f(a, b)
}
Related
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))
In functional programmming, there are two important methods named foldLeft and foldRight. Here is the implementation of foldRight
sealed trait List[+A]
case object Nil extends List[Nothing]
case class Cons[+A](head: A, tails: List[A]) extends List[A]
def foldRight[A, B](ls: List[A], z: B)(f: (A, B) => B): B = ls match {
case Nil => z
case Cons(x, xs) => f(x, foldRight(xs, z)(f))
}
And here is the implementation of foldLeft:
#annotation.tailrec
def foldLeft[A, B](ls: List[A], z: B)(f: (B, A) => B): B = ls match {
case Nil => z
case Cons(x, xs) => foldLeft(xs, f(z, x))(f)
}
}
My question is: I read from many documents, they often put order of f function is: f: (B, A) => B instead of f: (A, B) => B. Why this definition is better? Because if we use otherwise way, it will have same signature with foldLeft, and it will be better.
Because foldLeft "turns around" the cons structure in its traversal:
foldRight(Cons(1, Cons(2, Nil)), z)(f) ~> f(1, f(2, z))
^ ^
A B
foldLeft(Cons(1, Cons(2, Nil)), z)(f) ~> f(f(z, 2), 1)
^ ^
B A
And since it visits the conses in opposite order, the types are also traditionally flipped. Of course the arguments could be swapped, but if you have a non-commutative operation, and expect the "traditional" behaviour, you'll be surprised.
...if we use otherwise way, it will have same signature with foldLeft, and it will be better.
No, I think that would not be better. If they had the same signature then the compiler would not be able to catch it if you intend to use one but accidentally type in the other.
The A/B order is also a handy reminder of where B (initial or "zero") value goes in relationship to the collection of A elements.
foldLeft: B-->>A, A, A, ... // (f: (B, A) => B)
foldRight: ... A, A, A<<--B // (f: (A, B) => B)
I want to check if two variables taken in any order can be paired into a specific pair. Basically the below, only it doesn't work because of type erasure at runtime
def combination[A,B](x: Any, y: Any): Option[(A, B)] =
(x, y) match {
case (a: A, b: B) => Some(a, b)
case (b: B, a: A) => Some(a, b)
case _ => None
Is there another way to do the same which would work...
Note, since it wasn't clear in your message, if you want to pattern-match against a pair of constants (a, b), you may want to consider back-ticks instead of what you're doing :
case (`a`, `b`) => Some(a, b)
On the other hand if you are trying to retrieve the elements of a pair of any values of type (A, B), in any order, you can do it for non-primitive types (i.e. subtypes of AnyRef) :
import scala.reflect.ClassTag
def combination[A, B](x: AnyRef, y: AnyRef)(implicit tagA: ClassTag[A], tagB: ClassTag[B]): Option[(A, B)] = (x, y) match {
case (a: A, b: B) => Some(a, b)
case (b: B, a: A) => Some(a, b)
case _ => None
}
I would like to convert an expression such as: a.meth(b) to a function of type (A, B) => C that performs that exact computation.
My best attempt so far was along these lines:
def polish[A, B, C](symb: String): (A, B) => C = { (a, b) =>
// reflectively check if "symb" is a method defined on a
// if so, reflectively call symb, passing b
}
And then use it like this:
def flip[A, B, C](f : (A, B) => C): (B, A) => C = {(b, a) => f(a,b)}
val op = flip(polish("::"))
def reverse[A](l: List[A]): List[A] = l reduceLeft op
As you can pretty much see, it is quite ugly and you have to do a lot of type checking "manually".
Is there an alternative ?
You can achieve it easily with plain old subtype polymorphism. Just declare interface
trait Iface[B, C] {
def meth(b: B): C
}
Then you could implement polish easily
def polish[B, C](f: (Iface[B, C], B) => C): (Iface[B, C], B) => C = { (a, b) =>
f(a, b)
}
Using it is completely typesafe
object IfaceImpl extends Iface[String, String] {
override def meth(b: String): String = b.reverse
}
polish((a: Iface[String, String], b: String) => a meth b)(IfaceImpl, "hello")
Update:
Actually, you could achieve it using closures only
def polish[A, B, C](f: (A, B) => C): (A, B) => C = f
class Foo {
def meth(b: String): String = b.reverse
}
polish((_: Foo) meth (_: String))(new Foo, "hello")
Or without helper function at all :)
val polish = identity _ // Magic at work
((_: Foo) meth (_: String))(new Foo, "hello")
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