Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Activity
    Fabio Labella
    @SystemFw
    no need, wait
    try with maven
    what I'm interested in is the output of the actual compiler, and not of IntelliJ basically
    (I do recommend sbt over maven though)
    Alexandr
    @AlexandrSokolov

    @SystemFw , our Jenkins server is not configured with sbt. To ask ITO to additionally install it, it could be an issue for me. That's a reason I am using only maven for the projects that are built on Jenkins.

    Here is the full log. The file is located in test/scala:

    [INFO] --- scala-maven-plugin:3.3.2:testCompile (test-compile) @ scala_test ---
    [WARNING]  Expected all dependencies to require Scala version: 2.12.7
    [WARNING]  com.savdev:scala_test:1.0.0-SNAPSHOT requires scala version: 2.12.7
    [WARNING]  org.typelevel:cats-core_2.12:1.6.0 requires scala version: 2.12.7
    [WARNING]  org.typelevel:cats-macros_2.12:1.6.0 requires scala version: 2.12.7
    [WARNING]  org.typelevel:cats-kernel_2.12:1.6.0 requires scala version: 2.12.7
    [WARNING]  org.typelevel:machinist_2.12:0.6.6 requires scala version: 2.12.6
    [WARNING] Multiple versions of scala libraries detected!
    [INFO] /home/alexandr/projects/scala_test/src/test/java:-1: info: compiling
    [INFO] /home/alexandr/projects/scala_test/src/test/scala:-1: info: compiling
    [INFO] Compiling 3 source files to /home/alexandr/projects/scala_test/target/test-classes at 1551969962786
    [INFO] cmd:  /usr/lib/jvm/java-8-openjdk-amd64/jre/bin/java -Xbootclasspath/a:/home/alexandr/.m2/repository/org/scala-lang/scala-library/2.12.7/scala-library-2.12.7.jar:/home/alexandr/.m2/repository/org/scala-lang/scala-compiler/2.12.7/scala-compiler-2.12.7.jar:/home/alexandr/.m2/repository/org/scala-lang/modules/scala-xml_2.12/1.0.6/scala-xml_2.12-1.0.6.jar:/home/alexandr/.m2/repository/org/scala-lang/scala-library/2.12.0/scala-library-2.12.0.jar:/home/alexandr/.m2/repository/org/scala-lang/scala-reflect/2.12.7/scala-reflect-2.12.7.jar -classpath /home/alexandr/.m2/repository/net/alchim31/maven/scala-maven-plugin/3.3.2/scala-maven-plugin-3.3.2.jar scala_maven_executions.MainWithArgsInFile scala.tools.nsc.Main /tmp/scala-maven-8543241505940940968.args
    [ERROR] /home/alexandr/projects/scala_test/src/test/scala/com/savdev/Ex.scala:10: error: ambiguous implicit values:
    [ERROR]  both method catsDataMonadForKleisliId in class KleisliInstances of type [A]=> cats.CommutativeMonad[[γ$15$]cats.data.Kleisli[[A]A,A,γ$15$]]
    [ERROR]  and method catsApplicativeForArrow in object Applicative of type [F[_, _], A](implicit F: cats.arrow.Arrow[F])cats.Applicative[[β$0$]F[A,β$0$]]
    [ERROR]  match expected type cats.Applicative[com.savdev.Ex.ConfReader]
    [ERROR]   val ex = 1.pure[ConfReader]
    [ERROR]                  ^
    [ERROR] one error found
    Ex.scala:
    package com.savdev
    
    object Ex {
    
      import cats._, data._, implicits._
    
      type Configuration
      type ConfReader[A] = Reader[Configuration, A]
    
      val ex = 1.pure[ConfReader]
    }
    Fabio Labella
    @SystemFw

    our Jenkins server is not configured with sbt. To ask ITO to additionally install it, it could be an issue for me.

    That's ok, I assumed you were just playing around

    in any case, that code should compile, if it doesn't it means there is a problem with your configuration
    in particular you need the `"-Ypartial-unification" compiler option
    this will be the default in scala 2.13, but for now it needs to be added explicitly
    it's one line in sbt, but unfortunately I've never done with Maven. I don't think it's particularly hard, but you'll have to find out how to do that
    Alexandr
    @AlexandrSokolov
    it helped!
    -Ypartial-unification
    Fabio Labella
    @SystemFw
    yeah, it's in the cats docs everywhere, but still people get caught by it. Can't wait for it to be the default
    Alexandr
    @AlexandrSokolov
    I thout it makes sense to use only if I want to use functions, as monads with the cats
    Fabio Labella
    @SystemFw
    no, everytime you have something with two type params
    e.g. Reader
    also, just so you know, Reader is basically a function
    but it will apply also to Either, Validated, and so on
    basically every time you want a G[_, _] to fit into F[_]
    Alexandr
    @AlexandrSokolov
    yes, and I wanted to ask, what are the advantages to use Reader, if I can make a funciton - a monad and return plain function/monad instead of Reader (special Monad)?
    Fabio Labella
    @SystemFw
    you can do either thing, it's fine
    you'll see a more compelling example once you move to the transformer version of Reader, which is called Kleisli
    Alexandr
    @AlexandrSokolov
    Fabio, are there any other arguments for compiler, which it is recommended to use? Additionally to -Ypartial-unification
    Fabio Labella
    @SystemFw
    that one is the only essential one
    I also highly recommend -Ywarn-value-discard especially once (if) you start using fully pure code with IO instead of Future
    Rob has a giant list here https://tpolecat.github.io/2017/04/25/scalac-flags.html , but some of them give you false negatives so I recommend introducing them gradually as you learn more
    I don't use all of those, fwiw
    Alexandr
    @AlexandrSokolov
    ok. Thank you!
    Thank you all, guys, you helped a lot! The first steps are quite complicated. I feel myself like a junior:)
    which IDE do you use for Scala or recommend? I use Intellij IDEA, but sometimes it highlits code with red, althouth it is not an error and compiler compiles it correctly

    for instance

      def nonBlank(name: String)(data: String): FailFast[String] =
        Right(data).ensure(List(s"$name cannot be blank"))(_.nonEmpty)

    the 2nd line is red in my case. It is said that 'Expression of type Either[Any, String] doesn't conform to expected type FunctorTest.this.FailFast[String]'
    Definition of FailFast: type FailFast[A] = Either[List[String], A]

    but Scala compiler does not even warn about it
    Fabio Labella
    @SystemFw
    I use Emacs, which isn't an IDE and that I do not recommend unless you already like it for other reasons
    I think VsCode with Metals is a good middle ground, but tbh for now I'd recommend to stick to what you know even though it's not perfect, you don't want to learn too many things at once
    I heard that people switch off the IntelliJ checker by activating energy save mode
    mmynsted
    @mmynsted
    I must say that the latest Metals on VsCode is nice.
    Alexandr
    @AlexandrSokolov

    I am trying examples, described at https://github.com/underscoreio/scala-with-cats/blob/develop/src/pages/applicatives/validated.md
    Cannot comple readUser function. Here is a list of all imports and readUser itself (all functions are implemented as described in that page):

      import cats.Semigroupal
      import cats.data.Validated
    
      import cats.instances.string._ // for Semigroup
      import cats.instances.vector._ // for Semigroupal
      import cats.instances.list._ // for Semigroupal
    
      import cats.syntax.apply._   // for mapN
      import cats.syntax.validated._ // for valid and invalid
      import cats.syntax.either._ // for catchOnly
    
    case class User(name:String, age:Int)
    
      def readUser(data: FormData): FailSlow[User] =
        (
          readName(data).toValidated,
          readAge(data).toValidated
        ).mapN(User.apply)

    The error I am getting, is related to the line, where mapN is invoked:

    Error:(166, 7) value mapN is not a member of (cats.data.Validated[List[String],String], cats.data.Validated[List[String],Int])
    possible cause: maybe a semicolon is missing before `value mapN'?
        ).mapN(User.apply)
    Error:(166, 17) missing argument list for method apply in object User
    Unapplied methods are only converted to functions when a function type is expected.
    You can make this conversion explicit by writing `apply _` or `apply(_,_)` instead of `apply`.
        ).mapN(User.apply)

    what do I miss?

    The -Ypartial-unification is enabled:)

    Here is a simplified example, which can be copied as it is:

      import cats.syntax.either._ // for ensure and for catchOnly
      import cats.data.Validated
    
      type FailFastList[A] = Either[List[String], A]
      type FailSlow[A] = Validated[List[String], A]
    
      def nonBlank(name: String)(data: String): FailFastList[String] =
        Right(data).ensure(List(s"$name cannot be blank"))(_.nonEmpty)
    
      case class User(name:String, nickname:String)
    
      import cats.instances.list._ // for Semigroupal
      import cats.syntax.either._ // for catchOnly
      import cats.syntax.apply._ // for mapN
      import cats.syntax.validated._ // for valid and invalid
    
      def fromLists(data: Map[String,String]): FailSlow[String] =
        (
          nonBlank("name")(data.get("name").get).toValidated,
          nonBlank("nickname")(data.get("nickname").get).toValidated
        ).mapN(User.apply)

    Same error with mapN

    Alexandr
    @AlexandrSokolov

    One more question, related to fail slow. Here is an example, in which 2 dates are taken from map and validation checks if one dates comes after another. Most methods are copied from Cats with Scala, except the oneDateAfterAnother:

    object DateFailSlow {
    
     import cats.syntax.either._ // for ensure and for catchOnly
     import java.text.{ParseException, SimpleDateFormat}
     import java.util.Date
     import cats.data.Validated
     import cats.Semigroupal
    
     type FailFast[A] = Either[List[String], A]
     type FailSlow[A] = Validated[List[String], A]
    
     def oneDateAfterAnotherFailFast(dateBefore: String, dateAfter: String)
                                    (map: Map[String, String])(format: SimpleDateFormat)
      : FailFast[Boolean]=
      for {
       dateBefore <- readDate(dateBefore)(map)(format)
       dateAfter <- readDate(dateAfter)(map)(format)
      } yield dateAfter.compareTo(dateBefore) > 0
    
     def readDate(name:String)(map: Map[String, String])(format: SimpleDateFormat):FailFast[Date] =
      for {
       value <- readValue(name)(map)
       res <- parseDate(name)(value)(format)
      } yield res
    
     def readValue(name: String)(map: Map[String, String]): FailFast[String] =
      for {
       value <- getValue(name)(map)
       _ <- nonNullable(name)(value)
       res <- nonBlank(name)(value)
      } yield res
    
     def getValue(name: String)(map: Map[String, String]): FailFast[String] =
      map.get(name)
        .toRight(List(s"$name field not specified"))
    
     def nonNullable(name: String)(data: String): FailFast[String] =
      Right(data).ensure(List(s"$name cannot be nullable"))(_ != null)
    
     def nonBlank(name: String)(data: String): FailFast[String] =
      Right(data).ensure(List(s"$name cannot be blank"))(_.nonEmpty)
    
     def parseDate(name: String)(data: String)(format: SimpleDateFormat): FailFast[Date] =
      Either.catchOnly[ParseException](format.parse(data)).
        leftMap(_ => List(s"$name must be a date"))
    
    }

    It works fine, but I want to accumulate error s in oneDateAfterAnother. And it is an issue for me. Here is my try:

     def oneDateAfterAnotherFailSlow(dateBefore: String, dateAfter: String)
                                    (map: Map[String, String])(format: SimpleDateFormat)
      : FailSlow[Boolean]=
      Semigroupal.map2(
       readDate(dateBefore)(map)(format).toValidated,
       readDate(dateAfter)(map)(format).toValidated
      )(_.compareTo(_) > 0)

    As I understand map2 accepts 2 contexts, in my case it is to Validated and a function, that converts 2 arguments into the 3rd. Boolean in my case. But I am getting the error:

    Error:(23, 4) type mismatch;
     found   : cats.data.Validated[List[String],java.util.Date]
     required: ?F[?A0]
    Note that implicit conversions are not applicable because they are ambiguous:
     both method ArrowAssoc in object Predef of type [A](self: A)ArrowAssoc[A]
     and method Ensuring in object Predef of type [A](self: A)Ensuring[A]
     are possible conversion functions from cats.data.Validated[List[String],java.util.Date] to ?F[?A0]
      )(_.compareTo(_) > 0)

    Can you please explain, what I am doing wrong?

    Noel Welsh
    @noelwelsh
    There is an error here:
    def fromLists(data: Map[String,String]): FailSlow[String]
    The return type is not String but User
    Should be
    def fromLists(data: Map[String,String]): FailSlow[User]
    BTW, there is some new stuff that isn't in the book that might be useful to you: https://typelevel.org/cats/typeclasses/parallel.html
    Alexandr
    @AlexandrSokolov
    @noelwelsh , I have changed a return type to FailSlow[User], the error is slightly changed, but still the root cause is the same
    Alexandr
    @AlexandrSokolov
    Sorry guys, it is definitely my fault. Intellij IDEA is a piece of ... of not a code software for Scala. It turned out, that it does not inhrerit configuration of scala compiler from maven pom.xml, but it must.
    I had to explicitly configure Scala Compler in GUI with '-Ypartial-unification' property. And it seems it fixed the error. Still working on it. But please ignore all my previous questions
    starting working on Scala: first question must be - what is used to build it, maven, sbt or IDE
    Fabio Labella
    @SystemFw

    @AlexandrSokolov as a trick, every time you see:

    required: ?F[?A0]

    with those question marks, it's partial unification

    Alexandr
    @AlexandrSokolov
    Fabio, can we request for such compiler errors a description in the error: 'check if partial unification is enabled'. It will help a lot to analyze and not to guess
    Fabio Labella
    @SystemFw
    well, in 2.13 this error won't happen again so...