Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Activity
  • Sep 25 20:02
    joroKr21 commented #12463
  • Sep 25 09:30
    gaopinghuang0 opened #2190
  • Sep 24 18:28
    pjfanning commented #12327
  • Sep 24 18:28
    robert-blankenship commented #12327
  • Sep 24 18:27
    robert-blankenship commented #12327
  • Sep 24 18:25
    robert-blankenship commented #12327
  • Sep 24 17:34
    som-snytt commented #11631
  • Sep 24 15:28

    SethTisue on 2.13.x

    advance http4s to make it green… (compare)

  • Sep 24 14:11
    SethTisue commented on cf1b35b
  • Sep 24 14:10

    SethTisue on 2.13.x

    avro4s went green on JDK 17 (compare)

  • Sep 24 08:29
    scala-jenkins milestoned #9768
  • Sep 24 08:06
    NthPortal edited #9768
  • Sep 24 08:04
    NthPortal labeled #9768
  • Sep 24 08:04
    NthPortal opened #9768
  • Sep 24 08:04
    NthPortal labeled #9768
  • Sep 24 07:46
    nwk37011 synchronize #9752
  • Sep 24 07:12
    xuwei-k commented on cf1b35b
  • Sep 24 06:17
    som-snytt commented #12464
  • Sep 24 05:59
    NthPortal commented #9275
  • Sep 24 05:45
    NthPortal commented #9388
Marcin Sokrates
@marcinsokrates_twitter
@avremel you should refactor to get rid of Future[Try[Option[Double]]] because it's redundant, Future.fromTry lets you skip the Try
RoelofWobben
@RoelofWobben
thanks all
time for the chapter about the for/yield and Option
Avremel Kaminetzky
@avremel
@marcinsokrates_twitter interesting. I was using toOption.flatten to remove the Try
  private def calculateShippingPriceRedo(cookie: String, country: Option[String], state: Option[String], shippingMethodId: Option[Int] = None): Future[Option[Double]] = {
    val countryWithDefault = country.getOrElse("US")

    shippingOptionsFull(cookie, country=countryWithDefault, state).map{ opt => opt.map{ rows =>
      shippingMethodId.flatMap{ id =>
          rows.find(_.shippingSpeedType === id ).orElse(rows.headOption).map(_.charge)
        }
      }.toOption.flatten
    }
  }
Derek Wickern
@dwickern
it depends what you want
Avremel Kaminetzky
@avremel
How would I use Future.fromTry?
Derek Wickern
@dwickern
do you want a successful future with None when the Try fails
Rob Norris
@tpolecat
Future[Try is usually wrong because Future already has the bulletproof behavior.
Derek Wickern
@dwickern
or a failed future
Avremel Kaminetzky
@avremel
Ye, it's someone's code, i don't want to refactor his code yet
Rob Norris
@tpolecat
So fto.flatMap(Future.fromTry) should give you Future[Option[Double]]
Avremel Kaminetzky
@avremel
Oh, thanks for that
And OptionT to add Future[Option[Double]], right?
Rob Norris
@tpolecat
You have two of those and want to add the doubles together?
Avremel Kaminetzky
@avremel
Yes
Rob Norris
@tpolecat
Yeah OptionT or Nested if you're using cats.
You don't need a monad transformer there so Nested is a better choice.
@ val a = Future(Option(42)) 
a: Future[Option[Int]] = Future(Success(Some(42)))

@ (Nested(a), Nested(a)).mapN(_ + _).value 
res7: Future[Option[Int]] = Future(Success(Some(84)))
Actually you can use the bare semigroup in this case.
@ val a = Future(Option(42.0)) 
a: Future[Option[Double]] = Future(Success(Some(42.0)))

@ a |+| a 
res13: Future[Option[Double]] = Future(Success(Some(84.0)))
Avremel Kaminetzky
@avremel
cool!
Rob Norris
@tpolecat
Well that one collapses None to 0.0 which may not be what you want.
Avremel Kaminetzky
@avremel
the semigroup?
Rob Norris
@tpolecat
The first one gives you None if either of them is None.
There are a bunch of monoids for Option so you kind of have to be careful.
Avremel Kaminetzky
@avremel
How can I recover with Future.failed if any value is None?
Fabio Labella
@SystemFw
you can do it afterwards with a simple flatMap on the un-nested thing
Avremel Kaminetzky
@avremel
Ok, perfect
upd
@prayagupd

anybody knows why does sbt try to get look for working@machine_name -

[error] (*:update) sbt.ResolveException: unresolved dependency: junit#junit;working@MACC02V82BPHTD8: not found

seems network issue but should have said could not find the artifact url.

RoelofWobben
@RoelofWobben
Hello, I have these two filters :
def filterOnNumberFilms(numberOfFilms : Int): Seq[String] = directors.filter(_.films.length > numberOfFilms ).map(director => director.lastName)

def bornBefore(year: Int) : Seq[String] = directors.filter(_.yearOfBirth < year).map(director => director.lastName)
Is there a way I can combine the two functions into one filter so I can filter on both
I can do .filter(….).filter(….)
but there must be a better way
Rob Norris
@tpolecat
You can define functions for each filter, of type Director => Boolean, then say .filter(d => f(d) && g(d)) or you can get more clever and define combinators for functions of that type and say .filter(and(f, g)) … there's a lot to explore. Note also that you can conjoin with both && and || and either might make sense.
Rob Norris
@tpolecat
In FP world we define a kind of addition/multiplication over functions and use that very general mechanism to combine them. It's a good observation you made and it leads to a lot of beautiful stuff.
RoelofWobben
@RoelofWobben
@tpolecat thanks :
def filterBoth(numberOfFilms : Int, year : Int):Seq[String] = bornBefore(year).filter(filterOnNumberFilms(numberOfFilms).contains)
yep, I know , Before I came here , I learned haskell and learned a lot about re-using functions or as they called it function composition if im right
Dominic Egger
@GrafBlutwurst
in FP scala a lot of the inspiration comes from haskell, i'm sure you'll see a lot of thigs you'll be familiar with
RoelofWobben
@RoelofWobben
yep, monads, functors , applicative , recursion, map, foldmap are a few
the first three are explained in the cats book
the syntax is different and that is the most difficult to pick up
@GrafBlutwurst
RoelofWobben
@RoelofWobben
time to sleep here , see you all tomorrow
Jason Pickens
@steinybot

I’m having some problems with path dependent types. Not sure if what I am trying to do makes sense. Anyway here is an example:

sealed trait Foo {
  type F
}

object Bar extends Foo {
  type F = Array[Byte]
}

trait Baz[B] {
  def b(b: B): String
}

object Baz {
  implicit val bazByteArray: Baz[Array[Byte]] = (b: Array[Byte]) => new String(b)
}

def f(a: Foo): Baz[a.F] = {
  val baz = a match {
    case bar@Bar => g(bar)
  }
  baz
} // Expression of type Baz[(a.type with Bar.type)#F] doesn't conform to Baz[a.F]

def g(a: Foo)(implicit baz: Baz[a.F]): Baz[a.F] = {
  baz
}

val x1: Bar.type = Bar
val y1: Baz[x1.F] = f(x1)

val x2: Foo = Bar
val y2: Baz[x2.F] = f(x2) // Expression of type Baz[Foo#F] doesn't conform to expected type Baz[x2.F]

What I don’t get is why g compiles but f doesn’t. Are the types not the same?

zetashift
@zetashift
Just a question out of curiosity, making a function a first class value you need to add an apply method(function?), why is it named apply?
Mathieu Prevel
@mprevel
object Test {
  def apply() = doSomething()
}
can be called Test()
this is a special case
Ichoran
@Ichoran
Ugh, this expression stuff is so clunky in this FP example.
There are perfectly reasonable OO ways to make the whole thing tidy, e.g.
trait Expr { def eval: Either[String, Double] }
sealed trait BinOp extends Expr {
  def a: Expr
  def b: Expr
  def op: (Double, Double) => Either[String, Double]

  protected def safe(f: (Double, Double) => Double): (Double, Double) => Either[String, Double] = 
    (xa, xb) => Right(f(xa, xb))

  def eval = a match {
    case Left(s) => Left(s)
    case Right(xa) => b match {
      case Left(s) => Left(s)
      case Right(xb) => op(xa, xb)
  }
}
final case class Add(a: Expr, b: Expr) extends BinOp { val op = safe(_ + _) }
final case class Sub(a: Expr, b: Expr) extends BinOp { val op = safe(_ - _) }
final case class Mul(a: Expr, b: Expr) extends BinOp { val op = safe(_ * _) }
final case class Div(a: Expr, b: Expr) extends BinOp {
  val op = (xa, xb) => if (xb == 0) Left("Division by 0") else Right(xa / xb)
}