2025/04/11

2025-04-11 00:00:24 +0200 <EvanR> though linear base does
2025-04-11 00:00:37 +0200 <hellwolf> thinking about it, isn't State monad a nice way of bypassing the need of that threading for that use case?
2025-04-11 00:01:23 +0200 <monochrom> But I defy your false dichotomy. I estimate which one is shorter and go with it: manual threading like that vs using State.
2025-04-11 00:02:31 +0200 <monochrom> You see, there are always some annoying people like me who always answers "it depends".
2025-04-11 00:03:06 +0200 <monochrom> Ruining any rule of thumb, style guide, doctrine, dogma, ideology.
2025-04-11 00:03:10 +0200 <hellwolf> today, I actually managed to implement a different threading-hiding solution for lineartypes. Though, the Ur pattern makes most of the problem going away anyways; mine is for something different.
2025-04-11 00:03:42 +0200 <hellwolf> I like it depends, as long as it's explained clearly.
2025-04-11 00:04:22 +0200 <monochrom> I guess except for the it-depends ideology. :)
2025-04-11 00:04:35 +0200 <monochrom> itdependism
2025-04-11 00:04:45 +0200 <hellwolf> changing-goal-post as a merit.
2025-04-11 00:04:56 +0200 <Guest87> int-e monochrom okay, I have a similar implementation ready for haskell, though i am doing it in a text editor so I apologize for any typos
2025-04-11 00:04:58 +0200 <hellwolf> principle as a sin.
2025-04-11 00:05:30 +0200 <hellwolf> (tongue-in-cheek here. personally, I much prefer principle first)
2025-04-11 00:05:49 +0200 <Guest87> data Task = Task {programToRun :: String, input :: String}
2025-04-11 00:05:49 +0200 <Guest87> data Pipeline = Pipeline {initialTask :: String, steps :: [String -> Task]}
2025-04-11 00:05:50 +0200 <Guest87> makePipeline task = Pipeline task []
2025-04-11 00:05:50 +0200 <Guest87> addStep pipeline step = Pipeline (initialTask pipeline) (steps pipeline <> [step])
2025-04-11 00:05:51 +0200 <Guest87> runTask :: Task -> IO (Either String Task)
2025-04-11 00:05:51 +0200 <Guest87> run pipeline = do
2025-04-11 00:05:52 +0200 <Guest87>  case (steps pipeline) of
2025-04-11 00:05:52 +0200 <Guest87>   [] -> putStrLn "done"
2025-04-11 00:05:53 +0200 <Guest87>   [f:nxt] -> (beginRun nxt) . f . initialTask $ pipeline
2025-04-11 00:05:53 +0200 <Guest87> beginRun next task = do
2025-04-11 00:05:53 +0200 <EvanR> aaaaaaaa
2025-04-11 00:05:54 +0200 <Guest87>  step <- runTask task
2025-04-11 00:05:54 +0200 <Guest87>  case step of
2025-04-11 00:05:55 +0200 <Guest87>   Left res -> case next of
2025-04-11 00:05:55 +0200 <Guest87>    [] -> putStrLn "done"
2025-04-11 00:05:56 +0200 <Guest87>    [f:nxt] -> beginRun nxt (f res)
2025-04-11 00:05:56 +0200 <Guest87>   Right t -> beginRun next t
2025-04-11 00:05:59 +0200 <hellwolf> stooooop
2025-04-11 00:06:11 +0200 <Guest87> Ugh I should paste in a gist :(
2025-04-11 00:06:12 +0200 <hellwolf> https://paste.tomsmeding.com/
2025-04-11 00:06:19 +0200 <Guest87> Or there, thank you hellwolf
2025-04-11 00:06:41 +0200 <Guest87> https://paste.tomsmeding.com/tggksoJO
2025-04-11 00:06:52 +0200 <geekosaur> IRC is absolutely terrible for code, and too old to support things like code blocks
2025-04-11 00:07:05 +0200 <Guest87> I am too used to discord and other chats I think
2025-04-11 00:07:18 +0200 <EvanR> IRC gets new features all the time
2025-04-11 00:07:22 +0200 <EvanR> soon... code blocks
2025-04-11 00:07:23 +0200 <haskellbridge> <maralorn> hellwolf: I will try to use monadic-bang I have been hoping for something like it for a long time and had kinda forgotten about the plugin.
2025-04-11 00:07:28 +0200 <EvanR> and animated premium emojis
2025-04-11 00:08:28 +0200 <haskellbridge> <maralorn> Is this an IRC nitro pro channel?
2025-04-11 00:08:29 +0200 <Guest87> So, the problem/annoyance I have is that I want to [String -> Task] to be somehow squashed into a single (String -> Task)
2025-04-11 00:09:26 +0200 <EvanR> Monoid m => Monoid (a -> m)
2025-04-11 00:09:38 +0200 <hellwolf> maralorn: nice! It seems actively maintained, which is a good sign.
2025-04-11 00:09:42 +0200 <EvanR> mconcat :: [a -> m] -> a -> m
2025-04-11 00:09:52 +0200 <EvanR> if Task were a Monoid
2025-04-11 00:10:12 +0200 <haskellbridge> <maralorn> Doesn't look like a monoid to me.
2025-04-11 00:10:30 +0200 <monochrom> [String -> Maybe Task] is much more squashable.
2025-04-11 00:11:01 +0200 <haskellbridge> <maralorn> Would String -> [Task] be an option that looks more feasible.
2025-04-11 00:11:07 +0200 <monochrom> which is still repeating what we said before --- undefined is not very workable with in the first place. Use Nothing.
2025-04-11 00:12:00 +0200 <EvanR> [Task] be a monoid
2025-04-11 00:12:16 +0200 <monochrom> Oh yeah Maybe Task is too. Same difference :)
2025-04-11 00:12:31 +0200 <EvanR> pick your squash
2025-04-11 00:12:37 +0200 <monochrom> Also there are First and Last for overriding or not overriding existing mappings.
2025-04-11 00:13:22 +0200 <monochrom> Also did you know that flip (++) is also a monoid operator :)
2025-04-11 00:14:18 +0200rbdr(~rbdr@dynamic-089-012-130-183.89.12.pool.telefonica.de) (Quit: WeeChat 4.6.0)
2025-04-11 00:14:51 +0200 <Guest87> My current solution does the following:
2025-04-11 00:14:52 +0200 <Guest87> https://paste.tomsmeding.com/8E9is43S
2025-04-11 00:15:38 +0200 <Guest87> It works well, but the only problem is that `n` `addCont` calls means I have to unwrap `n-1` layers to get to the actual next step
2025-04-11 00:16:33 +0200 <EvanR> well if you're always operating on only one end of this list
2025-04-11 00:16:49 +0200 <EvanR> better make that end the list beginning
2025-04-11 00:17:03 +0200machinedgod(~machinedg@d108-173-18-100.abhsia.telus.net) (Ping timeout: 245 seconds)
2025-04-11 00:18:11 +0200 <EvanR> if you operate on both ends equally often, there is the functional queue ([Task],[Task]) where one list is backwards
2025-04-11 00:19:15 +0200 <Guest87> Always operating on one end
2025-04-11 00:20:19 +0200 <EvanR> that being said if "n" is not that much it probably doesn't matter either way
2025-04-11 00:20:50 +0200 <Guest87> I am worried some code reviewer will shoot this whole solution down regardless of what `n` is :/
2025-04-11 00:21:16 +0200 <EvanR> boils down to annoying the reader again
2025-04-11 00:21:16 +0200 <Guest87> But also, I could just do the list implementation if that happens
2025-04-11 00:21:50 +0200 <Guest87> Realizing how different/poorly statement my original problem was
2025-04-11 00:22:21 +0200 <Guest87> Now that the context is here, the problem statement would be "Is there a way to do `addCont` without this unwrapping behavior?"
2025-04-11 00:22:30 +0200 <EvanR> step 1. understand the question
2025-04-11 00:22:35 +0200 <EvanR> step 0. write a proper question
2025-04-11 00:23:39 +0200 <EvanR> you are shadowing t twice in your code so it's hard to grok what is going on
2025-04-11 00:24:12 +0200Square(~Square4@user/square) Square
2025-04-11 00:24:25 +0200 <haskellbridge> <loonycyborg> you don't even have a list of tasks
2025-04-11 00:24:31 +0200 <haskellbridge> <loonycyborg> only a way to calculate them
2025-04-11 00:25:27 +0200__monty__(~toonn@user/toonn) (Quit: leaving)
2025-04-11 00:25:57 +0200 <EvanR> alright addCont takes what seems to be an error handler and a program name / input string. Then it calls continue but but continue doesn't return an Either as far as I can tell
2025-04-11 00:26:03 +0200merijn(~merijn@host-vr.cgnat-g.v4.dfn.nl) merijn
2025-04-11 00:26:35 +0200 <monochrom> list of length n is just as inefficient as function chain of length n.
2025-04-11 00:27:17 +0200 <EvanR> but if fixed maybe this addCont produces a sort of recursive "object" as in OOP. But only a single one, not adding anything to anything
2025-04-11 00:27:27 +0200 <monochrom> If there is a code reviewer who does not treat both equally, well, I guess that's why you're paid to appease an arbitrary code reviewer.
2025-04-11 00:27:29 +0200Square2(~Square@user/square) (Ping timeout: 260 seconds)
2025-04-11 00:28:12 +0200 <Guest87> EvanR damn yea, the shadowing is real bad. Here is the full code without shadowing
2025-04-11 00:28:13 +0200 <Guest87> https://paste.tomsmeding.com/4T0PUPHR
2025-04-11 00:28:47 +0200 <EvanR> still, continue returns a Task, not a function to apply input to
2025-04-11 00:28:52 +0200 <EvanR> much less returning an Either
2025-04-11 00:29:15 +0200 <EvanR> though if you install GHC you would already know this
2025-04-11 00:29:54 +0200 <haskellbridge> <loonycyborg> honestly I'd recommend adding type annotations :P
2025-04-11 00:30:20 +0200 <EvanR> Right t2 seems to have a new string, but then you pass it into the recursive call where a function was supposed to be
2025-04-11 00:30:44 +0200 <Guest87> Ah crap, this is what I get for trying to port non-pure code without a type checker
2025-04-11 00:30:45 +0200merijn(~merijn@host-vr.cgnat-g.v4.dfn.nl) (Ping timeout: 248 seconds)
2025-04-11 00:31:00 +0200 <EvanR> in addStep you use f but f is not introduced anywhere
2025-04-11 00:31:46 +0200lxsameer(~lxsameer@Serene/lxsameer) (Ping timeout: 252 seconds)
2025-04-11 00:32:57 +0200 <EvanR> yeah a type signature for addCont and addStep ok all top level definitions here would go a long way
2025-04-11 00:33:52 +0200 <Guest87> Thank you for feedback, adding those
2025-04-11 00:40:31 +0200roconnor(~quassel@rocq/roconnor) (Ping timeout: 265 seconds)
2025-04-11 00:41:45 +0200roconnor(~quassel@rocq/roconnor) roconnor
2025-04-11 00:41:51 +0200merijn(~merijn@host-vr.cgnat-g.v4.dfn.nl) merijn
2025-04-11 00:43:22 +0200 <Guest87> Holy shit haskell playground is a thing now
2025-04-11 00:46:44 +0200merijn(~merijn@host-vr.cgnat-g.v4.dfn.nl) (Ping timeout: 260 seconds)
2025-04-11 00:47:44 +0200 <EvanR> > let tasks = [(++ "!"), (++ "world"), (++ " "), (++ "Hello")] in foldl (.) id tasks ""
2025-04-11 00:47:46 +0200 <lambdabot> "Hello world!"
2025-04-11 00:48:02 +0200 <EvanR> operating on the beginning of this list is operating on the "last task"
2025-04-11 00:48:11 +0200cheater(~Username@user/cheater) (Quit: Going offline, see ya! (www.adiirc.com))
2025-04-11 00:50:16 +0200 <EvanR> foldl (.) id combines them "first task" first
2025-04-11 00:52:00 +0200 <EvanR> the "" at the end is the initial input
2025-04-11 00:53:24 +0200hattckory(~hattckory@bras-base-toroon4524w-grc-30-70-27-118-207.dsl.bell.ca) (Ping timeout: 276 seconds)
2025-04-11 00:54:44 +0200 <EvanR> > foldl (.) id [t4, t3, t2, t1] initial
2025-04-11 00:54:45 +0200 <lambdabot> error:
2025-04-11 00:54:45 +0200 <lambdabot> • Variable not in scope: t4 :: c -> c
2025-04-11 00:54:45 +0200 <lambdabot> • Perhaps you meant one of these:
2025-04-11 00:55:11 +0200 <EvanR> > foldl (.) id [z, y, x, w] initial
2025-04-11 00:55:13 +0200 <lambdabot> error: Variable not in scope: initial
2025-04-11 00:55:16 +0200 <EvanR> > foldl (.) id [z, y, x, w] i
2025-04-11 00:55:17 +0200 <lambdabot> error:
2025-04-11 00:55:17 +0200 <lambdabot> • Couldn't match expected type ‘Expr -> Expr’
2025-04-11 00:55:17 +0200 <lambdabot> with actual type ‘Expr’
2025-04-11 00:56:14 +0200 <EvanR> > foldl (.) id [h, g, f] i
2025-04-11 00:56:16 +0200 <lambdabot> h (g (f i))
2025-04-11 00:57:38 +0200merijn(~merijn@host-vr.cgnat-g.v4.dfn.nl) merijn
2025-04-11 00:59:22 +0200 <Guest87> Okay, very sorry for the previous code. Here is it with ghc
2025-04-11 00:59:23 +0200 <Guest87> https://play.haskell.org/saved/RpqxGbLD
2025-04-11 01:01:34 +0200 <haskellbridge> <loonycyborg> you can turn [IO Task] into IO [Task] using "sequence" function
2025-04-11 01:03:04 +0200merijn(~merijn@host-vr.cgnat-g.v4.dfn.nl) (Ping timeout: 276 seconds)
2025-04-11 01:03:39 +0200 <haskellbridge> <loonycyborg> probably clearer would be to build a list of them and then sequence it
2025-04-11 01:03:47 +0200 <EvanR> alright you have the issue that the meat of your post never happens since beginRun never gets around to it
2025-04-11 01:03:54 +0200 <EvanR> but yeah
2025-04-11 01:06:01 +0200 <EvanR> I presume you want the result of each task to be threaded into the next one
2025-04-11 01:06:54 +0200 <Guest87> +haskellbridge I think what you are describing is what I concluded to be the way to do this efficiently, but I also don't have an intuition for what "sequencing something" means, so I am not sure
2025-04-11 01:06:57 +0200 <EvanR> [String -> IO (Either String String)]
2025-04-11 01:07:24 +0200 <EvanR> this function stands for a Task without the explicit type for it
2025-04-11 01:07:37 +0200 <EvanR> the list can be combined using a fold
2025-04-11 01:08:13 +0200 <EvanR> to get a final String -> IO (Either String String) to run on the initial input
2025-04-11 01:08:29 +0200peterbecich(~Thunderbi@syn-047-229-123-186.res.spectrum.com) peterbecich
2025-04-11 01:09:00 +0200 <emojelly> Remember my performance drama, where profiling didn't help? I think I found at least part of the issue, through experimentation.
2025-04-11 01:09:15 +0200sprotte24_(~sprotte24@p200300d16f15a4001c8bedf899879cb7.dip0.t-ipconnect.de) (Quit: Leaving)
2025-04-11 01:09:20 +0200 <emojelly> It seems to be related to how many Monad Transformers I layer. Partly also what those Monad Transformers are.
2025-04-11 01:09:24 +0200 <Guest87> EvanR correct. Running a single Task could require running more Task until the final result is obtained
2025-04-11 01:09:28 +0200 <emojelly> It seems to grow hyperlinearly with each transformer.
2025-04-11 01:10:35 +0200 <emojelly> I tried with an onion made of a few IdentityTs and Either, and it's enough to blow the runtime up massively.
2025-04-11 01:10:46 +0200 <Guest87> So having a list of Task is the correct thing to do here instead of "squashing it all up" into one Task?
2025-04-11 01:10:58 +0200 <EvanR> the list is there so you can edit it
2025-04-11 01:11:08 +0200 <EvanR> if it was a fixed sequence of tasks you wouldn't need it
2025-04-11 01:11:57 +0200 <emojelly> I'm now rewriting my Coroutine-code in Pipes, because that claims to be "fast", specifically also by internally weakening the monad transformer laws.
2025-04-11 01:12:20 +0200 <Guest87> EvanR: That's a good argument, I don't know why I am being so stubborn about not having a list
2025-04-11 01:12:33 +0200 <Guest87> Maybe I just miss working with functions
2025-04-11 01:13:04 +0200 <Guest87> Is there a proper name/term for the problem I am running into when I do it all with one Task?
2025-04-11 01:13:27 +0200merijn(~merijn@host-vr.cgnat-g.v4.dfn.nl) merijn
2025-04-11 01:14:28 +0200 <EvanR> functions in haskell are blackboxes the only thing you do with them, other than pass them around, is apply them to an argument
2025-04-11 01:14:55 +0200hattckory(~hattckory@bras-base-toroon4524w-grc-30-70-27-118-207.dsl.bell.ca)
2025-04-11 01:14:55 +0200 <emojelly> My Monad/Monad Transformer, mixed in with the one from the test framework (Hedgehog), is quite an impressive layer of Coroutine, ExceptT, ReaderT, WriterT, Maybe, IdentityT... I know WriterT has a problem, but even if I try a more minimal example consisting just of Coroutine, IdentityT, and Either, just adding an IdentityT can make things multiple times slower.
2025-04-11 01:15:01 +0200j1n37(~j1n37@user/j1n37) j1n37
2025-04-11 01:16:16 +0200j1n37-(~j1n37@user/j1n37) (Ping timeout: 268 seconds)
2025-04-11 01:16:34 +0200 <emojelly> This is a bit of a bummer, because I was stupidly assuming that Monad Transformers were mostly "free" in terms of performance, at least in terms of just being part of the type, without much actual usage. But that does not seem to be the case at all. Even an IdentityT can wreak havoc if you e.g. fmap through it (i.e. actually follow transformer laws).
2025-04-11 01:16:56 +0200 <EvanR> Guest87, question, what is the "empty list" of tasks supposed to do
2025-04-11 01:17:39 +0200 <EvanR> or is it never empty
2025-04-11 01:18:14 +0200 <emojelly> I guess this is part of why people use effectful these days? But my usage of Coroutine specifically precludes effectful, I think.
2025-04-11 01:18:24 +0200 <Guest87> Yea for now I am assuming I at least have (Task "identityProgram" startingInput (\t -> return Nothing))
2025-04-11 01:18:39 +0200Tuplanolla(~Tuplanoll@91-159-69-59.elisa-laajakaista.fi) (Quit: Leaving.)
2025-04-11 01:18:48 +0200 <EvanR> Guest87, something like ... https://paste.tomsmeding.com/JF0HROx2
2025-04-11 01:19:06 +0200 <EvanR> well you return Nothing so what goes on to the next program
2025-04-11 01:19:40 +0200xff0x(~xff0x@2405:6580:b080:900:1c0d:6c97:349e:6228) (Ping timeout: 265 seconds)
2025-04-11 01:19:59 +0200hattckory(~hattckory@bras-base-toroon4524w-grc-30-70-27-118-207.dsl.bell.ca) (Ping timeout: 260 seconds)
2025-04-11 01:20:05 +0200 <Guest87> In `addCont`, Nothing is where I end up passing on the result to the next task
2025-04-11 01:20:12 +0200 <Guest87> Otherwise, Nothing means "nothing left to do"
2025-04-11 01:20:25 +0200 <EvanR> but there is no result
2025-04-11 01:20:56 +0200 <EvanR> but since the code never runs in your case, that question doesn't need to be answered
2025-04-11 01:21:16 +0200merijn(~merijn@host-vr.cgnat-g.v4.dfn.nl) (Ping timeout: 276 seconds)
2025-04-11 01:23:26 +0200 <EvanR> in my paste, addCont would simply be prepending another Task to the list
2025-04-11 01:23:50 +0200L29Ah(~L29Ah@wikipedia/L29Ah) ()
2025-04-11 01:23:54 +0200xff0x(~xff0x@2405:6580:b080:900:1c0d:6c97:349e:6228)
2025-04-11 01:25:10 +0200 <Guest87> EvanR yup, this is easy to do with a list, I am just being a dummy and feel like using a list means I haven't figured out the elegant solution
2025-04-11 01:26:28 +0200peterbecich(~Thunderbi@syn-047-229-123-186.res.spectrum.com) (Ping timeout: 276 seconds)
2025-04-11 01:26:46 +0200 <EvanR> turning a non-empty [Task] into a Task using a Task -> Task -> Task... fairly "elegant" I'd say
2025-04-11 01:27:21 +0200 <Guest87> xD I am just making things hard for myself I guess
2025-04-11 01:28:14 +0200 <Guest87> Are there any haskell libraries that implement whatever I am dealing with here? At one point I was re-learning the Cont monad, but this doesn't feel like Cont exactly
2025-04-11 01:29:55 +0200 <EvanR> my paste is the entirety of the problem afaiui
2025-04-11 01:30:02 +0200 <EvanR> hardly needs a library
2025-04-11 01:30:26 +0200 <EvanR> but in general "Tasks" sounds like they'd be running concurrently and might need to communicate with each other, and the async library is pretty nice there
2025-04-11 01:31:19 +0200 <EvanR> :t foldl1
2025-04-11 01:31:20 +0200 <lambdabot> Foldable t => (a -> a -> a) -> t a -> a
2025-04-11 01:31:30 +0200merijn(~merijn@host-vr.cgnat-g.v4.dfn.nl) merijn
2025-04-11 01:32:19 +0200hattckory(~hattckory@bras-base-toroon4524w-grc-30-70-27-118-207.dsl.bell.ca)
2025-04-11 01:32:41 +0200 <EvanR> if it was just a bunch of IO actions in a list that needed to run, that's even less of a library, just sequence :: [IO a] -> IO [a]
2025-04-11 01:32:49 +0200jleightcap(7bc4014b62@user/jleightcap) ()
2025-04-11 01:34:05 +0200L29Ah(~L29Ah@wikipedia/L29Ah) L29Ah
2025-04-11 01:34:16 +0200 <EvanR> and my posted code can probably be golfed with some pointfree compositions
2025-04-11 01:34:26 +0200 <EvanR> to get that a -> a -> a smaller
2025-04-11 01:35:48 +0200cipherrot(~znc-user@user/petrichor) (Ping timeout: 245 seconds)
2025-04-11 01:36:49 +0200 <Guest87> EvanR: I think your Task type needs to be `String -> IO (Either String Task)` (assuming recursive `type` worked)
2025-04-11 01:36:52 +0200merijn(~merijn@host-vr.cgnat-g.v4.dfn.nl) (Ping timeout: 276 seconds)
2025-04-11 01:38:21 +0200 <EvanR> it does not
2025-04-11 01:38:44 +0200 <EvanR> I didn't see the point of the Task datatype as stated
2025-04-11 01:39:09 +0200sayurc_(~sayurc@169.150.203.34) sayurc
2025-04-11 01:39:19 +0200sayurc(~sayurc@169.150.203.34) (Read error: Connection reset by peer)
2025-04-11 01:39:37 +0200 <EvanR> it amounted to a function returning a thing to pass to the next function, and a string to pass into that function
2025-04-11 01:40:45 +0200 <Guest87> The issue is that when I "run" a Task, it either gives a result, or gives me another Task to get the final result
2025-04-11 01:41:03 +0200 <Guest87> Kinda like a trampoline situation I think
2025-04-11 01:42:00 +0200petrichor(~znc-user@user/petrichor) petrichor
2025-04-11 01:42:40 +0200 <EvanR> not in my paste, the next task is next in the list that you maintained
2025-04-11 01:42:58 +0200 <EvanR> if the task itself is supposed to determine that, that's another problem
2025-04-11 01:43:14 +0200 <EvanR> then "adding" a task from outside doesn't make much sense
2025-04-11 01:44:59 +0200 <EvanR> if running the task is supposed to yield a new task and so on, that's more like free monads
2025-04-11 01:45:13 +0200 <EvanR> plus interpreter
2025-04-11 01:46:08 +0200 <EvanR> but if all you're doing is IO actions that sometimes fail early
2025-04-11 01:46:24 +0200 <EvanR> that would be a pretty simple free monad
2025-04-11 01:46:45 +0200 <EvanR> or you could just use IO exceptions to fail early, and catch that exception
2025-04-11 01:46:52 +0200 <EvanR> and write IO actions
2025-04-11 01:47:02 +0200 <EvanR> if you were actually using haskell
2025-04-11 01:47:03 +0200merijn(~merijn@host-vr.cgnat-g.v4.dfn.nl) merijn
2025-04-11 01:50:00 +0200 <EvanR> in both cases you would not be able to outside force a task to suddenly be happening at the end
2025-04-11 01:50:21 +0200 <Guest87> Does "Free" in free monad mean "we get this for free", or does it mean something else?
2025-04-11 01:50:50 +0200 <EvanR> it sure does
2025-04-11 01:50:56 +0200 <EvanR> unless you get more specific
2025-04-11 01:52:01 +0200 <EvanR> but warning, just writing an IO program is already this "task runs and generates the next task to run until the final result"
2025-04-11 01:52:28 +0200merijn(~merijn@host-vr.cgnat-g.v4.dfn.nl) (Ping timeout: 276 seconds)
2025-04-11 01:52:28 +0200 <haskellbridge> <Bowuigi> It means "we get monadic structure for free" (or rather, from a functor)
2025-04-11 01:52:39 +0200 <EvanR> and stitching is just (>>=) :: IO a -> (a -> IO b) -> IO b
2025-04-11 01:53:27 +0200 <EvanR> if a = b = String
2025-04-11 01:53:40 +0200 <EvanR> then your pipeline could be just an IO String
2025-04-11 01:54:02 +0200 <EvanR> and I lied you can tack more IO actions before and after
2025-04-11 01:55:45 +0200 <Guest87> I am reading the following:
2025-04-11 01:55:45 +0200 <Guest87> https://www.haskellforall.com/2012/06/you-could-have-invented-free-monads.html
2025-04-11 01:56:23 +0200 <Guest87> and it feels kinda similar to what I am dealing with
2025-04-11 01:58:16 +0200 <Guest87> The `catch` function feels similar to my `addCont`
2025-04-11 01:59:13 +0200 <EvanR> say you have the IO String
2025-04-11 01:59:27 +0200 <EvanR> and you want to put String -> IO String "at the end" (post process)
2025-04-11 01:59:35 +0200 <EvanR> that's just >>=
2025-04-11 02:00:34 +0200 <EvanR> that's addCont
2025-04-11 02:01:05 +0200 <EvanR> but if you went the route of an interpreter for a free monad, you would "catch" there
2025-04-11 02:01:35 +0200 <EvanR> and >>= would still add another post processing step in that case as well
2025-04-11 02:02:51 +0200merijn(~merijn@host-vr.cgnat-g.v4.dfn.nl) merijn
2025-04-11 02:04:33 +0200jespada(~jespada@r179-25-43-11.dialup.adsl.anteldata.net.uy) (Ping timeout: 248 seconds)
2025-04-11 02:08:04 +0200merijn(~merijn@host-vr.cgnat-g.v4.dfn.nl) (Ping timeout: 276 seconds)
2025-04-11 02:10:12 +0200 <Guest87> Hmmm this is very cool
2025-04-11 02:10:33 +0200 <Guest87> EvanR, thank you so much for patiently letting me fix issues in my program and then talking through it
2025-04-11 02:10:59 +0200 <Guest87> I have ran into "Free Monads" before but this is the first time I see a use case, so I will just go and read about it
2025-04-11 02:18:35 +0200merijn(~merijn@host-vr.cgnat-g.v4.dfn.nl) merijn
2025-04-11 02:23:18 +0200merijn(~merijn@host-vr.cgnat-g.v4.dfn.nl) (Ping timeout: 245 seconds)
2025-04-11 02:25:52 +0200Unicorn_Princess(~Unicorn_P@user/Unicorn-Princess/x-3540542) (Remote host closed the connection)
2025-04-11 02:30:12 +0200ChaiTRex(~ChaiTRex@user/chaitrex) (Ping timeout: 264 seconds)
2025-04-11 02:30:46 +0200ChaiTRex(~ChaiTRex@user/chaitrex) ChaiTRex
2025-04-11 02:33:59 +0200potatoespotatoes(~quassel@user/potatoespotatoes) ()
2025-04-11 02:34:22 +0200merijn(~merijn@host-vr.cgnat-g.v4.dfn.nl) merijn
2025-04-11 02:35:42 +0200ezzieyguywuf(~Unknown@user/ezzieyguywuf) ezzieyguywuf
2025-04-11 02:36:40 +0200potatoespotatoes(~quassel@130.44.147.204)
2025-04-11 02:36:40 +0200potatoespotatoes(~quassel@130.44.147.204) (Changing host)
2025-04-11 02:36:40 +0200potatoespotatoes(~quassel@user/potatoespotatoes) potatoespotatoes
2025-04-11 02:39:06 +0200merijn(~merijn@host-vr.cgnat-g.v4.dfn.nl) (Ping timeout: 252 seconds)
2025-04-11 02:39:15 +0200potatoespotatoes(~quassel@user/potatoespotatoes) (Client Quit)
2025-04-11 02:39:17 +0200sabathan2(~sabathan@amarseille-159-1-12-107.w86-203.abo.wanadoo.fr) (Ping timeout: 248 seconds)
2025-04-11 02:39:45 +0200potatoespotatoes(~quassel@130.44.147.204) potatoespotatoes
2025-04-11 02:39:45 +0200potatoespotatoes(~quassel@130.44.147.204) (Changing host)
2025-04-11 02:39:45 +0200potatoespotatoes(~quassel@user/potatoespotatoes) potatoespotatoes
2025-04-11 02:42:57 +0200sabathan2(~sabathan@amarseille-159-1-12-107.w86-203.abo.wanadoo.fr)
2025-04-11 02:50:21 +0200merijn(~merijn@host-vr.cgnat-g.v4.dfn.nl) merijn
2025-04-11 02:57:20 +0200merijn(~merijn@host-vr.cgnat-g.v4.dfn.nl) (Ping timeout: 252 seconds)
2025-04-11 02:57:21 +0200 <haskellbridge> <Bowuigi> lens-regex-pcre introduces a clever approach to implementing and extending structural regular expressions. Are there generalizations of this? Such that you can query parts of a structure and modify them based on that
2025-04-11 02:57:49 +0200peterbecich(~Thunderbi@syn-047-229-123-186.res.spectrum.com) peterbecich
2025-04-11 02:58:16 +0200otto_s(~user@p4ff278a2.dip0.t-ipconnect.de) (Ping timeout: 265 seconds)
2025-04-11 02:58:54 +0200 <geekosaur> isn't that … lens?
2025-04-11 02:59:13 +0200 <haskellbridge> <Bowuigi> No no I mean, optics that check if there's a certain node inside a tree and allow you to modify the place where the query is ran rather than the node
2025-04-11 02:59:45 +0200otto_s(~user@p5de2fd33.dip0.t-ipconnect.de)
2025-04-11 03:01:53 +0200 <haskellbridge> <Bowuigi> "branch . without leaf" matching branches that do not have leaves as their inmediate substructures, for example
2025-04-11 03:02:26 +0200 <glguy> You can write that in regular lens
2025-04-11 03:02:29 +0200 <geekosaur> I think there are optics for that?
2025-04-11 03:03:03 +0200 <haskellbridge> <Bowuigi> I'd assume so yeah
2025-04-11 03:03:22 +0200 <glguy> you need to be careful about going and adding a leaf in that case where there wasn't one there before it you want to be able to use lens law reasoning
2025-04-11 03:08:13 +0200merijn(~merijn@host-vr.cgnat-g.v4.dfn.nl) merijn
2025-04-11 03:08:17 +0200 <haskellbridge> <Bowuigi> Based on that warning I think that filtered is what I'm looking for
2025-04-11 03:09:17 +0200 <haskellbridge> <Bowuigi> Actually no, it's rewriteOf
2025-04-11 03:09:54 +0200xff0x(~xff0x@2405:6580:b080:900:1c0d:6c97:349e:6228) (Ping timeout: 252 seconds)
2025-04-11 03:10:02 +0200 <haskellbridge> <Bowuigi> Based on this example https://github.com/stevenfontanella/microlens/pull/119#issuecomment-496004851
2025-04-11 03:13:43 +0200merijn(~merijn@host-vr.cgnat-g.v4.dfn.nl) (Ping timeout: 276 seconds)
2025-04-11 03:17:22 +0200acidjnk(~acidjnk@p200300d6e71c4f7444aa95b6f7c7abd1.dip0.t-ipconnect.de) (Ping timeout: 272 seconds)
2025-04-11 03:24:00 +0200merijn(~merijn@host-vr.cgnat-g.v4.dfn.nl) merijn
2025-04-11 03:26:35 +0200__jmcantrell__(~weechat@user/jmcantrell) jmcantrell
2025-04-11 03:26:35 +0200jmcantrellGuest8811
2025-04-11 03:26:35 +0200Guest8811(644f1bed9a@user/jmcantrell) (Killed (copper.libera.chat (Nickname regained by services)))
2025-04-11 03:26:35 +0200__jmcantrell__jmcantrell
2025-04-11 03:26:44 +0200jmcantrell_(644f1bed9a@user/jmcantrell) jmcantrell
2025-04-11 03:29:19 +0200merijn(~merijn@host-vr.cgnat-g.v4.dfn.nl) (Ping timeout: 276 seconds)
2025-04-11 03:31:42 +0200Guest87(~Guest87@2620:72:0:1f18:7d2a:62e7:7a20:d79f) (Quit: Client closed)
2025-04-11 03:32:41 +0200ezzieyguywuf(~Unknown@user/ezzieyguywuf) (Quit: Lost terminal)
2025-04-11 03:34:32 +0200ezzieyguywuf(~Unknown@user/ezzieyguywuf) ezzieyguywuf
2025-04-11 03:39:48 +0200merijn(~merijn@host-vr.cgnat-g.v4.dfn.nl) merijn
2025-04-11 03:43:03 +0200OftenFaded(~OftenFade@user/tisktisk) OftenFaded
2025-04-11 03:44:55 +0200merijn(~merijn@host-vr.cgnat-g.v4.dfn.nl) (Ping timeout: 276 seconds)
2025-04-11 03:55:34 +0200merijn(~merijn@host-vr.cgnat-g.v4.dfn.nl) merijn
2025-04-11 04:00:30 +0200merijn(~merijn@host-vr.cgnat-g.v4.dfn.nl) (Ping timeout: 252 seconds)
2025-04-11 04:05:35 +0200xff0x(~xff0x@fsb6a9491c.tkyc517.ap.nuro.jp)
2025-04-11 04:11:21 +0200merijn(~merijn@host-vr.cgnat-g.v4.dfn.nl) merijn
2025-04-11 04:16:19 +0200merijn(~merijn@host-vr.cgnat-g.v4.dfn.nl) (Ping timeout: 260 seconds)
2025-04-11 04:20:04 +0200peterbecich(~Thunderbi@syn-047-229-123-186.res.spectrum.com) (Ping timeout: 272 seconds)
2025-04-11 04:21:58 +0200inca(~inca@pool-96-255-212-224.washdc.fios.verizon.net) (Ping timeout: 276 seconds)
2025-04-11 04:22:26 +0200haskellbridge(~hackager@syn-024-093-192-219.res.spectrum.com) (Remote host closed the connection)
2025-04-11 04:23:00 +0200haskellbridge(~hackager@syn-024-093-192-219.res.spectrum.com) hackager
2025-04-11 04:23:00 +0200ChanServ+v haskellbridge
2025-04-11 04:26:58 +0200merijn(~merijn@host-vr.cgnat-g.v4.dfn.nl) merijn
2025-04-11 04:30:15 +0200ezzieyguywuf(~Unknown@user/ezzieyguywuf) (Remote host closed the connection)
2025-04-11 04:30:52 +0200Sciencentistguy(~sciencent@hacksoc/ordinary-member) (Quit: Ping timeout (120 seconds))
2025-04-11 04:31:13 +0200Sciencentistguy(~sciencent@hacksoc/ordinary-member) sciencentistguy
2025-04-11 04:32:43 +0200ezzieyguywuf(~Unknown@user/ezzieyguywuf) ezzieyguywuf
2025-04-11 04:33:57 +0200merijn(~merijn@host-vr.cgnat-g.v4.dfn.nl) (Ping timeout: 248 seconds)
2025-04-11 04:34:08 +0200ezzieyguywuf(~Unknown@user/ezzieyguywuf) (Client Quit)
2025-04-11 04:35:48 +0200ezzieyguywuf(~Unknown@user/ezzieyguywuf) ezzieyguywuf
2025-04-11 04:42:15 +0200inca(~inca@pool-96-255-212-224.washdc.fios.verizon.net)
2025-04-11 04:45:02 +0200merijn(~merijn@host-vr.cgnat-g.v4.dfn.nl) merijn
2025-04-11 04:48:24 +0200bitdex(~bitdex@gateway/tor-sasl/bitdex) bitdex
2025-04-11 04:49:16 +0200roconnor(~quassel@rocq/roconnor) (Ping timeout: 276 seconds)
2025-04-11 04:49:19 +0200roconnor_(~quassel@rocq/roconnor) roconnor
2025-04-11 04:49:54 +0200merijn(~merijn@host-vr.cgnat-g.v4.dfn.nl) (Ping timeout: 252 seconds)