Logs: freenode/#haskell
| 2021-04-16 20:50:25 | × | W3BV1P3R quits (~W3BV1P3R@c-73-5-91-226.hsd1.tn.comcast.net) (Client Quit) |
| 2021-04-16 20:52:30 | × | Varis quits (~Tadas@unaffiliated/varis) (Remote host closed the connection) |
| 2021-04-16 20:52:34 | → | fiedlr joins (~fiedlr@83.148.33.254) |
| 2021-04-16 20:52:40 | <qwerty2o> | im looking to implement a fast exponent function, is there a haskell utility that can help me with that (or on that related note, an interesting algorithm that i could try and implement)? |
| 2021-04-16 20:53:23 | × | cole-h quits (~cole-h@c-73-48-197-220.hsd1.ca.comcast.net) (Ping timeout: 265 seconds) |
| 2021-04-16 20:53:53 | → | Varis joins (~Tadas@unaffiliated/varis) |
| 2021-04-16 20:54:49 | × | egorbelibov quits (~65676f72@2001:8a0:5708:2a00:6084:24f9:c0d1:3aaf) (Read error: Connection reset by peer) |
| 2021-04-16 20:56:35 | → | ddellacosta joins (~ddellacos@ool-44c73afa.dyn.optonline.net) |
| 2021-04-16 20:59:20 | × | syntactic_sugar quits (~syntactic@c-67-169-78-228.hsd1.ca.comcast.net) (Quit: syntactic_sugar) |
| 2021-04-16 20:59:23 | × | nbloomf quits (~nbloomf@2600:1700:ad14:3020:441:ad95:9496:73d9) (Quit: My MacBook has gone to sleep. ZZZzzz…) |
| 2021-04-16 20:59:46 | × | Pickchea quits (~private@unaffiliated/pickchea) (Quit: Leaving) |
| 2021-04-16 21:00:37 | <jaykru> | qwerty2o: try this: https://en.wikipedia.org/wiki/Exponentiation_by_squaring and then do the modular version. see if you can prove that the modular version is fast in terms of the length of the binary-encoded input data. i can't think of any particular haskell library that would be needed to implement this idea. in general, IMO, writing everything yourself is instructive for problems like this. |
| 2021-04-16 21:01:19 | <SrPx> | https://github.com/uwu-tech/Kind/blob/master/blog/1-beyond-inductive-datatypes.md |
| 2021-04-16 21:01:30 | <monochrom> | The standard library's ^ operator already uses such an algorithm. |
| 2021-04-16 21:02:51 | × | frozenErebus quits (~frozenEre@37.231.244.249) (Ping timeout: 260 seconds) |
| 2021-04-16 21:02:57 | <jaykru> | sure. i think the qwerty2o was looking for an exercise, but i might be wrong. the stdlib implementation would be a good thing to compare their solution with :) |
| 2021-04-16 21:03:15 | <monochrom> | http://hackage.haskell.org/package/base-4.15.0.0/docs/src/GHC-Real.html#%5e is the source code |
| 2021-04-16 21:03:52 | × | joncol quits (~jco@c83-248-173-38.bredband.comhem.se) (Ping timeout: 240 seconds) |
| 2021-04-16 21:04:45 | → | ep1ctetus joins (~epictetus@ip72-194-54-201.sb.sd.cox.net) |
| 2021-04-16 21:04:57 | <jaykru> | that's some interesting code. i didn't know about the RULES pragma |
| 2021-04-16 21:05:04 | → | vicfred_ joins (~vicfred@unaffiliated/vicfred) |
| 2021-04-16 21:06:04 | × | tsaka__ quits (~torstein@athedsl-4519432.home.otenet.gr) (Quit: Konversation terminated!) |
| 2021-04-16 21:06:16 | × | vicfred quits (~vicfred@unaffiliated/vicfred) (Read error: Connection reset by peer) |
| 2021-04-16 21:06:35 | <monochrom> | Yikes haha this is known as "sorry excuse for constant folding" |
| 2021-04-16 21:07:00 | <jaykru> | i don't really see the point of this pragma; why not just do a pattern match in the language? |
| 2021-04-16 21:07:44 | <jaykru> | and what's going on with the useless `let` in the right-hand sides? |
| 2021-04-16 21:08:30 | <monochrom> | There is still a runtime difference between "during run time do a compare and then a conditional branch" and "during run time there is no conditional branching the code is u*u*u*u" |
| 2021-04-16 21:09:06 | × | nrh^ quits (nrh@ip98-184-89-2.mc.at.cox.net) () |
| 2021-04-16 21:09:11 | <monochrom> | But I don't know what's the author's motivation. |
| 2021-04-16 21:10:24 | <monochrom> | That "let" is memoization vs recomputation when "x" is an arbitrary expression. |
| 2021-04-16 21:11:11 | <jaykru> | is it actually memoization in lazy evaluation? |
| 2021-04-16 21:11:12 | × | raehik quits (~raehik@cpc95906-rdng25-2-0-cust156.15-3.cable.virginm.net) (Ping timeout: 240 seconds) |
| 2021-04-16 21:11:20 | × | ddellacosta quits (~ddellacos@ool-44c73afa.dyn.optonline.net) (Remote host closed the connection) |
| 2021-04-16 21:11:34 | <monochrom> | lazy evaluation has a memoization part. I am referring to that part. |
| 2021-04-16 21:11:40 | → | raehik joins (~raehik@cpc95906-rdng25-2-0-cust156.15-3.cable.virginm.net) |
| 2021-04-16 21:11:57 | <monochrom> | err I mean "yes" :) |
| 2021-04-16 21:12:24 | → | ddellaco_ joins (~ddellacos@ool-44c73afa.dyn.optonline.net) |
| 2021-04-16 21:13:07 | <jaykru> | oh right, haskell laziness = call-by-name + memoization. but i wonder why evaluating say x*x*x*x wouldn't cache x on its first evaluation whereas let u = x in u*u*u*u would |
| 2021-04-16 21:13:43 | <ep1ctetus> | Is it a good practice to write IO actions into your own typeclass, so that you can test them outside of IO? As described in this post: https://making.pusher.com/unit-testing-io-in-haskell/ |
| 2021-04-16 21:13:51 | × | kritzefitz quits (~kritzefit@212.86.56.80) (Remote host closed the connection) |
| 2021-04-16 21:14:00 | <monochrom> | But if you do "(fib 100)*(fib 100)*(fib 100)" that will be recomputation rather than reuse. |
| 2021-04-16 21:14:14 | <qwerty2o> | jakalx, you mean this: https://en.wikipedia.org/wiki/Modular_exponentiation |
| 2021-04-16 21:14:18 | <qwerty2o> | ? |
| 2021-04-16 21:14:53 | <monochrom> | It's when you do either "let u = fib 100 in u*u*u" or "(\u -> u*u*u) (fib 100)" that you enjoy the reuse. |
| 2021-04-16 21:14:56 | × | LKoen quits (~LKoen@65.250.88.92.rev.sfr.net) (Quit: “It’s only logical. First you learn to talk, then you learn to think. Too bad it’s not the other way round.”) |
| 2021-04-16 21:15:27 | <jaykru> | qwerty2o: that is indeed the problem, the other link i sent talks about how to use repeated squaring to solve that problem as well. scroll down a bit :) |
| 2021-04-16 21:15:43 | <monochrom> | ep1ctetus: Yes IMO when within reason. |
| 2021-04-16 21:16:10 | <jaykru> | monochrom: oh i see. so haskell only caches computations when associated with an identifier rather than, say, application expressions. |
| 2021-04-16 21:17:39 | <jaykru> | and i guess the reason you need to introduce `u` is that the `x` in the RULE is some sort of weird metavariable rather than a proper haskell variable |
| 2021-04-16 21:18:14 | <monochrom> | Yeah |
| 2021-04-16 21:19:37 | <ep1ctetus> | monochrom: I've read various things about how it's unwieldy to make new Monad Transformers, but this post makes it seem like no big deal |
| 2021-04-16 21:19:57 | × | jpds quits (~jpds@gateway/tor-sasl/jpds) (Remote host closed the connection) |
| 2021-04-16 21:20:35 | <monochrom> | Monad transformers are on the instance side. But MonadHTTP is on the class side. |
| 2021-04-16 21:21:07 | <monochrom> | And nothing says that you must or must not use, say, StateT for your instance of MonadHTTP. |
| 2021-04-16 21:21:32 | <ep1ctetus> | ah, right, that makes sense |
| 2021-04-16 21:22:34 | <monochrom> | And even the critiques against the classes in mtl is that MonadState, MonadReader, MonadWriter are too broad to be meaningful. The very same critiques conclude that you should design your own domain-specific MonadHTTP class. |
| 2021-04-16 21:22:46 | → | jpds joins (~jpds@gateway/tor-sasl/jpds) |
| 2021-04-16 21:25:13 | <monochrom> | On the instance side, it is OK to newtype-wrap around StateT (X,Y) (ReaderT Z IO). This satisfies both encapsulation and don't-reinvent-the-wheel. |
| 2021-04-16 21:26:33 | <ep1ctetus> | Yes, the Real World Haskell book has good examples of this |
| 2021-04-16 21:26:48 | <monochrom> | But it is really the same logic as "should I use (Int, Double) or should define data MyType = Make Int Double", "should I use type Level = Int or should I use newtype Level = Level Int" |
| 2021-04-16 21:27:34 | × | tumdedum quits (~tumdedum@unaffiliated/espiral) (Ping timeout: 276 seconds) |
| 2021-04-16 21:28:06 | → | tumdedum joins (~tumdedum@unaffiliated/espiral) |
| 2021-04-16 21:28:51 | × | hiroaki_ quits (~hiroaki@2a02:908:4b18:8c40:8c7f:db9f:4c52:d3d3) (Ping timeout: 248 seconds) |
| 2021-04-16 21:29:07 | × | jpds quits (~jpds@gateway/tor-sasl/jpds) (Remote host closed the connection) |
| 2021-04-16 21:29:58 | × | Guest45254 quits (~textual@zrcout.mskcc.org) (Ping timeout: 240 seconds) |
| 2021-04-16 21:31:39 | <ep1ctetus> | It's considered safer to use newtype, right? Because when you just use plain type or a plain tuple you're open to bad values that are the correct type |
| 2021-04-16 21:31:51 | → | jpds joins (~jpds@gateway/tor-sasl/jpds) |
| 2021-04-16 21:32:01 | → | eacameron joins (uid256985@gateway/web/irccloud.com/x-mgmmticzouvypcht) |
| 2021-04-16 21:32:57 | <monochrom> | Yes. And also machine-checked meaningful type names. |
| 2021-04-16 21:34:27 | → | jlode21 joins (54d781ab@84.215.129.171) |
| 2021-04-16 21:34:56 | <jlode21> | Hey. I'm trying to multiply together two `Nat`s (from GHC.TypeLits). Should this be extremely difficult? |
| 2021-04-16 21:35:15 | <monochrom> | Yes. |
| 2021-04-16 21:35:19 | <jlode21> | :k! (1 :: Nat) + (1 :: Nat) |
| 2021-04-16 21:35:22 | <jlode21> | gives me 1 as a result |
| 2021-04-16 21:35:36 | <jlode21> | Replacing + by * gives |
| 2021-04-16 21:35:38 | <jlode21> | Expected kind ‘* -> Nat -> k0’, but ‘5 :: Nat’ has kind ‘Nat’ |
| 2021-04-16 21:35:50 | <jlode21> | Err, and I'm obviously using other numbers than 1 :)) |
| 2021-04-16 21:35:57 | → | frozenErebus joins (~frozenEre@37.231.244.249) |
| 2021-04-16 21:36:02 | <monochrom> | Haha that's not even extremely difficult. It's extremely wrong. >:) |
| 2021-04-16 21:36:42 | <jlode21> | How so? (: I don't see how I could be making any mistakes by replacing + by * |
| 2021-04-16 21:37:08 | <monochrom> | Well, 1+1=1 is extremely wrong. |
| 2021-04-16 21:37:10 | × | mikoto-chan quits (~anass@gateway/tor-sasl/mikoto-chan) (Remote host closed the connection) |
| 2021-04-16 21:37:43 | <monochrom> | But * = Type so I don't think the computer is understanding you when you write "1*1". |
| 2021-04-16 21:37:44 | <jlode21> | Haha, d'oh |
| 2021-04-16 21:38:12 | <jlode21> | That's not what I'm actually getting. I just made up an example, and I'm really bad at arithmetic |
| 2021-04-16 21:38:21 | <monochrom> | There is an extension, something like NoStarType, that you could use to regain * as a binary operator |
| 2021-04-16 21:38:49 | <monochrom> | NoStarIsType is closer. I'm too lazy to look it up. |
| 2021-04-16 21:39:24 | <hpc> | imagine a reasonable name for StarIsType and add "No" to it |
| 2021-04-16 21:39:30 | <jlode21> | Thank you! |
| 2021-04-16 21:39:47 | <jlode21> | I was unable to find anything useful via google |
| 2021-04-16 21:39:51 | <hpc> | all of the No* extensions are turning off a yes extension |
| 2021-04-16 21:40:18 | <jlode21> | I'd expect something like this to be explained under `type family n * m` in GHC.TypeLits |
| 2021-04-16 21:40:19 | <monochrom> | Yeah it's from StarIsType |
| 2021-04-16 21:43:08 | → | Alleria joins (~textual@2603-7000-3040-0000-7880-0355-734f-9c41.res6.spectrum.com) |
| 2021-04-16 21:43:26 | <jlode21> | Now, in there an alternative way to say `Type` if I can't say it with * (since I just disabled that)? |
| 2021-04-16 21:43:27 | × | Alleria quits (~textual@2603-7000-3040-0000-7880-0355-734f-9c41.res6.spectrum.com) (Client Quit) |
| 2021-04-16 21:44:10 | × | fendor quits (~fendor@178.165.131.109.wireless.dyn.drei.com) (Ping timeout: 252 seconds) |
| 2021-04-16 21:44:15 | <jlode21> | Guess that's Data.Kind (Type) |
| 2021-04-16 21:45:01 | <monochrom> | Yeah import it from Data.Kind then you can use it. |
| 2021-04-16 21:45:11 | <jlode21> | Sorry, I'll stop rubber ducking. That's a lot for the help :) |
All times are in UTC.