Logs on 2023-12-04 (liberachat/#haskell)
| 00:00:15 | <iqubic> | I love the Church and state joke. |
| 00:00:25 | <ski> | (note that the `s' in `exists s. ..s..' there can commonly be thought of as a "state type". e.g. as in OOP. existentials is one way to encode closures, and OOP objects. one can also do ADTs (abstract data types) with existentials, but that's a quite distinct use of them) |
| 00:00:30 | → | JeremyB99 joins (~JeremyB99@2600:1702:21b0:a500:b427:1e7a:fffe:f069) |
| 00:01:09 | <iqubic> | Do we even actually care about Yoneda and Coyoneda? |
| 00:01:23 | × | JeremyB99 quits (~JeremyB99@2600:1702:21b0:a500:b427:1e7a:fffe:f069) (Read error: Connection reset by peer) |
| 00:01:25 | <EvanR> | we like to combine the church and the curry |
| 00:01:55 | <ski> | practically, they can be used to delay `fmap'ping over a structure, collecgting the functions to map over, so that when you finally extract, you do all the `fmap's in one pass, instead of multiple traversals |
| 00:02:08 | <ski> | iqubic ^ |
| 00:02:40 | <iqubic> | Right. That's cool. |
| 00:03:02 | <iqubic> | fmap f . fmap g = fmap (f . g) |
| 00:03:09 | <ski> | right |
| 00:03:19 | <iqubic> | that's just a functor law. |
| 00:03:29 | <ski> | and `Codensity' does something similar, for left-associated uses of `(>>=)' |
| 00:03:54 | <ski> | this is similar to "difference lists", btw |
| 00:04:17 | <ski> | (or keeping an extra accumulator parameter, to avoid having to add stuff to the end of a list, repeatedly) |
| 00:04:28 | <iqubic> | runCodensity :: forall b. (a -> m b) -> m b |
| 00:05:01 | <iqubic> | That's the sole constructor for a Codensity m a |
| 00:05:21 | × | pretty_dumm_guy quits (trottel@gateway/vpn/protonvpn/prettydummguy/x-88029655) (Quit: WeeChat 3.5) |
| 00:05:28 | <ski> | iqubic : consider a recursive definition like `data List a = Nil | Cons a (List a)'. we could "algebraically" write this as `List a = 1 + a * List a' |
| 00:06:02 | <iqubic> | I agree. That's why we call it an ADT. |
| 00:06:10 | <ski> | yea, basically |
| 00:06:22 | <geekosaur> | @quote getSum.*sleep |
| 00:06:22 | <lambdabot> | jle` says: let sleep = pure "zzz" in getSum sleep |
| 00:06:28 | <iqubic> | The A stands for Algebraic. |
| 00:07:12 | <ski> | now lets say we only really consider the *finite* length lists here. looking at `List a = 1 + a * List a', this is an equation in `List a', that has multiple solutions, though. one is the finite-length lists (this is the least solution). another is the possibly-finite streams (including infinite ones) (this is the greatest solution) |
| 00:07:38 | <iqubic> | Yeah, that makes sense. |
| 00:08:08 | <ski> | in order to be clear about which one we want, and to avoid having to write a recursive equation, we have notation where the least solution is written `mu r. 1 + a * r', and the greatest solution is written `nu r. 1 + a * r' |
| 00:08:41 | <ski> | so, for the least, we get `List a = mu r. 1 + a * r', and for the greatest, we get `List a = nu r. 1 + a * r' |
| 00:08:45 | <EvanR> | runCodensity :: Codensity m a -> (forall b. (a -> m b) -> m b) |
| 00:08:48 | <iqubic> | Oh, that's a clever way to disambiguate the solutions. |
| 00:09:00 | <ski> | think of `mu r. ..r..' and `nu r. ..r..' as being similar to `fix (\r -> ..r..) |
| 00:09:16 | <iqubic> | I already kinda assumed that. |
| 00:09:34 | <ski> | in (although, denotationally speaking, in Haskell, `fix' computes the least fixed point) |
| 00:10:21 | <ski> | iqubic : anyway, there are now useful ways in which we can refactor recursive types, expressed as `mu' (least) or `nu' (greatest) fixed points |
| 00:10:35 | <iqubic> | There are? |
| 00:10:47 | → | JeremyB99 joins (~JeremyB99@2600:1702:21b0:a500:b427:1e7a:fffe:f069) |
| 00:10:59 | <ski> | specifically, `mu r. ..r..' is equivalent to `forall r. (..r.. -> r) -> r', and `nu s. ..s..' is equivalent to `exists s. (s,s -> ..s..)' |
| 00:11:32 | <ski> | let's take `mu r. 1 + a * r', aka `List a', from above. this would then be equivalent to `forall r. (1 + a * r -> r) -> r' |
| 00:11:34 | × | JeremyB99 quits (~JeremyB99@2600:1702:21b0:a500:b427:1e7a:fffe:f069) (Read error: Connection reset by peer) |
| 00:12:11 | <iqubic> | Hmm... That makes sense. |
| 00:12:17 | <ski> | but `X + Y -> Z' is equivalent to `(X -> Z) * (Y -> Z)' (`o^(m+n) = o^m * o^n') |
| 00:12:35 | <ski> | so, that gets us to `forall r. (1 -> r) * (a * r -> r) -> r' |
| 00:12:57 | → | lg1889 joins (~lg188@82.18.98.230) |
| 00:13:02 | × | lg188 quits (~lg188@82.18.98.230) (Read error: Connection reset by peer) |
| 00:13:03 | lg1889 | is now known as lg188 |
| 00:13:04 | <iqubic> | I see how that works. |
| 00:13:23 | <ski> | now we can use currying. `1 -> Z' is equivalent to `Z' (`o^1 = o'), and `X * Y -> Z' is equivalent to `X -> Y -> Z' (`o^(m*n) = (o^n)^m') |
| 00:13:50 | <iqubic> | I follow you there. |
| 00:13:56 | <ski> | that gets us to `forall r. r * (a -> r -> r) -> r'. and if we uncurry the outer function type, we get `forall r. r -> (a -> r -> r) -> r' |
| 00:14:00 | <ski> | now, look at |
| 00:14:20 | <ski> | foldr :: (a -> r -> r) -> r -> [a] -> r |
| 00:14:43 | <iqubic> | Those two are very similar. |
| 00:14:46 | <ski> | flip foldr :: r -> (a -> r -> r) -> [a] -> r |
| 00:15:19 | <ski> | flip . flip foldr :: r -> [a] -> (a -> r -> r) -> r |
| 00:15:32 | <ski> | flip (flip . flip foldr) :: [a] -> r -> (a -> r -> r) -> r |
| 00:15:35 | <ski> | which is really |
| 00:15:42 | <ski> | flip (flip . flip foldr) :: forall a. forall r. [a] -> r -> (a -> r -> r) -> r |
| 00:15:46 | <ski> | which can be rewritten as |
| 00:15:56 | <ski> | flip (flip . flip foldr) :: forall a. [a] -> (forall r. r -> (a -> r -> r) -> r) |
| 00:16:11 | <iqubic> | Oh... That's really cool. |
| 00:16:31 | <ski> | (since `... -> forall a. ..a..' is equivalent to `forall a. (... -> ..a..)' .. and `(exists a. ..a..) -> ...' is equivalent to `forall a. (..a.. -> ...)') |
| 00:16:35 | <iqubic> | I'm shocked that the algebra woks like that. |
| 00:17:07 | <ski> | so, `foldr' basically converts from `List a' to the form `forall r. r -> (a -> r -> r) -> r)' |
| 00:17:08 | × | picnoir quits (~picnoir@about/aquilenet/vodoo/NinjaTrappeur) (Ping timeout: 268 seconds) |
| 00:17:28 | <ski> | @type GHC.Base.build |
| 00:17:28 | <lambdabot> | (forall b. (a -> b -> b) -> b -> b) -> [a] |
| 00:17:37 | <ski> | is a function that does the opposite |
| 00:17:40 | <ski> | defined as |
| 00:17:47 | <ski> | build f = f (:) [] |
| 00:18:15 | <iqubic> | Oh, that's really cool |
| 00:19:25 | <ski> | and there's specialization rules in GHC, amounting to `build' being inverse of `foldr' (and vice versa). namely `foldr cons nil (build f) = f cons nil' -- this is used for a type of "list fusion optimization" where we skip constructing intermediate lists, if we're going to `foldr' on them. we pass the `cons' (callback) and `nil' (starting point) directly to the "builder" `f' function |
| 00:19:37 | <iqubic> | foldr and build are just converting between the two types. I think [a] and forall r. r -> (a -> r -> r) -> r) are isomorphic |
| 00:19:43 | <ski> | yes |
| 00:19:47 | × | johnw quits (~johnw@69.62.242.138) (Quit: ZNC - http://znc.in) |
| 00:20:19 | → | clwif^ joins (~cd@c-98-242-74-66.hsd1.ga.comcast.net) |
| 00:20:59 | <ski> | so, many of the list-producing functions are "good producers" meaning they produce their output lists by calling `build', and many of the list-consuming functions are "good consumers" meaning they consume their input lists by calling `foldr' on them |
| 00:21:19 | <ski> | (of course, many functions are both producers and consumers of lists, and so would use both `build' and `foldr') |
| 00:21:19 | <iqubic> | That's really cool to know. And I know that there are many functions like this. |
| 00:21:26 | <iqubic> | @type maybe |
| 00:21:27 | <lambdabot> | b -> (a -> b) -> Maybe a -> b |
| 00:21:40 | <ski> | @type either |
| 00:21:41 | <lambdabot> | (a -> c) -> (b -> c) -> Either a b -> c |
| 00:21:52 | <iqubic> | Yeah. Those work in the same way. |
| 00:22:19 | <iqubic> | Those are the cosumers for Maybe a and Either a b |
| 00:22:29 | → | travgm joins (~travgm@2600:100e:a121:d6af:56b:4880:133:700e) |
| 00:22:54 | <ski> | they are the folds/catamorphisms, for `Maybe' and `Either', just as `foldr' is the one for `[]', yes |
| 00:23:26 | <iqubic> | Right. Catamorpism was the word I was thinking of. |
| 00:23:46 | × | wroathe quits (~wroathe@user/wroathe) (Quit: leaving) |
| 00:23:56 | <ski> | (they also happen to be the "case" functions for `Maybe' and `Either'. `foldr' is not the "case" function for `[]', because `[]' is recursive. its case would have type `(a -> [a] -> r) -> r -> [a] -> r', with `[a]' rather than `r' as argument type in the callback) |
| 00:24:13 | <iqubic> | @type unfoldr |
| 00:24:14 | <ski> | catamorphisms "tear down structure". anamorphisms "build up structure" |
| 00:24:14 | <lambdabot> | (b -> Maybe (a, b)) -> b -> [a] |
| 00:24:39 | × | eggplantade quits (~Eggplanta@2600:1700:38c5:d800:d9f3:ec2f:a760:e0fe) (Remote host closed the connection) |
| 00:24:43 | <ski> | yes, if we think of `[a]' as the greatest fixed point, then that `unfoldr' is its unfold/anamorphism |
| 00:24:45 | <iqubic> | I assume that unfoldr uses build somehow? |
| 00:25:21 | → | mobivme joins (~mobivme@112.201.111.217) |
| 00:25:23 | <ski> | note that `(s -> Maybe (a,s)) -> s -> [a]' may be more suggestive, thinking of `s' as a "state" or "seed" (think like random-generator seed, e.g.) type |
| 00:25:30 | <ski> | hm, dunno |
| 00:25:46 | × | misterfish quits (~misterfis@87.215.131.102) (Ping timeout: 245 seconds) |
| 00:26:07 | <ski> | anyway, say you take now `data Stream a = Cons {head :: a,tail :: Stream a}', abstractly `Steram a = a * Stream a'. here we definitely want the greatest fixed point interpretation (since there are no finite streams here, and so there would be zero finite values) |
| 00:26:21 | <ski> | so, `Stream a = nu s. a * s' |
| 00:26:36 | × | travgm quits (~travgm@2600:100e:a121:d6af:56b:4880:133:700e) (Ping timeout: 245 seconds) |
| 00:26:36 | × | chomwitt quits (~chomwitt@2a02:587:7a09:c300:1ac0:4dff:fedb:a3f1) (Ping timeout: 245 seconds) |
| 00:27:06 | <iqubic> | This uses nu instead of mu, because there are no least fixed points. |
| 00:27:16 | <ski> | if we expand this, using the equivalence above, we get `exists s. s * (s -> a * s)' .. the first `s' part is the "object instance state". the second part is a "method" taking the instance state, and produces an output of type `a', and a new instance state |
| 00:27:43 | <ski> | well, the least fixed point exists, but is empty, not interesting |
| 00:27:49 | <ski> | (is basically `Void') |
| 00:28:11 | <iqubic> | Yes, that's kinda what I meant, but you phrased it much better. |
| 00:29:11 | <iqubic> | How does using `exsist s. s * (s -> a * s)` change things? We have `exists' now, instead of `forall' |
| 00:30:08 | <ski> | now, imagine we want to represent a type of queues, of elements of type `a'. a `Queue a' has some private internal state (of unknown/forgotten/hidden/abstract/opaque/skolem type) `s', and some methods. namely one for enequeueing an `a' onto the queue, and one for dequeueing an `a' from the queue (if it's non-empty, otherwise we get a failure indication) |
| 00:31:04 | <ski> | this suggests `Queue a' should be `exists q. q * (a * q -> q) * (q -> Maybe (q * a))' (enqueue to the left, dequeue from the right) |
| 00:31:44 | <iqubic> | Sure. That's a reasonable guess to make. |
| 00:31:48 | <ski> | iqubic : yes. a value of type `forall a. ..a..' is a polymorphic value, works for *all* possible specific choices of type to use for `a', that the user/caller may pick |
| 00:32:12 | <iqubic> | I know that. |
| 00:32:24 | <ski> | while the producer/implementor must make sure that the code works for all possible `a', doesn't attempt to look into values of type `a', doesn't assume anything about the type |
| 00:32:25 | <iqubic> | But thanks for clarifying |
| 00:33:01 | <iqubic> | So, we're trying to model these queues. |
| 00:33:31 | <ski> | while, for a value of type `exists a. ..a..', this is an "abstract" value, we know there is *some* type `a', but we don't know which. the user/caller/consumer now must be prepared to handle all possible types, for `a', can't make assumptions about `a', does *not* get to pick `a'. instead, the producer/implementor/callee gets to pick `a' |
| 00:34:19 | <ski> | so, in `[exists a. ..a..]', the different elements in the list may have picked different `a's, so you can't assume them to be compatible. only within a single `exists a. ..a..' can you asssume the `a's are the same |
| 00:34:47 | <ski> | and, in `String -> Int -> IO (exists a. ..a..)', the choice of which `a' to use may depend on the arguments, and also in this case on the I/O interaction |
| 00:34:51 | <iqubic> | Oh! That's a really good way to explain the difference. |
| 00:35:30 | <ski> | basically, `exists' and `forall' are "opposite", wrt requirements and capabilities, as it pertains to user/caller/consumer vs. implementor/callee/producer |
| 00:35:40 | → | picnoir joins (~picnoir@about/aquilenet/vodoo/NinjaTrappeur) |
| 00:35:55 | <iqubic> | I get that now. |
| 00:36:07 | <ski> | for `exists', callee picks, and caller must handle any choice. for `forall', callee must handle any choice, and caller picks |
| 00:36:15 | <ski> | ok |
| 00:36:23 | <ski> | so, let's imagine |
| 00:36:37 | <ski> | data Queue a = MkQueue (exists q. q * (a * q -> q) * (q -> Maybe (q * a))) |
| 00:36:42 | <ski> | this means that |
| 00:36:54 | <ski> | MkQueue :: (exists q. q * (a * q -> q) * (q -> Maybe (q * a))) -> Queue a |
| 00:37:23 | <ski> | but, according to the equivalence between `(exists a. ..a..) -> ...' and `forall a. (..a.. -> ...)', this ought to be the same as |
| 00:37:26 | <iqubic> | Sure. I'd buy that. |
| 00:37:42 | <ski> | MkQueue :: forall q. q * (a * q -> q) * (q -> Maybe (q * a)) -> Queue a |
| 00:37:48 | <ski> | which we now can uncurry as |
| 00:38:01 | <ski> | MkQueue :: forall q. q -> (a -> q -> q) -> (q -> Maybe (q * a)) -> Queue a |
| 00:38:10 | [itchyjunk] | is now known as [itchTheIndiffer |
| 00:38:56 | <ski> | which we now can express in actuall Haskell (using the `ExistentialQuantification' extension (imho a misnomer, something like `ExistentialConstructors' would be a better name. i'd prefer to have `ExistentialQuantification' available for a real `exists' keyword)) |
| 00:39:21 | <ski> | data Queue a = forall q. MkQueue q (a -> q -> q) (q -> Maybe (q,a)) |
| 00:39:29 | <ski> | or, with record syntax, for field names |
| 00:39:49 | <ski> | data Queue a = forall q. MkQueue {queueState :: q,enqueue :: a -> q -> q,dequeu :: q -> Maybe (q,a)} |
| 00:40:00 | <ski> | we could alternatively use `GADTs' syntax |
| 00:40:08 | <ski> | data Queue a |
| 00:40:10 | <ski> | where |
| 00:40:22 | <iqubic> | I'm familiar with how `GADTs' work. |
| 00:40:22 | <ski> | MkQueue :: q -> (a -> q -> q) -> (q -> Maybe (q,a)) -> Queue a |
| 00:41:05 | <iqubic> | That's a catamorpism for `Queue a' |
| 00:41:11 | <ski> | (anyway, this ought to explain why the `ExistentialQuantification' syntax uses the `forall' keyword .. the data constructor *is* polymorphic in the existentially quantified type variable (which does not occur in the result type, only possibly in argument types)) |
| 00:41:39 | <iqubic> | I actually think I already knew that. |
| 00:41:57 | <ski> | now, `Queue a' encapsulates one internal state of a queue, together with methods for manipulating it |
| 00:42:34 | <iqubic> | That makes sense. |
| 00:42:44 | <ski> | in practice, you'd then define wrapper methods, which extract the state, and the method implementation in question, apply it to the state (and any extra parameters), and then *rewrap* the new state with the method implementations again, producing a new `Queue a' as result |
| 00:43:19 | <ski> | and, you'd define a "class constructor", which is just a function that returns a `Queue a' |
| 00:43:24 | <iqubic> | That's just the smart thing to do. |
| 00:43:26 | <ski> | emptyQ :: Queue a |
| 00:43:48 | <ski> | emptyQ = MkQueue [] enqueue dequeue |
| 00:43:50 | <ski> | where |
| 00:43:54 | <ski> | enqueue ... = ... |
| 00:43:58 | <ski> | dequeue ... = ... |
| 00:44:02 | → | JeremyB99 joins (~JeremyB99@2600:1702:21b0:a500:b427:1e7a:fffe:f069) |
| 00:44:24 | <ski> | so that's your "class"/"class constructor". it specifies the initial state, and provides implementations for the methods |
| 00:44:37 | <iqubic> | @type uncons |
| 00:44:38 | <lambdabot> | [a] -> Maybe (a, [a]) |
| 00:44:58 | <ski> | well, the above implementation uses `[a]' for `q' .. this is inefficient, namely to add to one end of a list, and remove from the other |
| 00:45:10 | <iqubic> | I agree. |
| 00:45:10 | × | JeremyB99 quits (~JeremyB99@2600:1702:21b0:a500:b427:1e7a:fffe:f069) (Read error: Connection reset by peer) |
| 00:45:19 | <iqubic> | Using a linked list is slow. |
| 00:45:31 | <ski> | better is to use `([a],[a])' for the state type `q', basically a queue with state `(front,revBack)' represents the items in the list `front ++ reverse revBack' |
| 00:45:42 | <ski> | this is the "folklore FP" implementation of queues |
| 00:46:54 | <iqubic> | I think I actually wrote an implementation of a Queue using that representation for the Queue |
| 00:47:18 | <ski> | (once in a while, when `revBack' becomes empty, you reverse `front' and move it over to `revBack', setting the new `front' to `[]'. but that `O(n)' cost is only incurred now and them, making the amorticized cost still `O(1)' .. assuming you just keep around the newest version of the queue, not older versions. there are ways to make it efficient, even if you keep around the older ones. see "Purely Functional |
| 00:47:24 | <ski> | Data Structures" by Chris Okasaki) |
| 00:47:30 | → | johnw joins (~johnw@69.62.242.138) |
| 00:48:06 | <ski> | anyway, taking a step back to `exists q. q * (a * q -> q) * (q -> Maybe (q * a))', we can use the equivalent with the `nu' form here actually, rewriting as |
| 00:48:22 | <ski> | exists q. q * (a * q -> q) * (q -> Maybe (q * a)) |
| 00:48:34 | <ski> | = exists q. q * (a -> q -> q) * (q -> Maybe (q * a)) |
| 00:48:41 | <ski> | = exists q. q * (q -> a -> q) * (q -> Maybe (q * a)) |
| 00:48:55 | <ski> | = exists q. q * (q -> (a -> q) * Maybe (q * a)) |
| 00:49:08 | <ski> | = nu q. (a -> q) * Maybe (q * a) |
| 00:49:12 | <ski> | which now suggests |
| 00:49:48 | <ski> | data Queue a = MkQueue {enqueue :: a -> Queue a,dequeue :: Maybe (Queue a,a)} |
| 00:49:57 | <iqubic> | I used my own Queue implementation for Advent of Code one year, before I found that Containers has Data.Seq, which has a much better API and implenentation than what I made myself. |
| 00:49:58 | <ski> | (taking the greatest fixed point interpretation of this) |
| 00:50:08 | <ski> | now the instance state is hidden, inside closures |
| 00:50:18 | <iqubic> | Right. |
| 00:52:00 | <ski> | there is a similar equivalence between `a -> b' and `exists env. env * (env * a #-> b)', expressing how functions can be represented as a closure, a pair of a "(user) data"/"context"/"environment"/"config" part, and a (low-level) function (think C function pointer, or address of a subroutine in assembler) taking that, and the function argument, as input |
| 00:52:13 | <iqubic> | Data.Seq is actually a dequeue, as you can add and remove from both ends. |
| 00:52:47 | <iqubic> | I didn't know about that last equivalence! |
| 00:53:01 | <ski> | (`#->' there is known as "strict implication", in logic, btw. `a #-> b' is equivalent to `[] (a -> b)', where `[]' is read "necessary", and in this case means that it's not "cotingent", doesn't depend on run-time input, is defined statically at the top-level) |
| 00:53:45 | <ski> | in C, the `qsort' (suggesting, but not mandating, "quick sort") function, is specified as |
| 00:54:01 | <ski> | void qsort(void *base,size_t nmemb,size_t size,int (*compar)(const void *,const void *)); |
| 00:54:21 | <iqubic> | Got it. I was thinking you had randomly decided to pull in Linear Types for some reason. Good to know that's not thecate. |
| 00:54:23 | <ski> | which, if we imagine an extension of C with parametric polymorphism (and parameterized data types), would really be |
| 00:54:29 | <iqubic> | *the case |
| 00:54:54 | <ski> | forall<T> void qsort<T>(T *base,size_t nmemb,typesize_t<T> size,int (*compar)(const T *,const T *)); |
| 00:55:16 | <ski> | but better would have been to make the interface pass along a "data pointer", to be passed to the callback, as |
| 00:55:34 | <ski> | forall<T,U> void qsort<T>(T *base,size_t nmemb,typesize_t<T> size,U *env,int (*compar)(U *,const T *,const T *)); |
| 00:55:37 | <ski> | or just |
| 00:55:59 | <ski> | void qsort(void *base,size_t nmemb,size_t size,void *env,int (*compar)(void *,const void *,const void *)); |
| 00:56:02 | <ski> | in actual C |
| 00:56:35 | <ski> | because then the callback would be able to depend on run-time data, without needing to use global state (which is undesirable in the presence of multi-threading, also reentrancy) |
| 00:56:49 | <iqubic> | That does seem lake a better type signature. |
| 00:57:32 | <ski> | GTK does callbacks in this style |
| 00:57:40 | <ski> | and it's basically emulating closures |
| 00:57:44 | → | eggplantade joins (~Eggplanta@2600:1700:38c5:d800:d9f3:ec2f:a760:e0fe) |
| 00:58:28 | <ski> | if you wanted to store a closure, more long-term, you'd use something like `struct { void *data; void (*foo)(void *data,size_t n,double (*parr)[n]); }' or somesuch |
| 00:58:40 | <ski> | (or, if you add multiple function pointers in there, you get "OO objects") |
| 00:58:53 | <iqubic> | I don't know how GTK works, as I've never used it. |
| 00:59:07 | → | nate4 joins (~nate@c-98-45-158-125.hsd1.ca.comcast.net) |
| 00:59:09 | <ski> | if you check <https://www.glfw.org/docs/latest/group__input.html#ga1caf18159767e761185e49a3be019f8d> (in GLFW), this says |
| 00:59:33 | <ski> | GLFWkeyfun glfwSetKeyCallback(GLFWwindow *window,GLFWkeyfun callback); |
| 00:59:40 | <iqubic> | C isn't Object Oriented is it? |
| 00:59:56 | <ski> | where `GLFWkeyfun' is defined at <https://www.glfw.org/docs/latest/group__input.html#ga5bd751b27b90f865d2ea613533f0453c> as |
| 01:00:12 | <ski> | typedef void (*GLFWkeyfun)(GLFWwindow *window,int key,int scancode,int action,int mods) |
| 01:00:26 | <ski> | .. so it looks like these callbacks are missing the "user data" to simulate closures :( |
| 01:00:38 | <ski> | iqubic : no, but this is one way to simulate OO objects |
| 01:00:54 | <ski> | (not including implementation inheritance, that requires a bit more stuff) |
| 01:00:57 | → | wroathe joins (~wroathe@207-153-38-140.fttp.usinternet.com) |
| 01:00:57 | × | wroathe quits (~wroathe@207-153-38-140.fttp.usinternet.com) (Changing host) |
| 01:00:57 | → | wroathe joins (~wroathe@user/wroathe) |
| 01:01:21 | <ski> | however, checking <https://www.glfw.org/docs/latest/group__window.html#gae77a4add0d2023ca21ff1443ced01653>, we see |
| 01:01:37 | <ski> | void *glfwGetWindowUserPointer(GLFWwindow *window); |
| 01:01:37 | <ski> | and |
| 01:02:01 | <ski> | void glfwSetWindowUserPointer(GLFWwindow *window,void *pointer); |
| 01:02:10 | <ski> | so there the user data is ! |
| 01:02:39 | <ski> | i suspect they realized the usefulness of this later, and decided to add it like this, rather than change the existing interface for creating a window |
| 01:03:06 | <ski> | (someone pointed this about GLFW out, the other day, which is why i recalled it now) |
| 01:03:35 | <ski> | (yea, no linear types, here) |
| 01:04:09 | <ski> | anyway, i wanted to say one more thing about the queues above |
| 01:04:10 | <wroathe> | Hey guys, me again... how would I go about determining what in this loop is allocating memory, and how many times it's being constructed? https://gist.github.com/JustinChristensen/2111f13e812112b5ac973e292606d17f#file-fixfile-hs-L65-L84 I'm running a memory benchmark that shows that for a 6.8M file that has ~7M characters a single call to fixFile allocates 4.5GB worth of heap objects and GCs 1079 times. |
| 01:04:12 | × | nate4 quits (~nate@c-98-45-158-125.hsd1.ca.comcast.net) (Ping timeout: 252 seconds) |
| 01:04:16 | <wroathe> | I'd like to determine how I could run a more detailed benchmark to show exactly where those allocations are occurring... |
| 01:04:44 | → | JeremyB99 joins (~JeremyB99@2600:1702:21b0:a500:b427:1e7a:fffe:f069) |
| 01:05:31 | <wroathe> | My two theories are constructing boxed Word8 values, and constructing boxed FixedState values in this loop. My goal is to get this loop to near-native performance where the automaton keeps the state value in a single word of memory |
| 01:05:34 | <ski> | consider again `exists q. q * (a * q -> q) * (q -> 1 + a * q)' -- but this time, think of it differently. think of the first `q' part not as "current state" but as "another operation", namely one for giving an empty queue. while the other two are still "enqueue" and "dequeue" |
| 01:06:30 | <ski> | data QueueOps a = forall q. MkQueueOps {empty :: q,enqueue :: a -> q -> q,dequeue :: q -> Maybe (q,a)} |
| 01:07:17 | <ski> | iqubic : the difference now is that, instead of unwrapping, applying method, then rewrapping state, repeatedly, we now just unwrap/open the container of operations *once* at the start, then pass around "naked queue states" to the operations |
| 01:08:41 | <ski> | and this makes a real difference, since now you can have "binary operations", like e.g. taking two heaps and merging them together into one. or taking two priority queues and merging them. with the "OO view" of existentials, you have just a single object state, so your "binary method" can't "look inside" both queue inputs, just one. the other might use a different internal state type |
| 01:09:00 | <ski> | but with this version, the "ADT view" (Abstract Data Type), you *can* have "binary operations" |
| 01:09:06 | → | [_] joins (~itchyjunk@user/itchyjunk/x-7353470) |
| 01:10:32 | × | JeremyB99 quits (~JeremyB99@2600:1702:21b0:a500:b427:1e7a:fffe:f069) (Read error: Connection reset by peer) |
| 01:11:40 | <ski> | wroathe : hm, you removed the strict patterns on `state', looks like |
| 01:12:21 | <ski> | did you try [Leary]'s other suggestion ? (Church encoding) |
| 01:12:22 | <wroathe> | ski: I did. That didn't help at all, and if it did I couldn't have explained why |
| 01:12:26 | × | [itchTheIndiffer quits (~itchyjunk@user/itchyjunk/x-7353470) (Ping timeout: 245 seconds) |
| 01:12:39 | <wroathe> | ski: I'm not going to do a lot of rewriting until I get past the "evidence" phase |
| 01:13:00 | <wroathe> | Still trying to figure out exactly what gets allocated where. Even ticky-ticky isn't very explanatory |
| 01:13:05 | <ski> | yea, your're only passing `Start' or `Backslash' as argument in the `state' position, so i wouldn't except being strict in the argument doing much |
| 01:13:05 | <iqubic> | ski: brb, switching machines |
| 01:13:35 | → | JeremyB99 joins (~JeremyB99@2600:1702:21b0:a500:b427:1e7a:fffe:f069) |
| 01:13:43 | × | JeremyB99 quits (~JeremyB99@2600:1702:21b0:a500:b427:1e7a:fffe:f069) (Read error: Connection reset by peer) |
| 01:13:48 | <wroathe> | ski: I was actually just looking at MutVar#. I'm wondering how I can make that enumeration an unlifted type, and then read/write it from a mutable location |
| 01:14:03 | → | iqubic- joins (~avi@2601:602:9502:c70:774c:879b:1855:10ba) |
| 01:14:13 | <iqubic-> | back |
| 01:14:49 | × | dcoutts quits (~duncan@cpc69402-oxfd27-2-0-cust903.4-3.cable.virginm.net) (Ping timeout: 276 seconds) |
| 01:15:05 | ski | 's not quite sure what `fixFile' is supposed to do |
| 01:16:00 | <ski> | iqubic : i'll wait for you to read the last above, and perhaps comment/ask about it |
| 01:16:02 | <wroathe> | ski: It's just a simple state machine. I'm iterating through the characters of a file, and I need to keep track of whether I've seen a Backslash or not. If I see a Backslash, and then I find a character that isn't a Backslash, I'm inserting a matching \ before continuing with output |
| 01:16:27 | <wroathe> | ski: The point of the program is that I've got a TSV that has a bunch of \ in unquoted fields, and this function "fixes" that by properly escaping them |
| 01:16:38 | <wroathe> | As an exercise I'm trying to see if I can get it to sed-like performance |
| 01:17:03 | <ski> | oh, i guess you double the backslashes .. unless it was already doubled ? |
| 01:17:05 | <wroathe> | (If I can't there will be no point in maintaining this in Haskell code when I've got a perfectly good shell script that runs sed just fine) |
| 01:17:09 | ski | missed the doubling, initially |
| 01:17:13 | <wroathe> | ski: Correct |
| 01:17:26 | × | iqubic quits (~avi@2607:fb91:1518:c0e2:d265:9ef3:5320:9df0) (Ping timeout: 245 seconds) |
| 01:17:47 | <wroathe> | Thanks to earlier suggestions in here and a bit of digging in the Base code I was able to minimize the amount of I/O and maximize the amount of buffering this does |
| 01:18:10 | <wroathe> | But something within this loop is doing a bunch of allocating throwaway objects, and I'd like to make it stop doing that |
| 01:18:18 | <ski> | i was wondering how efficient it would be to use a buffer size of `1' |
| 01:18:54 | <wroathe> | ski: Well that's just intended to be a memory location to hold a single character being examined in the loop. The actual buffering is done on the Handle |
| 01:19:38 | <wroathe> | If you look at the top I defined this thing I'm calling a "Fat FD" that allows me to create a separate instance of BufferedIO where I set my buffer size to 8M. I learned yesterday that for regular FD GHC hardcodes that to just 8192 bytes! |
| 01:20:09 | <ski> | mhm |
| 01:20:10 | <wroathe> | So if I've got an 800M TSV that would end up being like almost 100k write calls |
| 01:20:49 | <ski> | i see |
| 01:21:07 | <wroathe> | read/write, actually. On either end. |
| 01:21:39 | <wroathe> | Pretty happy with how that turned out. It works nicely. Now to make Haskell stop doing Haskell things in the loop itself. |
| 01:21:42 | ski | would proably look at core of the code, trying to see where it could allocate |
| 01:22:20 | <ski> | (`-ddump-simpl', or perhaps some other version of it) |
| 01:22:43 | <wroathe> | Let me see if that makes more sense to me than the stg or cmm did |
| 01:22:47 | <wroathe> | I haven't tried simpl yet |
| 01:24:41 | <wroathe> | ski: What does an allocation "look like" in simpl? |
| 01:25:10 | <wroathe> | For example, I see this: case ghc-prim:GHC.Prim.word8ToWord# ipv3_a3KB of { __DEFAULT -> src<bench/memory/Main.hs:69:47-51> Main.Start; 92## -> src<bench/memory/Main.hs:69:32-40> Main.Backslash }) |
| 01:26:13 | <ski> | that's checking `c == bs' |
| 01:26:53 | × | smalltalkman quits (uid545680@id-545680.hampstead.irccloud.com) (Quit: Connection closed for inactivity) |
| 01:27:32 | <wroathe> | Right, but I mean the terms "Main.Backslash" and "Main.Start" there. Do those constitute an allocation? |
| 01:27:33 | <ski> | `let' would allocate. and lambdas, often, i guess. and i suppose calling data constructors |
| 01:29:08 | <ski> | hm, i suspect so |
| 01:29:32 | <wroathe> | My theory right now is that GHC isn't recognizing what this pattern is, and is just allocating a new value of type FixState on every loop iteration |
| 01:29:55 | <wroathe> | So I think what I need to do here is figure out what the syntax for making it an unlifted type is, and use something like MutVar# |
| 01:30:28 | <iqubic-> | ski: I assume using this would be better than trying roll my own Queue code: https://hackage.haskell.org/package/containers-0.7/docs/Data-Sequence.html#t:Seq |
| 01:31:56 | → | JeremyB99 joins (~JeremyB99@2600:1702:21b0:a500:b427:1e7a:fffe:f069) |
| 01:32:05 | × | eggplantade quits (~Eggplanta@2600:1700:38c5:d800:d9f3:ec2f:a760:e0fe) (Remote host closed the connection) |
| 01:32:06 | × | JeremyB99 quits (~JeremyB99@2600:1702:21b0:a500:b427:1e7a:fffe:f069) (Read error: Connection reset by peer) |
| 01:32:21 | → | eggplantade joins (~Eggplanta@2600:1700:38c5:d800:d9f3:ec2f:a760:e0fe) |
| 01:32:21 | <iqubic-> | It's O(1) for popping from each end and O(1) for pushing to either end |
| 01:33:42 | <iqubic-> | Oh... except that this doesn't work with infinite Seqs |
| 01:34:19 | <iqubic-> | (1 :<| undefined) `index` 0 = undefined |
| 01:34:27 | × | Square quits (~Square@user/square) (Ping timeout: 252 seconds) |
| 01:34:45 | <iqubic-> | It's strict in the spine of the sequence. But it's still really good for what it does. |
| 01:36:30 | <ski> | iqubic- : probably, yea |
| 01:36:48 | <ski> | .. how would you like infinite queues to work ? |
| 01:37:15 | <ski> | (enqueueing being a black hole, and dequeueing just removing from its infinite end ?) |
| 01:38:12 | <ski> | wroathe : yea. i suspect that using a Church representation, GHC could perhaps use "join points", which would not require additional allocation |
| 01:38:13 | <iqubic-> | Yeah... I don't know when I'd need an infinite Sequence. |
| 01:38:29 | <ski> | (but i haven't tried playing around with that, with `-ddumpl-simpl' or similar) |
| 01:38:49 | <ski> | iqubic- : no, i mean, not when you need it, but how ought it to work, reasonably |
| 01:39:20 | <ski> | (iqubic- : i also PMed you a question) |
| 01:39:39 | <wroathe> | ski: Hmm, Church scares me... (on a number of levels). I'll try both that and this approach. Ultimately I would prefer to use Lifted types for this that GHC magically optimizes to the code I want |
| 01:39:58 | <geekosaur> | require a Monoid constraint, enqueue eats, dequeue produces mempty 🙂 |
| 01:40:31 | ski | nods to wroathe |
| 01:41:10 | × | iqubic- quits (~avi@2601:602:9502:c70:774c:879b:1855:10ba) (Remote host closed the connection) |
| 01:41:25 | <ski> | geekosaur : not necessarily. you could have `listToQueue :: [a] -> Queue a', where if the list is infinite, enqueueing is just a black hole, and dequeueing removes from the infinite list |
| 01:41:33 | <geekosaur> | the Hawking version requires an Arbitrary constraint so dequeue can produce a randomized value |
| 01:41:45 | → | iqubic joins (~avi@2601:602:9502:c70:774c:879b:1855:10ba) |
| 01:42:57 | <ski> | hehe :p |
| 01:45:05 | <ski> | listToQueue revBack = loop [] revBack |
| 01:45:08 | <ski> | where |
| 01:45:36 | <ski> | enqueue (loop front revBack) x = loop (x:front) revBack |
| 01:46:22 | <ski> | dequeue (loop front [ ]) = ... |
| 01:46:49 | <ski> | dequeue (loop front (x:revBack)) = Just (loop front revBack,x) |
| 01:49:41 | <ski> | iqubic : anyway, continuations can be useful for efficiency reasons (directly call a callback, instead of making a bundle that'll only be unwrapped by the receiver immediately after the call). can also be useful sometimes for control reasons (early return/exit / short-circuiting), and for more advanced control (e.g. backtracking, ..) |
| 01:50:12 | <iqubic> | Yeah. That's really cool. |
| 01:51:17 | <ski> | e.g. you can use this to turn "internal iteration" (like a `mapM' library operation that applies a callback to each element of some collection (perhaps virtual, generated as we go)), into "external iteration" (the caller gets to decide if and when we advance to the next element) |
| 01:51:49 | → | szkl joins (uid110435@id-110435.uxbridge.irccloud.com) |
| 01:52:50 | <ski> | if a language has composable/delimited/sub- continuation side-effects (or, equivalently, (undelimited) continuation side-effects, and at least one mutable cell (state side-effect)), then, given any implementation of a monad, you can turn that into a side-effect, as if that monad was a built-in side-effect in the language (and with composable continuations, this can be relatively efficient, more than |
| 01:52:56 | <ski> | interpreting different data constructors all the time in (especially left-nested) `(>>=)'s). e.g. you could introduce parser side-effects that way |
| 01:53:19 | <ski> | there's two nice papers by Andrzej Filinski about this. the technique (and the papers) is called "monadic reflection" |
| 01:54:34 | <iqubic> | I'll look into that when I get time. I need to get some dinner now. |
| 01:54:46 | → | JeremyB99 joins (~JeremyB99@2600:1702:21b0:a500:b427:1e7a:fffe:f069) |
| 01:54:48 | <ski> | if you have `foo :: ... -> Maybe T', you can replace this with `withFoo :: ... -> o -> (T -> o) -> o' (or perhaps, if you had `foo :: ... -> IO (Maybe T)', you'd replace this with `withFoo :: ... -> IO o -> (T -> IO o) -> IO o') |
| 01:55:06 | <ski> | this is passing two continuations, one for the `Nothing' case, and one for the `Just' case, of the `Maybe' |
| 01:55:16 | <iqubic> | I am now a more clever and learned lady! |
| 01:55:43 | → | Xyloes joins (~wyx@2400:dd01:103a:1012:5923:33ce:7857:fc04) |
| 01:55:54 | <ski> | `withFoo' will directly call the appropriate continuation (corresponding to a branch of a `case'), rather than constructing a `Maybe T', only to have the caller take it apart immediately and branch into a `case' |
| 01:56:43 | <ski> | effectively, `withFoo' will jump to the appropriate branch immediately, without the control flow having to first pass through the "needle's eye" of the `case', requiring allocating a `Maybe' somewhere |
| 01:57:39 | <ski> | parsing combinator libraries often do something like this, internally |
| 01:58:11 | <ski> | also the `LogicT' type, for fair backtracking, iirc |
| 01:58:48 | <ski> | @hackage logict |
| 01:58:48 | <lambdabot> | https://hackage.haskell.org/package/logict |
| 02:00:18 | <ski> | newtype LogicT m a = LogicT { unLogicT :: forall r. (a -> m r -> m r) -> m r -> m r } -- yep |
| 02:01:21 | <ski> | (note `LogicT Identity a' is the Church representation for `[a]') |
| 02:02:11 | <ski> | oh, i guess, on the topic of `withXXX', i should mention the two encodings of `exists' |
| 02:02:15 | <ski> | if we want |
| 02:02:42 | <ski> | foo :: ... -> exists q. (q,(a,q) -> q,q -> Maybe (q,a)) |
| 02:02:47 | <ski> | we can represent this as |
| 02:02:54 | <ski> | foo :: ... -> Queue a |
| 02:03:15 | <ski> | defining `Queue a' as we did above, using `ExistentialQuantification' or `GADTs' |
| 02:03:40 | <ski> | or, we can use the equivalence between `...' and `forall o. (... -> o) -> o', to get from |
| 02:03:44 | <ski> | foo :: ... -> exists q. (q,(a,q) -> q,q -> Maybe (q,a)) |
| 02:03:46 | <ski> | to |
| 02:04:03 | <ski> | withFoo :: ... -> forall o. ((exists q. (q,(a,q) -> q,q -> Maybe (q,a))) -> o) -> o |
| 02:04:07 | × | sawilagar quits (~sawilagar@user/sawilagar) (Ping timeout: 255 seconds) |
| 02:04:26 | <ski> | which, by `(exists a. ..a..) -> ...' being equivalent to `forall a. (..a.. -> ...)', amounts to |
| 02:04:46 | <ski> | withFoo :: ... -> forall o. (forall q. (q,(a,q) -> q,q -> Maybe (q,a)) -> o) -> o |
| 02:05:22 | <ski> | or, uncurrying (and removing the `forall o.', since `... -> forall a. ..a..' is equivalent to `forall a. (... -> ..a..)', and we can elide top-level `forall's) |
| 02:05:54 | <ski> | withFoo :: ... -> (forall q. q -> (a -> q -> q) -> (q -> Maybe (q,a)) -> o) -> o |
| 02:06:27 | <ski> | so, this is the "CPS" encoding of existentials, by passing an extra callback, that will be polymorphic in the existentially quantified type variable |
| 02:06:42 | <ski> | iqubic : have a nice dinner |
| 02:08:49 | <iqubic> | Thanks for being willing to teach a trans woman like me. |
| 02:11:56 | → | peterbecich joins (~Thunderbi@047-229-123-186.res.spectrum.com) |
| 02:15:01 | → | travgm joins (~travgm@fsf/member/travgm) |
| 02:16:14 | × | peterbecich quits (~Thunderbi@047-229-123-186.res.spectrum.com) (Ping timeout: 252 seconds) |
| 02:18:46 | × | emmanuelux quits (~emmanuelu@user/emmanuelux) (Quit: au revoir) |
| 02:29:56 | × | travgm quits (~travgm@fsf/member/travgm) (Ping timeout: 245 seconds) |
| 02:33:31 | <wroathe> | ski: So I lost Leary's example, but is the church encoding for FixState in my example basically the same as the "bool" encoding? Is this correct? |
| 02:33:34 | <wroathe> | type FixState a = a -> a -> a |
| 02:33:36 | <wroathe> | start :: FixState a; start a _ = a |
| 02:33:39 | <wroathe> | backslash :: FixState a; backslash _ b = b |
| 02:34:11 | <ski> | well, more like `type FixState = forall a. a -> a -> a' .. but yes, for `start' and `backslash' |
| 02:34:32 | <wroathe> | Ah, I was wondering about forall a. there |
| 02:34:46 | <wroathe> | I still don't get the use of forall beyond making the compiler shut up |
| 02:34:55 | × | Xyloes quits (~wyx@2400:dd01:103a:1012:5923:33ce:7857:fc04) (Remote host closed the connection) |
| 02:35:08 | <wroathe> | Is it RankNTypes that enables that for type synonyms? |
| 02:35:14 | <ski> | `forall' means the corresponding value is polymorphic |
| 02:36:00 | <ski> | `length :: forall a. ([a] -> Int)' means that, strictly speaking, `length' is not a function, but a "polymorphic value". namely one that, when specialized, yields a function. (a "polymorphic function", for short) |
| 02:36:28 | <wroathe> | type FixState a = a -> a -> a |
| 02:36:28 | <wroathe> | start :: FixState a; start a _ = a |
| 02:36:29 | <wroathe> | backslash :: FixState a; backslash _ b = b |
| 02:36:34 | <ski> | if you use `forall' around an argument type, then that argument itself (not necessarily the whole function that takes that argument) is polymorphic. this is known as rank-3 |
| 02:36:34 | <wroathe> | Whooops, sorry |
| 02:36:37 | <ski> | er, rank-2 |
| 02:36:52 | <wroathe> | • Illegal polymorphic type: forall a. a -> a -> a |
| 02:36:52 | <wroathe> | • In the expansion of type synonym ‘FixState’ |
| 02:36:52 | <wroathe> | In the type signature: |
| 02:36:52 | <wroathe> | emit :: Handle -> Ptr Word8 -> Word8 -> FixState -> IO FixState |
| 02:37:29 | → | Xyloes joins (~wyx@2400:dd01:103a:1012:5923:33ce:7857:fc04) |
| 02:37:38 | <wroathe> | I take it that's not very useful with type synonyms then |
| 02:37:41 | <ski> | *usually*, if you write a type signature with type variables in it, like `zip :: [a] -> [b] -> [(a,b)]', there's "implicit" `forall's *directly* after the `::' |
| 02:38:03 | → | Sciencentistguy9 joins (~sciencent@hacksoc/ordinary-member) |
| 02:38:35 | <ski> | iow, we really have `zip :: forall a b. [a] -> [b] -> [(a,b)]', but Haskell allows us to be implicit about the `forall's, omit/elide them, so just writing `zip :: [a] -> [b] -> [(a,b)]', and the implementation will (conceptually, at least) insert them back for us |
| 02:38:57 | <ski> | this is merely a convenience thing. some other languages with polymorphism has no such convenience syntax |
| 02:39:10 | <wroathe> | So is the above error saying that we basically do need FixState paramterized by a so that I can quantify it in function signatures? |
| 02:39:22 | → | travgm joins (~travgm@2600:100e:a121:d6af:56b:4880:133:700e) |
| 02:40:12 | × | Sciencentistguy quits (~sciencent@hacksoc/ordinary-member) (Ping timeout: 268 seconds) |
| 02:40:12 | Sciencentistguy9 | is now known as Sciencentistguy |
| 02:40:40 | <ski> | in any case, `a -> Bool' is *not* short for `forall a. a -> Bool' (since if it were, then `filter :: (a -> Bool) -> [a] -> [a]', could be said to mean the same as `filter :: (forall a. a -> Bool) -> [a] -> [a]', which it most definitely does *not*) .. it's only at the "top-level" of a type *signature*, right after the `::', where implicit `forall's can be added |
| 02:41:15 | <wroathe> | Your brain is too big for me :P |
| 02:41:45 | <ski> | "I take it that's not very useful with type synonyms then" -- with `Rank2Types' or `RankNTypes', they can be |
| 02:42:28 | <ski> | "So is the above error saying that we basically do need FixState paramterized by a so that I can quantify it in function signatures?" -- no, it's asking you to turn on higher-rank (or at least rank-2) |
| 02:42:32 | <ski> | since |
| 02:42:36 | <ski> | emit :: Handle -> Ptr Word8 -> Word8 -> FixState -> IO FixState |
| 02:42:45 | <ski> | by the type synonym, expands to |
| 02:42:58 | <wroathe> | I've got RankNTypes enabled |
| 02:42:59 | <ski> | emit :: Handle -> Ptr Word8 -> Word8 -> (forall a. a -> a -> a) -> IO (forall a. a -> a -> a) |
| 02:43:09 | <ski> | and that's rank-2, the argument is polymorphic |
| 02:43:22 | <ski> | the second problem is that you now also have `forall' nested inside of `IO' |
| 02:43:23 | <wroathe> | It won't let me define type FixState = forall a. a -> a -> a without it |
| 02:43:57 | <ski> | that requires `ImpredicativeTypes' .. which at least used to only be partially implemented. there was some paper with a new approach to it, but i dunno if that's available in GHC yet |
| 02:44:16 | <ski> | one way around that is to wrap the `forall' inside a data type |
| 02:44:28 | <ski> | newtype FixState = FS (forall a. a -> a -> a) |
| 02:44:37 | <geekosaur> | QuickLook has been in ghc since 9.2 |
| 02:44:39 | <ski> | then `IO FixState' will be fine |
| 02:44:59 | <ski> | geekosaur : and it works fine, also for `IO (forall a. ..a..)' say ? |
| 02:45:09 | ski | can't recall the details of the paper |
| 02:45:13 | <wroathe> | ski: https://gist.github.com/JustinChristensen/2111f13e812112b5ac973e292606d17f#file-church-hs |
| 02:45:17 | <geekosaur> | I think so, yes |
| 02:45:19 | <ski> | ok |
| 02:45:23 | <geekosaur> | I don't do impredicativity much |
| 02:45:28 | → | hgolden_ joins (~hgolden@cpe-172-251-233-141.socal.res.rr.com) |
| 02:45:30 | <wroathe> | This is obviously wrong, but this I think is what you guys are suggesting I do when you say church encoding |
| 02:45:59 | → | jmdaemon joins (~jmdaemon@user/jmdaemon) |
| 02:46:59 | × | hgolden quits (~hgolden@2603-8000-9d00-3ed1-dd4f-298a-9c49-a0ed.res6.spectrum.com) (Ping timeout: 268 seconds) |
| 02:50:56 | <ski> | hm, yea, i think if you were just returning `IO FixState', that could be useful. but now you're also taking a `FixState' as input, which is making this more questionable. passing `start' or `backslash' as input might allocate closures here, unless these get allocated once, outside |
| 02:51:04 | × | Unicorn_Princess quits (~Unicorn_P@user/Unicorn-Princess/x-3540542) (Remote host closed the connection) |
| 02:51:46 | <ski> | (and even then, calling `state' with two `do's may allocate those, i guess unless they get translated into join points ?) |
| 02:52:37 | <wroathe> | So are you saying you're cooling on the idea of the church encoding being a solution for this? |
| 02:52:48 | <wroathe> | I still haven't gotten this to compmile |
| 02:52:51 | <wroathe> | compile* |
| 02:55:44 | → | smalltalkman joins (uid545680@id-545680.hampstead.irccloud.com) |
| 02:59:01 | wroathe | gives up on this idea |
| 03:09:30 | × | travgm quits (~travgm@2600:100e:a121:d6af:56b:4880:133:700e) (Ping timeout: 268 seconds) |
| 03:34:34 | × | ddellacosta quits (~ddellacos@ool-44c73d16.dyn.optonline.net) (Ping timeout: 276 seconds) |
| 03:44:21 | × | FinnElija quits (~finn_elij@user/finn-elija/x-0085643) (Killed (NickServ (Forcing logout FinnElija -> finn_elija))) |
| 03:44:21 | → | finn_elija joins (~finn_elij@user/finn-elija/x-0085643) |
| 03:44:21 | finn_elija | is now known as FinnElija |
| 03:44:33 | → | codolio joins (~dolio@130.44.134.54) |
| 03:45:19 | × | dolio quits (~dolio@130.44.134.54) (Ping timeout: 260 seconds) |
| 03:45:27 | → | nate4 joins (~nate@c-98-45-158-125.hsd1.ca.comcast.net) |
| 03:48:59 | → | hapisnake joins (~hapisnake@120.138.12.144) |
| 03:49:31 | × | td_ quits (~td@83.135.9.0) (Ping timeout: 245 seconds) |
| 03:51:37 | → | td_ joins (~td@i53870905.versanet.de) |
| 03:55:24 | → | dolio joins (~dolio@130.44.134.54) |
| 03:55:34 | × | codolio quits (~dolio@130.44.134.54) (Ping timeout: 256 seconds) |
| 03:55:59 | → | ddellacosta joins (~ddellacos@ool-44c73d16.dyn.optonline.net) |
| 03:59:59 | × | szkl quits (uid110435@id-110435.uxbridge.irccloud.com) (Quit: Connection closed for inactivity) |
| 04:01:04 | → | takuan joins (~takuan@178-116-218-225.access.telenet.be) |
| 04:05:29 | × | hays quits (rootvegeta@fsf/member/hays) (Remote host closed the connection) |
| 04:05:51 | × | hamess quits (~hamess@user/hamess) (Ping timeout: 260 seconds) |
| 04:10:14 | × | hapisnake quits (~hapisnake@120.138.12.144) (Ping timeout: 250 seconds) |
| 04:26:02 | → | hays joins (rootvegeta@fsf/member/hays) |
| 04:27:08 | × | hays quits (rootvegeta@fsf/member/hays) (Client Quit) |
| 04:29:00 | → | hays joins (rootvegeta@fsf/member/hays) |
| 04:41:00 | × | ddellacosta quits (~ddellacos@ool-44c73d16.dyn.optonline.net) (Quit: WeeChat 4.1.1) |
| 04:47:09 | → | aforemny_ joins (~aforemny@2001:9e8:6cd2:2300:81b8:672c:d485:69b9) |
| 04:47:15 | × | aforemny quits (~aforemny@i59F516CC.versanet.de) (Ping timeout: 256 seconds) |
| 04:48:41 | × | nate4 quits (~nate@c-98-45-158-125.hsd1.ca.comcast.net) (Ping timeout: 245 seconds) |
| 05:02:13 | → | peterbecich joins (~Thunderbi@047-229-123-186.res.spectrum.com) |
| 05:12:12 | → | trev joins (~trev@user/trev) |
| 05:16:55 | × | lg188 quits (~lg188@82.18.98.230) (Quit: Ping timeout (120 seconds)) |
| 05:17:16 | → | lg188 joins (~lg188@82.18.98.230) |
| 05:17:35 | <glguy> | int-e: you get to leverage so laziness for part 2? |
| 05:17:54 | <int-e> | I didn't |
| 05:19:15 | <glguy> | oh, maybe just recursively built up a list? |
| 05:20:40 | glguy | tries to reframe this as a scanr |
| 05:22:18 | <probie> | I used a boring `foldr` for part 2 |
| 05:23:58 | <probie> | glguy: c3VtICQgZm9sZHIgKFx4IHhzIC0+IDEgKyBzdW0gKHRha2UgKHgtMSkgeHMpOiB4cykgW10gKG1hcCBjb3VudFdpbm5lcnMgZ2FtZXMp is how I did it (base64 "encrypted" to avoid spoilers) |
| 05:38:15 | × | peterbecich quits (~Thunderbi@047-229-123-186.res.spectrum.com) (Ping timeout: 260 seconds) |
| 05:39:21 | × | azimut quits (~azimut@gateway/tor-sasl/azimut) (Remote host closed the connection) |
| 05:39:47 | → | azimut joins (~azimut@gateway/tor-sasl/azimut) |
| 05:41:54 | <EvanR> | I want my client to decode64 when clicking on base64 encoded text |
| 05:46:01 | → | robobub joins (uid248673@id-248673.uxbridge.irccloud.com) |
| 05:49:22 | × | azimut quits (~azimut@gateway/tor-sasl/azimut) (Remote host closed the connection) |
| 05:49:46 | → | azimut joins (~azimut@gateway/tor-sasl/azimut) |
| 05:56:35 | → | danza joins (~francesco@rm-19-56-167.service.infuturo.it) |
| 05:58:34 | × | wroathe quits (~wroathe@user/wroathe) (Ping timeout: 255 seconds) |
| 06:10:49 | × | euleritian quits (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Ping timeout: 255 seconds) |
| 06:11:25 | → | euleritian joins (~euleritia@dynamic-002-247-251-082.2.247.pool.telefonica.de) |
| 06:16:20 | → | zetef joins (~quassel@95.77.17.251) |
| 06:22:13 | → | chomwitt joins (~chomwitt@2a02:587:7a09:c300:1ac0:4dff:fedb:a3f1) |
| 06:22:37 | → | hapisnake joins (~hapisnake@103.28.246.140) |
| 06:22:59 | × | JeremyB99 quits (~JeremyB99@2600:1702:21b0:a500:b427:1e7a:fffe:f069) (Remote host closed the connection) |
| 06:23:52 | → | JeremyB99 joins (~JeremyB99@2600:1702:21b0:a500:b427:1e7a:fffe:f069) |
| 06:33:56 | → | wroathe joins (~wroathe@207-153-38-140.fttp.usinternet.com) |
| 06:33:57 | × | wroathe quits (~wroathe@207-153-38-140.fttp.usinternet.com) (Changing host) |
| 06:33:57 | → | wroathe joins (~wroathe@user/wroathe) |
| 06:34:43 | × | hapisnake quits (~hapisnake@103.28.246.140) (Quit: Client closed) |
| 06:45:02 | × | wroathe quits (~wroathe@user/wroathe) (Ping timeout: 255 seconds) |
| 06:45:44 | → | nate4 joins (~nate@c-98-45-158-125.hsd1.ca.comcast.net) |
| 06:46:21 | → | peterbecich joins (~Thunderbi@047-229-123-186.res.spectrum.com) |
| 06:48:32 | → | rosco joins (~rosco@175.136.158.171) |
| 06:50:13 | × | nate4 quits (~nate@c-98-45-158-125.hsd1.ca.comcast.net) (Ping timeout: 256 seconds) |
| 06:50:46 | × | danza quits (~francesco@rm-19-56-167.service.infuturo.it) (Ping timeout: 255 seconds) |
| 06:50:55 | × | clwif^ quits (~cd@c-98-242-74-66.hsd1.ga.comcast.net) (Remote host closed the connection) |
| 06:55:16 | × | euleritian quits (~euleritia@dynamic-002-247-251-082.2.247.pool.telefonica.de) (Read error: Connection reset by peer) |
| 06:55:33 | → | euleritian joins (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) |
| 06:56:41 | <EvanR> | the more I think about part 2 the less I understand it |
| 06:56:54 | <EvanR> | luckily I got my stars already |
| 06:59:51 | × | euleritian quits (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Ping timeout: 256 seconds) |
| 07:00:11 | → | euleritian joins (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) |
| 07:02:01 | × | zetef quits (~quassel@95.77.17.251) (Ping timeout: 245 seconds) |
| 07:05:59 | × | peterbecich quits (~Thunderbi@047-229-123-186.res.spectrum.com) (Ping timeout: 260 seconds) |
| 07:08:12 | → | Sgeo_ joins (~Sgeo@user/sgeo) |
| 07:11:35 | × | Sgeo quits (~Sgeo@user/sgeo) (Ping timeout: 260 seconds) |
| 07:11:36 | → | zetef joins (~quassel@95.77.17.251) |
| 07:16:36 | → | acidjnk joins (~acidjnk@p200300d6e72b9356246dd2d07051f792.dip0.t-ipconnect.de) |
| 07:16:36 | × | euleritian quits (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Read error: Connection reset by peer) |
| 07:16:43 | → | euleritian joins (~euleritia@dynamic-002-247-251-082.2.247.pool.telefonica.de) |
| 07:17:05 | × | euleritian quits (~euleritia@dynamic-002-247-251-082.2.247.pool.telefonica.de) (Read error: Connection reset by peer) |
| 07:17:21 | → | euleritian joins (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) |
| 07:25:38 | → | misterfish joins (~misterfis@84-53-85-146.bbserv.nl) |
| 07:30:03 | → | sord937 joins (~sord937@gateway/tor-sasl/sord937) |
| 07:37:38 | × | sord937 quits (~sord937@gateway/tor-sasl/sord937) (Remote host closed the connection) |
| 07:37:59 | → | sord937 joins (~sord937@gateway/tor-sasl/sord937) |
| 07:48:51 | → | lortabac joins (~lortabac@2a01:e0a:541:b8f0:55ab:e185:7f81:54a4) |
| 07:53:16 | × | iqubic quits (~avi@2601:602:9502:c70:774c:879b:1855:10ba) (Ping timeout: 245 seconds) |
| 07:54:06 | × | zetef quits (~quassel@95.77.17.251) (Ping timeout: 245 seconds) |
| 07:55:57 | → | danse-nr3 joins (~danse@na-19-84-78.service.infuturo.it) |
| 07:56:59 | × | danse-nr3 quits (~danse@na-19-84-78.service.infuturo.it) (Remote host closed the connection) |
| 07:57:21 | → | danse-nr3 joins (~danse@na-19-84-78.service.infuturo.it) |
| 08:01:43 | × | azimut quits (~azimut@gateway/tor-sasl/azimut) (Ping timeout: 240 seconds) |
| 08:02:46 | → | CiaoSen joins (~Jura@2a05:5800:2d9:1600:ca4b:d6ff:fec1:99da) |
| 08:02:59 | × | misterfish quits (~misterfis@84-53-85-146.bbserv.nl) (Ping timeout: 264 seconds) |
| 08:04:15 | <EvanR> | ah ha! |
| 08:04:56 | → | fendor joins (~fendor@2a02:8388:1605:d100:267b:1353:13d7:4f0c) |
| 08:07:06 | → | zetef joins (~quassel@95.77.17.251) |
| 08:12:35 | × | _d0t quits (~{-d0t-}@user/-d0t-/x-7915216) (Ping timeout: 268 seconds) |
| 08:15:47 | → | _d0t joins (~{-d0t-}@user/-d0t-/x-7915216) |
| 08:21:30 | × | tzh quits (~tzh@c-71-193-181-0.hsd1.or.comcast.net) (Quit: zzz) |
| 08:24:03 | → | waleee joins (~waleee@h-176-10-144-38.NA.cust.bahnhof.se) |
| 08:24:49 | → | coot joins (~coot@89.69.206.216) |
| 08:28:41 | → | misterfish joins (~misterfis@84-53-85-146.bbserv.nl) |
| 08:37:04 | × | lg188 quits (~lg188@82.18.98.230) (Quit: Ping timeout (120 seconds)) |
| 08:37:27 | → | lg188 joins (~lg188@82.18.98.230) |
| 08:37:38 | → | dcoutts joins (~duncan@cpc69402-oxfd27-2-0-cust903.4-3.cable.virginm.net) |
| 08:37:56 | → | idgaen joins (~idgaen@2a01:e0a:498:fd50:fcc6:bb5d:489a:ce8c) |
| 08:42:08 | × | FinnElija quits (~finn_elij@user/finn-elija/x-0085643) (Remote host closed the connection) |
| 08:42:40 | × | dcoutts quits (~duncan@cpc69402-oxfd27-2-0-cust903.4-3.cable.virginm.net) (Ping timeout: 276 seconds) |
| 08:42:48 | → | FinnElija joins (~finn_elij@user/finn-elija/x-0085643) |
| 08:46:58 | × | coot quits (~coot@89.69.206.216) (Quit: coot) |
| 08:48:16 | → | gmg joins (~user@user/gehmehgeh) |
| 08:50:28 | × | euleritian quits (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Read error: Connection reset by peer) |
| 08:51:30 | → | euleritian joins (~euleritia@dynamic-002-247-251-082.2.247.pool.telefonica.de) |
| 08:56:45 | × | Sgeo_ quits (~Sgeo@user/sgeo) (Read error: Connection reset by peer) |
| 08:58:55 | × | TMA quits (tma@twin.jikos.cz) (Ping timeout: 276 seconds) |
| 09:00:04 | → | tromp joins (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) |
| 09:03:37 | × | steew quits (~steew@user/steew) (Ping timeout: 255 seconds) |
| 09:03:45 | <danse-nr3> | morning. Enjoying reading abuseofnotation.github.io/category-theory-illustrated, although it may look like kindergarden study material to many |
| 09:04:47 | × | Incredia quits (~Incredia@176.254.244.83) (Ping timeout: 264 seconds) |
| 09:06:40 | → | Square2 joins (~Square4@user/square) |
| 09:08:23 | × | zetef quits (~quassel@95.77.17.251) (Ping timeout: 264 seconds) |
| 09:14:15 | → | cfricke joins (~cfricke@user/cfricke) |
| 09:17:20 | × | YoungFrog quits (~youngfrog@2a02:a03f:ca07:f900:3d37:6f51:8df5:683d) (Ping timeout: 268 seconds) |
| 09:19:56 | → | zetef joins (~quassel@95.77.17.251) |
| 09:21:15 | × | infinity0 quits (~infinity0@pwned.gg) (Remote host closed the connection) |
| 09:23:22 | → | infinity0 joins (~infinity0@pwned.gg) |
| 09:23:43 | → | Incredia joins (~Incredia@176.254.244.83) |
| 09:23:54 | × | Square2 quits (~Square4@user/square) (Quit: Leaving) |
| 09:24:23 | → | Square2 joins (~Square4@user/square) |
| 09:24:59 | → | pretty_dumm_guy joins (trottel@gateway/vpn/protonvpn/prettydummguy/x-88029655) |
| 09:27:33 | × | econo_ quits (uid147250@id-147250.tinside.irccloud.com) (Quit: Connection closed for inactivity) |
| 09:29:36 | → | coot joins (~coot@89-69-206-216.dynamic.chello.pl) |
| 09:30:21 | × | eggplantade quits (~Eggplanta@2600:1700:38c5:d800:d9f3:ec2f:a760:e0fe) (Remote host closed the connection) |
| 09:33:46 | → | alp_ joins (~alp@2001:861:e3d6:8f80:59a0:3738:2d56:41bc) |
| 09:34:28 | × | waleee quits (~waleee@h-176-10-144-38.NA.cust.bahnhof.se) (Ping timeout: 256 seconds) |
| 09:34:47 | × | shriekingnoise quits (~shrieking@186.137.175.87) (Ping timeout: 264 seconds) |
| 09:51:23 | → | chele joins (~chele@user/chele) |
| 10:01:20 | → | eggplantade joins (~Eggplanta@2600:1700:38c5:d800:d9f3:ec2f:a760:e0fe) |
| 10:02:04 | → | iqubic joins (~avi@2601:602:9502:c70:7ce7:f8c:f1d2:dccf) |
| 10:02:46 | → | __monty__ joins (~toonn@user/toonn) |
| 10:03:41 | × | zetef quits (~quassel@95.77.17.251) (Ping timeout: 245 seconds) |
| 10:05:12 | × | danse-nr3 quits (~danse@na-19-84-78.service.infuturo.it) (Remote host closed the connection) |
| 10:09:28 | → | danse-nr3 joins (~danse@na-19-84-78.service.infuturo.it) |
| 10:09:45 | → | kuribas joins (~user@ip-188-118-57-242.reverse.destiny.be) |
| 10:11:04 | × | tomboy64 quits (~tomboy64@user/tomboy64) (Ping timeout: 276 seconds) |
| 10:14:08 | × | Lord_of_Life quits (~Lord@user/lord-of-life/x-2819915) (Ping timeout: 256 seconds) |
| 10:14:12 | → | zetef joins (~quassel@95.77.17.251) |
| 10:14:41 | → | Lord_of_Life joins (~Lord@user/lord-of-life/x-2819915) |
| 10:15:01 | → | malte joins (~malte@mal.tc) |
| 10:18:40 | → | guy80 joins (~guy@250.79-105-213.static.virginmediabusiness.co.uk) |
| 10:19:27 | guy80 | is now known as telem |
| 10:19:42 | <telem> | hi, im reading about solidity |
| 10:19:51 | <telem> | it uses top level variables |
| 10:19:56 | × | misterfish quits (~misterfis@84-53-85-146.bbserv.nl) (Ping timeout: 245 seconds) |
| 10:20:05 | <telem> | i want to understand how this fits into the haskell story |
| 10:20:19 | <danse-nr3> | haskell also has top level vals |
| 10:20:27 | <telem> | but they are immutable |
| 10:20:51 | <telem> | like, not variable |
| 10:21:05 | <telem> | we have top level immutable values |
| 10:21:35 | <telem> | is it something to do with the evaluation order? |
| 10:21:43 | <telem> | like, in do syntax you can overwrite them |
| 10:21:53 | <telem> | its something to do with it not being imperative? |
| 10:22:03 | <danse-nr3> | that is shadowing more than overwriting |
| 10:22:24 | <telem> | sure, but it would throw a syntax error at top level right? |
| 10:22:31 | <telem> | about conflicting function definitions... |
| 10:22:40 | <telem> | or it would just strat trying to pattern match them or something |
| 10:22:43 | <telem> | ahhh, maybe thats it |
| 10:22:55 | <telem> | so all the declerations are taken to be simultaniously true |
| 10:23:09 | → | tomboy64 joins (~tomboy64@user/tomboy64) |
| 10:23:09 | <telem> | that kind of makes sense about the top down imperative evaluation order |
| 10:23:16 | <telem> | kind of adds a sort of temporality |
| 10:23:23 | <telem> | temporal scoping* |
| 10:24:12 | <telem> | i guess thats why you can overwrite a top level value in a restrected scope |
| 10:24:30 | <telem> | im always amazed how much scoping considerations affect the language |
| 10:24:41 | <telem> | i think its what makes it so different to imperative languages |
| 10:24:54 | <telem> | i think i understand how top level variables fit into this now |
| 10:25:09 | <telem> | so i answerd my own question! but i didnt think i could do that when i asked it! |
| 10:25:12 | <telem> | derp |
| 10:25:20 | <danse-nr3> | you are welcome |
| 10:25:30 | <telem> | yeah, thanks for the input |
| 10:25:37 | <telem> | i was kind of hoping there could be some interesting offshoot |
| 10:25:59 | <telem> | but then i just trying to think about carried scopes in imperative program specifications in some DSL |
| 10:26:27 | <telem> | i think that would make a really cool haskell style language |
| 10:26:54 | <telem> | i guess kind of making the list of active variables in a do-like block |
| 10:27:02 | <telem> | making it explicit |
| 10:27:44 | <telem> | i was doing something like that, where i had programs in datatypes so you could modify them |
| 10:28:25 | <telem> | but then there was a kind of horrible formalism of how you would have to write the corresponding program in pure haskell so that its implementation would map over nicely to how it would be written in the DSL |
| 10:29:34 | <telem> | you end up implementing a sort of graph with explicit shape decorations that the program sits ontop of, which essentially mimics how top level functions fit together to form a program graph |
| 10:29:53 | <telem> | and then get frustrated at the idea of having to somehow compile pure code to it |
| 10:30:25 | → | ridcully_ joins (~ridcully@p57b52ac5.dip0.t-ipconnect.de) |
| 10:30:43 | <telem> | but then, if you can either do that, or are happy writing it by hand, then in these imperative subsequent code lines, then you can repeatedly modify the program with lenses into it and stuff |
| 10:31:15 | <telem> | modify_program all_if_statements_are_true |
| 10:32:11 | <telem> | im not sure if anything would be lost with these semantics |
| 10:32:16 | × | ridcully quits (~ridcully@p508acfd3.dip0.t-ipconnect.de) (Ping timeout: 255 seconds) |
| 10:32:32 | <telem> | other than pattern matching using multiple lines of function decleartion |
| 10:33:27 | <telem> | i think also, re with me cos this is kind of mind-bending. so, something like, to level value declerations *replacing* pattern matching |
| 10:33:46 | <telem> | like, where do you specify the value name. some languages have it in the type sig |
| 10:33:55 | <telem> | f :: (x :: String) -> Bool |
| 10:34:07 | <telem> | while in the imperative style its |
| 10:34:10 | <telem> | x :: String |
| 10:34:16 | <telem> | f :: x -> Bool |
| 10:34:24 | <telem> | or something like that |
| 10:34:48 | <telem> | obviously that conflicts with polymorphic syntax |
| 10:35:29 | <telem> | seems to force pattern matching into the type signature, not sure to what effect! |
| 10:36:26 | <telem> | i guess if the imperative ordering risked shadowing or overwriting the value, then a distinguishing annotation to a required type signature could kind of handle both value overwrites, and pattern matching which does not overwrite, other than matching a seperate case |
| 10:36:58 | <telem> | and then how you would treat unreachable patterns |
| 10:37:20 | <telem> | i think we already *have* the imperative ordering for patterns which makes me suspicious! |
| 10:37:31 | <telem> | i hate it when it makes *too much* sense! |
| 10:37:48 | <telem> | makes me think im onto something, which makes me afraid! |
| 10:38:17 | <telem> | so im glad that was useful!? |
| 10:38:40 | <telem> | and then like, i guess i dont have to wait for a response then... ciao? |
| 10:38:51 | × | telem quits (~guy@250.79-105-213.static.virginmediabusiness.co.uk) (Quit: Connection closed) |
| 10:40:23 | × | euleritian quits (~euleritia@dynamic-002-247-251-082.2.247.pool.telefonica.de) (Read error: Connection reset by peer) |
| 10:40:43 | → | euleritian joins (~euleritia@77.22.252.56) |
| 10:46:57 | → | nate4 joins (~nate@c-98-45-158-125.hsd1.ca.comcast.net) |
| 10:48:49 | × | remedan quits (~remedan@ip-94-112-0-18.bb.vodafone.cz) (Quit: Bye!) |
| 10:52:02 | × | nate4 quits (~nate@c-98-45-158-125.hsd1.ca.comcast.net) (Ping timeout: 252 seconds) |
| 10:56:43 | × | mobivme quits (~mobivme@112.201.111.217) (Ping timeout: 256 seconds) |
| 10:59:55 | → | oo_miguel joins (~Thunderbi@78-11-179-96.static.ip.netia.com.pl) |
| 11:00:02 | → | mobivme joins (~mobivme@112.201.111.217) |
| 11:01:07 | × | danse-nr3 quits (~danse@na-19-84-78.service.infuturo.it) (Ping timeout: 256 seconds) |
| 11:02:17 | → | `2jt joins (~jtomas@90.162.208.36) |
| 11:04:20 | → | remedan joins (~remedan@ip-94-112-0-18.bb.vodafone.cz) |
| 11:06:47 | × | zetef quits (~quassel@95.77.17.251) (Ping timeout: 256 seconds) |
| 11:16:15 | → | misterfish joins (~misterfis@87.215.131.102) |
| 11:16:22 | → | zetef joins (~quassel@95.77.17.251) |
| 11:27:29 | → | bitmapper joins (uid464869@id-464869.lymington.irccloud.com) |
| 11:30:25 | → | YoungFrog joins (~youngfrog@2a02:a03f:ca07:f900:1f5c:a3c6:297:feeb) |
| 11:34:49 | × | lortabac quits (~lortabac@2a01:e0a:541:b8f0:55ab:e185:7f81:54a4) (Ping timeout: 255 seconds) |
| 11:35:12 | → | dcoutts joins (~duncan@cpc69402-oxfd27-2-0-cust903.4-3.cable.virginm.net) |
| 11:39:49 | × | lottaquestions quits (~nick@2607:fa49:503d:b200:791c:1e35:f3fd:c3f3) (Remote host closed the connection) |
| 11:40:15 | → | lottaquestions joins (~nick@2607:fa49:503d:b200:2d55:64ae:c120:e947) |
| 11:45:34 | × | pretty_dumm_guy quits (trottel@gateway/vpn/protonvpn/prettydummguy/x-88029655) (Quit: WeeChat 3.5) |
| 11:46:27 | → | pretty_dumm_guy joins (trottel@gateway/vpn/protonvpn/prettydummguy/x-88029655) |
| 11:51:14 | → | shriekingnoise joins (~shrieking@186.137.175.87) |
| 11:51:23 | → | danse-nr3 joins (~danse@na-19-84-78.service.infuturo.it) |
| 11:55:53 | × | danse-nr3 quits (~danse@na-19-84-78.service.infuturo.it) (Read error: Connection reset by peer) |
| 11:56:11 | → | danse-nr3 joins (~danse@151.47.50.89) |
| 11:57:01 | × | __monty__ quits (~toonn@user/toonn) (Ping timeout: 245 seconds) |
| 11:58:42 | → | __monty__ joins (~toonn@user/toonn) |
| 12:00:04 | × | JeremyB99 quits (~JeremyB99@2600:1702:21b0:a500:b427:1e7a:fffe:f069) (Read error: Connection reset by peer) |
| 12:03:08 | → | ritog joins (~ritog@45.112.243.193) |
| 12:03:38 | → | JeremyB99 joins (~JeremyB99@2600:1702:21b0:a500:b427:1e7a:fffe:f069) |
| 12:04:00 | × | JeremyB99 quits (~JeremyB99@2600:1702:21b0:a500:b427:1e7a:fffe:f069) (Read error: Connection reset by peer) |
| 12:05:07 | → | _ht joins (~Thunderbi@28-52-174-82.ftth.glasoperator.nl) |
| 12:05:19 | → | Sciencentistguy7 joins (~sciencent@hacksoc/ordinary-member) |
| 12:06:55 | → | lortabac joins (~lortabac@2a01:e0a:541:b8f0:55ab:e185:7f81:54a4) |
| 12:08:28 | × | Sciencentistguy quits (~sciencent@hacksoc/ordinary-member) (Ping timeout: 268 seconds) |
| 12:08:28 | Sciencentistguy7 | is now known as Sciencentistguy |
| 12:10:50 | × | zetef quits (~quassel@95.77.17.251) (Ping timeout: 260 seconds) |
| 12:11:43 | × | jjhoo quits (~jahakala@user/jjhoo) (Ping timeout: 255 seconds) |
| 12:14:32 | × | ritog quits (~ritog@45.112.243.193) (Quit: Leaving) |
| 12:15:52 | → | Tisoxin joins (~Ikosit@user/ikosit) |
| 12:18:41 | → | jjhoo joins (~jahakala@user/jjhoo) |
| 12:20:17 | <Tisoxin> | Hi! Is there a lens combinator (in the lens package) that allows me to do |
| 12:20:17 | <Tisoxin> | > [1, 2, 3] & ix 1 `cbr` \x -> Just (x+1) |
| 12:20:17 | <Tisoxin> | ⇒ Just [1, 3, 3] |
| 12:20:17 | <Tisoxin> | > [1, 2, 3] & ix 1 `cbr` \x -> Nothing |
| 12:20:17 | <Tisoxin> | ⇒ Nothing |
| 12:20:18 | <Tisoxin> | cbr is the lens combinator I'm searching |
| 12:20:18 | <lambdabot> | error: |
| 12:20:18 | <lambdabot> | • Variable not in scope: |
| 12:20:19 | <lambdabot> | cbr :: (m0 -> f0 m0) -> (a1 -> Maybe a1) -> t |
| 12:20:19 | <lambdabot> | error: |
| 12:20:19 | <lambdabot> | • Variable not in scope: |
| 12:20:20 | <lambdabot> | cbr :: (m0 -> f0 m0) -> (p0 -> Maybe a0) -> t |
| 12:21:11 | <ncf> | id? |
| 12:21:49 | <ncf> | > [1,2,3] & ix 1 `id` (\x -> Just (x+1)) |
| 12:21:51 | <lambdabot> | Just [1,3,3] |
| 12:21:52 | <ncf> | > [1,2,3] & ix 1 `id` (\x -> Nothing) |
| 12:21:53 | <lambdabot> | Nothing |
| 12:22:36 | <ncf> | or if you want to pretend that lens doesn't use the van laarhoven encoding, (%%~) https://hackage.haskell.org/package/lens-5.2.3/docs/Control-Lens-Lens.html#v:-37--37--126- |
| 12:22:58 | <ncf> | (i think that's a good idea, actually!) |
| 12:23:23 | <Tisoxin> | ok thanks, I guess I should really once again take a look at how exactly lenses work |
| 12:23:29 | → | waleee joins (~waleee@h-176-10-144-38.NA.cust.bahnhof.se) |
| 12:23:55 | <Tisoxin> | I also just now found traverseOf which should do the right thing as well™ |
| 12:24:44 | <Tisoxin> | Thanks ncf! |
| 12:24:56 | <ncf> | what you're asking for is basically the "universal use case" for traversals; so much so that they're encoded that way: in the lens library, a Traversal s t a b is a polymorphic function (forall f. Applicative f => (a -> f b) -> s -> f t) |
| 12:26:06 | <ncf> | for an analogy, if you consider that the universal use case for natural numbers is to be able to recurse on them, i.e. given a function and an initial value, apply the function n times to the initial value, then you end up with the "Church encoding" for natural numbers, (forall a. (a -> a) -> a -> a) |
| 12:27:34 | <Tisoxin> | very interesting, I didn't now that this is how one can construct the church encoding of a type but it's very intuitive |
| 12:29:12 | <dminuoso_> | Tisoxin: I think what you're really after is just `at` |
| 12:29:34 | <dminuoso_> | Which captures writing/updating/deleting indexed elements via a lens. |
| 12:31:02 | <Tisoxin> | I don't think so. `at` only works for Maps and not for lists afaik |
| 12:32:11 | × | CiaoSen quits (~Jura@2a05:5800:2d9:1600:ca4b:d6ff:fec1:99da) (Ping timeout: 260 seconds) |
| 12:33:56 | → | JeremyB99 joins (~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) |
| 12:34:01 | <dminuoso_> | Ah. Mmm. |
| 12:34:20 | <dminuoso_> | Oh, I did read your initial question wrong too, you dont mean to delete with Nothing. |
| 12:36:47 | × | JeremyB99 quits (~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) (Read error: Connection reset by peer) |
| 12:37:01 | × | danse-nr3 quits (~danse@151.47.50.89) (Ping timeout: 245 seconds) |
| 12:37:38 | <dminuoso_> | Tisoxin: To continue on ncf's points, a Lens then is just a (forall f. Functor f => (a -> f b) -> s -> f t) - and the rationale here is that instead of focusing on "multiple" points (where you have to combine the effects via Applicative), it focus only on a single thing. |
| 12:37:49 | <dminuoso_> | Which is why you only have Functor (since no combination of effects occur) |
| 12:37:51 | <dminuoso_> | > (1, 2) & _1 `id` (\x -> Just (x + 1)) |
| 12:37:52 | <lambdabot> | Just (2,2) |
| 12:39:06 | <Tisoxin> | hm, ok; thanks |
| 12:39:27 | → | simendsjo joins (~user@84.209.170.3) |
| 12:41:09 | → | danse-nr3 joins (~danse@151.47.50.89) |
| 12:41:13 | → | JeremyB99 joins (~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) |
| 12:43:24 | <dminuoso_> | % data Vec3 a b c = Vec3 a b c |
| 12:43:24 | <yahb2> | <no output> |
| 12:43:36 | <dminuoso_> | % traverseV3 f = \(Vec3 a b c) -> Vec3 <$> f a <*> f b <*> f c |
| 12:43:37 | <yahb2> | <no output> |
| 12:43:40 | <dminuoso_> | % l1 f = \(Vec3 a b c) -> (\x -> Vec3 x b c) <$> f a |
| 12:43:40 | <yahb2> | <no output> |
| 12:43:44 | <dminuoso_> | % l1 f = \(Vec3 a b c) -> (\x -> Vec3 x b c) <$> f a |
| 12:43:44 | <yahb2> | <no output> |
| 12:43:50 | <dminuoso_> | err that one should have been named l2. |
| 12:44:07 | <dminuoso_> | Tisoxin: ^- Do you see how Lens is a sort of degenerate traversal that doesnt run over the entire thing? |
| 12:44:51 | <dminuoso_> | % l1 f = \(Vec3 a b c) -> (\x -> Vec3 x b c) <$> f a |
| 12:44:51 | <yahb2> | <no output> |
| 12:44:54 | <dminuoso_> | % l2 f = \(Vec3 a b c) -> (\x -> Vec3 a x c) <$> f b |
| 12:44:55 | <yahb2> | <no output> |
| 12:51:08 | → | akegalj joins (~akegalj@78-1-167-210.adsl.net.t-com.hr) |
| 12:51:17 | × | JeremyB99 quits (~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) (Read error: Connection reset by peer) |
| 12:51:50 | <Tisoxin> | > Tisoxin: ^- Do you see how Lens is a sort of degenerate traversal that doesnt run over the entire thing? |
| 12:51:50 | <Tisoxin> | yes |
| 12:51:51 | <lambdabot> | <hint>:1:10: error: parse error on input ‘^-’ |
| 12:55:29 | × | jespada quits (~jespada@cpc121308-nmal25-2-0-cust15.19-2.cable.virginm.net) (Read error: Connection reset by peer) |
| 12:55:32 | → | jespada_ joins (~jespada@cpc121308-nmal25-2-0-cust15.19-2.cable.virginm.net) |
| 12:55:41 | × | tromp quits (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: Textual IRC Client: www.textualapp.com) |
| 12:56:46 | → | azimut joins (~azimut@gateway/tor-sasl/azimut) |
| 12:57:13 | → | JeremyB99 joins (~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) |
| 12:58:04 | → | tromp joins (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) |
| 12:59:26 | × | JeremyB99 quits (~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) (Read error: Connection reset by peer) |
| 13:03:18 | → | JeremyB99 joins (~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) |
| 13:09:40 | → | [itchyjunk] joins (~itchyjunk@user/itchyjunk/x-7353470) |
| 13:11:46 | → | zetef joins (~quassel@95.77.17.251) |
| 13:13:03 | × | JeremyB99 quits (~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) (Read error: Connection reset by peer) |
| 13:13:31 | × | [_] quits (~itchyjunk@user/itchyjunk/x-7353470) (Ping timeout: 268 seconds) |
| 13:16:15 | → | JeremyB99 joins (~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) |
| 13:16:29 | × | JeremyB99 quits (~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) (Read error: Connection reset by peer) |
| 13:17:03 | → | sawilagar joins (~sawilagar@user/sawilagar) |
| 13:17:27 | × | sawilagar quits (~sawilagar@user/sawilagar) (Remote host closed the connection) |
| 13:17:50 | → | sawilagar joins (~sawilagar@user/sawilagar) |
| 13:18:05 | → | JeremyB99 joins (~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) |
| 13:22:57 | × | JeremyB99 quits (~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) (Read error: Connection reset by peer) |
| 13:23:16 | → | JeremyB99 joins (~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) |
| 13:23:34 | → | rgh joins (~ritog@45.112.243.193) |
| 13:25:59 | × | JeremyB99 quits (~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) (Read error: Connection reset by peer) |
| 13:26:43 | → | JeremyB99 joins (~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) |
| 13:29:43 | → | pastly joins (~pastly@gateway/tor-sasl/pastly) |
| 13:35:44 | × | JeremyB99 quits (~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) (Read error: Connection reset by peer) |
| 13:36:26 | rgh | is now known as ritog |
| 13:36:33 | ritog | is now known as rito |
| 13:37:49 | → | CiaoSen joins (~Jura@2a05:5800:2d9:1600:ca4b:d6ff:fec1:99da) |
| 13:38:55 | × | iqubic quits (~avi@2601:602:9502:c70:7ce7:f8c:f1d2:dccf) (Ping timeout: 260 seconds) |
| 13:40:46 | → | JeremyB99 joins (~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) |
| 13:40:59 | × | JeremyB99 quits (~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) (Read error: Connection reset by peer) |
| 13:43:09 | <haskellbridge> | 12<Benno Fünfstück> @djinn (a -> b) -> [a] -> [b] |
| 13:44:29 | <ncf> | can't djinn from the bridge |
| 13:44:38 | × | gabiruh quits (~gabiruh@vps19177.publiccloud.com.br) (Ping timeout: 260 seconds) |
| 13:46:37 | × | danse-nr3 quits (~danse@151.47.50.89) (Read error: Connection reset by peer) |
| 13:47:26 | × | misterfish quits (~misterfis@87.215.131.102) (Ping timeout: 260 seconds) |
| 13:50:18 | <haskellbridge> | 12<Benno Fünfstück> sad :( is there an online versoin of djinn somewhere |
| 13:51:49 | <xerox> | on irc |
| 13:52:06 | → | gabiruh joins (~gabiruh@vps19177.publiccloud.com.br) |
| 13:53:43 | × | phma quits (phma@2001:5b0:210d:4b88:db07:55ae:ef67:3fd5) (Read error: Connection reset by peer) |
| 13:54:05 | → | bennofs joins (~bennofs@141.76.100.206) |
| 13:54:06 | × | ft quits (~ft@p508dbe71.dip0.t-ipconnect.de) (Ping timeout: 245 seconds) |
| 13:54:31 | → | phma joins (~phma@host-67-44-208-166.hnremote.net) |
| 13:54:58 | → | JeremyB99 joins (~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) |
| 13:55:32 | <probie> | @djinn (a -> b) -> [a] -> [b] |
| 13:55:33 | <lambdabot> | Error: Undefined type [] |
| 13:55:53 | → | ft joins (~ft@p4fc2a395.dip0.t-ipconnect.de) |
| 13:58:57 | → | danse-nr3 joins (~danse@151.47.50.89) |
| 13:59:31 | <ncf> | https://www.hedonisticlearning.com/djinn/ ? |
| 14:01:48 | <danse-nr3> | interesting, looks like an alternative to hoogle |
| 14:02:34 | <danse-nr3> | oh, no, > Generate Haskell code from a type |
| 14:03:14 | × | Xyloes quits (~wyx@2400:dd01:103a:1012:5923:33ce:7857:fc04) (Quit: Konversation terminated!) |
| 14:04:37 | <akegalj> | I ran into augustss implementation of BASIC http://augustss.blogspot.com/search/label/BASIC but I can't figure out why line "10 GOSUB 1000" works? How can this be valid? Source is here https://hackage.haskell.org/package/BASIC-0.1.5.0/docs/src/Language-BASIC-Parser.html#getBASIC and its pretty short. How can number 10 come before GOSUB. What magic is this? |
| 14:06:00 | × | JeremyB99 quits (~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) (Read error: Connection reset by peer) |
| 14:06:29 | <exarkun> | akegalj: What would you say type of the numeric literal `10` is? |
| 14:08:50 | <akegalj> | exarkun: I can't even guess. I would guess it is Num a |
| 14:09:10 | <exarkun> | akegalj: What if, instead of `10`, that line had `f`? As in, `f GOSUB 1000`? |
| 14:09:13 | <exarkun> | What's the type of f? |
| 14:09:23 | → | JeremyB99 joins (~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) |
| 14:10:11 | <akegalj> | exarkun: f would be some function in this case as its bound to some type variable. But its not literal |
| 14:10:47 | <exarkun> | "f would be some function" -> indeed. I'm not sure what you mean by "its bound to some type variable". |
| 14:11:14 | × | danse-nr3 quits (~danse@151.47.50.89) (Ping timeout: 260 seconds) |
| 14:11:43 | <exarkun> | How do you figure f would be a function just by looking at that expression? |
| 14:11:55 | <akegalj> | exarkun: ignore type variable part |
| 14:12:42 | <akegalj> | exarkun: its function becouse it takes two arguments, right ? |
| 14:12:56 | <exarkun> | Yea |
| 14:13:01 | <akegalj> | its applied to them by type aplication " " |
| 14:13:08 | <exarkun> | yep |
| 14:13:58 | <akegalj> | that doesn't make me less confused :D |
| 14:14:20 | <akegalj> | is 10 a function ? |
| 14:14:42 | × | JeremyB99 quits (~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) (Read error: Connection reset by peer) |
| 14:16:32 | <exarkun> | If `f x y` is function application to two arguments and the type checker accepts `10 x y` then ...? |
| 14:17:06 | <akegalj> | exarkun: which type checker? Haskells ? |
| 14:17:53 | × | bennofs quits (~bennofs@141.76.100.206) (Quit: Connection closed) |
| 14:18:24 | <exarkun> | akegalj: yea |
| 14:18:31 | → | JeremyB99 joins (~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) |
| 14:19:11 | → | danse-nr3 joins (~danse@151.47.50.89) |
| 14:19:23 | <exarkun> | akegalj: We can narrow down the type a bit. It's not just a function, but a function of two arguments, and those arguments have particular types. |
| 14:20:19 | <exarkun> | Like, GOSUB is a constructor for GOTO |
| 14:21:23 | × | dcoutts quits (~duncan@cpc69402-oxfd27-2-0-cust903.4-3.cable.virginm.net) (Ping timeout: 260 seconds) |
| 14:21:25 | → | dcoutts_ joins (~duncan@cpc69402-oxfd27-2-0-cust903.4-3.cable.virginm.net) |
| 14:21:47 | <exarkun> | And we probably know something about its return type because the way you use this thing is with `runBASIC`' which accepts a value of `BASIC` (an alias for `Expr ()`) |
| 14:22:10 | <exarkun> | So given that, what's a narrower type for `f` in `f GOSUB 1000`? |
| 14:22:12 | × | JeremyB99 quits (~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) (Read error: Connection reset by peer) |
| 14:22:25 | <akegalj> | exarkun: Its Expr () |
| 14:22:44 | → | thegeekinside joins (~thegeekin@189.141.65.247) |
| 14:22:59 | <exarkun> | `f GOSUB 1000` is, yea. How about `f` by itself? |
| 14:24:21 | → | Unicorn_Princess joins (~Unicorn_P@user/Unicorn-Princess/x-3540542) |
| 14:24:22 | <akegalj> | exarkun: I can't tell . Its f :: a -> b -> Expr () |
| 14:24:35 | <akegalj> | exarkun: where is this Expr defined? |
| 14:24:59 | <exarkun> | Expr is in Types.hs |
| 14:25:26 | <probie> | https://hackage.haskell.org/package/BASIC-0.1.5.0/docs/src/Language-BASIC-Types.html |
| 14:25:38 | <exarkun> | `f :: a -> b -> Expr ()` is right but we can narrow it further. We saw GOSUB as a value for the first parameter, so we know `a` must be the type of GOSUB. |
| 14:26:38 | → | JeremyB99 joins (~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) |
| 14:27:14 | <probie> | exarkun: I think you mean of type `GOTO`. `data GOTO = GOTO | GOSUB deriving (Eq)` |
| 14:27:53 | <akegalj> | exarkun: yes, then is `f :: GOTO -> b -> Expr ()` |
| 14:28:15 | <exarkun> | sorry yea. I mean whatever type `GOSUB` is must be the same as `a`. so, indeed, GOTO. |
| 14:28:25 | <akegalj> | I guess this fits into `Cmd Integer Command [Expr a]` of the Expr type |
| 14:30:10 | × | 040AADFUL quits (~nand@haasn.dev) (Killed (NickServ (GHOST command used by haasn!sid579015@id-579015.hampstead.irccloud.com))) |
| 14:30:28 | <exarkun> | akegalj: Yea, getting close |
| 14:30:30 | → | haasn` joins (~nand@haasn.dev) |
| 14:30:49 | × | idgaen quits (~idgaen@2a01:e0a:498:fd50:fcc6:bb5d:489a:ce8c) (Quit: WeeChat 4.1.1) |
| 14:30:50 | × | zetef quits (~quassel@95.77.17.251) (Ping timeout: 256 seconds) |
| 14:31:03 | × | haasn` quits (~nand@haasn.dev) (Remote host closed the connection) |
| 14:32:29 | <byorgey> | akegalj: In Haskell, what type is 10? |
| 14:32:42 | <exarkun> | So in, eg, the Func.hs example, we've got this do block full of similar things. Since these things return `Expr ()` and we use them in a `do` block, do we know something else about `Expr`? |
| 14:33:31 | <danse-nr3> | % :t 10 -- this byorgey? |
| 14:33:31 | <yahb2> | 10 -- this byorgey? :: Num a => a |
| 14:34:26 | <cheater> | if i have two types, Foo and Bar that take the same kind of parameters (say 5 int parameters), can i somehow make the constructor a variable when creating the value with the constructor? something like x 1 2 3 4 5 |
| 14:35:06 | <danse-nr3> | yeah but maybe wrap the types in a product first |
| 14:35:14 | <akegalj> | exarkun: sorry, where is Func.hs? |
| 14:35:18 | <exarkun> | akegalj: https://hackage.haskell.org/package/BASIC-0.1.5.0/src/examples/Func.hs |
| 14:35:32 | <exarkun> | just an arbitrary but specific example of using the library |
| 14:36:03 | <cheater> | duh, put the constructor in a variable |
| 14:36:04 | <exarkun> | although it doesn't use GOSUB so maybe not the bet choice |
| 14:36:05 | × | JeremyB99 quits (~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) (Read error: Connection reset by peer) |
| 14:36:14 | → | billchenchina joins (~billchenc@2a0d:2580:ff0c:1:e3c9:c52b:a429:5bfe) |
| 14:36:17 | × | billchenchina quits (~billchenc@2a0d:2580:ff0c:1:e3c9:c52b:a429:5bfe) (Remote host closed the connection) |
| 14:36:36 | <akegalj> | exarkun: ... sec ... to check that |
| 14:36:58 | <exarkun> | Maybe https://hackage.haskell.org/package/BASIC-0.1.5.0/src/examples/HiLo.hs is closer to what you were looking at originally? |
| 14:37:17 | <exarkun> | oh yea, I think that's the same example as from the blog post |
| 14:37:22 | → | JeremyB99 joins (~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) |
| 14:37:57 | → | machinedgod joins (~machinedg@modemcable243.147-130-66.mc.videotron.ca) |
| 14:38:11 | <akegalj> | exarkun: yes, that's the same example |
| 14:40:09 | <akegalj> | exarkun: I think I am confused with "parsing" part from Language.BASIC.Parser . I ll try to play around and see if I can figure this out. Fortunately example is quite short but I guess my mind can't bend over this one |
| 14:40:25 | <exarkun> | akegalj: I think there's basically one more leap to make |
| 14:40:55 | <exarkun> | I haven't hinted at it much yet because I want to let you figure out the surprise :) |
| 14:41:02 | <cheater> | hm no that didn't work |
| 14:41:10 | <cheater> | the two constructors are from different types |
| 14:41:50 | <exarkun> | akegalj: You're on the right track thinking about `Cmd`. Keep thinking about that `f :: GOTO -> b -> Expr ()` type also. |
| 14:42:06 | <exarkun> | And pay attention to the instances that Parser.hs defines |
| 14:42:44 | <akegalj> | exarkun: thanks for hand holding, will play in repl to figure it out |
| 14:43:36 | <exarkun> | np, have fun |
| 14:46:09 | × | seeg123456 quits (~seeg12345@64.176.64.83) (Quit: Gateway shutdown) |
| 14:46:45 | <danse-nr3> | maybe now we have more bandwidth cheater ... i was thinking that maybe i was wrong pointing to a product, could be a case for composition |
| 14:47:11 | <cheater> | think about it this way |
| 14:47:12 | × | JeremyB99 quits (~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) (Read error: Connection reset by peer) |
| 14:48:06 | <cheater> | data Foo = Foo Int deriving Show; data Bar = Bar Int deriving Show; if bool then show (Foo 2) else show (Bar 2) |
| 14:48:27 | → | nate4 joins (~nate@c-98-45-158-125.hsd1.ca.comcast.net) |
| 14:48:41 | <cheater> | i want this to be something like: let x = if bool then Foo else Bar; show (x 2) |
| 14:49:03 | → | JeremyB99 joins (~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) |
| 14:49:14 | <danse-nr3> | show $ if ? |
| 14:49:42 | <danse-nr3> | hum maybe that does not type check actually |
| 14:51:32 | <danse-nr3> | no it does not |
| 14:52:11 | <cheater> | yeah |
| 14:52:29 | <danse-nr3> | but `show` takes a constraint, i guess we should make an example with something else, as you probably do not want to use a class |
| 14:53:44 | × | nate4 quits (~nate@c-98-45-158-125.hsd1.ca.comcast.net) (Ping timeout: 268 seconds) |
| 14:55:53 | → | seeg123456 joins (~seeg12345@64.176.64.83) |
| 14:56:54 | × | simendsjo quits (~user@84.209.170.3) (Ping timeout: 252 seconds) |
| 14:57:52 | × | JeremyB99 quits (~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) (Read error: Connection reset by peer) |
| 14:58:46 | <akegalj> | exarkun: byorgey: aha, the whole trickery is to implement instances of functions over Num typeclasses . When I reread I saw byorgey simple question "what type is 10" :D |
| 15:00:58 | → | JeremyB99 joins (~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) |
| 15:01:06 | <akegalj> | do people tend to write DSLs using these tricks or is this not so common ? |
| 15:01:13 | × | JeremyB99 quits (~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) (Read error: Connection reset by peer) |
| 15:02:44 | <exarkun> | I think this style is a fun joke that would practically never be used for serious code |
| 15:04:17 | → | JeremyB99 joins (~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) |
| 15:05:09 | × | euleritian quits (~euleritia@77.22.252.56) (Ping timeout: 252 seconds) |
| 15:05:34 | → | euleritian joins (~euleritia@dynamic-002-247-248-235.2.247.pool.telefonica.de) |
| 15:05:43 | <kuribas> | The problem with overly polymorphic code is that it can often compile, but into something different than intended. |
| 15:06:07 | <kuribas> | Also function monad or Num instance is pretty hard to read. |
| 15:06:57 | <danse-nr3> | i find function applicative legit at least. Num instance... a bit more edgy |
| 15:07:40 | <kuribas> | Meh, 99% of obfuscated code examples are using the function applicative/monad. |
| 15:08:08 | <kuribas> | If you really want this, insert a Reader newtype to make it explicit. |
| 15:08:26 | <exarkun> | Also the Num instance in BASIC is trivially unlawful. It only provides fromInteger. And I'm not sure why the empty Eq and Show instances are there, but they have no implementation at all. |
| 15:08:51 | <probie> | exarkun: Once upon a time, Haskell required both `Eq` and `Show` for `Num` |
| 15:08:55 | <exarkun> | Could you implement the rest of them? I'm not sure. Probably not in a very meaningful or coherent way. |
| 15:09:01 | <exarkun> | probie: Ah |
| 15:09:54 | <exarkun> | akegalj: More concretely, the types say you can do `negate $ 10 GOTO 20` it will just crash at runtime if you try. Also, what could it even mean? |
| 15:10:15 | <exarkun> | I mean .. maybe `negate $ 10 GOTO 20` should be the same as `20 COMEFROM 10`? :) But in general it's nonsense. |
| 15:10:16 | × | JeremyB99 quits (~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) (Read error: Connection reset by peer) |
| 15:10:40 | <exarkun> | (actually 20 COMEFROM 10 probably equals 10 GOTO 20, maybe I meant 10 COMEFROM 20) |
| 15:10:43 | → | zetef joins (~quassel@95.77.17.251) |
| 15:13:08 | <kuribas> | exarkun: intercal? |
| 15:14:39 | <exarkun> | as legit a choice as BASIC! |
| 15:15:11 | <exarkun> | (well maybe not) |
| 15:15:14 | → | JeremyB99 joins (~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) |
| 15:15:19 | <akegalj> | exarkun: yes, I saw they are not lawful. Fun example no matter what |
| 15:15:25 | × | JeremyB99 quits (~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) (Read error: Connection reset by peer) |
| 15:20:43 | → | wib_jonas joins (~wib_jonas@business-37-191-60-209.business.broadband.hu) |
| 15:22:54 | → | misterfish joins (~misterfis@84-53-85-146.bbserv.nl) |
| 15:25:27 | → | JeremyB99 joins (~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) |
| 15:25:56 | × | JeremyB99 quits (~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) (Read error: Connection reset by peer) |
| 15:35:17 | × | alp_ quits (~alp@2001:861:e3d6:8f80:59a0:3738:2d56:41bc) (Ping timeout: 252 seconds) |
| 15:37:26 | → | alp_ joins (~alp@2001:861:e3d6:8f80:c0c9:d001:c090:e9f8) |
| 15:43:58 | → | JeremyB99 joins (~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) |
| 15:44:40 | × | bitdex quits (~bitdex@gateway/tor-sasl/bitdex) (Quit: = "") |
| 15:45:05 | → | iqubic joins (~avi@2601:602:9502:c70:3f43:b574:9cc8:e2f) |
| 15:48:16 | × | JeremyB99 quits (~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) (Read error: Connection reset by peer) |
| 15:50:34 | → | JeremyB99 joins (~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) |
| 15:51:10 | × | chomwitt quits (~chomwitt@2a02:587:7a09:c300:1ac0:4dff:fedb:a3f1) (Ping timeout: 246 seconds) |
| 15:53:16 | × | CiaoSen quits (~Jura@2a05:5800:2d9:1600:ca4b:d6ff:fec1:99da) (Ping timeout: 245 seconds) |
| 15:57:26 | × | zetef quits (~quassel@95.77.17.251) (Ping timeout: 245 seconds) |
| 15:58:41 | × | danse-nr3 quits (~danse@151.47.50.89) (Ping timeout: 245 seconds) |
| 15:58:52 | → | danse-nr3 joins (~danse@rm-19-41-115.service.infuturo.it) |
| 16:02:20 | × | JeremyB99 quits (~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) (Read error: Connection reset by peer) |
| 16:06:25 | × | machinedgod quits (~machinedg@modemcable243.147-130-66.mc.videotron.ca) (Remote host closed the connection) |
| 16:06:31 | → | JeremyB99 joins (~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) |
| 16:06:48 | → | notzmv joins (~zmv@user/notzmv) |
| 16:08:11 | × | JeremyB99 quits (~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) (Read error: Connection reset by peer) |
| 16:08:35 | → | zetef joins (~quassel@95.77.17.251) |
| 16:10:07 | <iqubic> | ski: I think you can use forall for existential qualification and fake heterogeneous lists. |
| 16:11:33 | <iqubic> | data Showable = forall s. Show s => S s |
| 16:12:04 | <iqubic> | And then you can have [Showable]. |
| 16:12:34 | × | euleritian quits (~euleritia@dynamic-002-247-248-235.2.247.pool.telefonica.de) (Read error: Connection reset by peer) |
| 16:12:39 | <iqubic> | But the only thing you can do with the elements of that list is call the Show methods on them. |
| 16:12:51 | → | euleritian joins (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) |
| 16:13:08 | × | euleritian quits (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Read error: Connection reset by peer) |
| 16:13:56 | → | euleritian joins (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) |
| 16:16:49 | → | JeremyB99 joins (~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) |
| 16:17:01 | × | JeremyB99 quits (~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) (Read error: Connection reset by peer) |
| 16:19:31 | × | akegalj quits (~akegalj@78-1-167-210.adsl.net.t-com.hr) (Ping timeout: 245 seconds) |
| 16:20:37 | <byorgey> | glguy: I did part 2 with a lazy recursively defined list, kind of ad-hoc though. I didn't figure out a way to formulate it as a scanr or anything. https://github.com/byorgey/AoC/blob/master/2023/04/04.hs#L49 |
| 16:21:17 | <glguy> | byorgey: I think the benefit of scanr would have been lost by having to post-process the result with map (take 1) |
| 16:21:59 | <byorgey> | maybe so |
| 16:22:07 | <xerox> | nice sprinkling of >>> |
| 16:22:49 | <byorgey> | I always sprinkle >>> when solving programming challenges, but never use it in real projects =) |
| 16:22:55 | × | lortabac quits (~lortabac@2a01:e0a:541:b8f0:55ab:e185:7f81:54a4) (Quit: WeeChat 4.1.1) |
| 16:23:50 | <danse-nr3> | >>> considered harmful? |
| 16:23:53 | → | szkl joins (uid110435@id-110435.uxbridge.irccloud.com) |
| 16:24:11 | <byorgey> | not at all, just a style thing |
| 16:24:44 | <xerox> | my heat of the moment one was like this https://github.com/mrtnpaolo/advent-of-code-2023/blob/5e8feb7/execs/Day04.hs#L37-L42 |
| 16:25:47 | <byorgey> | ah, nice |
| 16:26:43 | × | qqq quits (~qqq@92.43.167.61) (Quit: leaving) |
| 16:26:49 | <xerox> | wished there was an insertwith that also returns the possibly different eventually inserted value |
| 16:28:16 | → | JeremyB99 joins (~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) |
| 16:28:40 | <byorgey> | I feel like there must be a way to do that in one line with lens combinators. |
| 16:29:44 | <ski> | iqubic : yes, `[Showable]' encodes `[exists s. Show s *> s]' |
| 16:29:54 | <ncf> | i used löb https://github.com/ncfavier/aoc/blob/main/src/2023/Day04.hs |
| 16:29:58 | <ski> | "ut the only thing you can do with the elements of that list is call the Show methods on them." -- yes |
| 16:30:28 | <xerox> | löve that |
| 16:31:21 | <byorgey> | ncf: fantastic |
| 16:32:22 | × | JeremyB99 quits (~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) (Read error: Connection reset by peer) |
| 16:33:26 | <ski> | ncf : each one depends on the following `n' ? |
| 16:33:41 | <ncf> | yes |
| 16:33:58 | <ski> | sounds like a course-of-values recursion could also be used there, then |
| 16:35:09 | <ncf> | yes that's what glguy did |
| 16:35:15 | <glguy> | https://github.com/glguy/advent/blob/main/solutions/src/2023/04.hs#L57-L60 |
| 16:35:23 | <ski> | mhm |
| 16:36:16 | → | JeremyB99 joins (~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) |
| 16:36:28 | → | dhil joins (~dhil@2001:8e0:2014:3100:5872:f936:bc7a:ceb8) |
| 16:36:50 | × | JeremyB99 quits (~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) (Read error: Connection reset by peer) |
| 16:36:59 | <ncf> | re lens, probably something with (<%~) |
| 16:37:51 | × | misterfish quits (~misterfis@84-53-85-146.bbserv.nl) (Ping timeout: 256 seconds) |
| 16:38:01 | × | danse-nr3 quits (~danse@rm-19-41-115.service.infuturo.it) (Ping timeout: 255 seconds) |
| 16:39:00 | <cheater> | what are those directories called ~/.ghcup/hls/1.2.3.4 ? i mean i know they're related to the hls, but how do i get rid of them? i have two, one's called 2.4.0.0 and the other called 1.9.0.0. i guess i don't need both, so how do i get rid of one? they're 2 gigs a pop |
| 16:39:47 | <glguy> | cheater: if you use "ghcup tui", you can uninstall things with the u key |
| 16:40:30 | <ncf> | insertWith' f k v = at k <%~ \x -> f v <$> x <|> Just v |
| 16:40:34 | <glguy> | While you're there you can uninstall both and upgrade to 2.5.0.0 if you want |
| 16:40:35 | <cheater> | is there any reason at all to have two different versions of hls? |
| 16:40:58 | <haskellbridge> | 14<maerwald> Yes |
| 16:41:18 | <haskellbridge> | 14<maerwald> Hls 2.5.0.0 doesn't support GHC 9.4.7 anymore |
| 16:41:45 | <haskellbridge> | 14<maerwald> If you use vscode, it can downgrade automatically if your project GHC is e.g. 9.4.7 |
| 16:42:17 | <cheater> | https://i.imgur.com/S2VPCmH.png |
| 16:42:19 | <glguy> | are a lot of projects that use 9.4.7 not compatible with 9.4.8? |
| 16:42:28 | <cheater> | i honestly don't even use hls at all right now |
| 16:42:41 | <cheater> | i might look into setting it up with vim |
| 16:43:13 | <glguy> | I use it both with vim and vscode - it's pretty useful |
| 16:43:31 | × | juri_ quits (~juri@faikvm.com) (Ping timeout: 255 seconds) |
| 16:43:42 | <ncf> | insertWith'' f k v = alterF (\x -> let x' = maybe (f v) v x in (x, Just x)) k |
| 16:44:29 | <ncf> | er |
| 16:44:37 | <ncf> | insertWith'' f k v = alterF (\x -> let x' = maybe v (f v) x in (x', Just x')) k |
| 16:44:48 | <iqubic> | I haven't updated to 9.6.2 because jle's advent-of-code-api fails to work with newer versions of transformers. I think it's something to do with liftIO not being re-exported. |
| 16:45:08 | <iqubic> | jle`: you might want to fix this. |
| 16:45:43 | → | Guest87 joins (~Guest87@2409:11:1420:a600:fc27:c511:dd24:c407) |
| 16:46:23 | × | Guest87 quits (~Guest87@2409:11:1420:a600:fc27:c511:dd24:c407) (Client Quit) |
| 16:46:32 | <cheater> | what is the haskellbridge bridging towards |
| 16:46:59 | <yushyin> | matrix |
| 16:47:57 | <yushyin> | the room name is haskell-irc, iirc |
| 16:48:38 | <cheater> | OK |
| 16:49:14 | → | chomwitt joins (~chomwitt@2a02:587:7a09:c300:1ac0:4dff:fedb:a3f1) |
| 16:49:19 | × | YoungFrog quits (~youngfrog@2a02:a03f:ca07:f900:1f5c:a3c6:297:feeb) (Ping timeout: 260 seconds) |
| 16:49:58 | <geekosaur> | yes |
| 16:50:25 | → | juri_ joins (~juri@faikvm.com) |
| 16:50:57 | <geekosaur> | if you /whois haskellbridge it'll give you some more information |
| 16:51:21 | <yushyin> | nice |
| 16:51:24 | <geekosaur> | although there isn't enough room to list all the bridged channels and where they go |
| 16:53:23 | <geekosaur> | hm, didn't include matrix in that, should fix that |
| 16:53:59 | × | zetef quits (~quassel@95.77.17.251) (Ping timeout: 264 seconds) |
| 16:54:03 | <cheater> | geekosaur: the /whois doesn't tell me anything |
| 16:56:23 | <ski> | -!- ircname : Haskell matterbridge operated by geekosaur |
| 16:56:54 | <geekosaur> | it tells you the important part which is who to contact for more information |
| 16:56:57 | <cheater> | yeah i saw that |
| 16:57:03 | <cheater> | but i already knew that part |
| 16:57:07 | <geekosaur> | as I said, there isn;'t enough room (IRC limits) to really say more |
| 16:57:08 | <cheater> | since you're the one who told me about it |
| 16:57:10 | <cheater> | lol |
| 16:57:32 | <cheater> | try setting your ircname to "Haskell chat bridge https://tiny.co/blah" |
| 16:57:54 | → | YoungFrog joins (~youngfrog@2a02:a03f:ca07:f900:1f5c:a3c6:297:feeb) |
| 17:00:53 | → | TMA joins (tma@twin.jikos.cz) |
| 17:01:11 | → | JeremyB99 joins (~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) |
| 17:01:23 | × | JeremyB99 quits (~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) (Read error: Connection reset by peer) |
| 17:02:31 | <trev> | glguy: can you explain to me (a dummy) how your part 2 works? even printing out the accumulator each fold, i still can't grasp it :| |
| 17:02:31 | × | wib_jonas quits (~wib_jonas@business-37-191-60-209.business.broadband.hu) (Quit: Client closed) |
| 17:03:23 | <glguy> | trev: it's building up a list of how many total cards you get by playing one of each card in the list |
| 17:04:24 | <glguy> | so you start with: wins_on_card_1 : wins_on_card_2 : ... : [] |
| 17:04:49 | <glguy> | the output in each position is how many cards one of that card turns into |
| 17:05:06 | → | idgaen joins (~idgaen@2a01:e0a:498:fd50:fcc6:bb5d:489a:ce8c) |
| 17:05:15 | → | euandreh joins (~Thunderbi@189.6.18.26) |
| 17:05:17 | <glguy> | foldr replaces all of those : constructors in the input with a function |
| 17:05:43 | <glguy> | The function takes two things: the number of wins on the current card and the output list for all cards following it |
| 17:06:03 | <glguy> | It extends that output list by one element, that element is the number of cards this card will turn into |
| 17:06:07 | × | iqubic quits (~avi@2601:602:9502:c70:3f43:b574:9cc8:e2f) (Ping timeout: 260 seconds) |
| 17:07:00 | → | JeremyB99 joins (~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) |
| 17:07:53 | <glguy> | f wins_1 (f wins_2 (f wins_3 [])) ==> f wins_1 (f wins_2 [output_3]) ==> f wins_1 [output_2, output_3] ==> [output_1, output_2, output_3] |
| 17:08:02 | <trev> | i guess i don't even understand the first iteration of the fold - the accumulator is [] and then you prepend `1 + sum (take wins xs)` but that should just be 1 |
| 17:08:04 | × | JeremyB99 quits (~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) (Read error: Connection reset by peer) |
| 17:08:16 | × | `2jt quits (~jtomas@90.162.208.36) (Ping timeout: 255 seconds) |
| 17:08:27 | <glguy> | The very last card in the list will necessarily have 0 wins on it |
| 17:08:46 | <glguy> | so you'll have: f 0 [] ==> 1 + sum (take 0 []) : [] ==> [1,] |
| 17:08:51 | <glguy> | s/,// |
| 17:09:19 | <trev> | ah so it's going backwards |
| 17:09:21 | <glguy> | so that last card doesn't turn into any more cards, when you play it you only play 1 card |
| 17:09:37 | × | coot quits (~coot@89-69-206-216.dynamic.chello.pl) (Quit: coot) |
| 17:10:04 | × | AlexZenon quits (~alzenon@5.139.232.120) (Ping timeout: 256 seconds) |
| 17:10:21 | → | coot joins (~coot@89-69-206-216.dynamic.chello.pl) |
| 17:10:41 | × | eggplantade quits (~Eggplanta@2600:1700:38c5:d800:d9f3:ec2f:a760:e0fe) (Remote host closed the connection) |
| 17:10:57 | → | eggplantade joins (~Eggplanta@2600:1700:38c5:d800:d9f3:ec2f:a760:e0fe) |
| 17:11:24 | <trev> | thanks. genius solution |
| 17:12:46 | × | phma quits (~phma@host-67-44-208-166.hnremote.net) (Read error: Connection reset by peer) |
| 17:12:49 | × | fendor quits (~fendor@2a02:8388:1605:d100:267b:1353:13d7:4f0c) (Remote host closed the connection) |
| 17:13:34 | → | phma joins (~phma@2001:5b0:2143:bdc8:5f21:c979:aa9:dd43) |
| 17:13:57 | <trev> | i confused myself since i'm doing it in OCaml which doesn't have tail recursion on foldr so i was using foldl and reversing the input -_- |
| 17:14:02 | × | YoungFrog quits (~youngfrog@2a02:a03f:ca07:f900:1f5c:a3c6:297:feeb) (Ping timeout: 256 seconds) |
| 17:14:17 | <glguy> | Oh, you could reverse and foldl like this just fine |
| 17:14:39 | <trev> | yeah, it works that way. i forgot about the rev and couldn't conceptualize it in my mind |
| 17:14:47 | <glguy> | ah, I see |
| 17:15:47 | → | YoungFrog joins (~youngfrog@2a02:a03f:ca07:f900:1f5c:a3c6:297:feeb) |
| 17:16:58 | <ski> | trev : "OCaml which doesn't have tail recursion on foldr" -- Haskell doesn't, either |
| 17:17:06 | → | AlexZenon joins (~alzenon@5.139.232.120) |
| 17:19:05 | → | iqubic joins (~avi@2601:602:9502:c70:dd03:78c7:a43f:a269) |
| 17:19:11 | <trev> | ski, oh then i have no idea why it wasn't working with foldr |
| 17:19:32 | <ski> | ? |
| 17:19:37 | × | coot quits (~coot@89-69-206-216.dynamic.chello.pl) (Quit: coot) |
| 17:20:52 | <trev> | ski: it just doesn't work correctly with fold_right in OCaml. No idea why right now |
| 17:21:29 | <ski> | you mean you don't get the right result ? |
| 17:21:53 | <trev> | yep |
| 17:22:52 | × | Square2 quits (~Square4@user/square) (Ping timeout: 246 seconds) |
| 17:23:00 | <ski> | hm, i don't see why it shouldn't |
| 17:23:11 | <ski> | val fold_right : ('a -> 'b -> 'b) -> 'a list -> 'b -> 'b |
| 17:23:45 | <ski> | argument ordering is slightly different, but shouldn't be a problem. it's also not incremental, but that shouldn't be needed here, afaiui |
| 17:25:15 | <trev> | i'll put the two side by side in a paste |
| 17:26:05 | <trev> | https://paste.tomsmeding.com/rqjAOycf |
| 17:26:36 | <trev> | perhaps i've been staring at it too long |
| 17:26:46 | × | kuribas quits (~user@ip-188-118-57-242.reverse.destiny.be) (Remote host closed the connection) |
| 17:27:06 | <idgaen> | in ocaml foldr can product stack overflow enough easily. But in haskell there is not this issue (there is no stack, for saying it merely). |
| 17:27:28 | → | JeremyB99 joins (~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) |
| 17:27:42 | × | JeremyB99 quits (~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) (Read error: Connection reset by peer) |
| 17:28:26 | <trev> | i don't get a stack overflow, just the wrong answer |
| 17:28:46 | <idgaen> | weird |
| 17:28:57 | → | albet70 joins (~xxx@2400:8902::f03c:92ff:fe60:98d8) |
| 17:29:26 | <idgaen> | possibly an arithmetic overflow then |
| 17:29:46 | <trev> | that is possible cause the output is a huge negative number |
| 17:30:47 | <glguy> | trev: aren't the arguments to fold_right in the wrong order in your paste? |
| 17:31:44 | <trev> | glguy: left and right have swapped args in ocaml |
| 17:32:16 | <glguy> | well your code doesn't match what ski pasted |
| 17:32:31 | <glguy> | if the type signature ski pasted is correct, then your code has the arguments in the wrong order |
| 17:32:48 | <trev> | oh wow you're right |
| 17:32:53 | <idgaen> | I'd rather like the haskell arguments order for fold… each time I tried to play with ocaml I was confused |
| 17:33:15 | <trev> | that is super annoying! |
| 17:33:28 | <trev> | now my |> won't work |
| 17:33:46 | <glguy> | good, because that direction of composition is always so awkward |
| 17:33:48 | <glguy> | :-p |
| 17:33:53 | <ncf> | how does it typecheck if the arguments are swapped? |
| 17:34:03 | <trev> | acc and [] are the same type |
| 17:34:10 | <trev> | int list |
| 17:34:13 | <ski> | idgaen : there is a stack, just not in quite the ordinary sense. also GHC will extend the stack on overflow, now, rather than crashing |
| 17:34:22 | × | loonycyborg quits (loonycybor@wesnoth/developer/loonycyborg) (Remote host closed the connection) |
| 17:34:42 | <glguy> | There goes the illusion of types helping with program correctness :-S |
| 17:34:43 | <idgaen> | ski: ok, thanks you for this information. |
| 17:34:48 | <ncf> | oh right, you're building a list |
| 17:35:02 | <ski> | trev : no, `fold_left' is the same as in Haskell |
| 17:35:08 | <ski> | val fold_left : ('a -> 'b -> 'a) -> 'a -> 'b list -> 'a |
| 17:35:31 | <ski> | (and yea, i just copied these from `ocaml') |
| 17:35:52 | <trev> | ski i meant in ocaml's fold_left and fold_right swap the two last args |
| 17:36:04 | <trev> | and also the args of the accumulator :\ |
| 17:36:07 | <ski> | idgaen : part of the point of the OCaml ordering, is to be able to say `fold_right o fold_right' or `fold_left o fold_left' |
| 17:36:50 | <ski> | .. and SML has yet another ordering |
| 17:36:56 | <trev> | what does the `o` mean ski? |
| 17:37:12 | <ski> | function composition |
| 17:37:26 | <idgaen> | ski: oh! It is for composition of function. I have never noticed |
| 17:37:29 | <ski> | val foldr : ('a * 'b -> 'b) -> 'b -> 'a list -> 'b |
| 17:37:32 | <ski> | val foldl : ('a * 'b -> 'b) -> 'b -> 'a list -> 'b |
| 17:37:47 | <ski> | in SML, they preferred to keep the signatures of both exactly the same |
| 17:37:55 | <ski> | (and uncurried the callback) |
| 17:39:27 | <ski> | @type let foldl :: (s -> a -> s) -> s -> [a] -> s; foldl = Prelude.foldl in foldl . foldl |
| 17:39:28 | <lambdabot> | (s -> a -> s) -> s -> [[a]] -> s |
| 17:39:30 | <ski> | vs. |
| 17:39:32 | <ski> | @type let foldr :: (a -> s -> s) -> s -> [a] -> s; foldr = Prelude.foldr in foldr . flip . foldr |
| 17:39:33 | <lambdabot> | (a -> s -> s) -> s -> [[a]] -> s |
| 17:39:42 | <ski> | that `flip' isn't needed in the OCaml version |
| 17:39:56 | <EvanR> | last night I finally realized this "foldr" solution, and it's very fast and sensible. But now I'm wondering if foldl' would be even faster xD |
| 17:40:34 | <EvanR> | also discussing the detailed solution the day of? |
| 17:41:11 | <ski> | @type map . map |
| 17:41:16 | <lambdabot> | (a -> b) -> [[a]] -> [[b]] |
| 17:41:18 | <ski> | @type zipWith . zipWith |
| 17:41:19 | <idgaen> | I used to use foldl' unless if lazyness or I build a list. In these last case foldr is better, I feel. |
| 17:41:19 | <lambdabot> | (a -> b -> c) -> [[a]] -> [[b]] -> [[c]] |
| 17:41:38 | <EvanR> | you can build a list backwards with foldl' very fast xD |
| 17:42:00 | <EvanR> | i.e. what is required here |
| 17:42:31 | <idgaen> | depends I you want keep the original order. |
| 17:42:34 | <ski> | > foldl' (flip (:)) [] [0 ..] -- very fast infinite list building |
| 17:42:40 | <lambdabot> | mueval-core: Time limit exceeded |
| 17:43:00 | <EvanR> | laziness doesn't help with memory usage in this one |
| 17:44:17 | <EvanR> | if you build list L backwards, it is in the right order still |
| 17:44:21 | × | tromp quits (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…) |
| 17:44:31 | <EvanR> | i.e. start with the last element and prepend second to last element, etc |
| 17:44:53 | → | econo_ joins (uid147250@id-147250.tinside.irccloud.com) |
| 17:47:48 | → | JeremyB99 joins (~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) |
| 17:48:17 | → | tzh joins (~tzh@c-71-193-181-0.hsd1.or.comcast.net) |
| 17:49:11 | × | JeremyB99 quits (~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) (Read error: Connection reset by peer) |
| 17:52:34 | × | CrunchyFlakes quits (~CrunchyFl@ip92348280.dynamic.kabel-deutschland.de) (Ping timeout: 276 seconds) |
| 17:52:42 | → | JeremyB99 joins (~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) |
| 17:53:42 | → | CrunchyFlakes joins (~CrunchyFl@ip92348280.dynamic.kabel-deutschland.de) |
| 17:53:44 | <EvanR> | I just tried and it has no effect on runtime, maybe because everything else in the program is much slower, maybe because optimizer thinks they are equivalent |
| 17:53:53 | <EvanR> | or both |
| 17:54:35 | → | Square joins (~Square@user/square) |
| 17:54:37 | <EvanR> | but the foldl' version has simpler code, and I'd like to ask for input on beautifying my foldr code, but only if the spoiler period is over |
| 17:54:48 | × | pavonia quits (~user@user/siracusa) (Quit: Bye!) |
| 17:55:25 | <EvanR> | or by the time I get back from the DMV I'll have figured it out xD |
| 17:56:08 | <trev> | my bad for bringing up the solution so early. it was eating at me |
| 17:57:27 | × | JeremyB99 quits (~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) (Read error: Connection reset by peer) |
| 18:00:01 | <idgaen> | trev: I'm happy, I joined too lately for looking at your solution ;) |
| 18:02:07 | → | JeremyB99 joins (~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) |
| 18:02:08 | × | euleritian quits (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Read error: Connection reset by peer) |
| 18:02:08 | × | JeremyB99 quits (~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) (Read error: Connection reset by peer) |
| 18:02:56 | × | adium quits (adium@user/adium) (Excess Flood) |
| 18:03:01 | → | euleritian joins (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) |
| 18:04:59 | → | adium joins (adium@user/adium) |
| 18:09:32 | → | akegalj joins (~akegalj@141-136-219-144.dsl.iskon.hr) |
| 18:10:42 | → | AlexNoo_ joins (~AlexNoo@5.139.232.120) |
| 18:12:26 | → | JeremyB99 joins (~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) |
| 18:13:14 | × | JeremyB99 quits (~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) (Read error: Connection reset by peer) |
| 18:13:58 | × | AlexNoo quits (~AlexNoo@5.139.232.120) (Ping timeout: 255 seconds) |
| 18:22:22 | × | euleritian quits (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Read error: Connection reset by peer) |
| 18:22:31 | → | euleritian joins (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) |
| 18:23:10 | → | JeremyB99 joins (~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) |
| 18:23:25 | → | edr joins (~edr@user/edr) |
| 18:27:39 | → | tromp joins (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) |
| 18:28:44 | → | peterbecich joins (~Thunderbi@047-229-123-186.res.spectrum.com) |
| 18:36:14 | × | bwe quits (~bwe@2a01:4f8:1c1c:4878::2) (Quit: Lost terminal) |
| 18:42:26 | × | euleritian quits (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Ping timeout: 245 seconds) |
| 18:43:05 | → | euleritian joins (~euleritia@dynamic-002-247-248-235.2.247.pool.telefonica.de) |
| 18:43:34 | × | peterbecich quits (~Thunderbi@047-229-123-186.res.spectrum.com) (Ping timeout: 256 seconds) |
| 18:50:10 | → | nate4 joins (~nate@c-98-45-158-125.hsd1.ca.comcast.net) |
| 18:50:19 | × | JeremyB99 quits (~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) (Read error: Connection reset by peer) |
| 18:51:22 | × | gentauro quits (~gentauro@user/gentauro) (Read error: Connection reset by peer) |
| 18:52:58 | → | JeremyB99 joins (~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) |
| 18:54:55 | × | nate4 quits (~nate@c-98-45-158-125.hsd1.ca.comcast.net) (Ping timeout: 255 seconds) |
| 18:56:40 | → | gentauro joins (~gentauro@user/gentauro) |
| 18:56:42 | × | JeremyB99 quits (~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) (Read error: Connection reset by peer) |
| 18:57:41 | × | akegalj quits (~akegalj@141-136-219-144.dsl.iskon.hr) (Ping timeout: 252 seconds) |
| 18:59:14 | AlexNoo_ | is now known as AlexNoo |
| 19:00:40 | → | JeremyB99 joins (~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) |
| 19:01:06 | × | JeremyB99 quits (~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) (Read error: Connection reset by peer) |
| 19:02:11 | <EvanR> | also if you're ok with foldr it seems this becomes one of the situations you can count on one hand where foldl not-prime would at least not be wrong |
| 19:07:49 | × | rosco quits (~rosco@175.136.158.171) (Quit: Lost terminal) |
| 19:11:04 | → | JeremyB99 joins (~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) |
| 19:11:06 | × | JeremyB99 quits (~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) (Read error: Connection reset by peer) |
| 19:14:45 | × | chele quits (~chele@user/chele) (Remote host closed the connection) |
| 19:16:15 | <monochrom> | Usually, if you use foldl to build a list and then reverse it, you can use foldr to build a diff list instead. |
| 19:16:52 | <EvanR> | no need to reverse in this case |
| 19:17:33 | × | euandreh quits (~Thunderbi@189.6.18.26) (Remote host closed the connection) |
| 19:17:37 | <glguy> | EvanR: if you're worried about spoilers just put the code in a pastebin instead of directly into channel |
| 19:17:45 | <EvanR> | oh |
| 19:18:12 | <EvanR> | also I tried a 3rd way and the runtime is still not affected |
| 19:18:16 | <monochrom> | Yeah if you say "this paste contains spoilers" then people can choose to not click. |
| 19:19:17 | → | euandreh joins (~Thunderbi@189.6.18.26) |
| 19:19:44 | × | eggplantade quits (~Eggplanta@2600:1700:38c5:d800:d9f3:ec2f:a760:e0fe) (Remote host closed the connection) |
| 19:20:45 | → | AlexNoo_ joins (~AlexNoo@5.139.232.120) |
| 19:20:59 | → | acidjnk_new joins (~acidjnk@p200300d6e72b930718d4047c6b088385.dip0.t-ipconnect.de) |
| 19:21:17 | → | Incredia_ joins (~Incredia@176.254.244.83) |
| 19:21:41 | × | alp_ quits (~alp@2001:861:e3d6:8f80:c0c9:d001:c090:e9f8) (Ping timeout: 240 seconds) |
| 19:22:11 | → | drewjose6 joins (~drewjose@129.154.40.88) |
| 19:22:33 | → | g__ joins (g@libera/staff/glguy) |
| 19:22:34 | → | WzC joins (~Frank@77-162-168-71.fixed.kpn.net) |
| 19:22:52 | → | mniip_ joins (mniip@libera/staff/mniip) |
| 19:22:56 | × | g quits (g@libera/staff/glguy) (Killed (cadmium.libera.chat (Nickname regained by services))) |
| 19:22:56 | g__ | is now known as g |
| 19:22:57 | → | caasih_ joins (sid13241@id-13241.ilkley.irccloud.com) |
| 19:22:57 | → | yandere_ joins (sid467876@id-467876.ilkley.irccloud.com) |
| 19:22:57 | → | lally_ joins (sid388228@id-388228.uxbridge.irccloud.com) |
| 19:22:58 | → | totbwf_ joins (sid402332@id-402332.uxbridge.irccloud.com) |
| 19:23:00 | → | _0xa_ joins (~user@2001:19f0:5001:2ba8:5400:1ff:feda:88fc) |
| 19:23:01 | → | meooow_ joins (~meooow@2400:6180:100:d0::ad9:e001) |
| 19:23:02 | → | dsal_ joins (sid13060@id-13060.lymington.irccloud.com) |
| 19:23:04 | → | Taneb0 joins (~Taneb@runciman.hacksoc.org) |
| 19:23:04 | → | jackdk_ joins (sid373013@cssa/jackdk) |
| 19:23:05 | → | hovsater_ joins (sid499516@id-499516.lymington.irccloud.com) |
| 19:23:07 | → | smalltalkman_ joins (uid545680@id-545680.hampstead.irccloud.com) |
| 19:23:08 | → | Fangs_ joins (sid141280@id-141280.hampstead.irccloud.com) |
| 19:23:10 | → | nurupo_ joins (~nurupo.ga@user/nurupo) |
| 19:23:13 | → | delyan__ joins (sid523379@id-523379.hampstead.irccloud.com) |
| 19:23:14 | → | dysfigured joins (~dfg@dfg.rocks) |
| 19:23:14 | → | kaskal- joins (~kaskal@2001:4bb8:2d2:5771:29a:c01c:fefc:78b5) |
| 19:23:19 | → | sa_ joins (sid1055@id-1055.tinside.irccloud.com) |
| 19:23:20 | → | jmtd joins (jon@dow.land) |
| 19:23:23 | → | bw____ joins (sid2730@id-2730.ilkley.irccloud.com) |
| 19:23:24 | → | urdh_ joins (~urdh@user/urdh) |
| 19:23:38 | → | innegatives_ joins (sid621315@id-621315.tinside.irccloud.com) |
| 19:24:57 | → | np joins (~nerdypepp@user/nerdypepper) |
| 19:25:26 | → | abrar_ joins (~abrar@pool-108-52-90-30.phlapa.fios.verizon.net) |
| 19:25:33 | → | farn_ joins (~farn@2a03:4000:7:3cd:d4ab:85ff:feeb:f505) |
| 19:25:33 | → | aosync_ joins (~alews@141.94.77.100) |
| 19:25:36 | → | ezzieygu1wuf joins (~Unknown@user/ezzieyguywuf) |
| 19:25:37 | → | shane_ joins (~shane@ana.rch.ist) |
| 19:25:40 | × | Taneb quits (~Taneb@runciman.hacksoc.org) (Ping timeout: 252 seconds) |
| 19:25:41 | × | yandere quits (sid467876@id-467876.ilkley.irccloud.com) (Ping timeout: 252 seconds) |
| 19:25:41 | × | Jon quits (jon@dow.land) (Ping timeout: 252 seconds) |
| 19:25:41 | × | smalltalkman quits (uid545680@id-545680.hampstead.irccloud.com) (Ping timeout: 252 seconds) |
| 19:25:41 | × | jackdk quits (sid373013@cssa/jackdk) (Ping timeout: 252 seconds) |
| 19:25:41 | × | totbwf quits (sid402332@id-402332.uxbridge.irccloud.com) (Ping timeout: 252 seconds) |
| 19:25:41 | × | hovsater quits (sid499516@id-499516.lymington.irccloud.com) (Ping timeout: 252 seconds) |
| 19:25:41 | × | bw___ quits (sid2730@id-2730.ilkley.irccloud.com) (Ping timeout: 252 seconds) |
| 19:25:41 | × | meooow quits (~meooow@2400:6180:100:d0::ad9:e001) (Ping timeout: 252 seconds) |
| 19:25:41 | × | lally quits (sid388228@id-388228.uxbridge.irccloud.com) (Ping timeout: 252 seconds) |
| 19:25:41 | × | Incredia quits (~Incredia@176.254.244.83) (Ping timeout: 252 seconds) |
| 19:25:41 | × | abrar quits (~abrar@pool-108-52-90-30.phlapa.fios.verizon.net) (Ping timeout: 252 seconds) |
| 19:25:41 | × | nerdypepper quits (~nerdypepp@user/nerdypepper) (Ping timeout: 252 seconds) |
| 19:25:41 | × | farn quits (~farn@2a03:4000:7:3cd:d4ab:85ff:feeb:f505) (Ping timeout: 252 seconds) |
| 19:25:41 | × | _0xa quits (~user@user/0xa/x-3134607) (Ping timeout: 252 seconds) |
| 19:25:41 | × | delyan_ quits (sid523379@id-523379.hampstead.irccloud.com) (Ping timeout: 252 seconds) |
| 19:25:42 | × | krj quits (~krjst@2604:a880:800:c1::16b:8001) (Ping timeout: 252 seconds) |
| 19:25:42 | × | aosync quits (~alews@user/aws) (Ping timeout: 252 seconds) |
| 19:25:42 | × | kaskal quits (~kaskal@89.144.222.250) (Ping timeout: 252 seconds) |
| 19:25:42 | × | caasih quits (sid13241@id-13241.ilkley.irccloud.com) (Ping timeout: 252 seconds) |
| 19:25:42 | × | hughjfchen quits (~hughjfche@vmi556545.contaboserver.net) (Ping timeout: 252 seconds) |
| 19:25:42 | × | edr quits (~edr@user/edr) (Ping timeout: 252 seconds) |
| 19:25:42 | × | AlexNoo quits (~AlexNoo@5.139.232.120) (Ping timeout: 252 seconds) |
| 19:25:42 | × | infinity0 quits (~infinity0@pwned.gg) (Ping timeout: 252 seconds) |
| 19:25:42 | × | acidjnk quits (~acidjnk@p200300d6e72b9356246dd2d07051f792.dip0.t-ipconnect.de) (Ping timeout: 252 seconds) |
| 19:25:42 | × | Lycurgus quits (~georg@user/Lycurgus) (Ping timeout: 252 seconds) |
| 19:25:42 | × | urdh quits (~urdh@user/urdh) (Ping timeout: 252 seconds) |
| 19:25:42 | × | cln_ quits (cln@wtf.cx) (Ping timeout: 252 seconds) |
| 19:25:43 | × | Fangs quits (sid141280@id-141280.hampstead.irccloud.com) (Ping timeout: 252 seconds) |
| 19:25:43 | × | dsal quits (sid13060@id-13060.lymington.irccloud.com) (Ping timeout: 252 seconds) |
| 19:25:43 | × | ezzieyguywuf quits (~Unknown@user/ezzieyguywuf) (Ping timeout: 252 seconds) |
| 19:25:43 | × | titibandit quits (~titibandi@user/titibandit) (Ping timeout: 252 seconds) |
| 19:25:43 | × | nurupo quits (~nurupo.ga@user/nurupo) (Ping timeout: 252 seconds) |
| 19:25:43 | × | ski quits (~ski@remote11.chalmers.se) (Ping timeout: 252 seconds) |
| 19:25:43 | × | shane quits (~shane@ana.rch.ist) (Ping timeout: 252 seconds) |
| 19:25:43 | × | yushyin quits (XznNkBgf65@karif.server-speed.net) (Ping timeout: 252 seconds) |
| 19:25:43 | × | haveo quits (~weechat@pacamara.iuwt.fr) (Ping timeout: 252 seconds) |
| 19:25:43 | × | innegatives quits (sid621315@id-621315.tinside.irccloud.com) (Ping timeout: 252 seconds) |
| 19:25:44 | × | drewjose quits (~drewjose@129.154.40.88) (Ping timeout: 252 seconds) |
| 19:25:44 | × | sa quits (sid1055@id-1055.tinside.irccloud.com) (Ping timeout: 252 seconds) |
| 19:25:44 | × | Noinia quits (~Frank@77-162-168-71.fixed.kpn.net) (Ping timeout: 252 seconds) |
| 19:25:44 | × | dfg quits (~dfg@user/dfg) (Ping timeout: 252 seconds) |
| 19:25:44 | × | dhil quits (~dhil@2001:8e0:2014:3100:5872:f936:bc7a:ceb8) (Ping timeout: 252 seconds) |
| 19:25:44 | lally_ | is now known as lally |
| 19:25:44 | jackdk_ | is now known as jackdk |
| 19:25:45 | smalltalkman_ | is now known as smalltalkman |
| 19:25:45 | caasih_ | is now known as caasih |
| 19:25:45 | hovsater_ | is now known as hovsater |
| 19:25:45 | Fangs_ | is now known as Fangs |
| 19:25:45 | totbwf_ | is now known as totbwf |
| 19:25:45 | yandere_ | is now known as yandere |
| 19:25:45 | delyan__ | is now known as delyan_ |
| 19:25:45 | urdh_ | is now known as urdh |
| 19:25:45 | drewjose6 | is now known as drewjose |
| 19:25:45 | dsal_ | is now known as dsal |
| 19:25:46 | → | hughjfch1 joins (~hughjfche@vmi556545.contaboserver.net) |
| 19:25:49 | sa_ | is now known as sa |
| 19:25:50 | → | ski joins (~ski@remote11.chalmers.se) |
| 19:25:58 | → | Lycurgus joins (~georg@li1192-118.members.linode.com) |
| 19:25:58 | × | Lycurgus quits (~georg@li1192-118.members.linode.com) (Changing host) |
| 19:25:58 | → | Lycurgus joins (~georg@user/Lycurgus) |
| 19:25:59 | → | haveo joins (~weechat@pacamara.iuwt.fr) |
| 19:26:01 | → | cln_ joins (cln@wtf.cx) |
| 19:26:10 | → | titibandit joins (~titibandi@user/titibandit) |
| 19:26:18 | → | krasjet joins (~krjst@2604:a880:800:c1::16b:8001) |
| 19:26:32 | × | mniip quits (mniip@libera/staff/mniip) (Read error: Connection reset by peer) |
| 19:27:00 | → | dhil joins (~dhil@2001:8e0:2014:3100:5872:f936:bc7a:ceb8) |
| 19:27:16 | nurupo_ | is now known as nurupo |
| 19:27:32 | → | JeremyB99 joins (~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) |
| 19:28:32 | → | infinity0 joins (~infinity0@pwned.gg) |
| 19:29:11 | → | mc47 joins (~mc47@xmonad/TheMC47) |
| 19:30:41 | × | cfricke quits (~cfricke@user/cfricke) (Quit: WeeChat 4.0.5) |
| 19:31:20 | × | JeremyB99 quits (~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) (Read error: Connection reset by peer) |
| 19:32:09 | → | coot joins (~coot@89-69-206-216.dynamic.chello.pl) |
| 19:32:34 | × | rito quits (~ritog@45.112.243.193) (Quit: Leaving) |
| 19:32:52 | → | ritog joins (~ritog@45.112.243.193) |
| 19:34:43 | → | rito joins (~ritog@45.112.243.193) |
| 19:35:15 | → | JeremyB99 joins (~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) |
| 19:35:34 | × | ritog quits (~ritog@45.112.243.193) (Client Quit) |
| 19:35:34 | × | rito quits (~ritog@45.112.243.193) (Remote host closed the connection) |
| 19:35:36 | × | JeremyB99 quits (~JeremyB99@2607:fb90:8de2:efba:5583:eaba:6418:d88c) (Read error: Connection reset by peer) |
| 19:37:13 | × | coot quits (~coot@89-69-206-216.dynamic.chello.pl) (Quit: coot) |
| 19:37:27 | → | coot joins (~coot@89-69-206-216.dynamic.chello.pl) |
| 19:37:33 | → | yushyin joins (sJ30bcriGA@mail.karif.server-speed.net) |
| 19:39:46 | → | misterfish joins (~misterfis@84-53-85-146.bbserv.nl) |
| 19:40:28 | × | oo_miguel quits (~Thunderbi@78-11-179-96.static.ip.netia.com.pl) (Ping timeout: 276 seconds) |
| 19:41:03 | → | bwe joins (~bwe@2a01:4f8:1c1c:4878::2) |
| 19:42:12 | → | bwe_ joins (~bwe@2a01:4f8:1c1c:4878::2) |
| 19:42:59 | × | tromp quits (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…) |
| 19:45:30 | → | JeremyB99 joins (~JeremyB99@208.64.173.6) |
| 19:47:01 | × | bwe_ quits (~bwe@2a01:4f8:1c1c:4878::2) (Client Quit) |
| 19:47:06 | → | alp_ joins (~alp@2001:861:e3d6:8f80:9ca3:38ae:c1a8:63c1) |
| 19:47:15 | × | bwe quits (~bwe@2a01:4f8:1c1c:4878::2) (Remote host closed the connection) |
| 19:47:32 | → | bwe joins (~bwe@2a01:4f8:1c1c:4878::2) |
| 19:47:59 | × | bwe quits (~bwe@2a01:4f8:1c1c:4878::2) (Client Quit) |
| 19:49:06 | → | bwe joins (~bwe@2a01:4f8:1c1c:4878::2) |
| 19:49:31 | × | bwe quits (~bwe@2a01:4f8:1c1c:4878::2) (Client Quit) |
| 19:50:40 | → | bwe joins (~bwe@2a01:4f8:1c1c:4878::2) |
| 19:52:26 | → | tromp joins (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) |
| 19:53:37 | → | eggplantade joins (~Eggplanta@2600:1700:38c5:d800:97d:c646:7189:b78d) |
| 19:56:05 | × | dcoutts_ quits (~duncan@cpc69402-oxfd27-2-0-cust903.4-3.cable.virginm.net) (Ping timeout: 252 seconds) |
| 19:56:46 | → | Feuermagier_ joins (~Feuermagi@user/feuermagier) |
| 19:56:47 | Feuermagier | is now known as Guest6842 |
| 19:56:47 | × | Guest6842 quits (~Feuermagi@user/feuermagier) (Killed (tungsten.libera.chat (Nickname regained by services))) |
| 19:56:47 | Feuermagier_ | is now known as Feuermagier |
| 19:57:42 | → | alexherbo2 joins (~alexherbo@2a02-8440-3341-75a8-58d4-3b45-b569-2dca.rev.sfr.net) |
| 20:01:16 | × | eggplantade quits (~Eggplanta@2600:1700:38c5:d800:97d:c646:7189:b78d) (Remote host closed the connection) |
| 20:01:29 | × | bwe quits (~bwe@2a01:4f8:1c1c:4878::2) (Quit: Lost terminal) |
| 20:01:43 | → | eggplantade joins (~Eggplanta@2600:1700:38c5:d800:97d:c646:7189:b78d) |
| 20:02:04 | → | bwe joins (~bwe@2a01:4f8:1c1c:4878::2) |
| 20:03:51 | → | wroathe joins (~wroathe@207-153-38-140.fttp.usinternet.com) |
| 20:03:51 | × | wroathe quits (~wroathe@207-153-38-140.fttp.usinternet.com) (Changing host) |
| 20:03:51 | → | wroathe joins (~wroathe@user/wroathe) |
| 20:07:54 | AlexNoo_ | is now known as AlexNoo |
| 20:11:51 | × | eggplantade quits (~Eggplanta@2600:1700:38c5:d800:97d:c646:7189:b78d) (Remote host closed the connection) |
| 20:12:32 | × | coot quits (~coot@89-69-206-216.dynamic.chello.pl) (Quit: coot) |
| 20:12:46 | → | coot joins (~coot@89-69-206-216.dynamic.chello.pl) |
| 20:16:14 | × | bwe quits (~bwe@2a01:4f8:1c1c:4878::2) (Quit: Lost terminal) |
| 20:17:54 | → | bwe joins (~bwe@2a01:4f8:1c1c:4878::2) |
| 20:18:29 | × | bwe quits (~bwe@2a01:4f8:1c1c:4878::2) (Remote host closed the connection) |
| 20:18:48 | → | bwe joins (~bwe@2a01:4f8:1c1c:4878::2) |
| 20:19:36 | → | eggplantade joins (~Eggplanta@2600:1700:38c5:d800:97d:c646:7189:b78d) |
| 20:21:59 | Taneb0 | is now known as Taneb |
| 20:25:52 | → | kassouni joins (~textual@2601:646:401:6c30:5dd8:64ca:fd4d:e39b) |
| 20:26:00 | × | trev quits (~trev@user/trev) (Quit: trev) |
| 20:27:40 | × | wroathe quits (~wroathe@user/wroathe) (Ping timeout: 246 seconds) |
| 20:29:48 | × | eggplantade quits (~Eggplanta@2600:1700:38c5:d800:97d:c646:7189:b78d) (Remote host closed the connection) |
| 20:32:52 | × | coot quits (~coot@89-69-206-216.dynamic.chello.pl) (Quit: coot) |
| 20:33:07 | → | coot joins (~coot@89-69-206-216.dynamic.chello.pl) |
| 20:37:29 | × | opus quits (~nil@user/opus) (Quit: bye) |
| 20:37:29 | × | pedant quits (~who@user/pedant) (Quit: bye) |
| 20:37:30 | × | anderson quits (~anderson@user/anderson) (Quit: bye) |
| 20:41:16 | → | eggplantade joins (~Eggplanta@2600:1700:38c5:d800:97d:c646:7189:b78d) |
| 20:45:23 | <zero> | there has to be a more elegant way of writing `req_msg <$> (decodeStrict =<< req)` |
| 20:45:55 | <Rembane> | zero: req_msg . decodeStrict =<< req -- IIRC |
| 20:46:14 | <dminuoso_> | That doesnt look right. |
| 20:46:17 | <shapr> | @pl req_msg <$> (decodeStrict =<< req) |
| 20:46:17 | <lambdabot> | req_msg <$> (decodeStrict =<< req) |
| 20:46:22 | <shapr> | oh well, worth trying |
| 20:46:26 | <dminuoso_> | zero: You can drop the parenthesis. |
| 20:46:33 | <Rembane> | dminuoso_: I had to write it to realize it. :/ |
| 20:46:45 | <dminuoso_> | zero: Even ignoring precedence! No matter how you associate that <$>, it will be the same. |
| 20:46:52 | <dminuoso_> | By law. |
| 20:46:56 | <Rembane> | zero: Just out of curiousity, what's the type of decodeStrict? |
| 20:47:30 | → | cimento joins (CO2@gateway/vpn/protonvpn/cimento) |
| 20:47:31 | × | eggplantade quits (~Eggplanta@2600:1700:38c5:d800:97d:c646:7189:b78d) (Remote host closed the connection) |
| 20:47:40 | <zero> | i thought so too. but i get an error |
| 20:47:47 | <Rembane> | What's the error? |
| 20:47:57 | <zero> | decodeStrict :: forall a. FromJSON a => ByteString -> Maybe a |
| 20:48:39 | <zero> | Couldn't match type ‘Text’ with ‘Maybe Text’Expected: ByteString -> Maybe Text Actual: ByteString -> Text |
| 20:48:45 | <zero> | without the parenthesis |
| 20:50:02 | <zero> | Couldn't match type ‘Maybe a0’ with ‘Req’Expected: ByteString -> Req Actual: ByteString -> Maybe a0In the second argument of ‘(.)’, namely ‘decodeStrict’In the first argument of ‘(=<<)’, namely ‘req_msg . decodeStrict’ |
| 20:50:06 | <zero> | with the . |
| 20:50:42 | <Rembane> | I was super wrong about the dot, I'm sorry. |
| 20:50:54 | <zero> | Rembane: i did the same mistake |
| 20:51:22 | → | zetef joins (~quassel@95.77.17.251) |
| 20:51:23 | <Rembane> | zero: It looks nice, but doesn't work. :) |
| 20:51:52 | <zero> | my brain tells me to write it another way |
| 20:54:11 | <Rembane> | zero: You could use do-notation if that makes your brain happier. |
| 20:54:50 | <dminuoso_> | zero: Depending on surrounding code, <&> could help |
| 20:54:53 | × | alp_ quits (~alp@2001:861:e3d6:8f80:9ca3:38ae:c1a8:63c1) (Remote host closed the connection) |
| 20:55:10 | → | alp_ joins (~alp@2001:861:e3d6:8f80:fcbc:9c69:6404:51f0) |
| 20:55:59 | <dminuoso_> | zero: Or making a decodeReq :: (Req -> a) -> Inp -> Decode a type of function |
| 20:56:05 | <dminuoso_> | Such that you can write `decodeReq req_msg =<< req` |
| 20:58:09 | × | tromp quits (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…) |
| 20:59:06 | → | dcoutts_ joins (~duncan@cpc69402-oxfd27-2-0-cust903.4-3.cable.virginm.net) |
| 21:02:11 | → | tromp joins (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) |
| 21:02:30 | <Hecate> | win la |
| 21:02:32 | <Hecate> | (woops) |
| 21:02:37 | × | zetef quits (~quassel@95.77.17.251) (Ping timeout: 255 seconds) |
| 21:03:02 | → | zetef joins (~quassel@5.2.182.98) |
| 21:03:08 | → | not_reserved joins (~not_reser@185.195.59.27) |
| 21:04:14 | × | dhil quits (~dhil@2001:8e0:2014:3100:5872:f936:bc7a:ceb8) (Ping timeout: 260 seconds) |
| 21:11:16 | × | _ht quits (~Thunderbi@28-52-174-82.ftth.glasoperator.nl) (Remote host closed the connection) |
| 21:17:24 | × | tromp quits (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…) |
| 21:17:46 | × | sord937 quits (~sord937@gateway/tor-sasl/sord937) (Quit: sord937) |
| 21:21:13 | × | alp_ quits (~alp@2001:861:e3d6:8f80:fcbc:9c69:6404:51f0) (Ping timeout: 246 seconds) |
| 21:21:23 | → | eggplantade joins (~Eggplanta@2600:1700:38c5:d800:97d:c646:7189:b78d) |
| 21:23:20 | → | tromp joins (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) |
| 21:24:50 | → | akegalj joins (~akegalj@141-136-219-144.dsl.iskon.hr) |
| 21:25:38 | × | eggplantade quits (~Eggplanta@2600:1700:38c5:d800:97d:c646:7189:b78d) (Ping timeout: 252 seconds) |
| 21:26:12 | × | kassouni quits (~textual@2601:646:401:6c30:5dd8:64ca:fd4d:e39b) (Ping timeout: 256 seconds) |
| 21:27:46 | × | akegalj quits (~akegalj@141-136-219-144.dsl.iskon.hr) (Client Quit) |
| 21:28:01 | × | coot quits (~coot@89-69-206-216.dynamic.chello.pl) (Quit: coot) |
| 21:30:32 | × | takuan quits (~takuan@178-116-218-225.access.telenet.be) (Remote host closed the connection) |
| 21:38:07 | × | mobivme quits (~mobivme@112.201.111.217) (Excess Flood) |
| 21:40:33 | → | mobivme joins (~mobivme@112.201.111.217) |
| 21:45:16 | → | zzz joins (~z@user/zero) |
| 21:48:41 | × | zero quits (~z@user/zero) (Ping timeout: 245 seconds) |
| 21:48:41 | zzz | is now known as zero |
| 21:51:04 | → | alp_ joins (~alp@2001:861:e3d6:8f80:2823:fd6b:81cc:5297) |
| 21:51:28 | → | Square2 joins (~Square4@user/square) |
| 21:53:20 | <darkling> | ROFL @ Venn diagrams. |
| 21:53:30 | <darkling> | Err. -ECHANNEL. |
| 21:54:21 | × | Square quits (~Square@user/square) (Ping timeout: 252 seconds) |
| 21:55:27 | × | misterfish quits (~misterfis@84-53-85-146.bbserv.nl) (Ping timeout: 260 seconds) |
| 22:00:57 | → | fendor joins (~fendor@2a02:8388:1605:d100:267b:1353:13d7:4f0c) |
| 22:09:26 | × | dcoutts_ quits (~duncan@cpc69402-oxfd27-2-0-cust903.4-3.cable.virginm.net) (Remote host closed the connection) |
| 22:09:39 | → | eggplantade joins (~Eggplanta@2600:1700:38c5:d800:97d:c646:7189:b78d) |
| 22:09:44 | → | dcoutts_ joins (~duncan@cpc69402-oxfd27-2-0-cust903.4-3.cable.virginm.net) |
| 22:11:49 | × | mc47 quits (~mc47@xmonad/TheMC47) (Remote host closed the connection) |
| 22:11:57 | <monochrom> | I love Venn diagrams! |
| 22:14:02 | × | robobub quits (uid248673@id-248673.uxbridge.irccloud.com) (Quit: Connection closed for inactivity) |
| 22:14:47 | <glguy> | If I do part 2 as a list of partial sums I get: asPart2' = head . foldr (\wins xs -> 1 + (2 * head xs - xs !! wins) : xs) [0] |
| 22:18:25 | × | chomwitt quits (~chomwitt@2a02:587:7a09:c300:1ac0:4dff:fedb:a3f1) (Ping timeout: 256 seconds) |
| 22:19:33 | × | euandreh quits (~Thunderbi@189.6.18.26) (Ping timeout: 256 seconds) |
| 22:26:10 | → | euandreh joins (~Thunderbi@189.6.18.26) |
| 22:27:52 | <glguy> | I should put that in my c++ solution where the indexing can be efficient |
| 22:28:08 | <monochrom> | :) |
| 22:29:15 | <int-e> | Hmm... 1 + (head xs - xs !! wins) + head xs ...okay, yeah, that looks correct :P |
| 22:30:39 | × | euandreh quits (~Thunderbi@189.6.18.26) (Ping timeout: 252 seconds) |
| 22:32:24 | × | fendor quits (~fendor@2a02:8388:1605:d100:267b:1353:13d7:4f0c) (Remote host closed the connection) |
| 22:32:28 | ski | Euler's some diagrams |
| 22:33:42 | → | euandreh joins (~Thunderbi@189.6.18.26) |
| 22:41:05 | × | tromp quits (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…) |
| 22:43:14 | → | tromp joins (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) |
| 22:44:31 | <iqubic> | I love Euler Diagrams. |
| 22:51:42 | → | nate4 joins (~nate@c-98-45-158-125.hsd1.ca.comcast.net) |
| 22:55:25 | × | tromp quits (~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl) (Quit: My iMac has gone to sleep. ZZZzzz…) |
| 22:56:46 | × | nate4 quits (~nate@c-98-45-158-125.hsd1.ca.comcast.net) (Ping timeout: 276 seconds) |
| 22:59:58 | × | szkl quits (uid110435@id-110435.uxbridge.irccloud.com) (Quit: Connection closed for inactivity) |
| 23:00:51 | × | euandreh quits (~Thunderbi@189.6.18.26) (Remote host closed the connection) |
| 23:01:13 | × | mobivme quits (~mobivme@112.201.111.217) (Quit: ZNC 1.8.2+deb2build5 - https://znc.in) |
| 23:02:04 | → | mobivme joins (~mobivme@112.201.111.217) |
| 23:02:08 | × | gmg quits (~user@user/gehmehgeh) (Quit: Leaving) |
| 23:04:26 | × | euleritian quits (~euleritia@dynamic-002-247-248-235.2.247.pool.telefonica.de) (Read error: Connection reset by peer) |
| 23:04:45 | → | euleritian joins (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) |
| 23:06:45 | × | notzmv quits (~zmv@user/notzmv) (Ping timeout: 268 seconds) |
| 23:07:04 | × | mobivme quits (~mobivme@112.201.111.217) (Quit: ZNC 1.8.2+deb2build5 - https://znc.in) |
| 23:09:57 | → | mobivme joins (~mobivme@112.201.111.217) |
| 23:10:10 | × | zetef quits (~quassel@5.2.182.98) (Remote host closed the connection) |
| 23:11:47 | × | Square2 quits (~Square4@user/square) (Ping timeout: 252 seconds) |
| 23:20:22 | → | notzmv joins (~zmv@user/notzmv) |
| 23:25:19 | × | __monty__ quits (~toonn@user/toonn) (Quit: leaving) |
| 23:28:47 | → | pavonia joins (~user@user/siracusa) |
| 23:30:01 | → | Sgeo joins (~Sgeo@user/sgeo) |
| 23:33:22 | × | euleritian quits (~euleritia@ip4d16fc38.dynamic.kabel-deutschland.de) (Read error: Connection reset by peer) |
| 23:33:39 | × | acidjnk_new quits (~acidjnk@p200300d6e72b930718d4047c6b088385.dip0.t-ipconnect.de) (Ping timeout: 256 seconds) |
| 23:33:56 | → | euleritian joins (~euleritia@77.22.252.56) |
| 23:38:05 | × | waleee quits (~waleee@h-176-10-144-38.NA.cust.bahnhof.se) (Ping timeout: 240 seconds) |
| 23:52:47 | × | tomboy64 quits (~tomboy64@user/tomboy64) (Ping timeout: 264 seconds) |
All times are in UTC on 2023-12-04.