## Where communities thrive

• Join over 1.5M+ people
• Join over 100K+ communities
• Free without limits
##### Activity
Luis Miguel Mejía Suárez
@BalmungSan
:grimacing:
@arosien
scala 3 will lower the conceptual overhead of this stuff
Eugene Apollonsky
@chessman

hi! rookie's question. I have a List[ValidatedNec[Error, Any]] and I want to collect left parts as Option[NonEmptyChain[Error]]. I came up with

    List(Error("a").invalidNec[String], Error("b").invalidNec[Any]).map(_.fold(Some(_), _ => None)).combineAll

but it looks ugly. is there a better way to do it?

daenyth
@daenyth:matrix.org
[m]
mmm
Luis Miguel Mejía Suárez
@BalmungSan
list.sequence.swap.toOption ?
You may even avoid the List[Validated] in the first place if you can use parTraverse but you would need to show more code for that.
@arosien
separate
def separate[G[_, _], A, B](fgab: F[G[A, B]])(implicit FM: Monad[F], G: Bifoldable[G]): (F[A], F[B])
Separate the inner foldable values into the "lefts" and "rights"
Example:
scala> import cats.implicits._
scala> val l: List[Either[String, Int]] = List(Right(1), Left("error"))
scala> Alternative[List].separate(l)
res0: (List[String], List[Int]) = (List(error),List(1))
Eugene Apollonsky
@chessman
thanks, looks good
bblfish
@bblfish:matrix.org
[m]
I see there is initial work on fthomas/refined#921.
@arosien
noel and i presented about various options for refinements, etc., for a larger view on the subject: https://www.youtube.com/watch?v=w7FuQiSi48w
but yes, refined is quite amazing
bblfish
@bblfish:matrix.org
[m]
Oh thanks.
I am actually starting to wonder if refinement is not actually extremely useful when working with data. So RFC8941 defines a bunch of types for HTTP headers. But each header will only use a subset of some of those types. So eg. a Signing HTTP Messages header will have a SfDict, but restricted to certain types of lists, and certain types of attributes. So it would be interesting if one could keep the underlying data structure but after testing it that it matches some criteria, refine it without changing the structure. Then one could use the underlying data structures without always needing to copy them to new structures.
@arosien
yes!
bblfish
@bblfish:matrix.org
[m]
now I understand what sealed abstract case classes are about :-)
2 replies
Rob Norris
@tpolecat
It's a good trick.
I wish it weren't a trick but I'm glad it's possible.
bblfish
@bblfish:matrix.org
[m]
It would be nice to have an update on arosien (Adam Rosien)'s talk on how to use opaque type classes for refinement now that they are widely available with scala3
Also in that talk Adam mentions how AnyVal's are not that efficient. I wonder if the same criticism is true of extension methods.
bblfish
@bblfish:matrix.org
[m]
I guess one would create opaque types using object { def apply(...) } which would just return the same object, and then use extension methods, that limit how the type can be used, to only the valid things that can be done with the validated subset.
Luis Miguel Mejía Suárez
@BalmungSan

I wonder if the same criticism is true of extension methods.

No, one-level extension methods is one of the few cases where AnyVal always work as expected.

@arosien
AnyVal are efficient, but there are a set of cases where they don't work. they are generally good though.
bblfish
@bblfish:matrix.org
[m]
did you do a follow up talk on opaque types?
@arosien
i know nothing about opaque types, in the scala 3 sense
it probably works most of the time, and doesn't work in weird ways
bblfish
@bblfish:matrix.org
[m]
There is a nice intro talk to it here: https://www.youtube.com/watch?v=8-b2AoctkiY I am just watching now.
Luis Miguel Mejía Suárez
@BalmungSan
AFAIK they always work, because they are exactly that just opaque type alias.
The downside is that they are very raw.
You need to re-create a lot of functionality.
Christopher Davenport
@ChristopherDavenport
They work, but the scopes and rules are pretty difficult to get rightl
Atleast if you want to combine static validation and opaque types, which I often do
Luis Miguel Mejía Suárez
@BalmungSan
Why do you need the inner scope?
bblfish
@bblfish:matrix.org
[m]
I was trying to use an opaque type a few days ago for a Long to refine it to an SfLong (which can have only 15 decimal digits), but I think I discovered that the compiler gave me a warning on pattern matching those, relating Scala loosing type information... (But I did not investigate much deeper and move to case classes..)
Christopher Davenport
@ChristopherDavenport
The inner scope is to allow the static validation to exist outside the scope of the opaque type, as inline and opaque types internal scope conflicts
That's my example of simplest I could manage that was equivalent to - https://github.com/ChristopherDavenport/nonemptystring/blob/master/modules/core/src/main/scala-2/io/chrisdavenport/nonemptystring/NonEmptyString.scala#L23 - Happy to simplify if folks have easier ways. I'm fairly certain I'll have to the same scoping, but now I can use literally rather than writing the custom macro validation myself.
Luis Miguel Mejía Suárez
@BalmungSan
@-@
bblfish
@bblfish:matrix.org
[m]
This is what I get
 Warning: /Volumes/Dev/Programming/Scala3/cosy/src/main/scala/run/cosy/http/headers/Signature-Input.scala:104:70
[warn] 104 |    def created: Option[Long] = params.get(Token("created")).collect{case num: SfInt => num.long}
|the type test for run.cosy.http.headers.Rfc8941.SfInt cannot be checked at runtime
So that is where opaque type SfInt = Long and with a simple extension method long to get out the Long again.
@arosien
in scala 2 you'd want to create an extractor (unapply), not sure what scala 3 requires
bblfish
@bblfish:matrix.org
[m]
Ah yes, of course. Let me see. Scala3 has some new extractor tech.
bblfish
@bblfish:matrix.org
[m]
I was able to get that pattern match to work by adding a TypeTest
given TypeTest[SfInt, Long] =
new TypeTest[SfInt, Long]:
def unapply(s: SfInt): Option[s.type & Long] = Some(s)
It looks like Scala3 needs Optionless TypeTest for opaque types used in refinement contexts
is there the equivalent of the scala 2 unapply where you can type the return value as Some to "guarantee" the extraction?