<    March 2017    >
Su Mo Tu We Th Fr Sa  
          1  2  3  4  
 5  6  7  8  9 10 11  
12 13 14 15 16 17 18  
19 20 21 22 23 _2_4 25  
26 27 28 29 30 31
00:01 defaultnick joined
00:01 ilja_kuklic joined
00:01 markus1209 joined
00:02 markus1219 joined
00:02 meba joined
00:02 <glguy> robkennedy: The type 'o' can't float out of (forall i. c i => i -> o) because we don't know what c is
00:02 <glguy> c could have equality constraints
00:02 mr_sm1th joined
00:02 michael1 joined
00:03 jrajav joined
00:03 <glguy> and type families are not injective, so 'o' isn't available under FullOf'
00:03 defaultnick___ joined
00:03 peterbecich joined
00:06 cschneid_ joined
00:07 <Axman6> bgamari: yeah the first definition I stumbled across was v1, which has een replaced by v2 which seems to be much better specified: http://docs.opengeospatial.org/is/12-063r5/12-063r5.html#13 in particular, it outlines what a <number> is, which the old one left unspecified... who even does that
00:07 <bgamari> heh
00:07 <bgamari> that may explain it
00:08 <bgamari> would you like to fix this or should i?
00:08 solrize joined
00:08 solrize joined
00:08 <Axman6> bgamari: I might give it a go if I have time, but today it least that's looking unlikely :)
00:08 <bgamari> I can have a look tonight
00:10 <Axman6> don't rush into it on my account though, I don't have a good usecase for it yet, just wanted a nicer structure for dealing with projection descriptions.
00:10 ego joined
00:10 theDon_ joined
00:10 jmcarthur joined
00:11 ludat joined
00:11 <* Axman6> has grand but probably very ambitious plan to rewrite proj4 in Haskell
00:13 Eduard_Munteanu joined
00:13 myrdin joined
00:14 <bgamari> Axman6, that would be great
00:14 <bgamari> we could really use some better geospatial tools
00:14 <* bgamari> has done some hydrological modelling in Haskell and it was quite painful
00:15 <Axman6> yes,very much so. I was surprised how understandable proj4 actually is tbh
00:15 xcmw joined
00:15 snowalpaca joined
00:16 TxmszLou joined
00:17 TxmszLou joined
00:17 <robkennedy> How can I silence unused errors for data constructors (since I can't use `newtype F = _F {unF :: Int}`)
00:18 myrdin left
00:18 <glguy> You can export the data constructor
00:20 JeanCarloMachado joined
00:20 plutoniix joined
00:20 afarmer joined
00:20 <robkennedy> Yeah, but it's an internal type. Seems like the hack will be to replace an unF site with the F syntax
00:21 plutoniix joined
00:21 mounty joined
00:21 <glguy> It's an internal type for which you never construct a value?
00:22 <`Guest00000> there are no functions fractional :: Double -> Double and floor_f :: Double -> Double in Haskell????
00:22 <robkennedy> Or like, I have example values in my code I don't export called like `_example`, but I can't have example types called _Example
00:22 <`Guest00000> nooo
00:23 <Axman6> glguy: what do you want those functions to do?
00:23 <Axman6> uh, `Guest00000
00:24 <robkennedy> :t fromIntegral . floor :: Double -> Double
00:24 <lambdabot> Double -> Double
00:24 pasukon joined
00:24 <`Guest00000> Axman6: return the fractional part and return floor
00:24 <`Guest00000> robkennedy: but that's probably inefficient
00:24 <glguy> :t properFraction
00:24 <lambdabot> (RealFrac a, Integral b) => a -> (b, a)
00:24 augur joined
00:25 <Axman6> `Guest00000: "probably" sounds like you haven't tested
00:26 segmond joined
00:26 sid_fules joined
00:26 <Axman6> :t truncate
00:26 <lambdabot> (RealFrac a, Integral b) => a -> b
00:26 <Axman6> hmm
00:27 Swizec joined
00:27 diegoksp joined
00:28 <robkennedy> > properFraction pi
00:28 <lambdabot> (3,0.14159265358979312)
00:28 lambda-11235 joined
00:28 darjeeling joined
00:28 nakal joined
00:30 darjeeling joined
00:30 darjeelinG joined
00:31 defaultnick joined
00:33 carlomagno joined
00:35 segmond joined
00:36 Rotaerk joined
00:36 fizruk joined
00:38 deepfire joined
00:39 JeanCarloMachado joined
00:39 defaultnick__ joined
00:39 segmond joined
00:43 sellout- joined
00:44 infinity0 joined
00:45 janos__ joined
00:45 tomboy64 joined
00:47 gcross_ joined
00:47 sellout- joined
00:48 gatsbyverde joined
00:49 oaao joined
00:49 jedws joined
00:50 cschneid_ joined
00:51 defaultnick__ joined
00:51 <`Guest00000> so
00:51 nighty joined
00:51 <`Guest00000> i just tested it
00:51 <`Guest00000> and, as https://mail.haskell.org/pipermail/haskell-cafe/2008-January/038022.html says, those are slow
00:52 ramzifu joined
00:52 <`Guest00000> int2Double . double2Int is faster
00:52 <`Guest00000> but it's non-portable
00:53 andyhuzhill joined
00:54 pleax joined
00:55 Nicmavr joined
00:55 aarvar joined
00:55 Guest83939 joined
00:56 Igloo joined
00:57 sid_fules joined
00:57 <glguy> `Guest00000: You get that for free after optimizations
00:57 <glguy> test :: Double -> Double; test x = fromIntegral (truncate x :: Int) -- compiles to
00:58 <glguy> \x -> case x of D# y -> D# (int2Double# (double2Int# y))
00:58 <`Guest00000> that brings me to the question of how explicit the optimizations should be
00:58 <`Guest00000> because implicit = unreliable
00:59 <robkennedy> Man, `snd . properFraction` ought to be optimal. You could submit a PR to make `properFraction = (,) <$> intToDouble . doubleToInt <*> (\x -> x - doubleToInt x)`
00:59 markasoftware joined
00:59 <glguy> robkennedy: that's already what it is
00:59 <glguy> if you specify Int
00:59 gugah joined
01:00 markus1189 joined
01:00 markus1199 joined
01:00 <`Guest00000> ohh
01:00 <robkennedy> Sorry, that doesn't typecheck, but you get what I mean
01:00 nighty joined
01:00 <robkennedy> glguy: tight
01:01 k0001_ joined
01:02 anuxivm left
01:02 <`Guest00000> glguy: hmm no
01:03 <`Guest00000> i just tested snd . (properFraction :: Double -> (Int, Double))
01:03 <`Guest00000> has same slowness
01:03 <`Guest00000> well
01:03 <`Guest00000> will try -O...
01:04 xaviergmail_ joined
01:04 <glguy> You forgot the optimization flag when timing the previous one?
01:05 nighty joined
01:05 Claudius1aximus joined
01:06 <`Guest00000> ok
01:06 <`Guest00000> with optimizations, int2Double . double2Int seems slightly faster...
01:06 <`Guest00000> than snd . properFraction with Int
01:06 rperry joined
01:07 <glguy> fromIntegral . (truncate :: Double -> Int)
01:07 <glguy> for some reason the snd . properFraction version does an extra test
01:08 nighty- joined
01:09 defaultnick___ joined
01:09 <`Guest00000> ok
01:09 <`Guest00000> thanks for replies
01:10 <`Guest00000> it's awful that by default fromIntegral . truncate will specialize to Integer and be slower
01:11 louispan joined
01:12 <hpc> something for HaskellPrime maybe?
01:12 <hpc> specializing to Int is a bit of a concession, but maybe being explicit about numbers that large is better than being explicit about optimizations
01:14 zar joined
01:14 Textmode joined
01:15 brynedwa1ds joined
01:15 iross_ joined
01:17 sdothum joined
01:17 oisdk joined
01:18 jsgrant_ joined
01:18 defaultnick joined
01:19 <`Guest00000> but still
01:19 <`Guest00000> frac :: Double -> Double isn't even in prelude
01:22 sdothum joined
01:23 dan_f joined
01:26 Boomerang joined
01:27 mtncoder joined
01:28 sid_fules joined
01:30 sdothum joined
01:32 defaultnick__ joined
01:33 bencryption joined
01:34 twopoint718 joined
01:36 defaultnick__ joined
01:38 sdothum joined
01:39 igt0 joined
01:40 path[l] joined
01:43 afarmer joined
01:45 Jesin joined
01:46 sdothum joined
01:47 robertkennedy joined
01:47 jchia joined
01:48 defaultnick joined
01:49 andyhuzhill joined
01:53 mr_sm1th joined
01:54 pleax joined
01:55 emmanuel_erc joined
01:55 vwker joined
01:59 sid_fules joined
02:00 indi_ joined
02:00 harfangk joined
02:01 conal joined
02:02 louispan joined
02:02 pickle_ joined
02:03 juhp joined
02:03 edffef joined
02:05 conal joined
02:05 FreeBirdLjj joined
02:07 michael1 joined
02:07 meba joined
02:10 mkoenig_ joined
02:11 pickle_ left
02:12 gugah joined
02:13 skeuomorf joined
02:15 JPisaBrony left
02:21 defaultnick_ joined
02:24 chrisdotcode joined
02:25 remer688 joined
02:26 djapo joined
02:26 ChaseBen joined
02:29 juhp joined
02:29 sid_fules joined
02:29 sdothum joined
02:31 afarmer joined
02:33 Wizek joined
02:33 Wizek_ joined
02:34 darjeeling_ joined
02:34 sdothum joined
02:35 pickle_ joined
02:36 andrei_chifa joined
02:36 sdothum joined
02:39 FreeBirdLjj joined
02:40 nshepperd joined
02:42 FreeBirdLjj joined
02:42 funkshun joined
02:42 hiWorld joined
02:43 hiWorld joined
02:45 sobaken joined
02:46 twopoint718 joined
02:47 FreeBirdLjj joined
02:48 louispan joined
02:49 FreeBirdLjj joined
02:50 brh joined
02:51 sh0rug0ru joined
02:52 ramzifu joined
02:52 FreeBirdLjj joined
02:55 coltfred joined
02:55 pickle_ left
02:55 xcmw joined
02:55 pleax joined
02:55 travula joined
02:56 FreeBirdLjj joined
02:59 diegoksp joined
03:00 steeze joined
03:00 hucksy joined
03:03 FreeBirdLjj joined
03:03 michael1 joined
03:05 shafox joined
03:05 manlet joined
03:07 xcmw joined
03:07 FreeBirdLjj joined
03:08 meba joined
03:11 falafel joined
03:13 CoconutCrab joined
03:14 deepfire joined
03:15 pickle_ joined
03:15 <Koterpillar> Is there a library to ulimit one's process (specifically memory)?
03:15 afarmer joined
03:15 sid_fules joined
03:16 dmwit_ joined
03:16 <kadoban> There's RTS flags for that as I recall, if it's a haskell program. And I believe they can be compiled in.
03:16 doomlord joined
03:17 <c_wraith> you can also set the maximum number of allocations for a specific forkIO thread
03:18 <Koterpillar> there's some kind of a leak in non-Haskell code I'm calling via FFI
03:21 sellout-1 joined
03:21 defaultnick joined
03:22 andrei_chifa joined
03:22 coot joined
03:22 peterbecich joined
03:23 gabe4k joined
03:24 Cxom joined
03:24 <Claudius1aximus> Koterpillar: you could FFI out to setrlimit() perhaps, not sure if there's a binding already
03:25 defaultnick joined
03:25 xtreak joined
03:26 FreeBirdLjj joined
03:26 swalladge joined
03:27 Tourist joined
03:27 Tourist joined
03:29 rekahsoft joined
03:30 permagreen joined
03:32 pickle_ joined
03:32 drostie joined
03:34 rekahsoft joined
03:36 dan_f joined
03:36 gugah_ joined
03:39 defaultnick_ joined
03:39 wtetzner joined
03:40 johnmendonca joined
03:40 mizu_no_oto joined
03:41 howdoi joined
03:42 mda1 joined
03:43 pickle_ joined
03:43 FreeBirdLjj joined
03:43 yuri_ joined
03:45 defaultnick joined
03:45 yuri joined
03:46 cdg joined
03:46 yuri joined
03:46 peterbecich joined
03:46 sid_fules joined
03:48 yuri joined
03:49 fabianhu joined
03:49 takle joined
03:56 exferenceBot joined
03:57 takle joined
03:57 defaultnick_ joined
03:57 twopoint718 joined
03:58 xlaech joined
03:58 benl23 joined
03:58 pleax joined
03:58 haskull joined
03:58 <xlaech> wow :) Didn't expect so much people in here
03:59 <kadoban> :)
03:59 FreeBirdLjj joined
04:00 Welkin joined
04:00 hexagoxel joined
04:01 pickle_ joined
04:02 shurick joined
04:02 cdg_ joined
04:04 Koterpillar joined
04:04 <haskull> could someone with the latest ghc version test if https://hastebin.com/zihagukafi.hs causes a panic?
04:04 takle joined
04:05 Koterpillar joined
04:05 jake___ joined
04:06 jake___ left
04:07 jake___ joined
04:08 eklavya joined
04:09 defaultnick__ joined
04:09 <jake___> @help
04:09 <lambdabot> help <command>. Ask for help for <command>. Try 'list' for all commands
04:11 Xlaech joined
04:11 jake___ left
04:11 sdothum joined
04:12 Uakh joined
04:13 Big_G joined
04:13 Xlaech joined
04:13 jbiesnecker joined
04:14 v0id joined
04:15 Uakh joined
04:15 otto_s_ joined
04:16 pickle_ joined
04:17 sid_fules joined
04:17 eklavya_ joined
04:20 defaultnick__ joined
04:20 robotroll joined
04:20 <deepfire> is there a typeclass that would give a least upper bound on pairs of Linear.V2.V2? I.e. (V2 0 1) (V2 1 0) -> (V2 1 1)
04:21 sdothum joined
04:21 <deepfire> I have tried to peruse the V2 class haddocks, yet to no avail..
04:23 electrostat joined
04:24 <deepfire> I'm seeing Data.Lub, but is that all?
04:24 <deepfire> Data.Lub has no instances for V2.. not that they aren't trivial to provide, but if there already is such a class with instances, then why not..
04:25 <Claudius1aximus> haskull: no panic in ghci-8.0.2, just a type error
04:29 xtreak joined
04:29 sssilver joined
04:30 pickle_ left
04:31 erisco joined
04:31 <sssilver> I'm so fucking annoyed, there's this guy in my company that keeps arguing that OOP is the only true way and exercising functional programming is "ignoring 40 years of programming research" and going back to 60ies
04:31 <sssilver> the worst part is that he reviews everyone's pull requests and just keeps imposing this crap
04:31 <Rotaerk> immediate aversion is the reaction I get from a lot of people the moment I start suggesting concepts related to FP
04:31 <erisco> this person sounds fictional
04:32 <sssilver> erisco I can actually paste slabs of arguments on slack
04:32 <sssilver> *from slack
04:32 <Koterpillar> wrap everything in appropriate Action<> classes or equivalents :P
04:33 <erisco> I trust you. A perfect FP antagonist is just unlikely
04:33 <sssilver> "why is this function an orphan?" is a question I had to answer today
04:33 hexagoxel joined
04:33 i-amd3 joined
04:33 <orion> ha
04:33 <Rotaerk> erisco, but imperfect ones are common?
04:33 <erisco> yes
04:34 <erisco> like the ones with aversion you meet ;)
04:34 pickle__ joined
04:34 <Rotaerk> heh
04:34 ddere joined
04:34 <erisco> though usually it is a dismissive "sounds cool"
04:34 <sssilver> I get it that people have opinions but I just hate this air of relentless self-righteousness
04:34 <deepfire> investment, danger, etc.
04:35 <Rotaerk> it's often dismissive until I cross a threshold and then it's SHUT UP
04:35 <sssilver> it's almost like he finally grasped the concept of polymorphism, and can't get enough
04:35 <Rotaerk> (over a long period of time)
04:36 <erisco> sssilver, people with strong convictions like that tend to not know a lot -- it is a natural consequence
04:36 defaultnick joined
04:37 <sssilver> we have a large number of junior programmers who can't tell if wisdom and experience or bullshit
04:37 <sssilver> and I just get so freaking annoyed
04:37 shayan_ joined
04:37 <sssilver> I need to learn to be bold and brash and stuff
04:37 sobaken joined
04:38 <Rotaerk> well, it's a sign of the beginner when a person relies on rules of thumb (such as "best practices") to govern their decisions
04:38 <Rotaerk> it's the sign of an *expert* beginner when a person dogmatically adheres to these rules of thumb as dogma
04:38 <sssilver> he's not a beginner, he has like 15 years of experience shipping fairly large systems
04:38 <Rotaerk> (reference to http://www.daedtech.com/how-developers-stop-learning-rise-of-the-expert-beginner/)
04:38 <erisco> the expert beginner, heh :P that is a keen description
04:39 <sssilver> the expert beginner aka "the professional that lacked talent"?
04:39 <orion> That's a great article.
04:39 <sssilver> *the experienced professional that lacked talent
04:40 <erisco> I haven't read that article, but to me that term sounds to the phenomenon of people being most confident when they know just a little bit
04:40 rajiv1 joined
04:40 djapo_ joined
04:40 <erisco> confidence tends to go from "I know nothing" to "I know everything" to "I know little"
04:41 <Rotaerk> the article does mention the dunning kruger effect
04:41 <nshepperd> heh, "orphan" functions. this program needs more implicit state!
04:42 <johnw> for a list [Word8], how much memory is allocated for each Word8 stored? I'm not sure how large the header blocks are on a 64-bit system, for example
04:42 <erisco> how could you possibly be satisfied with that answer johnw? :P the overhead on a byte will at least be another byte
04:43 dbmikus joined
04:43 <johnw> which answer?
04:43 <erisco> to your question
04:43 <johnw> I don't understand what you're saying then
04:43 <Rotaerk> lol
04:43 <johnw> I want to know how much memory is allocated by [0] :: [Word8]
04:44 <erisco> the answer is A. I am saying A >= 2 bytes, and based on that I am saying the price on a byte is too high
04:44 <johnw> erisco: I think you're answering a question I'm not asking
04:44 <johnw> I don't care that the overhead exists, I'm asking how much it is, exactly, in bytes
04:45 <johnw> or, alternatively, how to find that out
04:45 <johnw> I've forgotten what the Haskell equivalent to sizeof is...
04:45 pleax joined
04:47 <johnw> ah, @hackage ghc-datasize
04:48 JoshS joined
04:48 <erisco> I think you want to know sizeof [0] - sizeof []
04:48 sid_fules joined
04:48 doomlord joined
04:48 <johnw> yeah, likely that
04:50 <Rotaerk> deepfire, could you do something like... liftA2 max (V2 0 1) (V2 1 0)
04:50 <Rotaerk> can't test it myself, at the moment
04:50 isenmann joined
04:51 <Rotaerk> or replace liftA2 with mzipWith, since it's implemented as liftA2 for V2
04:52 govg joined
04:52 <Rotaerk> > V2 0 1
04:52 <lambdabot> error:
04:52 <lambdabot> • Data constructor not in scope: V2 :: Integer -> Integer -> t
04:52 <lambdabot> • Perhaps you meant variable ‘_2’ (imported from Control.Lens)
04:53 tommd joined
04:53 <nshepperd> johnw: i seem to recall it being 24 bytes per item
04:56 peterbecich joined
04:56 <deepfire> Rotaerk, thank you, that worked like a charm!
04:57 defaultnick joined
04:57 <Rotaerk> \o/
04:57 <deepfire> that's a good implementation for a HasLub instance : -)
04:58 <johnw> nshepperd: so, there's cons header, cons pointer to Word8, cons pointer to next cell; Word8 header, pointer to Word8 contents; Word8 data. Unless the constructor syntax "W8# Word#" implies some kind of unpacking...
04:58 haskull joined
04:59 <nshepperd> or maybe it's more...oh wait, maybe 24 bytes is just list spine
04:59 <johnw> yeah, definitely 24 in spine
05:01 <nshepperd> so... 24 + 16 = 40 bytes? I think Word# is indeed unpacked
05:01 <johnw> hmm.. GHC.DataSize.recursiveSize says that [0] :: [Word8] uses 376 bytes of memory?
05:01 Rainb joined
05:02 <johnw> and recursizeSizeNF is 600?
05:02 connrs joined
05:02 <ertes> is there a way to set link flags from the Main module via a pragma or some other means to specify a C dependency without cabal or command line?
05:03 <Rotaerk> how do you learn about these low level properties of haskell/ghc?
05:03 defaultnick_ joined
05:03 takle joined
05:04 <nshepperd> johnw: `recursiveSize $! force ([1]::[Word8]` gives me 48 in ghci
05:04 soLucien joined
05:04 <johnw> isn't that what recursiveSizeNF does?
05:04 <johnw> ah, $! makes the difference
05:05 nwf joined
05:05 <nshepperd> recursiveSizeNF looks like a mistake :/
05:05 <johnw> it does, weird numbers
05:05 <nshepperd> it applys `force` but doesn't actually evaluate the value
05:05 <johnw> so, 40 bytes per element, plus 8 for nil
05:05 thunderrd joined
05:06 defaultnick_ joined
05:07 haasn joined
05:07 <kadoban> 376 sounds pretty high, wonder how that adds up. Every possible piece like ... 3? could be a thunk, and then the actual required sizes of stuff? Hmm.
05:07 MP2E joined
05:07 <johnw> nshepperd had it right with 24 + 16
05:08 twopoint718 joined
05:09 rajiv2 joined
05:10 <nshepperd> kadoban: in ghci it's probably a pointer to some extremely unoptimized code for building the list
05:10 <kadoban> Ahh
05:11 takle joined
05:13 <nshepperd> especially with numbers, you've got a whole thunk just to call fromInteger in there
05:13 <nshepperd> (and then another one to build the integer i guess)
05:15 path[l] joined
05:17 FreeBirdLjj joined
05:18 sid_fules joined
05:19 revprez_atlanta joined
05:19 diegoksp joined
05:21 eklavya joined
05:21 doomlord joined
05:22 xcmw joined
05:22 igniting joined
05:26 takle joined
05:26 mstruebing joined
05:28 wedify joined
05:30 n1k joined
05:30 roconnor joined
05:31 Goplat joined
05:31 pleax joined
05:33 ystael joined
05:33 xtreak joined
05:33 dbmikus joined
05:34 roconnor_ joined
05:36 Tourist joined
05:36 Tourist joined
05:38 dbmikus joined
05:39 jbiesnecker joined
05:40 takle joined
05:41 rkazak_ joined
05:42 kritzcreek_ joined
05:44 peterbecich joined
05:44 lowryder joined
05:46 `Guest00000 joined
05:48 fragamus joined
05:48 takle joined
05:48 sibi joined
05:49 defaultnick joined
05:49 sid_fules joined
05:51 sssilver joined
05:54 osa1 joined
05:54 osa1 joined
05:55 lak joined
05:57 ramzifu joined
05:57 <sssilver> do you guys agree that the whole "haskell is hard, it'll brake your teeth" crap is very damaging and misleading and stifles proliferation? it almost seems like a guided narrative
05:57 <sssilver> I consider myself a below average programmer and it's so much easier for me to write bug free code in a language that won't allow me to mess up
05:58 <sssilver> than in a language where I, having my subpar brain, will forget to check for null, or modify state somewhere wrong and forget about it, etc
05:58 <sssilver> Why don't we pursue the Python narrative of "Haskell is programming for the rest of us"
05:59 pantsman_ joined
06:00 defaultnick joined
06:00 <orion> Break your teeth? That's usually what I hear about C.
06:01 <sssilver> orion I think the common narrative is that Haskell is the apogee of programming language "hardness"
06:01 <sssilver> only the enlightened ones have the mental capability to even consider it, let alone approach it
06:01 <dminuoso> sssilver: In C you modify state wrong, in Haskell you reduce to a wrong value. You still get to make *that* mistake :P
06:03 gabe4k joined
06:03 takle joined
06:03 <orion> sssilver: Unfortunately, most imperative programmers I speak with are just talented *enough* to get things working for business people. That's all you need of course.
06:04 raycoll joined
06:06 defaultnick___ joined
06:07 afarmer joined
06:07 travula joined
06:08 sdothum joined
06:08 <orion> They don't care about functional languages because they haven't been incentivized to care.
06:08 <sssilver> like people rave about Javascript because it's approachable by noobs and then sit down and flex their muscles to deal not just with everything being potentially nullable, but freaking nullable in MULTIPLE ways!
06:09 <sssilver> I still can't grok the difference between null and undefined in Javascript
06:09 <sssilver> I mean I can, but it's quite ridiculous
06:09 <MP2E> I think a big part of it is that the tutorials I read come at it from the perspective of understanding the language step by step, and IO comes later, usually accompanied by learning about typeclasses like Monad, Functor, Applicative. For a new user, this can feel like a lot of abstract stuff to take in for something as simple as pulling in input, transforming it in a simple way, and printing it out.
06:09 <MP2E> Of course actually *doing* that isn't a big deal at all
06:10 <orion> I think words like "noobs" are divisive.
06:10 Immune joined
06:10 takle joined
06:11 <MP2E> I think there would be value in a tutorial/book that comes at it from the approach of writing outright imperative haskell at first to get the user off the ground running, and then later delve into the deeper stuff. Maybe there's even already something like this out there
06:11 <MP2E> I didn't have much issues learning Haskell as is, I just think it would be helpful to bring in people from other languages
06:12 <sssilver> MP2E that's roughly how Swift/Rust approach it, i.e. you start programming, and then they go "imagine if you could count on the fact that X will never be null"
06:12 <sssilver> "oh look, we actually have optionals for that!"
06:13 doomlord joined
06:14 <sssilver> explaining optionals to an average person who had to do a null check in every function in their Objective C code is so much easier than explaining the Maybe monad in general terms
06:14 jhrcek joined
06:14 <sssilver> I think one issue is that Haskell books/people tend to approach explanations from a wider/more general angle
06:15 <sssilver> and there's value in approaching these things from a more narrow/practical angle
06:15 connrs joined
06:15 defaultnick_ joined
06:15 <haskull> How would you define a monad concisely, with words any programmer would know?
06:16 tripped joined
06:16 <sssilver> haskull I would probably not define a monad
06:16 <haskull> best I can do is something like "pass data between functions with nice syntax"
06:16 <sssilver> haskull interesting, that's not at all what I think when I think of monads :))
06:16 <orion> The syntax has nothing to do with the definition of a Monad.
06:17 <sssilver> I'd probably explain optionals in practical terms
06:17 <sssilver> e.g. letting the compiler infer what can be null and what cannot be
06:17 <sssilver> and then explain the concept of unwrapping an optional
06:17 <orion> haskull: The most concise, accurate, definition of a monad is the mathematical one. If you're a programmer and you don't understand (or don't *want* to understand) mathematical terms, I have to question your career choice.
06:17 <sssilver> e.g. peek in it to see whether there's value in it
06:18 <sssilver> and then perhaps suggest that the "unwrapping" could in fact be *any* action
06:18 <`Guest00000> haskull: monad is a container which has return and bind.
06:18 wagle joined
06:18 <`Guest00000> and what return and bind are
06:18 <`Guest00000> that's all
06:18 <Rotaerk> haskull, I think that when someone asks what a monad is, you should just say it's an abstract concept that requires sufficient exposure to examples in order to "get"
06:18 <`Guest00000> class of containers, okay
06:18 steeze joined
06:19 <Rotaerk> i.e. there's no quick way to make them go "oh, I get it"
06:19 <orion> Best definition of a Monad: http://hackage.haskell.org/package/base-
06:19 <Rotaerk> well, at least not without misleading them
06:19 <sssilver> `Guest00000 I don't think of it as a container. I think of it as of a type that performs some action when acted upon.
06:19 <sssilver> `Guest00000 it doesn't have to contain anything at all
06:19 <Rotaerk> and the definition itself isn't sufficient for "getting" it
06:20 twopoint718 joined
06:20 <Rotaerk> unless maybe you're just used to mathematical thinking or something
06:20 <orion> haskull: Moreover, you could start by introducing functors first, then applicatives, then maybe monoids, then monads.
06:20 <sssilver> I am completely barefoot when it comes to mathematics, but I successfully ship production Haskell code, and it helps me write bug-free programs that I can actually reason about
06:20 <`Guest00000> well
06:20 <sssilver> my Haskell programs are so much less squishy than my Python programs
06:20 <monochrom> There is one aspect any programmer would not know. Monadness is for things like "Maybe" and "Reader e", not "Maybe a" and "Reader e a". Most programmers do not already have words or concepts of this.
06:21 <`Guest00000> sssilver: i might mean functor instead of "container"
06:21 <orion> sssilver: I suspect that you may find beauty in the mathematics underpinning Haskell.
06:21 <sssilver> `Guest00000 a function in my book is a Java class with a single method called call() :))
06:21 <sssilver> *a functor
06:22 <monochrom> As a corollary, "container" is wrong. Most programmers' "container" refer to things like "List<T>" and "Vector<T>". Emphatically with the <T> there.
06:22 <sssilver> monochrom +1
06:22 <Rotaerk> yea, to monochrom's point, if you want to say "monad is a ___ with a return and a bind function", the ___ should be something to the effect of "a type of kind * -> *"
06:22 hktang joined
06:22 <Rotaerk> and people won't get even THAT without examples
06:23 raycoll joined
06:24 dec0n joined
06:24 <sssilver> Rotaerk I think that doesn't explain what a monad is, because "something that has a return and a bind function" is just stating properties, and that's not very helpful
06:24 <Rotaerk> yes, you need to explain by *showing*, with examples, and let them intuit the concept
06:25 razzi53 joined
06:25 <orion> sssilver: Many programmers I've met have a huge sense of entitlement when it comes to understanding. They think that if they don't understand a concept immediately without any serious study, it's my fault.
06:25 <Rotaerk> mainstream languages tend not to even support higher kinded types... I've even suggested that it'd be nice if C# supported them, and other C# programmers go "eh? why on earth would you want that?"
06:25 Sh4pe joined
06:25 <sssilver> would you explain a chair by "something that has 4 legs and a flat surface attached to them"?
06:26 watabou joined
06:26 <monochrom> The reason why so many programming languages look like each other and copy each others' mistakes and stagnation is precisely because of this "everything must not exceed what programmers already know" mentality.
06:26 <Rotaerk> orion, that or it's just not something WORTH understanding, because they've done fine without it
06:26 <sssilver> that'd be pretty precise but also pretty useless to anyone who's trying to figure out what problem is chair trying to solve
06:26 <orion> Rotaerk: Indeed -- they are just good enough to get a job. They don't find value in going above and beyond the bare minimum.
06:27 defaultnick_ joined
06:27 <sssilver> orion I think a lot of people are actually too humble to question the quality of their tools, so they question their own skill
06:27 `Guest03 joined
06:27 <sssilver> e.g. "my program in C++ is very buggy" ~> "I am not good a enough programmer"
06:27 laz joined
06:27 ragepandemic joined
06:28 <sssilver> and from there it goes to "if you're good enough, language is just a tool"
06:28 takle joined
06:28 <orion> sssilver: How old are you? How old are the programmers you interact with regularly?
06:28 <Rotaerk> lol
06:28 <Rotaerk> "humble"
06:28 <sssilver> orion I'm 32, age of people I interact with varies from 25 to 50
06:28 dbmikus joined
06:29 <sssilver> I know what I say sounds wrong, but I think there's something to it
06:29 <orion> I'm 25. The programmers I interact with are 18-35.
06:29 <Rotaerk> I've met primarily arrogant programmers, and apathetic programmers
06:29 <Rotaerk> can't say I've met many humble ones
06:29 <orion> Rotaerk: Yes!
06:29 <monochrom> No, I don't think they question their own skill. I think they question each other's skill.
06:30 <sssilver> you can be arrogant because deep down you're compensating for the feeling of defeat
06:30 <monochrom> If you can't get "make" to work, you aren't the one questioning your IQ, someone else is.
06:31 <sssilver> monochrom that's a fair point
06:31 <pacak> But Haskell is hard.
06:31 <sssilver> pacak why?
06:31 <sssilver> C++ is fucking hard
06:31 <sssilver> anyone here that shipped any production C++ project and disagrees with me, please raise your hand
06:31 <sssilver> one, Haskell is small. It's a tiny language.
06:32 <Rotaerk> using C++ is hard, learning C++ is time consuming, but it's not that hard to understand conceptually
06:32 <sssilver> two, it doesn't have as many concepts to "understand" as your average multi-paradigm OOP language with bells and whistles
06:32 <sssilver> "so there are fundamental types and user types"
06:32 <sssilver> "and templates"
06:32 <sssilver> "and pointers, and pointer arithmetic"
06:33 <sssilver> "and exceptions and all that good stuff like throwing an exception in a destructor"
06:33 <Rotaerk> using haskell is kind of easy, learning haskell itself isn't that time consuming, but learning the concepts that let you excel in it is hard
06:33 <sssilver> "copy constructors, move semantics"
06:33 <pacak> sssilver: It allows much fancier abstraction compared to (probably not C++, but let's take ruby or javascript) and supports you in all those abstractions.
06:33 <haskull> My first real language (I'm not counting visual basic) was C++. Every couple years it just gets harder. Meanwhile, every other popular language is easy to pick up because of that. Haskell has been the biggest challenge for me since then.
06:33 <SexHendrix> hi guys, i have a feeling im missing a pattern that would make this problem less convoluted
06:33 dbmikus joined
06:34 <SexHendrix> i have a [[Int]]
06:34 <SexHendrix> which is a list of x,y coords effectively
06:34 ystael joined
06:34 <sssilver> the reason Haskell was a bit hard for me is because I approached it with the mindset of "this is gonna be the hardest thing ever", and I kept looking for a black cat in a dark room that wasn't there
06:34 throughnothing joined
06:34 l_zzie joined
06:34 diamat joined
06:34 <SexHendrix> i want to run down the list, doing an operation between each pair of points
06:34 <Rotaerk> SexHendrix, why not [(Int, Int)], then? [[Int]] suggests each element can vary in length
06:35 <SexHendrix> Rotaerk: well yeah but in this problem i don't think it makes a difference
06:35 <Rotaerk> k
06:35 <SexHendrix> im pretty sure what i want is some type of fold
06:36 xall joined
06:36 <SexHendrix> fn :: [[Int]] -> Int
06:36 <sssilver> SexHendrix "an operation between each pair of points"?
06:36 <sssilver> what does between mean here?
06:36 <Rotaerk> for example?
06:36 loupgaroublond joined
06:36 <SexHendrix> ok, well im using coordinate geometry to calculate the area of a polygon given the vertices
06:36 <sssilver> e.g. [(a, b)] an operation would be performed between a and b?
06:37 fiddlerwoaroof joined
06:37 <sssilver> or [(a, b), (x, y)] it would be performed between (a, b) and (x, y), etc?
06:37 <SexHendrix> where A = (x1y2 - y1x2) + (x2y3 - y2x3) + ...
06:37 <pacak> sssilver: A while ago we had a competition with one guy to write a factorial computation. He used java, I used haskell hylomorphism. Haskell version worked way faster so he asked the source code to look at. It was something like 10 short lines - no imported functions, one functor, two algebras and that's about it. It took him 2 weeks to "understand" how this works and to implement the same in java. in 500+ lines.
06:38 <`Guest03> SexHendrix: "an operation between each pair of points" does it mean pairs of adjacent points in the list or all possible pairs of points from list?
06:38 <SexHendrix> adjacent points
06:38 <geppettodivacin> SexHendrix: That can be done with a fold.
06:38 <SexHendrix> from start to end
06:38 <pacak> That was probably the second program I wrote with recursion schemes but ghc and type declarations helped a lot.
06:38 govg joined
06:38 <SexHendrix> nice one
06:39 <geppettodivacin> The accumulator would store the previous value and the current calculated area.
06:39 <Rotaerk> and I think you *should* convert to [(Int, Int)]... simplifies the code
06:39 <SexHendrix> i agree
06:39 shayan_ joined
06:39 <SexHendrix> thanks
06:42 insitu joined
06:42 benl23 joined
06:42 <`Guest03> SexHendrix: you need to fold the expression (zip l (tail l)), where l is initial list
06:43 <`Guest03> (zip l (tail l)) generates list of pairs of adjacent elements in l
06:44 <geppettodivacin> Ooh, I like that better than my solution.
06:44 <SexHendrix> i did it with the very ugly `zip (fmap head l) (fmap last l)`
06:46 insitu_ joined
06:46 jutaro joined
06:46 takle joined
06:47 <`Guest03> SexHendrix: your expression converts [[Int]] to [(Int, Int)]. where do you get [Int]'s as points from?
06:47 raycoll joined
06:47 <`Guest03> if you need to convert them, i would do it with just "map (\[x, y] -> (x, y)) l"
06:48 <Cale> pacak: Of course, it would have been *really* embarrassing for Haskell to somehow lose at a competition for computing factorials ;)
06:48 <SexHendrix> example input comes in the string "0 0\n0 1\n1 1\n1 0"
06:48 <SexHendrix> into stdin
06:49 <SexHendrix> im thinking it through, ill be back if i get stuck
06:50 rperry joined
06:50 Rainb joined
06:51 <SexHendrix> `words <$> lines input` gets it to [[String]] then i just rained read all over it to get the [[Int]] from before
06:51 <`Guest03> SexHendrix: yeah, i'd do like you did and then just convert as i said
06:52 <pacak> Cale: I don't recall what value was it but the idea was to compute them as a tree: ((1 * 2) * (3 * 4) ) * ... rather than 1 * (2 * (3 * 4 * (... to minimize number of expensive multiplications of multi-megabyte Integers
06:52 jle` joined
06:52 jle` joined
06:52 <`Guest03> plus you get program crash on invalid input data for free...
06:52 indi_ joined
06:53 <`Guest03> if a line has less or more than 2 numbers
06:53 <monochrom> It is very easy to lose at a competition for computing factorials. Even with an optimizing compiler. See http://www.luschny.de/math/factorial/FastFactorialFunctions.htm
06:53 ikke joined
06:53 <SexHendrix> `Guest03: im assured it wont ;)
06:53 indi_ joined
06:54 xtreak joined
06:55 <pacak> "is even fast up to 10000!." - I think we were using something like 1000000000000000000....
06:56 takle joined
06:57 defaultnick__ joined
06:57 <monochrom> If you use GHC, you want to multiply two numbers of similar magnitude. You want to multiply two large numbers ASAP, not postpone it by multiplying a large number by a small number.
06:58 jle` joined
06:58 jle` joined
06:58 <monochrom> This is because GHC is going to call GMP for multiplication, and reaching the multiplication of two large numbers earlier means GMP uses the advanced multipliers earlier.
06:58 alexknvl joined
06:59 vlatkoB joined
06:59 jle` joined
06:59 <monochrom> (Ideally you would rather call GMP's factorial function directly, which uses an even more advanced algorithm. But GHC doesn't expose this.)
06:59 tv1 joined
07:01 [swift] joined
07:01 <pacak> Let's assume every number in factorial is the same. If you split a huge list in half and take product of every half you'll get two numbers with N digits each - that would be one expensive multiplication and product will give 2N. Split every of those lists in half - there will be only N/2 digits and so on.
07:01 <SexHendrix> whenever i have to write a load of horrible functions to get from input to the datatype i want, i make a function called `magic` that is just all of them composed
07:02 <pacak> If you multiply them as a tree you'll get one multiplication of size N, 2 of size N/2, 4 of size N/4 and so on
07:02 <SexHendrix> then just `magic input`
07:02 <pacak> It's much cheaper than multiplying big number by small number N times
07:03 <SexHendrix> https://ptpb.pw/DKsV :]
07:03 takle joined
07:04 discrttm joined
07:04 sparr left
07:05 snowalpaca joined
07:05 calincru joined
07:06 snowalpaca joined
07:07 <SexHendrix> input -> useful datastructure is my least favourite part of writing haskell
07:07 <`Guest03> ugh
07:07 <`Guest03> those lines on edges of triangles
07:07 vlatkoB_ joined
07:07 byte512 joined
07:08 tv joined
07:10 meba joined
07:10 takuan joined
07:12 raichoo joined
07:13 takle joined
07:14 hdeshev joined
07:14 hexagoxel joined
07:14 insitu joined
07:16 Swizec joined
07:19 variable joined
07:20 takle joined
07:21 <cocreature> SexHendrix: parsing inputs is always annoying :)
07:21 castlelore joined
07:21 castlelore joined
07:23 xtreak joined
07:23 dbmikus joined
07:23 Sampuka joined
07:26 CGML joined
07:26 Warrigal joined
07:27 takle joined
07:28 Khisanth joined
07:28 dbmikus joined
07:29 xall joined
07:29 quchen joined
07:31 malinoff joined
07:31 twopoint718 joined
07:32 <malinoff> hi everyone, I can't google a way to inject non-code metadata (like build timestamp or Jenkins' BUILD_NUMBER) into a binary built by stack; maybe someone knows some way?
07:32 ali_bush joined
07:32 ali_bush joined
07:32 fizruk joined
07:32 <cocreature> malinoff: you might want to look into how gitrev embeds the git version number https://hackage.haskell.org/package/gitrev
07:33 <malinoff> cocreature: thanks, I'll take a look
07:33 <Cale> malinoff: Template Haskell splices would do.
07:33 xall joined
07:33 <cocreature> yeah that’s what gitrev uses
07:33 <Cale> You can perform IO from inside a splice.
07:34 <malinoff> Cale: awesome, thanks
07:35 ystael joined
07:35 xcmw joined
07:36 <pacak> malinoff: CPP/TH
07:40 certainty joined
07:41 Fairy joined
07:41 jbiesnecker joined
07:43 owiecc joined
07:46 defaultnick__ joined
07:48 defaultnick joined
07:49 fizruk joined
07:49 Xanather joined
07:50 <quchen> Meta question. When I say »data Nat where Zero :: Nat; Succ :: Nat -> Nat«, how would I argue that Succ is already defined here, and not merely a statement of Succ’s type that has a value yet to be given (such as \_ -> 1)?
07:50 darjeeling_ joined
07:50 <quchen> In other words, where does the »uniqueness« of Succ come from?
07:51 <quchen> In a Haskell context this is clear (because well, Haskell works this way). But in type theory there is the same notation without the Haskell Report to fall back to.
07:51 bjz joined
07:51 <`Guest03> i don't quite understand this
07:52 <`Guest03> neither first part nor restatement
07:52 <quchen> If you give a mathematician »succ : ℕ -> ℕ«, then succ could be any function from ℕ to ℕ.
07:53 <quchen> But when we have a functional language (Haskell, Agda), the »succ« in a data definition gives us a unique way to go from one Nat to another.
07:54 <quchen> It’s not any general function from ℕ to ℕ, it’s »the successor function«. I’m wondering where that comes from.
07:54 <`Guest03> the succ gives an unique way because it is unique
07:54 <`Guest03> if you had Succ1, Succ2
07:54 <`Guest03> would no longer be unique
07:54 <quchen> Why is it unique? I can think of many other functions of type ℕ → ℕ.
07:54 malinoff left
07:55 <`Guest03> is your question "why does Succ denote the successor function instead of anything else?"?
07:55 refold joined
07:55 <quchen> Yes, sounds right
07:56 unK_ joined
07:56 baldrick1 joined
07:56 codesoup joined
07:56 <quchen> Is it maybe given not by the data definition alone, but also by the accompanying destructor (i.e. that you can pattern match on it), and the two are mutually inverse?
07:57 <`Guest03> i think we should distinguish the constructor and the function
07:57 <barrucadu> I think the fact that you can pattern match on the Succ is key
07:57 <`Guest03> defining the constructor (the element in the list of constructors) gives rise to a function
07:58 insitu joined
07:58 thc202 joined
07:58 <dmwit_> quchen: you know about lfp def. of inductive types?
07:59 <quchen> LFP?
07:59 <ClaudiusMaximus> makes me think of https://en.wikipedia.org/wiki/Free_group#Examples and https://en.wikipedia.org/wiki/Word_%28group_theory%29
07:59 KarboniteKream joined
07:59 <dmwit> least fixed point
07:59 <quchen> dmwit: No, I don’t
07:59 <dmwit> okay
07:59 <dmwit> take any set
07:59 <`Guest03> the notion "any functions N -> N" is meaningless before we define the set of constructors for N
08:00 <`Guest03> it's a weird question
08:00 <quchen> `Guest03: Oh, good point! Maybe I don’t know what a function is either then ;-)
08:00 <dmwit> choose some fresh symbols, i'll call them zero and succ for absolutelp no reason ;-)
08:00 johnmendonca joined
08:00 <quchen> dmwit: Resemblence to existing natural numbers is purely coincidential
08:01 raichoo joined
08:01 <dmwit> define nat(s) = { zero } U { succ(n) | n \in s }
08:02 connrs joined
08:02 <dmwit> so for any set, we can ex.and the set by one this way
08:02 dan_f joined
08:02 <dmwit> *expand
08:03 <`Guest03> why does 0 denote the number zero?
08:03 <dmwit> now i ask, are there any sets for which nat(s)=s?
08:03 takle joined
08:04 xtreak joined
08:04 <dmwit> turns out there are lots. but a few are special
08:04 <quchen> »ex.«?
08:04 <quchen> Oh.
08:04 <quchen> Nevermind.
08:04 <quchen> I see where this is going, but please carry on :-)
08:04 edsko joined
08:05 <dmwit> in particular there is a smallest such set
08:05 <dmwit> in the sense that it is a subset of any other set that has this property
08:06 <dmwit> that set looks suspiciously like the natural numbers
08:06 <quchen> What are other sets that satisfy nat(s)=s?
08:07 guiben joined
08:08 <dmwit> ones that have elements consistitg of infinitely-deeply-applied succ, e.g.
08:08 khaihuynhminh joined
08:08 <SexHendrix> `Guest03: finished that problem finally
08:08 xall joined
08:08 <SexHendrix> http://lpaste.net/353335
08:08 <SexHendrix> still seems like a right mess
08:08 <dmwit> rather than just infinitely many elemenns, each of which have only finitely deeply applied succs
08:09 <quchen> I see.
08:09 freusque joined
08:09 <`Guest03> omg
08:10 <`Guest03> why do you need [([Int], [Int])] ?
08:10 <dmwit> so one can and sometimes does take this as a def. of the nats
08:10 magneticduck joined
08:10 razzi53 joined
08:10 <SexHendrix> `Guest03: i got bored of constantly transforming the input
08:10 <SexHendrix> and like that it just about worked
08:10 <quchen> dmwit: But now we have another problem: you used »succ« in your definition. Where does that come from?
08:10 <`Guest03> also, "(fmap . fmap) read $ words" looks convoluted. do you understand the meaning of the first fmap?
08:10 Itkovian joined
08:11 <quchen> dmwit: zero I can see being just some arbitrary object. But succ has the same uniqueness problem I mentioned initially it seems.
08:11 <`Guest03> the first fmap is function composition
08:11 <dmwit> quchen: i told you: pick a fresh value
08:11 <quchen> dmwit: succ acts as a sort of tag, right?
08:11 <SexHendrix> i know fmap (fmap function) = fmap . fmap function
08:11 <`Guest03> which composes (fmap read) and words
08:11 Iskarlar joined
08:11 <SexHendrix> i was trying to dig in twice
08:11 <dmwit> quchen: yep, sure
08:11 <quchen> dmwit: I guess I don’t understand what a fresh value is for a function
08:12 <dmwit> quchen: in fact it's not even im.artant that it be fresh, only that it be injective and distinguishable from zero
08:13 qwe123_ joined
08:13 <quchen> It seems like it’s a function without a definition, that is, it has no ways to react on inputs.
08:13 takle joined
08:13 <quchen> (Hence me seeing it as a tagging device)
08:14 <`Guest03> oh well
08:14 soLucien joined
08:14 <`Guest03> i guess my metric of convolutedness was meaningless
08:14 <dmwit> quchen: e.g. succ(x) = (1, x); zero = (0, 0) is a fine choice if you are happy that we can def. 0, 1, and pairing
08:15 <quchen> dmwit: I see. (I’m happy with pairing and having some 0 and 1)
08:15 <`Guest03> aha.
08:15 <`Guest03> you use ([Int], [Int]) for pairs of points...
08:15 <`Guest03> you should use ((Int, Int), (Int, Int))
08:16 <`Guest03> but whatever
08:16 janos joined
08:16 janos joined
08:17 CurryWurst joined
08:17 <dmwit> quchen: but often we don't care to make everything depend on set theory
08:17 <SexHendrix> noted
08:18 defaultnick___ joined
08:18 <dmwit> so we start from the inductive def. and go from there
08:18 <SexHendrix> i did have another magic' function that put it in [(Int, Int)]
08:18 <SexHendrix> but by then i already wanted to pull my eyeballs out
08:18 dbmikus joined
08:18 <dmwit> that is: zero is a nat, and if n is a nat, then succ(n) is a nat
08:19 <quchen> Sure, but that holds even if succ(n) ≡ 0.
08:19 <dmwit> this is simultaneously a def. of nat, succ, and zero
08:20 <dmwit> no, succ isn't just any old function
08:20 <quchen> Ah right, the (n,1) tuple example you gave.
08:20 <dmwit> implicit in my sentenge i guess is that succ is injective and not the identity
08:21 <quchen> dmwit: Hm. I guess »a type« is not simply the type, but the tuple (formation, constructors, elimination), and not merely the »ℕ«. So »the natural numbers« is (ℕ, {0, succ}, recurse) rather than just »the thing made with 0 and succ«
08:21 <dmwit> a similar implicit applies to other inductive def.s of course
08:22 <dmwit> quchen: absolutely agree
08:22 <quchen> so Tuple = (a -> b -> Set, a -> b -> Tuple a b, \f (Tuple a b) -> f a b)
08:22 xall joined
08:23 <quchen> In the tuple case this makes much more sense, since we would never talk about »the tuple« the way we would talk about »the nats«
08:23 cyborg-one joined
08:23 <quchen> So it’s harder to mistake »(,)« for »tuple«, compared to mistaking »0, succ« for »ℕ«
08:24 <`Guest03> i want to make a cool game in haskell.
08:24 <`Guest03> but i don't have ideas.
08:24 connrs joined
08:25 certainty joined
08:25 <SexHendrix> `Guest03: mastermind
08:25 txcyuio_ joined
08:25 <quchen> dmwit: So coming back to my original problem, which is explaining how succ+zero make ℕ to a very smart, but type-unfamiliar mathematician, I guess the postulate is »let zero be something and succ be an *injective* non-identity function from N to N« etc.
08:25 <SexHendrix> this one https://upload.wikimedia.org/wikipedia/commons/2/2d/Mastermind.jpg
08:25 <quchen> dmwit: I’m still not sure how to conclude that this forms exactly the natural numbers, but the injective part brings me a huge step further :-)
08:25 albertid joined
08:26 <dmwit> observe that the nats are a fixed point
08:26 halogenandtoast joined
08:26 <dmwit> then observe they must be a subset of any fixed point
08:28 <dmwit> (up to isomorphism everywhere)
08:28 <dmwit> or: what is your def. of "the nats"?
08:29 defaultnick___ joined
08:29 <osa1> is there a shorthand of `if this prism matches run this monad action otherwise return ()` in lens?
08:29 <ski> implicit in dmwit's sentence is that `nat' is defined in the least restrictive way, in order to support `zero' and `succ'. since `succ(n) = zero' doesn't need to hold if `zero' is an element and `succ' and endo-function, that means it doesn't hold, with `nat' being inductively defined like this
08:29 <ski> quchen : injectiveness follows from this
08:29 <osa1> similar to `case x of C1 (C2 (C3 x y z))) -> f x y z; _ -> return ()`
08:29 <dmwit> osa1: traverse does that
08:29 takle joined
08:29 <dmwit> :t traverse_
08:29 <lambdabot> (Foldable t, Applicative f) => (a -> f b) -> t a -> f ()
08:30 <quchen> ski: »least restrictive« seems rather informal though
08:30 <jle`> osa1: if you have to use a prism then i think `traverseOf_ p` would work
08:31 <osa1> so for the `t a` part I need the lens expression that returns `Maybe (x, y, z)` ?
08:31 defaultnick joined
08:31 <dmwit> :t traverse_ :: Applicative f => (a -> f b) -> Maybe a -> f ()
08:31 <lambdabot> Applicative f => (a -> f b) -> Maybe a -> f ()
08:31 <osa1> OK
08:32 <osa1> thanks dmwit jle`
08:32 <ski> quchen : you can formalize it as the initial object in a specific category
08:32 <jle`> :t traverseOf_ _Just
08:32 <lambdabot> Applicative f => (b -> f r) -> Maybe b -> f ()
08:32 <jle`> :t traverseOf_ hex
08:32 <lambdabot> (Applicative f, Integral a) => (a -> f r) -> String -> f ()
08:33 <dmwit> i'm going to hand off to ski and get some sleep. enjoy
08:34 <quchen> dmwit: Thanks a lot for your explanations!
08:34 <ski> quchen : in this case, the objects of the category are triples `(X,z,s)', with `X' being a set, `z : 1 >---> X' and `s : X >---> X'. and a morphism `m : (X_0,z_0,s_0) >---> (X_1,z_1,s_1)' is a function `m : X_0 >---> X_1' such that `m . z_0 = z_1' and `m . s_0 = s_1 . m'
08:35 <quchen> dmwit: The obvious »constructors are injective« is invaluable for my understanding
08:35 <quchen> Not that I didn’t know that, but I didn’t *know* it ;-)
08:35 <ski> .. if you prefer, you could take `X' as being an object in an arbitrary "base" category `C', and then `m : X_0 >---> X_1' is a morphism in that category `C'
08:35 ystael joined
08:35 takle joined
08:36 <ski> in the former case, the initial object in this new category is `(|N,zero,succ)', the natural numbers. the initiality of this object gives you fold (catamorphism)
08:36 pleax joined
08:36 <quchen> Categories unfortunately make things much less clear for me, usually. :-(
08:36 <ski> in the latter case, you call it "a natural numbers object in `C'"
08:37 aarvar joined
08:37 xmonader joined
08:38 txcyuio joined
08:39 <ski> quchen : anyway, apart from "constructors are injective", you also get "constructors are disjoint", and also that if you build a function `\x -> ..x..', `..x..' being an expression built by using `x' and the constructors, then this function is the identity only if the expression is `x' itself
08:39 connrs joined
08:39 <ski> the latter means there is no `n' with `n = succ(n)', e.g.
08:40 tv joined
08:40 <quchen> I see, so you get a lot of mileage out of that definition then.
08:40 cinimod joined
08:41 janos joined
08:41 <quchen> But leaving away the higher math, one could say that constructors are injective, not the identity, and disjoint.
08:41 takle joined
08:42 <quchen> The »has no fixed point« property is a speciality of the ℕ successor.
08:42 indi_ joined
08:42 <ski> in a more general setting, one'd have both constructors/generators, and given *equations*/relations/laws between them (cf. generating e.g. a group from a set of generators, and a set of "relations" between them)
08:43 twopoint718 joined
08:43 <ski> e.g. one could specify a category where objects are `(X,z,s,p)', with `X' a set, `z : 1 >---> X', `s : X >---> X' and `p : X >---> X', subject to `s . p = id' and `id = p . s'
08:43 _sg joined
08:44 <ski> the initial object here would be the integers
08:44 defaultnick joined
08:44 xtreak joined
08:44 <ski> (so in this case the "constructors" are not disjoint, due to the presence of the laws)
08:45 defaultnick joined
08:45 <quchen> Not disjoint in the sense that 0 is possibly both a »s« and a »p«?
08:46 BartAdv joined
08:46 <ski> yes
08:46 <`Guest03> how to define infinite graphs?
08:46 Mortomes|Work joined
08:47 <jle`> it depends on your graph type
08:47 <`Guest03> uh
08:47 <`Guest03> just graph?
08:47 <`Guest03> undirected
08:47 <ski> quchen : this latter would be an example of an archic algebra (iow having, or being subject to, laws). the former (the peano natural numbers) being an anarchic algebra (no laws)
08:48 variable joined
08:48 <ski> any object of the category in question would be an algebra. the initial object is the "initial algebra", the naturals in one case, the integers in the other
08:48 xall joined
08:49 pleax joined
08:49 <jle`> `Guest03: usually the type will provide some way in its API
08:49 <jle`> i mean, the data type that implements your graphs
08:49 <jle`> or are you talking about it mathematically?
08:49 <quchen> ski: The »initial« gives you what dmwit called the »smallest« then?
08:49 <`Guest03> yes, mathematically
08:49 <ski> yes
08:50 louispan joined
08:50 <jle`> `Guest03: an infinite graph is defined as a graph that is not finite
08:50 <ski> if you want to specify monoids, then objects are `(X,n,m)' with `X' a set, `n : 1 >---> X' and `m : X * X >---> X', subject to `forall y. m(n(),y) = y', `forall x. x = m(x,n())', and `forall x,y,z. m(m(x,y),z) = m(x,m(y,z))'
08:50 raichoo joined
08:50 <`Guest03> how to define graph*s*
08:51 <Cale> `Guest03: Perhaps by an adjacency function?
08:51 <jle`> do you mean how to describe a specific graph?
08:51 <Cale> If you want to be able to define graphs on infinite sets, that might be the way to do it.
08:51 <Cale> It really depends on what operations you need on graphs
08:51 <ski> the initial monoid is here also the natural numbers, with `n() = 0', and `forall x,y. m(x,y) = x + y'
08:52 <Cale> Or wait, you just want a mathematical definition of graphs, not a Haskell one?
08:52 grayjoc joined
08:52 bjz joined
08:53 <ski> to specify "monoids generated from a set `S'", you have objects `(X,n,m,i)', with `(X,n,m)' as above and `i : S >---> X'. `i' acts as an "inclusion" function from your set of generators `S' into `X'
08:53 <Cale> A (simple, undirected) graph consists of a set V of vertices, and a set E of unordered pairs of distinct elements of V, called edges.
08:53 zar joined
08:53 <`Guest03> sorry i don't inderstand your question Cale
08:53 pantsman_ joined
08:53 variable joined
08:53 <`Guest03> but i probably need a haskell definition
08:54 <`Guest03> judging by this name..
08:54 <`Guest03> i need to be able to
08:54 <`Guest03> walk them
08:54 <`Guest03> and store / load info in current vertex
08:54 <ski> the initial object in this case is the type `[S]' of finite lists of inhabitants of `S'. `i' is here the singleton function : `forall s. i(s) = [s]', and obviously `n() = []' and `forall xs,ys. m(xs,ys) = xs ++ ys'
08:54 <Cale> Ah, well, as soon as you want to start writing algorithms, you care a lot more about exactly how the thing is given. Usually I find that something along the lines of Map Vertex (Set Vertex) is a good representation.
08:55 <ski> quchen : does this make any vague sense at all ?
08:55 <Cale> With variations on that to be able to label the vertices and edges.
08:55 path[l] joined
08:55 <Cale> You can independently store a labelling on vertices as a separate Map Vertex Label
08:56 <Cale> Sometimes if you're labelling the edges as well, it's better to use something like Map Vertex (Map Vertex Label)
08:56 JeanCarloMachado joined
08:56 mmn80 joined
08:56 <`Guest03> jle`: yes
08:57 takle joined
08:57 <`Guest03> but not a specific graph
08:57 <`Guest03> just what are some ways
08:57 <Cale> Note that you'll need to be somewhat cautious if your graph is meant to be undirected here -- you can always encode an undirected graph as a directed one where every edge consists of two arcs going in opposite directions
08:57 <Cale> Another way is to encode it via a function which describes whether vertices are adjacent.
08:57 <quchen> ski: Yes, vaguely. :-)
08:58 <quchen> ski: I recognize most words :-þ
08:58 <Cale> i.e. Vertex -> Vertex -> Bool
08:58 <Cale> Or a function which tells you the set of neighbours of a given vertex
08:58 <Cale> Vertex -> Set Vertex
08:58 <quchen> ski: I just have difficulties working with initial objects and terminal ones because I’m not very used to them. But taking initial as smallest works well enough
08:59 <Cale> When I wrote http://hackage.haskell.org/package/astar, I went with that... it looks like Johannes went and changed it to use HashSet instead for some reason, I'm not sure how happy I am about that one :)
09:00 <Cale> http://hackage.haskell.org/package/astar-
09:00 <ski> quchen : anyway, if we go back to the case of "natural number algebras", being objects `(X,z,s)', `X' a set, `z : 1 >---> X', `s : X >---> X', and with the stated requirement on morhphisms to "preserve" this "structure". then an example such object in this category is `(Bool,True,not)'. makes sense ?
09:00 <ski> well, `(Bool,\() -> True,not)' i really should say
09:01 <quchen> ski: Sooo the natural numbers are: 1. the type ℕ formed out of thin air; 2. the two injective, disjoint, non-identity functions Z : ℕ and S : ℕ → ℕ, and the elimination »elim : ∀ C. C -> (ℕ -> C -> C) -> ℕ -> C« with elim z f 0 = z; elim z f (S x) = f x (elim z f x)
09:02 <quchen> Showing the injection from this into the natural numbers as we know it seems easy enough, I wonder how to do the reverse.
09:02 <ski> quchen : the eliminator is given by the initiality
09:03 defaultnick__ joined
09:03 <quchen> ski: That is, »yes, but part of what you said was redundant«?
09:03 <ski> the eliminator is the initial object morphism `elim z f : (ℕ,0,S) >---> (C,z,f)'
09:03 <mbrock> with lenses foo and bar, when I do "let x = foo . bar" that seems to overspecify x's type in a way that prevents me from doing both "x . baz" and "x . qux" when baz and qux have different target types...
09:04 <ski> quchen : .. rather, an alternate way to understand it, in terms of initial algebras
09:04 <mbrock> it's always confusing to me when introducing a let binding for a common expression messes with type inference
09:04 <`Guest03> i don't know whether my question is related to graph's underlying data structure
09:04 atz__ joined
09:05 <`Guest03> or to a "way of defining" for a particlar graph
09:05 <ski> mbrock : DMR ?
09:06 <mbrock> I do actually have the NoMonomorphismRestriction language feature on
09:06 schjetne joined
09:06 <`Guest03> initially it is about latter, but those two layers seem to be interwoven
09:08 bjz joined
09:09 danthemyth joined
09:09 aib joined
09:12 andyhuzhill joined
09:12 <quchen> Does anyone have an example of a non-type-inferrable definition without type classes? I vaguely remember a small example by Richard Eisenberg that looked similar to »f (x:xs) = x : zipWith f xs xs«.
09:12 <quchen> The crux was that polymorphic recursion is a problem.
09:12 certainty joined
09:13 dbmikus joined
09:13 SpinTensor joined
09:14 <ski> quchen : yeah, i was just thinking polymorphic recursion would probably be involved, then i saw you said that :)
09:15 <quchen> It also involved zip(With). :-)
09:15 <quchen> The polymorphic recursion was a ---> [a]
09:15 <quchen> That’s all I remember :-(
09:15 <quchen> And it was a short definition.
09:16 <ski> > let length [] = 0; length (_:xs) = 1 + length (map (:[]) xs) in length "abc" -- how about this one ?
09:16 <lambdabot> error:
09:16 <lambdabot> • Occurs check: cannot construct the infinite type: a ~ [a]
09:16 <lambdabot> Expected type: [[a]] -> t1
09:16 <ski> > let length :: [a] -> Int; length [] = 0; length (_:xs) = 1 + length (map (:[]) xs) in length "abc"
09:16 <lambdabot> 3
09:16 <ski> works with a type signature
09:16 <quchen> Good one!
09:17 Nicnux joined
09:17 takle joined
09:18 xtreak joined
09:18 dbmikus joined
09:19 rcsole joined
09:20 tomphp joined
09:21 jle` joined
09:21 jle` joined
09:22 <Unhammer> Can I put the path to my system ghc in stack.yaml somewhere? (so I can e.g. install both 7.8.4 and 7.10.3 from ppa's instead of compiling for each computer …)
09:23 foldu[m] joined
09:23 M92854[m] joined
09:23 balor joined
09:24 pleax joined
09:24 andrei_chifa joined
09:25 Laney joined
09:25 mrKonny joined
09:25 <SexHendrix> hm, how come the lambdabot in here supports multiline stuff with semicolons but mine doesn't
09:26 petermw joined
09:26 justicefries joined
09:27 <Unhammer> mine = your bot or your ghci?
09:27 tsmish joined
09:27 <SexHendrix> nvm missed the `in`
09:27 systadmin joined
09:28 kungp joined
09:28 killtheliterate joined
09:29 ByronJohnson joined
09:29 beanbagula joined
09:29 Tene joined
09:29 Tene joined
09:31 danvet joined
09:31 Iskarlar joined
09:31 <`Guest03> ski: why can't a compiler infer the type?
09:31 alanz joined
09:31 takle joined
09:32 eacameron joined
09:33 path[l] joined
09:33 defaultnick___ joined
09:34 Aidan[m] joined
09:34 karroffel joined
09:34 sword865 joined
09:34 j201[m] joined
09:34 m4lvin[m] joined
09:34 SolitaryCypher joined
09:34 M-BostonEnginerd joined
09:34 <ski> `Guest03 : the type of the recursive use of `length' isn't the same as the type of the current call to `length'
09:35 xcmw joined
09:35 petermw joined
09:35 fetter_oml joined
09:35 takle_ joined
09:35 M-berdario joined
09:35 infinity0 joined
09:36 Ch3ck joined
09:36 ystael joined
09:40 janos joined
09:40 deepfire joined
09:41 permagreen joined
09:42 Nicnux joined
09:44 jle` joined
09:44 jle` joined
09:44 bjz_ joined
09:44 balor joined
09:45 magnusgbr joined
09:47 xcmw joined
09:47 insitu joined
09:48 defaultnick__ joined
09:49 ynyounuo joined
09:49 GK___1wm____SU joined
09:51 tv1 joined
09:53 exferenceBot joined
09:53 snowalpaca joined
09:53 coot joined
09:53 zv joined
09:53 janos joined
09:54 twopoint718 joined
09:54 jaspervdj joined
09:55 Tourist joined
09:55 Tourist joined
09:55 GK___1wm____SU joined
09:55 janos__ joined
09:55 oish joined
09:56 Sigyn joined
09:56 GK___1wm____SU joined
09:57 pleax joined
09:59 wlemuel joined
09:59 danza joined
09:59 GK___1wm____SU joined
10:00 janos joined
10:00 Denth joined
10:01 GK___1wm____SU joined
10:01 hazmat__ joined
10:01 phaji_ joined
10:02 GK___1wm____SU joined
10:02 xcmw joined
10:06 GK___1wm____SU joined
10:08 indi_ joined
10:08 certainty joined
10:08 sid_fules joined
10:08 dbmikus joined
10:09 jmorris joined
10:09 defaultnick___ joined
10:11 yezariaely joined
10:11 marfoldi joined
10:13 marr joined
10:14 jle` joined
10:14 jle` joined
10:14 ub joined
10:14 ramzifu joined
10:18 takle joined
10:19 FreeBirdLjj joined
10:22 xtreak joined
10:23 rixile joined
10:23 cloudhead joined
10:24 defaultnick_ joined
10:25 gabe4k joined
10:25 zero_byte joined
10:27 fotonzade joined
10:27 systadmin joined
10:28 hazmat_ joined
10:28 merijn joined
10:28 Gurkenglas_ joined
10:30 aib joined
10:31 grayjoc joined
10:32 louispan joined
10:33 defaultnick_ joined
10:33 bernouli joined
10:33 tommd joined
10:35 takle joined
10:36 danza joined
10:37 sidei_ joined
10:37 ystael joined
10:38 oisdk joined
10:44 jbiesnecker joined
10:46 infinity0 joined
10:47 FullyFunctional joined
10:48 dhil joined
10:48 lep-delete joined
10:50 augur joined
10:51 defaultnick joined
10:53 tv joined
10:53 infinity0 joined
10:53 sidei joined
10:54 silver joined
10:55 _sg joined
10:55 AndreasK joined
10:56 insitu joined
10:57 Tourist joined
10:57 Tourist joined
10:58 lukaramu joined
11:00 defaultnick_ joined
11:00 augur_ joined
11:03 defaultnick joined
11:03 coot joined
11:03 dbmikus joined
11:05 twopoint718 joined
11:06 skapazzo joined
11:06 owiecc joined
11:07 owiecc joined
11:07 shayan__ joined
11:08 dbmikus joined
11:08 cschneid_ joined
11:09 <nshepperd_> Huh. I suppose translating polymorphic recursion to an application of fix doesn't work there, because it would be impredicative?
11:10 <nshepperd_> Like you need a specialised rank 2 fix
11:10 coot joined
11:10 danthemyth joined
11:10 janos joined
11:10 michael1 joined
11:11 fendor joined
11:11 meba joined
11:13 Rainb joined
11:16 Sampuka joined
11:17 otto_s joined
11:19 Iskarlar joined
11:20 calincru joined
11:20 gmhafiz joined
11:23 janos joined
11:24 kmelva joined
11:24 halogenandtoast joined
11:27 kuribas joined
11:31 albel727 joined
11:32 calincru joined
11:32 Aruro joined
11:32 Icewing joined
11:33 ejay joined
11:35 JeanCarloMachado joined
11:36 defaultnick_ joined
11:37 jutaro joined
11:38 ystael joined
11:38 xcmw joined
11:41 jshjsh joined
11:44 mojjo joined
11:45 janos joined
11:46 tfc joined
11:48 eacameron joined
11:49 jaziz joined
11:49 louispan joined
11:49 FullyFunctional left
11:50 mr_sm1th joined
11:51 defaultnick joined
11:53 fbergmann joined
11:54 systadmin joined
11:55 mda1 joined
11:58 sh0rug0ru joined
11:58 dbmikus joined
11:58 rgr joined
12:02 janos joined
12:02 Snircle joined
12:02 janos joined
12:03 defaultnick joined
12:03 dbmikus joined
12:04 schjetne joined
12:05 Prathamb joined
12:06 Prathamb left
12:07 certainty joined
12:09 freusque joined
12:10 Denthir joined
12:10 bjz joined
12:12 deepfire joined
12:16 twopoint718 joined
12:16 muzzle joined
12:17 <muzzle> is it possible to use the GHC-tokenizer as a library?
12:17 <muzzle> I want to tokenize haskell code at runtime in my program
12:17 <muzzle> and I would really like to use a given haskell tokenizer
12:17 systadmin joined
12:17 <muzzle> and possibly other parsing steps
12:18 chrissl joined
12:18 pavonia joined
12:19 hexagoxel joined
12:19 dunx joined
12:21 CurryWurst joined
12:21 <lyxia> muzzle: https://downloads.haskell.org/~ghc/latest/docs/html/libraries/ghc-8.0.1/Lexer.html ?
12:23 k0001_ joined
12:24 jbiesnecker joined
12:24 <tfc> hey there, i am currently implementing a parseJson function using aeson library to parse from json to my own types. i have type "Foo A String String", and my parser looks like parseJson (Object o) = Foo <$> o .: "key1" <*> o .: "key2", which works great. Now i switched from Foo String String to Foo A String. For type A, i have a Parsec parser function of type Parser A. but i can't fiddle out how to combine THAT now. can anyone help me
12:24 <tfc> ?
12:24 <tfc> sorry first type was "Foo String String", then the upgrade is "Foo A String"
12:26 <Rembane> tfc: What's the type signature of your parser?
12:26 lep_ joined
12:26 lep_ left
12:26 <tfc> parse_func :: Parser A
12:26 <muzzle> lyxia thx, I failed at google...
12:26 oisdk joined
12:26 xcmw joined
12:26 congnotronicist joined
12:27 <tfc> Rembane i can already write "parse parse_func "" "some input string which can be parsed to an A instance"
12:27 novakboskov joined
12:27 <tfc> in my json the object at "key1" is a string which i need to parse into an A
12:27 MitchW joined
12:28 <Rembane> tfc: What happens if you replace this `o .: "key1"` with: `(o .: "key1" >>= parse_func)`
12:28 <tfc> one moment
12:29 taktoa joined
12:29 <tfc> couldnt match "Text.Parsec.Prin.ParsecT String () Data.Functor.Identity.Identity A" with "a0 -> Parser a"
12:29 tomphp joined
12:30 soLucien joined
12:30 lep_ joined
12:30 <tfc> so aeson wants a "a -> Parser A" and i only have "Parser A" (but a parsec parser)
12:30 <novakboskov> Somewhere I've read a good point which been said like "Haskell basically have two languages, one _____ which is before :: sing and type language which is after :: sign...". Is there name for that first language, that one which remains when type language is separated?
12:31 andrei_chifa joined
12:31 <hpc> the right word for what you're thinking of is "levels"
12:31 <hpc> the type level and the value level
12:31 <hpc> above the type level is the kind level
12:33 <hpc> the TypeInType language extension makes it so kinds are the top level
12:33 <hpc> values :: types, types :: kinds
12:33 <hpc> and with TypeInType, * :: *
12:34 <hpc> otherwise there is a simple "sort" system above kinds that never shows up in code
12:34 lieven joined
12:34 sdothum joined
12:35 fendor joined
12:35 Fairy joined
12:35 jedws joined
12:36 <tfc> Rembane maybe you have an idea how i can use "String -> Either ErrStr A" in aeson to get an A or fail?
12:37 <Rembane> tfc: Supply a string to that function and pattern match on the result?
12:38 <tfc> yes but if i do a "case foo of Left _ -> fail "blabla" Right aInstance -> return aInstance" it's still a type error
12:38 <Rembane> tfc: What types does it want?
12:38 Xanather joined
12:38 MitchW joined
12:38 ystael joined
12:39 IndigoTiger_ joined
12:39 <tfc> Rembane sheesh... i somehow got it working now. not sure what i made different from before. let me test it... will report back
12:40 <Rembane> tfc: More brackets? :D
12:40 <Rembane> tfc: Good luck!
12:40 ij left
12:41 <tfc> ok, it actually works... so i have Foo <$> o .: "key1" <*> o .: "key2" again, and then instance FromJSON A where parseJson (String s) = case parse aParser "" (unpack s) of Left _ -> fail "blabla" Right m -> return m
12:41 <tfc> and that does the job. although it looks pretty clunky to me with the unpack etc.
12:42 sdothum joined
12:42 <Rembane> It is indeed, it's the curse of having a gazillion string types.
12:42 cyborg-one joined
12:43 mohsen_ joined
12:43 Fairy joined
12:43 <tfc> Rembane: too bad. all the string types are really a curse. it's all in all less a curse than programming in other languages.
12:44 janos joined
12:44 ramzifu joined
12:44 skeuomorf joined
12:45 <tfc> Rembane: thx for your help!
12:45 <Rembane> tfc: Indeed.
12:45 <Rembane> tfc: No worries! :D
12:45 janos joined
12:45 twoninefive joined
12:45 <tfc> Rembane alone for the parsing i love haskell. :D
12:46 <Rembane> tfc: It's really nice! So powerful, so succinct.
12:46 freusque joined
12:46 bennofs joined
12:47 nilof joined
12:49 tommd joined
12:49 balor joined
12:50 janos joined
12:51 schjetne joined
12:51 janos joined
12:51 owiecc joined
12:53 certainty joined
12:53 dbmikus joined
12:53 lelf joined
12:54 <Wizek> if I'd like to specify a local package as a dependency for a cabalized project, in theory all I need to do is `cabal sandbox add-source /local/path/to/package/`, right?
12:54 MitchW joined
12:54 Iskarlar joined
12:56 <erisco> "string" is vague and that is why you see various implementations of it
12:56 lep_ left
12:56 pleax joined
12:58 <dminuoso> erisco: Mind my asking since I was curious about this, what is vague about it?
12:59 <erisco> tell me what it is
13:00 janos joined
13:00 defaultnick_ joined
13:00 maybefbi joined
13:03 fizruk joined
13:05 <maybefbi> will anyone share their haskell development salary with me? you can /msg me if you dont want it to be public
13:06 <erisco> mine is $0
13:06 <maybefbi> mine too
13:06 xall joined
13:06 jbiesnecker joined
13:07 <erisco> I am looking for fix succ dollars
13:08 <robertkennedy> I work in data analytics and use Haskell to get my work done, bit I'm not a dev. Making 60k in Boise Idaho USA
13:09 defaultnick_ joined
13:09 <nilof> Out of curiosity, is it common practice to not include the prelude and use a different standard library?
13:10 lep_ joined
13:10 <dminuoso> erisco: I would say it's just a list
13:11 <erisco> I don't think so, but it can be selectively imported when it is in the way, such as if you want (.) from Control.Category instead
13:11 MitchW joined
13:11 lep_ left
13:11 owiecc joined
13:11 <erisco> dminuoso, a list of characters? what is a character? and then does Text and ByteString not qualify because they are not lists?
13:12 steshaw joined
13:12 _sg joined
13:12 bennofs joined
13:12 danthemyth joined
13:13 danthemyth joined
13:13 ps-auxw joined
13:15 bjz joined
13:15 travula joined
13:16 ystael joined
13:17 fendor joined
13:18 vi0 joined
13:19 eklavya joined
13:19 merijn joined
13:20 xcmw joined
13:23 dhil joined
13:24 defaultnick_ joined
13:26 fendor joined
13:27 justanotheruser joined
13:28 twopoint718 joined
13:28 cheater joined
13:32 baldrick joined
13:33 chlong_ joined
13:33 lukaramu_ joined
13:35 grayjoc joined
13:35 asthasr joined
13:35 asmyers joined
13:36 <novakboskov> Is there any counterpart of fields reuse (through class inheritance in OOP) here in haskell?
13:37 <liste> novakboskov: https://github.com/adamgundry/ghc-proposals/blob/overloaded-record-fields/proposals/0000-overloaded-record-fields.rst
13:37 systadmin joined
13:38 <liste> novakboskov: also https://downloads.haskell.org/~ghc/master/users-guide/glasgow_exts.html#duplicate-record-fields
13:38 deepfire joined
13:39 systadmin joined
13:40 <Cale> novakboskov: Ignoring the language extensions (which are somewhat questionable, imo), usually we just factor things to pull out common substructures into their own type.
13:41 mada joined
13:41 <Cale> novakboskov: If you have a bunch of types which are related by having similar fields, it's quite probable that you really want a type for the fields that they have in common instead.
13:42 dsh joined
13:42 <novakboskov> liste: Thanks for directions.
13:43 <novakboskov> Cale: It makes sense too ... :D
13:43 bob3434 joined
13:44 <Cale> If you know about lenses, it's also possible to define a type class which defines one or more lenses for accessing common fields, and there's some template haskell machinery for doing that included with the lens package if you want to go that way.
13:45 MitchW joined
13:45 insitu joined
13:45 <Cale> I've not often found it necessary to go quite that far
13:45 defaultnick__ joined
13:46 <Cale> But some kind of type class might be in order -- you might not just have it give you a lens, but instead, operations that are more specific to your application.
13:47 MoronMan joined
13:48 coltfred joined
13:48 takle joined
13:49 jutaro joined
13:51 owiecc joined
13:54 FullyFunctional joined
13:54 jomg joined
13:56 jcdietrich joined
13:56 jcdietrich joined
13:57 HoierM joined
13:58 cpennington joined
13:59 jutaro1 joined
14:00 defaultnick_ joined
14:01 janos__ joined
14:02 ramzifu joined
14:02 bob3434 joined
14:03 doodlehaus joined
14:03 eacameron joined
14:03 yqt joined
14:03 sidei joined
14:03 surelyourejoking joined
14:03 Berra joined
14:04 shafox joined
14:06 fendor joined
14:08 balor joined
14:10 c_wraith joined
14:12 defaultnick_ joined
14:13 bodisiw joined
14:15 AndreasK joined
14:15 freechips joined
14:15 defaultnick_ joined
14:15 cpennington joined
14:16 yyyyy joined
14:16 sidei_ joined
14:18 asmyers joined
14:18 cheater joined
14:20 arun_t joined
14:20 Gloomy joined
14:20 <Athas> What's the simplest way to do a parallel map?
14:20 <Athas> (Over a list.)
14:21 aarvar joined
14:21 aarvar left
14:21 <c_wraith> parallel or concurrent?
14:21 <Athas> Parallel. Pure code.
14:22 <c_wraith> list isn't a great structure for that, but sometimes it works
14:22 <Athas> Something from Control.Parallel.Strategies, maybe...
14:22 <arun_t> please let me know how haskell embrace immutability?
14:22 <c_wraith> yeah, it has combinators for lists
14:22 <Athas> These lists will typically be quite short, so it should be OK.
14:22 robkennedy joined
14:23 <c_wraith> there's parList and parListChunk
14:23 <quchen> arun_t: All variables are constant.
14:23 <c_wraith> or parMap
14:23 <c_wraith> err, *and* parMap
14:23 <arun_t> quchen: what about data structures?
14:23 schjetne joined
14:23 freechips joined
14:24 <quchen> Variables whose values are data structures are just as constant.
14:24 <quchen> You can do things that do mutable updates in memory if that’s what you’re getting at. But it’s rarely necessary.
14:24 <Athas> c_wraith: so 'evalList rpar' would be a good strategy to apply to my list?
14:24 <arun_t> so mutation is not even possible
14:25 <Athas> Or... 'parList rseq'? What's the difference?
14:25 <quchen> The compiler mutates lots of things, but that’s not visible on in the code :-)
14:25 <quchen> s/on//
14:25 <tabaqui1> can I combine function in one infix function?
14:25 <tabaqui1> alike
14:25 <c_wraith> Athas: maybe just parMap rseq
14:26 <tabaqui1> a `pure (&&)` b
14:26 <Athas> c_wraith: yes, that looks the simplest.
14:26 <c_wraith> Athas: there are a lot of equivalent options. It's just a matter of what conceptual building blocks you want to use. :)
14:26 <bodisiw> quchen, are those impure operations, or ffi kinda things?
14:27 <tabaqui1> *a <*> `pure (&&)` <*> b
14:27 <tabaqui1> argh
14:27 <tabaqui1> dunno
14:27 <tabaqui1> wrong too
14:27 <arun_t> quchen : what do you mean by this line variables whose values are data structures are just as constant Please explain?
14:27 <tabaqui1> nevermind
14:27 <Athas> c_wraith: yes, I see. Are these things frequently used in practice?
14:28 <quchen> arun_t: x = [1,2,3] -- A list is a data structure, and x is immutable.
14:28 <ongy> c_wraith: what's better suited for parallel evaluation than lists?
14:28 <quchen> We can’t change the 1 there. We can make a new list that has a different first element though.
14:28 <Wizek> Has anyone of you encountered an error like this before? /usr/bin/ar: .stack-work/dist/x86_64-linux/Cabal- No such file or directory
14:28 baldrick1 joined
14:28 <merijn> ongy: arrays and vectors :p
14:28 sidei joined
14:28 <quchen> bodisiw: The compiler can mutate whatever it wants, as long as this preserves the semantics of Haskell :-)
14:29 <quchen> bodisiw: Most importantly, when you evaluate a thunk, its result is often written over the memory location of the former thunk
14:29 rekahsoft joined
14:29 pleax joined
14:29 certainty joined
14:29 <bodisiw> right, i meant if you explicitly want to peek/poke (or whatever), that would have to be through IO monad?
14:29 <quchen> That’s a real mutable update in your RAM (or cache or whatever)
14:29 <merijn> bodisiw: There is a crucial distinction between "what the compiler/compiled code *does*" and "what we can observe it to do" :)
14:29 <bodisiw> i might be way off base... i am still real new
14:29 <c_wraith> Athas: occasionally, but the wins often are small, so they're usually very limited in scope
14:29 <arun_t> quchen: so how we can solve problems in haskell which needs mutable states in program
14:30 <merijn> arun_t: Haskell supports mutable state in a bunch of different ways
14:30 mmn80 joined
14:30 <quchen> arun_t: Many problems don’t need mutable state :-) And for when you *really* need mutable state, you can go back to using IO or ST.
14:30 <Athas> c_wraith: do you know of any "production" Haskell programs (or libraries) that do?
14:30 funkshun joined
14:30 <quchen> Preferrable ST.
14:30 mda1 joined
14:30 <merijn> arun_t: IO based operations, STM, the ST monad, etc.
14:30 <c_wraith> ongy: lists are a completely serial data structure - evaluating them in parallel only makes sense if most of the calculation goes into figuring out the element at each location, and there aren't dependencies between the elements.
14:30 <Athas> I had trouble finding real users of things like Repa or Accelerate, but this looks more accessible, maybe.
14:31 revtintin joined
14:31 defaultnick joined
14:31 augur joined
14:31 ystael joined
14:31 <merijn> Yeah, accelerate is like most high-level GPU tools in that people who want GPU performance don't use it
14:31 jmcarthur joined
14:32 <c_wraith> Athas: monad-par might be used more - it's a bit simpler conceptually than Strategies, though it requires bigger code changes to use
14:32 <merijn> And people who don't need GPU performance don't have a use for using accelerate that much :p
14:32 meba joined
14:32 <arun_t> merijn: why i need IO based operation to handle the mutable state in simple program, & i don't anything about monads?
14:32 <Athas> merijn: not a lot of HPC people using Haskell; agreed!
14:32 <merijn> I would've loved using Haskell bindings for CUDA, but the existing ones aren't what I'd like
14:33 sid_fules joined
14:33 <Athas> What would you like?
14:33 <arun_t> merijn: quchen: I'm confuse about choosing b/w a lisp or haskell? to learn
14:33 hazmat_ joined
14:33 <merijn> Athas: Higher level control flow descriptions and data marshalling
14:34 <Athas> arun_t: pick Haskell. I used to be a (Common) Lisp programmer for many years. It's a great language. I switched to Haskell because Lisp is at the top of its power curve. You can't really add anything without first taking something away. On the other hand, Haskell still grows.
14:34 <merijn> arun_t: I'd say pick Haskell, because it's more different. I daresay that looking at lisp after haskell will be very easy
14:34 <c_wraith> ongy: most lists in Haskell end up being either super-simple so that the overhead of parallel evaluation isn't worth it, or there are evaluation dependencies between consecutive elements so they can't usefully be evaluated in parallel
14:34 <Athas> merijn: do you get that in C++ CUDA?
14:34 <merijn> arun_t: So if you've skipped list you're not losing much
14:34 <merijn> Athas: No, but then I don't have to worry about bindings and potential overhead in the FFI fucking up my benchmarks
14:34 <quchen> arun_t: Haskell is the better functional language (with its focus on purity, encapsulating effects, equational reasoning). Lisp’s strength is its macro system and that code and data share the same domain, allowing pretty interesting solutions to problems.
14:35 <bodisiw> hopefully this is an easy beginner question... i've got an Either String DynamicImage in ghci... what's needed in between to pass it to a (DynamicImage -> Image PixelRGBA8) ?
14:35 <merijn> arun_t: IO prevents the mutability leaking into other operations. As for the monad part, it's not really relevant here, since IO would work the same if monads had never been discovered :)
14:35 <merijn> bodisiw: You probably want fmap?
14:36 cereal_killer_ joined
14:36 <bodisiw> ahh, thanks
14:36 <merijn> bodisiw: What do you expect to happen if you get a String instead of an image? That's presumably an error
14:37 Denthir joined
14:37 <bodisiw> merijn, i believe that's correct... since i'm working on ghci, i'd like to ignore it. but really i'm just trying to understand... in a program, i _must_ handle both sides
14:37 <ongy> c_wraith: I don't see how the datatype would influence most of that. Provided the spine of the list is easy to compute and the content is the complex stuff
14:37 <bodisiw> to satisfy the semantics? like, that's the whole point of it being defined that way?
14:38 <merijn> bodisiw: Yes
14:38 <sshine> I've got a datatype Foo = Alice | Bob, and I'd like for Show Foo to only show the first letter, so deriving Show does too much. is there any neat way to derive a Show that's based off the default derive?
14:38 <Cale> sshine: I wouldn't use show for that...
14:38 <merijn> bodisiw: But you can just pattern match "case myResult of Left _ -> putStrLn "Error!"; Right img -> processImage img"
14:38 <merijn> bodisiw: I mean, 'fmap' is basically doing the same
14:39 <sshine> Cale, I have actually got a little PP type class for it, but can I still derive?
14:39 <Cale> sshine: It's usually most convenient for show to produce valid source code for reconstructing values, whenever possible
14:39 <sshine> Cale, right!
14:39 twopoint718 joined
14:39 <sshine> Cale, it's just that while I'm testing, I'm chaining my PP to Show :)
14:39 <arun_t> quchen: what is equational reasoning in haskell? merijn: can you explain more about IO use case and monad use case for mutable state?
14:39 <bodisiw> nice -- i think i need to understand the sugar and unsugar way... finding it kind of tough to learn both at once
14:39 mizu_no_oto_work joined
14:39 <Cale> Well, you can derive show, and then write your pretty printing function to use the first letter that show gave.
14:39 <sshine> hmm, I'll stick with that.
14:40 <merijn> bodisiw: What do you mean by sugar? fmap isn't sugar, it's just a function
14:40 <bodisiw> 'case...of' ?
14:40 sidei_ joined
14:40 <c_wraith> ongy: well, compare that to a binary tree. Even if the children are hard to compute and the elements are easy, it parallelizes easily. It's just far more difficult to get data dependencies that mess up parallel evaluation. (spark floods are a different and more likely issue, though, which require some care in a different way)
14:40 <merijn> bodisiw: case of is just pattern matching, it's the exact opposite of syntactic sugar :)
14:41 <bodisiw> dang! one day i will get this all straight :-)
14:41 <merijn> bodisiw: Like, if there's anything in Haskell that is not sugar, but direct mechanical behaviour it's case-of :p
14:41 <c_wraith> in Haskell, if/then/else is syntactic suger. :)
14:41 <merijn> bodisiw: You're familiar with pattern matching while writing functions, right?
14:42 <merijn> bodisiw: The compiler just translates those into case-of expressions
14:42 <bodisiw> i've read about guards and such, but cant write them intuitively yet
14:42 <Cale> Yeah, one can imagine that at some level, the only reason that anything is ever evaluated is because it is the scrutinee of a case expression which needs to know which constructor matches.
14:43 <Cale> (and everything else that does pattern matching or causes evaluation is syntax sugar for case expressions)
14:44 <bodisiw> i love this aspect of haskell
14:44 <bodisiw> though obviously still struggling with it
14:44 <Cale> There is in reality at least one exception to that, because when you have something like seq f y where f is of function type, then you can't cause the function to similarly be evaluated using case
14:45 <Athas> A lot of people were upset in the 90s because of that!
14:45 <Cale> (seq is primitive and ensures that its first argument is evaluated before resulting in its second argument)
14:45 eacameron joined
14:45 <bodisiw> Athas, i admit i usually code for the 'happy path'... because i am lazy
14:45 <Cale> Yeah, it screws up the denotational semantics a bunch
14:46 <bodisiw> but haskell and i can't both be lazy ;-)
14:46 cheater joined
14:46 halogenandtoast joined
14:46 <Athas> bodisiw: well, that's fine. I think good language (and program) design requires compromises for practical reasons.
14:46 <Athas> Haskell only compromises in a very few places. Look at OCaml for a language that perhaps compromises a bit too much.
14:48 Fairy joined
14:48 <quchen> arun_t: Equational reasoning is what you do in math a lot: insert definitions to simplify things. For example, if you know that f(x)=2*x, then f(4) can be shown to be equal to 2*4. It’s a trivial example, but equational reasoning goes a *long* way. For example, »map id list = list« allows you to drop a loop from your program.
14:48 <quchen> Equational reasoning allows us to do pretty complex program transformation in our heads, and the compiler catches most errors humans make :-)
14:49 dan_f joined
14:49 <quchen> Aaaand he’s gone
14:49 ClaudiusMaximus joined
14:49 sid_fules joined
14:49 tommd joined
14:51 defaultnick joined
14:55 eklavya joined
14:55 ramzifu joined
14:55 govg joined
14:55 ChristopherBurg joined
14:56 xcmw joined
14:56 fotonzade joined
14:58 snowalpaca joined
14:58 mjo_ joined
14:58 phaji joined
14:59 bernouli joined
14:59 jbiesnecker joined
15:01 <dredozubov> does -O2 work for libraries nowadays?
15:01 sternmull joined
15:01 <dredozubov> I always thought it doesn't, but i saw some conflicting opinions on the internet. :)
15:02 freechips joined
15:02 <Cale> dredozubov: I'm unaware of any point in time at which it didn't.
15:03 hazmat_ joined
15:03 <shapr> Is there a collection of documents about structuring libraries/programs?
15:03 <c_wraith> cabal/hackage warn against -O2, but it's always worked.
15:04 <c_wraith> They just are suggesting that for most libraries, -O2 doesn't help much but significantly increases install time
15:04 <c_wraith> Of course, the cases where it does help the most are the same ones it increases install time the most...
15:05 <c_wraith> *cough* vector-algorithms *cough*
15:05 asmyers joined
15:05 owiecc joined
15:06 defaultnick__ joined
15:06 <dredozubov> basically i have a multi-package repo that i usually build with stack/nix
15:06 MitchW joined
15:07 <dredozubov> nix have an override to build with -O2 for production builds
15:07 <dredozubov> but i'm wondering if i should set it in ghc-options in .cabal files
15:07 <bennofs> dredozubov: i don't think you should set it in .cabal files
15:08 infinity0 joined
15:08 athan joined
15:08 <dredozubov> any explicit pro/cons?
15:09 <dredozubov> defaulting .cabal to -O0 sounds reasonable for all kinds of development feedback loops
15:09 <bennofs> dredozubov: it's might be hard to override if it's set in ghc-options
15:09 `^_^v joined
15:10 drostie joined
15:10 Itkovian joined
15:10 <dredozubov> how is that different from omitting it? It defaults to -O afaik.
15:10 <merijn> dredozubov: You can do even better for development feedback loops
15:11 <merijn> You can incidentally locally override what cabal does
15:11 <merijn> If you change your .cabal/config you can have it build everything with -O2
15:12 conal joined
15:13 osa1 joined
15:13 <dredozubov> that doesn't sounds particularly good for development :)
15:13 janos__ joined
15:14 pfurla joined
15:14 <merijn> dredozubov: No, the one that speeds up development is '-fno-code'
15:14 <merijn> That just does typechecking, no code generation
15:14 <merijn> It's superfast combined with -O0
15:14 al-damiri joined
15:15 janos__ joined
15:15 <dredozubov> i need to try that
15:15 <dredozubov> i'm not super happy with intero
15:15 <dredozubov> so i'm looking for a way to make typecheck-report faster in some other way
15:16 <merijn> dredozubov: I have ghc-mod setup to always use '-O0 -fno-code' for that reason
15:16 takle joined
15:16 <dredozubov> launching stack on every check is not really fast
15:16 <dredozubov> i was wondering if i should hook flycheck to 'stack build --file-watch'
15:16 <dredozubov> but it requires writing some cringe-worthy elisp
15:16 simukis__ joined
15:17 <dredozubov> merijn: good tip!
15:18 defaultnick_ joined
15:19 cosmodanger joined
15:19 jao joined
15:20 <ertes> dredozubov: why do you even compile? i just use GHCi during development (or rather my emacs + haskell-interactive-mode does)
15:20 rixile joined
15:21 mjo joined
15:21 rixile joined
15:21 rixile left
15:22 <dredozubov> haskell-interactive-mode doesn't work with multi-package repos
15:22 <dredozubov> so it's out of the question for me
15:22 <ertes> dredozubov: "work"?
15:22 <dredozubov> intero doesn't seem too stable with my setup either
15:22 <ertes> dredozubov: or rather: what is a "multi-package repo"?
15:23 <dredozubov> and i use compilation-mode to find the next error that usually occurs in some arbitrary module
15:23 infinity0 joined
15:23 <dredozubov> ertes: a lot of cabal-packages depending on each other
15:23 <ertes> h-i-m does the same without compilation… it even reuses next-error
15:24 <dredozubov> > "work"?
15:24 <dredozubov> it's a work project if that's what you're asking
15:24 <ertes> dredozubov: that's a weird thing to say, considering that i do have those locally
15:24 <ertes> but i don't know much about stack… in my setup nix handles those dependencies quite transparently
15:25 hazmat_ joined
15:25 danharaj joined
15:25 MitchW joined
15:28 <dredozubov> i have ~20 packages in one repo
15:28 <dredozubov> i remember doing cabal yadda-yadda add-source
15:28 <dredozubov> and it felt like pure madness
15:28 <dredozubov> so i switched to stack and never looked back
15:29 tommd joined
15:30 <ertes> dredozubov: the workflow is: C-c C-l, then h-i-m will first check whether the cabal file has changed and restart my nix-ghci wrapper script if necessary (it just wraps GHCi in nix-shell), then reloads the module… after that i use next-error to cycle errors
15:30 takle_ joined
15:30 JagaJaga joined
15:30 ludat joined
15:30 certainty joined
15:30 <ertes> dredozubov: i don't have any of that… i just have a nix expression that specifies my local packages globally
15:31 <ertes> it's in ~/.nixpkgs/config.nix
15:31 cads joined
15:31 raycoll joined
15:31 <dredozubov> can you share a gist of it?
15:31 <dredozubov> i'm interested how that works
15:31 netheranthem joined
15:32 augur joined
15:32 mthek joined
15:33 mattyw joined
15:34 NeverDie joined
15:35 <ertes> dredozubov: here is the config.nix: https://github.com/esoeylemez/config/blob/master/files/.nixpkgs/config.nix
15:36 MitchW joined
15:36 <ertes> this one specifies local overrides for packages… in your case you would have to do without asGit, because it assumes that each git repo is a package
15:36 Rizy joined
15:36 defaultnick_ joined
15:36 augur_ joined
15:37 <ertes> this is my wrapper script (h-i-m fires up this one instead of "ghci"): https://github.com/esoeylemez/config/blob/master/bin/nix-ghci
15:37 oisdk_ joined
15:37 <dredozubov> i have to run now, but i'll definitely look at it later, thanks!
15:37 <ertes> hopefully h-i-m will get first-class support for nix some day, so it will no longer be needed
15:38 MoALTz joined
15:40 takle joined
15:40 danza joined
15:40 janos__ joined
15:41 someone_ joined
15:41 Snircle joined
15:41 cads joined
15:42 bodisiw joined
15:43 cyborg-one joined
15:44 dbmikus joined
15:46 Faucelme joined
15:47 wraithm joined
15:48 unK_ joined
15:50 Luke joined
15:50 jmcarthur joined
15:51 kubunto joined
15:54 <kubunto> i am trying to fix my code that is supposed to replace a char in a string
15:54 <kubunto> http://lpaste.net/353344
15:54 <kubunto> not sure why it isnt working
15:54 <merijn> kubunto: What does "ghc -> nothing" mean?
15:54 <kubunto> expected output is what i see in the ghci readout
15:54 <kubunto> merijn: litterally gives no string
15:55 <merijn> kubunto: What does the file you give to ghc look like?
15:55 <c_wraith> kubunto, that foldr is just concat
15:56 <kubunto> c_wraith: it is a string replacement function
15:56 cloudhead joined
15:56 <c_wraith> kubunto, the fmap is supposed to be. the foldr is just a concat
15:56 <kubunto> ok, function was not invoked
15:57 <ocharles> Ok, I am having a serious wtf experience with GHC atm - can any one shed any light on this? https://gist.github.com/ocharles/c028fa7c3f7c8242904a2beb33420eba
15:57 <merijn> ocharles: What part of "this" needs light?
15:58 <ocharles> See lines 22 , 30 and 31
15:58 <ocharles> I don't understand why abstracting `expressions (traverse f)` into `foo` causes a <<loop>>
15:58 cheater joined
15:59 peschkaj joined
15:59 <ocharles> Though the abstracting is fine if I introduce one more class (line 22)
15:59 <c_wraith> ocharles, usually that means you're accidentally shadowing something
15:59 <ocharles> there are some weird type class contexts, so I've tried to provide as much of those classes as I can
15:59 <ocharles> usually, but I'm not here
15:59 <Athas> c_wraith: parMap is working like a charm for me. It's rare that I get good Haskell parallelism experiences, but this is looking like one.
15:59 <ocharles> at least, as much as I can tell
15:59 ludat joined
16:00 owiecc joined
16:00 <kubunto> ok, seems like i have scoping issue
16:00 someone_ joined
16:01 <ocharles> I mean I have expressions = baseTableExprs, and baseTableExprs just calls gexpressions, and gexpressions just calls itself (or terminates). Using GHCI with -fbreak-on-exception and :trace doesn't really shed any light
16:01 coltfred joined
16:01 <kubunto> so why would c not be passed into the case function in this fragment: http://lpaste.net/353345
16:02 <ocharles> If I hit Ctrl-c and use :list, I'm apparently stuck at https://gist.github.com/ocharles/c028fa7c3f7c8242904a2beb33420eba#file-wat-hs-L100
16:02 <c_wraith> kubunto, you're not matching on the string "c"
16:02 <merijn> kubunto: Case only matches on patterns
16:02 fendor joined
16:02 <merijn> kubunto: You're just introducing a new variable 'c' and not using it
16:03 <ocharles> I've commented with :history on that gist now too
16:03 <ocharles> I'll try and get something standalone reproducible
16:03 <kubunto> how would i do what i want then
16:03 <c_wraith> use ==
16:03 <kubunto> namely pass in char c to the case match
16:03 <merijn> kubunto: Use "x == c"
16:03 janos__ joined
16:04 <c_wraith> ocharles, well.. have you tried putting an exact type annotation on foo?
16:04 codesoup joined
16:05 <kubunto> c_wraith: merijn getting parse errors
16:05 <ocharles> Yep, it doesn't help. I put on foo :: (Table expr haskell, Applicative f) => (Some Expr -> f (Some Expr)) -> expr -> f expr which is the most general type I want
16:06 <c_wraith> ocharles, how about without type variables? I'm trying to control the instance selection exactly.
16:06 <ocharles> c_wraith: if I use foo :: (Some Expr -> IO (Some Expr)) -> Small Expr -> IO (Small Expr) then it does work
16:06 mattyw joined
16:07 <ocharles> Likewise foo :: Applicative f => (Some Expr -> f (Some Expr)) -> Small Expr -> f (Small Expr)
16:07 <c_wraith> ocharles, then it's definitely related to instance selection somehow. I bet there are incoherent instances involved.
16:07 <ocharles> I'll paste the extensions I'm using in the module that defines those clasess
16:07 <c_wraith> well, hmm. overlapping would suffice
16:08 <ocharles> https://gist.github.com/ocharles/f1c707302f85cf386727849a1f60d4b1
16:08 <ocharles> and yea, there's the {-# OVERLAPPING #-} instance
16:08 yyyyy joined
16:08 Kreest__ joined
16:08 <c_wraith> overlapping instances don't really play nicely with inference
16:09 <kubunto> c_wraith: merijn how do i add in ==
16:09 <c_wraith> kubunto, replace the case with an if
16:09 <ocharles> that overlapping instance gets selected with polymorphic types - if I put `expressions = undefined`, then it crashes in both cases
16:11 <c_wraith> kubunto, like... if c == [x] then " " else [x]
16:11 <c_wraith> kubunto, or something like that, but actually what you're trying to do
16:11 Glooomy joined
16:12 stites joined
16:12 urodna joined
16:13 raichoo joined
16:13 <c_wraith> ocharles, I can't really suggest much. this is just the downside of overlapping instances. instance resolution becomes really hard to understand.
16:13 <ocharles> ok, I think I've found the problem...
16:13 <ocharles> {-# OVERLAPS #-} might the pragma I really wanted
16:13 <kubunto> c_wraith: tyvm
16:13 <ocharles> rather than {-# OVERLAPPABLE #-}
16:13 gabe4k joined
16:14 <c_wraith> Oh. yes, those are very different
16:14 <ocharles> ah, no
16:14 <ocharles> I had another line commented out still. Still loops with OVERLAPS
16:14 pasukon joined
16:14 jbiesnecker joined
16:14 osa1 joined
16:14 osa1 joined
16:14 <ocharles> (and OVERLAPPING)
16:14 <ocharles> Urgh
16:14 <ocharles> Maybe I'll just kill this stupid instance and make people write two instances
16:14 nwf joined
16:14 <ocharles> all the methods are generic anyway
16:15 <c_wraith> if you can avoid overlapping, it's worth it.
16:15 `Guest03 joined
16:15 <ocharles> https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html?highlight=overlapping#ghc-flag--XOverlappingInstances I guess the WARNING here is what I'm hitting
16:15 Bish joined
16:16 <tfc> hey there. i have a function a -> IO Bool
16:16 <tfc> and i basically want to filterM (not . f) list
16:16 <tfc> while f is a -> IO Bool
16:16 cschneid_ joined
16:17 dgonzo joined
16:17 <tfc> of course not . f does not work in that context. but i am currently puzzled finding out how it can be done
16:17 <tfc> <$> and <*> won't work
16:17 <MarcelineVQ> :t fmap not
16:17 Gurkenglas_ joined
16:17 <lambdabot> Functor f => f Bool -> f Bool
16:17 hackebeilchen joined
16:18 <tfc> (fmap not f) then?
16:18 defaultnick_ joined
16:18 fotonzade joined
16:18 <MarcelineVQ> not quite, that's not <$> f
16:18 <tfc> ok, i see...
16:18 <MarcelineVQ> you want the composition to happen still
16:18 <c_wraith> fmap not . f
16:18 <tfc> yes
16:18 ramzifu joined
16:19 <tfc> wow that works, thank you!
16:19 gienah joined
16:19 jbiesnecker joined
16:20 zaesur joined
16:20 <kubunto> is char a legal variable name?
16:20 Geoi joined
16:21 <kubunto> nvm
16:21 jbiesnecker joined
16:21 dfeuer joined
16:21 janos__ joined
16:22 FjordPrefect joined
16:23 <tfc> MarcelineVQ: ok, i have working what i need. but i do not understand the syntax of "fmap not . testMachine". i do not find a pair of braces i can put there to understand how this works.
16:23 boombanana joined
16:24 cheater joined
16:24 robotroll joined
16:25 <tfc> MarcelineVQ: if :t fmap is Functor f => (a -> b) -> f a -> f b, then i do not see how the "not . f" fits in. while "not" alone can be the first parameter alone , which makes it all a f a -> f b function, i don't understand the next composition step. can you help me here?
16:26 igniting joined
16:26 <Tuplanolla> Expand the definition of `.`, tfc.
16:26 <MarcelineVQ> the definition for (.) is f . g = \x -> f (g x) so to plug in the values for your case it's something like \x -> fmap not (f x)
16:27 <tfc> oh, i see. the lambda version is more comprehensive to me. thank you.
16:27 <SexHendrix> @src (.)
16:27 <lambdabot> (f . g) x = f (g x)
16:27 coot joined
16:27 razzi53 joined
16:27 <tfc> i know the definition of ".'
16:28 <tfc> the problem is that i know what fmap does, and i know what "a . b" does, but while "not . (f :: a -> IO Bool)" does not work, and "fmap not f" also does not work, it's kind of complicated why "fmap not . f" works.
16:29 andrei_chifa joined
16:29 Bish joined
16:29 <MarcelineVQ> did the above clear that up for you now?
16:30 Rainb joined
16:30 dgonzo joined
16:31 <kubunto> how would i do a recursive list comp?
16:32 <tfc> MarcelineVQ: the \x -> fmap not (f x) looks clear to me. but i fail to see how that is identical to "fmap not . f"
16:32 <MarcelineVQ> it's worth mentioning the f's are different, I should have written: j . k = \x -> j (k x) ... \x -> fmap not (f x)
16:32 <MarcelineVQ> fmap not is j and f is k
16:33 defaultnick_ joined
16:33 <shapr> kubunto: [x | xs <- ["foo","bar"], x <- xs] ?
16:33 <tfc> aaah now i get it. (fmap not) . testMachine
16:33 <tfc> :)
16:33 raynold joined
16:33 <tfc> thank yo very much MarcelineVQ!
16:34 <MarcelineVQ> np, I should have been more clear
16:34 <kubunto> shapr: i want to be able to loop thru a list of punctuation marks and use them as arguments to a function i wrote
16:34 trism joined
16:34 <tfc> i am still quickly confused by missing parentheses
16:34 <shapr> kubunto: do you want to pass each mark to different functions? or what?
16:35 <c_wraith> tfc, function calls always bind more tightly than operators
16:35 <kubunto> shapr: one sec
16:35 <c_wraith> I suppose I should say "function application"
16:35 <tfc> c_wraith: yes, while i know this, i am used yet to always read it like that. hling keeps kicking me for adding too many parentheses
16:36 revtintin joined
16:36 <SexHendrix> kubunto: functionYouMade <$> listOfPunctuation
16:36 <shapr> yeah, fmap is the easy way
16:37 Copperis joined
16:37 <kubunto> SexHendrix: i have better idea
16:37 <kubunto> make my if a little more useful in the replacement function i wrote
16:37 Deide joined
16:37 dgonzo joined
16:37 doomlord joined
16:37 Lord_of_Life joined
16:37 <SexHendrix> @get-shapr
16:38 <lambdabot> shapr!!
16:38 <shapr> you screamt?
16:38 <SexHendrix> i knew id seen that name somewhere
16:38 <shapr> SexHendrix: that command hasn't seen much use the past five or so years
16:39 <SexHendrix> recently set up my own lambdabot, saw it was installed by default
16:39 <SexHendrix> no idea what it was till i saw your name just now
16:39 sepp2k joined
16:39 <SexHendrix> :)
16:39 <shapr> I used to host lambdabot and I started #haskell, so I was the single point of failure for a pile of years.
16:39 <shapr> thankfully that's no longer the case
16:40 <SexHendrix> its a nice bot
16:40 <shapr> SexHendrix: any thoughts on lambdabot ?
16:40 <shapr> There's a bug in the Quote module that's nearing fifteen years old, I really need to fix that.
16:41 <SexHendrix> yeah i haven't looked much into hacking it yet but feels more premium than supybot
16:41 <shapr> amusingly, supybot's @command syntax came from lambdabot
16:41 <Tuplanolla> I feel lambdabot's ux could do with a lot of work.
16:41 <shapr> I wasn't the original author of lambdabot, that would be Andrew Bromage, but I did write the plugin system and most of the early plugins.
16:42 <int-e> @quote bug
16:42 <lambdabot> Knuth says: The conventional wisdom shared by many of today's software engineers call for ignoring efficiency in the small; but I believe this is simply an overreaction to the abuses they see being
16:42 <lambdabot> practiced by pennywise-and-pound-foolish programmers, who can't debug or maintain their "optimized" programs.
16:42 <SexHendrix> still feels a lot more like a tool than a gen purpose bot
16:42 <SexHendrix> might write a duckhunt plugin
16:42 <Tuplanolla> If you define `x` for example, it should say "defined `Lambdabot.x`; already in scope: `SimpleReflect.x`, `Some.Other.x`".
16:43 <shapr> Yeah, people started plugging lambdabot into ghci at some point
16:43 <shapr> but most of those tools are now available in various plugins
16:43 <SexHendrix> deleting single definitions wouuld be nice
16:43 <shapr> though I'd still like to be able to do M-x pl-region
16:43 <SexHendrix> typos keep screwing me over
16:43 <shapr> Tuplanolla: fix it?
16:43 <SexHendrix> letlpaste is great though
16:43 <Tuplanolla> The `@let import` syntax is also impossible to figure out without seeing it in action first.
16:43 <SexHendrix> best feature
16:44 <shapr> One reason lambdabot got popular was that you got ops on lambdabot when you wrote a plugin :-)
16:44 michael1 joined
16:44 <Tuplanolla> Whoa, extra responsibilities for free.
16:44 <Rembane> Sneaky! :D
16:44 afarmer joined
16:44 <SexHendrix> people will do insane things for a slight increase in internet power
16:45 <shapr> yeah, imaginary internet points are coveted
16:45 conal joined
16:45 defaultnick_ joined
16:46 <SexHendrix> in it for the 1337 hostmasks
16:47 ner0x652 joined
16:47 felko joined
16:48 balor joined
16:48 <felko> Is there anyway of using a type-level Nat as a value in a computation ? I can't find anything online
16:48 sssilver joined
16:48 <ertes> felko: on the type level or value level?
16:48 mnislaih joined
16:49 conal joined
16:49 <cocreature> KnownNat allows you to get the value corresponding to a type-level nat
16:49 <glguy> felko: You can use the KnownNat class
16:49 <felko> ok i'll check it out thanks
16:49 <ertes> felko: for type-level computation you can use the type families like (+) from the GHC.TypeLits module
16:50 <felko> ertes: i meant using a type-level Nat in a value-level computation
16:50 <felko> Ok KnownNat seems to correspond to what I want, thanks a lot
16:52 <kubunto> ok i cant figure this out
16:52 <kubunto> i have a string of punctuation that i want to remove
16:53 <kubunto> function is http://lpaste.net/353349
16:54 <shapr> > filter (not . flip elem "'!") "I don't want punctuation!"
16:54 <lambdabot> "I dont want punctuation"
16:54 _sg joined
16:54 <glguy> kubunto: Do you know that this "\[x] -> ..."
16:54 <glguy> is matching single element lists?
16:54 <kubunto> glguy: no but it matches what i have observed
16:55 dgonzo joined
16:55 <cocreature> maybe start by adding a type signature :)
16:55 <ertes> kubunto: you should really write a type signature for both 'replace' and 'replacef'
16:55 balor joined
16:55 <glguy> In this context [x] is a pattern for a single element list where the single element is named x
16:55 cdg joined
16:56 jmelesky joined
16:56 <glguy> like the list: [1] or [True]. It's different from the type level where you have [Int] which means "a list of Ints"
16:57 dgonzo joined
16:57 danharaj joined
16:58 refold joined
16:59 <`Guest03> tfc: (not <$>) . f
16:59 JonReed joined
17:00 <tfc> `Guest03: nice, this works too. thx!
17:00 <shapr> tfc: lambdabot's @pl command is fun too
17:00 <shapr> @pl \x -> fmap not (f x)
17:00 <lambdabot> fmap not . f
17:00 <glguy> If we're obfuscating: (not <$>) <$> f
17:00 <SexHendrix> my favourite is
17:00 <SexHendrix> @protontorpedo
17:00 <lambdabot> so how do you use haskell tools to build large programs?
17:01 conal joined
17:01 <SexHendrix> or maybe
17:01 <SexHendrix> @ghc
17:01 <lambdabot> Info table already?
17:01 <shapr> SexHendrix: yeah, that user had a surprising amount of surreality
17:01 <ertes> to (<$>) or not to (<$>): (<$>) (not (<$>)) f
17:01 <SexHendrix> im in a channel where some other lads are running a markov plugin on the entire log history
17:02 <dolio> protontorpedo is kind of boring. keal is better.
17:02 <merijn> @keal
17:02 <SexHendrix> so i like to spam @ghc in there to poison all output with sassy ghc quips
17:02 <lambdabot> b*(Floor[v/b^p]/b-Floor[Floor[v/b^p]/b])
17:03 <ongy> :t b*(Floor[v/b^p]/b-Floor[Floor[v/b^p]/b])
17:03 <lambdabot> error:
17:03 <lambdabot> • Data constructor not in scope: Floor :: [Expr] -> Expr
17:03 <lambdabot> • Perhaps you meant variable ‘floor’ (imported from Prelude)
17:03 <ertes> :t \f -> (id <*> not) (<$>) f
17:03 <lambdabot> error:
17:03 <lambdabot> • Couldn't match type ‘Bool’ with ‘a -> b’
17:03 <lambdabot> Expected type: ((a -> b) -> f a -> f b) -> f a -> f b
17:03 <kubunto> brb
17:04 <`Guest03> :t x
17:04 <lambdabot> Expr
17:04 hyuvkr joined
17:05 mthek joined
17:05 <`Guest03> > x + x
17:05 <lambdabot> x + x
17:05 <ertes> :t (id <*> not :: (forall f. (Functor f) => (a -> b) -> f a -> f b) -> [Bool] -> [Bool]) (<$>)
17:05 <lambdabot> error:
17:05 <lambdabot> • Couldn't match type ‘Bool -> [Bool] -> [Bool]’
17:05 <lambdabot> with ‘forall (f :: * -> *). Functor f => (a -> b) -> f a -> f b’
17:05 nwf joined
17:06 balor joined
17:07 <ertes> @src (<$$>)
17:07 <lambdabot> Source not found.
17:08 <ongy> :t (<$$>(
17:08 <ongy> :t (<$$>)
17:08 <lambdabot> error:
17:08 <lambdabot> parse error (possibly incorrect indentation or mismatched brackets)
17:08 <lambdabot> error:
17:08 <lambdabot> • Variable not in scope: <$$>
17:08 <lambdabot> • Perhaps you meant one of these:
17:08 <ertes> lambdabot is not in tsunderebot mode today?
17:08 <SexHendrix> :t <$$$>
17:08 <lambdabot> error: parse error on input ‘<$$$>’
17:08 dgonzo joined
17:09 fresheyeball joined
17:09 <ongy> you have to put operators in parens for things like this. so <$> becomes (<$>) and so forth
17:09 refold joined
17:09 <ertes> where did i see (<$$>) = flip fmap? would be quite useful to have in Prelude
17:09 <ongy> same for import lists, so 'import Control.Applicative ((<$>))' is rather common for me
17:10 <ertes> :t (<**>) -- like this
17:10 <lambdabot> Applicative f => f a -> f (a -> b) -> f b
17:10 Sonolin joined
17:13 connrs joined
17:14 jwat joined
17:14 dbmikus joined
17:15 andrei_chifa joined
17:15 Lord_of_Life joined
17:16 rekahsoft joined
17:17 BlueRavenGT joined
17:19 ramzifu joined
17:20 Iskarlar joined
17:21 <MarcelineVQ> ertes: often I see it as <&> if that's useful
17:22 connrs joined
17:22 dgonzo joined
17:24 ragepandemic joined
17:24 jutaro joined
17:25 <`Guest03> (<&>) can also be of type f (a -> b) -> a -> f b
17:25 <nitrix> :t (<&>) -- from lens
17:25 <lambdabot> Functor f => f a -> (a -> b) -> f b
17:26 Glooomy joined
17:26 owiecc joined
17:26 dgonzo joined
17:26 kubunto joined
17:26 Noldorin joined
17:26 <kubunto> i am still lost on trying to get punctuation to be replaced with spaces
17:26 mnislaih joined
17:27 <ongy> kubunto: have you seen the version with filter that removes punctuation glguy posted earlier?
17:27 <kubunto> ongy: i dont want them removed
17:27 <kubunto> i want them replaced
17:27 <glguy> I don't think I posted one
17:28 wraithm joined
17:28 <ongy> oh I thought it was you.
17:28 <ongy> kubunto: you can easily modify that filter ot something that replaces:
17:28 <nitrix> map (\c -> if isPunctuation c then ' ' else c)
17:29 <ongy> > let fun x = x `notElem` "'!" in map (\c -> if fun c then ' ' else c) "I don't want punctuation!"
17:29 <lambdabot> " ' !"
17:29 <ongy> whoops wrong way around. But I will let this be your homework
17:30 <`Guest03> hmm
17:30 <nitrix> Data.Char.isPunctuation already provides you with the detection, you can spare writing you own version.
17:30 steeze joined
17:30 twopoint718 joined
17:31 michael1 joined
17:31 raichoo joined
17:31 defaultnick__ joined
17:32 <nitrix> In which case, it simply becomes:
17:32 <`Guest03> (\c -> fromEither $ guard (isPunctuation c) *> return c <|> return ' ')
17:32 dgonzo joined
17:32 <nitrix> > filter (not . isPunctuation) "Hello, World!"
17:32 <lambdabot> "Hello World"
17:33 <nitrix> Oh I'm doing the same mistake.
17:33 danharaj joined
17:33 <teto> any advice to a beginner for parsing CSV ?
17:33 <`Guest03> > concatMap (\c -> if (isPunctuation c) then " " else [c]) "1, 2, 3..."
17:33 <lambdabot> "1 2 3 "
17:34 <sm> teto: use one of the CSV libs on hackage ?
17:34 <kuribas> teto: cassava?
17:35 defaultnick__ joined
17:35 mtncoder joined
17:35 <teto> I hesitate between cassava and parsec ? any reason to choose one over the other ?
17:35 <sm> parsec doesn't come with a csv parser, you'd be writing it yourself
17:35 funkshun joined
17:36 Swizec joined
17:36 <sm> and that already exists (http://hackage.haskell.org/package/csv)
17:36 dgonzo joined
17:37 augur joined
17:37 <sm> which is old, but very simple
17:38 dgonzo joined
17:38 bjz joined
17:39 <teto> thanks
17:39 <JonReed> Hi, is there a way to provide default value to a lens. E.g., this `aList ^? ix 0` returns maybe and I want it to return simply `a`. I know I can `fromMaybe 42 $ aList ^? ix 0 `, but what is the lens way of doing it?
17:40 <Tuplanolla> Yes, `non`, JonReed.
17:40 uglyfigurine joined
17:41 <JonReed> Tuplanolla: Can you provide an example, please? I tried non before and I used it somehow in a wrong way
17:41 <Tuplanolla> See Microlens' documentation for several examples, JonReed.
17:41 <Tuplanolla> @hackage microlens
17:41 <lambdabot> http://hackage.haskell.org/package/microlens
17:41 <kubunto> can i put type definitions inside a function?
17:41 <Tuplanolla> Yes, anywhere, kubunto.
17:42 <* sm> thinks not
17:42 <Tuplanolla> Wait, declarations or definitions?
17:42 <kubunto> for instance repl :: Char -> Char
17:42 <Tuplanolla> Then yes, anywhere.
17:42 alexknvl joined
17:44 Rodya_ joined
17:44 <nitrix> JonReed: You want Iso.
17:44 <nitrix> JonReed: non :: Eq a => a -> Iso a (Maybe a)
17:44 Swizec joined
17:44 <nitrix> aList ^? ix 0 . non 42
17:45 <nitrix> (If I remember the fixity right)
17:46 malc_ joined
17:46 certainty joined
17:46 b4ff3r joined
17:47 <kubunto> damn
17:47 <kubunto> i have no idea what types my functions are
17:47 jmcarthur joined
17:48 insitu joined
17:48 oisdk joined
17:50 t7 joined
17:50 razzi53 joined
17:50 <ongy> you can compile with warnings enabled and ghc will tell you
17:50 schjetne joined
17:52 raichoo joined
17:53 <glguy> No, you can't mix ix and non like that
17:54 <glguy> (or you can, but it doesn't do what the question wants)
17:54 ertesx joined
17:55 sobaken joined
17:56 <glguy> fromMaybe is the lens way
17:57 <nitrix> Ah. Well you can keep using Ix then.
17:57 <nitrix> > Nothing ^. at () . non 69
17:57 <lambdabot> 69
17:58 <nitrix> > Just 42 ^. at () . non 69
17:58 <lambdabot> 42
17:58 <glguy> Right, non pairs better with at, and lists aren't an instance of At
17:59 coot joined
17:59 Ariakenom joined
17:59 <glguy> (> [0..3] ^?! (ix 10 <> like 42), [0..3] ^?! failing (ix 10) (like 42))
18:00 <glguy> > ([0..3] ^?! (ix 10 <> like 42), [0..3] ^?! failing (ix 10) (like 42))
18:00 <lambdabot> mueval-core: Time limit exceeded
18:00 <glguy> (42,42)
18:00 pleax joined
18:00 coot_ joined
18:00 Coldblackice joined
18:01 <nitrix> JonReed: aList ^. at 0 . non 69 -- So basically change `ix` for `at` and you'll be able to use `non` nicely.
18:01 <glguy> and change aList to something that isn't a list
18:02 <kubunto> ongy: i had issues declaring types of lambda functions
18:02 <nitrix> glguy: Once you go lens, you never come back :P
18:03 <nitrix> glguy: (As in rabbit hole)
18:03 <glguy> There's a phase to go through to learn that lens isn't a framework that all your computation needs to be embedded in, but that requires figuring out what's actually in lens
18:04 pera_ joined
18:04 fizruk joined
18:04 darjeeling_ joined
18:04 <MarcelineVQ> I'm still in the phase of "what the hell am I looking at"
18:05 <ongy> wait, lens is more than "fancy extensions to records"?
18:06 AndreasK joined
18:06 <Tuplanolla> Lens is a lifestyle.
18:06 <kuribas> ongy: only that and the kitchen sink
18:06 defaultnick_ joined
18:06 fnurglewitz joined
18:06 psh_ joined
18:06 <glguy> very little of lens is about fancy extensions to records
18:07 <ongy> then I am at the point where I have no idea what lens is :)
18:07 losso joined
18:08 <kuribas> lens is a traverse generalized to any structure and part.
18:08 txcyuio joined
18:08 <kuribas> traverse on steroids
18:08 <tommd> It's a way to peg your CPU for longer during compilation. It's also about structure traversal or even monadic actions that are structure-specific (ex: state).
18:09 dedgrant joined
18:09 minn joined
18:10 <bennofs> tommd: i think the CPU pegging part is called "template haskell" :)
18:14 Cassiopaya joined
18:15 a3Dman joined
18:17 zaesur left
18:18 rperry joined
18:19 alx741 joined
18:19 defaultnick_ joined
18:20 ramzifu joined
18:21 cereal_killer_ joined
18:21 Swizec joined
18:22 ner0x652 joined
18:23 uglyfigurine joined
18:23 janos__ joined
18:23 tfc joined
18:23 afarmer joined
18:24 asmyers joined
18:24 initiumdoeslinux joined
18:25 mkoenig joined
18:26 balor joined
18:27 cosmodanger joined
18:29 robotroll joined
18:30 wraithm joined
18:30 Luke joined
18:30 defaultnick_ joined
18:31 replay joined
18:32 nadirs joined
18:32 FullyFunctional left
18:33 Jacoby6000 joined
18:34 castlelore joined
18:34 Itkovian joined
18:34 connrs joined
18:34 balor joined
18:36 tommd joined
18:37 mr_sm1th joined
18:37 caumeslasal joined
18:37 <sdrodge> I still struggle a lot with knowing when to use lazy variants of various data structures/monads, and when its a good idea to add strictness annotations. Does anyone know of a good write up on this topic?
18:37 <sdrodge> (better than the wiki, that is)
18:37 b4ff3r joined
18:38 paolino joined
18:38 <sdrodge> Or is the approach in "real" Haskell programs to actually just write everything using one default or the other and then do profiling to fix it?
18:38 <sdrodge> Perhaps I'm overestimating the extent to which practitioners know the answer to this question.
18:39 mda1 joined
18:39 <sdrodge> Or perhaps I'm overestimating how often this impacts performance significantly.
18:42 beanbagu1 joined
18:42 <sdrodge> To make this more concrete: would any strictness annotations in this programming be an obviously good idea? https://hastebin.com/oweyizopax.hs
18:44 scinawa joined
18:45 gmalecha joined
18:45 <sdrodge> *thi program
18:45 <sdrodge> *this program
18:46 coot joined
18:48 merijn joined
18:48 ziocroc joined
18:48 connrs joined
18:49 mizu_no_oto_work joined
18:50 curious_corn joined
18:50 serendependy joined
18:51 janos__ joined
18:52 <Cale> sdrodge: I suspect using IM.insertWith' may improve things.
18:52 refold joined
18:52 <* Sonolin> shrugs
18:52 <Cale> sdrodge: When you use IM.insertWith (+) there, it won't actually calculate the sum, it just sticks the unevaluated expression into the map
18:52 <Sonolin> I always just use lazy, and when I come into problems or issues then look at strict variants
18:53 balor joined
18:53 Gloomy joined
18:53 <Sonolin> profiling with ghc is a breeze IMO
18:53 dpren joined
18:53 <sdrodge> Is that the general practice, then?
18:53 <sdrodge> Write lazy and then profile it and fix it?
18:54 <merijn> sdrodge: Well, if you get better at understanding the implications of laziness you can predict them without profiling
18:54 <Cale> So if you don't observe the values in the map, you'll end up with large expressions of the form (...((1 + 1) + 1) + ...) + 1) + 1
18:54 <sdrodge> No real guidelines to follow for inserting strictness annotations that are "obviously" right the first time you write it?
18:54 <merijn> sdrodge: Well, there are heuristics and guidelines, but they are rather tricky to articulate
18:54 <sdrodge> Cale: Is that a real cost given that I'm storing all the past versions of the map anyway?
18:54 <merijn> At least, I realise I have them, but don't know how to articulate them
18:55 <sdrodge> merijn: Know of any good write ups?
18:55 <Cale> Yes, an expression like that requires much more memory than an Int would otherwise take
18:55 <monochrom> The real guideline is to learn laziness and decide, very consciously, whether you want it or not.
18:55 <Cale> and if you wait too long before eventually evaluating it, you'll end up with a stack overflow
18:55 <Cale> because (+) is strict in both its arguments
18:55 <merijn> sdrodge: Starting point for understanding laziness would be: https://hackhands.com/guide-lazy-evaluation-haskell/
18:55 <Cale> So you'll start out with (...) + 1
18:55 maksim__ joined
18:55 soLucien joined
18:56 max3 joined
18:56 <merijn> sdrodge: A more in-depth follow up (assumes you know a little bit about C/asm) would be the STG paper: http://citeseerx.ist.psu.edu/viewdoc/download?doi=
18:56 <Cale> and the outermost (+) will say, "Oh, I need to match on my first argument", and that pattern match will wait on the stack while the first argument is evaluated
18:56 <Cale> and it too will be of the form (...) + 1
18:56 <Cale> and if you have like a million of those, you'll blow up your stack
18:57 <sdrodge> merijn: My problem is that I already know how Haskell does laziness, but I find it hard to convert that knowledge into good strictness annotations while writing code.
18:58 pfurla joined
18:58 <Cale> My usual rule of thumb is to break things down by whether operations are taking or producing things with many or few separately evaluatable parts
18:58 <sdrodge> Cale: I see why that would be true if I were only keeping the current map around, but aren't I paying that memory penalty anyway by keeping all the maps around?
18:59 <Cale> It's the cases where something is taking many separate parts, and condensing them down into something with few parts that you want strictness.
18:59 <monochrom> That's probably just because your own strictness annotation is not enough. Libraries you use have a say too. It's why Data.Map.Strict exists. Not something you can do outside the library.
18:59 <merijn> sdrodge: Why do you think you're keeping all the maps around?
18:59 aesthetik joined
18:59 <Cale> sdrodge: No, this is a separate penalty
18:59 path[l] joined
18:59 <sdrodge> merijn: Because I'm keeping all the old maps in a sequences as state.
18:59 <sdrodge> *in a sequence
19:00 <Cale> This isn't the *Map*, this is the *Int* inside.
19:00 defaultnick__ joined
19:00 curious_corn joined
19:00 <monochrom> Yes, you have "one single Int" that takes up 100MB because it's still in a "1+1+1+..." form.
19:00 <Cale> You're storing a big complicated expression for that Int which, once you evaluate it, will be replaced by a machine word or two.
19:00 xcmw joined
19:01 <aesthetik> Click on the link and get $110!
19:01 <aesthetik> https://richmondberks.com/?ref=rbd118972
19:01 <aesthetik> - Make 1,5% Daily profit !
19:01 <aesthetik> - Invite a friend and get 1$ as a gift !
19:01 <aesthetik> - Comissions of 10% !
19:01 was kicked by monochrom: aesthetik
19:01 <sdrodge> Okay, yes, good point.
19:02 <Cale> sdrodge: Doing that sooner rather than later also makes the garbage collector's life easier, and you'll save a bunch of time on allocations.
19:02 <sdrodge> So is the generalization here that I should use insertWith' unless I specifically need the value inserted to be calculated lazily?
19:03 <SLi> I've been pondering way too long about how to best implement this (as always seems to happen when I program in Haskell :(). Essentially, I'm writing a tool that works on expressions (and-inverter-graphs, i.e each node is a binary AND operator, and the two inputs to each gate may independently either be inverted or not) and applies local rewrites. But there's a wrinkle: Expressed as trees, the expressions are huge and share a lot of subexpressions, so the
19:03 <SLi> input is provided as a DAG, and should be kept as a DAG. So need sharing. Lots of times I would like to essentially rewrite the DAG node, i.e. the expression everywhere in the tree, but other times I might want to essentially unshare it and rewrite it in only parts of the tree.
19:03 <monochrom> Why are you in such a hurry for generalizations and no-brainer rules of thumb? But yes.
19:03 <Cale> Usually... it depends of course, but yeah.
19:03 <SLi> So, I guess I could implement this as described, but I wonder there's some abstraction that could help me, like abstracting the "sharing container with ability to unshare" idea somehow.
19:04 <Cale> Sometimes it'll be profitable to store a lazy expression for something in the Map -- if computing the outcome will be expensive and you might not need the result, or if you expect the space for the result to be larger than the space for the expression.
19:04 <sdrodge> monochrom: Because it's really helpful to have guidelines/rules to follow when programming as to not overload working memory.
19:05 <monochrom> (Fortunately this is still not a no-brainer because "do I need laziness" still requires conscious rational reasoning.)
19:05 <sdrodge> If I have to spend time thinking carefully about whether I want the strict or the lazy version every single time I write a line of code, that's not good.
19:05 janos__ joined
19:05 <Cale> Well, you kind of do.
19:05 <sdrodge> Sure, but it's a matter of how hard I need to think.
19:05 halogenandtoast joined
19:05 <Cale> It's just that 95% of the time, the answer is "it doesn't matter"
19:05 <monochrom> It has been pretty easy for me.
19:05 <Cale> and then the other 5% of the time, it's one way or the other and very important
19:06 <sdrodge> Oh, I see.
19:06 <sdrodge> So it's more that the cost of computing this is low enough that strictness is obviously right.
19:06 <sdrodge> Even though the value may not be needed.
19:06 <SLi> I've also looked at graph rewriting packages in hoogle. Of those, I think this looks most promising at least for testing, but I think it lacks the sharing part. https://hackage.haskell.org/package/graph-rewriting
19:06 meck joined
19:07 <Cale> sdrodge: yeah, in this case, you're not saving anything by deferring that addition until later
19:07 <monochrom> (Fortunately it is still not a no-brainer because for every line you still have to consciously rationally reason whether that line is in the 95% or in the 5%. Resistance is futile.)
19:07 <sdrodge> I'm really not looking for a no-brainer.
19:07 <Cale> monochrom: Yeah
19:07 <sdrodge> I'm just looking for a better feel about how to frame the question so that I can figure it out faster in the future.
19:07 <Cale> (though I'm not sure it's actually fortunate)
19:07 <SLi> I agree I've also had problems with laziness everywhere causing hard-to-debug memory issues. Trying strict-by-default Haskell is on my list of things to do.
19:07 <monochrom> That is called experience.
19:07 <sdrodge> Instead of the situation I currently have where I write a program and then wonder, huh, did I miss any obvious strictness annotations?
19:08 medicijnman joined
19:08 <sdrodge> Okay, but it's even better if you can learn from others' experience instead of your own.
19:08 <SLi> Actually, almost every time I write a Haskell program that takes a moderately large input and outputs something simple I have a problem that the memory usage grows to gigabytes. I've been told religiously avoiding lazy IO helps.
19:08 <monochrom> Yes. You have a USB port in your head? I could download mine to you.
19:08 bodisiw joined
19:08 <sdrodge> So one very useful tip I seem to have learned today is that in general for inexpensive operations on small data (like addition on ints), you want to demand strictness.
19:08 <merijn> SLi: Well, lazy IO is rather rarer than people seem to think it is
19:09 <merijn> Like, there's only 5 or so lazy IO operations in base
19:09 <monochrom> Or you can send me 100 bitcoins to commission me to write a whole book on this.
19:09 <SLi> merijn: Hmm, ok.
19:09 <merijn> sdrodge: Right, that's a reasonable heuristic
19:09 crobbins joined
19:09 <sdrodge> monochrom: You could see if there's a way to gel your experience into a great article with worked examples!
19:09 <merijn> sdrodge: He already has that for most topics :p
19:09 <monochrom> Yes. You can send me 100 bitcoins to commission me to write it.
19:09 <SexHendrix> just written what could be the worlds slowest numerical integrator
19:09 <SexHendrix> http://lpaste.net/353356
19:10 <SexHendrix> looking for some obvious areas for speeding it up
19:10 <sdrodge> monochrom: Look, I just asked if there was such a write-up somewhere. You're the one attacking me for asking the question and suggesting this knowledge is impossible to transfer anywhere other than hard-won experience.
19:10 twopoint718 joined
19:10 <sdrodge> Cool your jets.
19:10 <monochrom> I just asked for money.
19:10 <sdrodge> :P
19:10 <monochrom> You need to take a walk.
19:11 betao joined
19:11 <monochrom> And I need a haircut.
19:11 <SLi> I need both.
19:12 zar joined
19:12 <monochrom> But what merijn said. http://www.vex.net/~trebla/haskell/lazy.xhtml
19:12 janos__ joined
19:12 <monochrom> The foldr and foldl examples are not too different from the insertWith situation.
19:12 unK_ joined
19:12 simendsjo joined
19:13 <sdrodge> Yeah. I mean, I understand the foldr and foldl examples. I just find it difficult to apply that knowledge when writing larger programs.
19:13 muesli4 joined
19:13 <sdrodge> When you guys write Haskell, do you actually stop and think about whether strictness or laziness is correct for each expression that you write?
19:13 <monochrom> Yes I do.
19:14 pleax joined
19:14 <monochrom> And no, not taxing.
19:14 <Cale> sdrodge: The general rule of thumb that I use is that whenever you're taking many separately evaluatable things, and combining them together into a single indivisible value (which can't be partially evaluated), that almost always describes the places where you want the strictness annotations.
19:14 <sdrodge> Cale: Interesting.
19:14 <sdrodge> Thanks!
19:15 <merijn> sdrodge: Well, I just kinda have a feel for things, like Cale describes, and that sets of my warning "I need to pause and think" reflex
19:15 <kuribas> sdrodge: for small numerical functions, lazyness can be a high cost. I had a 10X performance increase by forcing a tuple, because keeping the closure and garbage collecting it was much more expensive.
19:15 ragepandemic joined
19:15 jomg joined
19:15 <sdrodge> I guess maybe the misconception that I have is that it doesn't always seem possible to reason about stricness locally.
19:15 <mniip> sdrodge, depends on what mode I'm programming in
19:15 <sdrodge> But maybe I'm missing something.
19:15 <merijn> kuribas: Well, forcing it might also help the strictness analyser
19:15 <Cale> sdrodge: Well, it's not.
19:15 <mniip> sometimes I'm writing code so that it runs well, sometimes I only need a qualitative result
19:16 <Cale> That's not a misconception -- how expressions are evaluated are something that can require insight into what the whole program is doing in general.
19:16 zariuq joined
19:16 <kuribas> merijn: it wasn't strict, because both values depended on the same computations.
19:16 <sdrodge> That's the part that bothers me.
19:16 certainty joined
19:16 jutaro joined
19:16 <sdrodge> Because whole program reasoning doesn't scale.
19:16 tomphp joined
19:17 biglama joined
19:17 <merijn> kuribas: No, I meant that adding the strictness might lead the strictness analyser to kick in and unbox things
19:17 <merijn> sdrodge: That's a downside yes, but there's also an upside!
19:17 <kuribas> merijn: right
19:17 <sdrodge> Don't worry, I'm not upset about laziness.
19:17 <sdrodge> I love it.
19:17 <merijn> sdrodge: If you have code that is "too strict", making it lazier requires changing ALL the code
19:17 <SLi> So, I wonder if it would be possible to write some... thing that takes any type (Hashable a, Eq a, Functor f) => f a and produces an isomorphic type with observable sharing of a. Though that still wouldn't work for sharing subtrees in trees. Hmh.
19:17 <sdrodge> I just want to learn how to manage the lazy/strict choice better.
19:18 <merijn> sdrodge: Whereas, making something that's "too lazy" stricter is a local code change (see foldl vs foldl')
19:18 conal joined
19:18 sid_fules joined
19:18 <merijn> sdrodge: So the upside is that code that's too lazy can be fixed/worked around without needing to change any original code, which cannot be said for too strict
19:18 <merijn> But it's time to log off!
19:18 <sdrodge> Cale, merijn: Out of curiosity, do you tend to default to Data.Map.Strict or Data.Map.Lazy?
19:18 okami joined
19:18 <monochrom> "whole-program" is the pathological worst case. It rarely happens. For most programs, especially well-structured ones, very few parts actually has access to the data in question, even though those few parts don't sit together.
19:18 <sdrodge> merijn: Thanks for the help!
19:18 mthek joined
19:19 pbgc joined
19:19 <Cale> sdrodge: Data.Map.Lazy
19:19 <monochrom> So instead, it is "everyone has access to everything" that doesn't scale.
19:19 <kuribas> sdrodge: the morale is I think don't keep thunks that are cheap to evaluate, or will be evaluated anyway.
19:19 begriffs joined
19:19 <Cale> There are only a few operations which need strictness.
19:19 <sdrodge> monochrom: Fair enough.
19:20 <Cale> sdrodge: But note that it's not mutually exclusive
19:20 <Cale> The actual type is the same, only the functions are different.
19:20 deepfire joined
19:20 cosmodanger joined
19:20 grayjoc joined
19:20 <Cale> Data.Map.Strict just has functions that force evaluation of the elements of the Map that they interact with.
19:20 <sdrodge> Oh, didn't realize that.
19:21 <sdrodge> How about other cases where it is mutually exclusive?
19:21 defaultnick_ joined
19:21 <sdrodge> Like Control.Monad.State.{Lazy, Strict}
19:21 <sdrodge> Do you tend to default to Lazy or Strict?
19:21 <sdrodge> Is the answer the same or different for ST?
19:21 <Cale> For Control.Monad.State I just import Control.Monad.State
19:21 bernouli joined
19:21 <sdrodge> So that's the Lazy one.
19:21 <Cale> which I believe gets me the Lazy one, yeah
19:21 baldrick1 joined
19:22 NeverDie joined
19:22 <Cale> That doesn't matter too much in practice -- it's referring to whether the pairs are being forced in the definition of bind
19:22 maksim__ joined
19:22 max3 joined
19:23 <Cale> i.e. whether it's x >>= f = State (\s -> let (v,s') = runState x s in runState (f v) s')
19:23 <Cale> or x >>= f = State (\s -> case runState x s of (v,s') -> runState (f v) s')
19:24 <monochrom> Actually they use "(v, s')" vs "~(v, s')" now.
19:24 <Cale> fair enough (should be the same thing)
19:24 <Cale> Note that even with Control.Monad.State.Strict, you can still have the state itself be an unevaluated expression
19:25 erewok joined
19:25 <monochrom> (and an implicit case. Why implicit? Because they obtained the "case" from do-notation. Why do-notation? Because it's StateT, even if it's StateT Identity)
19:25 <Cale> ah, right, that makes sense :)
19:25 okami left
19:25 conal joined
19:25 <sdrodge> So it seems I am missing something here. What is the significance of forcing the tuple directly in the bind vs. not?
19:26 <monochrom> Yes this one is very sutble.
19:26 <monochrom> My http://lpaste.net/41790/ shows what could happen.
19:27 doodlehaus joined
19:27 ramzifu joined
19:28 bodisiw joined
19:28 koneko joined
19:28 <monochrom> In this case I do have a rule of thumb. But it is only because of statistics on how people use Control.Monad.State empirically.
19:29 <monochrom> When people use Control.Monad.State, 100% of the time they imagine that they're writing C or Pascal or Algol or something.
19:29 snowalpaca joined
19:29 cyborg-one joined
19:29 <monochrom> The Strict version is the one closer to their fantasy. This is why it is the safe default.
19:30 <sdrodge> Does that mean you think State was the wrong choice for that example program I shared?
19:30 <monochrom> The Lazy version corresponds to an imperative language that no one has thought of. (Except in my thesis.)
19:30 <dolio> What if they imagine they're writing Algol 68?
19:30 <monochrom> Well this is where the empirical statistics comes in. 0% of the people actually do that.
19:31 defaultnick_ joined
19:31 vektorweg11 joined
19:31 <Cale> In my experience, people usually don't care and import Control.Monad.State, which makes that the sensible default regardless of its semantics
19:32 haskull joined
19:32 <monochrom> Ah but they have a high chance of consuming more memory than they need.
19:32 nakal_ joined
19:32 <dolio> Strict used to avoid some stack overflows from really big computations. But I guess that's gone now.
19:33 Swizec joined
19:33 <monochrom> There is a conspiracy in the correlation between "I am lazy, I just type 'Control.Monad.State'" and "it gets me Control.Monad.State.Lazy".
19:34 ramzifu joined
19:34 <Cale> Of course, that only matters if you expose things which involve explicitly the State/StateT you imported, which you probably shouldn't do anyway :P
19:34 Boomerang joined
19:34 <dolio> The maintainers are also too lazy to bother changing the semantics from when the lazy version was the only one that was offered.
19:34 <sdrodge> I guess when it comes to performance, all abstractions are leaky.
19:36 <Cale> sdrodge: Right -- depending on the amount of pain you want to take in making your programs time and space efficient, you might need to break through any abstraction barrier. Eventually you reach a point where it's no longer worth the trouble.
19:37 doomlord joined
19:37 <kuribas> for performance, you should look at bottlenecks first.
19:38 <sdrodge> Sure. I mean, I understand that premature optimization is bad, and that you should look where the actual bottlenecks are before optimizing.
19:38 <sdrodge> But at the same time, there are usually rule of thumb sane defaults to get reasonable performance that you should follow when writing.
19:38 <kuribas> sdrodge: premature optimization is ok when you know what you are doing :)
19:39 <sdrodge> I'm trying to figure out what those rules are w.r.t. strictness in Haskell, though.
19:40 ub joined
19:40 sobaken joined
19:40 <kuribas> sdrodge: in general, or with a particular library?
19:40 <sdrodge> Either, honestly.
19:41 <sdrodge> Like, if there's good rules of thumb with particular commonly used libraries or data structures, I'd love to hear it.
19:41 gabe4k joined
19:41 <kuribas> sdrodge: I made my datatypes in my numerical library strict, since it doesn't make sense to make them lazy.
19:42 <sdrodge> I tend to make all my data structures strict unless I have a specific reason not to.
19:42 <sdrodge> But that's the only strictness optimization that I tend to do.
19:42 tapirus joined
19:42 coderpath joined
19:42 pleax joined
19:42 <kuribas> there's also lazy Bytestring and strict Bytestring.
19:43 gcross_ joined
19:43 <kuribas> lazy Bytestring for streaming, strict for random access...
19:43 <sdrodge> For some reason, I find that one much easier to reason about.
19:43 <johnw> although, lazy ByteString is somewhat of an interface on top of strict ByteString
19:43 coderpath left
19:43 <johnw> Lazy.ByteString = [Strict.ByteString]
19:43 <kuribas> lazy bytestring is great
19:43 <sdrodge> except it's head strict, right?
19:44 <kuribas> sdrodge: I wouldn't worry about it, unless profiling or benchmarking shows lazyness is a problem.
19:44 markus1199 joined
19:45 <SexHendrix> muh stack overflows
19:45 calincru joined
19:46 Tesseraction joined
19:49 caumeslasal joined
19:49 sssilver joined
19:50 cereal_killer_ joined
19:50 curious_corn joined
19:52 b4ff3r joined
19:57 Itkovian joined
20:01 mattyw joined
20:02 stelleg1 joined
20:02 codesoup joined
20:03 mnislaih joined
20:03 <stelleg1> is there a way to load the extensions listed in a file along with the definitions?
20:03 fizruk joined
20:03 <stelleg1> gets tedious setting them all with :set -XBlah
20:04 <stelleg1> *in ghci
20:05 epsilonhalbe joined
20:06 <AndreasK> stelleg1: You can use a .ghci file
20:06 defaultnick_ joined
20:06 <JonReed> stelleg1: I don't think so. But there is .ghci file thaht can be used to load them automatically
20:06 <JonReed> stelleg1: https://downloads.haskell.org/~ghc/7.2.2/docs/html/users_guide/ghci-dot-files.html
20:06 <stelleg1> thanks
20:06 ragepandemic joined
20:07 merijn joined
20:08 conal joined
20:10 Itkovian joined
20:10 <JonReed> Can anybody provide me a working example of providing defaults in a lens way. How to make this `[42] ^? ix 0` to return not `Maybe Int` but `Int`. I know how to do this with Maps `Map.empty ^.at "key" . non 0`, but my brain can't process how to do it with lists
20:10 zero_byte joined
20:11 janos joined
20:11 esad joined
20:12 louispan joined
20:12 pleax joined
20:13 defaultnick___ joined
20:14 bjz joined
20:14 <tapirus> I'm trying to sort two lists in a way that's slightly different from lexicographic order. As an example, 'compare [LT,GT] [LT,GT,LT,...]' 'compare [LT,GT] [LT,GT,EQ,...]' and 'compare [LT,GT] [LT,GT,GT,...]' all return LT. I'd like them to return LT, EQ, and GT respectively. Is there any simple way of doing this?
20:15 <johnw> JonReed: Use ^?!
20:15 louispan joined
20:16 <JonReed> johnw: But how to provide default? This will error out instead
20:16 <JonReed> johnw: I want it to return default value if Nothing is encountered
20:17 <JonReed> I know how to do it non-lens way with fromMaybe 42 $ .. lens stuff here
20:17 <JonReed> but the lens way escapes me
20:18 <Profpatsch> Concerning the regex package (which was announced a bit ago)
20:18 <Profpatsch> Of course everybody wants to say she build the One True Solution
20:18 <supki> > [] ^?! (ix 0 `failing` like 42)
20:18 <lambdabot> 42
20:18 <Profpatsch> But isn’t it a bit presumptuous to just call the package `regex`
20:18 JuanMiguel joined
20:19 <Profpatsch> When all that came before used some suffix.
20:19 <muesli4> tapirus: So you only want to compare the minimal length? E.g. wrap it in a newtype whose Ord instance brings them to the same length and then compares them.
20:19 takle joined
20:19 <Profpatsch> Originally wanted to reply that to the announcement mail, but that ML is probably not for discussions.
20:19 <JonReed> supki: Thanks!
20:21 <muesli4> tapirus: Something like: compare (Shortedned xs) (Shortened ys) = (let { zs = zip xs ys ; xs' = fst <$> zs ; ys' = snd <$> ys } in compare xs' ys'
20:21 alexknvl joined
20:22 defaultnick___ joined
20:22 <SexHendrix> is there a way to do solids of revolution numerically
20:23 <SexHendrix> ive written a program that does integrals numerically given function and limits
20:23 <SexHendrix> can it do revolutions the same way?
20:23 <tapirus> muesli4: cheers, looking at this
20:23 KindOne joined
20:24 <johnw> Profpatsch: time to grab the "haskell" name, I guess
20:24 umib0zu joined
20:24 <Profpatsch> johnw: Go for it.
20:26 paolino joined
20:26 <Profpatsch> johnw: http://profpatsch.de/lulz/the_lulz.jpg
20:26 defaultnick___ joined
20:26 eschnett joined
20:26 afarmer joined
20:28 jle` joined
20:28 jle` joined
20:28 govg joined
20:28 esad joined
20:28 prohobo joined
20:28 noobie22 joined
20:29 prohobo left
20:30 <lpaste_> Noobie22 pasted “Easy question” at http://lpaste.net/353360
20:30 osa1 joined
20:30 osa1 joined
20:31 <lpaste_> Noobie22 revised “Easy question”: “Easy question” at http://lpaste.net/353360
20:31 janos joined
20:31 KindOne left
20:31 coltfred joined
20:31 afarmer_ joined
20:31 darjeeling_ joined
20:32 <jle`> noobie22: did you have a question? :)
20:34 phaji joined
20:34 fotonzade joined
20:34 <Profpatsch> “remains the best example of developing regular expressions at scale”
20:34 <Profpatsch> I’m scared now.
20:35 <Profpatsch> But it could be pretty handy for shell contexts.
20:36 phyrex1an joined
20:36 <AWizzArd> How would one typically represent a configuration in Haskell? data Config = { key1::Int, key2::[Float], …, keyN::SomeType } ?
20:36 <Tuplanolla> @hackage dry-run
20:36 <lambdabot> http://hackage.haskell.org/package/dry-run
20:36 <Tuplanolla> This would also be a great package name.
20:37 tomphp joined
20:37 <maerwald> AWizzArd: how's that question answerable. There's no such thing as a typical way of something like that
20:37 meoblast001 joined
20:38 schjetne joined
20:38 <AWizzArd> maerwald: well, I am thinking of Hashmap vs own data type, with a certain number of key/value pairs.
20:38 indi_ joined
20:38 <AWizzArd> Is access to fields of a data type with 84 fields efficient?
20:38 <maerwald> I think darcs does it
20:39 <Tuplanolla> You can split it up into smaller parts that tend to change together, AWizzArd.
20:40 <SexHendrix> > let lucky n | mod n 7 == 0 = "LUCKY" | otherwise = "out of luck"; lucky' n = lucky <$> [0..n] in lucky' 10
20:40 <lambdabot> ["LUCKY","out of luck","out of luck","out of luck","out of luck","out of luc...
20:41 esad joined
20:41 michael3 joined
20:42 balor joined
20:43 zdenal joined
20:43 albertus1 joined
20:43 afarmer joined
20:43 petervaro joined
20:45 janos joined
20:45 ragepandemic joined
20:45 venkat24 joined
20:46 <cdornan> Profpatsch: the idea with reflex is that it should become the goto API for regex-base, the defacto regex framework for these last 10 years, so it is logical at least
20:47 hamishmack joined
20:47 certainty joined
20:47 oisdk joined
20:47 andrei_chifa joined
20:47 <ezyang> "reflex" haha
20:48 chlong_ joined
20:49 <cdornan> How about turning that around -- could be good that there is a serious effort to produce a definitive regex package
20:50 <Cale> cdornan: Wait, someone is naming a regex-related package "reflex"?
20:50 <Cale> ~trademark issues~
20:50 <cdornan> ezyang: I have cut down deps on library and added escape functions
20:50 hazmat_ joined
20:50 tommd joined
20:50 <blackdog> that's gonna be kinda confusing
20:50 <cdornan> Noooo -- that was my autocorrector
20:51 <Cale> ah, good
20:51 <cdornan> Package is called "regex"
20:51 asmyers joined
20:51 esad joined
20:51 <geekosaur> someone fatfingered "refex" at a guess. they must be borrowing my fingers :p
20:52 <cdornan> Fat autocorrector!
20:52 <dolio> You need really fat fingers to hit l when trying to hit f.
20:52 <Cale> Well, the main reason that regex-base hadn't seen any love is because Haskell programmers mostly don't use regexes for anything
20:52 <maerwald> they should
20:52 <johnw> although, they probably would, if they were asy to use
20:52 <Cale> (apart from via other tools, like text editors and sed)
20:52 <geekosaur> neh, they typoed regex as refex and autoincorrect added the l to get a word
20:53 <johnw> spending 30 mins trying to figure out regexps in Haskell usually leads people to Parsec as a simpler alternative
20:53 <cdornan> I agree -- a mistake , as I say in my blog post
20:53 <Cale> I can imagine some use cases where you'd want *actual* regular expressions, for performance reasons
20:53 Copperis joined
20:53 <geekosaur> althogh re regex, see recent -cafe message
20:53 <Cale> (due to the ability to compile to DFAs)
20:53 <maerwald> Cale: no, for complexity reasons
20:53 <Cale> Yes
20:53 <maerwald> don't make your recognizer more complex than your input language
20:53 Noldorin joined
20:54 <maerwald> that's a security principle, not a performance thing
20:54 <geekosaur> I have snarked here about the Text.Regex interface being intended to push people as far away from regexes as possible
20:54 <Cale> Well, parser combinator based parsers aren't necessarily of higher complexity anyway
20:54 <johnw> I remember as a young Haskeller reaching for regexs, only to pull back a bloody stump
20:54 <maerwald> computationally yes
20:54 Rodya_ joined
20:54 <johnw> and the problem is, even when you've figured out the interface, they don't really get any easier to use
20:55 <Cale> Yeah, regex-base is terrible, and if someone really needs regular expressions, they should probably build something else.
20:55 <muesli4> tapirus: My solution was actually wrong, am I correct that you want something like this? http://codepad.org/xVRPCH2t
20:55 <ezyang> I don't understand why we don't just have regular expression combinators
20:55 <geekosaur> regex-applicative?
20:55 <ezyang> people complain all the time about regexes being unreadable
20:56 <ezyang> sure :)
20:56 <johnw> I like regex-applicative for building up complex regex expressions
20:56 <geekosaur> also, the counternark to Text.Regex is how often we get someone who first asks how to use it, then asks what regex they want...
20:56 <cdornan> Was just going to say regex-applicative
20:56 <johnw> so says ^e(dward)z\.?yang$
20:56 <geekosaur> which *ought* to be a hint that maybe reaching for regex is not the right answer
20:56 <maerwald> the demonization of regular expressions in the haskell community is a consequence of the fact that parser combinators are more elegant to do in haskell
20:57 <muesli4> tapirus: Basically, when the suffix stays below a reference value it is seen as lower (above -> higher, on the reference value -> equal).
20:57 <johnw> maerwald: regexs *should* be a strict subset of those combinators, that restricts what you can say in a way that results in even clearer error messages about what you might have done wrong
20:57 e14 joined
20:58 Aruro joined
20:58 <johnw> while the "foo" type regex strings are just an alternate syntax, so who cares about that anyway
20:58 <Cale> Everyone knows that the only acceptable place to use regular expressions is as part of sed expressions in your .nix build scripts to hack the export lists on people's modules when they didn't export shit that you need. ;)
20:58 defaultnick joined
20:58 <cdornan> All true but not having conventional high quality regex API is not good in my experience
20:58 <hexagoxel> no, the usual notation to express regular expression does not leave room to write comments. this is in contrast with haskell's philosophy of writing extensive documentation for all code.
20:58 <johnw> Cale: and in the Perl scripts I use to patch the results of Coq's unverified extractor, thus resulting in complete confidence
20:59 <Cale> lol
20:59 michael4 joined
20:59 <Cale> hexagoxel: lol
20:59 <Aruro> are there many commercial standalone haskell apps ? beside hledger and haskell studio for mac ?
20:59 <maerwald> johnw: I don't understand. error messages in parser combinators are rarely clear
21:00 <Cale> Aruro: Do they also have to be open source?
21:00 <maerwald> ofc, depends on the library
21:00 <johnw> maerwald: that exactly my point; they are less clear the more general the combinators
21:00 <Aruro> Cale: no, just haskell
21:00 indi_ joined
21:00 <Aruro> only requirement it has to be an "app" not "We are doing consulting"
21:00 <ezyang> to me, the bigger problem with string regexes is lack of compositionality
21:00 <Cale> Aruro: Well, we build web applications for various clients entirely in Haskell.
21:01 <Cale> (and, more recently, mobile versions of those)
21:01 <maerwald> johnw: well, my point is rather the computational complexity of the recognizer. Choose the minimal complexity, not just for the input language, but also for the recognizer (if it can properly _detect_ it). Mitigating SQL injection with regexes is plain wrong
21:01 <Aruro> so apart from hledger and mac studio there are no haskell made apps? excluding industry internals.
21:01 <cdornan> ezyang: agreed -- one reason for adding macros and testbench to regex
21:01 <johnw> or how about writing RFC822 e-mail parsers
21:01 <Cale> Aruro: There are a bunch of industrial users of Haskell who have closed source apps.
21:01 <dolio> There are a bunch of problems with string regexes.
21:02 <Cale> Aruro: Well, there are a bunch of other open source things, but those I thought were more obvious.
21:02 indi_ joined
21:02 <Cale> Pandoc, XMonad
21:02 <Aruro> Cale: so haskell economics is all about internal interbuiseness solutions?
21:02 <Aruro> why not making apps?
21:03 <Cale> Like, what kind of apps?
21:03 takle joined
21:03 <Aruro> which people can buy. like paragon for example
21:03 defaultnick_ joined
21:03 <Cale> Most money is in web development these days
21:03 <blackdog> do you mean SaaS stuff?
21:03 <johnw> the best feature of regexs is how much they can liven up any IRC channel
21:03 <johnw> Cale: you'd think the Web would have been fully developed by now
21:03 <Cale> haha
21:03 <blackdog> johnw: think growth as in cancer
21:03 <Cale> Well, we're working on it
21:04 snowalpaca joined
21:04 <Aruro> like even commercial modeling software, or even SaaS buiseness applications
21:04 <Cale> Hopefully we can get things to a place where it's not such a big effort
21:04 <blackdog> Aruro: sure. betterteam.com is in haskell.
21:04 <blackdog> the point is, you wouldn't know unless somebody told you.
21:04 snowalpaca joined
21:05 <Aruro> i mean what stops developers to use haskell for end user programs?
21:05 <Aruro> excluding - cloud,services and such
21:05 <Xe> Aruro: managers
21:05 <Cale> Aruro: Almost nobody sells those at all?
21:05 <Aruro> why? i bout ntfs driver for mac from paragon, seems ok.
21:05 <Aruro> bought*
21:05 epsilonhalbe joined
21:06 indi_ joined
21:06 <Cale> I guess on Mac, there are some things which inexplicably cost money but which would ordinarily be part of your OS
21:06 <Aruro> i mean i would support good haskell developer of something nice
21:06 <blackdog> Aruro: nothing, really. i guess there isn't a clear winner in terms of writing graphical interfaces?
21:06 defaultnick_ joined
21:06 <geekosaur> r/o ntfs driver is built in, later releases have a hidden partial r/w support option
21:07 <blackdog> it's just way easier to make money by putting your code on a server, rather than dealing with licensing etc.
21:07 sssilver joined
21:07 <Aruro> so licensing is one of the issues?
21:08 <dolio> It's an issue with writing software.
21:08 <geekosaur> this isn;t so inexplicable because r/w ntfs info used to require microsoft nda. linux emulated it via an ugly hack (which basically meant do stuff and let ntfs journaling sort it out on the next windows boot. yes, this worked about as well as you could expect)
21:09 <kuribas> blackdog: GUI's support isn't the best in haskell.
21:09 FullyFunctional joined
21:10 <ongy> I'd say the haskell ecosystem makes it annoying to distribute licensed software, since dependencies have licenses all over the place and nobody cares
21:10 gabe4k joined
21:10 <Aruro> take alphasheets, their task is perfect for an app, but it will be webservice ? they do have some haskell coding there
21:10 <kuribas> ongy: most haskell libraries are BSD.
21:10 <ongy> I have seen a package (some library bindings) that has a conflicting license to the library. Which the author explicitly states
21:11 <maerwald> unfortunately
21:11 <ongy> kuribas: except for the (l)gpl ones
21:11 <Cale> ongy: Which package?
21:11 <ongy> I don't remember which one. I don't think I ended up using it
21:11 <Cale> Note that you can distribute BSD bindings to a GPL library, so long as you don't distribute the GPLed library with it.
21:11 <dolio> The majority of programmers don't care about licenses, regardless of which language they use.
21:11 <maerwald> people just seem to use what random thing "cabal init" suggests (which is BSD-3 afair)
21:11 <maerwald> and that's a pity
21:12 <Theophane> `stack legal` could be very useful ;)
21:12 <ongy> Cale: it was something like this. But it's a bit more annoying if someone intended to distribute it the usual windows way with libraries included
21:12 <Cale> Whatever you're making bindings to might as well be proprietary from your perspective if you're not distributing the code.
21:12 <Theophane> (or `cabal legal`)
21:12 <Cale> ongy: That's true.
21:12 <kuribas> ongy: how is that different from any other language?
21:13 <Xe> kuribas: unlike php you don't need to dencrypt your source code at runtime
21:13 <Xe> (such monsters do exist in this world)
21:13 <ongy> kuribas: I have seen *less* of that in the C(++) ecosystem. But maybe I just cared less
21:13 meoblast001 joined
21:14 <ongy> it's not language specific, but I feel like nobody cares. because for the main usecase (user downloads from hackage/stackage and builds/links themself) it doesn't matter
21:14 <jle`> huh didn't realize that hackagebot has been gone for over three months now
21:14 <jle`> i'll miss that little bot
21:14 <jle`> rest in peace hackagebot
21:14 <ongy> but if someone wanted to use it commercially and distribute binaries with *batteries included* (or for windows) things get hairy
21:14 janos joined
21:14 <maerwald> why?
21:15 <Aruro> even for support scheme? like donate and spport me?
21:15 <maerwald> ongy: why would that be a problem?
21:15 <Cale> Well, ongy has a point -- the fact that you can't figure out from the license on the Haskell binding what to do about the library it's a binding to might be a bit annoying if you have a ton of dependencies to go through.
21:16 <Cale> But I dunno, packaging stuff for Windows already seems like a pain.
21:16 <Aruro> linux users have money too
21:16 <Aruro> :)
21:16 <Aruro> question is where is haskell monetization ecosystem? even in form of donations
21:17 <Cale> It comes from various startups and other companies who pay us to build reliable software
21:17 <blackdog> kuribas: yeah, that's what i meant - we haven't concentrated behind a single framework or approach, so no single codebase gets the work.
21:17 curious_corn joined
21:17 roconnor joined
21:18 <blackdog> (which isn't a criticism, it's just not obvious what the best way forward is, and bluntly without a large base of people writing gui software nobody's that interested)
21:18 <kuribas> blackdog: I think it's more of a lack of interest in GUI code in general.
21:18 <ongy> maerwald: I have no example, but if there was a package that depended on another one and they have incompatible licenses, distributing binaries wouldn't be possible to my understanding
21:18 rperry joined
21:18 Jacoby6000 joined
21:18 <blackdog> Aruro: i tend to think the easiest path is just writing fast, safe web apps.
21:18 <maerwald> ongy: probably, I just didn't understand what "commercially" has to do with that
21:18 erewok joined
21:19 moth joined
21:19 <ongy> maerwald: most others don't give a damn, or just put it on hackage aswell and don't distribute binaries
21:19 <kuribas> blackdog: maybe because people think pure functional isn't a good much for the imperative nature of GUIs?
21:19 <ongy> blackdog: I think you can drop both fast and safe there....
21:20 <ongy> Aruro: I don't think there's any monetization options on hackage (or anywhere) maybe some people have donation buttons on their project websites
21:20 <Aruro> yeah, hledger has, would be interesting to hear his feedback
21:20 <ongy> if I ever get a userbase that's bigger than the people I know, I may put something up aswell
21:21 guampa joined
21:21 mda1 joined
21:21 <blackdog> ongy: why?
21:21 <blackdog> i mean, just by default you're going to have faster safer code than your average rubyist.
21:22 <blackdog> (i know this because i am a very average rubyist)
21:22 <ongy> have you seen the web? I doesn't look like safe and fast are a requirement these days. It's good to have, but...
21:22 <ystael> ongy: distinguish "requirement for running a business" from "requirement for making something you would actually want to work on" :)
21:22 <ongy> oh and I'm mixing safe and secure again. But still applies even for safe
21:23 <ongy> ystael: The starting question was about the money :)
21:23 <ystael> oh, yes, I see
21:23 <Aruro> about economy of haskell codebase
21:23 <Aruro> money support/motivation
21:24 <Aruro> hledger is not distributed on windows, so windows pain seems real.
21:25 <maerwald> it's ok to not support windows
21:25 <maerwald> it's an unethical operating system, taking away pretty much all user freedoms
21:25 <ongy> for GHC there's a few people that are payed by companies. Microsoft research for example
21:25 <ystael> Is it OK to advertise jobs in here?
21:26 insitu joined
21:27 <ongy> people do from time to time. But IRC may not be the best platform to do so (volatile, and with a fast-ish channel like this not many people will see it)
21:28 <ezyang> cdornan: You mispelled regex as reflex on Reddit too :P
21:29 meoblast001 joined
21:30 <cdornan> ezyang: Corrected -- thanks!
21:30 Luke joined
21:30 mizu_no_oto_work joined
21:31 mszczygiel joined
21:31 <tapirus> muesli4: thanks yeah, this looks like what I was looking for :) thanks!
21:33 defaultnick___ joined
21:33 Jesin joined
21:35 randomclown joined
21:36 machinedgod joined
21:37 indi_ joined
21:37 Ariakenom joined
21:38 mkoenig joined
21:39 augur joined
21:41 <tapirus> why does compare [EQ] (repeat EQ) return LT?
21:41 <jle`> > "hi" < "hill"
21:41 <lambdabot> True
21:41 <jle`> it's dictionary ordering
21:41 <jle`> would "hi" or "hill" come first in a dictionary?
21:41 <blackdog> i guess that's the same question as compare [] (repeat EQ), really.
21:41 <tapirus> hmm
21:42 <blackdog> wait, jle` 's explanation is better, ignore me
21:42 <tapirus> I guess intuitvely I expected it to behave as zipWith (compare) [EQ] (repeat EQ)
21:42 Koterpillar joined
21:42 <glguy> jle`: How heavy do you suppose this dictionary containing infinitely long words would be?
21:42 <jle`> so it should return an [Ordering] ?
21:42 <tapirus> but yeah, I get jle`s's explanation
21:42 permagreen joined
21:42 <jle`> :t compare
21:42 <lambdabot> Ord a => a -> a -> Ordering
21:42 <monochrom> Intuition is fantasy.
21:42 <jle`> compare returns an Ordering, not an 'a'
21:43 ramzifu joined
21:44 <jle`> tapirus: what would you have expected the answer to be?
21:44 Ariakenom joined
21:45 <nitrix> Can someone with a reasonable understanding of decision trees (used as classifiers) kind of breif me on the minimal operations (decisions) the tree needs to support to perform its classification work?
21:46 gabe4k joined
21:46 <nitrix> The inputs are doubles in the range [0, 1]. I'm guessing X > Y and X * Y > Z ?
21:46 cyborg-one joined
21:46 <nitrix> Is this the most minimal?
21:46 Lord_of_Life joined
21:47 sleblanc joined
21:47 augur joined
21:48 <nitrix> Actually X * Y > Z makes no sense, unless I don't have a tree with a single root, but a directed graph instead.
21:48 <jle`> what are you calling X, Y, and Z here?
21:48 <tapirus> jle`: yeah sorry, I just wrote that zipWith statement but that's not what I really meant...I get the right answer now, but for a moment, I was expecting that if I took some arbitrary array, say x, and compared it with (repeat n), then the result would be the same as (compare x (replicate (length x) y)
21:49 <nitrix> This is starting to look like a neural network. Let me think a little and ask a better question.
21:49 <jle`> tapirus: ah
21:49 <jle`> tapirus: how would you even implement that?
21:49 conal joined
21:50 <jle`> you can't test if a list was created with 'repeat' or not
21:50 JeanCarloMachado joined
21:50 sea_wulf joined
21:51 Javran joined
21:52 hiratara joined
21:53 Javran joined
21:54 augur joined
21:55 Javran joined
21:58 gabe4k joined
21:59 anuxivm joined
22:00 CurryWurst joined
22:01 OmnipotentEntity joined
22:04 bjz joined
22:05 bigos joined
22:06 mkoenig joined
22:06 nomotif joined
22:07 t0by joined
22:07 t0by joined
22:08 jmcarthur joined
22:08 ertes joined
22:10 rperry joined
22:12 silver_ joined
22:13 darjeeling_ joined
22:13 Itkovian joined
22:14 Micamo joined
22:16 e14 joined
22:16 danthemy_ joined
22:17 fotonzade joined
22:18 tag joined
22:18 Boomerang joined
22:19 quchen joined
22:22 FullyFunctional left
22:22 <* monochrom> is tempted to reply in haskell-cafe "No, this is an abuse of programs. Programs are not wrong, humans are."
22:23 conal_ joined
22:24 cschneid_ joined
22:25 cereal_killer_ joined
22:25 <kuribas> > let (+) = (-) in 1 + 1
22:25 <lambdabot> 0
22:25 sellout- joined
22:26 <glguy> monochrom: Which thread?
22:27 <monochrom> To [] or not to []
22:27 <Ariakenom> > let (+) = (*) in 2+2
22:27 <lambdabot> 4
22:28 <monochrom> So the original poster wrote statement of the form "if you use list for <a purpose that list is bad at>, your program is wrong"
22:28 <monochrom> And I think "your program is wrong" is a hyperbole and we should take it as such, rather than arguing semantics.
22:28 <maerwald> you're deliberately misinterpreting what he said I think
22:29 <monochrom> But Richard O'Keefe did decide to argue semantics. "This is an abuse of the word 'wrong'"
22:29 <maerwald> but I realize this sort of nitpicking is very characteristic to the haskell community
22:30 <maerwald> and ofc can be fun at times
22:30 <monochrom> maerwald, I did not nitpick, O'Keefe did.
22:30 <monochrom> Or rather, since O'Keefe felt like nitpicking, I would nitpick the nitpicker.
22:30 <maerwald> xD
22:31 hiratara joined
22:32 <jmcarthur> Is this metanitpicking?
22:32 <maerwald> haha
22:32 snowalpaca joined
22:33 <monochrom> No, this is reductio ad absurdum
22:34 connrs joined
22:36 zcourts joined
22:37 deepfire joined
22:37 koneko joined
22:39 kmelva joined
22:39 rajiv1 joined
22:39 <kuribas> we call it fucking ants
22:39 NeverDie joined
22:40 <kuribas> mierenneuken
22:40 louispan joined
22:40 jutaro joined
22:44 erewok left
22:44 buttbutter joined
22:44 Voldenet joined
22:44 Voldenet joined
22:45 <* kuribas> wishes haskell had better debuggers
22:47 balor joined
22:47 ilja_kuklic joined
22:48 sid_fules joined
22:49 Denthir joined
22:49 <frontendloader> kuribas: "The compiler is your debugger" - #haskell
22:49 <kuribas> it sucks
22:50 <ezyang> invest in your logging infra
22:50 <kuribas> I have a long list of data representing bezier curves, it's giving me a headache...
22:50 <monochrom> frontendloader, I have seen in the past few days that kuribas's debugging need exceeds what type-checking can do.
22:51 <frontendloader> I agree with him, being able to step through/inspect code is how I learn/progress primarily
22:51 janos joined
22:52 <benzrf> i debug using the repl
22:52 <kuribas> monochrom: yeah, it's numerical code.
22:53 <kuribas> monochrom: on the other hand I am abusing Data.Set, so it may be my fault...
22:53 balor joined
22:53 <monochrom> I can't imagine how Data.Set could possibly be abused...
22:53 janos joined
22:53 <kuribas> monochrom: I have an ordering of curves, which implies they don't touch.
22:54 <kuribas> monochrom: so I am using Data.Set as a binary tree
22:55 <kuribas> maybe debugging numerical code is just hard in general...
22:55 <monochrom> Ah, maybe you don't really have a total order. Yeah that could be abuse, but still not always.
22:56 <kuribas> monochrom: it's total as long as the invariant holds.
22:56 seangrove joined
22:57 <monochrom> Hmm. Debug the invariant? :)
22:57 <kuribas> yeah, I have many assertions now
22:58 Tesseraction joined
22:58 <`Guest03> how to poke an array efficiently?
22:59 <`Guest03> array comes from a list
22:59 <`Guest03> so, poke a list
22:59 <`Guest03> into adjacent locations as array
22:59 <monochrom> There is no efficient way for lists. Use a real array.
22:59 <`Guest03> oh, a question i wanted to ask
23:00 sellout- joined
23:00 <`Guest03> if i write: arr = ByteString.pack [0, 1, 2, 3, 4]
23:00 <monochrom> Most array libraries have a "fromList" function or such for dumping a list into an array.
23:00 <`Guest03> as top-level definition
23:00 <`Guest03> what will it do at compile time and runtime?
23:01 <monochrom> Compile time will preserve that expression. Run time will do the conversion at most once, then memoize.
23:01 P1RATEZ joined
23:01 <`Guest03> monochrom: can i get it to convert it at compile time without TemplateHaskell?
23:02 <monochrom> No.
23:02 <`Guest03> i want that
23:02 <monochrom> Yes. Write a GHC plugin.
23:02 <kuribas> doesn't ghc unroll short expressions?
23:02 <monochrom> 5 hours of template haskell can be saved by 5 months of GHC plugin.
23:02 manlet joined
23:03 <monochrom> FSVO "short"
23:03 sellout-1 joined
23:03 <monochrom> Pretty sure "x :: Int; x = 1+1" is compile-time simplified.
23:03 janos joined
23:03 <`Guest03> can we have it in future
23:03 <AWizzArd> System.Random.MWC – is it possible to use this to select a random item out of a list?
23:04 <kuribas> monochrom: because it's an arithmetic primitive...
23:04 <monochrom> I don't know the future.
23:04 <maerwald> I do, but only if you pay me...
23:04 ziocroc2 joined
23:05 defaultnick__ joined
23:05 <glguy> and when we don't the future is a blur to you?
23:05 <maerwald> exactly
23:05 Luke_ joined
23:07 <`Guest03> monochrom: i want to have a Ptr to an array of hardcoded data
23:07 <`Guest03> what is best way?
23:07 allenj12 joined
23:07 isenmann joined
23:07 mtncoder joined
23:07 <monochrom> I don't know. GHC.Prim may or may not help.
23:08 kvda joined
23:08 <glguy> Data.ByteString.Char8.pack "the bytestring"
23:08 jmcarthur joined
23:09 <monochrom> Is the rest of your program so highly optimized that the only thing left to do is optimizing initialization?
23:09 BlueRavenGT joined
23:09 louispan joined
23:09 janos joined
23:10 uglyfigurine joined
23:10 <`Guest03> monochrom: i don't care, i consider deferring conversion to runtime ugly
23:10 mbw joined
23:10 <`Guest03> i want to not have ugly things in my program
23:11 <monochrom> I think we talked about this before.
23:11 leafgreen joined
23:11 <glguy> You can put the data in a .c file and import that via the FFI
23:11 hololeap joined
23:11 Javran joined
23:12 <leafgreen> I have a question about the syntax of module. Why is it that the whole .hs file doesn't have to be indented with respect to the "module" lines at the beginning?
23:12 <glguy> I'd be a waste
23:12 <glguy> (but you can do it)
23:12 <glguy> it'd*
23:12 <glguy> I might be, too
23:12 <leafgreen> Is it just a special case in the parsing rule?
23:12 B4tMaN joined
23:12 <leafgreen> since it is still using a "where" typically
23:13 <monochrom> This is not a special case.
23:13 <glguy> the parsing rules for module aren't really a special case, just a case
23:13 <monochrom> There is, actually, no rule saying "after 'where' you must indent"
23:13 tomboy64 joined
23:13 <mbw> Hello everybody. I had to write a property test for my program, using hspec/QuickCheck. Luckily, I seem to have found the error immediately. I have a property prop_inequal :: SomeType -> Bool, which internally creates all the values that the argument should NOT compare equal to. So this test indeed failed. However, only the argument that triggered the failure is printed, and I do not know which other value
23:14 <mbw> it unexpectedly compared equal to. I presume my property should either be of a different type, or there should be some fancy verbose flag. Does anybody know about this?
23:14 <Tuplanolla> Use `===`, mbw.
23:14 <mbw> I'll try that.
23:14 <monochrom> The real rule is only of relative indentation. If you are comparing two scopes, then the inner scope needs to be more indented than the outer scope.
23:14 zero_byte joined
23:14 <dmj`> :t verboseCheck
23:14 <lambdabot> Test.QuickCheck.Property.Testable prop => prop -> IO ()
23:15 <monochrom> But the top level has no even-more-outer thing to compare to.
23:15 <leafgreen> I see, monochrom
23:15 <monochrom> In fact, " module F where" "x = True" works just fine.
23:16 <`Guest03> hmm
23:16 <`Guest03> one function withArray solves my problem perfectly.
23:16 ddere joined
23:16 sleblanc joined
23:16 <mbw> Tuplanolla: It has to work on lists, i.e. it should replace prop g = all (== g) valids, and prop' g = g `notElem` invalids, respectively.
23:17 ilja_kuklic joined
23:17 <`Guest03> except
23:17 <`Guest03> length
23:17 <`Guest03> withArrayLen
23:17 certainty joined
23:18 <`Guest03> except the length is in elements, not bytes...
23:20 <mbw> I'm sure I'll find the other fancy operators once I'm done accidentally building the haddock documentation...
23:20 alexknvl joined
23:22 <ezyang> Suppose that you can either define a helper function in a where clause, or top level. Which do you prefer? how do you decide?
23:23 doomlord joined
23:23 steeze joined
23:24 <`Guest03> ezyang: where clause
23:24 <`Guest03> except if it would be used by more than one function
23:24 <glguy> Inside is nice if I want to be able to use a few other where-claused defined things all of which share common values and/or access to the arguments of the parent
23:24 epsilonhalbe left
23:24 k0001_ joined
23:24 <glguy> outside the where clause otherwise so I can test it out independently from GHCi
23:24 <monochrom> Top level for the first few months (for easier testing and debugging). Then inner.
23:26 <ezyang> Quite a variation of responses! :O
23:26 <glguy> visibility can be managed by export lists, if the module gets too big I can make a new module
23:26 <monochrom> Then outer again because I am explaining it to someone else and I want to demo it. Then inner again.
23:26 <monochrom> This flipflopping continues indefinitely.
23:26 <ezyang> Sometimes I feel like if you put it in a where clause, you often have free variables that you shouldn't
23:26 Rizy joined
23:27 <glguy> having those free variables is why you'd put it in a where clause in the first place :) that seems like a contradiction
23:27 <monochrom> That kind of thinking will get you into the trouble of combinatory logic.
23:27 <ezyang> well, maybe it's just one or two new parameters
23:27 <ezyang> and the top level brings, like 10 names into scope
23:30 Jesin joined
23:30 tromp joined
23:30 Varis joined
23:31 ExcelTronic joined
23:32 <mbw> Ok I found out that I can do something like prop g = conjoin $ (=== g) <$> valids. However, I don't see an analogous inequality operator. How would I express that?
23:33 defaultnick__ joined
23:33 augur joined
23:33 <`Guest03> i'm pleasantly surprised with highlevelness of some binding libraries
23:33 <michalrus> Hey! Quick (silly?) question: I have a list of functions, say, [a -> Maybe b], but I would also want each of them to have access to its own state — each state being of different type, unknown/transparent to the call site using this list. What would be the best way to approach this?
23:34 <glguy> What's state?
23:34 <`Guest03> you could think it would have ugly low-level types which need conversion every time, but no
23:34 <monochrom> There is no "state".
23:34 <`Guest03> not all types are high-level, but most are
23:34 <jle`> michalrus: well, each function can have its own closure
23:35 <`Guest03> shaderSource :: Shader -> StateVar [String] -- how cool, native strings.
23:35 <jle`> but by state, do you mean some sort of environment?
23:35 Textmode joined
23:35 <michalrus> Yes, yes, I’m aware of that. :) Let’s say the signature is [s -> a -> (s, Maybe b)], and state is s.
23:35 <jle`> for addN n = (\x -> x + n), n is a part of the colsure/'state' of 'addN 10'
23:35 <michalrus> How can I have different s for each function?
23:36 sellout- joined
23:36 <jle`> michalrus: what are you planning on doing with this list?
23:36 <`Guest03> michalrus: existential quantification
23:36 <glguy> michalrus: You can have: data T a b = MkT (a -> (Maybe b, a -> T a b))
23:36 <jle`> michalrus: how would you even interact with each type?
23:37 <jle`> er, with each function
23:37 umib0zu left
23:37 <jle`> if the state type is opaque, how would you get a state to give each function?
23:37 <glguy> or rather: data T a b = MkT (a -> (b, a -> T a b)) -- If you want b to be Maybe Something, that's fine
23:37 <michalrus> jle`: I want to run each function until one matches and returns a Just b, and return this (potentially) matched Maybe b.
23:37 <jle`> michalrus: but how can you run the function without giving an 's'
23:37 <michalrus> Nice, thank you for all the replies, I know what to google/hoogle now! (:
23:38 ludat joined
23:38 <jle`> if the functions are (s -> a -> (s, Maybe b)), and you want to 'run' it while only having an 'a', where do you get the 's' from?
23:38 <michalrus> jle`: the state would have to be somehow kept in the call site, yes…
23:38 <jle`> if the state is opaque to the call-site, then the state cannot be kept at the call site
23:38 <michalrus> :(
23:38 Gurkenglas_ joined
23:38 <jle`> what you can do is "store" an initial state with every function
23:38 <glguy> michalrus: No need to Google, I already wrote the type that does that
23:39 <jle`> but that's basically the same thing as my 'addN' example up there
23:39 <michalrus> glguy: I’ll read about MkT, thank you. 🙇
23:39 <jle`> useBoolState b = (\x -> if b then x else negate x)
23:40 <jle`> useIntState n = (\x -> x + n)
23:40 <glguy> michalrus: No, there's nothing to read. MkT is being defined on that line
23:40 <michalrus> Ah!
23:40 <kuribas> michalrus: each function in the list updates the state?
23:40 <jle`> you can now store `useBoolState True` and `useIntState 10` inside the same list
23:40 <michalrus> kuribas: yes.
23:41 <glguy> michalrus: Do all the functions share the same 's' value? does the output of one become the input of another?
23:41 <michalrus> No, they’re completely separate.
23:41 <jle`> :t let useBoolState b = (\x -> if b then x else negate x); useIntState n = (\x -> x + n) in [useBoolState True, useIntState 10]
23:41 <lambdabot> Num a => [a -> a]
23:41 <jle`> i've stored functions with different types in their closures in the same list, there
23:42 <jle`> (it's also not clear what you want to do with the 's' in the result of each function)
23:42 <jle`> what's the bigger problem you want to solve here?
23:42 <michalrus> jle`: store it somehow, for future calls of that particular function. (:
23:42 <jle`> this sounds like it might be a clear XY problem kind of situation
23:43 <michalrus> Haha, OK. I’ll explain it more widely.
23:43 defaultnick_ joined
23:44 <jle`> there's something you might be able to do with the 'auto' library that might let you do exactly what you described, but i'm not sure if you really want what you're asking for
23:45 <jle`> but the `Auto' a b` type represents an `(s -> a -> (b, s))` function paired with an initial state 's'
23:45 <jle`> that's opaque to the caller
23:45 <jle`> and you can "run" it to get the resulting 'b', and also a new Auto with an updated state
23:45 dedgrant joined
23:46 <jle`> (it's also Mealy from the machines library)
23:47 <jle`> so your type might be runAllAutos :: a -> [Auto' a b] -> ([b], [Auto' a b]) -- the Auto's in the resulting list have the updated states
23:48 <ezyang> Flipping between [] and Maybe is surprisingly annoying
23:50 <michalrus> jle`: Bigger picture: I’ve got some `source :: IO Text` of, say, commands. Now, I want to have different handlers for these commands defined as `Text -> IO (Maybe SomeResult)`. If a handler returns Nothing, it means that the next handler should be used. If Just, just return that result. But I’d also want each handler to have access to its state that it can read and modify between calls. Now, since it’s
23:50 <michalrus> all happening in IO, I could probably store the state somewhere in IO, but there should be a better way…
23:50 <jle`> michalrus: if ti's all happening in IO then it's probably simplest to just have an IORef in the closure of the function
23:51 <michalrus> Call site has source, list of handlers and is supposed to return IO (Maybe SomeResult).
23:51 <michalrus> Yeah, but what if it wasn’t? (:
23:51 <jle`> if you're stuck with the idea of "state", then each call has to return a new list of functions
23:51 <glguy> ezyang: That reminds me that you can switch between Maybe and [] nicely in list comprehensions (with enough extensions), e.g. [ x | x <- [1..10], odd x, then listToMaybe, x > 3]
23:52 <jle`> and you would run the query on that new list every time
23:52 <jle`> the new list of functions would have the updated states in their closures
23:52 <jle`> libraries like 'auto'/'machines' make it a little more easy to implement state-updating closures like this, but there's no way getting around returning a new list every time you run it
23:53 <jle`> (if you're sticking with "pure" queries/handlers)
23:53 <glguy> also, libraries like auto and machines are not the place to start when getting stuck on questions like this
23:53 <ezyang> glguy: Hmm
23:53 bjz joined
23:54 <jle`> if you're already in IO then you can just have the IORef in the closure to the function, and you have an easy solution
23:54 <michalrus> Mhm. :) OK, thank you, all. I’ll read carefully through the log once more.
23:54 <ezyang> I don't really want to bust out comprehensions though, because the code is pointless
23:54 <Zemyla> You know, I think I have figured out the contravariant equivalent of Monad.join.
23:54 <jle`> but yeah, if you're not in IO, you have to be able to create closure-updating functions and return new functions every time you run them
23:55 <jle`> you can create them from scratch using lambda abstractions (they're not that hard), but there are libraries that make it simpler, yes.
23:55 <lyxia> Zemyla: what is it
23:55 mattyw joined
23:56 <jle`> data MyHiddenState a b = forall s. MkHS s (s -> a -> (b, s))
23:56 <Zemyla> lyxia: contrajoin :: f (f (f a)) -> f a
23:57 <jle`> runMyHiddenState x (MkHS s0 f) = let (y, s') = f s0 x in (y, MkHS s' f)
23:57 <jle`> runMyHiddenState :: a -> MyHiddenState a b -> (b, MyHiddenState a b)
23:58 <jle`> the type of the state isn't in the type of MyHiddenState, so you can store MyHiddenState's of different internal state types in the same list
23:58 wtetzner joined
23:59 justanotheruser joined
23:59 <Zemyla> It's basically triple negation elimination.
23:59 replay joined