<     May 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 24 _2_5 26 27  
28 29 30 31
00:00 <wizwizwizwiz> well,... in my case failure isn't really an option :/
00:00 <wizwizwizwiz> lost data isn't cool
00:00 Dance joined
00:00 <monochrom> You can code up your own retry.
00:00 <koala_man> there's no lost data. though if you spent those four hours making promises you can't keep, that's your business and not the DB's fault
00:01 <monochrom> Not so much lost data as lost opportunity.
00:01 infinity0 joined
00:01 <wizwizwizwiz> ... i'm also having weird troubles with foreign keys in mysql
00:01 thunderrd_ joined
00:02 <wizwizwizwiz> i don't remember the details clearly enough to ask about them but
00:02 <wizwizwizwiz> i've had two tables with identical foreign key entries
00:02 exarkun joined
00:02 <wizwizwizwiz> one has no issue, the other complains endlessly
00:02 <wizwizwizwiz> i've even copy/pasted the foreign key definitions
00:02 <monochrom> Like maybe there is a cash prize for "get your mark accepted before noon for a chance to win $10" but your transaction keeps failing before a hundred other people are also doing it.
00:02 <wizwizwizwiz> and that's also with the tables blank,...
00:02 <wizwizwizwiz> haha
00:03 tromp joined
00:04 infinity0 joined
00:04 e14 joined
00:04 <wizwizwizwiz> what about the "ORM redundancy" issue?
00:05 jedws joined
00:06 <wizwizwizwiz> i have to define my tables/types in sql
00:06 <wizwizwizwiz> and then re-define them in my code (in this case, python)
00:07 infinity0 joined
00:08 eacameron joined
00:08 sproingie joined
00:08 sproingie joined
00:09 conal joined
00:09 infinity0 joined
00:10 jer1 joined
00:11 louispan joined
00:12 ContessaTP joined
00:12 infinity0 joined
00:14 darlan joined
00:14 MP2E joined
00:15 justanotheruser joined
00:15 sdothum joined
00:16 ddere joined
00:18 alx741_ joined
00:19 <robkennedy> ericso: sorry for late follow up. I think I'm looking for Template Haskell.
00:20 torstein joined
00:20 <erisco> robkennedy, you can write a quasi-quoter and employ a library such as Parsec. If the parse fails you throw an error in the QQ and the compilation will fail with the error message
00:21 <erisco> robkennedy, I used this to implement regex strings
00:23 romank joined
00:23 matthewbauer joined
00:23 <erisco> robkennedy, this may help you as a reference https://github.com/erisco/regex-tdfa-quasiquoter
00:23 plutoniix joined
00:26 mjora7 joined
00:28 michaelw joined
00:28 roconnor_ joined
00:30 shayan_ joined
00:30 mbo_ joined
00:31 sdothum joined
00:31 jer1 joined
00:32 nighty-- joined
00:32 filterfish joined
00:32 darjeeling_ joined
00:34 Big_G joined
00:34 andyhuzhill joined
00:40 mattn joined
00:41 justkkay joined
00:42 <justkkay> When we search inside a hash table, how do we find a value that was moved due to collisions using linear probing?
00:42 beerdrop joined
00:43 ljhms joined
00:43 <erisco> been a few years... but as I remember it you just keep traversing forward (and roll over when necessary)
00:44 <erisco> so the first collision goes in the slot after, and the second in the second slot after, and so on
00:44 <justkkay> hmm, so I'm guessing we start with the hash value as a base, then move forward until we find it ?
00:44 <erisco> that's right
00:45 <erisco> "linear probing searches the table for the closest following free location and inserts the new key there" https://en.wikipedia.org/wiki/Linear_probing
00:46 <mniip> ListT IO is lawful, right?
00:46 <mattn> we (EvanR, dmwit) had a discussion last night about why only certain types (and newtypes of those) can be marshalled via the FFI. For my project, I wanted to be able to marshal more general types, such as “data EA = BadEA | EA Word64”, where BadEA is represented on the FFI side by a magic number.
00:46 <jle`> mniip: well
00:46 mizu_no_oto joined
00:46 <mattn> stemming from that conversation, I added a typeclass for marshalling values to and from the FFI to my code
00:47 fosterite joined
00:47 <mattn> would it be worthwhile to split that out into a small package?
00:47 <erisco> hashes aren't so functional though, last I knew
00:48 <erisco> moreso an exploit of the memory addressing hardware
00:50 matthewbauer joined
00:52 jer1 joined
00:52 safe joined
00:53 cschneid_ joined
00:53 amitoj joined
00:53 wizwizwizwiz joined
00:53 juhp joined
00:54 <wizwizwizwiz> so is there a way to do away with ORMs?
00:54 cioran89 joined
00:54 <johnw> wizwizwizwiz: we just all have to stop using them
00:54 amitoj joined
00:54 <wizwizwizwiz> what is the alternative?
00:54 <johnw> they'll get the hint if we do that
00:54 jaziz joined
00:54 Zekka joined
00:55 etehtsea joined
00:56 jaziz joined
00:57 eacameron joined
00:58 matuszak joined
00:58 path[l] joined
00:58 revprez_atlanta joined
00:59 mjora7 joined
01:03 bigos joined
01:03 lambdamu joined
01:03 fosterit_ joined
01:04 codesoup joined
01:04 takle joined
01:05 fosteri__ joined
01:07 andyhuzhill joined
01:09 <erisco> the only thing stopping paramorphisms from being catamorphisms is the zero, if I am seeing this correctly
01:09 <erisco> otherwise we can just build the tuple bottom up with a catamorphism
01:10 eacameron joined
01:11 <johnw> erisco: was that in relation to something I missed?
01:11 <erisco> no
01:12 <johnw> I thought a paramorphism provides the context for deciding the value at each point
01:12 <johnw> like, for a list, it gives you the tail at each element
01:12 jer1 joined
01:13 <erisco> yes, but we can almost do this with a catamorphism... let me demonstrate
01:16 <erisco> > oldr (\a (xs, b) -> (a:xs, xs:b)) ([], []) [1,2,3]
01:16 <erisco> > foldr (\a (xs, b) -> (a:xs, xs:b)) ([], []) [1,2,3]
01:16 <lambdabot> error:
01:16 <lambdabot> • Variable not in scope:
01:16 <lambdabot> oldr
01:16 <lambdabot> ([1,2,3],[[2,3],[3],[]])
01:16 Supersonic112_ joined
01:16 tlee753 joined
01:17 spacecadetbrown joined
01:18 <jle`> interesting thing you can type into ghci
01:18 <jle`> 1 = 0
01:18 <jle`> now that ghc doesn't require lets anymore
01:18 <erisco> but notice what I did here to make it work
01:19 <erisco> what is the first context? i.e. what is my zero... well I can't know
01:19 <erisco> so I've used a monoid to collect the contexts instead
01:19 lambda-11235 joined
01:19 <erisco> specifically because the monoid has a zero
01:20 <erisco> in my Coalgebra if I actually wanted to know the context I'd have to first figure out if the list was non-empty
01:20 pie_ joined
01:20 matthewbauer joined
01:20 flatmap13 joined
01:20 <erisco> I don't have to do this with a RCoalgebra
01:20 <erisco> derp, I mean Algebra and RAlgebra
01:21 NoCreativity joined
01:22 <erisco> I guess the way I set it up makes it more like a histomorphism... so use foldr (\a (xs, _) -> (a:xs, Just xs)) ([], Nothing) instead
01:23 takle joined
01:25 xcmw joined
01:27 _rht joined
01:27 macrover joined
01:29 <johnw> I don't quite follow
01:29 <johnw> if you ignore the argument, why are you passing it through?
01:29 bd_ joined
01:30 <erisco> johnw, I am just showing that the context is available even though this Algebra doesn't use it
01:30 <erisco> that is why I collected it in a list first... so it did something interesting
01:32 andyhuzhill joined
01:32 <erisco> now in the case of lists specifically we can cheat because we know exactly the context our zero appears in
01:32 <erisco> i.e. the empty list... it just doesn't generalise to Functor fixpoints
01:33 jer1 joined
01:36 acyed joined
01:38 e14 joined
01:39 uglyfigurine joined
01:43 rashmirathi joined
01:44 Goplat joined
01:44 skeuomorf joined
01:46 modal joined
01:48 xormor joined
01:49 e14 joined
01:51 ziyourenxiang joined
01:53 niko joined
01:53 systadmin joined
01:57 path[l] joined
01:58 Volt_ joined
01:59 Kuros` joined
02:00 takle joined
02:00 hucksy_ joined
02:01 eacameron joined
02:02 Manuca joined
02:03 sssilver joined
02:04 justanotheruser joined
02:04 sellout- joined
02:07 darjeeling_ joined
02:09 sproingie joined
02:09 sproingie joined
02:09 exferenceBot joined
02:11 sssilver_ joined
02:11 alx741 joined
02:12 jer1 joined
02:14 matthewbauer joined
02:18 refold joined
02:18 Dance joined
02:21 uglyfigurine joined
02:21 lambdamu joined
02:24 systadmin joined
02:27 brynedwardz joined
02:27 c4r50nz joined
02:29 jer1 joined
02:30 Hunter1_ joined
02:30 ryantm joined
02:31 exferenceBot joined
02:31 eacameron joined
02:32 Koterpillar joined
02:33 Dance joined
02:36 hexagoxel joined
02:38 path[l] joined
02:40 cyborg-one joined
02:41 noam_ joined
02:45 Koterpillar joined
02:46 21WAABRJG joined
02:47 takle joined
02:47 xcmw joined
02:48 uglyfigurine joined
02:49 louispan joined
02:49 Koterpillar joined
02:50 Wizek joined
02:51 xall_ joined
02:56 jer1 joined
02:57 Guest66391 joined
02:58 orhan89 joined
02:58 Argue_ joined
02:59 filterfish joined
02:59 takle joined
03:01 path[l] joined
03:06 permagreen joined
03:08 matthewbauer joined
03:09 cschneid_ joined
03:11 andyhuzhill joined
03:12 filterfish joined
03:14 jer1 joined
03:15 <threshold> What are the possible ways of creating a Future?
03:16 systemfault joined
03:16 <threshold> If STM can replicate the behaviour of MVar, then why not always use STM? When does it make sense to use MVar instead?
03:16 <jle`> the best future starts with the work we do today
03:16 <threshold> !quote
03:17 <threshold> I am unsure how to save timeless advice
03:17 systemfault joined
03:17 <threshold> I will heed your advice though jle`
03:19 takle joined
03:19 <threshold> The Async library looks it would do the job, but is there something equivalent. Can the Async functionality be replicated in STM?
03:20 ericsagnes joined
03:21 <jchia> I have a monad transformer stack where two components inside at different levels of the stack need to maintain their own states. The states are of types Foo & Bar. Can I expect a performance difference between using StateT (Foo, Bar) and using 'StateT Foo' & 'StateT Bar' separately in the stack? Generally, can I expect worse performance from deeper monad transformer stacks?
03:22 eacameron joined
03:24 sleffy joined
03:24 <glguy> threshold: async is implemented using STM
03:25 uglyfigurine joined
03:27 eacameron joined
03:27 dsfox1 joined
03:27 zachary12 joined
03:27 <jle`> jchia: program abstractly if you can
03:28 andyhuzhill joined
03:28 pera joined
03:29 <jle`> you can benchmark to figure out which concrete instance works better
03:30 felixsch__ joined
03:30 flatmap13 joined
03:30 dan_f joined
03:31 zachary12 joined
03:32 zachary12 joined
03:32 darjeeling_ joined
03:35 Koterpillar joined
03:36 jer1 joined
03:38 takle joined
03:38 zachary12 joined
03:43 uglyfigurine joined
03:44 xormor joined
03:45 rashmirathi joined
03:46 <robkennedy> threshold: MVar can give you nice guarantees about single concurrent use, but that can also be achieved with TMVar. So probably the only real reason is performance (although I've not had performance problems with STM)
03:47 primal joined
03:47 <johnw> and I believe only performance under the right circumstances
03:48 <johnw> meaning, STM only loses under certain conditions
03:49 louispan joined
03:49 <ReinH> johnw: o/
03:50 <johnw> Hi ReinH!
03:50 <johnw> will you be at Compose?
03:50 <ReinH> johnw: no :(
03:50 <johnw> *sniff*
03:50 <ReinH> I agree
03:50 <ReinH> maybe next year!
03:52 ania123 joined
03:52 <ania123> Construct regular expression to generate a language where every 1 is followed immediately by 00
03:52 <ania123> my english is not ok
03:52 <ania123> should this language contain
03:52 <ania123> 001?
03:52 <ania123> or 110?
03:52 benl23 joined
03:53 uglyfigurine joined
03:53 etehtsea joined
03:54 mrkgnao joined
03:54 primal_ joined
03:55 Argue joined
03:56 jer1 joined
03:57 isenmann joined
03:57 tripped joined
03:57 takle joined
03:57 <alx741> ania123: no
03:58 <kadoban> ania123: No, neither of those
03:58 <ania123> why not?
03:58 <ania123> 100
03:58 <ania123> i meant sorry
03:58 <ania123> misprint
04:00 robotroll joined
04:00 eklavya joined
04:01 <alx741> '001' nor '110' fit the requirement "1 immediately followed by 00"
04:01 sproingie joined
04:01 sproingie joined
04:02 <lpaste> threshold pasted “Async question” at http://lpaste.net/355412
04:02 <ania123> (0*100)*
04:02 matthewbauer joined
04:02 <threshold> Thank you for the feedback. I am now trying to understand how to group these actions into a single transaction
04:03 AntiSpamMeta_ joined
04:03 <threshold> The general look of the code is in lpaste above.
04:03 beaky joined
04:04 augur joined
04:04 primal joined
04:04 vlatkoB joined
04:04 cur8or joined
04:04 <threshold> The second and third actions don't need to wait on the first action, but they should be rolled back somehow if the first fails.
04:05 SuprDewd joined
04:05 ij joined
04:06 Nycatelos joined
04:06 noplamodo joined
04:06 insitu joined
04:06 carc joined
04:06 Xanather joined
04:06 sword865 joined
04:06 orcus joined
04:07 c4r50nz joined
04:08 <Cale> threshold: I'm not sure how to answer this... are you asking about how to fork threads?
04:09 augur joined
04:10 descender joined
04:10 <Cale> threshold: You can pass an IO action to forkIO which will run it in a new thread
04:13 spacecadetbrown joined
04:14 infinity0 joined
04:14 primal_ joined
04:15 Dance joined
04:16 yourname joined
04:16 <threshold> Cale: I'm not sure. This is my first time to think about this. I thought Strategies, Par, but then decided STM might be better. Why forkIO instead of STM?
04:16 vtomole joined
04:16 <Cale> You might use STM in conjunction with forking threads
04:17 <Cale> You generally won't use STM without using forkIO at all.
04:17 jer1 joined
04:17 <EvanR> not going to ask why youd use STM without multiple threads
04:18 <threshold> EvanR: I'm new to this and do not know better :)
04:19 <EvanR> are you trying to run 3 actions in parallel, with side effects only getting committed if they all succeed?
04:19 matthewbauer joined
04:19 <threshold> EvanR: Yes
04:20 <EvanR> does it involve IO
04:21 <threshold> EvanR: Yes
04:21 <EvanR> you can spawn 3 threads and wait for 3 results, (convenient with the async library), then you can commit the result
04:21 <EvanR> in the original thread
04:22 mivael_ joined
04:24 <threshold> It's possible my mind can handle that. I have a question that is completely ignorant, because I'm completely ignorant about this matter. If I delete a row from a database, how is it that those results can be turned into a transaction which can be rolled back?
04:24 yourname joined
04:24 <EvanR> the delete happens within a database transaction
04:25 primal joined
04:25 <EvanR> there various ways the database could implement that, but in any case, the delete does not happen until the transaction succeeds
04:26 <EvanR> in any haskell db lib ive seen, you always run your modifications inside some transaction context
04:26 <EvanR> if an error occurs, transaction is never committed
04:26 <EvanR> you could also intentionally rollback if you detect an inconsistency
04:27 cschneid_ joined
04:28 <EvanR> the simplistic way to understand it is, the transactions are basically a data structure, and only one transaction runs at a time
04:28 <EvanR> however default isolation levels dont actually act that way and you have gotchas
04:28 throughnothing joined
04:31 BlueRavenGT joined
04:32 <threshold> I am seeing atomic transactions are used for the database client I'm using, through atomicModifyIORef. This is helpful. Hope I can be helpful to new Haskellers one day
04:33 <EvanR> thats not the same thing
04:33 <threshold> *blush*
04:33 primal_ joined
04:34 ericsagnes joined
04:34 matuszak joined
04:35 cschneid joined
04:36 Koterpillar joined
04:36 yourname left
04:36 <EvanR> concurrent communication is tricky business
04:37 yourname joined
04:37 Mibaz joined
04:38 jutaro joined
04:38 primal joined
04:39 jinblack joined
04:39 <Cale> threshold: atomicModifyIORef just mutates memory, it isn't related to the database.
04:39 cartwright joined
04:39 noplamodo joined
04:40 jer1 joined
04:41 fluffystub joined
04:41 <Mibaz> I'm trying to understand the difference between applicative functors and monads. Is it essentially that chains of applicatives can't change type constructors partway through their execution?
04:42 BartAdv joined
04:42 <Mibaz> I'm getting a lot of metaphors online that are a bit too vague
04:42 <EvanR> chains of applicatives cant inspect intermediate results like monads can
04:42 <EvanR> to decide on a different continuation
04:42 <Mibaz> What do you mean by "continuation"?
04:43 <EvanR> :t (>>=)
04:43 <lambdabot> Monad m => m a -> (a -> m b) -> m b
04:43 <EvanR> a monadic expression may contain many >>='s, and the later (a -> m b)'s depend on the previous a's
04:44 primal_ joined
04:45 <Mibaz> :t (<*>)
04:45 <lambdabot> Applicative f => f (a -> b) -> f a -> f b
04:45 flatmap13 joined
04:45 <Mibaz> So you can't put inspection in <*>. Give me a second to think about that.
04:46 takle joined
04:46 <EvanR> in f <*> x <*> y <*> z, x y and z must "happen", no matter what f <*> x is, or (f <*> x) <*> y is
04:47 <EvanR> er, the f x y and z must "happen"
04:47 <pacak> > pure (+) <*> undefined <*> Just 4
04:47 <lambdabot> *Exception: Prelude.undefined
04:47 <pacak> EvanR: Is it?
04:48 <EvanR> thats a different demonstration
04:48 NinjaTrappeur joined
04:48 flipflop joined
04:49 <Mibaz> In " Just 4 >>= \x -> x >>= \y -> x + y " don't both anonymous functions just "happen" efen if the first value had been Nothing ? (That might not compile #newbproblems)
04:50 vlatkoB joined
04:50 <Mibaz> yeah sorry that's a garbage code example
04:50 <Mibaz> I don't see how that chain of functions don't "happen" in monads
04:50 <EvanR> in that example it does
04:51 <EvanR> Just 4 >>= \x -> if x < 3 then <more nested monad code> else <different nested monad code completely>
04:51 <pacak> Mibaz: In a monadic computation you can look at values and decide what to do next. In applicative - you can't.
04:52 <pacak> Resulting shape of applicative computation depends only on shape of components.
04:52 <Mibaz> EvanR: are these "continuations" necessarily demonstrated with if / else statements (or some other branch like that)?
04:52 <pacak> > (,) <$> [1,2] <*> [3,4]
04:52 <lambdabot> [(1,3),(1,4),(2,3),(2,4)]
04:52 <EvanR> the continuation is the second argument to >>=
04:52 <Mibaz> pacak: There's my confusion, what do you mean by "shape"?
04:53 <pacak> This will always* produce a list of 4 elements no matter what elements are.
04:53 South-Paw joined
04:53 <pacak> Always - given there's no undefined
04:54 primal joined
04:54 <pacak> In Monad you can inspect values.
04:54 nullifidian joined
04:54 mjora7 joined
04:54 <int-e> > length $ undefined <$> [1,2] <*> [3,4]
04:54 <lambdabot> 4
04:54 <jle`> Mibaz: one way you can see it is that for Applicative, the "structure" or "effects" is known in advance
04:55 <EvanR> that case, you used fmap first not <*>
04:55 <pacak> int-e: Nice one.
04:55 <jle`> based on the structure/effects of the inputs
04:55 <jle`> for example, for lists, you always know the length of the resulting list
04:55 <threshold> Does Persistent operate within a transactional context?
04:55 <jle`> just based on the length of the input lists
04:55 <jle`> this isn't the case for Monad
04:55 <Lokathor> threshold, it can do transactions, yeah
04:56 <jle`> for IO, the resulting IO action's effects are pre-determined, before any of the input IO actions are computed
04:56 <jle`> s/computed/executed
04:56 <jle`> for Maybe, the Nothing/Justness of the final result can be determined just from the Nothing/Justness of the inputs
04:56 <jle`> without looking at the function being mapped or lifted over them
04:56 <EvanR> you mean Applicative instance of IO
04:56 <Mibaz> jle': ah, ok, what you just said made more sense.
04:57 <jle`> i mean, using the Applicative combinators with IO
04:57 <jle`> if you only use the Functor and Applicative API for IO, the resulting actions will have effects that can be pre-determined
04:57 <jle`> but if you use >>=, that's not the case
04:57 <jle`> if you use >>=, the effects that are performed depend on the function you bind
04:57 <jle`> and cannot be known until you actually execute the IO action
04:58 flipflop left
04:58 <Mibaz> jle': can monads be thought of as applicative functors with an extra function thrown in? (rough statement, obviously).
04:58 <jle`> but for something like f <$> x <*> y, the effects in the reuslting IO action only depend on the effects of x and y
04:58 <jle`> Mibaz: i don't know if that's a useful way to think of monads
04:58 <jle`> i don't think it is
04:59 <jle`> some applicative functors are monads, and some aren't
04:59 <EvanR> Mibaz: there not really directly related. Monad are Functors with a join operation m (m a) -> m a
04:59 <jle`> you can't just "throw extra functions" into ZipList, or Const
04:59 <jle`> and expect them to become monads
04:59 <jle`> there is no exact function you can add to Const that will make it a lawful monad
04:59 <jle`> s/exact/extra
04:59 <EvanR> f (f a) -> f a
05:00 <jle`> take a look at the Const Applicative. you can't just add an extra function and turn it into a monad
05:00 jer1 joined
05:00 <Mibaz> jle': right right, I wasn't suggesting you could just add a function. I was speaking conceptually (and only conceptually about the relationship between applicatives and monads)
05:01 <Mibaz> EvanR: Doesn't a monad also have to be an applicative?
05:01 <jle`> for something to *be* a monad, it has to support all the things associated with applicatives, and there is an extra requirement, as well
05:01 <EvanR> yeah, now
05:01 <EvanR> but thats just a convenience for haskell code
05:01 <EvanR> you can implement an applicative for free with any monad
05:02 paolino joined
05:02 <EvanR> so now they make you
05:02 <Mibaz> EvanR: So they're not mathematically related, is what you are saying?
05:02 <jle`> Mibaz: the concept of a monad has one extra requirement
05:02 <EvanR> (unless you have a better applicative instance for it)
05:02 <EvanR> right
05:02 <jle`> Mibaz: kind of like, for something to be considered a square, it needs to fulfil all of the requirements of being a rectangle (four-sided polygon, right angles), and also one extra requirement
05:02 <jle`> Mibaz: which is that the four sides have to have the same length
05:02 flatmap13 joined
05:03 <jle`> the requirements that qualify something to be called a square is just slightly more restrictive than the requirements that qualify something to be called a rectangle
05:03 <EvanR> and they you stretch it and say applicatives are a rhombi ;)
05:03 <jle`> but it is true that anything that qualifies to be called a square will also, by definition, be qualified to be called a rectangle
05:04 primal_ joined
05:04 sproingie joined
05:04 dec0n joined
05:04 <int-e> EvanR: Note that for Const, join isn't the problem, it's the return/pure.
05:05 <jle`> er, wait, pure for Const is fine
05:05 <EvanR> interesting
05:05 <Mibaz> jle': EvanR: Ok, I kind of have all of this (rhombariffic) information at the top of my head, let me read a little more and think about it. What's going to help at this point is examples.
05:05 shayan_ joined
05:05 <cocreature> int-e: pure = Const mempty
05:06 <EvanR> right, monads are functors with *two* more operations, pure and join
05:06 <jle`> it's possible to write a typechecking join, but not one that satisfies the laws
05:06 <int-e> jle`: well that's cheating by taking something pointed as the base type
05:06 <int-e> huh, cocreature: I mean
05:06 <jle`> int-e: well we're talking about this in the context of the Applicative instance
05:06 rashmirathi joined
05:06 <int-e> I guess you can have pure _ = Const undefined.
05:07 <jle`> if you take Const X to have an Applicative instance, then you can't make a lawful Monad instance
05:07 <jle`> where ap = (<*>)
05:07 <cocreature> int-e: and that’s not cheating? ;)
05:07 <Lokathor> how do i make a Double into a Float
05:07 <int-e> cocreature: yes it is
05:07 <jle`> realToFrac
05:07 <Lokathor> the number tower always gets me lost
05:07 maarhart joined
05:07 <Mibaz> jle': quickly for clarification, the "effects" of <*> are known in advance, but the effects of >>= are also known IF you know the (a -> m b) in the type signature, correct?
05:07 <EvanR> Lokathor: realToFrac
05:07 <jle`> Mibaz: they are not known in advance
05:07 <int-e> cocreature: And I didn't want to allow either.
05:07 <Lokathor> cool
05:08 <EvanR> Lokathor: because its not a tower, its a salad bowl
05:08 <jle`> Mibaz: knowing the type 'm b' does not tell you mch about the effects
05:08 <cocreature> Lokathor: if you remember fromIntegral and realToFrac you can do most conversions
05:08 <jle`> Mibaz: oh, i see what you're asking
05:08 <jle`> Mibaz: no, not necessarily.
05:08 <Lokathor> well i remember fromIntegral all the time
05:08 <jle`> Mibaz: because the 'a' isn't known in advance
05:08 <Lokathor> usually i don't need Float, just GL using them is all
05:08 <EvanR> and fromInteger when possible
05:08 paolino_ joined
05:08 <jle`> Mibaz: 'getLine >>= putStrLn' for a counter-example
05:08 <EvanR> or fromRational
05:08 <jle`> Mibaz: it's impossible to know the effects until getLine is fully executed
05:09 <int-e> cocreature: I answered an objection I had that didn't make it to the channel: To define pure = Const mempty imposes a type class constraint on the first argument of Const.
05:09 <Mibaz> jle': ah, persuasive counterexample.
05:09 <EvanR> Lokathor: ;_; cant you use Double
05:09 paolino__ joined
05:09 matuszak joined
05:09 <EvanR> (answer, you can)
05:09 <jle`> Lokathor: i believe realToFrac has a rewrite rule that makes it performant
05:09 <cocreature> int-e: fair enough.
05:09 <jle`> for the case of Float -> Double
05:09 path[l] joined
05:09 <Mibaz> jle': there can't be an applicative implementation of IO, then?
05:10 <jle`> Mibaz: there can be an applicative instance for IO
05:10 <EvanR> jle`: are we sure of that
05:10 <jle`> well, there is one
05:10 <jle`> Lokathor: normally, realToFrac converts to a Rational, then converts back
05:10 <jle`> which is pretty bad
05:10 <Lokathor> EvanR, what i'm doing in this example is taking the time from GLFW-b (Maybe Double) and setting it as the green value of the pixels of a triangle (which are all Float)
05:10 <jle`> Mibaz: `f <$> getLine <*> getLine` -- the effects are known ahead of time, even if you don't know what 'f' is
05:11 <jle`> in general, 'f <$> x <*> y' will have exactly the effects of x and of y, sequenced after each other
05:11 <jle`> (talkin bout IO)
05:12 <Mibaz> jle': what about getLine <*> putStrLn
05:12 <jle`> that doesn't really typecheck
05:12 <EvanR> getLine doesnt have type IO (a -> b)
05:12 <jle`> maybe you mean f <$> getLine <*> putStrLn "hello" ...?
05:12 <jle`> in that case, the effects are also knowable w/o knowing f
05:13 paolino joined
05:13 <Mibaz> jle': ah, sorry forgot the type
05:13 <Mibaz> :t <*>
05:13 <lambdabot> error: parse error on input ‘<*>’
05:13 <Mibaz> um
05:13 <jle`> the type is only a reflection of the deeper problem
05:13 <jle`> which is what you gave doesn't really make sense
05:13 <Mibaz> :t (<*>)
05:13 <lambdabot> Applicative f => f (a -> b) -> f a -> f b
05:13 <Mibaz> jle': of course
05:13 <nshepperd> getLine >>= f -- might print the line you entered. for instance let f = putStrLn
05:14 <cocreature> in case anybody else got curious where the rules for realToFrac are declared, they’re here https://github.com/ghc/ghc/blob/master/libraries/base/GHC/Float.hs#L1194
05:14 primal joined
05:14 <nshepperd> g <*> getLine -- won't have any effects involving the line you entered, no matter what g is
05:14 <EvanR> nice
05:15 <Mibaz> nshepperd: Can you define "effects"
05:16 <nshepperd> Mibaz: eg. printing stuff
05:16 <nshepperd> opening files, etc
05:17 <Mibaz> Ok, I'm going to go read more. I'll probably be back with more dumb questions ;) thanks guys
05:17 <jle`> for a simplified example, you can look at Maybe, too
05:17 <jle`> where "effects" means Justness/Nothingness
05:17 <jle`> so for f <$> x <*> y, whether the result is Just or Nothing depends only on whether or not x and y are Just or Nothing
05:17 <Mibaz> jle': ok, that makes sense.
05:18 <jle`> but if you throw in >>=, all bets are off
05:18 osa1 joined
05:18 <jle`> `x >>= guard`, for instance, might be Just or Nothing, and you can't tell which just by looking at if x is Just or Nothing
05:18 systemfault joined
05:19 <jle`> > Just True >>= guard
05:19 <lambdabot> Just ()
05:19 <jle`> > Just False >>= guard
05:19 <lambdabot> Nothing
05:19 <jle`> > Nothing >>= guard
05:19 <lambdabot> Nothing
05:19 <Mibaz> :t guard
05:19 <lambdabot> Alternative f => Bool -> f ()
05:19 <jle`> guard True = Just (); guard False = Nothing
05:20 systemfault joined
05:20 <Mibaz> jle': thanks, hadn't seen that yet
05:20 <Lokathor> hey everybody, quiz time: what's wrong with the following line that's constructing a string to send off to OpenGL?
05:20 <Lokathor> ourColorP <- newArray (map (fromIntegral.fromEnum) "ourColor")
05:20 <Lokathor> blink and you'll miss it
05:20 <jle`> Mibaz: same for Either, too, btw, and it's actually a more interesting guaruntee
05:21 <jle`> if the result is Left, you can determine *exactly* what's in the Left
05:21 <jle`> without looking at the function
05:21 systemfault joined
05:21 jer1 joined
05:21 <Mibaz> jle': but given the definition of guard, aren't those results self evident? That's cool with Either.
05:21 <jle`> you only need to look at whether or not the inputs are Left, and what is 'inside' those lefts
05:21 <Cale> Lokathor: Array bounds?
05:21 <jle`> what results?
05:21 <Mibaz> > Just True >>= guard
05:22 <lambdabot> Just ()
05:22 <Mibaz> > Just Fale >>= guard
05:22 maarhart joined
05:22 <lambdabot> error:
05:22 <lambdabot> • Data constructor not in scope: Fale :: Bool
05:22 <lambdabot> • Perhaps you meant ‘False’ (imported from Data.Bool)
05:22 <Mibaz> >Just False >>= guard
05:22 <Lokathor> Cale, very close! I can't send the string "ourColor", I have to send the string "ourColor\0", because C strings
05:22 <Cale> ah
05:22 <jle`> yes, so if you use the monad interface for Maybe, you can't necessarily determine ahead of time if the result is Just or Nothing based *only* on the just/nothingess of the input Maybe's
05:22 systemfault joined
05:22 <Cale> I didn't know which newArray that is, but if it's the one from Data.Array.MArray, it would be a type error not to provide the bounds as the first argument
05:22 <Mibaz> jle': aaahh, you need to look at the value in the context, right?
05:22 takle joined
05:22 <Cale> Apparently it's not though.
05:23 jbgi joined
05:23 <jle`> Mibaz: for the case of Maybe, yes
05:23 <jle`> just/nothingness of the input is not enough to answer just/nothingess of the result
05:23 <Mibaz> jle': so the effects of applicatives are dependent on the effects of the inputs while the effects of a monad can depend on values
05:24 <jle`> yeah
05:24 Swizec joined
05:24 <jle`> values, and the binding funtions
05:24 <Lokathor> Cale, it's just the normal one from Foreign.Marshal, so it makes an array pointer to an array that holds the contents of the list you give it
05:24 primal_ joined
05:24 <Mibaz> jle': That might've cleared it up for me. Thanks for saying the same thing over and over again until it clicked
05:25 <jle`> no problem. this is a difficult concept because it touches on "general" ideas about monads and applicatives
05:25 <jle`> things that are true about monads and applicatives 'in general'
05:25 <Mibaz> Thanks guys. I'll be back.
05:25 <Cale> ah, that one
05:26 <Cale> Lokathor: You could use newArray0
05:27 <Lokathor> Cale, oh, right, there's that too.
05:27 <Cale> Lokathor: Perhaps better yet to use withArray0 so that you can ensure the memory is deallocated when you're done.
05:27 <Lokathor> Cale, well, I need to keep that array for the duration of the program, it's more like a literal than a value
05:27 <Lokathor> vertexColorP <- glGetUniformLocation shaderProgram ourColorP -- this line here runs every frame
05:29 <Lokathor> I'm sure that I'll need to craft quite a few helper functions to make opengl cleaner and safer if I really get into it. But I don't think I'll get too into it. I just wanna make a glyph grid thing as my short term goal.
05:29 andyhuzhill joined
05:29 viralstitch joined
05:30 exferenceBot joined
05:31 danvet joined
05:34 primal joined
05:37 ericsagnes joined
05:38 jer1 joined
05:38 Sose joined
05:40 takle joined
05:41 okuu joined
05:41 revprez_ joined
05:41 insitu joined
05:42 Argue_ joined
05:43 revprez_ joined
05:44 primal_ joined
05:45 JagaJaga joined
05:46 <osa1> anyone know a good way of using IntMap with Int newtypes as keys? I don't want to duplicate the whole API
05:46 ThomasLocke joined
05:46 ThomasLocke joined
05:47 <opqdonut> you might get some traction with Control.Newtype.under
05:47 <opqdonut> but I think you'll just have to write some boilerplate
05:49 <osa1> that's more boilerplate than I can afford. let me see the package though it looks interesting. never heard of it before.
05:49 Hunter1_ joined
05:49 xiengu joined
05:49 <opqdonut> actually it might not help you, it's more for lifting a->a stuff to newtype->newtype stuff
05:49 filterfish joined
05:50 jer1 joined
05:50 <opqdonut> you just basically need lookup . unMyNewtype etc.
05:51 fizruk joined
05:51 caumeslasal joined
05:51 Dance joined
05:51 <osa1> yeah I don't want to do that. in fact my newtype constructor is not even exposed.
05:51 <osa1> *sigh*
05:52 Hunter1_ joined
05:53 guiben joined
05:53 <opqdonut> I think your options are Data.Map, or duplicating the IntMap api (perhaps with something like "class IntMapKey a where toKey :: a -> Int; fromKey :: Int -> a; newtype MyIntMap a b = MyIntMap (IntMap b); lookup :: IntMapKey a => MyIntMap a b -> a -> Maybe b"
05:54 fizruk joined
05:54 primal joined
05:54 <opqdonut> the latter part would make for a nice hackage lib
05:54 <osa1> yeah I'm surprised that there isn't a package for this already
05:56 mstruebing joined
05:56 <kadoban> I think there's an EnumMap somewhere that's a wrapper for IntMap
05:57 <kadoban> Which is almost but not quite the same thing?
05:57 <Axman6> just use Data.Coerce on insert and lookup
05:57 <opqdonut> https://hackage.haskell.org/package/EnumMap-0.0.2/docs/Data-EnumMap.html
05:57 <Axman6> if they keys you're using are newtypes you should be fine
05:58 jbgi joined
05:59 doomlord_ joined
05:59 <Lokathor> are there still strong opinions on gl vs OpenGLRaw?
06:01 ogrady joined
06:02 xtreak joined
06:02 paolino_ joined
06:02 <johnw> it's only when you google for "how to make z3 faster" that you realize how many different products are known by the label 'Z3'
06:03 <johnw> and how speed relates to them all
06:03 hurkan joined
06:03 mjora7 joined
06:03 <Axman6> vroom vroom!
06:03 <pacak> Lokathor: I'd go with gl only because of author.
06:03 <Axman6> :t coerce
06:03 <lambdabot> error:
06:03 <opqdonut> you're talking about the Z3 cyclic group of course?
06:03 <lambdabot> • Variable not in scope: coerce
06:03 <lambdabot> • Perhaps you meant ‘coerced’ (imported from Control.Lens)
06:03 <Axman6> :t coerceed
06:03 <lambdabot> error:
06:03 <lambdabot> • Variable not in scope: coerceed
06:03 <lambdabot> • Perhaps you meant ‘coerced’ (imported from Control.Lens)
06:03 <Axman6> :t coerced
06:03 <lambdabot> (Coercible t b, Coercible s a, Functor f, Profunctor p) => p a (f b) -> p s (f t)
06:04 tromp joined
06:04 <Axman6> :t (^. coerced)
06:04 <lambdabot> Coercible s a => s -> a
06:04 <Axman6> :t (^. coerced) IM.insert
06:04 primal_ joined
06:04 <lambdabot> Coercible a1 (IS.Key -> a -> IM.IntMap a -> IM.IntMap a) => a1
06:04 <Axman6> :t (^. coerced) IM.insert :: Sum Int -> IM.Intmap a -> IM.IntMap a
06:04 <lambdabot> error:
06:04 <lambdabot> Not in scope: type constructor or class ‘IM.Intmap’
06:04 <lambdabot> Perhaps you meant ‘IM.IntMap’ (imported from Data.IntMap)
06:05 <Axman6> :t (^. coerced) IM.insert :: Sum Int -> IM.IntMap a -> IM.IntMap a
06:05 <lambdabot> error:
06:05 <lambdabot> • Couldn't match representation of type ‘IM.IntMap a0
06:05 <lambdabot> -> IM.IntMap a0’
06:05 <Lokathor> pacak, yeah. gl is pretty nice as well
06:05 <Lokathor> OpenGLRaw has a "merge this with gl" page on its git wiki, and for every point of contention it basically just says "resolution: go with our way"
06:06 <Lokathor> which strikes me as a little silly
06:06 <Axman6> not sure if Ed keeps it up to dte, but gl represented the entirety of OpenGL, including all extensions
06:06 matthewbauer joined
06:06 <Axman6> which is pretty amazing
06:06 <Lokathor> Axman6, latest version is "Uploaded Sat Mar 25 00:20:59 UTC 2017 by EdwardKmett" according to Hackage
06:06 <Axman6> that's pretty good
06:07 <osa1> Axman6: that's not gonna work because my newtype is actually opaque (i.e. no constructor in scope)
06:10 cpup joined
06:10 Koterpillar joined
06:10 patbecich joined
06:11 louispan joined
06:12 moongazer joined
06:13 <osa1> :t \k -> IM.insert (k ^. coerced) "ok" IM.empty
06:13 <lambdabot> Coercible s IS.Key => s -> IM.IntMap [Char]
06:13 <osa1> :t \k -> IM.insert (k ^. coerced)
06:13 <lambdabot> Coercible s IS.Key => s -> a -> IM.IntMap a -> IM.IntMap a
06:14 <Axman6> osa1: would it make sense to export something like insertIM :: MyKey -> a -> IntMap a -> IntMap a; insertIM = coerce IM.insert?
06:14 primal joined
06:14 matthewbauer joined
06:14 <osa1> Corercible here means any IS.Key can be coerced to my type, right? maybe I need one-way coercible here
06:15 <Axman6> yeap
06:15 <nshepperd> module MyMap (MyMap, insert, ...) where { newtype MyMap a = MyMap (IntMap a); insert = coerce IntMap.insert; ... }
06:15 <nshepperd> you will need the constructor of your newtype in scope there
06:15 path[l] joined
06:15 <osa1> nshepperd: that's too much boilerplate because IntMap API is large and I need pretty much all of it
06:16 <nshepperd> I don't see any other way to do it
06:16 <osa1> I think one way Coercible would be a good solution
06:16 bgamari joined
06:16 <nshepperd> not if you want to keep the newtype constructor hidden
06:16 steshaw_ joined
06:17 <osa1> nshepperd: I could provide a one-way Coercible instance without exposing the constructor
06:17 <osa1> so you could coerce to Int from my type but not the other way
06:17 steshaw joined
06:17 <nshepperd> how are you supposed to insert with that
06:17 <osa1> IM.insert (oneWayCoerce myType) value ?
06:18 <nshepperd> IM.insert needs an Int
06:18 <nshepperd> coerceForInsert :: MyType -> Int
06:18 <osa1> that's what oneWayCoerce does
06:18 <nshepperd> oh, to
06:18 <osa1> but ther's not `Int -> MyType`
06:19 <nshepperd> ok, that will work as long as you don't need the adjust functions
06:19 FooBr joined
06:19 <nshepperd> or toList
06:19 <osa1> hmm right
06:19 <nshepperd> or anything WithKey
06:20 <osa1> I guess that could be done with a new map implementation that uses Ints for keys but also stores original (un-coerced) keys
06:21 patbecich joined
06:22 Reshi joined
06:23 incognito joined
06:23 <nshepperd> dunno, to me this seems inferior to just writing the boilerplate
06:23 IdiopathicGravit joined
06:23 takle joined
06:24 <nshepperd> but what do i know
06:24 primal_ joined
06:24 <osa1> agreed I was just thinking out loud
06:28 jer1 joined
06:29 cschneid_ joined
06:30 FooBr` joined
06:30 ertes-w joined
06:30 splanch joined
06:31 CoderPuppy joined
06:31 aloiscochard joined
06:32 soniku joined
06:32 zeroed joined
06:32 zeroed joined
06:33 xtreak joined
06:34 primal joined
06:37 torstein joined
06:38 nickolay_ joined
06:39 WF-BATCH joined
06:44 incognito left
06:44 primal_ joined
06:45 alfredo joined
06:47 patbecich joined
06:47 takle joined
06:47 quchen joined
06:48 coot joined
06:51 jer1 joined
06:51 moongazer joined
06:52 jedws joined
06:53 mfukar joined
06:54 primal joined
06:55 sfcg joined
06:57 takle joined
06:58 splanch joined
06:59 Guest71533 joined
06:59 Argue__ joined
06:59 sleffy joined
06:59 Guest39355 joined
07:00 Guest25781 joined
07:01 oish joined
07:01 Guest15355 joined
07:02 Guest1228 joined
07:03 Argue_ joined
07:03 Guest83712 joined
07:04 bvad joined
07:04 Guest71495 joined
07:04 primal_ joined
07:04 ventonegro joined
07:05 sproingie joined
07:05 sproingie joined
07:07 takuan joined
07:07 Levex joined
07:08 oish joined
07:08 jedws joined
07:09 thunderrd joined
07:09 darjeeling_ joined
07:09 Argue joined
07:10 zariuq joined
07:10 systadmin joined
07:10 guillaum2 joined
07:10 jer1 joined
07:11 zeroed joined
07:11 zeroed joined
07:14 jelleke joined
07:15 vlatkoB_ joined
07:15 juhp joined
07:16 michaelw joined
07:16 matuszak joined
07:20 jelleke joined
07:20 codesoup joined
07:21 primal joined
07:21 takle joined
07:22 augur joined
07:23 cur8or joined
07:23 meba joined
07:24 zeroed joined
07:24 coot joined
07:24 besoo[m] joined
07:26 primal_ joined
07:27 ragepanda joined
07:28 mattyw joined
07:30 mjora7 joined
07:30 Levex joined
07:31 jer1 joined
07:32 muesli4 joined
07:32 Swizec_ joined
07:33 Mortomes|Work joined
07:35 nickolay joined
07:36 connrs joined
07:40 bvad joined
07:40 fotonzade joined
07:41 marr joined
07:41 raynold joined
07:42 eklavya joined
07:42 Cooler joined
07:43 <Cooler> which is the current standard haskell 98?
07:43 merijn joined
07:43 <Cooler> haskell 2010?
07:44 <Cale> btw, those two are almost the same thing
07:44 <quchen> Cooler: Haskell 2010, yes.
07:44 Levex joined
07:44 <Myrl-saki> > 2010 - 98
07:44 <lambdabot> 1912
07:44 <Cooler> is there a formal grammar for Haskell 2010?
07:44 <Cale> Haskell 2010 mostly just consolidated some extensions to the standard which had been made since Haskell 98, and made a few small changes here and there.
07:45 <Cale> It's in the Report.
07:45 eatman joined
07:45 <merijn> Cale: Of course it skipped like half of the things it could have usefully consolidated :p
07:45 <Cale> yes
07:46 <Cale> Also, it's not so much the consolidating which needs doing, but just producing documents in the first place which describe what's been implemented in a precise way.
07:46 <merijn> hmmm, I wonder if criterion assumes measurements are uniformly distributed around the mean, I suppose that could fuck things up...
07:46 <Cale> I didn't think it did
07:47 <Cale> It produces kernel density estimates, doesn't it?
07:47 <quchen> You mean »gaussian around the mean«?
07:47 <quchen> Or at least symmetric
07:48 <merijn> Cale: Well, the issue I'm having is that, given only positive timing results (obviously, since it clamps negative to zero...) it ends up predicting ranges who start in the negative runtime
07:48 <merijn> quchen: Yeah, something like that...it's early...
07:49 fbergmann joined
07:49 moongazer joined
07:50 <merijn> Looks like I'll have to reverse engineer statistics from this code >.>
07:51 <Cale> merijn: It's probably producing an estimate of the PDF which is a sum of Gaussians -- which doesn't necessarily make total sense for something which is supposed to be a length of time.
07:51 Durbley joined
07:51 <merijn> Cale: Especially for small runtimes with big (relatively) outlies
07:51 eatman joined
07:52 <merijn> Because you get things like:
07:52 <merijn> time 8.926 ms (-3.289 ms .. 14.23 ms)
07:52 <merijn> 0.935 R² (0.703 R² .. 1.000 R²)
07:52 jer1 joined
07:52 <merijn> Pretty confident about that negative runtime there...
07:52 patbecich joined
07:53 <Cale> There's a way, iirc, to have it plot a graph of the PDF it estimated
07:53 <tsahyt> negative runtime sounds sweet. Just run this function often enough and negate the cost of anything else.
07:53 <quchen> Most basic statistical analysis is based on Gaussians, so this wouldn’t surprise me.
07:53 darjeeling_ joined
07:53 <johnw> negative runtime will mean management expecting me to retroactively meet deadlines
07:54 <Cale> tsahyt: Note that if you run it enough though, it will tend to take an amount of time closer to the mean which is positive, so you'd have to luck out
07:54 <Cale> ;)
07:54 <quchen> johnw: Not like that’s any different with positive runtime
07:54 <johnw> yeah, true
07:55 <merijn> So...what are the odds of me finding a way to clamp the statistics to positive values? Basically 0?
07:55 <johnw> your odds are -0.3%
07:55 <Myrl-saki> merijn: What does R^2 mean.
07:55 <Cale> merijn: ah, try running your program with --output foo.html
07:56 <Cale> Myrl-saki: That's the https://en.wikipedia.org/wiki/Coefficient_of_determination
07:56 <merijn> Myrl-saki: Statistic mumbo jumbo about likelihood of the timing estimate being nonsense :p
07:56 xcmw joined
07:56 <merijn> Cale: Yeah, I know about that one :)
07:56 <Cale> merijn: What does the graph look like?
07:57 <Myrl-saki> Thanks.
07:57 ridho joined
07:58 <Cale> But yeah, the 0.703 suggests that the low end of that interval is meaningless.
07:58 <merijn> Cale: Well it also seems to be bootstrapping based on a mere 4 samples, which seems...wrong?
07:58 <Cale> yeah, that's odd
07:59 PennyNeko_ joined
07:59 <merijn> Presumably based on the fairly long runtime
08:00 <Cale> Maybe increase the timeLimit in the config?
08:00 cschneid_ joined
08:00 chrisM_1 joined
08:00 <merijn> Cale: http://files.inconsistent.nl/AtomicCounter.html
08:01 <merijn> Cale: I dunno how to increase that for a single benchmark, rather than all of them, though :\
08:02 patbecich joined
08:02 <Cale> That mean line on the KDE is pretty weird looking
08:03 thc202 joined
08:03 <Cale> timeLimit :: Double
08:03 <Cale> Number of seconds to run a single benchmark. (In practice, execution time will very slightly exceed this limit.)
08:03 tromp joined
08:03 c4r50nz joined
08:03 <Cale> It's a field of Config
08:03 <merijn> Yeah there's a a -L flag for that
08:04 <merijn> Defaults to 5s, I think
08:05 hackage joined
08:05 <merijn> 10 fold increase over the number of samples still results in only like 5 samples
08:06 <merijn> This might also just be me having half-broken criterion. Since it tries to benchmark batches of N runs for better accuracy. But this is basically forcing batches of N runs to be N individual runs added together
08:07 Itkovian joined
08:07 Gurkenglas joined
08:08 jhrcek joined
08:08 <merijn> Anyway, I guess I should just ignore the low end estimate, given how noisy this entire thing is
08:08 <merijn> ls
08:09 zariuq joined
08:09 takle joined
08:10 <merijn> Only a hanful of benchmarks seem really affected anyway and those are all noisy to begin with
08:10 eatman joined
08:10 <merijn> Althought the upperbound time estimate of "NaN s" is interesting too...
08:11 moongazer joined
08:11 rashmirathi joined
08:12 Itkovian joined
08:13 jer1 joined
08:13 rashmira_ joined
08:13 augur joined
08:14 rashmir__ joined
08:14 j03_k joined
08:22 mmn80 joined
08:23 slomo joined
08:23 slomo joined
08:24 Levex joined
08:24 Kreest__ joined
08:25 path[l] joined
08:25 meba joined
08:25 <j03_k> what does the _ mean in haskell
08:25 <merijn> j03_k: wildcard pattern
08:26 <MasseR> Or a hole
08:28 Yuras joined
08:29 <j03_k> what is the co-domain of the mod function?
08:29 acidjnk22 joined
08:30 <quchen> The codomain is what a function maps to.
08:30 eyck joined
08:30 bvad joined
08:30 kuribas joined
08:30 <Cale> :t mod
08:30 <lambdabot> Integral a => a -> a -> a
08:31 bigos joined
08:31 xtreak joined
08:31 <Cale> It's some type a -> a where a is an instance of Integral
08:31 filterfish joined
08:32 zeroed joined
08:32 <quchen> Cale: Nitpicky, but does mod even have a codomain? Isn’t it a family of functions parametrized over a constrained type?
08:33 xtreak joined
08:33 <quchen> Depends on whether we interpret => as a function arrow or not I suppose
08:33 jer1 joined
08:33 <Cale> My answer was relative to the type a that we choose.
08:33 dm3 joined
08:33 mekeor joined
08:34 Elhamer joined
08:34 <Cale> quchen: Or perhaps on whether we interpret forall a. as a function arrow :)
08:34 lep-delete joined
08:34 <quchen> Heh!
08:34 mekeor joined
08:35 <quchen> Cale: What kind is the »a« in »forall a«? I think we should first consider the »forall kind.« part
08:36 tomphp joined
08:37 sfcg joined
08:37 raichoo joined
08:38 xtreak joined
08:41 heurist` joined
08:44 ixxie joined
08:44 moongazer joined
08:44 mkoenig joined
08:45 Michaelt293 joined
08:46 NyanPasu joined
08:46 takle joined
08:46 ZuluKing joined
08:48 <Cale> quchen: a :: * here, it can't be kind-polymorphic
08:48 splanch joined
08:50 <quchen> Hm, right.
08:50 <quchen> Bad joke :-(
08:52 <Cale> But yeah, if it were kind-polymorphic, then we might have to consider that too
08:52 mattyw joined
08:52 splanch_ joined
08:53 <ZuluKing> hey, can someone who is familiar with vscode+haskero or actually even intero, tell me why does it keep complaining failed to load interface for local modules?
08:53 <ZuluKing> I have included them in other-modules in my .cabal already
08:53 juhp joined
08:54 jer1 joined
08:54 <Taneb> ZuluKing, are the modules installed on your system?
08:55 <ZuluKing> yes, they are part of my program, just not exposed ones.
08:55 <merijn> Right, so I think I have more timing data on concurrent synchronisation than anyone could ever want :p
08:55 <c_wraith> ZuluKing: I don't know specifically, but I can tell you that error specifically means that it can't find the .hi files ghc creates during compilation where it expects to
08:55 <c_wraith> ZuluKing: err, I can't tell you what that means in the context of those programs
08:55 <ZuluKing> where does it usually expect it to be?
08:55 <lpaste> merijn pasted “Concurrent synchronisation primitives benchmarks” at http://lpaste.net/355415
08:55 <ZuluKing> in local .stack-work?
08:56 <c_wraith> that's the part I can't tell you. It depends on the flags passed in, and there are a lot of ways to control it.
08:56 <merijn> Conclussion AtomicCounter, despite going wack at higher contention is by far the best, IORef is pretty solid, TMVar is terribad
08:56 ski joined
08:56 <merijn> Although I think the higher contention numbers are really to unstable to say anything sane
08:56 <ZuluKing> so I just checked all the .hi files are there in the .stack-work directory
08:57 <c_wraith> merijn: STM really is quite slow under contention. striping is often a huge win when working with any STM data structure, if you can find a way to do it.
08:57 {emptyset} joined
08:57 WhereIsMySpoon joined
08:57 <merijn> c_wraith: Actually, TVar and TSem do pretty well
08:57 <merijn> As does TQueue
08:58 <merijn> c_wraith: TSem is 20 ms vs 15 for MVar, TMVar is a whopping 5 s, of by like 3 orders of magnitude...
08:58 <merijn> For 10k threads
08:58 WhereIsMySpoon left
08:58 Silox| joined
08:58 <c_wraith> ZuluKing: that would suggest that something is misconfigured somehow - that ghc is looking in the wrong place for the .hi files
08:59 sfcg joined
09:00 <c_wraith> ZuluKing: but I can't be more specific as I don't use any of the tools you're using.
09:00 <ZuluKing> c_wraith I just followed the standard instructions
09:00 <* hackage> transformers-lift - Ad-hoc type classes for lifting https://hackage.haskell.org/package/transformers-lift- (int_index)
09:00 rashmirathi joined
09:00 <ZuluKing> c_wraith I am just using stack, vscode+haskero
09:00 twanvl joined
09:00 <c_wraith> Yep. I don't use any of those. :)
09:00 <ZuluKing> c_wraith I can stack build and stack exec with no problems
09:01 <ZuluKing> just that intero keeps reporting these errors
09:01 <ZuluKing> and it's midly irritating
09:01 <ZuluKing> c_wraith thanks for helping anyways :)
09:02 <merijn> Anyone that can think of any primitives I missed out on? Especially ones that might be able to contend with AtomicCounter/IORef?
09:02 acidjnk joined
09:02 rashmirathi joined
09:02 unK_ joined
09:03 patbecich joined
09:04 tromp joined
09:05 rashmirathi joined
09:06 sproingie joined
09:07 dddddd joined
09:07 entuland joined
09:08 brynedwards joined
09:08 v0latil3 joined
09:09 pellenation joined
09:09 balor joined
09:10 takle_ joined
09:10 Argue joined
09:11 skeuomorf joined
09:12 revprez_atlanta joined
09:12 <merijn> Can I turn an unbound thread into a bound thread somehow?
09:13 MDA2 joined
09:13 rashmirathi joined
09:13 rashmira_ joined
09:14 takle joined
09:14 Durbley joined
09:14 jer1 joined
09:15 mda1 joined
09:17 cranej joined
09:17 <merijn> oh, runInBoundThread solves my issue, I guess :)
09:18 deank joined
09:20 ub joined
09:22 Faucelme joined
09:24 xall_ joined
09:26 louispan joined
09:26 spacecadetbrown joined
09:26 magthe joined
09:26 Dance joined
09:28 moongazer joined
09:29 oisdk joined
09:29 Yuras joined
09:33 zargoertzel joined
09:34 oish joined
09:35 jer1 joined
09:37 zero_byte joined
09:37 tomphp joined
09:39 louispan joined
09:40 nuskin joined
09:40 Wizek_ joined
09:42 paolino joined
09:43 litchblade joined
09:44 xcmw joined
09:44 <nuskin> hey everyone, currently I'm trying to do an exercise and am really struggling to understand how haskell abstract data types work
09:45 <nuskin> we're trying to make a type safe version of printf and this is what we're given to start off with http://lpaste.net/4565166523269775360
09:46 xtreak joined
09:46 Argue joined
09:46 <nuskin> now ideally on line 11 I'd want L (x:xs) :: Format '[String ': Format xs]
09:46 paolino joined
09:46 <nuskin> but the compiler complains error: parse error on input ‘(’
09:47 fotonzade joined
09:47 razi1 joined
09:47 xtreak joined
09:48 kritzcreek joined
09:49 paolino joined
09:52 psychicist__ joined
09:52 mjora7 joined
09:54 <* hackage> mbox-utility 0.0.1 - List contents of an mbox file containing e-mails https://hackage.haskell.org/package/mbox-utility-0.0.1 (HenningThielemann)
09:55 tomphp joined
09:55 {emptyset} joined
09:57 xtreak joined
09:59 puma_ joined
09:59 jer1 joined
10:00 <Itkovian> I'm trying to get my head wrapped around conduit. the end goal is to have the input converted and send to one port (or sink?) if the conversion succeeds and to another port (or sink?)if it fails. any pointers to (recent) docs explaining this a bit more?
10:02 cchalmers joined
10:04 moongazer joined
10:05 Shish2 joined
10:06 richi235 joined
10:06 t7 joined
10:07 <cocreature> nuskin: can you explain what the L constructor is supposed to do or how it is supposed to be used?
10:08 harfangk joined
10:09 slomo joined
10:10 insitu joined
10:10 <Cooler> i am looking at the lexical syntax given here https://www.haskell.org/onlinereport/haskell2010/haskellch2.html#x7-140002
10:10 <Cooler> why do comments have weird rules?
10:10 <quchen> Cooler: »--|« is a valid operator name.
10:10 puma_ left
10:11 <quchen> Cooler: https://github.com/quchen/articles/blob/master/fbut.md#comment-syntax
10:11 <Cooler> you mean >>--|<< ?
10:11 cloudhead joined
10:11 <quchen> No, I did not mean that, but »>>--|<<« would also be a valid operator name.
10:12 <quchen> > let (--|) = "hello Cooler" in (--|)
10:12 <lambdabot> "hello Cooler"
10:12 <quchen> > let (--|) = (<>) in "hello" --| "Cooler"
10:12 <lambdabot> "helloCooler"
10:13 <pacak> > let (☭) = (+) in 10 ☭ 20
10:13 <lambdabot> 30
10:13 gmcabrita joined
10:14 sword865 joined
10:14 <pacak> > let (☭--+-) = (+) in 10 ☭--+- 20
10:14 <lambdabot> 30
10:15 <Cooler> what about ncomment?
10:15 <sophiag> why would ghci be telling me it can't load Control.Monad.Either?
10:17 <nuskin> cocreature: so L defines string literals, I integers, X is a terminating state and S for string
10:17 <Cooler> that page says theres no special cases with ncomment
10:17 <Cooler> but the rules are still weird
10:17 <quchen> Cooler: {- comments can be nested -}
10:17 paolino joined
10:17 <cocreature> nuskin: so what parameters am I supposed to pass to L as a user? a String and the rest of the format string?
10:18 <cocreature> or only the rest of the format string?
10:18 xtreak joined
10:18 <cocreature> I guess probably the latter
10:18 jer1 joined
10:18 xtreak joined
10:19 <nuskin> cocreature: the former
10:19 <Cooler> ncomment → opencom ANY seq {ncomment ANY seq} closecom
10:19 <Cooler> ANY seq → {ANY }⟨{ANY } ( opencom | closecom ) {ANY }⟩
10:19 <Cooler> wth is ANY seq
10:19 <cocreature> nuskin: so it’s a string constant instead of a string parameter?
10:19 cldr joined
10:19 <cocreature> nuskin: try http://lpaste.net/355416
10:19 <nuskin> cocreature: so my understanding from the examples is you need to take the string that's given as the first parameter, and then recursively call Format onto the second paramter
10:20 ski joined
10:20 mojjo joined
10:20 <nuskin> though I could be completely wrong
10:20 heyj joined
10:20 yellowj joined
10:21 <nuskin> I haven't been able to find any good textbook explanations of this and our lecturer simply said 'just think hard about the type magic and you'll get there eventually'
10:21 <cocreature> nuskin: does my code make sense to you?
10:21 <cldr> Hi there, newbie question. I'm in ch15 of the haskell book. Implementing monoids. My imports of Data.Semigroup and Data.Monoid conflict on (<>). Any way round this?
10:21 jedws joined
10:22 <nuskin> cocreature: what does the -> mean?
10:23 <mojjo> hi.. how would you implement a fn that behaves like this: ` f '-' ['A'..'C'] --> ["--A", "-B-", "C--"] ` I have a working implementation, but it looks quite awkward to me.. (http://lpaste.net/355417)
10:23 <cocreature> nuskin: constructors in Haskell are just functions. so this declares the constructor L as a function that takes a String, a format string (the rest of your format string) and returns a new format string
10:23 <nuskin> cocreature: so this is a type constructor, not a data constructor correct?
10:24 <cocreature> nuskin: no it’s a data constructor
10:25 <nuskin> cocreature: so are X L S I the constructors or is Format (fmt :: [*]) the constructor?
10:25 <cocreature> nuskin: Format is a type constructor, X L S and I are data constructors
10:26 meba joined
10:26 <cocreature> note that DataKinds gives you type constructors corresponding to data constructors if you prefix the names with ' (prefixing is not strictly always necessary but it’s good practise)
10:26 Wizek_ joined
10:28 <nuskin> cocreature: hmm I see. but I'm more confused now by the fact that the S and L type constructors being identical (in my head)
10:29 <cocreature> nuskin: ah I think I messed up the L constructor. what you really want is http://lpaste.net/355418
10:29 <nuskin> because they're both going to have a String as their first parameter and then a Format type as their second
10:29 <cocreature> L is a literal so it doesn’t add anything to the list of parameters "fmt"
10:29 <cocreature> http://lpaste.net/355418 might be what you’re looking for
10:32 <Cale> @let separate [] = []; separate (x:xs) = ([],x,xs) : [(x:us,v,vs) | (us,v,vs) <- separate xs]
10:32 <lambdabot> Defined.
10:32 <Cale> > map (\(us,v,vs) -> map (const '-') vs ++ v : map (const '-') us) (separate "ABCD")
10:32 <lambdabot> ["---A","--B-","-C--","D---"]
10:32 <nuskin> cocreature: that makes sense
10:33 notmyname1 joined
10:33 romank joined
10:33 oisdk joined
10:34 kuribas` joined
10:34 <nuskin> cocreature: I find that the syntax makes concepts like these a lot more convoluted than they ought to be
10:34 <nuskin> or that could be me just not used to haskell itself coming from a conventional programming background
10:35 <Cale> mojjo: ^^
10:35 <cocreature> nuskin: the fact that this fancy typelevel stuff was later bolted on to Haskell always makes it feel slightly awkward
10:35 <Cale> mojjo: Probably can do better still... somehow
10:35 zeroed joined
10:35 <cocreature> nuskin: it’s easier in a language designed for this such as Idris
10:35 <nuskin> I'd never heard of it before
10:36 sski joined
10:36 <cocreature> nuskin: btw what kind of course is that? that’s a very advanced exercise for a Haskell course imho
10:37 lazyunclebob_ joined
10:38 <lazyunclebob_> Hey haskellers, I've recently found my way to functional programming, and specifically Haskell, enjoying my trip so far.
10:38 kern joined
10:38 <nuskin> cocreature: it's the introductory functional programming/software design course at my uni
10:38 zeroed joined
10:38 nighty-- joined
10:38 <lazyunclebob_> Professionally I'm a web developer, specifically building API's, and I'd love to use Haskell to build API's, looked into Scotty, too barebones, looked into Yesod, but it has no API templates in Stack.
10:38 <cocreature> nuskin: puh, that’s some heavy stuff for an introductory course
10:38 <lazyunclebob_> Any recommendations for good frameworks?
10:39 hurkan left
10:39 xtreak joined
10:39 <nuskin> cocreature: I feel slightly better about myself you having said that
10:39 <Cale> lazyunclebob_: Snap and Happstack are two that I usually recommend
10:39 <Philonous> Is there any advantage to using :r in ghci over :l <filename> ?
10:39 <nuskin> you should see our second assignment...
10:39 <lazyunclebob_> Cale: does Snap have a good template for building an API?
10:39 louispan joined
10:40 <Cale> lazyunclebob_: I'm not exactly sure what that means.
10:40 <Cale> It should be easy enough to build whatever web API you want with it.
10:40 <nuskin> our first one was to write up some basic math equations to fulfill what physics dictates in a particle simulator
10:40 <lazyunclebob_> Cale: looking to build a RESTful API, PHP is too slow and inconsistent, so got into looking for some alternatives, Haskell seems just right.
10:41 <Cale> lazyunclebob_: There's also servant now -- I can never decide if it's brilliant or insane. It might be a bit of both. You construct a type which specifies how your API works, and it implements the server for you.
10:41 <nuskin> our second is creating a finite domain solver
10:41 <Philonous> lazyunclebob_, I really like servant. It makes good use of Haskell's type system
10:41 yaiyan joined
10:41 <Cale> I worry about recommending Servant to beginners though
10:41 <lazyunclebob_> I do feel like I qualify as a beginner.
10:41 erikd joined
10:41 ridho joined
10:41 <lazyunclebob_> I really like Yesod, but I'm really disappointed they do not have a pure template, well, they do, it's "yesod-pure", but it's 5 years old.
10:42 <Philonous> Yes, that's possibly a problem. If you're not used to a powerful type system it might be overwhelming.
10:42 <lazyunclebob_> And no longer supported or included in Stack.
10:42 <cocreature> nuskin: creating a finite domain solver might be difficult but you can probably implement it using a relatively small subset of Haskell. the typesafe printf function you’re supposed to write requires 5 extensions or so
10:42 zeroed joined
10:42 <Cale> lazyunclebob_: But anyway, Snap and Happstack and Servant all don't really have templates of any sort. They're just collections of libraries which make it relatively simple to build web servers.
10:43 <lazyunclebob_> Hmmm, I guess it's gonna be a bit of tinkering then.
10:43 <lazyunclebob_> Might go as far to create my own API template for Yesod or Snap.
10:43 <nuskin> cocreature: 5 extensions to make a finite domain solver or? the finite domain solver has a number of sub-tasks that they've given us
10:43 <Cale> I guess Snap has Snaplets, which I've never used.
10:43 jer1 joined
10:43 Elhamer joined
10:44 <cocreature> nuskin: I doubt you need any Haskell extensions to write a finite domain solver. but you do need them to write your printf function since standard Haskell does not allow for this kind of typelevel tricker
10:44 <cocreature> y
10:44 john joined
10:44 <Cale> lazyunclebob_: Most of the web applications I work on for work use Snap, but it's total overkill, since our applications are all single page applications which do most of their communication with the backend over a websocket connection.
10:44 <Cale> (so the webserver itself is pretty simple, with only maybe 5 or 6 routes to handle)
10:44 <Ulrar> Cale: So is snap any good ? I've been using yesod a lot
10:44 <Cale> It's okay
10:44 nick8325 joined
10:44 <lazyunclebob_> Cale: the company I work for builds almost everything as an API, which communicates with JS frontends.
10:45 <Ulrar> I have to say, having played with ocsigen (ocaml) a bit, I loved it
10:45 <Cale> lazyunclebob_: We use reflex-dom to write our frontends in Haskell
10:45 <Ulrar> so much simpler
10:45 <nuskin> cocreature: namely; turning untyped represantations into typed, writing a matching evaluator, checking for satisfiability and computing a solution set for logical formulas
10:45 <Cale> lazyunclebob_: It's very very nice to be able to write the frontend and backend in the same statically typed programming language, and have a guarantee that we'll never have issues with JSON encoding mismatch between them.
10:46 <nuskin> cocreature: ah as in Haskell extensions that we import, understood. I thought you were referring to extensions to the function printf that I'd have to create
10:46 {emptyset} joined
10:46 <Cale> (because the JSON encoders and decoders are constructed together automatically from the structure of the types, in code which is shared between the two)
10:46 <cocreature> nuskin: iirc the first exercise in the fp course at my university was to implement a "max" function that takes the maximum of 3 arguments instead of 2 like the builtin one :)
10:46 <lazyunclebob_> Cale: I can imagine, but our front-enders are weakly-typed fanatics
10:47 <Philonous> Cale, So you're using ghcjs for compiling Haskell to JS?
10:47 <Cale> Actually, the fact that we use JSON at all is a bit funny -- we could just as easily use a binary protocol, but it's easier to see JSON in Chrome's debugger.
10:47 <Cale> Philonous: yes
10:47 <nuskin> cocreature: what a time to be alive :)
10:47 <lazyunclebob_> Well I guess it's decided, I'll make my own Yesod template for API's.
10:47 <merijn> JSON is all fun and games until two files get the same inode because JS doesn't support actual integers
10:48 <Cale> and ghc to compile largely the same frontend code to ARM for mobile as well
10:48 <lazyunclebob_> With blackjack and wenches.
10:48 <Guest22651> I'm sorry to be disturbing. Could anyone tell me about the logic of groupBy, or how [[1],[2,3],[4],[5,6],[7],[8,9]] comes to be the result of 'groupBy (\x -> \y ->(mod (x*y) 3 ==0))) [1,2,3,4,5,6,7,8,9]'?
10:48 bram_ joined
10:48 <Philonous> Cale, I was thinking about trying that out, but the last time I checked the generated JS was gigantic. Is that solved, or do you just bite the bullet and hope caching will make load times not completely excruciating?
10:48 <Cale> Guest22651: groupBy will compare the first element of each group to the successive elements in the list to determine if they belong in the group or not
10:49 <Cale> Philonous: It's not so bad if you run it through the closure compiler and then zopfli it.
10:49 <Cale> But yeah, there are things which could yet be done to improve it.
10:49 <Philonous> Cale, Ah, so the trick is to post-process it. Do you happen to know what size you roughly end up with?
10:49 <Cale> also, the generated JS size is only constant term large, it's not like it grows rapidly with program size
10:50 <Cale> ~500kb or so
10:50 <Philonous> Sure, but even just 1 or 2 megabytes are already really bad for page load times
10:51 filterfish joined
10:51 <Philonous> 500kb is still sizeable, but maybe still OK
10:51 <Philonous> That's uncompressed, right?
10:51 <Cale> Our largest application is perhaps 3 MB, and that has a *lot* of stuff in it.
10:51 ub joined
10:51 <Cale> No, that's compressed.
10:51 <Philonous> Oh
10:51 Elhamer joined
10:51 <Cale> Er, the 3MB is uncompressed actually
10:51 <Guest22651> @Cale Looks like your reply does make sense. Thank you so much :-)
10:51 <lambdabot> Unknown command, try @list
10:51 <Philonous> Right, you said zopfli
10:51 jbgi joined
10:52 <Cale> actually, I'm uncertain, let me double check that
10:52 <nuskin> cocreature: thanks for your help so far, I'm gonna keep working on the second part to actually output a proper string given a format string
10:52 Elhamer joined
10:52 <Guest22651> Cale: Looks like your reply does make sense. Thank you so much :-)
10:52 <Cale> Guest22651: no problem
10:53 <Cale> Yeah, the 3MB was the compressed size. It's like 30MB uncompressed
10:54 <cldr> Hi, going through the haskell book. Confused. Is it possible to make a monoid with the type `newtype Identity a = Identity a`? It seems to me there's no obvious implementation for mempty? Am I missing something?
10:55 <Philonous> 30MB... blimey
10:55 <Cale> I'm fairly sure a lot of stuff could be done to get that down further, but it hasn't been a top priority thus far, because it's just a static file.
10:55 <Cale> Most YouTube videos are well above that :P
10:55 <Philonous> Sure, but you can watch while you stream. On a residential 3MBit line downloading the JS would take 10 seconds.
10:56 <Guest22651> :quit
10:56 <Guest22651> exit
10:56 <Guest22651> quit
10:56 <liste> Cale: you can do "instance Monoid a => Monoid (Identity a)"
10:56 Unode_ joined
10:56 soniku joined
10:56 <liste> cldr: ^
10:56 <liste> not Cale
10:56 <liste> sorry
10:57 <Cale> Philonous: We also can run the frontend code on the backend in a static page generation mode, and switch them to the live app once it's downloaded.
10:57 xplat|work joined
10:57 padfoot joined
10:57 <cldr> Hmmm. OK, let me try that. Having a tough time with these exercises. So, out of interest, how would you implement `mempty` for `Identity a`
10:57 <cldr> ?
10:58 <Philonous> Cale, Yes, I suppose could use a trick like that to make it bearable.
10:58 <Philonous> I guess I'll just have to try it and see where I end up.
10:58 <Cale> Philonous: I've never had any issue with the size anyway
10:59 <liste> cldr: there's not many ways to implement that
10:59 <Cale> Then again, I usually have no difficulty getting 80 Mbps.
10:59 <cldr> liste: :) are there any at all?
11:00 <Philonous> I'm on a 100mbit line, so it's not a problem for me personally, but I can't assume everyone is.
11:00 Elhamer_ joined
11:00 <liste> cldr: there is, if you have the Monoid a constraint
11:01 <liste> just "instance Monoid (Identity a)" is not possible
11:01 pellenation joined
11:02 <cldr> I see, good clue. Thank you.
11:02 jer1 joined
11:02 Snircle joined
11:04 <padfoot_maudrer> hey
11:04 <Cale> Philonous: It would be nice if it were more often reasonable to run the web application in a browser on mobile. We just compile a corresponding app for that, but perhaps if the size were a lot smaller, we could more often get away with it.
11:05 <padfoot_maudrer> can please someone suggest some good haskell projects for beginners ?
11:05 ub joined
11:06 ADG joined
11:06 patbecich joined
11:06 <ADG> when performing "do contents <- readFile "txt/13.txt";print . take 10 . show . sum . map read . lines $ contents" how to specify show (Intgeer/Double/etc?)
11:06 <ADG> it prints the first 10 digits of the sum
11:07 sproingie joined
11:07 <Cale> padfoot_maudrer: I dunno, it really depends on what sort of programs you enjoy writing.
11:08 <Cale> ADG: You could put the (sum . map read . lines $ contents) in parens, and then add a type annotation inside the parens, for which type you wanted the sum to be
11:08 <Cale> Or you could add a type signature to just the read or show
11:08 Dance joined
11:08 <Cale> (show :: Double -> String)
11:09 <mojjo> Cale: thanks for the code you send some half an hour ago. I'm still with the prob, I actually have something that looks ok clean (http://lpaste.net/355420)
11:10 <Cale> mojjo: Rather than take i pad
11:11 <Cale> You could write replicate i x
11:11 <ADG> Cale: like this "print . take 10 . show $ ((sum . map read . lines $ contents) :: Integer)"
11:11 <Cale> Oh, of course, you'd have to not shadow x there :)
11:11 <mojjo> Cale: oh true
11:11 <padfoot_maudrer> Cale will game development in haskell be a good place to start ?
11:11 <Cale> ADG: (sum . map read . lines $ contents :: Integer)
11:12 Klumben joined
11:12 frew joined
11:12 <ADG> what is the preecedence of "::" then?
11:12 <ADG> is there any preecedence table for haskell?
11:12 <Cale> padfoot_maudrer: Apart from the fact that games are among the most involved and complicated things one can write, it shouldn't be too bad
11:12 JuanDaugherty joined
11:12 <mojjo> Cale: well, I thought when taking from the same list twice (or more time) it might be faster.. but that's just a guess
11:12 ski joined
11:13 <merijn> padfoot_maudrer: Not worse than in other languages. But I think games are one of the worst things to start with to learn programming, since they're *hard*
11:13 <merijn> padfoot_maudrer: If you already have experience writing games in other languages it should mostly be fine
11:13 <Cale> ADG: :: isn't an infix operator -- it extends over the entire expression to its left (as far as it can go), and the entire type to its right
11:13 <ADG> thanks!
11:14 <ADG> well is there any table then?
11:14 <Cale> ADG: I think the Report might have a summary table
11:14 <Cale> you can also ask ghci with :info
11:14 <Cale> since anyone can define new infix operators at any point
11:15 <Cale> for example if you write :info (*)
11:15 <Cale> you'll see infixl 7 *
11:15 splanch joined
11:15 Levex joined
11:15 <Cale> The higher the number, the more tightly it will bind to its arguments
11:15 <Cale> and the 'l' indicates left associativity
11:16 <padfoot_maudrer> Cale Since I am new I am looking for a project through which I learn the basic and core concepts of Haskell and functional Programming especially MONADS
11:16 augur joined
11:17 agis joined
11:18 matuszak joined
11:18 <padfoot_maudrer> merijn I do not have prior experience in game development
11:18 <Cale> padfoot_maudrer: Perhaps something which involves a parser would be good. Pick up a library like attoparsec which defines a monad of parsers.
11:18 <merijn> padfoot_maudrer: Then I'd probably recommend starting with some simpler tasks
11:19 <Cale> I think I didn't properly appreciate the monad abstraction until I had used a parser combinator library.
11:20 <padfoot_maudrer> Cale Cool!! Thank you so much for the help ... any links you would suggest ?
11:22 fotonzade joined
11:22 <agis> Hey guys! I am trying to force a data type to hold only instances of Eq, but it seems that I am not doing it properly (ghc complains about "illegal qualified types"). I guess that this is impossible to do or I'm getting the syntax wrong
11:22 <agis> I am trying to do something like: data Test a = Test { myField :: (Eq a => a) }
11:23 <Cale> padfoot_maudrer: My problem is that all the resources I learned this stuff from are no longer around because it was over 10 years ago :)
11:23 <merijn> agis: Yeah, you generally don't want to do that
11:23 alem0lars joined
11:23 <merijn> agis: What do you hope this will accomplish?
11:23 <Philonous> «Eq a => a» means the value has the type a _for all possible a_. So it's an Int, a String, a Bool etc. all at the same time
11:24 jer1 joined
11:24 <Cale> n... no it doesn't
11:24 ub joined
11:24 <merijn> Philonous: That's not right
11:24 <Cale> a is still the type parameter there
11:24 <padfoot_maudrer> Cale: Okay cool..
11:24 <Philonous> I stand corrected
11:24 <merijn> What he has right now isn't legal Haskell. I have a suspicion of what he *thinks* he wants, but he shouldn't want that :p
11:24 <agis> merijn: afterwards I use that data type in different functions that require a to Eq a
11:25 <Philonous> Oh, I read a forall where there was none. My bad
11:25 <merijn> agis: Right, but those functions will then have an "Eq a" constraint, so having that in the datatype is useless :)
11:25 <Rembane> \o/ GADTS \o/
11:25 <agis> Ok, I was trying to move it to the datatype, bad idea I guess? Hahaha
11:26 <merijn> agis: Well, you *can* restrict a datatype to only work with 'Eq a', however that *doesn't* let you remove the Eq a from the functions
11:26 <merijn> agis: So instead of reducing how much you have to type 'Eq a', you're only uselessly making your datatype less flexible
11:26 doomlord_ joined
11:26 phaji joined
11:27 <* hackage> swish - A semantic web toolkit. https://hackage.haskell.org/package/swish- (DouglasBurke)
11:27 <agis> merijn: oooh ok, now the cryptic explanation I read before makes much more sense hahaha
11:28 <agis> Thanks merijn, that was super useful!
11:28 <Cale> padfoot_maudrer: https://www.schoolofhaskell.com/school/starting-with-haskell/libraries-and-frameworks/text-manipulation/attoparsec
11:28 <merijn> Golden rule: Beginners wanting to restrict datatypes almost ALWAYS want to avoid typing constraints on functions, but that's not possible :p
11:28 <Cale> padfoot_maudrer: That looks like a fairly decent tutorial
11:29 sillyotter joined
11:29 ridho joined
11:29 u-ou joined
11:30 <agis> Just curious, how could I restrict the datatype in case it was part of a module?
11:31 <merijn> agis: The main way to restrict things is to not export the constructor
11:31 <agis> In case it was exposed and I wanted to make more explicit that it is going to be useless if you build something in the datatype without it being Eq
11:31 <padfoot_maudrer> Cale Thanks!
11:31 <Cale> Oh, sorry Philonous -- it *does* implicitly forall there.
11:31 rashmirathi joined
11:31 <Cale> That's interesting
11:31 <Rembane> Hey! The hackage bot is back! Good times!
11:31 <merijn> agis: You could have "makeFoo :: Eq a => a -> Foo a" and hiding the constrctor of Foo
11:32 <Cale> Philonous: I was thinking of something like data T a = Eq a => T a
11:32 <agis> merijn: oooh cool. Super easy! Thanks man
11:32 xcmw joined
11:33 <merijn> agis: Although it doesn't make much sense, if all functions require Eq a anyway
11:33 <Cale> which btw agis, will actually mean what you wanted it to mean, but requires an extension.
11:33 <merijn> agis: For example, have a look at Data.Set
11:33 <Cale> (GADTs)
11:33 <Cale> @let data T a = Eq a => T a
11:33 <lambdabot> Defined.
11:33 <merijn> agis: You have "Data.Set.singleton :: a -> Set a" which doesn't require Ord
11:33 <Cale> @let f :: T a -> T a -> Bool; f (T x) (T y) = x == y
11:33 <Philonous> Cale, Then I was right purely by accident. I thought there was an explicit forall because I didn't read it properly.
11:33 <lambdabot> .L.hs:181:1: error:
11:33 <lambdabot> Multiple declarations of ‘f’
11:33 <lambdabot> Declared at: .L.hs:174:1
11:33 sdothum joined
11:33 <Cale> @let foo :: T a -> T a -> Bool; foo (T x) (T y) = x == y
11:33 <lambdabot> Defined.
11:33 <Cale> :t foo
11:34 <lambdabot> T a -> T a -> Bool
11:34 filterfish joined
11:34 <Cale> ^^ no constraint!
11:34 <merijn> agis: Bus since things like "union :: Ord a => Set a -> Set a -> Set a" require Ord you're indirectly forced to use it anyway
11:34 <Cale> We can do that because the dictionary for Eq gets packed up in the data constructor T
11:34 HoierM joined
11:34 ADG joined
11:34 <merijn> agis: The typechecker will stop people from using any "Test a" which doesn't have "Eq a" anyway :)
11:34 <ADG> how to make memoizable fibonacci numbers in hakell
11:34 Elhamer joined
11:34 Argue_ joined
11:34 <Rembane> ADG: There's a oneliner.
11:35 <merijn> Is there a least common multiple function somewhere in base?
11:35 <* hackage> HFitUI - The library for generating a graphical interface on the web https://hackage.haskell.org/package/HFitUI- (QSpider2017)
11:35 <Cale> :t lcm
11:35 <lambdabot> Integral a => a -> a -> a
11:35 <Cale> It's in the Prelude
11:35 <merijn> Cale: \o/
11:35 <Cale> > let fibs = 0 : 1 : zipWith (+) fibs (tail fibs) in fibs
11:35 <lambdabot> [0,1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,1597,2584,4181,6765,10946,...
11:35 spacecadetbrown joined
11:35 blep_blop joined
11:35 <Rembane> > let f a b = b:f a+b in f 1 1
11:35 <lambdabot> error:
11:35 <lambdabot> • Occurs check: cannot construct the infinite type: a ~ [a]
11:35 <lambdabot> • In the second argument of ‘(:)’, namely ‘f a + b’
11:35 xacktm joined
11:35 <agis> merijn: Yeah, you're right, and it seems that it will mess with other parts of what I'm doing, so I'll just stick to restricting the functions
11:35 <Rembane> > let f a b = b:f b a+b in f 1 1
11:36 <lambdabot> error:
11:36 <lambdabot> • Occurs check: cannot construct the infinite type: a1 ~ [a1]
11:36 <lambdabot> • In the second argument of ‘(:)’, namely ‘f b a + b’
11:36 <Rembane> Gah!
11:36 <Cale> > let lucas a b = a : lucas b (a+b) in lucas 0 1
11:36 <lambdabot> [0,1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,1597,2584,4181,6765,10946,...
11:36 <Rembane> lucas is strictly better than f.
11:36 <merijn> oh, wait...I suppose using lcm will fuck with my results...back to the "think hard" solution, then :)
11:36 <ADG> how does it work? in general for a function where i need to memoize what should i do?
11:36 petermw joined
11:36 sfcg joined
11:37 <Rembane> ADG: Do not recurse over the same things more than once.
11:37 <Cale> ADG: Well, in general, you might want to define a list or array or *some* datastructure containing the results
11:37 <Rembane> ADG: Maybe that's a quite hand wavy advice... hm...
11:37 <merijn> quot and div are identical for positive values, right
11:37 dmj` joined
11:37 <Cale> ADG: so long as that data structure remains in scope, its entries, once computed, will remain computed
11:38 <ADG> ok
11:38 <Cale> ADG: You can even define an array whose entries recursively refer to other entries of the same array, to do dynamic-programming style stuff.
11:38 psychicist__ joined
11:38 <ADG> nice
11:38 <Philonous> That only works for boxed arrays though, doesn't it?
11:39 <Cale> yes
11:39 JeanCarloMachado joined
11:39 <Cale> boxes are what enable polymorphism and laziness
11:40 hydraz joined
11:40 Elhamer_ joined
11:40 <mniip> Cale, I might have a better solution!
11:41 Dance joined
11:41 maambmb joined
11:42 <Cale> Oh, I should also mention data-memocombinators :)
11:42 <Cale> https://hackage.haskell.org/package/data-memocombinators-0.5.1/docs/Data-MemoCombinators.html
11:42 <Cale> https://hackage.haskell.org/package/data-memocombinators-0.5.1/docs/src/Data-MemoCombinators.html#bool
11:42 <mniip> > map peel [0..]
11:42 <lambdabot> [0,1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,1597,2584,4181,6765,10946,...
11:43 <Cale> This library defines a bunch of functions whose job it is to memoise the function they're given
11:43 <Cale> and which work on different domains
11:43 <* hackage> cabal2nix 2.2.1 - Convert Cabal files into Nix build instructions. https://hackage.haskell.org/package/cabal2nix-2.2.1 (PeterSimons)
11:43 <maambmb> guys, haskell noob, trying to sink my teeth into some IO. I'm trying to write a function that reverses the bytes in a file: https://pastebin.com/xwV9mPWP. I'm getting a "handle closed" error. how do I force the handle to stay open until I explictly close it at the end. Thanks!
11:43 <Cale> If you can understand the implementation of bool, the rest is just taking that same idea to various other types
11:43 <Unode> How do you usually deal with "BAD signature" errors when pulling dependencies (on stack).
11:44 <mniip> > let lucas a b = a : lucas b (a+b) in lucas 0 1 !! 1000000
11:44 <lambdabot> *Exception: stack overflow
11:44 <mniip> > peel 100000
11:44 <Cale> So what bool does, given some function g, is that it gives you back the result cond (g True) (g False)
11:44 <lambdabot> 2597406934722172416615503402127591541488048538651769658472477070395253454351...
11:44 <Cale> where cond t f True = t
11:44 <mniip> > peel 1000000
11:44 <mniip> oops
11:44 <lambdabot> 1953282128707757731632014947596256332443542996591873396953405194571625257887...
11:44 <Cale> and cond t f False = f
11:44 <mfukar> Unode report it to the package maintainers
11:45 danthemyth joined
11:45 <mfukar> The stack maintainers might want to know about it too
11:45 <Cale> Since (g True) and (g False) are bound to variables, once those variables are evaluated, they will remain evaluated so long as they don't get garbage collected
11:45 {emptyset} joined
11:45 <Cale> and if you hang on to the resulting function, they won't be
11:45 <Cale> (i.e. the parameters t and f)
11:46 xtreak joined
11:46 <quchen> mniip: I was about to ask you why the first one produces a stack overflow, and then remembered talking to you about the STG yesterday. :-)
11:46 <Cale> list does a similar trick, but for lists, and where it applies a memoiser for the elements.
11:47 jer1 joined
11:47 <mniip> quchen, my peel is a logarithmic matrix exponentiation thingy
11:47 <mniip> It can compute 'peel 1e7' on lambdabot before timing out
11:47 <Cale> and so using those two, you have list bool :: Memo [Bool] which is a memoiser for functions of binary strings, so at that point, any function whose argument can be turned into a binary string can be memoized.
11:48 rashmirathi joined
11:48 rashmira_ joined
11:48 g4k joined
11:49 <mniip> quchen, actually it's not apparent to me immediately. Does it stack overflow during evaluation of a bunch of additions that it built up
11:49 Filip_ joined
11:49 <quchen> Yup
11:49 <mniip> said additions being non-tail recursive and whatnot
11:49 <quchen> Make it »lucas a !b = …« and it should work
11:49 c4r50nz joined
11:49 <quchen> (Up to Lambdabot timeouts)
11:50 <mniip> > let lucas a !b = a : lucas b (a+b) in lucas 0 1 !! 1000000
11:50 <lambdabot> mueval-core: Time limit exceeded
11:50 <quchen> Tail recursion is not an issue in GHC. Function calls are not what blow up the stack, pattern matching is
11:51 <mniip> sure
11:51 <mniip> I'm talking about tail recursion in the imperative code
11:51 <mniip> not haskell code
11:51 <quchen> Ah, ok.
11:51 obihann joined
11:51 <mniip> like, to add two numbers is to enter them in sequence and then do magic on the boxes they evaluate to and then pop continuation
11:51 robertkennedy joined
11:52 <ertes-w> maambmb: don't use hGetContents
11:52 robkennedy joined
11:53 soniku joined
11:53 <ADG> Cale: what about thi https://hastebin.com/nayamewutu.pl?
11:54 jer1 joined
11:54 asmyers joined
11:54 <mniip> ADG, I would bind the 'map ... [1..]' to a global identifier
11:54 <ADG> will it work?
11:55 <mniip> also the body of collatzLength' is slightly terrible in terms of '1 + (1 + (1 + ...'
11:55 <Cale> ADG: Ah, collatzLength is interesting because you almost certainly *don't* want to memoize all of the values you come across
11:55 {emptyset} joined
11:55 <ADG> I want to, after all I am taking a maximum
11:55 <ertes-w> maambmb: you need to use B.hGet and B.putStr, and i recommend that you use strict ByteString in this case (mostly because there is no benefit in using the lazy one)
11:55 xtreak joined
11:55 <ADG> but not all above 1000000
11:55 <Cale> ADG: There will be occasional large values (way above the range you're exploring)
11:55 deank joined
11:55 <Cale> yeah
11:55 <mniip> was it 27 that jumped up to a few hundred k in the process?
11:56 fotonzade joined
11:56 <Cale> So let's do this the straightforward way by hand, defining an array
11:56 petermw joined
11:56 <ertes-w> maambmb: (i'm assuming that you want to reverse the file in constant memory)
11:57 <mniip> > takeWhile (!= 1) $ iterate 27 (liftA3 (`div` 2) ((+ 1) . (* 3)) even)
11:57 <lambdabot> error:
11:57 <lambdabot> • Variable not in scope:
11:57 <lambdabot> (!=)
11:57 <mniip> > takeWhile (/= 1) $ iterate 27 (liftA3 (`div` 2) ((+ 1) . (* 3)) even)
11:57 <lambdabot> error:
11:57 <lambdabot> • No instance for (Typeable c0)
11:57 <lambdabot> arising from a use of ‘show_M908406693332334994111434’
11:58 <mniip> > takeWhile (/= 1) $ iterate (liftA3 bool ((+ 1) . (* 3)) (`div` 2) even) 27
11:58 <mniip> there
11:58 <lambdabot> [27,82,41,124,62,31,94,47,142,71,214,107,322,161,484,242,121,364,182,91,274,...
11:58 <Cale> ADG: Oh, sorry, I didn't read your program carefully -- yes that sort of thing will work
11:58 <Cale> ADG: but you may want to lift that map collatzLength' [1..] out
11:58 conal joined
11:59 <Cale> (into its own definition)
11:59 <Cale> You're sort of relying on the compiler to do something there which isn't always an optimisation, but which it might do anyway
11:59 eacameron joined
11:59 ADG_ joined
11:59 <mniip> > maximum $ [1..1000] >>= (takeWhile (/= 1) . iterate (liftA3 bool ((+ 1) . (* 3)) (`div` 2) even))
12:00 <lambdabot> 250504
12:00 <ADG_> there is something wrong because it hung up my system I had to restart
12:00 <mniip> ADG_, you ate all the ram
12:00 <mniip> probably
12:00 <quchen> mniip: Woah, that code was Collatz!?
12:01 splanch joined
12:01 <mniip> yes
12:01 <quchen> I understand it now, but wow is that a strange version
12:01 <quchen> Cool use of liftA3 though!
12:01 <mniip> well, I wrote the lambda
12:01 <mniip> and I was like
12:01 acidjnk22 joined
12:01 <mniip> obviously this needs some liftA3
12:02 mkoenig joined
12:02 <ADG_> anyone know about time & memory limiting in linux... I found `timeout` thoguh
12:02 <mniip> premature pointfreeization
12:02 <mniip> ADG_, there's ulimit, but with modern ghc you want to use the RTS heap size
12:02 cschneid_ joined
12:02 <quchen> ADG_: https://github.com/quchen/dotfiles/blob/master/bin/util/limitmem
12:03 <quchen> ADG_: That file is there precisely for GHC. :-þ
12:03 <quchen> But GHC RTS settings are probably better.
12:03 netheranthem joined
12:03 <maambmb> ertes-w, correct
12:04 <maambmb> my approach is to read the file in chunks, going from the bottom back to the top
12:04 <maambmb> reversing as I go
12:05 xtreak joined
12:05 <Cale> ADG_: however, the (!!) there really slows things down a whole lot
12:05 <Cale> xs !! n takes O(n) time
12:05 <mniip> ADG_, found it
12:05 <mniip> +RTS -M4G -RTS
12:06 <ADG_> thinking of using hashmap!
12:06 <Cale> and you end up building much longer lists tham you'd want
12:06 <ADG_> mniip: what does it do
12:06 <maambmb> it seems as if I do readChunk more than once the handle closes
12:06 <mniip> limits the heap to 4 gib
12:06 <mniip> ADG_, your approach is inherently flawed
12:06 <mniip> while evaluating collatz length of N you will occasionally stumble into numbers on the order of N^2
12:06 <lpaste> Cale pasted “collatzLength memoised with an array” at http://lpaste.net/355422
12:06 <ADG_> so ./bin/a.out +RTS -M4G -RTS ?
12:07 <ertes-w> maambmb: hGetContents basically ruins the handle for future use
12:07 <mniip> ADG_, yes
12:07 <ertes-w> maambmb: if you want to use it, you should read its docs carefully, but i suggest that you simply don't use it
12:07 <Cale> ^^ that is *much* faster and doesn't consume nearly so much space
12:07 <ADG_> "Most RTS options are disabled. Link with -rtsopts to enable them"
12:07 <Cale> You could do the same by limiting the length of the list
12:07 <ertes-w> maambmb: lazy input is a bad idea in most cases
12:08 <Cale> but best to save lists for jobs they're good at
12:08 <Cale> Lists are basically only good for jobs where you're going to be iterating over those elements in order.
12:08 <maambmb> ertes-w, I've read that I should use the "iteratees" library
12:08 <maambmb> is that where I should look?
12:08 <Cale> They're terrible for random access
12:08 <maambmb> is that appropriate for what I'm doing
12:09 <Cale> maambmb: Perhaps more modern would be to use pipes
12:09 <hpc> "lists are loops waiting to happen" ;)
12:09 <maambmb> okay wicked
12:09 <maambmb> thanks
12:09 <maambmb> I'll check out "pipes"
12:09 rockfordal joined
12:09 cereal_killer_ joined
12:09 <Cale> maambmb: But wait, what was your actual question? :)
12:09 <Cale> maambmb: I based that off of the fact you mentioned iteratees
12:10 louispan joined
12:10 <maambmb> why does my pasted code not work (trying to reverse a file in constant memory by reading it backwards in chunks). Ertes-w pointed out that when I read a chunk using getContents, I'm also closing the handle, causing future reads to fail
12:10 <ertes-w> maambmb: we have quite a few stream processing libraries available, my favourites being machines and pipes
12:10 <Cale> maambmb: Oh, your actual problem is just that you're not allowed to hClose a handle which has been passed to hGetContents there.
12:10 patbecich joined
12:10 benl23 joined
12:10 <ertes-w> maambmb: i don't think you will benefit from stream processing here though, because if you read in blocks, you have shared state
12:11 <Cale> hGetContents will close the handle when you're done with the magic string it gives you.
12:11 <ADG_> Cale: you didn't use collatzLength ?
12:11 <Cale> ADG_: collatzLength' uses it
12:11 <ADG_> oh sorry you did
12:12 <ADG_> why not use it from cL~s
12:12 tuturto joined
12:12 <Cale> ADG_: The idea is that it looks in the array if the value it's looking up has an appropriately small index
12:12 jer1 joined
12:13 <Cale> ADG_: cL~s?
12:13 <ADG_> collatzLengths
12:13 <Cale> ADG_: Oh, because then you end up with an infinite loop
12:13 jchia joined
12:13 <ADG_> nice
12:14 <Cale> collatzLengths at the index i is defined to be collatzLength i
12:14 <Cale> and so collatzLength i can't just immediately try to look up the array at index i
12:14 <Cale> No work would get done
12:14 jutaro joined
12:15 <Cale> There are other ways we could wire up the same thing though
12:16 tomphp joined
12:17 <Cale> also, I could have used an otherwise guard, not sure why I didn't -- actually, I think it's just because I added that case with the guard at the top and didn't revise what I had below it
12:17 <mniip> also, to follow up, I did write a nonogram solver
12:18 <mniip> and it looks hella cool because it is slow and you can see the progress
12:19 <ertes-w> maambmb: practical note: it's not just easier, but also much safer to do the reversal using a separate file =)
12:20 <maambmb> ertes-w + Cale, thanks again for all the guidance
12:20 <maambmb> appreciate it
12:20 akl joined
12:21 louispan joined
12:22 etehtsea joined
12:22 <Cale> I do sort of think that it would be good for hClose on a semi-closed handle to result in an exception.
12:22 <* hackage> sqlcipher - Haskell binding to sqlcipher https://hackage.haskell.org/package/sqlcipher- (figo)
12:22 <Cale> Though I'm sure there's probably someone out there who would be very upset with that change
12:23 fbergmann joined
12:23 <Cale> mniip: Backtracking, or does it mostly solve them the way a human might?
12:23 <merijn> Cale: There's people who get upset about literally every sane change to Haskell libraries :)
12:24 troydm joined
12:24 <mniip> no backtracking
12:24 <mniip> absolutely deterministic
12:25 bkonkle joined
12:25 <mniip> for every marked row, calculate all possible positions of the runs, filter those that match with the known picture, take known set or known unset elements and integrate them into the picture marking columns that were modified
12:25 <mniip> and vice versa
12:27 freusque joined
12:27 oisdk joined
12:28 xormor joined
12:30 tomphp joined
12:31 hurkan joined
12:31 Elhamer_ joined
12:31 <lpaste> mniip pasted “nonogram solver” at http://lpaste.net/355423
12:31 <* hackage> sqlcipher - Haskell binding to sqlcipher https://hackage.haskell.org/package/sqlcipher- (figo)
12:31 <mniip> it's a bad-ish mix of lists and arrays tbqh
12:33 louispan joined
12:33 chlong joined
12:34 stevenxl joined
12:34 ski joined
12:34 tomphp joined
12:35 <stevenxl> Hi folks. I am trying to get my terminology straight. let's say I have the following data declaration: data Person = Person Name. Is the Person data constructor a unary data constructor?
12:37 schzwump joined
12:37 takle joined
12:38 blep_blop left
12:38 Sh4rPEYE joined
12:39 louispan joined
12:39 jer1 joined
12:39 kiltzman joined
12:39 <Cale> stevenxl: Yes, you could say that
12:40 <schzwump> can an applicative be alternatively defined so as to apply the (a -> b) to corresponding a's, instead of applying everything to everything?
12:40 <schzwump> can Applicative*
12:40 <Philonous> When writing web APIs I keep needing related bu slightly different records, each of with needs lens and aeson instances. Is there a good solution to get rid of that boilerplate?
12:40 <Cale> schzwump: Applicative itself doesn't specify anything like that
12:40 <schzwump> Cale: I know, let's say specifically with list
12:41 <Cale> schzwump: If you're talking about what happens with the list instance, yeah, see ZipList
12:41 <stevenxl> Cale: thanks. I was confused because I didn't see a type variable. However, `Person` (the data constructor) still has to be applied to an argument. The fact that there is no type variable in the declaration just means we know what type the argument must have.
12:42 louispan joined
12:42 cmdv joined
12:43 <schzwump> Cale: nice thanks, are there any other sensible Zip types?
12:43 <Philonous> So far I've come up with template haskell to create them automatically and a WithField (name :: Symbol) (field :: *) (b :: *) gadt, but neither seemed satisfactory
12:43 shlevy joined
12:43 Dance joined
12:44 <Cale> schzwump: Certain sorts of trees with labelled leaves would work
12:44 <shlevy> The pattern synonyms docs suggest you should be able to give a type signature, but I'm getting a syntax error. Do I need some extra extension?
12:45 paolino joined
12:45 oish joined
12:45 <Cale> Philonous: Why related but slightly different?
12:45 Big_G joined
12:46 <Cale> You can generate lens and aeson instances using Template Haskell
12:46 <Cale> ah, you mentioned that
12:46 eacameron joined
12:46 gehmehgeh joined
12:47 dinamyc joined
12:47 <schzwump> what about ((->) r)? Are there alternative Applicative instances of that?
12:48 <Cale> Try to write one
12:48 <schzwump> :/
12:48 {emptyset} joined
12:48 <Cale> No really :)
12:48 rellen joined
12:48 <Philonous> Well, for example say I want to handle users, so I have a User type. When querying users I want to return the time when they where created, so I have data User = User {name :: Text, created :: UTCTime}, but when creating new users it makes no sense to specify the creation time, so I need data CreateUser = CreateUser{ name :: Text }
12:48 <Cale> You'll be forced to come up with the existing instance
12:48 <schzwump> "theorems for free" or some such?
12:48 <Cale> If you just follow the types
12:49 <Cale> (r -> (a -> b)) -> (r -> a) -> r -> b
12:49 <phadej> the Monoidal version makes it quite obvious, mult :: (r -> a) -> (r -> b) -> r -> (a, b)
12:49 <Cale> So, imagine we're writing this
12:49 <Cale> We have f :: r -> (a -> b)
12:50 <Cale> and g :: r -> a
12:50 <Cale> and x :: r
12:50 <Cale> and we want b
12:50 <Cale> The only way to get b would be by using f
12:50 <phadej> @djinn (r -> (a -> b)) -> (r -> a) -> (r -> b)
12:50 <lambdabot> f a b c = a c (b c)
12:50 <Cale> So we know that our right hand side looks like f (... :: r) (... :: a)
12:51 <Cale> we only have one thing of type r, and we have no way to get other things of type r
12:51 <Cale> namely x
12:51 <Cale> So we know that our right hand side looks like f x (... :: a)
12:51 <mniip> about time I'd ask...
12:51 <mniip> what *are* free theorems
12:51 <Cale> and now we only have one way to get something of type a, namely g
12:51 <Cale> So we know that our right hand side looks like f x (g (... :: r))
12:52 <Cale> and so f x (g x) is the only option
12:52 <mniip> what makes a theorem free, and how are they proven
12:52 <Cale> https://people.mpi-sws.org/~dreyer/tor/papers/wadler.pdf
12:52 <phadej> mniip: "from a type of a polymorphic function we can derive a theorem that it satisfies"
12:52 <phadej> mniip: it's quite mechanical process
12:53 <Philonous> mniip, http://citeseer.ist.psu.edu/viewdoc/summary?doi=
12:53 drninjabatman left
12:53 cpennington joined
12:54 Elhamer_ joined
12:55 Nolrai joined
12:56 <fryguybob> merijn: You can never have enough timing data for concurrent primitives :D
12:56 plutoniix joined
12:56 umib0zu joined
12:57 <merijn> fryguybob: Well, this started as me trying to benchmark different channel implementations, because the benchmarks on, for example, unagi-chan are ridiculously unrealistic
12:57 yqt joined
12:57 FreeBirdLjj joined
12:57 <merijn> fryguybob: But benchmarking conccurent channel operations means I need a cheap way to synchronise threads. And before you know it, you're handwriting spinloops...
12:57 jer1 joined
12:58 camm joined
12:59 Anaxagorian joined
12:59 roconnor joined
13:01 Shish2 joined
13:01 <Sh4rPEYE> I have a question about do-notation. I understand that I can simply call an action on the current monad, but I don't get how that action can have any influence if I don use "<-". Example: I have defined a type Stack = [Int], push that pushes something onto it and pop which pops the first value.
13:02 <Sh4rPEYE> stackManip :: State Stack Int
13:02 <Sh4rPEYE> stackManip = do
13:02 <Sh4rPEYE> push 3
13:02 <Sh4rPEYE> pop
13:02 <Sh4rPEYE> pop
13:02 rann joined
13:02 <merijn> Sh4rPEYE: I would generally recommend beginners avoid do notation and use explicit >> and >>= until you get comfortable with that, which avoids this kinda confusion
13:02 <Sh4rPEYE> How does this work? Push 3 pushes "3" on the stack, but doesn't pass it along, does it? Newline is suger for >>
13:02 <merijn> Sh4rPEYE: See this explanation of do notation (and how to write things without it) https://en.wikibooks.org/wiki/Haskell/do_notation
13:03 <Sh4rPEYE> I've read that. Unfortunately this bit doesn't seem to be explained
13:03 <Guest80542> stackManip = push 3 >> pop >> pop
13:03 <merijn> Well, let's desugar
13:03 <merijn> "push 3 >> pop" -> "push 3 >>= \_ -> pop"
13:04 <merijn> What's push 3? presumably like "push x = modify (x:)" right?
13:04 <Sh4rPEYE> push :: Int -> State Stack ()
13:04 <Sh4rPEYE> push a = state $ \st -> ((), a : st)
13:04 <Sh4rPEYE> SOmething like "put"
13:04 <merijn> Right
13:04 <merijn> So
13:04 rann joined
13:04 <merijn> "state (\st -> ((), 3 : st)) >>= \_ -> pop"
13:04 <merijn> What's pop?
13:04 <Sh4rPEYE> get
13:05 <mniip> phadej, explain like I'm 5 years into haskell?
13:05 <Sh4rPEYE> pop :: State Stack Int
13:05 <Sh4rPEYE> pop = state $ \(x:xs) -> (x, xs)
13:05 <Sh4rPEYE> Not rly get actually *
13:05 <merijn> "state (\st -> ((), 3 : st)) >>= \_ -> state (\(x:xs) -> (x, xs))"
13:05 <merijn> Let's see what >>= does
13:06 matuszak_ joined
13:06 <Sh4rPEYE> Chain two "stateful functions"
13:06 <merijn> simplified version is "State x >>= f = State $ \s -> let (a, newState) = x s in f a newState"
13:08 <merijn> State $ \s -> let (a, newState) = (\st -> ((), 3 : st) s in (\_ -> state (\(x:xs) -> (x, xs)) x newState"
13:08 scopedTV joined
13:08 sproingie joined
13:08 <merijn> Let's simplify
13:08 iAmerikan joined
13:08 statusfailed joined
13:08 <merijn> State $ \s -> let (a, newState) = ((), 3 : s) in (\_ -> state (\(x:xs) -> (x, xs)) x newState
13:08 <merijn> and again
13:09 <merijn> State $ \s -> let (a, newState) = ((), 3 : s) in (\(x:xs) -> (x, xs)) newState
13:09 nurupo joined
13:09 jutaro joined
13:09 `micro joined
13:09 <phadej> mniip: is that sarcasm or not (I'm only 5 years into haskell myself)
13:09 <merijn> State $ \s -> (\(x:xs) -> (x, xs)) (3:s)
13:09 LeaChim joined
13:10 <merijn> State $ \s -> (3, s)
13:10 justin2 joined
13:10 Guest37310 joined
13:10 fosterite joined
13:11 dunx joined
13:11 bodisiw joined
13:11 whoisxy joined
13:11 <Guest80542> (>>=) "bind" in your case takes a State, applies a function to that State and returns that new State. And additionally could do something with an extra value passed arround
13:12 <kuribas`> Suppose I want to implement an interface for games. I have a datatype "data Game state move = Game {initState :: state, validmoves :: state -> [move], doMove :: state -> move -> state}". If I want a collection of games, do I need existential quantification to "hide" the type variables?
13:12 <mniip> phadej, I'm somewhere around 4
13:12 TCZ joined
13:12 <Sh4rPEYE> Of course, now I see it.
13:13 revprez_atlanta joined
13:13 <kuribas`> Or is there a better way?
13:13 <mniip> wait
13:14 <Sh4rPEYE> merijn: Thanks.
13:14 <mniip> is the free theorem the universality condition on the profunctor end?
13:14 <mniip> the "forall" in the type
13:14 <phadej> mniip: I'd say the the paper explains it well enough; cannot really condense into IRC message
13:14 <mniip> (I'm only half a paragraph into the paper)
13:14 <[exa]> kuribas`: what about saving it recursively? like a state that contains some state identification and list of valid moves together with next states
13:14 <[exa]> (nothing wrong with infinity here)
13:15 <kuribas`> [exa]: yeah, also possible
13:15 <kuribas`> So that would become: data Game = forall state move . Game {initState :: state, validmoves :: state -> [move], doMove :: state -> move -> state}
13:16 <[exa]> kuribas`: maybe if doMove would do something side-ish I'd go with doMove instead
13:16 xcmw joined
13:16 <kuribas`> [exa]: ?
13:17 danthemyth joined
13:17 carlomagno1 joined
13:17 permagreen joined
13:17 <kuribas`> [exa]: of course I could represent the game simply as a big tree.
13:17 simony joined
13:18 ChristopherBurg joined
13:19 <[exa]> side-ish as in doMove :: state->move->IO state or so
13:19 jer1 joined
13:19 <[exa]> but if you don't need it, I'd go with pregenerated structure of states, like State = [(Move, State)]
13:19 <kuribas`> [exa]: right. My idea was to keep it purely functional, but to have hooks into the UI for representing pieces, performing the actual moves, etc...
13:20 piyush-kurur joined
13:20 jutaro joined
13:21 <whoisxy> I'm very new to haskell I'm trying to implement an expresion which alternates between 2 values each time it's evaluated so far I have managed to produce a list of alternating values however I'm at a los on how to get anything but one of the values from it. I realise I'm probably running before I can walk but its a customazation I'm eger to implement now before I've finished learning the language this is
13:21 <whoisxy> my alternating list "[["hello", "bye"] !! (x `mod` 2) | x <- [0,1..]]" any ideas how I can use this as some kind of stack or any other better ways to alternate the value of an expression
13:21 fbergmann joined
13:22 <kuribas`> > concat $ repeat [1, 2]
13:22 <lambdabot> [1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2...
13:22 <whoisxy> by customization I mean to some software I'm currently running, I realize that word is out of context otherwise
13:22 <kuribas`> > cycle [1, 2]
13:23 <lambdabot> [1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2...
13:23 solidsnack joined
13:23 cpup joined
13:23 <whoisxy> kuribas`: no I need to acces alternating value as I said I've already got the list but if you read the first value its always the first value
13:23 <Philonous> whoisxy, What you are describing is impossible. Expressions always evaluate to the same value.
13:23 <kuribas`> whoisxy: yes, you need to remember the state.
13:24 <Philonous> whoisxy, That said, you can have _actions_ that return different values
13:24 <pacak> "Expressions always evaluate to the same value."
13:24 <pacak> Hold my beer!
13:24 spacecadetbrown joined
13:25 <pacak> https://github.com/tibbe/unordered-containers/issues/147 + https://ghc.haskell.org/trac/ghc/ticket/13615
13:26 MorTal1ty joined
13:27 <Philonous> Bugs and exceptions notwithstanding. You can also do some mischief with unsafePerformIO etc. of course. But I don't think this is relevant here
13:27 <kuribas`> nor would it work
13:27 <kuribas`> at least not as intended.
13:28 <whoisxy> kuribas`: what would be the best way to maintain the state
13:28 <pacak> whoisxy: state monad, unsafePerformIO + a global variable
13:28 <kuribas`> whoisxy: you have many options. Threading it, using a State monad, using IORef (if you are already inside IO).
13:28 <pacak> (state monad is better)
13:29 <kuribas`> pacak: it depends
13:29 <Philonous> Don't listen to pacak. Don't touch unsafeperformIO
13:29 <Philonous> You can use an IOref
13:29 <whoisxy> global vairables aren't possible atleast from what I'm imagining I coulding use this expression as a function for many diffrent functions if they all reference the same variable
13:30 antoine9298 joined
13:30 <whoisxy> s/coulding/couldn't/
13:31 kmels joined
13:31 `^_^v joined
13:31 <kuribas`> whoisxy: is the code in IO, or is it pure?
13:32 jangsutsr joined
13:32 <whoisxy> kuribas`: don;t know what you mean "in IO"
13:32 <Axman6> whoisxy: "functions" which behave differently each time they are called are fundamentally not functions - the result of a function is determined by _only_ their arguments
13:32 eklavya joined
13:32 <whoisxy> *don't
13:32 jathan joined
13:33 koserge joined
13:33 <Axman6> this a very important concept to understand. If you need a function to return two different values you need to pass it the information to tell it which one of the two computations to perform
13:34 hsk3 joined
13:34 <quchen> »Procedure« is a better word for »functions with side effects«.
13:34 <mniip> phadej, I think I'm missing something
13:34 <Axman6> whoisxy: are you following a book to learn Ha?skell
13:34 <mniip> how is parametricity defined if not with profunctor ends?
13:35 mizu_no_oto joined
13:35 Wizek_ joined
13:35 <whoisxy> Axman6: sortof http://learnyouahaskell.com , however this isn;t part of the book this is to do with xmonad It has keybindings and I want to create some keybindngs which alternate
13:37 <Axman6> well it sounds like you want a bool that is passed around 9or better yet, a data type which represents the two states better - data RedBlue = Red | Blue)
13:37 <whoisxy> Axman6: having functions always return the same output given the same input is fine with me but somewhow I need to alter the input of the next evaluation
13:37 <Axman6> whoisxy: then you need to give the function more information.
13:38 revtintin joined
13:38 <Axman6> I'm not familliar enough with how Xmonad works to know how to do that though I don't know if there's some user defined state which is passed around
13:39 jer1 joined
13:39 mmachenry joined
13:40 dbmikus joined
13:41 <Axman6> I believe there's an Xmonad channel though
13:41 <whoisxy> Axman6: is it not somethign thats really viable to do using haskell alone
13:41 gawen joined
13:42 <Axman6> what isn't?
13:42 <Axman6> uh, misread
13:42 ystael joined
13:42 <Axman6> of course it's possible, but magic functions which do different things each time you use them are better known as "bugs".
13:43 mrkgnao joined
13:43 mmo joined
13:43 acidjnk22 joined
13:44 <whoisxy> Axman6: I don;t care if its a function or any other way I can achive the same result
13:44 <whoisxy> for example similar to how python has generators
13:45 rashmirathi joined
13:45 oish joined
13:45 eschnett joined
13:46 <mmo> If anyone finds this useful: https://github.com/marcelmoosbrugger/hsudoku - An illustration of haskell-gi 's GTK bindings with a native sudoku game. It's one of my first haskell project. So feedback is appreciated.
13:46 CurryWurst joined
13:46 <Axman6> whoisxy: I'm trying to see if I can see how to do what you're after
13:48 <whoisxy> Axman6: thank you
13:49 meba joined
13:49 <* hackage> snap-core - Snap: A Haskell Web Framework (core interfaces and types) https://hackage.haskell.org/package/snap-core- (GregoryCollins)
13:49 locallycompact joined
13:50 <* hackage> snap-server - A web server for the Snap Framework https://hackage.haskell.org/package/snap-server- (GregoryCollins)
13:52 <Axman6> hmm, It's not obvious how you'd do it, maybe someone in #xmonad would know, and I have to go to sleep
13:52 dooml0rd joined
13:52 <whoisxy> Axman6: okay thanks for your help
13:52 <* hackage> openssl-streams - OpenSSL network support for io-streams. https://hackage.haskell.org/package/openssl-streams- (GregoryCollins)
13:54 simplething joined
13:56 darlan joined
13:56 jbalint joined
13:56 jbalint joined
13:57 moongazer joined
13:57 wenzowski joined
13:58 pavonia joined
13:58 <simplething> im having troubles with a simple list comprehension task summed up here: https://pastebin.com/h7kGr460
13:58 thoughtpolice joined
13:58 <simplething> having troubles with the syntax for adding another condition (and accessing the inner integers)
13:59 mmachenry joined
13:59 mmo left
13:59 <c_wraith> man, that just reminds me why I never use list comprehensions. I'm sure it's possible, but it's so much harder to think about than just using the map and filter functions
14:00 chrisM_1 joined
14:00 <seequ_> simplething: [[x | x <- sublist, x >= 6] | sublist <-xs, length sublist > 1]
14:00 <zaquest> whoisxy, seems like keybindings are monadic actions of type X () and X is a MonadIO, so you can use IORef. Or since X is also a MonadState XState (http://hackage.haskell.org/package/xmonad-0.13/docs/XMonad-Core.html#t:XState) where XState contains an extensibleState map that could be used to store something too.
14:00 epilys joined
14:00 jer1 joined
14:01 kuribas`` joined
14:01 padfoot_maudrer joined
14:01 <kuribas``> > let task xs = [sublist | sublist <- xs, length sublist > 1] in task [[1,4,76,3,23,6,3],[6],[8],[4]]
14:02 <lambdabot> [[1,4,76,3,23,6,3]]
14:02 <seequ_> simplething: Alternatively: map . filter (>= 6) $ filter (\s -> length s > 1) $ xs
14:02 Grisha joined
14:02 <Grisha> hi everyone
14:02 <simplething> seequ_ while your solutions works for the example input, another example input results in a wrong answer: [[1,4,76,3,23,6,3],[2,6],[2,3,6,9,8],[2,3,4]]
14:02 etehtsea joined
14:02 <seequ_> simplething: how so?
14:02 <epilys> I'm using Network.Simple.TCP's recv (up to 500KB), and I send a 320K file with netcat to the socket, but recv only returns 28.0K. Anyone know what's up? I made it recursive (recv'ing till result is Nothing) but then it just blocks
14:03 <c_wraith> seequ_: you did the operations backwards
14:03 <simplething> [[1,4,76,3,23,6,3],[2,6],[2,3,6,9,8],[2,3,4]]
14:03 <simplething> results in a list containing empty lists
14:03 <simplething> but one of the conditions was not having lists with less than 2 elements
14:03 <Axman6> I think it's supposed to filter out lists which have < 2 elements after filtering out all the numbers < 6
14:03 <Grisha> I’m trying to de-serialize (with the help of Aeson) data X = X {x_field1 :: Int, x_field2 :: String}
14:03 <seequ_> Ah, right.
14:03 Dance joined
14:03 cschneid_ joined
14:03 Argue joined
14:04 <Grisha> with defaultOptions { fieldLabelModifier = (“x_” ++)}
14:04 <Grisha> since in json there is no “x_” prefix
14:04 <Grisha> am I doing it right?
14:04 <whoisxy> zaquest: thanks but that I'm unsure how any of that helps me
14:04 <Grisha> I’m wondering what exactly fieldLabelModifier does
14:04 <lyxia> Grisha: fieldLabelModifier = drop 2 it goes the other way around
14:05 xificurC joined
14:05 <simplething> any suggestion as to why another example input results in a wrong answer?
14:05 <seequ_> > filter (\s -> length s > 1) . map (filter (>= 6)) $ [[1,4,76,3,23,6,3],[2,6],[2,3,6,9,8],[2,3,4]]
14:05 <lambdabot> [[76,23,6],[6,9,8]]
14:05 redcedar joined
14:05 <zaquest> whoisxy, if you have figured how to create a keybinding at all it shouldn't be too difficult to do what you want using http://hackage.haskell.org/package/xmonad-contrib-0.13/docs/XMonad-Util-ExtensibleState.html if you understand what typeclasses and monads are, otherwise you really should learn about them first
14:05 <Grisha> lyxia: the funny part is that my fieldLabelModifier has another part, namely, converting `type` into `typ` and `instance` into `instanc` and this part seems to be working :)
14:06 <simplething> oh, and im supposed to use primarily list comprehension. forgot to mention that one.
14:06 zariuq joined
14:06 <whoisxy> zaquest: thanks again
14:07 <Grisha> lyxia: is that the map from the labels in JSON to field names in Haskell or the other way around?
14:08 pie_ joined
14:08 <lyxia> Grisha: from Haskell to JSON field names.
14:08 u-ou joined
14:08 <Axman6> that seems backwards to me
14:09 <Axman6> @hoogle stripPrefix
14:09 <lambdabot> Data.List stripPrefix :: Eq a => [a] -> [a] -> Maybe [a]
14:09 <lambdabot> GHC.OldList stripPrefix :: Eq a => [a] -> [a] -> Maybe [a]
14:09 <lambdabot> Data.ByteString stripPrefix :: ByteString -> ByteString -> Maybe ByteString
14:09 <Grisha> lyxia: then I’m really wondering why my mapping “type” -> “typ” works…
14:09 <zaquest> whoisxy, if you don't understand typeclasses and monads yet, it might be easier to do it with IORef. show what you have in your config now, maybe i'll be able to tell something more specific.
14:09 crobbins_ joined
14:09 <Axman6> > Data.List.stripPrefix "x_" "x_field1"
14:09 theelous3 joined
14:09 <lambdabot> Just "field1"
14:10 <Grisha> Axman6: so if my Haskell fields have a prefix, I’ll have to add it, when reading in json with non-prefixed fields?
14:10 <seequ_> > let task xs = [s | sub <- xs, let s = [x | x <- sub, x >= 6], length s > 1] in task [[1,4,76,3,23,6,3],[2,6],[2,3,6,9,8],[2,3,4]]
14:10 <lambdabot> [[76,23,6],[6,9,8]]
14:10 <Grisha> those binary errors...
14:11 <seequ_> simplething: ^
14:11 Rodya_ joined
14:11 ystael joined
14:11 <lyxia> Grisha: it wouldn't make sense in the docs to write "fieldLabelModifier = map toUpper" otherwise
14:12 <simplething> seequ_ beautiful, thank you very much.
14:12 alx741 joined
14:12 dinamyc joined
14:12 <seequ_> simplething: we have different concepts of beauty :)
14:12 <exarkun> trying to meet the challenge in learnyouahaskell to implement fmap for Data.Map, don't really understand this error I've encountered: http://codepad.org/ydDIq8wk
14:13 <lyxia> Grisha: can you paste your code
14:13 pgiarrusso joined
14:13 matuszak joined
14:13 patbecich joined
14:14 <lyxia> exarkun: instance Ord k => Functorx (Map k)
14:14 pie_ joined
14:14 <Grisha> lyxia: this one works: http://lpaste.net/355425
14:14 Argorok joined
14:14 joelburget joined
14:14 <mauke> exarkun: right now you're saying all types k are an instance of class Map, provided the type Ord k is also an instance of Functorx
14:15 <mauke> small problem: Map is not a class and Ord is not a type
14:15 <whoisxy> zaquest: as you say it's porbably best I learn more before I attempt this http://bpaste.net/show/07ba6ba84dbc
14:15 <Grisha> lyxia: if this works, then adding `(“x_” ++) . ` in front of myMapper in the last string should also work
14:15 <Grisha> where’s the flaw in my logic?
14:15 afarmer joined
14:16 <Grisha> Axman6: does that look alright to you: http://lpaste.net/355425 ?
14:17 <exarkun> lyxia, mauke: okay, thanks, that kinda makes sense, though I guess it means I don't really understand the `instance` syntax.
14:18 alem0lars joined
14:18 dinamyc_ joined
14:19 Elhamer__ joined
14:19 Klumben joined
14:19 <mauke> exarkun: instance EXTRA_CONSTRAINTS => CLASS TYPE where ...
14:19 <mauke> exarkun: the "EXTRA_CONSTRAINTS =>" part is optional
14:19 Elhamer__ joined
14:20 <lyxia> Grisha: what's your type and instance like
14:20 <mauke> exarkun: in other words, the word after "=>" or "instance" is the class name you're trying to define an instance of
14:20 Elhamer__ joined
14:20 fendor joined
14:21 <exarkun> mauke: okay, thanks
14:21 <mauke> it looks like you were trying to do 'instance CLASS EXTRA_CONSTRAINTS => TYPE' but that's not how it works
14:21 Elhamer__ joined
14:21 <lyxia> Grisha: it doesn't work here. http://lpaste.net/355426
14:21 <Grisha> for the piece of code above `data X = X { typ :: String}`, `instance FromJSON X where parseJSON = genericParseJSON customJSONOptions`
14:21 juanpaucar joined
14:21 Elhamer__ joined
14:22 <Grisha> hm
14:22 Elhamer__ joined
14:22 robotroll joined
14:22 <lyxia> what's the JSON value? how are you parsing it?
14:22 mw joined
14:23 <Grisha> wait a sec
14:23 <Grisha> seems it’s not working here either
14:23 dan_f joined
14:23 <Grisha> lyxia: sorry about that, I was convinced the code was alright
14:24 <Grisha> you’re right, not working at
14:24 <Grisha> tremendeously not working
14:25 <Grisha> lyxia: you were 100% correct, it’s the other way around
14:25 <Grisha> stupid me
14:25 <lyxia> Don't worry.
14:26 <Grisha> lyxia: thanks a lot
14:26 mrkgnao joined
14:26 <Grisha> lyxia: the fields were all optional with Maybe, so I thought `there certainly was no field in json`
14:27 cdg joined
14:27 jer1 joined
14:28 refold joined
14:29 <Lokathor> if only the cabal file format could specify C files that things depended on, and then stack and cabal could try to download them automatically
14:29 joelburget joined
14:31 <* hackage> rethinkdb - A driver for RethinkDB 2.2 https://hackage.haskell.org/package/rethinkdb- (codedmart)
14:32 juanpaucar joined
14:32 xcmw joined
14:32 jabesed joined
14:32 juanpauc_ joined
14:33 juanpaucar joined
14:34 MDA2 joined
14:34 Silox| joined
14:34 stoopkid joined
14:34 <cocreature> Lokathor: if the number of C files is reasonably small, you can just bundle it in your cabal project.
14:35 <Lokathor> cocreature, in this case, I'm thinking about things like SDL
14:36 hurkan joined
14:36 <cocreature> yeah you probably don’t want to bundle that
14:36 <glguy> Certainly cabal shouldn't need to know about all of the package managers and operating systems and maintain ways to install various c library packages on various operating systems
14:36 xall_ joined
14:37 ralu joined
14:37 chrisM_1 joined
14:37 lexi-lambda joined
14:38 danthemyth joined
14:38 <Lokathor> glguy, if they knew about pacman, apt-get, and homebrew, they'd cover most cases. it'd even be helpful if there was a line that it could print when things went wrong, "the project says you probably want this C library, do you have it?"
14:38 Yuras joined
14:38 <Lokathor> of course, i understand that, as the glguy and not the sdlguy, you don't see the need, since GL drivers are already on most systems by default
14:38 <Lokathor> but trust me this would be handy
14:39 <glguy> yeah, it just would make sense
14:39 <glguy> not*
14:39 <Lokathor> ha
14:39 <Lokathor> good fix
14:40 shayan_ joined
14:40 <cocreature> also I’m not sure if the number of packages between the ones that you can just bundle and the ones that cabal wouldn’t be able to install automatically (packages like LLVM) is actually that large
14:41 drewr joined
14:41 burtons joined
14:42 <Lokathor> well perhaps custom scripts per package might be appropriate then
14:43 juanpauc_ joined
14:43 abhiroop joined
14:43 mpickering joined
14:43 camm joined
14:44 hackebeilchen joined
14:44 thimoteus joined
14:44 <cocreature> at that point you are reinventing system-level package managers
14:45 <cocreature> system-level is a bad term. but you are implementing a full package manager for C libs
14:45 michbad joined
14:45 jer1 joined
14:45 <Lokathor> i don't... what? It's not reinventing the package manager for, say, sdl2 to have a script that attempts to get the sdl2 files when it's installed in a local way, since there is almost always a way to attempt that on windows and linux at least (often on mac as well)
14:45 WhereIsMySpoon joined
14:46 <cocreature> so it should just fail if you don’t have the right version in your repo?
14:46 <WhereIsMySpoon> Hi, quick question to make sure I’m understanding terminology correctly - is a recursively implemented length function a monoid?
14:46 <Lokathor> it should print a warning that it couldn't find what it was expecting and that your use of the package is a lot less likely to work
14:46 <cocreature> I guess I don’t really see the problem with the current state. manually having to run "apt-get install" or whatever seems pretty painless
14:47 <Lokathor> cocreature, because windows and mac are less pretty painless, essentially
14:48 <cocreature> fair enough
14:48 whoisxy joined
14:49 gehmehgeh joined
14:49 eazar001 joined
14:49 al-damiri joined
14:50 cschneid_ joined
14:51 jutaro joined
14:51 WhereIsMySpoon joined
14:51 <cocreature> I guess I got confused because you said “pacman, apt-get and homebrew” would cover most cases but those seem exactly like the cases where there is only a very small benefit over just using them directly
14:51 <WhereIsMySpoon> Sorry, I got disconnected for some reason
14:51 uglyfigurine joined
14:51 <WhereIsMySpoon> I’ll repeat my question since I dont have a bnc :) is a recursively implemented length function (for a list, say) a monoid?
14:52 <lyxia> WhereIsMySpoon: no. A monoid is a set.
14:52 Tritlo joined
14:52 gehmehgeh left
14:52 <Grisha> lyxia: functions :: a -> a form a monoid under composition though, but it’s not the case
14:52 <Grisha> lyxia: is it true?
14:53 <Lokathor> Grisha, what's mempty for (a -> a) i wonder
14:53 <cocreature> id
14:53 teggi joined
14:53 <Grisha> Lokathor: id?
14:53 <lyxia> the set of endofunctions on a given type is a monoid
14:53 gehmehgeh joined
14:53 <Lokathor> i guess id counts
14:53 <WhereIsMySpoon> oh, I thought a monoid was an operation on a set
14:53 <WhereIsMySpoon> the heck is an endofunction
14:53 <WhereIsMySpoon> ive just started haskell
14:53 <lyxia> it makes no sense to say that a single function is a monoid
14:53 <WhereIsMySpoon> so be gentle :P
14:53 <Grisha> that’s true
14:53 <Lokathor> WhereIsMySpoon, Monoid is an interface that some data types support which lets you mush values together
14:53 <Grisha> I was hoping he was meaning smth like that
14:54 <cocreature> a monoid is a set and a binary operation on that set
14:54 <cocreature> e.g. integers and +
14:54 <Lokathor> things like String (++), Sum (+), Product (*), and so on
14:54 cyborg-one joined
14:54 <Grisha> a) monoid is an interface b) monot is a set
14:54 <Grisha> that’s why Haskell is highly popular :-)
14:54 <Grisha> *monoid
14:54 <lyxia> WhereIsMySpoon: we don't use "monoid" to refer to the operation itself
14:55 <Lokathor> cocreature, particularly in the case of pacman, there's a version of it bundled into msys2 with ghc, which stack can use or you can use yourself, but which is totally unobvious and that most guides do not talk about
14:55 DataComputist joined
14:55 <cocreature> Lokathor: oh I thought you were talking about archlinux’s pacman
14:55 Cooler joined
14:55 <Cooler> why is this correct?
14:55 <Cooler> push :: State [a] ()
14:55 <Cooler> push a = State $ \as -> (() , a:as)
14:55 <WhereIsMySpoon> In case it wasnt clear, I was talking about monoids in a general sense, not in any particular type sense
14:56 <Cooler> State doesn't take any arguments
14:56 <Lokathor> cocreature, the pacman program that msys2 bundles is based on the pacman from archlinux, because windows is so hopeless that bolting linux on top of it was all they could do :P
14:56 dsh joined
14:56 <Grisha> lyxia: now I’ve got a bunch of data types with fields with ugly prefixes (prefices?), but reading in json works like charm
14:56 <WhereIsMySpoon> Grisha: prefixae, surely :P
14:56 <lyxia> Cooler: the argument of State is a function
14:56 <cocreature> Lokathor: yeah, the fact that I keep forgetting that pacman is also a thing on windows hints at how often I use windows :)
14:56 eklavya joined
14:56 robotroll joined
14:57 <Lokathor> well if haskell had a better windows story I think its adoption rate could be a lot better over time
14:57 <WhereIsMySpoon> so to clarify - a monoid is a combined entity of a set and an operation on that set
14:57 <Cooler> lyxia, i mean push = State $ \as -> (() , a:as)
14:57 <WhereIsMySpoon> binary operation*
14:57 <Cooler> push shouldn't take arguments
14:58 <Cooler> actually push a = State $ \as -> (() , as)
14:58 <Cooler> actually push = State $ \as -> (() , as)
14:58 freusque joined
14:58 <lyxia> WhereIsMySpoon: by abuse of language we often call the set alone a monoid, with the binary operation being implicit
14:58 <Lokathor> WhereIsMySpoon, sorta. But "set" in the purely math sense, not like "set" in the computer science data type sense
14:58 stig joined
14:58 <WhereIsMySpoon> Lokathor: yes, thats what I meant by set :)
14:58 <Lokathor> :3
14:59 <lyxia> WhereIsMySpoon: the length function isn't a binary operation
14:59 <WhereIsMySpoon> re-learning mathematical notation is teh thing i look forward to least about re-learning haskell :P
15:00 <Grisha> WhereIsMySpoon: each time you can two things and combine it by a rule into a third thing of the same kind, you’ve got a monoid. For example, logs of, say, a http-server are not a monoid (in a useful way), but they summaries are: you can take summary of day1 and day2 and make another summary for both days
15:00 xall_ joined
15:01 Silox| joined
15:01 <Cooler> i am missing something why not push :: State [a] ()
15:01 <Cooler> push = State $ \as -> ((), as)
15:01 <mrkgnao> Additionally, we also want there to be a thing e that is an "identity" for the rule, i.e. applying the rule to e and anything else gives you back the latter.
15:01 dinamyc_ joined
15:01 <Lokathor> Grisha, I'd imagine that the logs are a list of entries of some sort though, and the List type is a Monoid at least
15:01 <Grisha> Cooler: check the definition of `data State`
15:02 <cocreature> Cooler: that doesn’t do anything.
15:02 <Cooler> where
15:02 <cocreature> you want push to push something
15:02 <Grisha> Lokathor: you’re right, of course, they are monoid in the sense of being strings of bytes
15:02 <WhereIsMySpoon> lyxia: whys that, or what makes an operation binary
15:02 <WhereIsMySpoon> right
15:02 <WhereIsMySpoon> makes sense
15:02 <WhereIsMySpoon> thanks!
15:02 <cocreature> so it has to take the argument that is being pushed
15:02 <Cooler> cocreature, i know but why can push take arguments? its just a value of type State [a] ()
15:02 <cocreature> Cooler: it’s not. it’s a function a -> State [a] ()
15:03 <Grisha> Cooler: given a (what to be pushed), push returns a state
15:03 <Grisha> `State` being a misnomer
15:03 <Cooler> cocreature, what? thats not the type signature push :: State [a] ()
15:03 <Grisha> it’s rather StateTransformer
15:03 <cocreature> Cooler: then that’s a type error :)
15:03 <Lokathor> Grisha, I don't mean the entries themselves are Monoids. i mean the logs as a whole are, since logs are lists of entries, essentially
15:03 <Cooler> cocreature, http://brandon.si/code/the-state-monad-a-tutorial-for-the-confused/
15:04 <cocreature> Cooler: even blogposts can contain mistakes :)
15:04 <Grisha> Lokathor: hm, what if those entries are not like each othe? some are warnings, some are errors and some are normal events with diff structure?
15:04 augur joined
15:04 dinamyc__ joined
15:04 <cocreature> Cooler: try it out. GHC will yell at you
15:04 <WhereIsMySpoon> Grisha: theyre still all loggable events
15:05 mizu_no_oto joined
15:05 FreeBirdLjj joined
15:05 <lyxia> WhereIsMySpoon: it should be a function that maps two elements of the set to an element of the set.
15:05 rlr joined
15:05 splanch joined
15:06 <WhereIsMySpoon> sure, like ++ does for lists
15:06 nominolo joined
15:06 <Grisha> WhereIsMySpoon: how would you compose a warning entry and an error entry into one entity?
15:07 jer1 joined
15:07 flatmap13 joined
15:08 <WhereIsMySpoon> i dont think it really matters
15:08 <WhereIsMySpoon> this is all a hypothetical situation anyway, ive gotten the point
15:08 bennofs joined
15:08 mada joined
15:09 sproingie joined
15:09 sproingie joined
15:09 spinda joined
15:11 <Cooler> is this correct?
15:12 <Cooler> put :: s -> State s ()
15:12 <Cooler> put s = State $ \_ -> (s,())
15:12 <Cooler> put s = State $ \_ -> ((), s) seems more correct
15:12 <mauke> depends on the definition of your State type
15:12 <Cooler> since its s -> (a, s)
15:12 psychicist__ joined
15:13 Rodya_ joined
15:13 dinamyc joined
15:14 gehmehgeh joined
15:15 rashmirathi joined
15:16 gridaphobe joined
15:16 ilyaigpetrov joined
15:16 urodna joined
15:17 <Cale> Cooler: If it's s -> (a,s), then you want the second one, yeah
15:17 <Cooler> Cale, isn't that the standard definition?
15:17 mstruebing joined
15:18 <Cale> Cooler: s -> (s,a) is a very slightly better definition, but it's not the one we inherited from mtl
15:18 patbecich joined
15:18 <Cooler> what mtl standard for btw?
15:18 <Cooler> does*
15:18 <Cale> Monad transformer library
15:19 <Cale> The reason it's better is that (,) s is also an instance of Functor
15:19 <Cale> So State s decomposes into (->) s and (,) s
15:19 raichoo joined
15:22 bvad joined
15:22 dinamyc_ joined
15:23 <Cooler> why doess the state from Control.Monad.State start with a small letter?
15:23 <Cooler> does*
15:23 <Cale> Because it's not a data constructor
15:24 <Cooler> it says variable state
15:24 <Cale> State s is defined as a type synonym for StateT s Identity
15:24 <Cale> So the only data constructor there is StateT
15:24 <Cale> In the past, there was a separate newtype State
15:25 <Cale> But at some point along the way, it got dropped in favour of just always using StateT
15:25 <Cooler> Cale, well theres a type State s
15:25 cschneid_ joined
15:25 <Cooler> type State s = StateT s Data.Functor.Identity.Identity :: * -> *
15:25 <Cooler> -- Defined in `Control.Monad.Trans.State.Lazy'
15:26 Gurkenglas joined
15:26 Hunter1_ joined
15:27 jer1 joined
15:27 <Cooler> why can't i use State as a data constructor?
15:28 mr_sm1th joined
15:28 deank joined
15:28 <pavonia> There's not data constructor State
15:28 <Cale> You could if it were actually defined anywhere
15:29 <Cale> But it's not
15:29 <Cale> Not in transformers or mtl anyway
15:29 <Cooler> State is type aliased to StateT
15:29 mizu_no_oto joined
15:30 <Cooler> if its type aliased why can't i use State
15:31 <pavonia> It's a type alias, so you can use it as a type
15:32 epilys left
15:32 <pavonia> But there is no new data constructor introduced here
15:32 <Cooler> but theres a new type constructor?
15:32 <Cale> Just a type synonym
15:33 sbauman joined
15:33 <Cale> type State s = StateT s Identity
15:33 <Cooler> how do i use StateT\
15:33 doomlord_ joined
15:33 <Cale> If you're learning and you just want to focus on the implementation of State alone, I would recommend just defining one for yourself
15:33 peteretep joined
15:34 <Cale> newtype StateT s m a = StateT { runStateT :: s -> m (a,s) }
15:34 zq joined
15:34 <Cale> It's just like State, except that instead of merely producing a pair of the result and final state, you produce a computation in the monad m which will compute those things
15:35 kmels joined
15:35 oisdk joined
15:36 <Cooler> you guys use an IDE? i get tried of switching back and forth between notepad++ and ghci in console
15:36 <Cooler> tired*
15:36 <Cale> nope
15:36 <Grisha> I find it confusing though that in order to appreciate StateT, you’ve got to understand what State is for and what a transformer is good for
15:36 <Cale> I just use a bunch of terminals and Sublime Text
15:37 xcmw joined
15:37 <Cale> I also sometimes use ghcid
15:37 <frontendloader> haskell's really lacking in the editing tools department :(
15:37 jabbslad joined
15:37 <Cale> which is a simple tool that displays the current errors/warnings, and updates itself whenever a file is changed
15:38 <Cale> It's the main useful part of an IDE
15:38 Despite joined
15:38 buglebudabey joined
15:38 <Cale> For getting around in the code, I use hasktags to generate a tags file
15:38 ogrady joined
15:38 rcschm joined
15:38 dinamyc joined
15:38 <buglebudabey> what libraries do you all use for high level GUI stuff? any FRP stuff you recommend?
15:38 afarmer joined
15:38 <Cale> Reflex is pretty sweet :)
15:39 aporia joined
15:39 <dysfun> transient looks cool but i haven't had a proper play yet
15:39 jer1 joined
15:39 davean joined
15:39 xall_ joined
15:40 <dysfun> can you get hot reloading in dev going with reflex?
15:40 Shatnerz0 joined
15:41 <Cale> I'm not sure what hot reloading refers to -- depending which branch and compiler you're using, you'll have different options.
15:41 <buglebudabey> Cale, would reflex be useful for let's say a client side GUI app?
15:41 entuland joined
15:41 <Despite> Question regarding lazy evaluation. Supposed to write a program that creates a list xs of tuples (x,y,z) with x, y and z coming from infinite lists of natural numbers using list comprehension. For every x,y and z, the term ‘elem‘ xs should terminate at one point. How do i manage that?
15:42 <Cale> buglebudabey: Sure, so long as the UI for your app is something that you can imagine building as a web application, it'll work. You can compile with GHC to get a native code application that manipulates the DOM directly inside a webkit browser.
15:43 <Cale> Or compile with GHCJS to get Javascript, and run your app in a web page.
15:43 zero_byte joined
15:43 <Cale> You could also use Reflex but not Reflex-DOM in a more general way
15:44 <Cale> with other GUI libraries or even not for GUIs at all
15:44 <Cale> But Reflex-DOM is the most well-developed way so far because it's how we make money
15:44 yellowj joined
15:45 <buglebudabey> Cale just reflex is what I had in mind because I'm not crazy about running it on a web page, but would you say reflex dom is easier to use as a result of it being most well-developed? at the end of the day i'm looking for something to make for me and my friend to use but to have it scalable for others down the line
15:46 <Cale> Well, it's easier because you won't have to build your own reflex binding to some other GUI library
15:47 jzeus joined
15:47 <buglebudabey> Cale ok I think that's enough to convince me to use it. I could host it on my hakyll blog you think?
15:47 <Cale> I'd love to see someone do reflex-gtk, but it's quite a large amount of work to start in on.
15:47 dinamyc_ joined
15:47 cereal_killer_ joined
15:47 <Cale> Yeah, sure.
15:48 <buglebudabey> awesome, thank you
15:48 mkoenig joined
15:49 jmelesky joined
15:49 quobo joined
15:49 <buglebudabey> Cale it's capable of doing simple stuff like drawing shapes and stuff?
15:50 Itkovian joined
15:50 meng_ joined
15:50 zq left
15:50 <Cale> buglebudabey: You could use SVG for that -- I've dynamically constructed SVG with Reflex -- you have to be aware of the element namespaces, but otherwise it's doable.
15:51 <buglebudabey> alright, thanks
15:51 zq joined
15:52 <Cale> If drawing simple shapes is the main thing you want to do, you might also have a look at gloss (and there's also reflex-gloss)
15:52 <zq> i'm getting an error from invoking `cabal install --deps-only`: 'ghc: could not execute: /usr/bin/gcc' why is ghc looking gcc, and what's the flag to tell it the right path?
15:52 skeet70 joined
15:53 tromp joined
15:54 doomlord_ joined
15:54 <lyxia> --with-gcc=mygcc
15:55 <lyxia> Does one of your dependencies have some C stuff
15:55 meng_ joined
15:56 <zq> lyxia: that's not ghc flag, or at least not listed in https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/flags.html
15:56 <clamchowder> has anyone looked into the pandoc code? I have a question about it: What does Text.Pandoc.Parsing do, compared to the code of the specific reader / writers?
15:56 <zq> the problem is ghc, not cabal
15:56 <zq> i've already set the gcc location in .cabal/config
15:57 <zq> i've tried --ghc-options='-pgmc alternate-gcc' but that has no effect
15:58 <clamchowder> Which one converts a file into an AST, Text.Pandoc.Parsing, or a specific reader, say Text.Pandoc.Reader.MediaWiki?
15:58 <Cale> zq: Which platform?
15:58 <zq> Cale: linux
15:58 <zq> why does that even matter
15:58 <zq> x86_64-unknown-linux-gnu
15:58 <Cale> Just curious, I've never seen that.
15:58 <zq> /usr/local/bin/ghc -c /tmp/1804289383846930886.c -o /tmp/16816927771714636915.o -pgmc clang -pgml clang -fllvm
15:58 <zq> ghc: could not execute: /usr/bin/gcc
15:58 <zq> from cabal --verbose
15:59 <Cale> It can matter, because, e.g. OS X is rather weird about where it puts gcc
15:59 <zq> the problem is ghc not obeying the flag, which implies either the wrong flag or idk
15:59 DataComputist joined
15:59 Wizek_ joined
16:01 <lyxia> zq: have you tried -pgmP clang too
16:01 <Cale> ah
16:01 zeroed joined
16:01 <Cale> ghc --print-libdir
16:01 <Cale> and then go to that directory and have a look at the file called "settings"
16:01 jsgrant_om joined
16:01 oisdk joined
16:01 <Cale> There will be a line in there with the path to the C compiler
16:02 Dookie12 joined
16:02 rkazak joined
16:03 juanpaucar joined
16:03 <zq> Cale: that worked. thank you!
16:04 mizu_no_oto joined
16:05 DataComputist joined
16:05 mjora7 joined
16:06 Swizec joined
16:06 jer1 joined
16:06 michaelw joined
16:07 <Cooler> i get a variable not in scope error
16:07 <Cooler> State $ \s0 -> (f a, s2) where
16:07 <Cooler> (f, s1) = statef1 s0
16:07 <Cooler> (a, s2) = statef2 s1
16:07 xcmw joined
16:07 revprez_atlanta joined
16:07 <Cooler> it says s0 isn't in scope
16:08 <monochrom> Use let. where is not for this.
16:08 trism joined
16:09 oberstein joined
16:09 exferenceBot joined
16:10 Sonolin joined
16:10 <Cooler> monochrom, well that works
16:10 <Cooler> but why
16:10 <monochrom> In "f x = expr where y=z" the where clause is outside the expr. The where clause cannot see local vars inside expr. The where clause can only see f and x.
16:10 zzz joined
16:10 descender joined
16:10 <monochrom> The where clause "belongs" to "f x =". It does not belong to expr.
16:11 <monochrom> Despite what Landin would love to do.
16:12 SpinTensor joined
16:12 Luke joined
16:14 meandi_2 joined
16:14 netheranthem joined
16:15 Itkovian joined
16:16 krok_ joined
16:17 sendak joined
16:17 LKoen joined
16:17 <Cale> Yeah, the difference between where and let is that where is actually part of the syntax of pattern matching constructs -- it exists to scope over multiple guards
16:18 pera joined
16:18 danthemyth joined
16:19 netheranthem joined
16:20 cschneid_ joined
16:20 <Despite> Hello everyone, problem: Im having a list xs of all triples (x,y,z), where x y and z are natural numbers. So basically an infinite list. My task is to be able to calculate with this list, so that (a,b,c) elem xs terminates for any a, b and c. How do it do that? right now im having: https://pastebin.com/9snzL8xH which isnt terminating, nor is it sav
16:20 <Despite> ing it to xs. Any volunteers?
16:20 patbecich joined
16:21 <Despite> I know it has something to do with lazy evaluation, but i cant make a connection quite yet.
16:22 <monochrom> Will not terminate in the False case.
16:22 <monochrom> Will only be True or nontermination.
16:22 mmachenry joined
16:23 <Despite> i know, but the conditions are that both (x,y,z) are natural numbers, and the request (a,b,c) are natural numbers. So it has to terminate at one point, depending how high the request is
16:23 Itkovian joined
16:24 mda1 joined
16:24 <Despite> My task is to basically create a list of (x,y,z) that allows the termination to happen
16:24 <monochrom> Oh! Right, I misread, what I said was not the reason.
16:24 jer1 joined
16:24 <LKoen> I think your list is correct
16:25 <LKoen> maybe it "doesn't terminate" because you typed it in somewhere where the compiler thought you might want it to be displayed
16:25 <LKoen> which won't work well if it's infinite
16:25 <monochrom> > [(x,y,z) | x<-[0..2], y<-[0..2], z<-[0..2]]
16:25 <lambdabot> [(0,0,0),(0,0,1),(0,0,2),(0,1,0),(0,1,1),(0,1,2),(0,2,0),(0,2,1),(0,2,2),(1,...
16:25 <Despite> if i try to check if (a,b,c) is element of this list xs, its never terminating. So my solution, unforunately, is not correct. Seems to easy, too.
16:25 <Cale> That list is incorrect, because it'll never get past x = 0 and y = 0
16:26 <Cale> You want to diagonalise in some fashion
16:26 <LKoen> ohhhhhh right, I get the question now
16:26 <Cale> You might do this by iterating over the possible sums x + y + z
16:26 <monochrom> Yeah, you will be stuck in (0,0,0), (0,0,1), (0,0,2) ... (0,0,n), (0,0,n+1).... this part does not end so there is no (0,1,0) to speak of.
16:26 <Cale> and then for each possible x from 0 up to the sum, iterate over the possible sums y + z
16:26 <monochrom> Look up "dovetailing" for how to do this right.
16:27 <EvanR> monochrom: non standard numbers ftw
16:27 <monochrom> It's precisely why "dovetailing" is a thing.
16:27 <monochrom> nonstandard numbers are irrelevant.
16:27 <Cale> > [(x,y,z) | s <- [0..], x <- [0..s], s' <- [0..s-x], y <- [0..s'], let z = s' - y]
16:27 <lambdabot> [(0,0,0),(0,0,0),(0,0,1),(0,1,0),(1,0,0),(0,0,0),(0,0,1),(0,1,0),(0,0,2),(0,...
16:27 <Cale> oops
16:28 dfeuer joined
16:29 <Cale> > [(x,y,z) | s <- [0..], x <- [0..s], y <- [0..s-x], let z = s' - y]
16:29 <lambdabot> error:
16:29 <lambdabot> • Variable not in scope: s'
16:29 <lambdabot> • Perhaps you meant one of these:
16:29 <Cale> > [(x,y,z) | s <- [0..], x <- [0..s], y <- [0..s-x], let z = s - x - y]
16:29 <lambdabot> [(0,0,0),(0,0,1),(0,1,0),(1,0,0),(0,0,2),(0,1,1),(0,2,0),(1,0,1),(1,1,0),(2,...
16:29 <Cale> there
16:30 <Cale> don't need to enumerate sums of the last two obviously -- we already know it's got to be s - x
16:30 Qommand0r joined
16:30 govg joined
16:31 mmn80 joined
16:31 oberstein joined
16:31 <Cale> So that's a relatively fair way to do it
16:32 <Cale> There are also less fair ways
16:32 <Cale> "fairness" being measured in terms of how rapidly we explore new values for each of the components
16:33 <Cale> We can define an interleaving operator on lists
16:33 <Cale> @let [] /\/ ys = ys; (x:xs) /\/ ys = x : (ys /\/ xs)
16:33 <lambdabot> Defined.
16:33 mmhat joined
16:34 <Despite> very interesting. Ill look into that, thank you!
16:35 <Cale> > foldr (/\/) [] [[(x,y) | y <- [0..]] | x <- [0..]]
16:35 <lambdabot> [(0,0),(1,0),(0,1),(2,0),(0,2),(1,1),(0,3),(3,0),(0,4),(1,2),(0,5),(2,1),(0,...
16:35 <Cale> Note that every other element of this list has 0 as its first component
16:36 <Cale> and then every other element of those which remain have 1 as their first component
16:36 <Cale> and so on
16:36 <Cale> and of course, we can extend this once more
16:37 <LKoen> if you define a function f such that f n = (power of 2 in prime factorization of n, n / 2^x), then this should work: [(x, y, z) | n <- [1..], let (x, n') = f n, let n'' = (n'-1)/2, let (y, n''') = f n'', let z = (n'''-1)/2 ]
16:37 <Cale> > foldr (/\/) [] . foldr (/\/) [] $ [[[(x,y,z) | z <- [0..]] | y <- [0..]] | x <- [0..]]
16:37 <lambdabot> [(0,0,0),(1,0,0),(0,0,1),(0,1,0),(0,0,2),(1,0,1),(0,0,3),(2,0,0),(0,0,4),(1,...
16:37 tzh joined
16:38 gawen joined
16:38 <LKoen> it uses the bijection NxN -> N\{0} (i, j) -> 2^i (2j+1)
16:38 sssilver joined
16:40 <LKoen> hmm, actually it doesn't work, because n'' can be zero
16:41 <LKoen> this can be fixed by defining n'' = (n'-1)/2+1 instead
16:41 jzeus joined
16:41 <LKoen> I don't know why anyone would want to use this method, though
16:44 metaporia joined
16:46 jer1 joined
16:47 <monochrom> A bijection is preferrable because it has no redundancy.
16:47 padfoot_maudrer joined
16:48 <EvanR> is there any use in making a function field strict
16:49 <monochrom> Yes if the function term is "if blah blah then (\x -> x+1) else (\x -> x * 4)"
16:50 <monochrom> where blah blah may be "insert 42 into my set. does my set have more than 20000 elements now?"
16:50 yrdz joined
16:50 <EvanR> mkay
16:51 zq left
16:55 mohsen_ joined
16:55 ludat joined
16:56 metaporia joined
16:56 eklavya joined
16:58 Swizec joined
16:59 revtintin joined
17:02 ogkloo joined
17:02 connrs joined
17:02 matuszak_ joined
17:05 dinamyc_ joined
17:05 metaporia joined
17:06 jer1 joined
17:06 dkk joined
17:06 <dkk> hello all...
17:08 pera_ joined
17:08 bvad joined
17:09 rashmirathi joined
17:09 sproingie joined
17:10 tree6014 joined
17:11 <* hackage> HSet 0.0.1 - Faux heterogeneous sets https://hackage.haskell.org/package/HSet-0.0.1 (athanclark)
17:11 dkk_ joined
17:11 <dkk_> hello all...
17:12 czyborra joined
17:12 <dkk_> I have a question that I am working on a project to do form filling to a particular website programatically is there a way to use haskell for it
17:12 Taslem joined
17:12 <orzo> As a default rule of thumb, is it better to put a record into an ioref or is it better to put an ioref as a field of a record?
17:13 <c_wraith> orzo, it's better to do whichever means the right thing for your use case.
17:13 joe9 joined
17:14 oberstein joined
17:14 DataComputist joined
17:14 <orzo> well what are the tradeoffs
17:14 ertes joined
17:15 <davean> Well, for what what memory gets dirtied on a change, and what you get a reference to
17:15 whoisxy_ joined
17:15 <nshepperd> an ioref containing a record lets you have atomic updates of the whole record, compared to a record containing several iorefs
17:16 <c_wraith> I don't really even see "tradeoffs". they mean sufficiently different things that it's rare they could even be used interchangeably
17:16 <davean> what c_wraith said
17:17 Swizec joined
17:17 <orzo> I've an object that will alternate between two configurations, two fields swapped, very frequently. Less frequently.
17:18 <orzo> er s/less frequently//
17:18 joncfoo joined
17:19 fnurglewitz joined
17:19 <orzo> i was figuring i could put a Bool in an IORef to maintain the state, that would require some if branching to actually simulate the swapped fields
17:19 <c_wraith> orzo, should someone holding a record value see those changes, or should they see a consistent view?
17:19 <orzo> or I could just put the fields directly in the record and do an atomic update
17:19 <orzo> i dont understand your question
17:20 shayan_ joined
17:21 <c_wraith> say I have one of these records. is it correct for me to see changes made to them from elsewhere, or correct for me to always see the same thing?
17:21 <dkk_> seems like no one has seen my question
17:21 asmyers joined
17:21 <dkk_> please help me with
17:22 tree6014 left
17:22 <dkk_> I have a question that I am working on a project to do form filling to a particular website programatically is there a way to use haskell for it
17:22 <orzo> c_wraith, this isn't really a multithreaded application. Object will alternate states and code will see the current state
17:23 <* hackage> one-liner 0.9 - Constraint-based generics https://hackage.haskell.org/package/one-liner-0.9 (SjoerdVisscher)
17:23 <* hackage> hsx2hs 0.14.1 - HSX (Haskell Source with XML) allows literal XML syntax in Haskell source code. https://hackage.haskell.org/package/hsx2hs-0.14.1 (JeremyShaw)
17:23 <Taneb> orzo, do you need an IORef at all
17:23 <orzo> i'm using mutable data because i'm intereacting with the gpu anyway
17:23 <c_wraith> orzo, it doesn't need multiple threads. it just needs to be shared at all.
17:23 <Taneb> I find IORefs tend to make things trickier than they need to be 95% of the time
17:23 troydm joined
17:24 dm3 joined
17:24 <orzo> i don't need an ioref, but considering all the closely related global state, it seems odd to program this without it
17:24 phaji joined
17:24 patbecich joined
17:26 jgertm joined
17:26 HoierM joined
17:26 jutaro joined
17:26 <orzo> would you go out of your way to avoid mutable state when you are maintaining something synced with GL library and GPU mutable state?
17:26 <dkk_> hello if someone listening to my voice ...
17:26 jer1 joined
17:26 icicled joined
17:27 <orzo> i mean, is there a good reason for me to avoid a ref here?
17:28 gienah_ joined
17:28 juanpaucar joined
17:28 mjora7 joined
17:29 <EvanR> orzo: no reason to avoid IORefs if youre in IO
17:29 <mivael> dkk_, for me, your question seems to be too broad to provide you with a useful answer
17:29 <EvanR> though some "state" forms are simpler without them, to me
17:30 <EvanR> in other cases, (in IO), its like the obvious choice
17:30 <Cale> dkk_: By "form filling" do you mean making POST requests?
17:30 cloudhead joined
17:31 <robkennedy> dkk_: I use wreq for posting, it's good, but the API is lower level than I pythons request
17:31 albertus1 joined
17:31 codesoup joined
17:32 juanpauc_ joined
17:33 dkk joined
17:34 <dkk> hello suffered from a connection error
17:34 gawen joined
17:34 <dkk> cale : yes
17:34 <robkennedy> Especially if you're doing file upload with additional parameters, you'll probably have to experiment a bit. BOS also made its interface fairly lens dependently​, but his tutorial on serpentine is nice
17:34 joncfoo joined
17:34 aporia joined
17:34 <dkk> if someone told something then please repeat so that i could read
17:35 <robkennedy> I said you should look at the wreq library
17:35 Hunter1_ joined
17:36 <dkk> robkennedy: did you told to me ...
17:36 juanpaucar joined
17:37 <robkennedy> Yeah...
17:37 BlueRavenGT joined
17:37 matuszak joined
17:38 <dkk> robkennedy: do you have any prior experience with this
17:38 ystael joined
17:40 <dkk> help
17:40 camm left
17:41 martinalex joined
17:41 juanpauc_ joined
17:41 padfoot_maudrer joined
17:41 <dkk> If some here has used Haskell for web-form filling automation task for a given website
17:41 icicled joined
17:42 Bassetts joined
17:42 <Cale> wreq is probably a bit easier, but I've used http-conduit directly to make POST requests before
17:42 <Cale> and that wasn't so bad either
17:43 <EvanR> dkk is talking about selenium type stuff
17:44 fresheyeball joined
17:44 <dkk> EvanR: yes something like that
17:44 fendor joined
17:45 <dkk> Cale : can you help me in that a little please....
17:45 jutaro joined
17:46 juanpaucar joined
17:46 <Cale> dkk: If you're talking about simulating keypresses in a running browser or something, I have no experience with that
17:47 <dkk> Cale : I just want to do posting in a given website
17:47 jer1 joined
17:47 oberstein joined
17:48 danthemyth joined
17:48 michbad joined
17:49 <Cale> There are examples of how to form POST requests here. https://hackage.haskell.org/package/wreq-
17:49 antoine9298 joined
17:49 <dkk> Cale: ok
17:50 <Cale> You probably will want to use the version which looks like: post "http://httpbin.org/post" ["num" := 31337, "str" := "foo"]
17:50 joncfoo joined
17:50 juanpaucar joined
17:50 replay joined
17:50 <Cale> to post urlencoded form data.
17:52 <dkk> Cale: let me see
17:52 Luke joined
17:53 <dkk> Cale: can we do a private chat please...
17:54 <Cale> sorry, I'm busy with work
17:55 juanpauc_ joined
17:56 DTZUZU joined
17:57 govg joined
17:57 ddk joined
17:57 icicled joined
17:57 xanadu_ joined
17:57 <lyxia> yay hackagebot is back
17:58 <dkk> hey
17:58 ogkloo joined
17:58 <dkk> Cale: do you have 2 mins plzz
17:59 chaosmasttter joined
17:59 phaji joined
17:59 patbecich joined
18:00 juanpaucar joined
18:00 metaporia joined
18:01 <dkk> Cale: I want just a guidance to how to do this job with Haskell
18:01 <EvanR> dkk: there is a package on hackage for that page automation stuff, if you jsut search for it
18:01 Jesin joined
18:01 <EvanR> beyond that, you just need to learn haskell
18:02 <dkk> EvanR: I am old with haskell 2 years and Haskell is my fav lang , my mother programming lang...
18:02 <Cale> dkk: I linked you a bunch of examples... you're going to have to be more specific what you're having trouble with
18:02 <EvanR> well then this shouldnt be a big deal
18:03 metaporia joined
18:03 Durbley joined
18:03 <dkk> EvanR: I would do it any how just want an initial kickstart
18:03 sssilver joined
18:03 <EvanR> i think thats too much to ask for IRC
18:03 <EvanR> especially with this topic, which is often used for exploiting/abusing web pages
18:03 <dkk> Cale: but where are the examples
18:04 juanpauc_ joined
18:04 metaporia joined
18:04 <dkk> EvanR: no EvanR I am not going to use it for ... actually its for promotion
18:04 juanpaucar joined
18:04 phyrex1an joined
18:05 joncfoo joined
18:05 sssilver joined
18:05 mda1 joined
18:07 asmyers joined
18:08 jer1 joined
18:09 tommd joined
18:09 JuanMiguel joined
18:10 fotonzade joined
18:11 aporia joined
18:11 dkk joined
18:12 <Cale> dkk: In the documentation I linked... https://hackage.haskell.org/package/wreq-
18:12 joe9 joined
18:12 <Cale> all the boxes with a blue background
18:12 <dkk> Cale: ohk that's one..
18:12 icicled joined
18:13 <dkk> Cale: sorry I thought you are talking about something else
18:14 Hunter1_ joined
18:14 connrs joined
18:14 <dkk> Thanks for all your support ... that's great about Haskell community
18:16 FreemanXiong joined
18:16 <dkk> byee
18:16 entuland joined
18:18 rkazak joined
18:20 joncfoo joined
18:22 MDA2 joined
18:22 yrdz joined
18:24 mda1 joined
18:24 skeuomorf joined
18:25 antoine9298 joined
18:26 ziocroc joined
18:27 connrs_ joined
18:27 yrdz joined
18:28 icicled joined
18:29 jer1 joined
18:29 kfollesdal joined
18:29 yrdz joined
18:29 `^_^v joined
18:30 jsgrant_om joined
18:31 yrdz joined
18:34 sz0 joined
18:35 pikajude joined
18:36 joncfoo joined
18:36 P1RATEZ joined
18:37 revprez_atlanta joined
18:38 cyborg-one joined
18:40 Destol joined
18:40 sproingie joined
18:40 sproingie joined
18:41 etehtsea joined
18:42 fosterite joined
18:42 cschnei__ joined
18:43 duck_08 joined
18:43 <duck_08> hello, anyone there for a quick question ?
18:43 ekinmur joined
18:43 icicled joined
18:44 <phadej> duck_08: just ask
18:44 flatmap13 joined
18:45 buttbutter joined
18:46 <duck_08> phadej can you help me understand catamorphism and anamorphism ?
18:47 <phadej> that's an intersting topic
18:47 <phadej> at which point you get lost?
18:48 <monochrom> That is not a quick question.
18:49 Jesin joined
18:49 jer1 joined
18:49 caumeslasal joined
18:51 joncfoo joined
18:51 jimmyrcom joined
18:52 mizu_no_oto joined
18:55 sphinxo joined
18:55 flatmap13 joined
18:55 ziocroc joined
18:55 juanpaucar joined
18:58 im0nde joined
18:58 icicled joined
18:59 juanpauc_ joined
19:02 juanpaucar joined
19:03 juanpaucar joined
19:06 mmachenry1 joined
19:06 shayan_ joined
19:07 joncfoo joined
19:07 <c_wraith> the Greek roots are actually somewhat informative. ana -> up, cata -> down. an anamorphism builds something up, a catamorphism tears something down.
19:08 <sbrg> yeah I just read that the other day as well.
19:08 raynold joined
19:08 <sbrg> hadn't thought about it like that
19:09 tromp joined
19:10 jer1 joined
19:11 rkazak joined
19:14 chaosmasttter joined
19:14 icicled joined
19:15 psmakro joined
19:18 <* hackage> statistics - A library of statistical types, data, and functions https://hackage.haskell.org/package/statistics- (AlexeyKhudyakov)
19:19 <Tuplanolla> Whoa, a new Hackage bot!
19:19 <EvanR> level up
19:20 <Tuplanolla> Does this one collect similar updates together?
19:20 <t7> No instance for (Traversable Set.Set) really?
19:21 <glguy> t7: such an instance can't be written, so it doesn't exist
19:21 <t7> theres a low view function or whatever
19:22 fizruk joined
19:22 joncfoo joined
19:22 Chiamavano joined
19:22 <glguy> I don't know what that means
19:23 <t7> glguy: http://hackage.haskell.org/package/containers-
19:23 <t7> wait
19:23 <Tuplanolla> It's because of the `Ord`, t7.
19:24 eschnett joined
19:24 <Tuplanolla> Can't have `Functor`, so can't have `Traversable` either.
19:24 ekinmur joined
19:24 <t7> what about Set.map ?
19:25 buglebudabey joined
19:25 <glguy> That has the wrong type to be an implementation of fmap
19:25 augur joined
19:26 <t7> oh wait
19:26 <t7> no wait i dont get why Set cant be a functor
19:26 <dmwit> fmap :: (a -> b) -> Set a -> Set b
19:27 <glguy> You'd need to be able to write a function with type: (a -> b) -> Set a -> Set b
19:27 <dmwit> But `Set.map :: Ord b => (a -> b) -> Set a -> Set b`.
19:27 <t7> aha!
19:28 np356 joined
19:28 <EvanR> is there a standard name for strict pair
19:29 afarmer joined
19:29 <Tuplanolla> Mathematicians get away with it, because everything they work with has equality and performance doesn't matter, t7.
19:29 icicled joined
19:30 <np356> I'm writing a parsar for a DSL, and I have the following structure for describing the syntax tree: http://lpaste.net/355442. Every node (except a translation unit) has a parent SyntaxNode that is its first argument to the constructor. Is there a more elegant way to write this?
19:30 jer1 joined
19:31 <glguy> The more elegant way would be to not have that SyntaxNode field
19:31 <np356> how?
19:31 <EvanR> data Pair a b = !a :!: !b ?
19:32 <np356> what does this syntax mean?
19:32 <glguy> np356: Remove the "SyntaxNode" field from each constructor that has one
19:32 <glguy> np356: EvanR's comment wasn't related to your problem
19:32 doomlord_ joined
19:33 rockfordal joined
19:33 <np356> http://lpaste.net/355443
19:33 ij left
19:33 <np356> now I lost information about the parent node
19:33 <np356> right?
19:33 <glguy> Yeah, this is how it should look
19:34 <glguy> If you need a notion of parent, you can track that while processing the value
19:34 <np356> but now gien a syntax node I can't navigate to its parent
19:34 <glguy> That's something you'd track while processing such a node
19:34 <np356> hmm...
19:34 <dmwit> EvanR: Yes, the strict package offers one, I think.
19:34 <glguy> Tracking the parent in the node means that updating the structure will be a disaster
19:34 <dmwit> EvanR: And of course there's unboxed pairs as well, `(# a, b #)`.
19:34 meoblast001 joined
19:35 <glguy> np356: it's extremely uncommon to do that
19:35 <np356> glguy: the structure is immutable, its the parsed script
19:35 <glguy> np356: OK
19:35 <dmwit> np356: Perhaps you are looking for the concept of zippers.
19:36 <dmwit> np356: Normally the type you care about navigating around in and the type you use for tracking where you are/actually doing navigation are separated.
19:36 bkboggy joined
19:37 jgertm joined
19:37 joncfoo joined
19:37 padfoot_maudrer joined
19:37 <dmwit> np356: Have you started using this structure yet? What is motivating a need for parent pointers?
19:38 <np356> dmwit: thats an excellent point.
19:38 <glguy> If TranslationUnit was only supposed to occur at the top-level, it probably shouldn't be in the SyntaxNode type
19:38 <paolino> can someone write an example on using http://hackage.haskell.org/package/hetero-map-0.21/docs/HeteroMap-Map.html ?
19:38 dm3 joined
19:38 <np356> not yet actually, i just think that I would need it at some point. Right. I'll wait until I actully need it
19:38 <sbrg> I wrote a haskell implementation of a tree data-structure for a class, which traditionally uses parent pointers. I solved it using zippers and some knot-tying
19:38 <EvanR> "you might not need it"
19:38 oisdk joined
19:39 <jle`> paolino: fair warning, it looks pretty out of date
19:39 <Taneb> sbrg, could I see that?
19:39 <jle`> paolino: the techniques it uses are ancient
19:39 <jle`> try dependent-map instead
19:39 <jle`> or even better, don't use heterogeneous maps
19:39 <jle`> hehe
19:39 coot joined
19:39 <sbrg> Taneb: sure, I guess. it's called a scapegoat tree. I'm not sure my implementation (which is unfinished due to various reason I cba going into) meets all the performance requirements etc, and it's not fully tested.
19:40 <paolino> mh I want the constraint In, which seems dependent-map is missing
19:40 <paolino> is it ?
19:40 <paolino> let me recheck :-)
19:40 xcmw joined
19:41 Frans-Willem joined
19:41 <dmwit> paolino: The obvious example seems like it would be `newKey $ \k -> lookup k (singleton k 3)` or so.
19:41 <dmwit> paolino: That said, I haven't tried it in ghci so I could be wrong.
19:41 <cocreature> paolino: dependent-map doesn’t track what’s in the map at the typelevel so that constraint is not possible
19:42 <paolino> I wanted to use HList , but it's so complex
19:43 <cocreature> paolino: HList as in the HList package or as in the general idea of heterogenous lists?
19:43 <paolino> in the package yes
19:43 <paolino> just not to rewrite the wheel
19:44 bennofs joined
19:44 phaji joined
19:44 <cocreature> sadly I think reinventing the wheel might be your best solution
19:44 <dmwit> Are you suuuuure you wanted to use HList? =P
19:44 ptek joined
19:44 padfoot_maudrer joined
19:45 <dysfun> i'm still not convinced hlist the library actually solves a problem
19:45 <dmwit> (You don't have to defend yourself. But if you feel like it, you could describe what makes you think you want HList or similar, and folks here may be able to help you design things in a way that avoids heterogeneity.)
19:45 <bennofs> it certainly creates some problems
19:45 <paolino> dmwit, I want to express the presence of an aspect in a context, for modularity
19:45 icicled joined
19:45 <dmwit> Okay. Can you unpack that jargon a bit for us?
19:47 ZuluKing joined
19:47 <cocreature> if you ignore all the record stuff, vinyl is actually a pretty usable implementation of hlists but as long as you need all of it, it’s often still easier to implement it yourself
19:47 <paolino> write functions like In MyAspect Context => a -> Reader Context b
19:47 <paolino> write functions like In MyAspect context => a -> Reader context b
19:48 augur joined
19:48 mjora7 joined
19:48 <ZuluKing> if I have a function Transform :: x -> y and I need to make a list of y using a list of x, how can I do it using map?
19:48 Bassetts joined
19:48 <bennofs> paolino: would it be feasible to create a new type class and manually write an instance for each aspect / context pair?
19:49 <cocreature> ZuluKing: map transform
19:49 FreemanXiong joined
19:49 <paolino> dmwit so I can define context structure later
19:49 <bennofs> paolino: like: HasMyAspect ctx => a -> Reader ctx b
19:49 <dmwit> paolino: Perhaps you are looking for `lens`, and especially the zoomy stuff therein.
19:49 <dmwit> Or just `asks`...
19:49 gehmehgeh joined
19:50 <dmwit> :t asks
19:50 <lambdabot> MonadReader r m => (r -> a) -> m a
19:50 <ZuluKing> cocreature it wouldn't give a list of y, would it?
19:50 oish joined
19:50 <dmwit> ?let data X; data Y
19:50 <lambdabot> Defined.
19:50 <cocreature> ZuluKing: why not?
19:50 <cocreature> :t map
19:50 <lambdabot> (a -> b) -> [a] -> [b]
19:50 <dmwit> :t let transform :: X -> Y; transform = undefined in map transform
19:50 <lambdabot> [X] -> [Y]
19:51 <cocreature> if you provide a function a -> b and a list of as you get a list of bs
19:51 jer1 joined
19:51 <cocreature> replace a by x and b by y and you have what you want
19:51 allenj12 joined
19:52 rashmirathi joined
19:52 ski joined
19:52 g0d355__ joined
19:53 joncfoo joined
19:53 <ZuluKing> cocreature, if I understand correctly, if z :: [y] and let z = map Transform [x,x,...x] is correct?
19:54 ragepanda joined
19:54 nscott76 joined
19:54 <paolino> bennofs, it doesn't seem very different from HList
19:54 <paolino> but it introduces new classes and instances
19:54 LHoT10820 joined
19:54 <dmwit> paolino: (I admit that I still don't really understand what you're trying to do.)
19:55 <cocreature> ZuluKing: I think it would be helpful if you provide some concrete example of what you are trying to do
19:55 <dmwit> ZuluKing: That seems plausible. Have you done some experiment that makes you believe that is incorrect?
19:55 <cocreature> you might be confusing types and values here
19:55 matuszak joined
19:56 metaporia joined
19:57 <bennofs> paolino: it is a lot less complex, gives better type errors and doesn't require tons of ghc extensions
19:57 doomlord_ joined
19:58 <paolino> dmwit I'm writing some functions and I know they are going to ask from a context. I want them to express what they want to be be in form of a constraint on the context
19:59 phyrex1an joined
19:59 otulp joined
20:00 <paolino> I see I can pass the lenses in the context, together with it
20:00 <dmwit> To me, that sounds like a proposal for how to achieve your goals, not a goal in itself.
20:00 <lpaste> ZuluKing pasted “FooBaz” at http://lpaste.net/355444
20:00 icicled joined
20:01 <ZuluKing> cocreature, dmwit, can you look?
20:01 <dmwit> ZuluKing: I looked. Do you have a question associated with the code?
20:01 <dmwit> ?let data A
20:01 <lambdabot> Defined.
20:01 mjora7 joined
20:02 <ZuluKing> someFunc needs a list, map Transform won't build one
20:02 <dmwit> ?let someFunc :: [Y] -> A; someFunc = undefined; transform :: X -> Y; transform = undefined; list1 :: [X]; list1 = undefined
20:02 <lambdabot> Defined.
20:02 <dmwit> :t someFunc $ map transform list1
20:02 <lambdabot> error:
20:02 <lambdabot> Ambiguous occurrence ‘transform’
20:02 <lambdabot> It could refer to either ‘Lens.transform’,
20:02 <dmwit> oh, bugger
20:02 <cocreature> ZuluKing: it definitely will
20:02 <dmwit> ?let transformZuluKing :: X -> Y; transformZuluKing = undefined
20:02 <lambdabot> Defined.
20:02 <dmwit> :t someFunc $ map transformZuluKing list1
20:02 <lambdabot> A
20:03 <dmwit> ZuluKing: GHC appears to disagree with you. Can you say why you believe what you just asserted?
20:03 <dmwit> ?undefine
20:03 <lambdabot> Undefined.
20:03 jdnavarro joined
20:03 `^_^v joined
20:03 nullifidian joined
20:03 <ZuluKing> sorry guys, sleep deprived.
20:04 <ZuluKing> and confused
20:04 <ZuluKing> thanks a lot
20:04 prkc joined
20:06 Rodya_ joined
20:06 lorentzus joined
20:07 leonardys joined
20:08 sellout- joined
20:08 joncfoo joined
20:09 caumeslasal joined
20:09 jle` joined
20:09 jle` joined
20:10 zzz joined
20:11 padfoot_maudrer joined
20:11 jer1 joined
20:14 slomo joined
20:14 slomo joined
20:15 cpennington joined
20:15 juanpaucar joined
20:15 icicled joined
20:18 juanpauc_ joined
20:18 juanpauc_ joined
20:19 mmn80 joined
20:20 caumeslasal joined
20:21 Itkovian joined
20:23 joncfoo joined
20:24 balor joined
20:24 xcmw joined
20:28 oisdk joined
20:29 Filip joined
20:29 benl23 joined
20:30 icicled joined
20:31 skeuomorf left
20:32 jer1 joined
20:34 bigos joined
20:34 cdg joined
20:34 Lambda_ joined
20:34 <Lambda_> Hey
20:34 splanch joined
20:35 Noldorin joined
20:35 iAmerikan joined
20:35 sssilver joined
20:35 kolko joined
20:38 hsk3 joined
20:39 joncfoo joined
20:41 sproingie joined
20:41 sproingie joined
20:42 toure left
20:43 insitu joined
20:43 JuanDaugherty joined
20:44 LKoen joined
20:44 unK_ joined
20:45 nycs joined
20:45 iAmerikan joined
20:46 icicled joined
20:47 rkazak joined
20:49 psmakro joined
20:49 sellout- joined
20:50 czyborra joined
20:53 stelleg joined
20:53 jer1 joined
20:54 joncfoo joined
20:55 nilg joined
20:55 balor joined
20:56 dsfox1 joined
20:58 Lazersmoke joined
20:59 carlomagno joined
20:59 cpennington joined
21:00 <Lazersmoke> Right now, I have a typeclass like `class C a where {perInstance :: String, perObject :: a -> Int}`, which has both a property that is the same across every object of the same type and a property that differs between individual objects. I want to model this without using a typeclass like this to avoid using existentials. How can I encode `perInstance`?
21:01 <Lazersmoke> In other words, I want: `data C = MkC {perInstance :: {- What goes here? -}, perObject :: Int}`
21:01 <jle`> the traditional way is to have it take a dummy parameter
21:01 <Lazersmoke> right now I am pulling it out with type applications
21:01 <Lazersmoke> perInstance @SomeTypeThatIsAnInstance
21:01 <* hackage> safecopy - Binary serialization with version control. https://hackage.haskell.org/package/safecopy- (JeremyShaw)
21:01 <jle`> yeah, that's the newfangled way
21:01 <monochrom> perInstance :: p a -> String
21:01 icicled joined
21:02 <monochrom> A user can then request: perInstance ([] :: [X]) or perInstance (Nothing :: Maybe X) or perInstance (Proxy :: Proxy X).
21:02 <monochrom> (See Data.Proxy)
21:02 <jle`> or even perInstance @SomeType Proxy
21:03 <jle`> or perInstance (Proxy @SomeType)
21:03 emanuelbuholzer_ joined
21:04 balor joined
21:04 <Lazersmoke> I don't want to use this method, though, because it requires me to use existentials: `[forall a. C a => a]` or whatever if I want a list of them
21:04 <jle`> how does it require you to use existentials
21:04 <Lazersmoke> or is this a valid use case for existentials?
21:05 <jle`> existentials here is an unrelated concept
21:05 <jle`> to an orthogonal concept
21:05 <jle`> why do you think you need them?
21:05 <jle`> *orthogonal problem
21:05 <monochrom> existential is caused by wanting a heterogeneous list, not caused by method type sigs.
21:06 <lyxia> Can you reorder the variables in a MultiParamTypeClass, such that if you have some class Foo a b where foo :: stuff and foo @B @A would select the Foo B A instance? I know you can write a separate foo', but I'm wondering whether you can somehow put an explicit forall in the Foo class declaration.
21:06 <jle`> why do you think you need a [forall a. C a => a] ? that's the real problem, not the typeclass
21:06 <monochrom> For example if your class had no method at all, your heterogeneous list would still incur the same existential.
21:06 <Lazersmoke> what I'm really modeling here is an Item type. I need to store Items in collections, lists, etc
21:06 <jle`> is Item a type?
21:06 <lyxia> uh, actually I want foo @B @A to select Foo A B
21:06 <jle`> then you can just have [Item] ...
21:07 <jle`> no existentials required
21:07 <Lazersmoke> no Item is the typeclass :P
21:07 <Lazersmoke> that's the problem
21:07 <Lazersmoke> perInstance = itemId
21:07 <Lazersmoke> perObject = objectData
21:07 <monochrom> Consider not using a type class at all.
21:07 <jle`> so what do you want to do
21:07 <Lazersmoke> I want to enforce the same typing garuntees from the typeclasses `perInstance` in a normal data type
21:08 augur joined
21:08 <monochrom> With 99.9999% probability it is wrong to translate [OOP class, OOP object] to [Haskell class, Haskell type].
21:09 joncfoo joined
21:09 <Lazersmoke> yeah I'm trying to do [OOP class, OOP object] to [Haskell type, value with that Haskell type]
21:09 <jle`> then why do you need a typeclass?
21:09 sssilver joined
21:10 <monochrom> So no class necessary.
21:10 <monochrom> Delete the class now.
21:10 tromp joined
21:11 <Lazersmoke> how I currently have it is that for example a stick always has itemId 4, but sometimes has different data associated with it
21:11 <Lazersmoke> so I have the extra data be a function `Stick -> ExtraData`
21:11 <Lazersmoke> and `itemId :: forall i. Item i => Int`
21:11 oisdk joined
21:12 simukis_ joined
21:12 sleffy joined
21:12 <Lazersmoke> but itemId with normal datatypes would be `itemId :: Item -> Int`, as well as `extraData :: Item -> ExtraData`
21:13 <Lazersmoke> so now my value represents a specific stick instead of a stick in general
21:13 sssilver joined
21:13 jer1 joined
21:14 darjeeling_ joined
21:15 <Lazersmoke> oh I just realized I can't do that properly because of the lack of dependent types :(
21:15 <Lazersmoke> ideally I would move itemId to a type parameter
21:17 augur joined
21:17 icicled joined
21:19 carlomagno joined
21:20 fizruk joined
21:21 juanpaucar joined
21:22 <jle`> Lazersmoke: what would you want to do with a container of general items, anyway
21:22 <jle`> the only thing you could do with it is storeitem id's
21:22 <jle`> so why not just have [Int]s
21:22 <jle`> instead of [exists a. C a => a]
21:23 <jle`> (btw, there are no actual values of forall a. C a => a)
21:23 carlomagno1 joined
21:23 <Lazersmoke> Item has other methods as well, like `onClick :: (Member Stuff r, Member OtherThing r, ...) => i -> BlockCoord -> Eff r ()`
21:24 <monochrom> Time for shameless plug.
21:24 <monochrom> @quote monochrom river
21:24 <lambdabot> monochrom says: You are to send a boolean, a character, and an integer across the river. The list for transporting across the river can hold 3 items, in fact any number of items you like, but they
21:24 <lambdabot> must all be of the same type. On the bright side, after crossing the river, the boolean, the character, and the integer need only be put on show. How many trips do you need? Solution: one trip, [
21:24 <lambdabot> show the_boolean, show the_character, show the_integer]
21:25 <monochrom> Existential is also fine. But you remember it is caused by you wanting heterogenity.
21:25 icicled joined
21:25 jzeus joined
21:25 mrcrjs joined
21:26 JeanCarloMachado joined
21:26 <monochrom> I would start with anti-OOP altogether. data Item = Stick | Pen | Cup. (Add fields as needed.)
21:26 <Lazersmoke> it also must be extensible
21:26 <monochrom> Until proven otherwise, I would not consider "oh so open subclassing system" at all.
21:26 macrover joined
21:27 <monochrom> I disbelieve in extensibility.
21:27 mrcrjs joined
21:27 <Lazersmoke> there are also a large number of items
21:27 <monochrom> 99.999% of claims of "need to be open" turn out to be false.
21:27 <Lazersmoke> like 450+
21:28 <monochrom> You will write Θ(450) lines of code one way or another.
21:28 <hpc> in open systems like that, the programming language turns into the configuration language
21:29 jutaro joined
21:29 <Lazersmoke> yeah that's the plan actually hpc
21:29 <Lazersmoke> like xmonad
21:30 <* ski> . o O ( `[exists a. C a *> a]' )
21:31 <hexagoxel> Lazersmoke: this recent post seems relevant: https://two-wrongs.com/dynamic-dispatch-in-haskell-how-to-make-code-extendable
21:31 sssilver joined
21:31 <Lazersmoke> yeah already read that
21:32 <Myrl-saki> My `stack install`'s target binary is broken. What file should I delete?
21:32 <Myrl-saki> stack install foo; foo; --> command not found: foo
21:32 joncfoo joined
21:32 <jle`> Lazersmoke: instead of having a typeclass, have a data type that can be configured to have the behavior you want
21:33 <Myrl-saki> Ah. snapshots.
21:33 mrcrjs joined
21:33 xcmw joined
21:33 <Myrl-saki> Or not.
21:34 <Myrl-saki> I just got a `couldn't find executable` :C
21:34 jer1 joined
21:34 Destol joined
21:34 dm3 joined
21:34 NyanPasu joined
21:34 dfeuer joined
21:34 <Lazersmoke> yes that is what we have been discussing. Should I keep the type class head as a type variable on my data type?
21:35 <Lazersmoke> I think that might solve the problem, but I'm not sure
21:35 <jle`> if there are two solutions, and one of them involves a typeclass while the other doesnt...
21:35 <jle`> the solution without the typeclass is the better one
21:35 <jle`> you should be avoiding new typeclasses at all reasonable costs
21:36 marvin2 joined
21:36 <* hackage> persistent-ratelimit - A library for rate limiting activities with a persistent backend. https://hackage.haskell.org/package/persistent-ratelimit- (jp_rider)
21:36 <jle`> oh hey i didn't notice hackagebot was back
21:36 <jle`> welcome back hackagebot
21:37 <lyxia> mniip++
21:37 tomphp joined
21:37 <mniip> what
21:37 mrcrjs joined
21:37 augur joined
21:38 <np356> cmake ..
21:38 <np356> fuck, sorry, wrong window
21:38 <lyxia> mniip: for hackage!
21:38 <mniip> ah yes
21:40 balor joined
21:40 <Myrl-saki> I'm 2 years, I feel a bit better now.
21:41 carlomagno joined
21:41 <mniip> old?
21:41 funkyb1 joined
21:41 icicled joined
21:41 <Myrl-saki> Still a bit salty that mniip didn't remember me though.
21:41 <mniip> Myrl-saki, who are you again
21:42 <Myrl-saki> see
21:42 mattn joined
21:42 <marvin2> jle` why? what is wrong with typeclasses?
21:42 NoCreativity joined
21:43 <EvanR> subject oriented programming?
21:43 matuszak_ joined
21:43 <EvanR> urg missed the whole convo
21:44 <monochrom> What's wrong with typeclasses: Its name contains "class" and people think it's a meaningful name.
21:46 <jle`> marvin2: it quickly leads to unmaintainble and unreadable code if it's used in an undisciplined way
21:46 <jle`> and it's usually the wrong design pattern
21:46 biglama joined
21:47 juanpaucar joined
21:48 <monochrom> Num shows you what Haskell classes are for. So you can say the same name (+) for a lot of different types. Operator overloading.
21:49 <EvanR> they can also convert types into values at runtime, which is another way of saying the same thing
21:49 juanpauc_ joined
21:50 kadoban joined
21:50 <monochrom> Compare to SML where they make you say + for int (fixed width), .+. for floating point, and yet another name for unbounded integers.
21:50 <jle`> marvin2: https://www.reddit.com/r/haskell/comments/3mhbuq/so_i_was_working_on_putting_some_math_im_learning/cvezu3w/
21:50 jsgrant_om joined
21:50 NoCreativity_ joined
21:50 <ReinH> It's a bit funny that vanilla Haskell doesn't even *need* typeclasses if it infers functions from types like idris or agda do. It's the language extensions that make it interesting.
21:51 <ReinH> otoh that doesn't play well with inference
21:51 <ReinH> but I'm usually pretty happy to give up inference
21:51 balor joined
21:52 <jle`> TDNR is either the best thing in the world or the worst thing in the world depending on who you ask
21:52 <monochrom> Ask me!
21:52 <EvanR> good if it works big if?
21:53 SkyPatrol joined
21:53 <* jle`> asks monochrom
21:53 hiratara joined
21:53 <monochrom> Answer: http://www.mail-archive.com/haskell-cafe@haskell.org/msg84162.html
21:53 <monochrom> :)
21:53 <hpc> sometimes i think it's bad because it makes figuring out a function call hard
21:53 <hpc> sometimes i think it's good because at least they have types
21:53 <ski> (TDNR ?)
21:53 <hpc> type-driven name resolution
21:54 hackage joined
21:54 <EvanR> type directed name disambiguation
21:54 <ReinH> jle`: :p
21:55 jer1 joined
21:55 <ReinH> It's good when it works but when it doesn't work it's terrible.
21:55 <Myrl-saki> I think XMonad is arcane magic with its typeclasses.
21:55 <ReinH> how terrible it is depends on how good the error messages are.
21:55 <ReinH> or, rather, how bad they are.
21:55 <Myrl-saki> I have no idea how XMonad's typeclasses works. I just trust that it will.
21:56 <jle`> every once in a while someone comes in here and asks, "hey, i mean, 'lookup' has different types for lists, lazy maps, strict maps, hashmaps etc. why not just import them unqualified and let haskell figure out which one you want based on type inference'
21:56 <jle`> "why can't haskell do this"
21:56 <Myrl-saki> jle`: I still wonder that. Why?
21:56 ryandv joined
21:56 <ryandv> @pl \x -> x
21:56 <lambdabot> id
21:56 <jle`> that's TDNR, and idris and other languages do that
21:56 juanpaucar joined
21:56 <hpc> Myrl-saki: imagine someone defines a module that has lookup = unsafeCoerce
21:56 <ryandv> @pl f >> (\x -> g >> return x)
21:56 <lambdabot> f >> (g >>) . return
21:56 <jle`> and like i said, you either hate it or love it
21:56 <hpc> Myrl-saki: when you your type-directed name resolution, does lookup always resolve to it, or never?
21:57 doomlord_ joined
21:57 <jle`> there are also pretty big issues with readability
21:57 <Myrl-saki> hpc: Ah, true.
21:57 <hpc> basically polymorphism is the problem
21:57 acarrico joined
21:57 <monochrom> They are conflating type inference with the opposite direction of type inference.
21:58 <monochrom> Type inference does not mean "from types deduce value choice". It means "from value choice deduce types".
21:58 <monochrom> Another example of flawed reasoning by meaningful words.
21:58 <ReinH> jle`: my main point was that vanilla typeclasses could be obsoleted by TDNR.
21:58 darjeeling_ joined
21:58 <jle`> well
21:58 <ryandv> @pl f >>= (\x -> g >> return x)
21:58 <lambdabot> (g >>) . return =<< f
21:58 <jle`> how would you write preludie functions like 'sum'
21:58 <hpc> ReinH: i would argue vanilla type classes /are/ TDNR
21:58 <jle`> or 'print'
21:58 <hpc> with a layer of type safety on top
21:59 <ReinH> hpc: with a layer of making the human compute things on top
21:59 <jle`> how does 'print' have a type w/o typeclasses
21:59 <hpc> well, the human has to compute things anyway
21:59 <hpc> and more or less the same things, without a framework to help out
21:59 <ReinH> the human compute fewer things if the computer computes more things
21:59 <ReinH> *can compute
22:00 nomotif joined
22:00 pie_ joined
22:01 <Myrl-saki> hpc: Let's assume a "most specific type" first, how would that fail? I'm guessing it's because we're going to be doing C++ arcane magic.
22:01 mrcrjs joined
22:01 <hpc> Myrl-saki: you run into the same issue as overlapping instances, actually
22:01 <hpc> which already have a concept of "most specific" that isn't entirely unambiguous
22:02 <hpc> the solution in that case is instances are global and you can always solve for "this isn't a clear hierarchy of instances" and fail
22:02 <hpc> which you could... maybe technically emulate with TDNR
22:03 ChaiTRex joined
22:03 <hpc> but i wouldn't want to be the one to implement it
22:03 <Myrl-saki> I see.
22:04 kadoban_ joined
22:04 <hpc> it might not be north of "it's not possible", but it's definitely north of "why would you?"
22:04 <hpc> ;)
22:05 msks joined
22:07 Blkt joined
22:09 ertes joined
22:10 takle joined
22:13 doomlord_ joined
22:14 marvin3 joined
22:14 juanpaucar joined
22:14 <doomlord_> does haskell 'maybe' have an optimization similar to Option<T> in Rust, where if T is a pointer type (where null is invalid) it doesn't need an extra slot to store the flag that says 'none vs some(T)
22:15 jer1 joined
22:16 conal joined
22:16 <monochrom> No.
22:16 mrcrjs joined
22:17 tomphp joined
22:17 <doomlord_> is it a possible retrofit , or is it simply not needed for other reasons, or what
22:17 <monochrom> It is a flawed translation from Rust to Haskell.
22:18 <monochrom> null is invalid for all types, since there is no null.
22:18 <monochrom> Therefore if a programmer bothers to request Maybe T, then it is reasonable to believe that the programmer will actually use Nothing.
22:19 <dgpratt> it's not hard to find explanations of how folks use Nix with Haskell, but I get the impression that significant changes have happed to how Haskell gets packaged for Nix to the extent that it changes some of the..."best practices"; can anyone point me to a relatively recent resource on the subject?
22:19 <monochrom> Another way to put it: Unlike Rust, Nothing is always valid, regardless of T.
22:19 <doomlord_> this is kind of what rust is doing: there's no null pointer; anything that might return a null pointer returns a None.. and ti just happens to optimise the storage of Option<Box<T>> to recognize the bitpattern 0x000000000 as 'None'
22:19 iAmerikan joined
22:20 <doomlord_> monochrom absolutely, an Option<Box<T>> may well be 'None' (nothing)
22:21 <doomlord_> it's just it can store that as one pointer sized object, which happens to represent nothing as 0x00000 , or any other value is 'something'
22:21 <glguy> No, GHC doesn't use this trick of a special pointer encoding for "Nothing" to avoid an indirection, but there are examples of doing such a thing
22:21 <doomlord_> the optimization could be generalized perhaps, e.g. floating point numbers could represent 'None' as NaN perhaps
22:21 <glguy> for example https://github.com/ekmett/structs/blob/master/src/Data/Struct/Internal.hs#L105-L132
22:22 <np356> alright, a bit of a philosophical question: I have a tree, I know exactly how many levels it will have and what type of node it will have at each level. what is the kosher way of describing it?
22:22 <glguy> You can't do this "with Haskell" but you can do it "with GHC", but GHC doesn't promise that it will work, so you have to be quite careful to check that it works out on any version you're using
22:22 <np356> something that is type-safe
22:23 <monochrom> But GHC does a related different thing. Look for "pointer tagging".
22:23 isenmann joined
22:24 <doomlord_> ok i recall something like 'pointer tagging' in lisp / ML ..
22:24 <doomlord_> using the low bits for ...
22:25 Tharbakery joined
22:25 conal joined
22:25 <monochrom> "Just x" still takes two words, one for Just one for x. But after I have built that on the heap and give you the address, I give you real_address+1.
22:26 <lyxia> np356: this is still pretty vague... how about one type per level?
22:26 <monochrom> So you do monochrom's_return_value & 7 and you know that I'm giving you a Just.
22:26 albertus1 joined
22:26 <lyxia> np356: If the nodes look uniform in some way, GADTs are a more compact option
22:27 <monochrom> real_address is always a multiple of 8 (nice alignment anyway) so this scheme works.
22:28 coot joined
22:28 dsfox1 joined
22:29 <monochrom> This is done for all algebraic data types of 7 constructors or fewer. Therefore it is more general than Rust. But it does not aim to save space, therefore it is different from Rust's.
22:29 bvad joined
22:29 <monochrom> Also, on Tuesday I walked by a pub that put up a sign that said "Tuesday is like Monday, but different".
22:30 Tharbakery joined
22:30 <monochrom> Actually, real_address+2.
22:31 <lyxia> why do you still need the word for Just
22:31 <monochrom> +1 for Nothing, +2 for Just, +3 for the 3rd data constructor (if exists). +0 for "possibly not in WHNF yet".
22:31 <Rembane> So the maximum is +7, and then something happens?
22:31 tomphp joined
22:32 xcmw joined
22:32 <monochrom> Because the value may start out as an unevaluated thunk at conception time.
22:33 <drdo> Does anyone happen to know if the Eq instance of Data.Set is the usual extensional equality?
22:33 <monochrom> One day later, it evaluates to Just, sure, but most stakeholders haven't been notified yet.
22:33 <EvanR> two sets are equal if they are subsets of each other
22:33 <monochrom> They are still holding on to real_address+0 because when they received it, the value was still unevaluated.
22:34 <drdo> EvanR: Great, thanks
22:34 <EvanR> which suggests the next question
22:34 <monochrom> So they need the heap object to tell them "it is now a Just. This happened just 5 seconds ago"
22:34 <monochrom> (OK, they don't care about the time.)
22:35 Tharbakery joined
22:35 <monochrom> The next time GC comes along, which will be next month, this will be fixed, the stakeholders will receive the shiny new real_address+1 version.
22:35 <monochrom> But that's for next month.
22:35 juanpaucar joined
22:35 cloudhead joined
22:36 <monochrom> Err, +2!
22:37 mr_sm1th joined
22:37 mrcrjs joined
22:37 juanpauc_ joined
22:37 <monochrom> I forgot what happens to 8 constructors or more. But you can always code up an example and see the Cmm code.
22:37 <Rembane> ^________^
22:38 <monochrom> Some jump table seems to be involved.
22:38 laplacian joined
22:38 <Rembane> Good stuff
22:38 Tharbakery joined
22:38 juanpaucar joined
22:39 <monochrom> The design of GHC (and STG) follows a fundamental philosophy of uniform treatment over WHNF and thunks.
22:39 jer1 joined
22:40 <monochrom> For example, the machine word spent on Just is a tag in the conventional sense. It is a pointer to a piece of code again. So as to be on par with thunks.
22:40 revprez_atlanta joined
22:41 <monochrom> Except Just's piece of code is a trivial "return real_address+2" so that it also unifies with the pointer tagging scheme.
22:41 <Rembane> It seems like a whole lot of pointer indirection. Doesn't that make Haskell slow?
22:41 gugah joined
22:42 <mniip> iirc what happens for 8+ constructors is you get the 0 tag always
22:42 paulsamways joined
22:42 sproingie joined
22:42 <EvanR> thats pretty much everything a computer is doing nowadays, and speed depends critically on cache use
22:42 <monochrom> After code optimization, it is not. There are 3 cases.
22:42 sfcg joined
22:43 <mniip> the function is tagForCon
22:43 <c_wraith> it would be really slow naively. the history of ghc is more or less "how can we make this compile to efficient code?"
22:43 JeanCarloMachado joined
22:43 <Rembane> :D
22:43 sfcg joined
22:43 <monochrom> A. If your ADT is comparable to a Java record or Java tree node, Java isn't having fewer pointers than yours.
22:44 sfcg joined
22:44 <mniip> https://github.com/ghc/ghc/blob/master/compiler/codeGen/StgCmmClosure.hs#L359-L368
22:44 <monochrom> B. If your ADT is really just an enum, "data V = A | B | C", pointer tagging reduces it to a C enum.
22:44 sw1nn joined
22:44 <thang1> Dataflow diagrams are the bane of my existance ಠ_ಠ
22:44 <monochrom> (Add strictness to make it happen more often.)
22:45 sfcg joined
22:45 <monochrom> C. If your ADT is "data Int = I# Int#", if you look at a tight loop, code optimization is very likely to work with Int# directly and not incur the I# at all. Until you exit the loop.
22:46 sfcg joined
22:46 <Rembane> What happens when I exit the loop?
22:46 <Rembane> And the C in the B-case, is that the C. or does strictness reduce enums to the last element in the enum?
22:46 <monochrom> Build the I# 42# heap object and return real_address+1
22:46 <Rembane> Ah
22:46 balor joined
22:46 czyborra joined
22:47 <monochrom> Ah, "reduces it to a C enum" refers to the C language.
22:47 <monochrom> Pointer tagging for V gives you x+1, x+2, x+3 respectively.
22:48 NocnaShada joined
22:48 juanpaucar joined
22:49 <Rembane> Oh, there were many C:s there for a while.
22:49 <Rembane> That's nice.
22:49 kgadek joined
22:49 mrcrjs joined
22:51 <EvanR> its interesting in the comments for realToFrac rules, it mentions that using primitive conversions for converting Float an Double and back gives like 1000x speedup, and the C backend is even faster (than native)
22:51 twanvl joined
22:51 mada joined
22:51 <EvanR> not sure why i thought C backend would be slower
22:52 erikd joined
22:52 <EvanR> or if that comment is out of date
22:52 <Myrl-saki> EvanR: native -> opcodes?
22:52 <EvanR> ghc direct code generation instead of through C
22:52 <Myrl-saki> Ah.
22:53 <Myrl-saki> Didn't realize the "backend".
22:53 nil joined
22:54 uglyfigurine joined
22:54 thimoteus joined
22:55 ericsagnes joined
22:58 jer1 joined
22:59 <drdo> Is there a good reason why there is no "standard" fold that works for any size of container yet does not require a starting value?
23:00 <Rembane> drdo: Like, even if the size is 0?
23:00 <Rembane> drdo: There is foldMap, but then your container needs to be a Monoid
23:00 <marvin3> :t foldr1
23:00 <lambdabot> Foldable t => (a -> a -> a) -> t a -> a
23:00 <drdo> Rembane: yes
23:01 <EvanR> > foldr1 (+) []
23:01 <lambdabot> *Exception: Prelude.foldr1: empty list
23:01 <marvin3> ^ if by "works" you meant "returns bottom". because that is the only thing it can return without a default value
23:01 <drdo> foldMap doesn't take the folding function
23:02 <Rembane> :t foldM
23:02 <lambdabot> (Monad m, Foldable t) => (b -> a -> m b) -> b -> t a -> m b
23:03 <drdo> Nevermind what I said, I was thinking of a special case where this actually makes sense
23:03 alveric joined
23:05 ekasc joined
23:05 cschneid_ joined
23:06 sleffy joined
23:06 alx741 joined
23:07 jmcarthur joined
23:08 nil joined
23:09 alx741 joined
23:09 mbazs joined
23:09 erisco joined
23:09 <nil> Hey, does anyone know why I'm getting this message from a blacklisted intero project in Emacs? "Suspicious state from syntax checker haskell-stack-ghc: Flycheck checker haskell-stack-ghc returned non-zero exit code 1, but its output contained no errors: Cannot determine project root directory."
23:09 tommd joined
23:12 pgiarrusso joined
23:12 shayan_ joined
23:13 opios joined
23:13 <* hackage> shellmate - Simple interface for shell scripting in Haskell. https://hackage.haskell.org/package/shellmate- (AntonEkblad)
23:14 ninedotnine joined
23:15 HoierM joined
23:17 HoierM joined
23:17 doomlord_ joined
23:17 whoisxy joined
23:19 opios joined
23:19 jer1 joined
23:19 balor joined
23:20 afarmer joined
23:21 <orion> Under what conditions would you use the free package, and when would you use the monad-coroutine package?
23:21 <orion> (If your goal is to suspend and resume computations)
23:21 indi_ joined
23:22 <EvanR> or would you make your own based on thethe oleg freer monad tutorial
23:23 <orion> http://okmij.org/ftp/Computation/free-monad.html <-- This?
23:23 <EvanR> yeah
23:23 LordBrain joined
23:23 <EvanR> i.e. your type for effects doesnt even need to be a Functor
23:26 nakal joined
23:26 carlomagno2 joined
23:27 balor joined
23:30 <EvanR> what do you call a data type whose two values are East and West
23:30 <erisco> ThreeNine
23:30 matuszak_ joined
23:30 cschneid_ joined
23:31 <Tuplanolla> Obviously `T`.
23:31 <EvanR> T_T
23:31 JeanCarloMachado joined
23:33 <erisco> could call it Lateral
23:33 balor joined
23:33 <monochrom> OldWorld
23:34 <Rembane> PortugalSpain
23:34 <monochrom> Berlin <duck>
23:35 <erisco> MarioStory
23:35 <MarcelineVQ> Spin | AntiSpin
23:35 <geekosaur> Sun
23:35 ljhms joined
23:35 <monochrom> erisco: Oh haha I get it now.
23:36 <erisco> ;)
23:36 tromp joined
23:36 <monochrom> I did take advantage of HMV closing sale to buy West Side Story blu-ray at a very low price.
23:37 <pacak> How would you go about figuring out unused definitions/modules in a big project?
23:37 typedrat joined
23:38 zero_byte joined
23:39 <EvanR> DirEW
23:39 JeanCarloMachado joined
23:39 <Tuplanolla> Be a good C programmer and call it `HrzCmps`.
23:40 <monochrom> heh
23:40 meba joined
23:40 <robkennedy> Everytime I read about Free Monads, I feel like I ought not trust them - that some inline failure will happen, or that the applicative for my class isn't the trivial one from Monad. How did you overcome that?
23:40 Cale joined
23:40 <monochrom> Wth is "inline failure"?
23:41 theDon_ joined
23:42 <robkennedy> The bane of Vector code
23:43 jer1 joined
23:43 <monochrom> No understand.
23:43 markus1189 joined
23:43 markus1199 joined
23:47 chao-tic joined
23:47 aarvar joined
23:47 <robkennedy> Ie `f x = case x of {Left _ -> g x; Right y -> y}; g x = case x of {Left y -> y; Right _ -> f x}`. Here we ought to be able to say `reallyUnsafePointerEquality# f (either id id) == 1`
23:48 <robkennedy> *modulo bottoms, sure
23:48 <monochrom> No. GHC code optimization does not include de-duplicating code.
23:48 <monochrom> In fact I think I saw more duplicated identical code than less.
23:48 JeanCarloMachado joined
23:48 plutoniix joined
23:49 <monochrom> All of them highly optimized. But still separate clones.
23:50 <robkennedy> First, this is tangential to my point, which is about how well GHC can analyze Free. And second, I think you're wrong
23:50 xcmw joined
23:50 <robkennedy> Hold up while I look up the example
23:50 <glguy> GHC optimizes that to: g = f; and f t x = case x of { Left ds -> ds; Right y -> y }
23:51 <glguy> Though I don't know what the point of that was
23:51 <glguy> oh and the t was a type argument, so ignore that
23:52 <erisco> it is strange to begin with the speculation of compiler bugs
23:52 <robkennedy> https://youtu.be/jcL4bp4FMUw at 12
23:53 <robkennedy> Yeah, GHC well get `g = f`
23:54 <monochrom> But still not reallyUnsafePointerEquality# f (either id id) == 1
23:54 Destol joined
23:55 <robkennedy> ... okay, it might only get `f === (either id id $!)`
23:56 <edwardk> monochrom you need joachim breitner's toy for that
23:56 <glguy> Hay, it worked!
23:56 robotroll joined
23:56 <glguy> they are equal :)
23:57 <monochrom> Also, I have watched from 12:00 to 13:00, and still no sign of unsafeWhatever. Or core code for that matter.
23:57 Welkin joined
23:57 <robkennedy> But, my original question is about how much other users worry that Free might obscure these sorts of (to be honest incredible) optimizations
23:57 <monochrom> If you use Free, you have already lost the performance war.
23:57 <robkennedy> You'll get it by 1518, it's worth the wait
23:58 <edwardk> monochrom: =P
23:58 <robkennedy> Right, that's the exact concern :-(
23:58 infinity0_ joined
23:58 infinity0_ joined
23:58 <edwardk> i tend to start with free then rewrite my code into whatever interpretwtion i'm putting on the original Free thing
23:59 <glguy> https://paste.fedoraproject.org/paste/XLM-0kohGMP7NQZQRLy8L15M1UNdIGYhyRLivL9gydE=
23:59 <EvanR> like a church encoded version