These are chat archives for fthomas/refined

6th
Jul 2016
Ben Hutchison
@benhutchison
Jul 06 2016 09:08

Im completely sold on the concept behind Refined and have been waiting for a suitable moment to begin using it. That moment is today :) I have some practical questions one hour in, having watched the talk, read a few docs, and joyfully rewritten a function from Int => Xor[String, Int] to Int Refined Positive => Int.

Firstly, imports. I'm an all-you-can-eat wildcarder myself. Is there anything like cats.implicits._that cuts down the number of imports required from:

import eu.timepit.refined._
import eu.timepit.refined.numeric._
import eu.timepit.refined.api._
import eu.timepit.refined.auto._

Secondly, type aliases. I feel like Im going to be writing Int Refined Positive alot. Are there any standard aliases for common refinements?

(apologies if this stuff is on page 2 of the manual, because Ive only read page 1 :P)

Ben Hutchison
@benhutchison
Jul 06 2016 10:00

FWIW Im using these locally now

   type NatInt = Int Refined Positive
   type Nat0Int = Int Refined NonNegative

Because (a) whether Nats include zero is still controversial, but ℕ₀ seems to be a thing, (b) Nat clashes with shapeless, and (c) NatInt allows NatLong etc

Frank S. Thomas
@fthomas
Jul 06 2016 10:10
@benhutchison I'm sympathetic to the idea of an über-import, but we don't have one yet. This would also simplify the docs. The only downside I've heard so far is that such imports could slow down IntelliJ. To your second question: The only aliases of refined types in the library are in the util.time module. I think I haven't figured out what are common refinements and how to name them properly (I see serious potential for bikeshedding there :smile:). E.g. quasar calls your NatInt Positive and Nat0Int Natural, see here. But providing some type aliases doesn't prevent others from defining their own. So I'm also sympathetic to adding some to the library.
Ben Hutchison
@benhutchison
Jul 06 2016 10:20

Bikeshedding definitely a problem with any kind of naming choice. But some standard aliases, handed down by a benevolent dictator, would probably help reduce fragmentation/divergents (as already happened to me vs Quasar after just 2 hours use!)

Early impressions are that refined has taken a fairly un-opinionated position, which is probably appropriate choice for a foundation library. But more opinionated and/or ergonomic layers on top seem useful to me

Frank S. Thomas
@fthomas
Jul 06 2016 10:26
Agreed. I don't have any strong objections to not providing such aliases in refined. Would you like to open issues for the über-import and the standard aliases?
Ben Hutchison
@benhutchison
Jul 06 2016 11:13

Found @howyp 's question about typeful operators. Ok, I have a Int Refined Positive, now how do I add 1 to it?

For the code site where Im trialing Int Refined Positive, it will runtime-error-out anyway if the Int overflows, so nothing gets worse by using a plusUnsafe(n1: Int Refined Positive, n2: Int Refined Positive): Int Refined Positive operator that throws if it overflows

Frank S. Thomas
@fthomas
Jul 06 2016 11:37
Would that behaviour be more desireable than plusSafe that overflows to one, eg. 1 plusSafe Int.MaxValue == 1?
Ben Hutchison
@benhutchison
Jul 06 2016 12:10

That could be preferable in some situations, although probably not all - potentially such a program could lose "sanity" but keep running, not cleanly failing.

Turns out I was too pessimistic before about my specific example's failure mode. It actually has a Xor[String, Int] threaded through it (using the magic of Eff ) and would have given a nice "$n is not > 0" msg on overflow.

So a plusOrElse[L](n: Int Refined NonNegative, left: L): Xor[L, Int Refined Positive]would seem appropriate in my situation