Home liberachat/#haskell: Logs Calendar

Logs: liberachat/#haskell

←Prev  Next→ 1,804,543 events total
2021-08-30 08:03:58 <maerwald[m]> Like a web page going blank in production, because you deleted a bracket at a wrong place and the code still compiled
2021-08-30 08:04:38 <kuribas> maerwald[m]: we've had a client complaining because our code broke due to a type error.
2021-08-30 08:04:48 <kuribas> email reporting I mean...
2021-08-30 08:04:59 <maerwald[m]> Yes, the only advantage of clojure, interactive development
2021-08-30 08:05:31 <kuribas> interactive development is much worse in haskell, but I still prefer it, because I am not "forced" to use the repl.
2021-08-30 08:05:32 hendursa1 joins (~weechat@user/hendursaga)
2021-08-30 08:05:42 <kuribas> I just use it when *I* want to.
2021-08-30 08:06:16 × mikoto-chan quits (~mikoto-ch@ip-83-134-2-136.dsl.scarlet.be) (Quit: mikoto-chan)
2021-08-30 08:06:39 <maerwald[m]> I stopped interactive development in haskell and it made me better at coding. Thinking for more than 5 minutes about code without compiling it has an interesting effect
2021-08-30 08:07:28 <maerwald[m]> And it's a pleasure when things compile after you've been editing for 30 minutes
2021-08-30 08:07:36 <kuribas> maerwald[m]: I test my code *after* writing it.
2021-08-30 08:08:36 × hendursaga quits (~weechat@user/hendursaga) (Ping timeout: 276 seconds)
2021-08-30 08:12:49 × rbocquet quits (~weechat@2001:bc8:47a8:44e::1) (Quit: WeeChat 2.8)
2021-08-30 08:16:10 rbocquet joins (~weechat@2001:bc8:47a8:44e::1)
2021-08-30 08:17:15 arjun joins (~Srain@user/arjun)
2021-08-30 08:17:53 <arjun> Hi, i'm inside a function with some constraints (MonadIO m, MonadCatch m .... etc)
2021-08-30 08:18:08 <arjun> now one of the arguments is a Maybe FilePath
2021-08-30 08:18:39 <arjun> and i can't seem to do ` dir <- givenPath ` inside the `do`
2021-08-30 08:18:40 × notzmv quits (~zmv@user/notzmv) (Ping timeout: 240 seconds)
2021-08-30 08:18:53 <arjun> " Couldn't match type ‘m’ with ‘Maybe’ "
2021-08-30 08:19:18 <arjun> while, i could do `let dir = fromJust givenPath` just fine
2021-08-30 08:19:26 <merijn> Maybe is not an instance of MonadIO, so you can't do that, no
2021-08-30 08:20:19 × azeem quits (~azeem@176.200.56.216) (Ping timeout: 250 seconds)
2021-08-30 08:20:21 <arjun> bump.
2021-08-30 08:21:08 <arjun> what's the prefered way to do this kindda thing, just for my curiosity's sake
2021-08-30 08:21:41 <kuribas> arjun: don't use fromJust, use fromMaybe instead.
2021-08-30 08:21:45 <kuribas> :t fromJust
2021-08-30 08:21:46 <lambdabot> Maybe a -> a
2021-08-30 08:21:50 <kuribas> :t fromMaybe
2021-08-30 08:21:50 <merijn> "preferred way to do this" <- you haven't really specified what "this" is
2021-08-30 08:21:51 <lambdabot> a -> Maybe a -> a
2021-08-30 08:22:24 <merijn> arjun: You have said "I have a Maybe FilePath", but not really anything about how you wanna use it or what you expect to happen
2021-08-30 08:22:27 <kuribas> arjun: fromJust will crash when you pass a Nothing, with a very unhelpful message.
2021-08-30 08:22:29 azeem joins (~azeem@62.18.127.19)
2021-08-30 08:22:33 <arjun> kuribas: yea, just repl'd it. fromJust is unsafe if i get Nothing
2021-08-30 08:23:08 <kuribas> arjun: as merijn said, you have to figure out what to do when it's `Nothing`.
2021-08-30 08:23:45 <arjun> merijn: get a value from Just if it's Just (for eg get 5 from Just 5) and Nothing if it's Nothing from a polymorphic function with constraints ? does that make sense?
2021-08-30 08:24:13 <arjun> merijn: i understand Maybe not having a MonadIO instance
2021-08-30 08:24:25 <merijn> That doesn't really make sense no
2021-08-30 08:24:38 <merijn> What does "getting Nothing if it's Nothing" mean
2021-08-30 08:24:44 <arjun> kuribas: i see. i was hoping "<-" would take care of it for me : P
2021-08-30 08:24:50 <merijn> <- is not magic
2021-08-30 08:24:57 <merijn> <- is just sugar for >>=
2021-08-30 08:25:00 <merijn> :t (>>=)
2021-08-30 08:25:02 <lambdabot> Monad m => m a -> (a -> m b) -> m b
2021-08-30 08:25:02 rtpg joins (sid443069@charlton.irccloud.com)
2021-08-30 08:25:08 <kuribas> arjun: you mean, <- would pry into your mind, and do the right thing?
2021-08-30 08:25:10 <merijn> That means all sides have to be the same 'm'
2021-08-30 08:25:40 <kuribas> arjun: or better, infer the business logic that needs to apply in this case?
2021-08-30 08:25:46 __monty__ joins (~toonn@user/toonn)
2021-08-30 08:25:48 <arjun> kuribas: it should also write the docs, white it's at it : P
2021-08-30 08:25:55 <merijn> arjun: Specifically, if you *did* use <- with Maybe, then they entire do block would be a "Maybe" type
2021-08-30 08:25:58 <arjun> while*
2021-08-30 08:26:03 <kuribas> arjun: cool, let me know when you find this :)
2021-08-30 08:26:25 <merijn> arjun: And your function wouldn't be "foo :: MonadIO m => Maybe FilePath -> m ()" it'd just be "foo :: Maybe FilePath -> Maybe ()" or whatever
2021-08-30 08:26:39 <arjun> merijn: yes, that's what the error is saying i suppose (hard to read for untrained eyes)
2021-08-30 08:27:00 burnsidesLlama joins (~burnsides@dhcp168-015.wadham.ox.ac.uk)
2021-08-30 08:27:20 <arjun> my function is expected to return m Bool, but it returns a fixed type Maybe ..
2021-08-30 08:27:38 <arjun> i see.
2021-08-30 08:27:46 <arjun> thanks ! merijn
2021-08-30 08:28:08 <rtpg> Has there ever been any discussion of having Haskell adopt anonymous sum types? That is to say, instead of using Either Int Bool, being able to write out Int | Bool and pattern match directly off of that? Essentially making sum types first-class in the same way products are
2021-08-30 08:28:41 <[exa]> (product types are first class?)
2021-08-30 08:28:47 <opqdonut> sums are first-class in exactly the same way as products
2021-08-30 08:28:55 <opqdonut> both have their type constructor: (,) and Either
2021-08-30 08:29:38 <opqdonut> (and you have the ADT syntax which allows you to define a custom collection of sums and products and give it a name)
2021-08-30 08:29:39 <arjun> why do i always get the image of people evacuating the Titanic when it's drowning when people say "first class"
2021-08-30 08:30:13 <rtpg> I think it's pretty easy to argue that tuples are ... more.... first-class (like I don't have to give names, I can do N-products instead of stacking with Either). But I get your point from a mechanical level
2021-08-30 08:30:45 <kuribas> rtpg: tuples have type constructors as well.
2021-08-30 08:31:24 <rtpg> At least for me, Typescript allows for using anonymous unions, and then is able to very easily deduce what your thing is without having you need to name some helper type like StringOrPropertyAccessorOrInteger
2021-08-30 08:32:51 <kuribas> rtpg: you should never name things like that :)
2021-08-30 08:33:25 <[exa]> rtpg: you can't reliably infer an anonymous union without abusing a closed-world assumption
2021-08-30 08:34:51 <[exa]> rtpg: what about just making a tiny typeclass for that?
2021-08-30 08:34:58 <rtpg> ah that's a good point, suddenly it's like "is this supposed to return A | B or is it meant to return A and B is a mistake"
2021-08-30 08:35:34 <[exa]> stuff like "f :: MyFunctionWorksWith a => a -> a" is pretty common I'd say
2021-08-30 08:35:38 <rtpg> I mean y'all never just have a bucket of things that exist in some inner function that don't have much semantic value beyond being the return type of a handful of objects?
2021-08-30 08:36:27 <kuribas> rtpg: in lisps often they make one function do a lot of things. The haskell way is more to have different "combinators", to provide different features.
2021-08-30 08:36:35 <kuribas> rtpg: it works better with static typing
2021-08-30 08:36:53 <rtpg> though yeah I guess I don't mind making the function itself have to be explicit, it's more around callsites, I would love to pattern match directly on A | B without having to unwrap an Either first. But I guess with Rust I end up taking a trait anyways
2021-08-30 08:36:56 <merijn> rtpg: Datatypes are cheap to define in Haskell
2021-08-30 08:36:57 <[exa]> rtpg: or, say. `mySemanticOf :: HasMySemantics a => a -> Bool`, and use it to downcast the many possibilities to something predictable
2021-08-30 08:37:09 <merijn> rtpg: So, might as well define a datatype
2021-08-30 08:37:34 <kuribas> rtpg: err, how would you pattern match on A | B, if you don't have a constructor?
2021-08-30 08:38:00 <merijn> rtpg: In fact, as my projects scale up, the more I love previous me for defining lots and lots of custom datatypes
2021-08-30 08:39:33 × eggplantade quits (~Eggplanta@2600:1700:bef1:5e10:10be:968:241f:1aa6) (Remote host closed the connection)
2021-08-30 08:39:47 × hyiltiz quits (~quassel@31.220.5.250) (Ping timeout: 240 seconds)
2021-08-30 08:40:05 <rtpg> let's say you have Foo = Bar Int | Baz String, and like Mouse Int, then Foo | Mouse you could pattern match like "f:: (Foo | Mouse) -> Int" and just directly "f (Bar i) = i; f (Baz s) = length s, f (Mouse m) = m"
2021-08-30 08:41:11 <kuribas> merijn: the same for me. And my code becomes more readable.
2021-08-30 08:41:31 <rtpg> this is very much a "thought about for a little bit" thing, where how the compiler turns this into executable code is probably tricky. TS doesn't have that problem since it doesn't have to actually evaluate the code of course
2021-08-30 08:41:39 hyiltiz joins (~quassel@31.220.5.250)
2021-08-30 08:42:26 <merijn> rtpg: How is writing (Foo | Mouse) in a function better than taking 1 line to define an ADT that implements that? :p
2021-08-30 08:43:03 <rtpg> FooOrMouse = Either Foo Mouse , then I'm writing Left (Bar i) and Left (Baz s) blah blah blah.... it's all line noise to me in that case
2021-08-30 08:43:29 <rtpg> like sometimes things don't have any conceptual meaning outside of one specific spot! Surely you have had situations where a thing just doesn't have a good name available for it right?
2021-08-30 08:43:30 <kuribas> important semantic information /= line noise
2021-08-30 08:44:53 <rtpg> I don't believe that saying Either and then Left/Right in this case is adding extra semantic information in these kinds of cases (where you're really just wanting a sum type). This isn't a general judgement on all sum types, just wondering if this is a thing that has been discussed
2021-08-30 08:45:13 <merijn> rtpg: I didn't say either, I said defining your own ADT
2021-08-30 08:45:48 × shriekingnoise quits (~shrieking@186.137.144.80) (Quit: Quit)
2021-08-30 08:46:36 <rtpg> You know that base lisp thing where if you want to define a variable with a let, you end up introducing indentation into your code that wouldn't exist in, say, Python/C? I feel the same way with introducing the intermediate ADT in my example (even if in the internals something would have to be done to get that to work)
2021-08-30 08:47:59 <kuribas> rtpg: my take is that if you have lots of intermediate ADTs like that, your not thinking in a haskell way...
2021-08-30 08:48:15 <kuribas> see my comment above
2021-08-30 08:49:24 <kuribas> If I write my functions in haskell as I would write lisp, it may end up like that.

All times are in UTC.