I am writing a trait that contains a function:
trait MyTrait[X,Y] {
def f(x : X) : Y
}
I'm trying to add a map function:
trait MyTrait[X,Y] {
def f(x : X) : Y // the outer f
def map[Z](g : Y => Z) : MyTrait[X,Y] = MyTrait[X,Z] {
//namespace conflict : I need to access the outer f within this f
override def f(x : X) : Z = outerF andThen g
}
}
My question is: how do I reference the outer f? I've tried super.f and this.f to no avail. I'm sure this is a basic question that has been asked before but it's not very "google-able", e.g. easy to search for.
thank you in advance for your consideration and response.
You can use self type
trait MyTrait[X,Y] {
self =>
def f(x : X) : Y // the outer f
def map[Z](g : Y => Z) : MyTrait[X,Y] = MyTrait[X,Z] {
override def f(x : X) : Z = self.f andThen g
}
}
You can also use override def f(x : X) : Z = MyTrait.this.f andThen g.
Related
What is an idiomatic way of chaining function calls, passing results between each with parameters supplied on the way in Scala?
Here's an example:
def a(x : A, param : String) : A = x
def b(x : A, param : String) : A = x
def c(x : A, param : String) : A = x
def d(x : A, param : String, anotherParam : String) : A = x
val start = A()
d(c(b(a(start, "par1"), "par2"), "par3"), "par4", "anotherPar")
One approach that comes to my mind is Ruby's Kernel#yield_self which allows to do the following:
start
.yield_self {|x| a(x, "par1") }
.yield_self {|x| b(x, "par2") }
.yield_self {|x| c(x, "par3") }
.yield_self {|x| d(x, "par4", "anotherPar) }
You may combine chain of functions into one function:
val start = new A()
val func: (A => A) =
((x: A) => a(x, "par1"))
.andThen(b(_, "par2"))
.andThen(c(_, "par3"))
.andThen(d(_, "par4", "anotherPar"))
func(start)
But I'm not sure if it's a your goal.
I'd say that chaining functions using well... chaining isn't that bad already:
(
{ (x: A) => a(x, "par1") } andThen
{ x => b(x, "par2") } andThen
{ x => c(x, "par3") } andThen
{ x => d(x, "par4", "anotherPar") }
)(start)
However, if you insist on having a yieldSelf method, here you go:
import scala.language.implicitConversions
case class YieldSelf[X](x: X) {
def yieldSelf[Y](f: X => Y): Y = f(x)
}
implicit def everythingCanYieldSelf[X](x: X) = YieldSelf(x)
start.
yieldSelf{ a(_, "par1") }.
yieldSelf{ b(_, "par2") }.
yieldSelf{ c(_, "par3") }.
yieldSelf{ d(_, "par4", "anotherPar") }
As soon as the implicit definition is in the scope, it adds a yieldSelf method to every object, which has the same semantics as in Ruby.
I'm working my way through parts of
http://ropas.snu.ac.kr/~bruno/papers/FOPOA.pdf
Feature-Oriented Programming with Object Algebras
I'm not a scala programmer, I can do a bit of F# and Haskell, but the nuances of scala are not obvious to me....so I try to enter the code from the paper;
def fix[A](f: Open[A, A]): A = {
lazy val s: A = f(s); s
}
trait GExpAlg[In,Out] {
def Lit(x : Int) : Out
def Add(e1 : In, e2 : In) : Out
}
type ExpAlg[E] = GExpAlg[E,E]
type OExpAlg[S <: E, E] = GExpAlg[S, Open[S,E]]
type Open[S <: E, E] = (=> S) => E
trait IEval { def eval() : Int }
trait IPrint { def print() : String }
trait ExpPrint2[S <: IEval with IPrint] extends OExpAlg[S, IPrint] {
def Lit(x : Int) = self => new IPrint() { def print() = x.toString() }
def Add(e1 : S, e2 : S) = self => new IPrint() {
def print() = e1.print() + " + " + e2.print() + " = " + self.eval()
}
}
trait CloseAlg[E] extends ExpAlg[E] { val alg : OExpAlg[E,E]
def Lit(x : Int) : E = fix(alg.Lit(x))
def Add(e1 : E, e2 : E) : E = fix(alg.Add(e1,e2))
}
def closeAlg[E](a : OExpAlg[E,E]) : ExpAlg[E] = new CloseAlg[E] {
val alg = a
}
trait SelfAlg[Self <: Exp, Exp] {
val fself : ExpAlg[Self]
}
trait SelfExpAlg[Self <: Exp, Exp] extends GExpAlg[Self,Open[Self,Exp]] with SelfAlg[Self,Exp]
trait ExpPrint3[S <: IEval with IPrint] extends SelfExpAlg[S,IPrint]{
def Lit(x : Int) = self => new IPrint() {def print() = x.toString()}
def Add(e1 : S, e2 : S) = self => new IPrint() {
def print() = {
val plus54 = fself.Add(fself.Lit(5), fself.Lit(4));
e1.print() + " + " + e2.print() + " = " + self.eval() + " and " + "5 + 4 = " + plus54.eval();
}
}
}
def ExpPrint3[S <: IEval with IPrint] : OpenExpAlg[S,IPrint] = s => new ExpPrint3[S] {
lazy val fself = s
}
type OpenExpAlg[S <: E, E] = (=> ExpAlg[S]) => GExpAlg[S, Open[S,E]]
// this is where the error is....
def close[S](f : OpenExpAlg[S,S]) : ExpAlg[S] = fix(compose(closeAlg,f))
Error:(154, 55) not found: value compose
def close[S](f : OpenExpAlg[S,S]) : ExpAlg[S] = fix(compose(closeAlg,f))
Error:(154, 63) missing argument list for method closeAlg in object ScalaApp
Unapplied methods are only converted to functions when a function type is expected.
You can make this conversion explicit by writing closeAlg _ or closeAlg(_) instead of closeAlg.
I can force the second error to go away, but I'm confused by the inability to not find compose....(there is some odd about the function type, they are "by name" which I'm not too sure what that means, maybe it's that)
I really don't especially know what I'm doing in scala, and I don't especially know how the IDE works.
def close[S](f : OpenExpAlg[S,S]) : ExpAlg[S] = fix(compose(closeAlg,f))
EDIT
I've amended the code thanks to below answer to
Cyrille Corpet below
def close[S](f : OpenExpAlg[S,S]) : ExpAlg[S] = fix(f.compose(closeAlg _))
I now get;
Error:(160, 65) polymorphic expression cannot be instantiated to expected type;
found : [E]ScalaApp.OExpAlg[E,E] => ScalaApp.ExpAlg[E]
(which expands to) [E]ScalaApp.GExpAlg[E,(=> E) => E] => ScalaApp.GExpAlg[E,E]
required: ? => => ScalaApp.ExpAlg[S]
(which expands to) ? => => ScalaApp.GExpAlg[S,S]
def close[S](f : OpenExpAlg[S,S]) : ExpAlg[S] = fix(f.compose(closeAlg _))
What you should really know about scala, is that everything is an object.
In particular, functions are objects with a method named apply which can be called without naming it so
val f: Int => String = _.toString
f(5) == f.apply(5)
Functions also have a method compose with the given signature:
trait Function1[In, Out] { // A => B is actually syntactic sugar for Function1[A, B]
def compose[Before](that: Before => In): Before => Out
}
So to use it, you should do fun1.compose(fun2) (or using the infix notation fun1 compose fun2), where fun2 is actually the first function to be applied (this is the same weird ordering that you have in mathematics).
EDIT
To know in which order to compose the functions, let's resolve types (I'll use == for type equality, although it does not make sense in code):
f: OpenExpAlg[S, S] == (=> ExpAlg[S]) => GexpAlg[S, Open[S, S]]
closeAlg[S]: OExpAlg[S, S] => ExpAlg[S] == GExpAlg[S, Open[S,S]] => ExpAlg[S]
So (closeAlg[S] compose f): (=> ExpAlg[S]) => ExpAlg[S] == Open[ExpAlg[S]] has the right signature to be a parameter for fix.
However, you still get a problem because closeAlg is not a function, but a method of the enclosing structure. The compiler usually make a conversion between the two, but it might have some trouble sometimes. To help it, you should do
(closeAlg[S] _) compose f
This method _ notation is to force the method to be seen as a function.
Suppose I would like to define arithmetic operators for functional types like () => Int, () => Double etc in the following manner
def + (a : () => Int, b : () => Int) =
new (() => Int) {
def apply() = a() + b()
}
Is there any way to avoid boiler plate code in defining similar functions for all possible argument type combinations?
These types can be built-in ones (Int, Long, Double), user-defined ones (like Currency, Quantity etc), and Option[T] where T can be any before mentioned types.
def + (a : () => Option[Int], b : () => Double) =
new (() => Option[Double])
{
// this specific code could be factored out
def apply() =
a() map { _ + b() }
}
You can create trait which instances define concrete implementation of your operations for particular type. Then require this trait as implicit parameter for your operations and invoke these concrete implementations.
For the example, check sources of scala.math.Numeric.
It seems to me that the problem can be solved by introducing
trait PlusDefined[A,B] {
type Ret
def plus(a : A, b : B) : Ret
}
and introducing implicit values for different types. My current solution couldn't avoid all boiler-plate code (like explicit overloads for Option[T]) but looks workable:
import language.implicitConversions
trait Conversion[From, To]
{
def convert(from : From) : To
}
object Conversions {
implicit def toOption[T, U](implicit ev : Conversion[T,U])
: Conversion[T, Option[U]] =
new Conversion[T, Option[U]]
{
def convert(x : T) = Some(ev.convert(x))
}
implicit def toOptionId[T]
: Conversion[T, Option[T]] =
new Conversion[T, Option[T]]
{
def convert(x : T) = Some(x)
}
implicit def betweenOptions[T, U](implicit ev : Conversion[T,U])
: Conversion[Option[T], Option[U]] =
new Conversion[Option[T], Option[U]]
{
def convert(x : Option[T]) = x map { y => ev.convert(y) }
}
implicit val int2double =
new Conversion[Int, Double]{ def convert(x : Int) = x }
implicit val int2long =
new Conversion[Int, Long] { def convert(x : Int) = x }
implicit val long2double =
new Conversion[Long, Double]{ def convert(x : Long) = x }
}
trait PlusDefined[A,B]
{
type Ret
def plus(a : A, b : B) : Ret
}
trait Addable_Level1 {
implicit def rightConversion[A,B](implicit c : Conversion[A,B],
ev : PlusDefined[B,B])
: PlusDefined[A,B] =
new PlusDefined[A,B]
{
type Ret = PlusDefined[B,B]#Ret
def plus(a : A, b : B) = ev.plus(c.convert(a), b)
}
implicit def leftConversion[A,B](implicit c : Conversion[B,A],
ev : PlusDefined[A,A])
: PlusDefined[A,B] =
new PlusDefined[A,B]
{
type Ret = PlusDefined[A,A]#Ret
def plus(a : A, b : B) = ev.plus(a, c.convert(b))
}
}
trait Addable_Level2 extends Addable_Level1
{
implicit def rightOpt[A,B](implicit ev : PlusDefined[A,B])
: PlusDefined[A,Option[B]] =
new PlusDefined[A,Option[B]]
{
type Ret = Option[PlusDefined[A,B]#Ret]
def plus(a : A, b : Option[B]) = b map { x => ev.plus(a,x) }
}
implicit def leftOpt[A,B](implicit ev : PlusDefined[A,B])
: PlusDefined[Option[A],B] =
new PlusDefined[Option[A],B]
{
type Ret = Option[PlusDefined[A,B]#Ret]
def plus(a : Option[A], b : B) = a map { x => ev.plus(x,b) }
}
implicit def bothOpt[A,B](implicit ev : PlusDefined[A,B])
: PlusDefined[Option[A],Option[B]] =
new PlusDefined[Option[A],Option[B]]
{
type Ret = Option[PlusDefined[A,B]#Ret]
def plus(a : Option[A], b : Option[B]) =
(a,b) match {
case (Some(x), Some(y)) => Some(ev.plus(x,y))
case _ => None
}
}
}
object Addable extends Addable_Level2 {
implicit def fromNumeric[T : Numeric]
: PlusDefined[T,T] = new PlusDefined[T,T]
{
type Ret = T
def plus(a : T, b : T) = implicitly[Numeric[T]].plus(a,b)
}
}
Trying to learn how to program monads in Scala, got some troubles
Given the quick code sample
import Control.Monad
newtype LJ a = LJ { session :: a }
instance Monad LJ where
return s = LJ s
(>>=) m f = f ( session m )
instance Functor LJ where
fmap f m = LJ . f $ session m
type SimpleLJ = LJ String
auth :: String -> String -> SimpleLJ
auth = undefined
readFeed :: String -> SimpleLJ
readFeed = undefined
closeFeed :: String -> SimpleLJ
closeFeed = undefined
proceed = auth "123" "456" >>= readFeed >>= closeFeed
how do I write the same thing in Scala (not scalaz)? As far as I learned, it's enough to implement map/flatMap methods in scala, but what is return here? And how to do binding without free variables in for statement?
Here's an almost direct translation, which I believe should answer your question. It's not completely direct because it doesn't utilize typeclasses which are present in form of a pattern in Scala, because in the current case it would have only overcomplicated things without a real reason.
case class LJ[A]( session : A ) {
// See it as Haskell's "fmap"
def map[B]( f : A => B ) : LJ[B] =
LJ( f( session ) )
// See it as Haskell's ">>="
def flatMap[B]( f : A => LJ[B] ) : LJ[B] =
f( session )
}
type SimpleLJ = LJ[String]
def auth( a : String, b : String ) : SimpleLJ = ???
def readFeed( a : String ) : SimpleLJ = ???
def closeFeed( a : String ) : SimpleLJ = ???
def proceed : SimpleLJ =
auth("123", "456").flatMap(readFeed).flatMap(closeFeed)
// Same as above but using a for-comprehension, which is
// used as a replacement for Haskell's "do"-block
def proceed2 : SimpleLJ =
for {
a <- auth("123", "456")
b <- readFeed(a)
c <- closeFeed(b)
}
yield c
This solution demonstrates a classical object-oriented approach. With this approach you can't have the return function encapsulated in the LJ type because you end up working on another level - not on a type as with typeclasses, but on the instance of a type. So the LJ case class constructor becomes the counterpart of return.
I would consider Nikita's answer to be the idiomatic translation (which should be preferred in real world situations, e.g. because of for-comprehension support), but it is definitely not the most "direct" one.
class LJ[A](val session : A)
trait Functor[F[_]] {
def fmap[A,B](fa:F[A])(f:A => B) : F[B]
}
trait Monad[M[_]] {
def pure[A](a:A):M[A]
def bind[A,B](ma:M[A])(f:A => M[B]):M[B]
}
object LJFunctor extends Functor[LJ] {
def fmap[A,B](lj:LJ[A])(f:A => B) = new LJ(f(lj.session))
}
object LJMonad extends Monad[LJ] {
def pure[A](a:A) = new LJ(a)
def bind[A,B](lj:LJ[A])(f:A => LJ[B]) = f(lj.session)
}
object MonadTest {
type SimpleLJ = LJ[String]
def auth(s:String, t:String):SimpleLJ = null
def readFeed(s:String):SimpleLJ = null
def closeFeed(s:String):SimpleLJ = null
val proceed = LJMonad.bind(LJMonad.bind(auth("123","456"))(readFeed _))(closeFeed _)
}
Note that you could add some syntactic sugar on top in order to get a nice (>>=) operator.
I'm trying to write a generic interpolate method that works on any type that has two methods, a * and a +, like this:
trait Container {
type V = {
def *(t: Double): V
def +(v: V): V
}
def interpolate(t: Double, a: V, b: V): V = a * (1.0 - t) + b * t
}
This doesn't work though (on Scala 2.8.0.RC7), I get the following error messages:
<console>:8: error: recursive method + needs result type
def +(v: V): V
^
<console>:7: error: recursive method * needs result type
def *(t: Double): V
^
How do I specify the structural type correctly? (Or is there a better way to do this?)
Surely you could solve this problem using the typeclasses approach (of e.g. Scalaz):
trait Multipliable[X] {
def *(d : Double) : X
}
trait Addable[X] {
def +(x : X) : X
}
trait Interpolable[X] extends Multipliable[X] with Addable[X]
def interpolate[X <% Interpolable[X]](t : Double, a : X, b : X)
= a * (1.0 - t) + b * t
Then obviously you would need a (implicit) typeclass conversion in scope for all the types you cared about:
implicit def int2interpolable(i : Int) = new Interpolable[Int] {
def *(t : Double) = (i * t).toInt
def +(j : Int) = i + j
}
Then this can be run easily:
def main(args: Array[String]) {
import Interpolable._
val i = 2
val j : Int = interpolate(i, 4, 5)
println(j) //prints 6
}
AFAIK, this is not possible. This was one of my own first questions.