Skip to content

Instantly share code, notes, and snippets.

@jmgimeno
Forked from betehess/scalaz.irclog
Last active August 29, 2015 14:11
Show Gist options
  • Save jmgimeno/c2ac77ab718394acc6bc to your computer and use it in GitHub Desktop.
Save jmgimeno/c2ac77ab718394acc6bc to your computer and use it in GitHub Desktop.
<RaceCondition> can I use Scalaz to get exhaustion checks when matching on numeric values? Scala obviously doesn't do that
<RaceCondition> ! 1.1 match { case x if 0.0 <= x && x < 0.5 => "bad"; case x if 0.5 <= x && x <= 1.0 => "good" }
<dibblego> doubt it
<multibot_> scala.MatchError: 1.1 (of class java.lang.Double)
<multibot_> ... 38 elided
<dibblego> use types though?
<RaceCondition> wdym?
<dibblego> use a type to note each range
<dibblego> you want a floating-point between 0.0 and 1.0?
<RaceCondition> wouldn't that just move the problem to a different stage?
<dibblego> yes, to the earliest possible stage
<RaceCondition> I'd have to convert the Double to that type, at which point I'd still use matching, at which point I'd like the compiler to warn me if I've forgotten a range :)
<dibblego> that's the point of types after all
<RaceCondition> so the question remains
<dibblego> you'd have to not start with a Double
<qu1j0t3> RaceCondition: you are talking about classification. Just classify
<qu1j0t3> RaceCondition: then match on the classification
<dibblego> why do you have a Double? from where did it come from?
<RaceCondition> qu1j0t3: that code IS the classification code btw
<qu1j0t3> right
<dibblego> how do you know it is "bad"?
<qu1j0t3> that's another good question.
<dibblego> what invariant made that the case?
<qu1j0t3> what would an exhaustiveness check on a Double mean
<RaceCondition> ! 1.1 match { case x if 0.0 <= x && x < 0.5 => "bad"; case x if 0.5 <= x && x <= 1.0 => "good" }
<multibot_> scala.MatchError: 1.1 (of class java.lang.Double)
<multibot_> ... 38 elided
<qu1j0t3> see my question in the other channel... there are values that are not in [-∞,∞]
<qu1j0t3> etc, etc.
<dibblego> type error > warning
<RaceCondition> the match expression obviously doesn't cover < 0 and > 1.0 — that could be statically detected
<dibblego> it could yes
<qu1j0t3> eCondition | qu1j0t3: that code IS the classification code btw
<qu1j0t3> oops
<qu1j0t3> i mean, what about this question:
<qu1j0t3> dibblego | why do you have a Double? from where did it come from?
<RaceCondition> from a mathematical computation that computes certain scores for people
<dibblego> something makes you think it is in that range
<dibblego> fix that bit
<RaceCondition> but look, this might as well be a Double that can actually range from -Inf to Inf... then I'd still have the same question
<RaceCondition> I'm not saying there aren't workarounds
<dibblego> same answer
<dibblego> this question generalises to "use types"
<dibblego> how do I know my Int is a valid age?
<dibblego> well how indeed? how did you even come to that conclusion?
<dibblego> well, because age returns Int
<dibblego> stop doing that!
<dibblego> Age returns a value between 0 and MAX_AGE
<dibblego> oh, then you want a type for that
<dibblego> but what about my Int!
<dibblego> there was never an Int
<dibblego> but I want to use it as an Int!
<dibblego> so do that
<dibblego> but it is clumsy and annoying to convert all the time!
<dibblego> so use libraries
<dibblego> which library?
<dibblego> well, in this case, lenses
<dibblego> or prisms or whateva
<dibblego> but now I have to learn lens!
<RaceCondition> at some point I still have to convert Int => Age
<dibblego> yes, you do
<dibblego> Nope.
<dibblego> do you know how I know you dont have that point?
<dibblego> because *nobody does because it does not exist*
<dibblego> go on then, convert 3333 to Age
* dibblego twiddles
<dibblego> how do I get the (a) out of (IO a)?
<dibblego> you don't
<dibblego> but I need the (a)!
<dibblego> so get it
<dibblego> but how?
<dibblego> libraries
<dibblego> what do you mean libraries!?
<dibblego> you know, like say, the IO monad
<dibblego> but now I have to learn monads!
<dibblego> yes, you do
<dibblego> but I want the (a) out of (IO a)!
<dibblego> no you don't!
<dibblego> yes I do, don't tell me what I want!
<dibblego> well, I know you don't want it, because it is *not a thing that exists*
<dibblego> gah, but I want things that don't exist
<dibblego> yes, I want puppies all over my face right now, doesn't exist
<dibblego> IO is a terrible example of course
<dibblego> how about this one
<dibblego> how do I get the A out of (B => A)?
<dibblego> you give it a B
<dibblego> but I don't have a B!
<dibblego> then you don't have an A
<dibblego> but I need it!
<dibblego> libraries
<dibblego> (or doesn't exist)
<dibblego> of course, you might have f(x) is believed to always return an Int in Age range
<dibblego> but unfortunately, some assclown made f return Int
<dibblego> and so, you draw a line in the sand and say, "enough! no more assclowns from here on!"
<RaceCondition> if I have Age1, Age2, Age3, etc upto Age<Max>, and say, also, AgeInvalid, I'd still want exhaustion checks in my rawAge match { ... } expression so as to make sure I didn't forget the `case _ => AgeInvalid` bit
<dibblego> then you fix it at that point
<dibblego> that's what really happens
<dibblego> that's just Option[Age] — you have exhaustion checks
<dibblego> you really want a *type error*
<dibblego> these are just limitations of impredicate logic
<dibblego> in light of this, scala says, "you know, I may be wrong here, but you probably want to do the Invalid/None case"
<RaceCondition> so what is the purpose of exhaustion checks in the first place then?
<dibblego> that is an exhaustion check — a sad consolation
<dibblego> to make up for the limitations of the type system in this case
<RaceCondition> if I validate input then the type system can't help me
<dibblego> the benefit is expressiveness on a turing machine
<RaceCondition> user input, I mean
<dibblego> sure it can
<RaceCondition> maybe I don't want a type error
<RaceCondition> maybe I actually have categories for each possible value of a Double
<RaceCondition> or Int
<dibblego> then what? a program that doesn't work?
<dibblego> so do that too
<RaceCondition> in which case I'd still want exhaustion checks in `rawInt match { ... }`
<dibblego> you can say, Int => Option[Age] you know
<dibblego> n => if(inRange(n)) Some(Age(n)) else Nope
<dibblego> exhaustion checks are a desperate last resort
<dibblego> use types
<RaceCondition> the point of exhaustion checks is to help me not forget a range
<dibblego> no that is the point of type errors
<RaceCondition> matter of opinion
<dibblego> nope
<RaceCondition> OCaml and Haskell rely more heavily on exhaustion checks
<dibblego> my opinion is that working programs are more valuable than not working programs
<dibblego> no they don't
<dibblego> thousands and thousands of lines of haskell and you know what? not a single inexhaustive check
<dibblego> that's because: types, dunrite
<dibblego> I bladdy well made it that way
<dibblego> beginner haskell programmers rely on them
<dibblego> well, not all of them — not when I am finished with them
<dibblego> show me this heavy reliance and I will show you a better program without it
<RaceCondition> why would my sealed trait Foobar get exhaustion checks but not Int? Int is also an "enumeration"
<dibblego> because checking exhausation on *everything* is the same as solving the halting problem
<dibblego> that's why you strive for safety in the first place, instead of conceding to exhaustive checks
<RaceCondition> you mean exhaustion checks on Ints are in general impossible to achieve?
<dibblego> I am quite exactly doing this right now you know
<dibblego> no, on everything in genera
<dibblego> do you know a WGS84 latitude/longitude?
<dibblego> is that an Int?
<dibblego> nope
<dibblego> but it is 73 degrees! it is an Int!
<dibblego> stop it
<dibblego> types
<RaceCondition> it'd have sufficed to just use `case n if n * n > 100` as an example, and I would have believed you right away.
<dibblego> I don't know what that means
<dibblego> I gave several examples
<dibblego> I'm not asking you to believe me
<dibblego> you might value not-working programs after all
<RaceCondition> I already do; I just don't see a need for that wall of text
<dibblego> the moment you don't, well, facts have something to say
<RaceCondition> nor the sarcasm
<dibblego> oh excellent, I should have just said at the start: types
<dibblego> (which I did)
<RaceCondition> that's a different point...
<dibblego> ugh
<RaceCondition> it's not the same as "ints simply can't be exhaustion checked"
<RaceCondition> types are just a solution to that limitation, which I agree with
<dibblego> you'll note that I didn't say that
<dibblego> and when you asked, I repeated, no, I didn't say that
<dibblego> but hey, sure, yes
<dibblego> whichevz
<RaceCondition> you said: "no, on everything in genera" which also includes ints
<dibblego> no, it really doesn't
<RaceCondition> so ints can be exhaustion checked? :)
<dibblego> jesus fuck me drunk christ
<RaceCondition> I've never seen that style of speech/attitude on #scalaz btw; but I guess there's always a first time
<dibblego> oh talk police now?
<RaceCondition> I'll get back to work now
<dibblego> k bye
<RaceCondition> swearing is fine but the "you're stupid I'm smart" attitude puts people off
<dibblego> yes thank you for that advice I will take it into consideration
<dibblego> fucking hell
<dibblego> go to work
<dibblego> "I am OK if you say those words, but not those other ones"
<dibblego> by the way, go fuck yourself, a little bit?
<RaceCondition> rinse and repeat? :)
<dibblego> I don't give a flying fuck for imposed morality, especially when it is cheap and bullshit
<RaceCondition> I agree with that, dibblego
<dibblego> excellent
<dibblego> have fun at work
<dibblego> use types!
<RaceCondition> I do, thanks
<dibblego> @pl \b r -> pure (b (r n))
<lambdabot> (pure .) . (. ($ n))
<dibblego> @pl \r -> pure (b (r n))
<lambdabot> pure . b . ($ n)
<dibblego> @type bool id
<lambdabot> (a -> a) -> Bool -> a -> a
<ceedubs> dibblego: It looks to me like RaceCondition was asking a question in good faith. I want #scalaz to be a place where that is welcomed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment