Logs: freenode/#haskell
| 2020-10-04 03:44:43 | <hololeap> | ghc outputs frowny faces? |
| 2020-10-04 03:45:04 | <dsal> | I don't know... if you get too deep into inference, the error is too large for anyone to really know what happens. |
| 2020-10-04 03:45:14 | <dsal> | Well, except for C++ programmers, I guess. They won't notice the error scroll by. |
| 2020-10-04 03:46:17 | <dolio> | It's not necessarily that it's large. It's more that it's non-local. |
| 2020-10-04 03:47:08 | × | ym555 quits (~ym@41.42.203.37) (Ping timeout: 260 seconds) |
| 2020-10-04 03:47:39 | <dolio> | You can write code where the types accidentally work out until a part that isn't really related to where the problem is. |
| 2020-10-04 03:48:21 | <dsal> | Yeah, and as you make things more generic, they can work in more places, so you use them in more places, and then just weird happens. |
| 2020-10-04 03:49:05 | <hololeap> | "Occurs check: cannot construct infinite type" is usually the hardest one for me to understand what i did wrong |
| 2020-10-04 03:49:34 | <dsal> | > foldMap (*1) [0, 1, 2, 3, 4] |
| 2020-10-04 03:49:36 | <lambdabot> | error: |
| 2020-10-04 03:49:36 | <lambdabot> | • Ambiguous type variable ‘a0’ arising from a use of ‘show_M650599424046... |
| 2020-10-04 03:49:36 | <lambdabot> | prevents the constraint ‘(Show a0)’ from being solved. |
| 2020-10-04 03:49:57 | <dsal> | Errors like this will ramble on for a bit. |
| 2020-10-04 03:50:03 | <dsal> | > foldMap (*1) [0, 1, 2, 3, 4] :: Sum Int |
| 2020-10-04 03:50:07 | <lambdabot> | Sum {getSum = 10} |
| 2020-10-04 03:50:11 | <dsal> | > foldMap (*1) [0, 1, 2, 3, 4] :: Product Int |
| 2020-10-04 03:50:14 | <lambdabot> | Product {getProduct = 0} |
| 2020-10-04 03:50:18 | <dsal> | Stupid zero. |
| 2020-10-04 03:51:25 | <dsal> | It gets *really* exciting when you enable OverloadedLists |
| 2020-10-04 03:52:04 | <c_wraith> | hololeap: that error means that GHC tried to unify a pair of types where one occurs inside the other. Just declaring them to be equal would mean the full expansion is infinite. |
| 2020-10-04 03:52:44 | <dsal> | a ~ [a] kinds of things |
| 2020-10-04 03:52:47 | <hololeap> | c_wraith: it often crops up when i refactor to pointfree and i forgot to remove one of the arguments from the function definition |
| 2020-10-04 03:52:55 | → | wei2912 joins (~wei2912@unaffiliated/wei2912) |
| 2020-10-04 03:53:11 | <dsal> | OMG, I'm trying to figure out where I've used OverloadedLists, and I have a tiny file here with it on, but I'm still using Map.fromList |
| 2020-10-04 03:53:14 | <c_wraith> | hololeap: sure, a -> b and b could unify if infinite types were allowed |
| 2020-10-04 03:53:17 | <dolio> | You can actually have type systems that allow that. But it catches so many incidental errors it'd be kind of terrible. |
| 2020-10-04 03:53:31 | <dsal> | Ah, I use it in tests sometimes. |
| 2020-10-04 03:53:33 | <c_wraith> | hololeap: but it would also imply a -> a -> b is the same type as b |
| 2020-10-04 03:53:37 | <dolio> | At least, you don't want it without requesting it. |
| 2020-10-04 03:54:17 | × | GyroW quits (~GyroW@unaffiliated/gyrow) (Quit: Someone ate my pie) |
| 2020-10-04 03:54:27 | <hololeap> | c_wraith: i am glad that it throws _some_ error, but that particular error message usually leaves me scratching my head for a minute. at least it gives a line number so i can stare at it until i see what i did wrong |
| 2020-10-04 03:54:30 | <dsal> | The error message confuses people because it's accurate in type theorist language, but it generally means, "I don't think you're saying what you mean." |
| 2020-10-04 03:54:35 | → | GyroW joins (~GyroW@ptr-48ujrfd1ztq5fjywfw3.18120a2.ip6.access.telenet.be) |
| 2020-10-04 03:54:35 | × | GyroW quits (~GyroW@ptr-48ujrfd1ztq5fjywfw3.18120a2.ip6.access.telenet.be) (Changing host) |
| 2020-10-04 03:54:35 | → | GyroW joins (~GyroW@unaffiliated/gyrow) |
| 2020-10-04 03:54:51 | <c_wraith> | Just look at the two types it tells you |
| 2020-10-04 03:54:54 | × | jedws quits (~jedws@121.209.139.222) (Quit: My MacBook has gone to sleep. ZZZzzz…) |
| 2020-10-04 03:55:31 | <c_wraith> | If the bigger one is a function type, it means you have differing numbers of arguments in different branches. |
| 2020-10-04 03:55:49 | <hololeap> | that's a very useful tip that i will keep in mind |
| 2020-10-04 03:56:00 | <dsal> | It's usually `a ~ [a]` for me which is always a dumb error. |
| 2020-10-04 03:56:21 | <c_wraith> | > let f 0 = Nothing ; f x = show x in f () |
| 2020-10-04 03:56:23 | <lambdabot> | error: |
| 2020-10-04 03:56:24 | <lambdabot> | • Couldn't match type ‘[Char]’ with ‘Maybe a2’ |
| 2020-10-04 03:56:24 | <lambdabot> | Expected type: Maybe a2 |
| 2020-10-04 03:56:25 | <dolio> | Yeah, it usually has something to do with too many or too few arguments, or arguments in the wrong order or something. |
| 2020-10-04 03:56:29 | <c_wraith> | Oh, whoops. |
| 2020-10-04 03:56:34 | <c_wraith> | > let f 0 = Nothing ; f x = x in f () |
| 2020-10-04 03:56:36 | <lambdabot> | error: |
| 2020-10-04 03:56:36 | <lambdabot> | • Couldn't match expected type ‘Maybe a’ with actual type ‘()’ |
| 2020-10-04 03:56:37 | <lambdabot> | • In the first argument of ‘f’, namely ‘()’ |
| 2020-10-04 03:56:43 | <dolio> | Or forgetting to map/bind something. |
| 2020-10-04 03:56:46 | <c_wraith> | Oh, too much inference. Oh well. |
| 2020-10-04 03:56:59 | <c_wraith> | Anyway. Look at the two types it's telling you it's trying to unify |
| 2020-10-04 03:57:15 | <c_wraith> | The difference between them is the important part |
| 2020-10-04 03:57:17 | <dolio> | I'm not sure if GHC tries to tell you what's wrong, but I'm not sure how it would narrow it down. |
| 2020-10-04 03:58:59 | <hololeap> | don't get me wrong, i'm not complaining. the fact that ghc uses type theory to allow a huge number of valid things is awesome. but at first it complaining that i was trying to construct an infinite type for some mundane function made me go WTF |
| 2020-10-04 03:59:29 | <c_wraith> | the thing to remember is that GHC tries *really* hard to make your code work. |
| 2020-10-04 03:59:58 | <c_wraith> | In this case, it's reaching the conclusion "this code would type-check if these two types are the same." |
| 2020-10-04 04:00:13 | <c_wraith> | And then going "oops, I'm not allowed to make these two types the same" |
| 2020-10-04 04:00:59 | <c_wraith> | And it reports that last problem, because that's the point from which it could make no more progress. |
| 2020-10-04 04:03:22 | × | Jesin quits (~Jesin@pool-72-66-101-18.washdc.fios.verizon.net) (Ping timeout: 258 seconds) |
| 2020-10-04 04:03:28 | <hololeap> | it's like if i was trying to skip rocks, and failed, and someone came up to me and said "why are you trying to subvert the laws of physics by skipping a rock at that velocity and trajectory?" |
| 2020-10-04 04:03:36 | <zoom> | kind of an open-ended questions but I'm in the midst of learning haskell and I'm about 2/3 through the learnyouhaskell guide. I can see the steep learning curve and I'm fine with that but I'm wondering if there's any hidden learning curves I don't forsee. for example, quirks in the language that you really only learn "on the job" after using it in |
| 2020-10-04 04:03:36 | <zoom> | a production environment. |
| 2020-10-04 04:04:00 | <zoom> | and if so, how significant those additional learning curves might be |
| 2020-10-04 04:04:21 | <c_wraith> | You can bounce hard off of some of the more high-powered libraries used in production code |
| 2020-10-04 04:05:45 | <c_wraith> | like... lenses are so useful it's hard to justify not using them on sufficiently large projects, but there's another huge upfront cost to learn. |
| 2020-10-04 04:06:17 | <cohn> | agree --^ |
| 2020-10-04 04:06:22 | <zoom> | maybe quirks isn't the right word. I guess I'm asking how deep the rabbit hole goes beyond the basic language. like undocumented or lightly documented behaviors |
| 2020-10-04 04:06:28 | <MarcelineVQ> | it is a bit of a cost, I wrote a lens library and still don't know how to use them ^^; |
| 2020-10-04 04:06:42 | × | sand_dull quits (~theuser@cpe-67-252-1-237.nycap.res.rr.com) (Ping timeout: 272 seconds) |
| 2020-10-04 04:07:10 | <c_wraith> | debugging performance issues is probably the one big thing with poor documentation. |
| 2020-10-04 04:07:34 | <hololeap> | zoom: it isn't as bad as you might think. there are some well known thorns such as lazy IO and space leaks, but overall, the scariness overshoots the actual dangers |
| 2020-10-04 04:07:47 | <c_wraith> | There are a ton of tools that are all documented individually, but there's little in the way of unified big-picture documentation for the process |
| 2020-10-04 04:08:01 | <zoom> | i actually enjoy exploring the nuances and corner-cases of languages but that seems like kids play to what I'm facing with haskell |
| 2020-10-04 04:08:22 | <c_wraith> | for the language itself, Haskell has fewer corner cases than most. |
| 2020-10-04 04:08:25 | → | sand_dull joins (~theuser@179.48.249.132) |
| 2020-10-04 04:08:37 | <c_wraith> | Unless you start turning on every type system extension you can find :) |
| 2020-10-04 04:09:21 | <hololeap> | but, then again, there are many benign language extensions that shouldn't be off-limits for a beginner |
| 2020-10-04 04:09:49 | <c_wraith> | Sure. There are lots of extensions that don't hurt anything. But *some* of them add all sorts of corner cases. |
| 2020-10-04 04:09:50 | <zoom> | for example i discovered a few of the {-# LANGUAGE ... } behaviors and the breadth of what's there is a bit scary to me |
| 2020-10-04 04:10:05 | <hololeap> | i was scared of using any language extensions when i first started, and now i see how many of them really don't hurt at all |
| 2020-10-04 04:10:55 | <zoom> | it almost seems like one has to learn or at least understand all the antecedent versions and behaviors |
| 2020-10-04 04:11:20 | <c_wraith> | *most* extensions can be learned in isolation. They're just a thing that can be added to the base language. |
| 2020-10-04 04:11:52 | <c_wraith> | There are exceptions. Functional dependencies only make any sense with multiple parameter type classes, for instance. |
| 2020-10-04 04:12:47 | <c_wraith> | But for the most part, extensions try to be focused additions to the language. |
| 2020-10-04 04:13:34 | <hololeap> | i remember seeing a list of language extensions that was sorted by relative safety |
| 2020-10-04 04:13:49 | <dolio> | You can use functional dependencies without multi-parameter classes. It means you can only write one instance. :) |
| 2020-10-04 04:14:01 | <dolio> | Like `class C a | -> a where ...` |
| 2020-10-04 04:14:24 | <c_wraith> | so... the same as just writing a function? :P |
| 2020-10-04 04:14:26 | <hololeap> | and it included which ones you could have turned on all the time without having any dangerous corner cases |
| 2020-10-04 04:14:30 | <c_wraith> | (or set thereof) |
| 2020-10-04 04:15:22 | <hololeap> | there were quite a few that were deemed totally safe, like MultiParamTypeClasses, FlexibleContexts, FlexibleInstances, LambdaCase, etc... |
| 2020-10-04 04:15:34 | <MarcelineVQ> | hololeap: search for What I Wish I Knew when learning haskell or something |
| 2020-10-04 04:15:40 | <zoom> | A comment I watched from Simon Peyton Jones scared me too - he said they put as much complication they could get away with without programmers running away. |
| 2020-10-04 04:16:04 | <hololeap> | zoom, it's well-typed complications :) |
| 2020-10-04 04:16:18 | <c_wraith> | It's useful to remember that SPJ is all about accessibility. |
| 2020-10-04 04:16:56 | <cohn> | MarcelineVQ: http://dev.stephendiehl.com/hask/ <-- great read |
| 2020-10-04 04:16:58 | × | LKoen quits (~LKoen@lstlambert-657-1-123-43.w92-154.abo.wanadoo.fr) (Remote host closed the connection) |
| 2020-10-04 04:17:20 | <hololeap> | MarcelineVQ: thank you |
All times are in UTC.