Logs: liberachat/#haskell
| 2021-05-24 00:48:21 | <mniip> | no? |
| 2021-05-24 00:48:25 | <dmwit> | For some reason I had "Heyting algebra is the right choice" as a cached thought, and I didn't critically consider it. |
| 2021-05-24 00:48:28 | <mniip> | you need the algebra to be boolean |
| 2021-05-24 00:48:41 | <mniip> | so that the only objects are top and bottom |
| 2021-05-24 00:48:47 | <mniip> | so that `if` can make a choice |
| 2021-05-24 00:49:41 | <dmwit> | A test for bottom-ness (or top-ness) should be sufficient. |
| 2021-05-24 00:49:52 | → | eggplantade joins (~Eggplanta@108-201-191-115.lightspeed.sntcca.sbcglobal.net) |
| 2021-05-24 00:50:10 | <dmwit> | I don't see a reason to restrict it to algebras with only a top and bottom. |
| 2021-05-24 00:50:27 | <dmwit> | The choice of whether bottom or top controlled which branch you took would be pretty arbitrary, of course. |
| 2021-05-24 00:51:41 | <dmwit> | Or... hm. |
| 2021-05-24 00:54:26 | <jaevanko> | Sometimes I wonder if it would be practical for Applicative instances to automatically lift things with pure/fmap/liftA2, so e.g. [1, 2, 3] + 4 would get lifted to (liftA2 (+) [1, 2, 3] (pure 4)). Could somebody convince me this is a horrible idea? |
| 2021-05-24 00:54:47 | <jaevanko> | Maybe in a language that isn't Haskell... |
| 2021-05-24 00:54:49 | <dmwit> | I guess one choice would be to have a class for ultrafilters, and use that to have an `if` with about the same typing rules as usual except the first thing is class-polymorphic. Or you could do something wilder, like `class If a where type family Branch a b; if' :: a -> b -> b -> Branch a b` + some laws. |
| 2021-05-24 00:54:53 | × | eggplantade quits (~Eggplanta@108-201-191-115.lightspeed.sntcca.sbcglobal.net) (Ping timeout: 272 seconds) |
| 2021-05-24 00:54:54 | <sclv> | jaevanko: there's a slightly more verbose notion of this called "idiom brackets" |
| 2021-05-24 00:55:00 | <sclv> | which is how applicative was first introduced |
| 2021-05-24 00:55:11 | × | boxscape quits (4ff0bb95@user/boxscape) (Quit: Connection closed) |
| 2021-05-24 00:55:25 | <sclv> | also there's work on "effectful languages" like frank and a few others that have this sort of approach |
| 2021-05-24 00:55:55 | <sclv> | so i'd say its not a bad impulse, and it underlay some of the initial work on the abstraction, but getting it Right and Nice and Usable turned out to be a high bar |
| 2021-05-24 00:56:13 | → | boxscape joins (4ff0bb95@user/boxscape) |
| 2021-05-24 00:56:17 | <dmwit> | jaevanko: It's a great idea, with one exception: functions are a monad, and this gets in the way a surprising amount, because you constantly have to decide whether each arrow is a monad thing or no (so you know whether to lift it). |
| 2021-05-24 00:56:28 | × | exzeta__ quits (~exzeta@client-8-84.eduroam.oxuni.org.uk) (Remote host closed the connection) |
| 2021-05-24 00:56:42 | <jaevanko> | sclv: I was kind of thinking of it from the perspective of Julia/matlab/etc where array operations lift naturally to any number of dimensions, just beefed up a bit |
| 2021-05-24 00:56:48 | <dmwit> | jaevanko: Lightweight Monadic Programming in OCaml develops the idea fully, and even goes as far as supporting automatic insertion of `lift` (from monad transformers), but doesn't allow the arrow monad. |
| 2021-05-24 00:57:18 | <jaevanko> | dmwit: Yeah, I had some big issues when I defined a Num instance on ((->) a) :/ |
| 2021-05-24 00:57:22 | <jaevanko> | I might have that arrow backwards |
| 2021-05-24 00:57:49 | <dmwit> | Oh, I like that instance a lot! What issues did you have? ...perhaps user-reading-code issues? |
| 2021-05-24 00:58:17 | <dmwit> | jaevanko: (In fact, you can do `instance Num a => Num (F a)` for any `Applicative F`.) |
| 2021-05-24 00:58:36 | <jaevanko> | It could very well be a pebcak issue, but I think it was some type errors |
| 2021-05-24 01:00:03 | <dmwit> | % instance Num a => Num (b -> a) where (+) = liftA2 (+); (-) = liftA2 (-); (*) = liftA2 (*); negate = fmap negate; abs = fmap abs; signum = fmap signum; fromInteger = pure . fromInteger |
| 2021-05-24 01:00:03 | <yahb> | dmwit: |
| 2021-05-24 01:00:19 | <dmwit> | % sqrt (sin^2 + cos^2) 42 |
| 2021-05-24 01:00:19 | <yahb> | dmwit: ; <interactive>:157:1: error:; * No instance for (Floating (Double -> Double)) arising from a use of `it'; (maybe you haven't applied a function to enough arguments?); * In the first argument of `print', namely `it'; In a stmt of an interactive GHCi command: print it |
| 2021-05-24 01:00:21 | × | heath quits (~heath@68.68.64.38) (Ping timeout: 244 seconds) |
| 2021-05-24 01:00:36 | <dmwit> | % (sin^2 + cos^2) 42 |
| 2021-05-24 01:00:36 | <yahb> | dmwit: 1.0 |
| 2021-05-24 01:00:57 | → | merijn joins (~merijn@83-160-49-249.ip.xs4all.nl) |
| 2021-05-24 01:00:59 | <jaevanko> | Yeah, that's the kinda stuff I was trying |
| 2021-05-24 01:01:19 | <jaevanko> | Starts to look almost like forth at that point, which could be kinda neat |
| 2021-05-24 01:02:15 | <boxscape> | % map (3 * id^2 + id) [-3..3] |
| 2021-05-24 01:02:15 | <yahb> | boxscape: [24,10,2,0,4,14,30] |
| 2021-05-24 01:02:15 | <jaevanko> | Maybe I'm just being pessimistic, but it feels like making everything automatically generalize to Functor+Applicative is asking for type to be undecidable |
| 2021-05-24 01:03:13 | → | zaraksidd94 joins (6f77bb2b@107.161.19.109) |
| 2021-05-24 01:03:20 | <dmwit> | Sure. But having everything automatically generalize for each of the existing Functor+Applicative is fine. ^_^ |
| 2021-05-24 01:03:39 | <jaevanko> | boxscape: if there was a Num instance for [a] could that be written (3 * id^2 + id) [-3..3] without the explicit map? |
| 2021-05-24 01:03:47 | × | geekosaur quits (~geekosaur@069-135-003-034.biz.spectrum.com) (Remote host closed the connection) |
| 2021-05-24 01:03:48 | → | allbery_b joins (~geekosaur@069-135-003-034.biz.spectrum.com) |
| 2021-05-24 01:03:56 | <jaevanko> | How do you mean? |
| 2021-05-24 01:04:15 | <dmwit> | (...and having everything automatically generalize to Functor+Applicative+Monad is also fine, but you need a different type inference algorithm than the one currently in GHC.) |
| 2021-05-24 01:04:29 | <jaevanko> | Like the set of Applicatives in base is fine, or law-abiding Applicative? |
| 2021-05-24 01:04:52 | <boxscape> | jaevanko not sure |
| 2021-05-24 01:04:54 | → | abrar joins (~abrar@static-108-30-103-121.nycmny.fios.verizon.net) |
| 2021-05-24 01:05:16 | <jaevanko> | % instance Num a => Num [a] where (+) = liftA2 (+); (-) = liftA2 (-); (*) = liftA2 (*); negate = fmap negate; abs = fmap abs; signum = fmap signum; fromInteger = pure . fromInteger |
| 2021-05-24 01:05:19 | <dmwit> | jaevanko: I mean if instead of `instance (Applicative f, Num a) => Applicative (f a)` you write `instance Num a => Num [a]` and `instance Num a => Num (b -> a)` and `instance Num a => Num (Maybe a)` and and and... |
| 2021-05-24 01:05:54 | <dmwit> | % (3*id^2 + id) [-3..3] |
| 2021-05-24 01:05:54 | <yahb> | dmwit: ; <interactive>:161:1: error:; * No instance for (Num [Integer]) arising from a use of `it'; * In the first argument of `print', namely `it'; In a stmt of an interactive GHCi command: print it |
| 2021-05-24 01:06:07 | <jaevanko> | Oh gotcha. Or if those instances were automatically written by the compiler when you define a new Applicative |
| 2021-05-24 01:06:16 | <dmwit> | Oh, jaevanko you left a space before your last yahb command. |
| 2021-05-24 01:06:18 | <jaevanko> | % instance Num a => Num [a] where (+) = liftA2 (+); (-) = liftA2 (-); (*) = liftA2 (*); negate = fmap negate; abs = fmap abs; signum = fmap signum; fromInteger = pure . fromInteger |
| 2021-05-24 01:06:18 | <yahb> | jaevanko: |
| 2021-05-24 01:06:25 | <jaevanko> | % (3*id^2 + id) [-3..3] |
| 2021-05-24 01:06:26 | <yahb> | jaevanko: [24,25,26,27,28,29,30,15,16,17,18,19,20,21,6,7,8,9,10,11,12,-3,-2,-1,0,1,2,3,-12,-11,-10,-9,-8,-7,-6,-21,-20,-19,-18,-17,-16,-15,-30,-29,-28,-27,-26,-25,-24,15,16,17,18,19,20,21,9,10,11,12,13,14,15,3,4,5,6,7,8,9,-3,-2,-1,0,1,2,3,-9,-8,-7,-6,-5,-4,-3,-15,-14,-13,-12,-11,-10,-9,-21,-20,-19,-18,-17,-16,-15,6,7,8,9,10,11,12,3,4,5,6,7,8,9,0,1,2,3,4,5,6,-3,-2,-1,0,1,2,3,-6,-5,-4,-3,-2,-1,0,-9,-8,-7,-6,- |
| 2021-05-24 01:06:42 | <jaevanko> | Oh right, liftA2 on list does permutations |
| 2021-05-24 01:06:44 | × | Deide quits (~Deide@user/deide) (Quit: Seeee yaaaa) |
| 2021-05-24 01:07:00 | <dmwit> | % instance Num a => Num (ZipList a) where (+) = liftA2 (+); (-) = liftA2 (-); (*) = liftA2 (*); negate = fmap negate; abs = fmap abs; signum = fmap signum; fromInteger = pure . fromInteger |
| 2021-05-24 01:07:00 | <yahb> | dmwit: |
| 2021-05-24 01:07:10 | <dmwit> | % (3*id^2 + id) (ZipList [-3..3]) |
| 2021-05-24 01:07:10 | <yahb> | dmwit: ZipList {getZipList = [24,10,2,0,4,14,30]} |
| 2021-05-24 01:07:36 | <dmwit> | Okay, I admit I'm slightly puzzled by that. |
| 2021-05-24 01:07:37 | <ski> | i don't believe in the "automatically lift/generalize" thing. but i think the basic instinct is sound |
| 2021-05-24 01:07:38 | <jaevanko> | Though I suppose if you had a list type that was parameterized over its length at the type level... |
| 2021-05-24 01:07:45 | drewolson1 | is now known as drewolson |
| 2021-05-24 01:08:11 | <dmwit> | Oh, no I'm not, I just can't count. |
| 2021-05-24 01:08:25 | <jaevanko> | Lol, I was expecting 3 too |
| 2021-05-24 01:09:02 | → | ddellacosta joins (~ddellacos@86.106.121.23) |
| 2021-05-24 01:09:10 | <jaevanko> | I can only imagine the type errors this could bring :D |
| 2021-05-24 01:09:14 | → | hmmmas joins (~chenqisu1@183.217.200.8) |
| 2021-05-24 01:09:26 | <dmwit> | Pfffft, waaaay more things typecheck this way! ^_^ |
| 2021-05-24 01:09:33 | <ski> | (my "reflective effectful syntax" was inspired by idiom brackets (and some other things)) |
| 2021-05-24 01:10:11 | <jaevanko> | ski: is that something I could search for on the web? I'm accruing reading materials rn |
| 2021-05-24 01:10:25 | <ski> | .. not really |
| 2021-05-24 01:10:34 | <jaevanko> | This whole diversion was inspired by this: conal.net/blog/posts/beautiful-differentiation, btw |
| 2021-05-24 01:10:36 | <ski> | it mostly exists in my head |
| 2021-05-24 01:10:43 | × | xff0x quits (~xff0x@2001:1a81:52b2:9700:e0dc:1f9b:63de:5b34) (Ping timeout: 272 seconds) |
| 2021-05-24 01:10:53 | <jaevanko> | I know the feeling |
| 2021-05-24 01:11:49 | → | eggplantade joins (~Eggplanta@108-201-191-115.lightspeed.sntcca.sbcglobal.net) |
| 2021-05-24 01:12:08 | → | xff0x joins (~xff0x@2001:1a81:52e8:5900:fcc8:4950:4702:a177) |
| 2021-05-24 01:12:25 | <boxscape> | ski and in #haskell IRC logs :P |
| 2021-05-24 01:12:35 | <jaevanko> | Is the idiom brackets terminology the reason the infix applicative functions are all <>-y? |
| 2021-05-24 01:12:51 | <ski> | (there's still some things i'd like to work out with it .. and choosing some workable concrete syntax would be nice. but i think the basic idea is sound (and better than idiom brackets)) |
| 2021-05-24 01:13:11 | <ski> | jaevanko : hm. good question. i suspect not |
| 2021-05-24 01:13:24 | <ski> | boxscape : yes |
| 2021-05-24 01:13:42 | <dmwit> | jaevanko: They are all <>-y because the papers introducing Applicative used a diamond around its operators. |
| 2021-05-24 01:13:43 | × | ddellacosta quits (~ddellacos@86.106.121.23) (Ping timeout: 265 seconds) |
| 2021-05-24 01:13:58 | <jaevanko> | Simple enough, I suppose |
| 2021-05-24 01:14:10 | ski | would have guessed a circle |
| 2021-05-24 01:14:15 | <boxscape> | jaevanko this is the original paper about idiom brackets - they originally used double square brackets, a bit like [[ ]] |
| 2021-05-24 01:14:16 | <boxscape> | https://www.staff.city.ac.uk/~ross/papers/Applicative.pdf |
| 2021-05-24 01:14:24 | → | killsushi joins (~killsushi@user/killsushi) |
| 2021-05-24 01:14:37 | <boxscape> | well, not just about idiom brackets |
All times are in UTC.