Logs: liberachat/#haskell
| 2021-07-09 02:42:31 | → | hmmmas joins (~fidnc@183.217.200.144) |
| 2021-07-09 02:42:48 | <safinaskar> | pavonia: yes. but megaparsec doesn't support unbiased choice |
| 2021-07-09 02:43:30 | <glguy> | safinaskar: happy has no trouble being used with tokens that have line and also column information |
| 2021-07-09 02:44:35 | × | dragestil quits (~quassel@user/dragestil) (Ping timeout: 252 seconds) |
| 2021-07-09 02:45:28 | <glguy> | There's an example here where *parsing* fails because a name wasn't declared, but it think it's a lot nicer for the user if things like that don't break parsing. Once you've parsed the syntax you can then find all the problems at once and things like scope and typing, etc, don't have to be passing to know that the syntax is OK |
| 2021-07-09 02:46:04 | → | dragestil joins (~quassel@user/dragestil) |
| 2021-07-09 02:46:24 | <pavonia> | safinaskar: Why is unbiased choice better than biased choice? |
| 2021-07-09 02:46:45 | <Axman6> | yeah I would have thought that often you know which bias you want |
| 2021-07-09 02:47:12 | <c_wraith> | Nah, biased choice without backtracking is terrible. You constantly have to refactor your grammar around the parser limitations |
| 2021-07-09 02:47:42 | <glguy> | I generally find it's a liability when you start computing inside your parser, which is a problem with most examples of parser-combinators uses |
| 2021-07-09 02:47:58 | <glguy> | the grammar gets lost in the midst of the computation |
| 2021-07-09 02:48:04 | <Axman6> | safinaskar: Good news, the haddocks have appeared on hackage :) |
| 2021-07-09 02:49:13 | <glguy> | Unbiased choice parsing was handy on this year's Advent of Code; it saved me from having to think too hard when going for quick completion |
| 2021-07-09 02:54:14 | <qrpnxz> | > • Could not deduce: ((n1 + m) + 1) ~ (n + m) |
| 2021-07-09 02:54:14 | <qrpnxz> | > from the context: n ~ (n1 + 1) |
| 2021-07-09 02:54:15 | <qrpnxz> | rip |
| 2021-07-09 02:54:15 | <lambdabot> | <hint>:1:1: error: parse error on input ‘•’ |
| 2021-07-09 02:54:15 | <lambdabot> | error: |
| 2021-07-09 02:54:15 | <lambdabot> | Pattern syntax in expression context: ~(n1 + 1) |
| 2021-07-09 02:55:11 | → | bitmapper joins (uid464869@id-464869.tooting.irccloud.com) |
| 2021-07-09 02:55:40 | <Axman6> | yeah you need to be quite careful about how you structure types with nats, sometimes just changing the order of the arguments can help. I think there are also GHC plugins which can resolve things which are obviously true |
| 2021-07-09 02:56:07 | → | cmburnett joins (~cmburnett@c-73-37-184-238.hsd1.mn.comcast.net) |
| 2021-07-09 02:56:49 | ← | cmburnett parts (~cmburnett@c-73-37-184-238.hsd1.mn.comcast.net) () |
| 2021-07-09 02:57:20 | <safinaskar> | glguy: "happy has no trouble being used with tokens that have line and also column information" - yes, but then you have to manually combine this location information. For example, using (<-->) from srcloc. And you should do this in every happy production. My library does this automatically |
| 2021-07-09 02:58:47 | → | fizbin joins (~fizbin@c-73-33-197-160.hsd1.nj.comcast.net) |
| 2021-07-09 03:00:03 | <safinaskar> | glguy: "but it think it's a lot nicer for the user if things like that don't break parsing" - fully agree. My library (thanks to power of arrows) allow you to check you for parsing errors and then (if there is no parsing errors) check semantic errors. In other words parsing code is mixed/ |
| 2021-07-09 03:00:54 | <safinaskar> | glguy: in other words, parsing code is mixed/interleaved, but thanks to arrow power, when you actually run parser (in "main") you check for parsing errors and then other errors!!! |
| 2021-07-09 03:01:58 | <Axman6> | trifecta adds location information by default right? |
| 2021-07-09 03:03:29 | × | fizbin quits (~fizbin@c-73-33-197-160.hsd1.nj.comcast.net) (Ping timeout: 255 seconds) |
| 2021-07-09 03:05:25 | → | andreabedini joins (~andreabed@8s8kj6nl13s474s8p7bh.ip6.superloop.com) |
| 2021-07-09 03:06:11 | <glguy> | putting code into the parser isn't great, but that's nice that it helps with locations |
| 2021-07-09 03:08:15 | <safinaskar> | pavonia: "Why is unbiased choice better than biased choice?" - because unbiased choice captures my parsing intuition. And I think it captures parsing intuition of everybody else. I once had one tragedy: I created grammar for my language. In my head this grammar used unbiased choice, i. e. in my mental map the choice was unbiased. Then I converted this my mental map to code. To parsec code. Which uses |
| 2021-07-09 03:08:21 | <safinaskar> | biased choice. The code worked. I wrote lot of code in this my new language. But then I discovered that original grammar (with unbiased choice) was ambiguous! But when I converted it to parsec code, the ambiguity vanished! So, the actual parser simply stick to particular choices, and I don't know to which! So all code in this my new language was possibly ambiguous! |
| 2021-07-09 03:08:21 | × | mei quits (~mei@user/mei) (Ping timeout: 252 seconds) |
| 2021-07-09 03:09:51 | <safinaskar> | pavonia: well, again: i think biased is counter-intuitive. Also, definitions of many languages use unbiased choice |
| 2021-07-09 03:10:09 | × | dragestil quits (~quassel@user/dragestil) (Read error: Connection reset by peer) |
| 2021-07-09 03:11:09 | → | mei joins (~mei@user/mei) |
| 2021-07-09 03:15:09 | × | P1RATEZ quits (piratez@user/p1ratez) (Remote host closed the connection) |
| 2021-07-09 03:18:23 | → | yauhsien joins (~yauhsien@61-231-39-135.dynamic-ip.hinet.net) |
| 2021-07-09 03:32:53 | <qrpnxz> | i found out how to do existential with data by the way :) |
| 2021-07-09 03:34:33 | → | warnz joins (~warnz@2600:1700:77c0:5610:edd9:472d:4b89:9ab8) |
| 2021-07-09 03:34:51 | <qrpnxz> | this is epic |
| 2021-07-09 03:35:40 | <lechner> | Hi, are emails for hackage account registration sent with a delay? |
| 2021-07-09 03:36:02 | <Axman6> | I believe they have to be actioned by a human |
| 2021-07-09 03:36:05 | <safinaskar> | qrpnxz: how? |
| 2021-07-09 03:36:22 | <lechner> | Axman6: ah, no rush. thanks! |
| 2021-07-09 03:36:33 | → | luna_ joins (~luna@124.205.197.98) |
| 2021-07-09 03:37:43 | <qrpnxz> | you can make something like `data SomeFoldable = forall a. Foldable f => SomeFoldable (f a)`, then you can do `deriving instance Foldable SomeFoldable`, and whatever you wrap will act like a dynamic interface type |
| 2021-07-09 03:37:45 | <qrpnxz> | it's pretty nice |
| 2021-07-09 03:39:02 | × | warnz quits (~warnz@2600:1700:77c0:5610:edd9:472d:4b89:9ab8) (Ping timeout: 252 seconds) |
| 2021-07-09 03:39:12 | <glguy> | Do you mean: data SomeFoldable a = ... ? |
| 2021-07-09 03:39:19 | <qrpnxz> | yeah oops |
| 2021-07-09 03:41:08 | × | norias quits (~jaredm@c-98-219-195-163.hsd1.pa.comcast.net) (Ping timeout: 272 seconds) |
| 2021-07-09 03:41:37 | <qrpnxz> | for that you need DeriveFoldable, StandaloneDeriving, and ExistentialQuantification by the way |
| 2021-07-09 03:43:49 | <qrpnxz> | i wish it would just do all that for you, but oh well |
| 2021-07-09 03:44:57 | <glguy> | What're you doing that you needed that? |
| 2021-07-09 03:46:07 | <qrpnxz> | you can use this to return an interface on a function |
| 2021-07-09 03:48:07 | <monochrom> | I'm pretty sure even "data SomeFoldable a = forall a. Foldable f => SomeFoldable (f a)" is not the real code. |
| 2021-07-09 03:48:19 | <qrpnxz> | it is, it compiles |
| 2021-07-09 03:48:19 | <monochrom> | For starters, free variable f. |
| 2021-07-09 03:48:27 | <qrpnxz> | oh, i meant forall f |
| 2021-07-09 03:48:28 | <qrpnxz> | ofc |
| 2021-07-09 03:50:54 | <c_wraith> | I thought you were concerned with preventing fusion |
| 2021-07-09 03:51:31 | → | merijn joins (~merijn@83-160-49-249.ip.xs4all.nl) |
| 2021-07-09 03:52:27 | → | bontaq joins (~user@ool-18e47f8d.dyn.optonline.net) |
| 2021-07-09 03:52:30 | <qrpnxz> | I'm just saying I found how to do it |
| 2021-07-09 03:53:20 | <qrpnxz> | thx for bringing that up though, would be good to bench it |
| 2021-07-09 03:58:00 | <safinaskar> | qrpnxz: please write correct code. "f" is free |
| 2021-07-09 03:58:13 | → | oxide joins (~lambda@user/oxide) |
| 2021-07-09 03:58:34 | <qrpnxz> | already brought up, here is the corrected version `data SomeFoldable a = forall f. Foldable f => SomeFoldable (f a)` |
| 2021-07-09 04:00:01 | <safinaskar> | qrpnxz: thanks |
| 2021-07-09 04:01:00 | <safinaskar> | qrpnxz: so, SomeFoldable itself can be passed as "f", right? is this intentional? |
| 2021-07-09 04:01:18 | <qrpnxz> | idk what you mean by passed as f |
| 2021-07-09 04:02:42 | <qrpnxz> | c_wraith, seems to fuse fine. I think where you get in trouble is if you accept SomeFoldable for your function, but if you just return, the real type should always be known, and ghc can optimize for that. (And accepting SomeFoldable should never happen; should be using constraint there). |
| 2021-07-09 04:05:52 | <safinaskar> | qrpnxz: i mean that SomeFoldable can be f. i. e. you can substitute SomeFoldable as f |
| 2021-07-09 04:06:33 | <qrpnxz> | Eh, yes. |
| 2021-07-09 04:06:57 | × | slowButPresent quits (~slowButPr@user/slowbutpresent) (Quit: leaving) |
| 2021-07-09 04:07:16 | <safinaskar> | qrpnxz: is this intentional? i. e. i need this fact to understand this code? |
| 2021-07-09 04:07:25 | <Axman6> | feels related to Yoneda |
| 2021-07-09 04:08:52 | <qrpnxz> | safinaskar: It is intentional that SomeFoldable is a foldable if that's what you're asking. |
| 2021-07-09 04:09:27 | <c_wraith> | Axman6: it's just the existential typeclass antipattern |
| 2021-07-09 04:10:16 | <Axman6> | @hoogle Yoneda |
| 2021-07-09 04:10:16 | <lambdabot> | module Data.Profunctor.Yoneda |
| 2021-07-09 04:10:16 | <lambdabot> | Data.Profunctor.Yoneda newtype Yoneda p a b |
| 2021-07-09 04:10:16 | <lambdabot> | Data.Profunctor.Yoneda Yoneda :: (forall x y . (x -> a) -> (b -> y) -> p x y) -> Yoneda p a b |
| 2021-07-09 04:11:41 | <Axman6> | that was not useful |
| 2021-07-09 04:12:51 | × | Megant quits (megant@user/megant) (Read error: Connection reset by peer) |
| 2021-07-09 04:13:32 | <c_wraith> | Yoneda does something different - it captures the functionality of a class, but it doesn't wrap an unknown instance |
| 2021-07-09 04:13:45 | <c_wraith> | wait, no, I'm thinking Coyoneda |
| 2021-07-09 04:14:39 | Axman6 | muses that we need a Yoyoneda, which caputres the idea of traversing down into a structure and back up, and down again... |
| 2021-07-09 04:16:43 | × | luna_ quits (~luna@124.205.197.98) (Remote host closed the connection) |
| 2021-07-09 04:18:27 | <qrpnxz> | c_wraith, Why do you say it is an antipattern |
| 2021-07-09 04:18:49 | × | yauhsien quits (~yauhsien@61-231-39-135.dynamic-ip.hinet.net) (Ping timeout: 246 seconds) |
| 2021-07-09 04:19:47 | <c_wraith> | because hiding types like that basically always gets in the way of good code in Haskell |
| 2021-07-09 04:20:34 | <qrpnxz> | ok how |
| 2021-07-09 04:21:47 | → | hexfive joins (~eric@50.35.83.177) |
| 2021-07-09 04:25:00 | ← | safinaskar parts (~user@109-252-90-89.nat.spd-mgts.ru) () |
| 2021-07-09 04:25:31 | <qrpnxz> | i could instead return like `(a -> b -> b) -> b -> b` which would be a completely explicit type, yet reveal no new information. Because functions are abstractions, and this is also an abstraction, except it's much nicer to use imo |
| 2021-07-09 04:25:50 | × | merijn quits (~merijn@83-160-49-249.ip.xs4all.nl) (Ping timeout: 255 seconds) |
| 2021-07-09 04:29:28 | × | hexfive quits (~eric@50.35.83.177) (Quit: WeeChat 3.0) |
All times are in UTC.