<    April 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 25 26 27 28 29  
30
00:00 <Welkin> dcz__: write your own filter
00:00 <iqubic> I would do this:
00:00 <Welkin> it is just a fold
00:00 <Welkin> which is just a recursive function
00:00 <iqubic> :t filter
00:00 <lambdabot> (a -> Bool) -> [a] -> [a]
00:01 <iqubic> ff xs = filter (b /= ".webm") xs
00:01 <monochrom> No.
00:01 <mbw> kuribas: Seriously, that's it? I'll try that out right away. Also, are these recommendations part of the documentation?
00:01 <iqubic> where b = snd (splitExtension)
00:02 <iqubic> Wait, it's not that simple.
00:02 <dcz__> no no dont tell me the answer pls :D
00:02 <iqubic> Sorry, I'll let you do it on your own.
00:02 <kuribas> mbw: it's in the ghc documentation, and in various tutorials
00:02 <iqubic> Also, what I wrote is not quite right either.
00:02 <iqubic> Not going to post the correct one.
00:02 <kuribas> mbw: just remember that ghc only specialized functions if they are called in the same module.
00:02 <dcz__> cool :D
00:03 <dcz__> i will ask soon
00:03 <kuribas> mbw: And in this case specializing bubblesortM seemed to be necessary as well.
00:03 <iqubic> Is there a function that takes a list, and a boolean returning function, and return a list of element that returned true from the function.
00:03 <codedmart> lyxia: OK what about this. What if I want a fallback alternative `someFieldLens . _Just %~ (+1) <|> someFieldLens ~. Just 1`. So if someField is Nothing set it to Just 1?
00:04 <kuribas> mbw: wait, you mean enumFromM? Yeah, thats from the vector documentation.
00:04 <iqubic> :t filter
00:04 <lambdabot> (a -> Bool) -> [a] -> [a]
00:04 <dcz__> my mind mixed recursively iqubic :D
00:04 <monochrom> filter does the recursion for you. This may be to your benefit or to your demise.
00:05 <kuribas> mbw: but polymorphism is very expensive, so it's usually a good candidate when performance is needed.
00:05 <iqubic> Oh, wait, what I want is something that takes a predicate and a list, and returns elements, that fail the predicate?
00:05 <mbw> Ok, so cross-module specialization only takes places when functions are marked specializable?
00:05 <dcz__> in short, filter checks list elements with some function
00:05 <iqubic> :t not
00:05 <lambdabot> Bool -> Bool
00:06 <iqubic> so I want filter (not b) xs
00:06 <monochrom> I think you will have to use filter and add your own not.
00:06 <iqubic> So like I just said?
00:06 <monochrom> I don't see a ready-made one in Data.List
00:06 <iqubic> where b is of type a -> Bool
00:07 <monochrom> For a lax version of "like".
00:07 <robertkennedy> Got a peek: https://downloads.haskell.org/~ghc/master/libraries/base/base/index.html
00:07 <iqubic> monochrom: what would you do instead of filter (not b) xs?
00:07 <monochrom> I would check its type.
00:07 <iqubic> Check what type?
00:07 <iqubic> does that not work?
00:08 <monochrom> You can perform experiments to find out.
00:09 <monochrom> Oh, the experiment exploded.
00:09 <ski> (wg 69
00:09 kfish joined
00:09 <kuribas> mbw: yes
00:10 <dcz__> monochrom: you are funny :D
00:10 hc_ joined
00:10 EvanR_ joined
00:10 <kuribas> mbw: and only for the types you give inside the SPECIALIZE pragma
00:10 pheaver joined
00:11 jbiesnecker joined
00:11 <kuribas> mbw: unless you use the INLINABLE pragma, in which case it may try.
00:12 <kuribas> mbw: INLINABLE just means put the whole definition inside the interface file.
00:12 JeanCarloMachado joined
00:13 <mbw> But seriously, a factor 100...
00:14 ddere joined
00:14 permagreen joined
00:14 <mbw> Sadly I wasn't successfull with my go function approach, I'll try that again tomorrow.
00:14 glamas joined
00:15 hc joined
00:15 bhiliyam joined
00:16 <mbw> kuribas: So I guess all these memory allocations I saw were related to dictionary arguments?
00:16 acidjnk22 joined
00:16 <kuribas> mbw: I think so
00:18 <mbw> Now to get it faster by a factor of 2?
00:18 <mbw> I'll try that tomorrow.
00:19 ryantrinkle joined
00:19 <mbw> Anyways, thanks for your help, especially taking into consideration how long it took and you had to restart and all.
00:19 <ryantrinkle> I'm having a bit of a tough time using ShowTag:
00:19 <ryantrinkle> instance ShowTag k (ComposeMaybe k) where
00:19 <ryantrinkle> showTaggedPrec = undefined
00:19 <ryantrinkle> whoops, wrong paste; https://hackage.haskell.org/package/dependent-sum-0.4/docs/Data-Dependent-Sum.html#t:ShowTag
00:20 filterfish joined
00:20 <ryantrinkle> Has anyone found a reasonably nice way to use that without constantly running into overlapping instances?
00:21 rcschm joined
00:22 <codedmart> Can you do alternative with lenses? Anyone know?
00:22 Lord_of_Life joined
00:23 <EvanR> i just "realized" that C allows field names to collide while haskell doesnt
00:23 <EvanR> and it all works out
00:23 hybrid joined
00:24 <monochrom> Yes, C has a record system.
00:25 <lyxia> codedmart: I think you just use the one lens for the field and use "maybe" or pattern match on the Just.
00:25 <monochrom> Still, many C libraries do the same thing as Haskell programmers in uniquizing field names with prefixes.
00:26 StoneToad joined
00:27 <monochrom> For example, struct sigaction has fields sa_handler, sa_sigaction, sa_mask, sa_this, sa_that
00:29 <EvanR> whats the point of that
00:29 <monochrom> I don't know!
00:30 <monochrom> And the irony is that struct socket_address (sp?) has fields with the sa_ prefix again!
00:31 <monochrom> The correct spelling is sockaddr
00:31 chewzerita joined
00:31 <chewzerita> @lpaste
00:31 <lambdabot> Haskell pastebin: http://lpaste.net/
00:32 Shatnerz0 joined
00:32 ali_bush joined
00:32 serendependy joined
00:33 cables joined
00:33 <dcz__> monochrom: i couldn't find the answer with filter :D
00:34 <monochrom> filter (\x -> determine whether x has suffix .webm or not) list
00:34 benl23 joined
00:35 <monochrom> My x is the same idea as your x in x:xs
00:35 <dcz__> ff x:xs = filter (\s -> s == (b=".webm")) xs
00:35 <dcz__> doesnt work :D
00:35 <monochrom> No, don't bother with your own x:xs. filter already does it for you.
00:36 <monochrom> Also, you have a really bad case of "wth is b?"
00:36 <monochrom> Also, s == whatever is unlikely to work.
00:36 <monochrom> == really means equal, not "looks like".
00:37 path[l] joined
00:38 <dcz__> yea, i just thought okey
00:38 <joe9> http://dpaste.com/11JENF4 is my code, line 136, I cannot figure out how to get the conName . Can anyone please help? http://codepad.org/G4EHi352 is the function if the other file is too big to look at.
00:39 pera joined
00:39 firef1y joined
00:40 <joe9> Would a Proxy help to get the constructor name?
00:42 leat joined
00:42 adolby joined
00:43 hamishmack joined
00:43 cschneid_ joined
00:43 <Koterpillar> joe9: what's wrong with that line?
00:43 <Koterpillar> joe9: also, are you calling gbuildIBFormat on the same exact type again?
00:43 <joe9> Koterpillar: gOod catch. I need to strip the M1 there. sorry about that.
00:44 <Koterpillar> does it give an error or anything?
00:45 <joe9> Koterpillar: with gparseIBFormat, I get U1 or L1 or R1 from the gParseIBFormat. But, I cannot figure out how to run the conName?
00:45 <joe9> Koterpillar: I put an undefined there to mask the error.
00:45 <Koterpillar> joe9: run conName on what you have there
00:45 <joe9> Koterpillar: I want to do: fmap M1 (parseIBFormat (constructor name))
00:45 andyhuzhill joined
00:45 <Koterpillar> joe9: ah, parse... use undefined
00:45 <joe9> Koterpillar: on what?
00:46 <Koterpillar> joe9: I have an example just for you... https://www.koterpillar.com/talks/instances-for-everyone/#13
00:46 <Koterpillar> sorry, next page, https://www.koterpillar.com/talks/instances-for-everyone/#14
00:46 <Koterpillar> you need ScopedTypeVariables here, which you already have
00:46 Reshi joined
00:47 dcz__ joined
00:47 <joe9> Koterpillar: exactly what I need.
00:47 fXl joined
00:47 alex__ joined
00:47 <joe9> the (undefined :: S1 m t p) is the key
00:47 <dcz__> monochrom: ff xs = filter (\s -> takeExtensions s == ".webm") xs , this works :D
00:47 rcschm joined
00:48 <joe9> Koterpillar: the S1 m t p are the same as that defined in the instance line? So, the type variable is matching from the undefined?
00:48 coot joined
00:48 <Koterpillar> joe9: yes, you could write (in my example) (S1 m (Rec0 Text) p) as t doesn't matter
00:48 <monochrom> dcz__: Congrats.
00:49 <joe9> Koterpillar: it appears to be magic on how that match happens. Is there some material that can help understand it?
00:49 <dcz__> thank you :D it took long but i made it somehow :D i tried splitExtensions thats why struglled :D
00:49 <joe9> Koterpillar: if you do not mind me asking.
00:49 <Koterpillar> joe9: no magic, just clever instance declarations
00:50 robertkennedy joined
00:50 <Koterpillar> joe9: read the Hackage docs on GHC.Generics and the declarations source
00:50 <Koterpillar> what my understanding is, conName is defined on anything that's Constructor c => C1 m t p
00:50 <dcz__> is there any stack data structure in hakell ?
00:51 <Koterpillar> joe9: sorry, Constructor m => C1 m t p
00:51 <kadoban> dcz__: [] works as one
00:51 <joe9> I can understand the above line with Constructor m =>
00:51 steeze joined
00:51 <Koterpillar> joe9: or, Constructor m => M1 C m t p, which is the same (you can use C1 in the instance declaration just fine though)
00:52 <joe9> what I fail to understand is how the undefined works.
00:52 MindlessDrone joined
00:52 <Koterpillar> joe9: the implementation of this conName is the same for any value of this type, the value isn't examined
00:52 <dcz__> kadoban: you meant , works like stack ?
00:52 <Koterpillar> joe9: when the program is compiled, the type is enough to select the correct instance
00:52 <joe9> It is almost as if we are pattern matching teh type variables in the function definiton.
00:53 <Koterpillar> joe9: we always are! imagine class FavoriteNumber a where fav :: a -> Int
00:53 <kadoban> dcz__: It's a fine implementation of one; it behaves close enough that you don't even really need a wrapper.
00:53 <joe9> Koterpillar: got it. Thanks. That makes perfect sense. well explained. Thanks again.
00:53 <dcz__> i dont know actually what i need. for example, i want to go further and backward on list elements , like playlist
00:53 <Koterpillar> joe9: instance FavoriteNumber Int where fav = const 1
00:53 <Koterpillar> joe9: instance FavoriteNumber Char where fav = const 2
00:53 lambda-11235 joined
00:53 <Koterpillar> joe9: now, fav (undefined :: Int) is 1
00:54 <dcz__> mpv will use it :D
00:55 <EvanR> zipper?
00:55 <kadoban> dcz__: Doesn't sound like a stack
00:56 edvorg joined
00:56 <dcz__> what i need actually? queue ?
00:56 Stanley00 joined
00:56 <joe9> Koterpillar: Thanks, That helps. and undefined is a member of all types.
00:56 takle joined
00:57 <geekosaur> dcz__, sounds to me like you want either Seq or a zipper
00:57 <Koterpillar> it's the only value of that type you can produce in that context, because you haven't been given any other
00:57 <joe9> yes, makes sense. How did you get so good at this? any reading material that can help me too?
00:58 darjeeling_ joined
00:58 <dcz__> geekosaur: i have filepath list in hand right now. Media player will play these from terminal so i want the capability of going forward or backward. thats what i will try to do
00:59 nighty-- joined
01:00 <Koterpillar> joe9: I read the docs and tried to make ridiculous things
01:00 <Koterpillar> joe9: for high level of ridiculousness, https://aphyr.com/posts/342-typing-the-technical-interview
01:00 <Koterpillar> (that's not me)
01:00 <joe9> Koterpillar: my eyes glaze over when I see kinds. Any suggestions to understand it better? read up on GHC core? System F?
01:01 <Koterpillar> if it helps, I have little idea about either of those. I vaguely remember Core actually erases types, but that might be wrong.
01:01 <Koterpillar> but really, here's another example of FavoriteNumber
01:01 edvorg joined
01:02 <joe9> I understand this. but, just looking for better intuition about haskell.
01:02 <joe9> there seems to be some stumbling block all the time.
01:03 <joe9> I feel that it might be because I am missing some important concept.
01:03 eschnett joined
01:03 <Koterpillar> hmm, I can't actually write what I wanted as a one-liner. instance FavoriteNumber a => FavoriteNumber [a]
01:03 <joe9> that might help build better intuition about reasoning about haskell definitions.
01:04 <Koterpillar> this is nothing but typeclass trickery, which is: choosing the right function based on your type
01:05 takle joined
01:05 brynedwardz joined
01:07 wroathe joined
01:08 Sindriava joined
01:08 vaibhavsagar joined
01:09 <joe9> Koterpillar: as an fyi, this is how I used it. http://codepad.org/yU9ZKTOf
01:09 firef1y joined
01:11 <Koterpillar> joe9: you can safely replace "M1 C" with "C1" everywhere
01:11 <joe9> yes, agreed. Thanks.
01:12 ali_bush joined
01:12 ali_bush joined
01:15 Cale joined
01:16 ystael joined
01:16 bhiliyam joined
01:16 sampuka joined
01:17 des_ joined
01:17 takle joined
01:18 ali_bush joined
01:18 ali_bush joined
01:22 eacameron joined
01:23 <biglambda> Is there a version of the lens operator (%=) that allows the right operand to be in the same monad? So I think the type would be: (Profunctor p, MonadState s m) => Setting p s s a b -> p a (m b) -> m () instead of (Profunctor p, MonadState s m) => Setting p s s a b -> p a b -> m ()
01:24 <peddie> biglambda: I have no idea, but perhaps try #haskell-lens?
01:24 <biglambda> Ah.. thanks.
01:26 zcourts_ joined
01:27 alx741 joined
01:27 oaao joined
01:28 mbw joined
01:30 <rjeli> re: https://aphyr.com/posts/342-typing-the-technical-interview
01:30 <rjeli> can someone explain "You smile kindly. “Haskell is a dynamically-typed, interpreted language.”
01:30 Welkin left
01:30 <mbw> Could somebody explane to me again how those timings with +RTS -s are created. I have a total runtime of 0.340 seconds, and 0.246 seconds elapsed (all of which is MUT). Everything else is zero. So, where do the other 0.100s come from?
01:30 <rjeli> how is type level programming dynamic?
01:30 <EvanR> o_O
01:31 <EvanR> as for the quoted quoted section, haskell has dynamic types built on top of static types, and haskell has interpreted implementations
01:33 <rjeli> i assume you mean something like `data Var a`?
01:33 <rjeli> is he doing something like that at the type level?
01:34 <Koterpillar> :kind Int
01:34 <Koterpillar> :k Int
01:34 <lambdabot> *
01:34 cschneid_ joined
01:34 <lyxia> mbw: multithreading?
01:34 <Koterpillar> :k String
01:34 <lambdabot> *
01:34 <rjeli> o
01:34 <Koterpillar> rjeli: this is what she means, I think
01:35 <rjeli> ty
01:35 PennyNeko joined
01:35 starc joined
01:37 <mbw> lyxia: That could actually be it.
01:39 <mbw> Sadly, no.
01:39 NeverDie joined
01:40 <mbw> Is this some startup overhead of the GC maybe?
01:42 splanch joined
01:44 eacameron joined
01:44 <mbw> This is annoying. If the elapsed time was equal to the total time, I would be on par with my C++ implementation
01:48 pheaver joined
01:48 <sophiag> i have an ADT in order to store lists of multiple types in the same field of a record and want to compute all the permutations of each list, but i think i need to unwrap them to be lists of different types otherwise i just get the permutations of all the lists in that field with one another. this is my attempt to do so, but i'm getting many type errors: http://lpaste.net/354501
01:49 Supersonic112_ joined
01:49 <sophiag> (i'm also wondering with all the wrapping and unwrapping i'm doing in this program whether it would make more sense to use lenses, although i'm only beginning to understand how they work)
01:50 sword865 joined
01:52 zcourts joined
01:53 wroathe joined
01:53 fizbin joined
01:54 <ski> sophiag : you've got multiple type issues ..
01:54 <sophiag> ski: an understatement perhaps
01:55 <sophiag> do you understand what i'm trying to here and why i (at least think) i need to unwrap them?
01:56 <ski> well .. i think i perhaps have some idea of what some of this is attempting to do .. but not the big picture
01:56 Argue__ joined
01:56 <ski> anyway, let's start with
01:56 <ski> permList :: [Amb] -> [[MultiList]]
01:56 <ski> permList a = map (permutations . unwrapMultiList . ambVal) a
01:56 raycoll joined
01:56 <ski> `a' here has type `[Amb]' so thence the input to `permutations . unwrapMultiList . ambVal' will have type `Amb'
01:57 <sophiag> right
01:57 <ski> looking at `ambVal', it's here a selector function that will select a field of type `MultiList' in that `Amb'. so far, so good
01:57 <ski> next, that `Multilist' will get passed to `unwrapMultiList'
01:57 <sophiag> well that actually is throwing an error i believe
01:57 <sophiag> ambVal
01:57 <ski> but `unwrapMultiList :: Maybe [a] -> [a]'
01:58 <ski> `MultiList' does not match `Maybe [a]'
01:58 <ski> no, `ambVal' shouldn't be throwing an error. there's only one data constructor of `Amb'
01:59 <sophiag> the very last error seems to correspond to that. although i'm not sure if it's because i'm using composition instead of application with the functions in map
01:59 <ski> looking at the definition of `unwrapMultiList', it's argument gets passed to `unwrapSList',`unwrapCList',`unwrapIList',`unwrapFList', all of which take a `MultiList' as input
01:59 iCharlie joined
02:00 ystael joined
02:00 <ski> so it seems that the type signature of `unwrapMultiList' is wrong, in that it should be specified as taking a `MultiList' as input
02:00 <sophiag> i get that part. that was a careless mistake
02:00 <ski> (perhaps the return type is also wrong, we don't know yet)
02:00 hucksy_ joined
02:00 <sophiag> right. i'm more thinking in the other direction
02:00 <sophiag> oh
02:00 <sophiag> but that solved the problem with ambVal
02:00 <ski> hmm
02:00 <* ski> nods
02:01 <ski> with a type error, it's usually some kind of clash between several source locations, of which at least one must be changed to avoid the type error
02:01 <ski> the one that one wants to change isn't always the location where the type checker discovered the inconsistency
02:01 <sophiag> i'm not sure i can do unwrapMultiList :: MultiList -> [a] given the outputs can be of different types
02:02 <* ski> nods
02:02 DataComputist joined
02:02 <ski> let's ignore that for the moment
02:02 <sophiag> which brings me back to the original issue of wanting permutations of the lists themselves, not the fields wrapped inside constructors
02:02 <sophiag> ok. i just want to be clear i'm a bit unsure about needing to unwrap them at all :p
02:02 <ski> what i'm saying is that the ways i suggest to try to fix the errors may perhaps not be pushing the program in the direction you'd prefer
02:02 wroathe joined
02:03 <ski> but, let's see where this leads
02:03 <sophiag> ok
02:03 <ski> iow, let's not look at `unwrapSList' and friends
02:03 zcourts joined
02:04 <ski> you have `unwrapSList (SList list) = mapM (...) list', with the signature `unwrapSList :: MultiList -> Maybe [String]'
02:04 <ski> so thus `list :: [String]' here. agree ?
02:04 <sophiag> yes
02:04 <sophiag> and that is the case
02:05 Goplat joined
02:05 <ski> so the function you pass to `mapM', i.e. `\l -> case l of String x -> Just x; _ -> Nothing', will get an `l' of type `String'
02:05 <ski> the type of `mapM' here will be something like
02:05 BlueRavenGT joined
02:06 <ski> mapM :: (String -> Maybe a) -> [String] -> Maybe [a]
02:06 <ski> for some particular `a'
02:06 <ski> looking at the declared return type of `unwrapSList', this `a' must be `String'
02:06 <sophiag> yup, still following
02:06 <ski> so this function that is passed to `mapM' should then have type `String -> Maybe String'
02:06 darjeeling_ joined
02:07 <ski> so .. now the `case' there doesn't make sense at all
02:07 <ski> `l' is already of type `String'
02:07 jedws joined
02:07 skeuomorf joined
02:07 <ski> also, you can't write a pattern `String x' there, and expect it to match if the thing you `case' on is a `String', and fail to match otherwise
02:08 exferenceBot joined
02:08 <ski> types don't exist at run-time
02:08 <ski> you can't inspect a value, and discover its type
02:08 <ski> you must already know the type of the value, in order to inspect it
02:08 <ski> and .. we already know `l' must be a `String' here, always, so there's no need to check
02:09 <ski> one could simplify the function here to `\l -> case l of x -> Just x' .. or just `\l -> Just l', iow `Just'
02:10 <sophiag> well the purpose of using Maybe is for composition
02:10 <sophiag> otherwise that seems fine...although not sure it will typecheck. it says it's looking for a Literal
02:10 <ski> but `mapM Just' is `mapM return' which will give you back the same list that you passed it, wrapped in a `Just' (after walking through to the end, which will never terminate for infinite lists .. but presumably your lists here are finite)
02:11 <ski> yea .. i'm not sure where `Literal' comes from. i see no mention of it in the source
02:11 <ski> hm .. perhaps you do have some *data* (not type) constructor `String', possibly belonging to a type `Literal' ?
02:11 <sophiag> well, these were originally parsed from Literals (an AST type) but i don't understand why they would be of type Literal at this point
02:12 <sophiag> they're of the types you see in that paste. they shouldn't be Literals inside there at this point
02:12 <ski> in such case, either the above still holds, or the argument type of `unwrapSList' &co. here (and also the patterns on the left of the `='s) is wrong
02:12 hexagoxel joined
02:13 <ski> anyway, there's another problem here as well
02:13 <ski> `unwrapSList' is partial
02:13 wroathe joined
02:13 takle joined
02:13 <ski> if you pass it a `CList ...',&c., then it's abort the program
02:13 <sophiag> well that's why i chose to use Maybe
02:13 <ski> probably you'd prefer returning `Nothing' in these cases ?
02:13 <sophiag> that's what i'm currently doing...
02:13 <ski> adding another defining equation :
02:13 <ski> unwrapSList _ = Nothing
02:14 <sophiag> oh i see
02:14 <ski> after the existing one, would be the simplest way to do that
02:14 raycoll joined
02:14 <ski> (and ditto for friends)
02:14 <sophiag> hold on a sec
02:15 pera joined
02:15 <sophiag> i'm a bit confused as to the difference between matching in the argument and using a case analysis that returns Maybe and having two argument types that return Maybe
02:15 <ski> iow, you can check, at run-time, whether the `MultiList' that you get is of the particular form/variant (*not* type !) that you expect, and in that case you'll return `Just (...)', otherwise `Nothing'
02:16 <sophiag> seeing as i know anything matching the given data constructor will contain that type
02:16 <ski> well, saying
02:16 sleffy joined
02:16 <ski> unwrapSList (SList list) = ..list..
02:16 <ski> unwrapSList _ = Nothing
02:16 <ski> is the same as saying
02:16 <ski> unwrapSList ml = case ml of
02:16 <ski> SList list -> ..list..
02:16 <ski> _ -> Nothing
02:16 <sophiag> should it be Just list in both cases?
02:17 <ski> so you can always rephrase "matching in the argument" with "using a case analysis"
02:17 bhiliyam joined
02:17 <sophiag> right i know that
02:17 <* ski> ponders the ".. that returns Maybe and having two argument types that return Maybe" part
02:17 <sophiag> no i understand now
02:17 <sophiag> your example was good
02:18 <ski> i don't think you want argument types with `Maybe' in them, here
02:18 <ski> anyway .. going back to `unwrapMultiList'
02:19 nomicflux joined
02:19 <ski> it seems that you wanted to try one after the other of these `unwrapSList',&c. .. and then since presumably at least one of them must succeed, you used `fromJust'
02:19 <sophiag> right that's where my errors are at this point
02:19 <sophiag> exactly
02:20 <sophiag> that's what i did when parsing them into this adt as well
02:20 <sophiag> although there i applied data constructors to each and didn't return a type variable
02:20 <ski> do you have anything to add about why you were writing `Maybe [a]' as the argument type, or should i consider the suggested argument type `Multilist' as the corrected version for that ?
02:20 <sophiag> no you were correct
02:20 <ski> ok
02:21 <ski> it seems to me that *maybe* you were wanting to express some kind of existential thing here, but didn't know how. and that's explaining why you wrote `[a]' as result type here
02:22 <sophiag> hmm
02:22 <sophiag> well i know how to use existentials
02:22 <sophiag> not sure that would be ideal here...
02:22 <ski> but it's hard to say, without knowing more about how this is to be called and used
02:22 <ski> so let's go back to `permList'
02:22 <sophiag> oh, well that's why i tried to clarify if my explanation made sense
02:22 <ski> @type permutations
02:22 <lambdabot> [a] -> [[a]]
02:23 <Zemyla> @src permutations
02:23 <lambdabot> Source not found. And you call yourself a Rocket Scientist!
02:23 <ski> @index permutations
02:23 <lambdabot> GHC.OldList, Data.List
02:23 louispan joined
02:23 wroathe joined
02:23 <sophiag> if i map permutations the ambVal field then i get permutations of each field with one another
02:23 <ski> ideally, i think the desired type of `unwrapMultilist' here would be
02:24 <ski> unwrapMultiList :: Multilist -> exists a. [a]
02:24 <sophiag> so like [[SList [..], IList [..]], [IList [..], SList [..]]]
02:24 <sophiag> oh ok. i have not used existentials like that before. usually in constraints
02:24 <ski> conceptually, if you call `permutations' on the result of type `exists a. [a]', you'd get a result of type `exists a. [[a]]'
02:25 <ski> makes sense ?
02:25 <ski> should i explain this `exists' notation i'm using ?
02:25 Goplat joined
02:25 <sophiag> no i understand that
02:25 <ski> ok
02:25 <sophiag> although ghc is recommending RankNTypes when i'm already using it...
02:26 uelen joined
02:26 <sophiag> are you sure exists doesn't go in a constraint?
02:26 <ski> anyway, since `a :: [Amb]', and we're in a `map', the result of that would then be of type `[exists a. [[a]]]'
02:26 steshaw joined
02:26 <ski> `exists' goes nowhere. it's not implemented in GHC
02:26 <ski> i'm just using it as a (imho) nicer way to express what we're *conceptually* after
02:27 <sophiag> oh ok. you mean if i had some data type that was an existential
02:27 infinity0 joined
02:27 alunduil joined
02:27 <ski> i mean if we had an actual existential quantifier `exists'. like we actually *do* have a universal quantifier, `forall'
02:27 <sophiag> i see
02:27 <ski> both of these would go in types (not in constraints, unless one also added those)
02:28 <sophiag> ok
02:28 <sophiag> probably not what i want, but i understand it
02:28 <ski> you know how `length :: [a] -> Int' really means `length :: forall a. ([a] -> Int)', right ?
02:28 <ski> and it's the presence of the `forall' in the type of `length' that makes `length' polymorphic
02:29 <ski> anyway, a value with an `exists' in the type is "abstract", there's some part of its type that is unknown/opaque
02:29 infinity0 joined
02:29 <ski> if we have a value of type `exists a. [a]', then we know that there is some (unknown) type `a', such that we have a list of values, all of that same (unknown) type `a'
02:30 <ski> otoh, with `[exists a. a]', each of the list elements could potentially have a *different* type
02:30 <ski> so the exact placement of `exists' is important
02:30 <ski> now .. there's two main ways in which to represent/*encode* `exists'
02:30 <sophiag> right. and i do not want the latter or i could have avoided using MultiList entirely
02:31 <ski> one i'm sure you know. the `data Showable = forall a. Show a => WrapShowable a' one
02:31 <sophiag> yes
02:31 <ski> here `WrapShowable :: forall a. Show a => a -> Showable', which is the same thing as `WrapShowable :: (exists a. Show a *> a) -> Showable'
02:32 infinity0 joined
02:32 <ski> (just like `length :: forall a. ([a] -> Int)' is the same as `length :: (exists a. [a]) -> Int' : as long as there *exists* some type `a', such that the argument has type `[a]', then the result will have type `Int')
02:32 <ryantrinkle> is there a canonical representation of Data.Constraint.Dict in base?
02:32 ystael joined
02:33 wroathe joined
02:33 <lyxia> No
02:33 <ski> the other way involves Continuation-Passing Style (CPS). basically instead of turning `unwrapMultiList :: Multilist -> exists a. [a]' into `unwrapMultiList :: Multilist -> SomeList' with `data SomeList = forall a. WrapList [a]'
02:33 stoopkid joined
02:34 <ski> you instead turn `unwrapMultiList :: Multilist -> exists a. [a]' into `withUnwrapMultiList :: Multilist -> (forall a. [a] -> o) -> o', and then you pass as an extra argument a "continuation" function that will receive the "result" as input
02:34 infinity0 joined
02:35 <ski> sophiag : if you're interested, i could expand more on this .. but i suspect you'd rather we go back to your code atm, yes ?
02:35 gugah joined
02:35 <ski> <ski> anyway, since `a :: [Amb]', and we're in a `map', the result of that would then be of type `[exists a. [[a]]]'
02:36 geekosaur joined
02:36 <ski> the result type of `permList' is declared as `[[MultiList]]', though
02:36 <sophiag> ha. well i understand continuations and haven't seen them used in data types like that, but it doesn't seem like a road i want to go down here
02:37 <ski> the CPS encoding is sometimes nicer than the "existential" data type encoding. it's a trade-off
02:37 <ski> anyway, `[exists a. [[a]]]' doesn't match `[[MultiList]]', even on this conceptual level
02:37 {emptyset} joined
02:37 infinity0 joined
02:37 <ski> first, we'd have to go from `[exists a. [[a]]]' to `[[exists a. [a]]]', which should be possible (as opposed to going in the opposite direction)
02:37 <sophiag> well MultiList is already a list so it's nested to the same level, unless i'm confusing you
02:38 <ski> next, we'd need to go from the inner `exists a. [a]' to `MultiList'
02:38 <ski> iow, we need to actually instead one of the data constructors `SList',`CList',`IList',`FList' !
02:38 <ski> this is actual run-time code that is missing !
02:39 <ski> a value of type `MultiList' is *not* a(n ordinary Haskell) list
02:39 <ski> it *contains* a list, together with a tag (the data constructor), which tells the element type
02:39 <sophiag> right, which is why when i try to map permutations to them i get permutations of the data constructors
02:39 <sophiag> i.e. back to the original problem
02:39 jsgrant joined
02:40 <ski> so .. you're attempting to unwrap the data constructors first
02:40 <ski> then doing something
02:40 infinity0 joined
02:40 <ski> and then you presumably want to *rewrap* the *same* data constructor as you had before, right ?
02:40 robertkennedy joined
02:40 <sophiag> perhaps i should permute them then rewrap?
02:41 <sophiag> tbh i'm trying to debug a more complicated function and this is the simplest behavior i'd like to start with
02:41 <ski> rather than looking at the whole `permList :: [Amb] -> [[MultiList]]', it's probably simpler to look at `permutations . unwrapMultiList . ambVal :: Amb -> [MultiList]'
02:42 <ski> i have an idea, which looks like it'll work for this code
02:42 <ski> but perhaps not for the more complicated case you have in mind
02:43 <ski> note that `permutations' doesn't care about the element type of the list. it just reshuffles the elements (iow considers only element *positions*, not the elements themselves)
02:43 <sophiag> yeah, i'm unsure because ultimately i do need the rest of the record in order to filter based on the Maybe Strings, but this is certainly going to be an issue somewhere in there
02:43 <ski> is this also true for the more complicated case you have ?
02:43 <sophiag> yes
02:43 <ski> or do you really need to know whether the element is a `String' or whatever ?
02:43 ali_bush joined
02:43 <sophiag> i do not
02:43 wroathe joined
02:43 <ski> ok, good
02:44 emc2 joined
02:44 <ski> and let me also confirm that you do want `[[MultiList]]' (rather than some kind of existential thing) as result type of `permList' ?
02:44 <ski> anyway, what i suggest is :
02:45 moet joined
02:45 <sophiag> well most likely the order will be to match the other field of the record with another record that has a comparale field, then call permutations on the list wrapped in there, then filter it based on the matching other record
02:45 <ski> rather than call `permutations' on the result of `unwrapMultiList', instead pass `permutations' as an argument to it
02:45 <sophiag> so i would prefer to leave the mapping on the outside
02:45 <sophiag> ah, that's clever!
02:45 <ski> so `unwrapMultiList' will unwrap, then apply the argument function that it gets, then *rewrap* the *same* data constructor it unwrapped
02:46 <ski> so, better rename it to `mapMultiList' or something
02:46 des_ joined
02:46 <sophiag> yes. ideally i'd rather not have it actually print the data constructors but it seems i need them to do this operation on one record type
02:46 pavonia joined
02:46 <ski> note that the type signature of `mapMultiList' will be slightly .. exotic
02:46 <ski> can you guess what it'll be ?
02:47 <sophiag> hold on let me reread
02:48 <sophiag> wait, i'm not even sure what function you're referring to
02:49 cur8or joined
02:49 soLucien joined
02:49 <ski> (or perhaps something like .. `processMultiList' would be a better name ? not suggesting that there's a list on which we'll apply the given function to every element thereof -- because we're going to apply the given function once, to the whole list, not once to every element of the list)
02:49 <ski> i'm suggesting something like
02:49 <sophiag> still not sure which function in my actual code this corresponds to
02:50 <ski> permList a = map (processMultiList permutations . ambVal) a
02:50 <sophiag> ok
02:50 <ski> where `processMultiList' is a reformulation of `unwrapMultiList', to also rewrap, after having applied the argument function
02:50 <sophiag> ok
02:50 <sophiag> one sec
02:50 <ski> (and then you'd not need to use these `<|>'s .. in case that's not clear)
02:51 <sophiag> oh ok
02:51 <ski> (nor the `unwrapSList',&c. .. just match directly)
02:52 <sophiag> ok, writing it now
02:53 cschneid_ joined
02:53 ChaiTRex joined
02:53 <sophiag> well i figured it should be like unwrapMultiList :: ([a] -> [[a]]) -> MultiList -> [MultiList]
02:53 <sophiag> but not quite working
02:53 wroathe joined
02:54 <ski> right, good try
02:55 <ski> the point to note here is that we want the *argument* of this function to be polymorphic
02:55 <sophiag> oh so use an existential there?
02:55 meandi_2 joined
02:55 <ski> wait, not so fast :)
02:55 takle joined
02:55 <ski> we don't want this function, `unwrapMultiList'/`mapMultiList'/`processMultiList' (or whatever you prefer to call it) to be polymorphic
02:56 <sophiag> right, but i could just apply a constraint to a
02:56 <ski> `processMultiList' being polymorphic would mean that the *caller/user* of `processMultiList' will get to pick the type of `a'
02:56 <sophiag> i.e. the type of the function passed as an argument
02:56 <ski> processMultiList :: ([a] -> [[a]]) -> MultiList -> [MultiList]
02:56 <ski> is short for
02:56 <ski> processMultiList :: forall a. ([a] -> [[a]]) -> MultiList -> [MultiList]
02:56 <ski> or, to be extra clear
02:56 <ski> processMultiList :: forall a. (([a] -> [[a]]) -> MultiList -> [MultiList])
02:56 <ski> which *does* mean that `processMultiList' is what's to be polymorphic
02:57 <sophiag> oh ok. i just had the syntax wrong
02:57 <ski> but you want the argument function to be polymorphic, so
02:57 <ski> processMultiList :: (forall a. [a] -> [[a]]) -> MultiList -> [MultiList]
02:57 teggi joined
02:57 <ski> this means that the *caller/user* of the *argument* function, iow `processMultiList' itself, will get to pick `a'
02:57 <ski> which is exactly what you want
02:57 DataComputist joined
02:58 <ski> you want it to pick `a' as `String' in the `SList' case, as `Char' in the `CList' case, &c.
02:58 <ski> ok ?
02:58 SimpleL joined
02:58 <ski> this btw requires the extension `Rank2Types'
02:58 <sophiag> i'm using RankNTypes already
02:58 <ski> `processMultiList' is a rank-2 operation here, because it has a polymorphic argument
02:58 <* ski> nods
02:58 <sophiag> ghc doesn't like me applying the data constructor again if i'm like "SList x -> SList $ f x"
02:59 <sophiag> because that would return MultiList not [MultiList]
02:59 halogenandtoast joined
02:59 <ski> use `map' ?
03:00 <sophiag> ooo
03:00 <sophiag> all good :D
03:00 <* ski> smiles
03:01 <ski> so .. all good now ?
03:01 <sophiag> yup
03:01 shafox joined
03:01 <sophiag> well...that was just to replicate the simplest part of a function i'm trying to debug, but i was really confused about it
03:02 edvorg joined
03:02 <sophiag> and i'm still wondering whether all this wrapping and unwrapping would be a good use case for lenses. i'm on the fence considering i'm not using nested records
03:02 <sophiag> although i could be...probably best to get it working and consider refactoring as i begin to understand lenses more
03:03 <* ski> nods
03:04 wroathe joined
03:04 <sophiag> well, thanks so much for walking me through all that! now to see if i can fix the more complicated function :p
03:04 ContessaTP joined
03:05 flout joined
03:07 moet joined
03:07 cur8or joined
03:08 Flechette joined
03:08 xtreak joined
03:09 justanotheruser joined
03:12 robertkennedy joined
03:13 Koterpillar joined
03:15 Flechette joined
03:17 flatmap13 joined
03:17 sellout- joined
03:17 <sophiag> ski: mind if i throw the more complicated case at you? it's driving me a bit nuts because it compiles fine yet always returns an empty list :/
03:18 <sophiag> http://lpaste.net/354506
03:18 bhiliyam joined
03:20 felixsch__ joined
03:20 juhp joined
03:22 xall joined
03:24 wroathe joined
03:25 roboguy` joined
03:25 louispan joined
03:25 mizu_no_oto joined
03:26 hexfive joined
03:28 pera joined
03:30 flatmap13 joined
03:37 xtreak joined
03:37 <ski> sophiag : hrm, let me take a look
03:38 <sophiag> thanks. the recursive calls struck me as a bit janky from the start, but i don't think that's the issue
03:39 xtreak joined
03:41 <ski> i'm wondering if you perhaps wanted to use `++' (or `concat') rather than `do' there
03:42 <ski> line `30' is dead code, redundant
03:44 <ski> not sure why you don't just `fromBoolAmbVal . fromJust' instead of `fromJustAmbVal', where `fromBoolAmbVal :: AmbVal -> Bool'
03:44 <ski> still, it'll crash and burn in case that list ever contains anything ele than `BoolVal (...)'s
03:44 wroathe joined
03:45 <ski> (er, or rather, in case `reqAmbVal' on elements of the lists ever does that)
03:46 <ski> you're using `do' for the `[]' monad here -- it's not clear to me why you'd want to do that here. especially as you don't use `<-' to capture the results
03:46 <ski> > do "two" "three"
03:46 <lambdabot> error:
03:46 <lambdabot> • Couldn't match expected type ‘[Char] -> t’
03:46 <lambdabot> with actual type ‘[Char]’
03:46 <ski> > do "two"; "three" -- er, rather
03:46 <sophiag> oh hmm
03:46 <lambdabot> "threethreethree"
03:47 <ski> it's just replicate the last thing, as many times as there's elements of the list before
03:47 <ski> so .. in case that list is empty, the whole will be the empty lis
03:47 <ski> t
03:47 <ski> (which is probably what happened in your case)
03:47 <sophiag> that's a good point in that it will only return the last match whereas i want to concat the results of every pass through
03:47 <ski> right
03:47 <ski> <ski> i'm wondering if you perhaps wanted to use `++' (or `concat') rather than `do' there
03:47 steeze joined
03:48 <ski> btw, in either case, you could factor the common parts of the `if' branches out of the `if'
03:49 <sophiag> you mean the recursive calls?
03:49 <sophiag> yeah
03:49 <ski> yes
03:53 <sophiag> ok, so at least getting an exception now :)
03:55 <sophiag> oh ok i think it actually works now. but i realized i left out the ability to parse lists on the rhs of the lambdas (what i'm storing in Require) so they're not good for anything really
03:56 <sophiag> i would still prefer to remove the data constructors when it prints output tho :/
03:56 pheaver joined
03:57 <sophiag> oh and also i'm matching everything twice because i couldn't think of a way to match every element using recursion. so that's not good
03:57 chenshen joined
03:58 shafox joined
03:58 <sophiag> so with no actual filtering done i get something like "[ListVal [[IList [1,2,3],IList [2,1,3],IList [3,2,1],IList [2,3,1],IList [3,1,2],IList [1,3,2]]],ListVal [[IList [1,2,3],IList [2,1,3],IList [3,2,1],IList [2,3,1],IList [3,1,2],IList [1,3,2]]]]"
03:59 <sophiag> when i'd prefer just [[1,2,3], [2,1,3], [3,2,1], [2,3,1], [3,1,2], [1,3,2]]
03:59 cur8or joined
04:01 <sophiag> ski: this is how it looks now: http://lpaste.net/354506
04:02 wroathe joined
04:03 xinming joined
04:04 gmhafiz joined
04:05 boombanana joined
04:07 tudebot joined
04:08 tudebot left
04:09 aarvar joined
04:09 fkurkowski joined
04:10 fakenerd joined
04:11 splanch joined
04:12 <halogenandtoast> if I have a nested list, how can I compose lenses to update an element, I wanted to do xxs ^? ix 2 ^? ix 1 .~ newValue but the first ^? returns a maybe list not a list
04:12 <halogenandtoast> is there a lens operator for Maybe values?
04:13 hamishmack joined
04:13 <ski> sophiag : hm, the `do' isn't needed there, now
04:13 <sophiag> question about Show instances. i derived my own in order to strip out the data constructors from an adt and am now unsure how to make everything else that uses that type use my custom instance for that field rather than the generic one: http://lpaste.net/354508
04:13 <sophiag> ah, thanks ski
04:14 <ski> it'll automatically use your custom instance
04:14 <halogenandtoast> sophiag: what ski said
04:15 <sophiag> you mean if i leave off "deriving (Show)" in each case?
04:15 <sophiag> or use OverlappingInstances?
04:15 <sophiag> right now it's not compiling
04:15 <ski> no i mean if you keep deriving `Show' for `Amb' and `AmbVal'
04:15 <sophiag> oh i see
04:15 <ski> it'll pick up your custom insteance for `MultiList'
04:16 <ski> anyway, even skipping the data constructors, you have differing levels of nested lists
04:16 vlatkoB joined
04:16 <halogenandtoast> I'm a derp, I figured out my question
04:17 <ski> btw, i'm not really understanding what task your pattern of recursion in `eval' is meant to accomplish
04:17 xtreak joined
04:17 <sophiag> oh, the problem was just i forgot to omit "deriving (Show) from the first adt :p
04:17 <* ski> notes `eval' changed return type
04:18 <ski> yea, right. shouldn't spotted that
04:18 <ski> er. s/shouldn't/should've/
04:18 <sophiag> i understood
04:18 <* ski> is a bit tired
04:18 <sophiag> yeah, my sleep schedule got a bit off this weekend :/
04:18 <halogenandtoast> I needed to do xxs & (ix 0 . ix 2) .~ newValue
04:19 <sophiag> eval changed return types to match that of the functions in the Require records
04:19 bhiliyam joined
04:20 <ski> oh, i noticed before but then forgot to say : the argument of `Require' is unused
04:20 <nshepperd> halogenandtoast: that's the same as ((ix 0 . ix 2) .~ newValue) xxs right?
04:20 <sophiag> ski: oh, sorry missed your question. the reason i'm recursing that way is to match _every_ element in both lists rather than just by index, i.e. like a list comprehension would. but the way i'm doing it currently results in duplicates
04:20 <halogenandtoast> nshepperd: yes
04:21 <sophiag> ski: oh, thanks for pointing that out. that's a legacy thing from a refactor :p
04:22 <ski> sophiag : you want `eval xs ys' to match every element of `xs' with every element of `ys' ?
04:22 ali_bush joined
04:22 ali_bush joined
04:22 <sophiag> yes
04:22 wroathe joined
04:22 <sophiag> and described this way of doing it as "janky" :)
04:22 <ski> well, you're not doing that, even (even disregarding the duplication)
04:23 <sophiag> oh?
04:23 <ski> in the recursive defining equation, you're never passing both `xs' and `ys' to a recursive call
04:23 <ski> so you'll never compare the elements in the tail `xs' with the elements in the tail `ys'
04:23 <sophiag> oh, yeah it's just the head of each
04:23 <sophiag> plus if they're different lengths i'm in trouble
04:23 <ski> how about .. using a list comprehension ?
04:24 <ski> (or the `[]' monad, if you prefer. amounts to the same thing)
04:24 <sophiag> yeah, that would certainly simplify it. i think the only reason i didn't originally was because preferring explicit filters over constraints given i'm passing functions
04:25 <ski> that would reintroduce `do' here .. but not in quite the way you had it before
04:25 thunderrd joined
04:25 <ski> (not quite sure what you mean by "constraints" here ..)
04:25 <sophiag> the functions in Require
04:25 <ski> mhm, ok
04:26 <* ski> hrms
04:27 <ski> i suppose, since you're using a singleton list, you could avoid the `filter' call altogether
04:27 eklavya joined
04:27 <sophiag> i was trying something like: eval a r = [x | x <- a, y <- r , filter (fromJustAmbVal . reqAmbVal y) [ListVal $ permuteList x]]
04:29 <ski> eval a r = [l | x <- a,y <- r,let l = ListVal (permuteList x),(fromJustAmbVal . reqAmbVal y) [l]]
04:29 <sophiag> ah :)
04:29 <ski> you want to collect `ListVal (permuteList x)'s, not `x's
04:29 <sophiag> i was just fixing it, but wouldn't have got quite there
04:30 <ski> just writing a `Bool' expression in a list comprehension will do a "guard". no need to call `filter'
04:30 <ski> filter p as = [a | a <- as,p a]
04:31 <ski> @undo [a | a <- as,p a]
04:31 <lambdabot> concatMap (\ a -> if p a then [a] else []) as
04:31 <ski> well, which is the same as `filter p as'
04:31 <sophiag> i just wasn't certain whether anything returning Bool, i.e. lambdas, were ok
04:31 <ski> lambdas ?
04:31 <ski> where ?
04:31 baldrick joined
04:32 JoshS joined
04:32 <sophiag> the functions in Require are lambdas
04:32 wroathe joined
04:33 <ski> well, it doesn't matter how you compute the `Bool' ..
04:33 <sophiag> i think i need to rewrite some of the helper functions now to make the types match
04:33 xtreak joined
04:34 presiden joined
04:36 <sophiag> ok, it's compiling now...
04:37 <* ski> . o O ( that feeling when your program compiles the first time around, and you're wondering what's wrong )
04:37 <sophiag> well, i won't know until i fix how i'm parsing lambdas to take lists on the rhs
04:37 <sophiag> should be simple
04:37 <sophiag> considering i already have functions to parse lists
04:40 Wisseman joined
04:41 <sophiag> i'm just trying to get rid of the outer data constructor now with another custom Show instance...
04:42 <sophiag> the data constructor is ListVal [MultiList] so i can't do show ListVal x = show x
04:45 <sophiag> oh, it's fine. i was just missing parens... lisp trauma
04:46 cschneid_ joined
04:47 <sophiag> i just have an extra level of nesting that i'm not sure i can get rid of
04:50 louispan joined
04:50 samrat joined
04:52 ryxai joined
04:52 osa1 joined
04:53 path[l] joined
04:53 wroathe joined
04:56 <halogenandtoast> If I have a record, how to do make a lense to a field without using makeLenses ?
04:57 <Koterpillar> halogenandtoast: lens wiki has an example
04:57 <Koterpillar> halogenandtoast: http://hackage.haskell.org/package/lens search for "define lenses"
04:58 Cale joined
04:58 <halogenandtoast> thanks Koterpillar, that seems to be without lens, in addition to without makeLenses/templateHaskell
04:58 shafox joined
04:59 <halogenandtoast> I'm fine with the dependency
04:59 <Koterpillar> I'm not sure how much shorter can you make it
05:00 <Koterpillar> if you find a better one, let me know
05:02 fakenerd joined
05:02 ph88_ joined
05:03 azahi joined
05:04 beanbagula joined
05:04 jhrcek joined
05:04 dec0n joined
05:04 <halogenandtoast> Koterpillar: will do :\
05:05 tathougies joined
05:05 splanch joined
05:07 Mutter joined
05:10 systemfault joined
05:11 systemfault joined
05:12 ichor joined
05:13 systemfault joined
05:14 dan_f joined
05:14 systemfault joined
05:15 systemfault joined
05:17 <halogenandtoast> Koterpillar: I gave up and used makeLenses
05:17 <halogenandtoast> easier not to fight it.
05:17 <Koterpillar> I feel like you can derive some lenses using Generic
05:19 danvet joined
05:20 bhiliyam joined
05:20 zargoertzel joined
05:21 insitu joined
05:22 zargoertzel joined
05:23 wroathe joined
05:24 jud joined
05:24 jud joined
05:26 <Cale> halogenandtoast: Sometimes I like to think about the price tag associated to particular lines of code, especially TH code, in our codebase. In some cases, the developer effort to maintain the stuff that the TH is generating would be pretty large, and it's good. In other cases, the makeLenses that someone absentmindedly slapped on some type adds 10 seconds to the build time for something which wouldn't really be so hard to write by hand.
05:26 jgt2 joined
05:27 <halogenandtoast> Cale: right now I'm just learning lenses so I don't yet have a firm grasp of how to use them, nevermind write them.
05:27 beanbagula joined
05:27 <Cale> Ah, in the cases where we actually get lots of use out of the lenses, I'm not usually so upset, but those cases are pretty rare. It's usually just one line somewhere.
05:27 <halogenandtoast> The problem is that they are so simple they're extremely complicated
05:28 <halogenandtoast> I really just want a few lenses to do stuff like
05:29 <halogenandtoast> 5
05:29 <halogenandtoast> https://gist.github.com/halogenandtoast/8d4a17fa78e4719c4dfc51e7cf351f05
05:30 mazeinmaze_ joined
05:30 <halogenandtoast> Any suggestions on how to make that better would be appreciated.
05:30 AustinMatherne joined
05:31 <halogenandtoast> I figured since I have a nested structure lenses might be a good call.
05:31 xall joined
05:31 mrowe left
05:32 <Cale> Yeah, there's not really any problem with using lenses, and if your compile times aren't bothering you it's no big deal :)
05:32 kaeluka joined
05:32 <Cale> But I can show you how to write a lens
05:32 <halogenandtoast> Cale: That would be awesome, regardless of my compile times
05:32 <halogenandtoast> stack build 3.54s user 1.35s system 97% cpu 5.002 total
05:33 <halogenandtoast> which are fine
05:33 Swizec joined
05:33 <Cale> focus/build-frontend 253.12s user 36.44s system 101% cpu 4:44.89 total
05:33 <Cale> lol
05:33 <Cale> (thankfully ghci works, so that's not actually something I have to wait for very often)
05:34 wroathe joined
05:35 takle joined
05:35 <Cale> The key pattern is that it's like you're splitting the data structure into two parts: the part which is focused on (and which view will get out), and a function which given a replacement for that part, will reconstruct the structure with that filled in
05:35 <sophiag> ooo, i want to listen in on this :)
05:35 steeze joined
05:36 <Cale> So for example, let's just start with the first part of a pair
05:36 <Cale> If we have some pair (x,y), we can split that into the function (\x' -> (x',y)) and the value x
05:37 <Cale> and then to get our lens, what we want is to take some function f, and the pair (x,y) and produce (\x' -> (x',y)) <$> f x
05:37 <Cale> i.e.
05:38 <Cale> @let myFst f (x,y) = (\x' -> (x',y)) <$> f x
05:38 <lambdabot> Defined.
05:38 <Cale> > view myFst (3,4)
05:38 <lambdabot> 3
05:38 <Cale> > set myFst "hello" (3,4)
05:38 <lambdabot> ("hello",4)
05:38 caumeslasal joined
05:39 <thimoteus> :t myFst
05:39 <lambdabot> Functor f => (t2 -> f t1) -> (t2, t) -> f (t1, t)
05:40 <Cale> Let's rename that a bit: Functor f => (a -> f b) -> (a, x) -> f (b, x)
05:41 <halogenandtoast> I understood the type from context.
05:41 <Cale> The key pattern is that you're always going to be applying this arbitrary function to the part which is extracted, and then fmapping over the result of that a function which puts back everything else in the original structure
05:42 <Cale> Traversals are similar, except there, you get to make use of Applicative to pick out multiple bits of the structure at once:
05:42 <halogenandtoast> so does view fmap with id (or something to do with Const)
05:42 mstruebing joined
05:44 aarvar left
05:44 wroathe joined
05:44 <Cale> Yeah, view uses the Const functor
05:44 <Cale> > myFst Const (1,2)
05:44 <lambdabot> Const 1
05:44 <Cale> > getConst (myFst Const (1,2))
05:44 <lambdabot> 1
05:44 <Cale> :t Const
05:45 <lambdabot> forall k (b :: k) a. a -> Const a b
05:45 kaeluka joined
05:45 <Cale> set uses the Identity functor
05:45 <halogenandtoast> @src view
05:45 <lambdabot> Source not found. :(
05:45 <halogenandtoast> You're dead to me lambdabot
05:46 <Cale> > myFst (\v -> Identity "hello") (1,2)
05:46 <lambdabot> Identity ("hello",2)
05:46 <Cale> > runIdentity (myFst (\v -> Identity "hello") (1,2))
05:46 <lambdabot> ("hello",2)
05:47 <halogenandtoast> I see so Identity is used for set/over
05:47 <Cale> yep
05:47 <Cale> Now for Traversals, we can follow a very similar pattern
05:47 <halogenandtoast> And those by themselves aren't useful, but this allows us to compose.
05:48 <halogenandtoast> s/\./?/
05:48 <Cale> But we make use of the Applicative structure available to us to pick out multiple parts at once
05:48 <Cale> Sorry, what's not useful?
05:48 <halogenandtoast> The fact that Const and Identity are used are a byproduct of wanting to compose lenses (my assumption)
05:49 <halogenandtoast> We need something to fit the base case.
05:49 <Cale> Const and Identity are used there as a way to *use* lenses that we've already built
05:49 <Cale> Not so much to compose them
05:49 <halogenandtoast> alright
05:49 <Cale> Composing lenses is just a matter of function composition, with the way we've set things up
05:49 <Cale> :t myFst . myFst
05:49 <lambdabot> Functor f => (t3 -> f t2) -> ((t3, t), t1) -> f ((t2, t), t1)
05:50 <Cale> You'll always have something of the form
05:50 <Cale> (a -> f b) -> s -> f t
05:50 edsko joined
05:51 <Cale> (a -> f b) -> (s -> f t)
05:51 <Cale> Let's add those parens for emphasis
05:51 <Cale> Such functions are quite likely to compose, right?
05:52 <Cale> It sometimes helps to consider the case when f is a monad like IO
05:53 <halogenandtoast> How would one ascertain that those functions are likely to compose
05:53 <halogenandtoast> what's the red flag I'm looking for?
05:53 <Cale> Given an effectful function (a -> f b) which acts on some small part of the structure, the lens explains how to transform it to act on the whole structure, replacing the small part with its result
05:53 <Cale> Oh, just that the shape of the type in the domain and codomain is similar
05:54 <halogenandtoast> Cale: okay
05:54 wroathe joined
05:54 <Cale> If it helps you may want to regard a -> f b as an "effectful" function, and the lens is then telling you how to apply that effectful function to some part of a data structure.
05:55 pheaver joined
05:56 eacameron joined
05:56 ogrady joined
05:56 <Cale> In the case of Const, the "effect" is just to abort with the value we've obtained, without ever producing a result to replace it with in the overall structure (the Const functor doesn't have a place for us even to record that)
05:56 danvet joined
05:56 <halogenandtoast> Const a b = Const a or something
05:56 <Cale> Yeah, data Const a b = Const a
05:57 Destol joined
05:57 insitu joined
05:57 <halogenandtoast> Right
05:57 litchblade joined
05:57 MoALTz joined
05:57 <Cale> In the case of Identity, it's just like I described, but no potential for effects, we're applying a basically ordinary function to the value, obtaining a replacement, and putting that in.
05:58 <Cale> But yeah, if you want to think of these things as a way of transforming potentially-effectful functions, that might work
05:58 <Cale> (to operate on some smaller piece of a larger structure)
05:59 <Cale> (and leave the rest untouched)
05:59 <Cale> Good?
05:59 <halogenandtoast> I'm not sure I understand the term "effectful functions" well.
05:59 takle joined
06:00 <Cale> ah, well, I mean in the sense that you might regard a function of type a -> IO b as an "effectful function"
06:00 safe joined
06:00 <halogenandtoast> Sure, but it doesn't have to be effectful right?
06:00 ThomasLocke joined
06:00 ThomasLocke joined
06:00 <halogenandtoast> I'm now assuming effectful = side effect
06:00 <Cale> Well, the sense of the word "effect" is arbitrary
06:00 <halogenandtoast> but that might be incorrect
06:01 <Cale> because we have any functor whatsoever there
06:01 <Cale> The values of a lot of functors in Haskell tend to describe effects of various sorts, but sometimes you have to stretch your notion of what an "effect" consists of somewhat
06:02 zeroed joined
06:02 zeroed joined
06:02 <Cale> e.g. lists can be thought of as computations having nondeterminism effects: they can sort of describe multiple realities in which they've produced each of a number of different results
06:02 <Cale> > do x <- [1,2,3]; y <- [4,5]; return (x,y)
06:02 <lambdabot> [(1,4),(1,5),(2,4),(2,5),(3,4),(3,5)]
06:03 takuan joined
06:03 <halogenandtoast> That's still black magic
06:03 <Cale> You can think of "running" a list there as picking an element of the list, in all possible ways
06:03 beanbagula joined
06:03 <Cale> Of course, it just amounts to using map and concat
06:04 <Cale> But it's possible to think of it that way anyhow.
06:04 <halogenandtoast> sure, similar to a list comprehension
06:04 <Cale> yeah, it's exactly the same thing as a list comprehension
06:04 wroathe joined
06:04 <halogenandtoast> [(x, y) | x <- [1,2,3], y <- [4,5]]
06:04 <halogenandtoast> > [(x, y) | x <- [1,2,3], y <- [4,5]]
06:04 pwnz0r joined
06:04 <lambdabot> [(1,4),(1,5),(2,4),(2,5),(3,4),(3,5)]
06:05 plutoniix joined
06:05 testosticore joined
06:05 <halogenandtoast> The syntax is even suspiciously similar
06:05 <Cale> > myFst (\v -> [v, 10*v, 100*v]) (1,"hello")
06:05 <lambdabot> [(1,"hello"),(10,"hello"),(100,"hello")]
06:05 <Cale> > myFst (\v -> [v, 10*v, 100*v]) (4,"hello")
06:05 <lambdabot> [(4,"hello"),(40,"hello"),(400,"hello")]
06:06 raichoo joined
06:06 plutoniix joined
06:06 juhp joined
06:06 sanett joined
06:07 <Cale> So we can enumerate many possible substitutions that way
06:07 hurkan joined
06:07 <nshepperd_> Hm. Nondeterminism monad that uses a quantum coin flip to literally create multiple realities for all the possible outcomes
06:07 plutoniix joined
06:08 mszczygiel joined
06:08 SimpleL joined
06:08 <Cale> > runWriter (myFst (\v -> do tell [v]; return "told") (42, "you"))
06:08 <lambdabot> (("told","you"),[42])
06:09 <Cale> So here, we replace the first component of the pair with a new value, and at the same time, write what was there before to the Writer monad's log.
06:09 <Cale> We could play similar games with State
06:10 testosticore left
06:11 <Cale> > flip runState 0 $ myFst (\v -> do x <- get; put v; return x) (1,2)
06:11 <lambdabot> error:
06:11 <lambdabot> Ambiguous occurrence ‘get’
06:11 <lambdabot> It could refer to either ‘Control.Monad.State.get’,
06:11 <Cale> tsk
06:11 <Cale> > flip runState 0 $ myFst (\v -> do x <- Control.Monad.State.get; put v; return x) (1,2)
06:11 <lambdabot> ((0,2),1)
06:11 <Cale> So, there, we swap the current state with the value in the first component of the pair
06:12 <Cale> halogenandtoast: cool?
06:12 DataComputist joined
06:12 <halogenandtoast> sorry reading a bit of backlog
06:13 <halogenandtoast> 1 sec
06:13 des_ joined
06:13 locallycompact joined
06:13 sw1nn joined
06:13 ner0x652 joined
06:14 <Cale> If we could use IO here, we could do something like
06:14 <halogenandtoast> Cale: I guess so, I tend to learn from practical examples, so I need to figure out how to write some lenses for my structure
06:14 wroathe joined
06:14 <halogenandtoast> so 1 sec, let me try one
06:15 <Cale> myFst (\v -> do putStrLn ("The existing value is " ++ show v ++ " enter a new one."); getLine) ("hello", "there")
06:15 <Cale> Yeah, these examples aren't especially practical, they're just trying to illustrate what the lens does to some extent.
06:16 <halogenandtoast> Cale: so let's say I have
06:16 <halogenandtoast> data Square = Square { mine :: Bool
06:16 <halogenandtoast> , flagged :: Bool
06:16 <halogenandtoast> , revealed :: Bool
06:16 <halogenandtoast> , mineCount :: Int
06:16 <halogenandtoast> , position :: Position
06:16 <halogenandtoast> } deriving (Show)
06:16 <halogenandtoast> is this a valid lens?
06:16 <halogenandtoast> revealed' f square@(Square _ _ r _ _) = (\r' -> square { revealed = r }) <$> f r
06:17 <halogenandtoast> err almost
06:17 <halogenandtoast> revealed' f square@(Square _ _ r _ _) = (\r' -> square { revealed = r' }) <$> f r
06:17 <Cale> yeah
06:17 <Cale> and what's the type of revealed'?
06:18 <Cale> (perhaps think about it a moment before asking ghci ;)
06:18 insitu joined
06:18 <halogenandtoast> Functor f => (Bool -> f Bool) -> Square -> f Square ?
06:19 <Cale> yep
06:19 <halogenandtoast> @let revealed' f square@(Square _ _ r _ _) = (\r' -> square { revealed = r' }) <$> f r
06:19 <lambdabot> .L.hs:182:21: error:
06:19 <lambdabot> Not in scope: data constructor ‘Square’
06:19 <lambdabot> Perhaps you meant variable ‘square’ (line 182)
06:20 <Cale> @let data Square = Square { mine :: Bool, flagged :: Bool, revealed :: Bool, mineCount :: Int, position :: (Int, Int) } deriving (Show)
06:20 doomlord joined
06:20 <lambdabot> Defined.
06:20 <halogenandtoast> @let revealed' f square@(Square _ _ r _ _) = (\r' -> square { revealed = r' }) <$> f r
06:20 <Cale> @let revealed' f square@(Square _ _ r _ _) = (\r' -> square { revealed = r' }) <$> f r
06:20 sanett joined
06:20 <lambdabot> Defined.
06:20 <lambdabot> .L.hs:188:1: warning: [-Woverlapping-patterns]
06:20 <lambdabot> Pattern match is redundant
06:20 <lambdabot> In an equation for ‘revealed'’:
06:20 <Cale> haha
06:20 <halogenandtoast> :t revealed'
06:20 <lambdabot> Functor f => (Bool -> f Bool) -> Square -> f Square
06:20 <halogenandtoast> checks out
06:21 bhiliyam joined
06:21 <halogenandtoast> so in the case where we use view it would be
06:21 MejGun joined
06:21 <halogenandtoast> (Bool -> Const Bool Bool) -> Square -> Const Bool Square
06:21 <Cale> > over revealed' not (Square True False False 9 (2,3))
06:21 <lambdabot> Square {mine = True, flagged = False, revealed = True, mineCount = 9, positi...
06:21 <Cale> > revealed' Const (Square True False False 9 (2,3))
06:21 <lambdabot> Const False
06:21 eatman joined
06:22 <Cale> > getConst (revealed' Const (Square True False False 9 (2,3)))
06:22 govg joined
06:22 <lambdabot> False
06:22 <Cale> and yeah
06:23 <Cale> You can think of a Const Bool Square as being a computation which purports to be trying to result in a Square, but never actually will, and will instead always abort with some value of type Bool.
06:23 <halogenandtoast> Yeah I understand Const, it's amazing.
06:23 <Cale> That is, if you like this computational analogy
06:24 <halogenandtoast> Just makes really cool use of Phantom Types.
06:25 wroathe joined
06:25 deech` joined
06:26 aarvar joined
06:26 <Cale> @let squareBools f (Square m l r c p) = (\m' l' r' -> Square m' l' r' c p) <$> f m <*> f l <*> f r
06:26 <lambdabot> Defined.
06:26 <Cale> This is silly, but let's pretend for a moment that it's not
06:26 <Cale> :t squareBools
06:26 <halogenandtoast> I'm bad at pretending.
06:26 <lambdabot> Applicative f => (Bool -> f Bool) -> Square -> f Square
06:26 <Cale> This no longer works for any Functor, but it's almost like a Lens
06:27 <Cale> It makes use of Applicative to be able to operate on multiple parts of the structure at once
06:27 beanbagula joined
06:27 <Cale> The pattern is the same: we split the thing up into a function which is basically like the original structure with some holes punched in it
06:27 <Cale> and then apply the given function to each of the things we popped out of the holes
06:28 <Cale> and substitute the results back in place
06:28 <Cale> > over squareBools not (Square True False False 9 (2,3))
06:28 <lambdabot> Square {mine = False, flagged = True, revealed = True, mineCount = 9, positi...
06:28 <Cale> So, there we negate all the bools at once
06:28 sanett joined
06:29 <halogenandtoast> Right
06:29 <Cale> and that's basically what a Traversal is
06:30 jgornick joined
06:30 zeroed joined
06:30 dpn` joined
06:30 Forkk joined
06:31 <Cale> > runWriter (squareBools (\b -> tell [b]) (Square True False False 9 (2,3)))
06:31 <lambdabot> error:
06:31 <lambdabot> • Couldn't match type ‘()’ with ‘Bool’
06:31 <lambdabot> Expected type: WriterT [Bool] Identity Bool
06:31 <Cale> oops
06:31 Vbitz joined
06:31 <Cale> > runWriter (squareBools (\b -> tell [b]; return b) (Square True False False 9 (2,3)))
06:31 <lambdabot> <hint>:1:39: error: parse error on input ‘;’
06:31 <Cale> > runWriter (squareBools (\b -> do tell [b]; return b) (Square True False False 9 (2,3)))
06:31 <lambdabot> (Square {mine = True, flagged = False, revealed = False, mineCount = 9, posi...
06:31 gregman_ joined
06:31 <Cale> > execWriter (squareBools (\b -> do tell [b]; return b) (Square True False False 9 (2,3)))
06:31 <lambdabot> [True,False,False]
06:31 <halogenandtoast> Cale: thanks I was able to remove TemplateHaskell.
06:32 geekosaur joined
06:33 <Cale> cool
06:34 darjeeling_ joined
06:34 GGMethos joined
06:35 wroathe joined
06:38 <joneshf-laptop> Is there an elegant way to encode the idea of a list that cannot contain some items?
06:38 <joneshf-laptop> Like, say I wanted a list of any `Int`s except `3`.
06:39 quchen joined
06:39 <Cale> Not really
06:40 <joneshf-laptop> :(
06:40 <Cale> You really need dependent types to encode that sort of thing
06:40 <Cale> (types which can be parameterised on values)
06:40 <joneshf-laptop> Can `GHC.TypeLits` get me part of the way? :)
06:40 <Cale> If you're willing to work really hard at it
06:40 <Cale> But it's usually not going to be worth the trouble.
06:41 <joneshf-laptop> poo
06:41 <joneshf-laptop> Okay
06:41 <Cale> The problem is that you need to be able to talk about the value of the Int that you have at the type level
06:41 <Cale> So your operation for building up the list needs to use singletons or something whose type isn't simply Int
06:42 <Cale> joneshf-laptop: A more straightforward approach in Haskell would be to do it via abstraction of the data type.
06:44 <Cale> Construct a module with a data type for lists that exclude the particular values you want to exclude (supposing that this is fixed), and carefully control the operations you provide on those lists.
06:45 takle joined
06:46 <joneshf-laptop> Makes sense
06:46 <joneshf-laptop> Thanks!
06:47 ali_bush joined
06:47 ali_bush joined
06:47 jgertm joined
06:50 typedrat joined
06:50 guiben joined
06:50 <halogenandtoast> I had this code originally:
06:50 <halogenandtoast> getPosition :: MaybeT IO Position
06:50 <halogenandtoast> getPosition = MaybeT (parsePosition <$> getInput) <|> getPosition
06:50 <halogenandtoast> but I want to change it to something like
06:51 <halogenandtoast> getMove :: MaybeT IO Move
06:51 <halogenandtoast> getMove = MaybeT (Reveal <$> (parsePosition <$> getInput)) <|> getMove
06:51 <halogenandtoast> where Reveal is a constructor Position -> Move
06:51 <halogenandtoast> but those types don't line up, and I'm lost, I can't see the types at the moment.
06:52 <halogenandtoast> I think I'm confused by the <|> and the MaybeT
06:53 <halogenandtoast> but I want to extend this to handle different types of moves that will be parsed differently so if parsePosition doesn't work, then I'll have a method for parsing a flag position, so I think I want the <|> and MaybeT
06:53 <tsahyt> joneshf-laptop: you can also leverage liquid haskell for this
06:53 jluttine joined
06:54 cheater joined
06:54 <tsahyt> from the top of my head, {-@ type NoThrees = { v : Int | v /= 3 } @-}
06:54 <tsahyt> might be != instead of /=
06:55 <halogenandtoast> I need to get the type: Maybe Position -> IO (Maybe Move)
06:55 <halogenandtoast> from Position -> Move
06:55 hexfive joined
06:55 wroathe joined
06:55 Mortomes|Work joined
06:56 <joneshf-laptop> tsahyt, nice!
06:57 <halogenandtoast> and an IO (Maybe Position)
06:57 detrumi joined
06:57 <tsahyt> joneshf-laptop: the problem with that is that (1) liquid haskell doesn't run with GHC >7.10 yet, (2) it requires an additional checking pass through liquid haskell, since it's not part of the compiler
06:57 chenshen joined
06:58 <tsahyt> but if you can live with that, you can use it to guarantee that your list never contains a 3
06:58 <joneshf-laptop> Unfortunately, I can't live with either :(
06:58 <joneshf-laptop> It's not a big deal though
06:58 <joneshf-laptop> It was more a curiosity.
06:58 <tsahyt> in almost all cases I'd opt for creating a type with a smart constructor
06:59 <tsahyt> e.g. newtype NoThree = NoThree Integer, with a constructor mkNoThree x = if x /= 3 then Just (NoThree x) else Nothing or something like that
06:59 <tsahyt> and then don't expose the NoThree constructor
06:59 sw1nn joined
07:00 <joneshf-laptop> halogenandtoast, Is it safe to assume that `getPosition` as you wrote it type checks?
07:00 <tsahyt> I've been playing around with this sort of thing for a while now and I'm getting more and more convinced that there's a sort of triviality threshold where stronger guarantees just don't pay anymore as the machinery necessary to get them just outpaces all the benefits
07:00 <tsahyt> especially when you're dealing with things that can be verified via equational reasoning in a matter of minutes
07:00 <joneshf-laptop> tsahyt, i love that sentiment
07:01 Mysterious_Light joined
07:01 <tsahyt> It turns out that liquid haskell can verify equational reasoning proofs though. in principle anyhow, in practice I've found a few bugs with that.
07:01 <halogenandtoast> joneshf-laptop: getPosition type checked
07:01 <tsahyt> but it's still improving I think
07:01 rcschm joined
07:01 <halogenandtoast> I feel like I'm "closer" now: getMove = MaybeT (Reveal . parsePosition <$> getInput) <|> getMove
07:01 mattyw joined
07:02 <halogenandtoast> still wrong but closer
07:02 <halogenandtoast> Expected type: Maybe Position -> IO (Maybe Move) Actual type: Position -> Move
07:02 thc202 joined
07:03 beanbagula joined
07:03 zargoertzel joined
07:04 <joneshf-laptop> halogenandtoast, so `(parsePosition <$> getInput) :: IO (Maybe Position)` yeah?
07:04 DataComputist1 joined
07:04 <halogenandtoast> Yes
07:04 <joneshf-laptop> And `Reveal :: Position -> Move`, yeah?
07:04 DataComputist1 joined
07:04 <halogenandtoast> correct
07:04 raichoo joined
07:05 DataComputist1 joined
07:05 <joneshf-laptop> :t fmap . fmap
07:05 <lambdabot> (Functor f, Functor f1) => (a -> b) -> f1 (f a) -> f1 (f b)
07:05 biglambda joined
07:05 takle joined
07:05 wroathe joined
07:06 <halogenandtoast> hmm
07:06 hdeshev joined
07:07 <halogenandtoast> Okay that works, I sort of get it, but it's definitely on the fringes for me.
07:07 <halogenandtoast> getMove = MaybeT ((fmap . fmap) Reveal (parsePosition <$> getInput)) <|> getMove
07:07 <halogenandtoast> ah I could rewrite that I assume
07:07 <joneshf-laptop> Yep!
07:08 <joneshf-laptop> :t (<$>) <$> (<$>)
07:08 <lambdabot> (Functor f, Functor f1) => (a -> b) -> f1 (f a) -> f1 (f b)
07:08 <joneshf-laptop> :P
07:08 <halogenandtoast> getMove = MaybeT (fmap Reveal <$> (parsePosition <$> getInput)) <|> getMove
07:08 ventonegro joined
07:09 <halogenandtoast> joneshf-laptop: I have no idea what you just wrote there. I would have assumed that was three fmaps...
07:09 shafox joined
07:09 <halogenandtoast> of
07:09 <halogenandtoast> <$> for functions is just .
07:09 <halogenandtoast> s/of/oh/
07:09 <joneshf-laptop> Yep!
07:10 ubsan_ joined
07:10 <halogenandtoast> Is there any subjectively cleaner way to write: getMove = MaybeT (fmap Reveal <$> (parsePosition <$> getInput)) <|> getMove
07:10 zariuq joined
07:10 <halogenandtoast> perhaps with less parens
07:11 <joneshf-laptop> I'd say change the first `(<$>)` to `(.)`
07:11 <joneshf-laptop> wait, is that right?
07:11 <halogenandtoast> but the rhs is not a function
07:11 <joneshf-laptop> that's probably not right.
07:11 nick_h joined
07:11 <halogenandtoast> my limited knowledge says it's not right.
07:11 <joneshf-laptop> what typeis `parsePosition`?
07:12 <Zemyla> Isn't a <$> (b <$> x) = (a . b) <$> x?
07:12 <halogenandtoast> parsePosition :: String -> Maybe Position
07:12 <halogenandtoast> Zemyla: yes
07:13 albertid joined
07:13 <halogenandtoast> that would look like
07:13 <halogenandtoast> getMove = MaybeT ((fmap Reveal . parsePosition) <$> getInput) <|> getMove
07:13 <Zemyla> :t \a b x -> ((a <$> b) <$> x) `asTypeOf` (a <$> (b <$> x))
07:13 <lambdabot> Functor f => (a1 -> b) -> (a -> a1) -> f a -> f b
07:14 <Zemyla> So the free theorem basically says that fmap is associative?
07:14 shafox joined
07:14 Lemmata joined
07:14 <halogenandtoast> err
07:14 <halogenandtoast> getMove = MaybeT (fmap Reveal . parsePosition <$> getInput) <|> getMove
07:15 freusque joined
07:15 insitu joined
07:15 wroathe joined
07:16 <halogenandtoast> that's slightly better. Thanks joneshf-laptop and Zemyla
07:16 <Zemyla> halogenandtoast: Couldn't you go getMove = fmap Reveal $ let x = MaybeT (parsePosition <$> getInput) <|> x in x?
07:16 vlatkoB joined
07:16 <joneshf-laptop> halogenandtoast, I feel like I didn't really explain how to arrive at it, but instead just blurted an answer.
07:16 <Zemyla> SinceReveal seems to be a data constructor mapping over the Maybe?
07:17 <halogenandtoast> joneshf-laptop: that's true, I planned on messing with fmap . fmap a bit more.
07:17 <halogenandtoast> Zemyla: not sure that will work when I add another Alternative
07:17 cur8or joined
07:18 <halogenandtoast> actually pretty sure I'm going to have to change a lot once I try to add another Alternative :(
07:18 Mysterious_Light joined
07:18 _sg joined
07:18 <joneshf-laptop> Hmm, well.
07:18 <halogenandtoast> because the next Alternative depends upon the result of getInput
07:19 Luke-Jr-jr joined
07:21 <halogenandtoast> and found myself in an infinite loop again
07:21 <halogenandtoast> blarg
07:21 <halogenandtoast> getMove = do
07:21 <halogenandtoast> input <- liftIO getInput
07:21 <halogenandtoast> MaybeT (return . fmap Reveal . parsePosition $ input) <|> getMove
07:22 <joneshf-laptop> I'm sorry.
07:22 bhiliyam joined
07:22 <joneshf-laptop> I hope someone else cna provide a more in depth explanation that actually helps you understand.
07:22 <halogenandtoast> No worries
07:23 <halogenandtoast> thanks for all you have explained joneshf-laptop
07:23 bennofs joined
07:23 <Zemyla> halogenandtoast: Why not do getMove = liftIO getInput >>= maybe getMove (return . Reveal) ?
07:23 ryxai joined
07:24 Salih joined
07:24 <Zemyla> That's what MaybeT would be doing internally anyways.
07:24 <halogenandtoast> Zemyla: because there are multiple moves that need t be parsed
07:24 <halogenandtoast> *to I just haven't added them yet
07:25 <halogenandtoast> so if one parse fails, I want it to use the Alernative parsing
07:25 <halogenandtoast> *Alternative
07:26 wroathe joined
07:26 CurryWurst joined
07:26 redpoppies joined
07:27 narendraj9 joined
07:27 <halogenandtoast> I'm assuming it's something similar to this
07:27 <halogenandtoast> MaybeT (return . fmap Reveal . parsePosition $ input) <|> MaybeT (return . fmap PlaceFlag . parseFlagPosition $ input) <|> getMove
07:27 CurryWurst joined
07:27 beanbagula joined
07:28 <halogenandtoast> but that is wrong
07:29 xtreak joined
07:30 vaibhavsagar joined
07:30 xtreak joined
07:33 eklavya joined
07:34 slomo joined
07:34 filterfish joined
07:36 biglambda_ joined
07:36 mtesseract joined
07:37 a3Dman joined
07:37 a3Dman joined
07:38 oisdk joined
07:39 biglama joined
07:39 takle joined
07:39 bollu joined
07:40 Swizec joined
07:41 halogenandtoast joined
07:43 juhp joined
07:43 byorgey joined
07:43 byorgey joined
07:44 <osa1> does lens have an operator for `fmap . view` ?
07:44 azahi joined
07:45 Xanather joined
07:45 oisdk joined
07:45 merijn joined
07:45 uogkco joined
07:46 wroathe joined
07:47 <quchen> :t fmap . view
07:47 <lambdabot> Functor f => Getting b s b -> f s -> f b
07:47 <quchen> :t views
07:47 <lambdabot> MonadReader s m => LensLike' (Const r) s a -> (a -> r) -> m r
07:48 <ph88_> good morning all
07:48 <quchen> osa1: Hmm, maybe that’s it. Maaaybe.
07:48 <quchen> :t [fmap . view, views]
07:48 <lambdabot> [Getting s s s -> (s -> s) -> s -> s]
07:48 <quchen> Wooo! :-)
07:48 <osa1> nice
07:48 <quchen> But that can’t change the result type. Hmm.
07:48 <quchen> Anyway, look in the docs next to »view«.
07:48 <ph88_> ertes, what timezone are you on ?
07:49 <quchen> The examples are much better than the type signatures.
07:49 <quchen> osa1: ^
07:49 <quchen> ph88_: He’s from central Europe
07:50 <quchen> …timezone wise at least.
07:50 <quchen> So this includes South Africa. Anyway, that. :-)
07:50 jophish joined
07:51 zcourts joined
07:51 <ph88_> i have a large file with data points, and i need a sliding window (i will use a ring-buffer), within the window i need to calculate the difference between min and max like this http://users.rcn.com/wpacino/jitwtutr/jw-f4.gif after i done this i need to increase the size of the window and go over the points again. But i figured since i know the next window will be larger than the previous one i only need to look at the previous calculated min/max. What
07:51 <ph88_> kind of data structure is good to store a list where i can remove elements from in the middle?
07:53 <halogenandtoast> joneshf-laptop: btw, I didn't have an infinite loop, I wrote my lens incorrectly :(
07:53 <halogenandtoast> red herring
07:54 <merijn> ph88_: Honestly, I'd probably just use an array and some offsets?
07:54 <merijn> ph88_: What's the file format?
07:54 mtesseract joined
07:54 adrian joined
07:54 <ph88_> merijn, textual
07:55 <merijn> ugh :p
07:55 <ph88_> merijn, what format would you recommend ?
07:56 laz joined
07:56 jasondockers_ joined
07:56 danthemyth joined
07:56 richi235 joined
07:56 wroathe joined
07:56 <pacak> ph88_: For a bigger window you will need to consider already known min/max plus some extra elements right next to that window
07:56 <merijn> ph88_: For this specific problem? A binary format of ints/double so you could just mmap the entire thing and it becomes trivial :)
07:56 <pacak> so you will have to keep them in memory anyway
07:56 Taneb joined
07:57 <ph88_> pacak, why do i have to consider some extra elements right next to that window ?
07:57 <ph88_> merijn, you mean map it directly into memory ?
07:58 <merijn> ph88_: Yes, because <3 mmap
07:58 jameseb joined
07:58 <ph88_> nice :P
07:58 <pacak> 11211 -- original elements, use window of size 2: 11, 12, 21, 11 and so on. You'll get minmax (1,1), (1,2), (1,2), (1,1)
07:59 <pacak> now make window wider - 3 so elements are 111, 112, 121 and 211. for first two elements you already know min/max, but to get min/max for window of size 3 you need to look at 2 as well.
08:01 <pacak> merijn: Imagine it's xml. mmap won't help much
08:01 <pacak> ph88_: How big is the file?
08:02 takle joined
08:02 <ph88_> i have a file right not that's 158 MB and takes more than half an hour to process with an old (non-haskell) program
08:02 <ph88_> right now *
08:02 <ph88_> but we can generate new files if we do new measurements
08:02 <jchia> Is it a known issue that Posix.changeWorkingDirectory fails if the current working directory doesn't exist?
08:03 <pacak> ph88_: Just parse it and put into vector.
08:03 raichoo joined
08:03 takle joined
08:03 fakenerd joined
08:03 filterfish joined
08:03 <jchia> System.Posix.Directory.changeWorkingDirectory
08:03 <ph88_> pacak, i didn't understand what you mean before with your example https://bpaste.net/show/1292a57a5652 i wanted to save the min/max values and their offset
08:04 <ph88_> not sure why this little parser doesn't work https://bpaste.net/show/72edcfeb9558
08:04 <ph88_> oh maybe because i forgot end of line
08:04 <ph88_> hhmm no i put \n and still doesn't work
08:04 <pacak> ph88_: I showed min maxes as tuples, you can add their offsets as well
08:05 <ph88_> pacak, if i know the offsets i don't need to remember the original data i think
08:05 <merijn> pacak: Well, that's why I said I dislike textual formats :p
08:05 <pacak> ph88_: Still. When you make window wider - you need to look at new data and compare it with original one
08:06 Yuras joined
08:06 <ph88_> pacak, i just don't see it .. why i need to look at new data
08:06 wroathe joined
08:07 <pacak> You have a window: 12. You know min, max and indices. Now you want to look at the same data with window of size 3
08:07 <pacak> THat'll be [1]12 or 12[1] - with new data added on the left or on the right.
08:08 eacameron joined
08:10 Beetny joined
08:11 xtreak joined
08:13 <halogenandtoast> Minesweeper is susprisingly difficult to implement in Haskell
08:13 eacameron joined
08:13 <pacak> ph88_: You have skipSpace at the end which can take more data
08:13 <Cale> I wouldn't expect it to be very different from implementing it in various other languages, at worst.
08:13 <halogenandtoast> took me 190 lines of code
08:13 <pacak> I'm not sure why you are getting Fail - it supposed to be Partial
08:13 beanbagula joined
08:14 <halogenandtoast> well less, because type signatures and newlines and all that.
08:15 <pacak> ph88_: Hmm... Actually skipSpace consumes both - spaces and end of line
08:15 lep-delete joined
08:15 teggi joined
08:15 snowalpaca joined
08:16 <pacak> ph88_: use "many1 (satisfy (== ' '))"
08:16 willprice94 joined
08:16 willprice joined
08:16 kian joined
08:16 kian joined
08:17 <pacak> halogenandtoast: I imagine it would be easier with Comonad...
08:17 wroathe joined
08:18 <ph88_> pacak, here for larger window i reuse the min/max found from previous window without scanning original data https://bpaste.net/show/1233a064775f
08:18 a3Dman joined
08:18 Sindriava joined
08:18 cheater joined
08:18 jchia joined
08:18 eacameron joined
08:19 <merijn> halogenandtoast: What makes it so different compared to other languages?
08:19 phyrex1an joined
08:20 takle joined
08:20 <ph88_> merijn, when you said "just use an array" you mean Data.Array ? and why you prefer this over Vector ?
08:21 mthek joined
08:21 <merijn> ph88_: No, I meant array as in C-like thing, so I guess that'd probably be a Storable vector or whatever they're called
08:21 doomlord joined
08:21 <EvanR> a Ptr a
08:22 <ph88_> merijn, if i remove elements from that the whole array needs to be reallocated ?
08:22 Mysterious_Light joined
08:22 <merijn> EvanR: Sure, but you probably want a vector wrapper to deal with some of the boiler plate
08:22 <merijn> ph88_: Why would you remove elements if you're computing min/max over a window?
08:22 <ph88_> halogenandtoast, can i see? i'm a big fan of minesweeper
08:23 <ph88_> merijn, because i would like to remove the min/max themselves as the window increases
08:23 _sras_ joined
08:24 marr joined
08:26 <ph88_> maybe a linked list is just the best structure here? removing an elements should just be changing a pointer, no ?
08:27 wroathe joined
08:27 eacameron joined
08:29 <_sras_> Is there any was I can make a haskell evn and ghc-mode and such tools running in a virtual machine communicate with the editor running in my host machine?
08:29 <ph88_> pacak, i thought it over, i think you're right i need to look at the original data again :P
08:29 <mtesseract> Hmm, haddock renders type classes strange in the presence of -XPolyKinds.
08:30 <jle`> it's definitely weird, and it's been going on for a while now
08:30 rcschm joined
08:30 <jle`> it's not really clear what it means either for most normal haskell users
08:31 <mtesseract> jle`: the haddock output you mean?
08:31 <jle`> yeah
08:31 ebzzry joined
08:32 presiden joined
08:32 <ph88_> pacak, since i need to re-inspect the original data .. wouldn't it be best if i load it all into memory instead of lazy ?
08:32 eacameron joined
08:33 <mtesseract> jle`: Interestingly there are at least two open issues about this, one from 2014 and one from 2016. I guess the haddock team could use some help, given that they have 200 open issues.
08:33 teggi_ joined
08:33 freusque joined
08:33 <Cale> mtesseract: Are you referring to the extra kind arguments?
08:33 a3Dman joined
08:34 llamma1 joined
08:34 <Cale> It's somewhat understandable why it's rendering them, those are present at a lower level, but usually not visible to the Haskell programmer.
08:34 <mtesseract> Cale: Yes
08:34 <halogenandtoast> ph88_: sure making a gist
08:34 <Cale> But yeah, it's a bug which would be good to fix :)
08:35 <ph88_> halogenandtoast, i want to play it xD
08:35 dhil joined
08:36 <halogenandtoast> ph88_: https://gist.github.com/halogenandtoast/9abb7e0ccd411ac558f0874783f7006d
08:36 <merijn> halogenandtoast: I would probably use ADTs rather than record for Square
08:36 <halogenandtoast> merijn: I've done a lot of OO languages and having state you can easily change makes some things a lot easier (or more concise at least)
08:37 <ph88_> halogenandtoast, does it work with the mouse ?
08:37 <merijn> halogenandtoast: This seems like a bunch of boolean blindness :)
08:37 <halogenandtoast> ph88_: nope
08:37 <ph88_> :/
08:37 <halogenandtoast> merijn: curse you and your boolean blindness
08:37 <ph88_> i only play minesweeper with mouse
08:37 <halogenandtoast> ph88_: but the game logic is abstracted from the UI so you could "trivially" write a gui interface for it
08:37 <merijn> halogenandtoast: Why not combine Square and SquareType into a single data type?
08:37 <tdammers> well, state that is easy to change is obviously convenient
08:38 <pacak> ph88_: Load everything, parse incrementally into a strict vector.
08:38 <tdammers> the problem is that without further protection, you'll quickly lose track of who changes state when and in what ways
08:38 <halogenandtoast> merijn: This was also a first pass, I've done no refactoring to it yet, a lot of it was learning or messing around with new things
08:39 <merijn> halogenandtoast: Sure, these are just suggestions for improvement, not accusations :)
08:39 <halogenandtoast> pacak: What did you mean about Comonads?
08:39 Mysterious_Light joined
08:39 <ph88_> pacak, do you know how i can change the parser so that it puts stuff in a strict vector ?
08:39 xall joined
08:40 <halogenandtoast> brb my computer keeps randomly locking up for a few seconds
08:40 jaspervdj joined
08:40 <pacak> halogenandtoast: cellular automatas are easy to implement with comonads. minesweeper looks a bit comonadish to me as well.
08:40 mszczygiel joined
08:40 <pacak> ph88_: Yes.
08:41 <merijn> halogenandtoast: btw, do you know brick? It's a library for terminal UIs, you could use that to allow people to select the position to reveal/flag using the cursor, rather than typing in coordinates :)
08:41 freusque joined
08:41 halogenandtoast joined
08:42 <halogenandtoast> back reading logs
08:43 <halogenandtoast> merijn: I've seen brick
08:43 <halogenandtoast> I didn't want to mess with it too much while learning a few other things.
08:43 <ph88_> pacak, how can i do it ?
08:44 <merijn> halogenandtoast: Just thought it might be neat if you decide to expand this into a 2.0 version :)
08:44 <halogenandtoast> merijn: fair enough. Can I probe your mind about Boolean blindness and ADTs?
08:44 <merijn> halogenandtoast: Sure
08:44 augur joined
08:44 samrat joined
08:45 <pacak> ph88_: Read incrementally chunk by chunk, create a bunch of smaller vectors then concat them all together.
08:45 <halogenandtoast> So what did you mean by ADT for Square? Just a normal data constructor?
08:46 <ph88_> pacak, since i'm using lazy it should already do chunk by chunk, no ?
08:46 <merijn> halogenandtoast: Rather than having a record for Square and having SquareType I'd try to consolidate them into a single type, especially since a bunch of the bool's in your Square are mutually exclusive
08:47 ccomb joined
08:47 Iceland_jack joined
08:47 <merijn> halogenandtoast: i.e. a square can never be both flagged and revealed
08:47 <pacak> Kind of. But lazy io is problematic in general.
08:47 <ph88_> pacak, what's a good size of the chunk ?
08:48 <halogenandtoast> merijn: sure, but having the type together with square doesn't make it not a record. I'm not sure I understand what an ADT is I'm not sure what the eventual intent is.
08:48 xtreak joined
08:48 <pacak> you can impelement it to be chunk size agnostic and just try several different versions.
08:48 <pacak> You can look at iteratess/pipes/conduit/whatever
08:48 biglambda_ joined
08:49 <ph88_> pacak, hows conduit gonna help ?
08:50 <merijn> halogenandtoast: All haskell type are ADT (Algebraic Data Types), but in common usage it refers to using Sum types over records, such as having "data Square = Unrevealed ? | Revealed Int" with Int allowed to be zero, or, alternatively using "Revealed (Maybe Int)" Which leaves the question of how to deal with Unrevealed and the fact that they can have a flag and mine.
08:50 freusque joined
08:51 <pacak> ph88_: I'm using iteratees for similar task, but my files are bigger. The idea is to have Enumerator that produces stream of bytestrings, then several enumeratees that parse data in steps then iteratee that collects result into a single vector.
08:52 <halogenandtoast> merijn: sure, I wasn't sure how to encapsulate the idea that a square could be in many different related states. Flagged Mine, Flagged Not Mine, Unrevealed Mine, Unrevealed Not Mine, Revealed Mine, Revealed Not Mine
08:52 <ph88_> pacak, aaaah ok, that sounds very very optimized :P
08:52 <merijn> halogenandtoast: Yeah, I agree that that specific case is a bit awkward
08:53 <merijn> halogenandtoast: But I'd at the very least split the "revealed/unrevealed" case apart, since flag/mine can't appear for revealed
08:53 zero_byte joined
08:53 <phz_> hey, what is the recommendation on documenting instances?
08:54 <phz_> doc on the instance? on the method?
08:54 <merijn> phz_: Both?
08:54 <phz_> well, the typeclass has only one method
08:54 <halogenandtoast> merijn: type Square = (State, IsMine)
08:54 <phz_> that seems like redundancy
08:54 jgertm joined
08:54 <merijn> phz_: I'd be suspicious of a class with only one method?
08:55 <dmj`> phz_: pretty sure for 100% haddock coverage you have to document the top level of an instance. Unsure about instance methods though… maybe just document it at the class
08:55 govg joined
08:55 <phz_> merijn: FromJSON
08:55 twanvl joined
08:55 <phz_> even though it has two, but the other one has a default implementation I don’t give a heck yet
08:55 <halogenandtoast> phz_: He just said suspicious, not that it should never happen.
08:55 <phz_> and you have a lot of classes with one methods
08:56 <phz_> I think it’s saner that way
08:56 <merijn> phz_: I suppose in that case documenting the instance seems redundant in the first place
08:56 <phz_> yeah yeah
08:56 <phz_> merijn: why?
08:56 <phz_> I need documentation because the instance doesn’t tell enough
08:56 bjz joined
08:56 <halogenandtoast> merijn: Also I wanted to encode the neighboring mine count somehow so maybe type Square = Square Status IsMine MineCount
08:56 <phz_> because the representation of the type is ambiguous
08:57 <merijn> phz_: I haven't actually used FromJSON, so I can't be much more helpful
08:57 <halogenandtoast> *not type
08:57 wroathe joined
08:58 <merijn> halogenandtoast: And then have "data Status = Flagged | Revealed | Blank"?
08:58 <phz_> thank you anyway :)
08:58 <merijn> halogenandtoast: That sounds reasonable too
08:58 <merijn> halogenandtoast: I would definitely prefer that to the current type
08:58 <halogenandtoast> it's encodes the related parts in a single type
08:59 dynrzk joined
08:59 <halogenandtoast> type Square = Mine Status | Empty Status MineCount
08:59 <halogenandtoast> or something like that ?
08:59 <halogenandtoast> *data
08:59 <eatman> Hi there.
08:59 <srhb> eatman: Hello.
08:59 <merijn> halogenandtoast: I think I like the Square Status IsMine MineCount one best
08:59 <eatman> I'd like to load Data.Magma in GHCI.
09:00 <halogenandtoast> merijn: what is the advantage over the alternative I just proposed?
09:00 <eatman> How can I install it (Using stack).
09:00 <srhb> eatman: stack install magma
09:00 <srhb> I think.
09:00 eacameron joined
09:00 <merijn> halogenandtoast: That 2nd ons is also ok, avoids the boolean :)
09:00 <eatman> Is there an option that allow to instlal dependencies?
09:01 <srhb> eatman: It does that automatically, but it may actually not work with the latest snapshot
09:01 <eatman> (First stack install use)
09:01 <srhb> eatman: So you might have to use an earlier one
09:01 mmn80 joined
09:01 <srhb> eatman: I'm guessing you're seeing: profunctors >=3.2 && <5.2
09:01 <eatman> Yep.
09:01 <srhb> eatman: Right, you will need an earlier snapshot for that.
09:01 <eatman> I'm ok for a global update as well.
09:01 <halogenandtoast> I feel like this is the exactly problem lts is supposed to solve :(
09:02 <srhb> eatman: Update won't help you. It's incompatible with ghc > 8.0 I think.
09:02 <eatman> Ha, ok.
09:02 <srhb> eatman: Either you'd have to patch the package or use an earlier version entirely.
09:02 <halogenandtoast> merijn: While it's okay, does one have an advantage over the other?
09:02 Guest33249 joined
09:02 Guest33249 left
09:02 <merijn> halogenandtoast: Maybe, but not one that I can immediately think off :)
09:02 <pacak> ph88_: Or you can simply write a loop, read a bit, parse, pack into vector, read more, parse leftovers from previous run with current data and so on. The idea is not to parse all the numbers at once because it will create a ton of object that needs to be GCed - doubles and []
09:02 cschneid_ joined
09:02 ub joined
09:02 <eatman> Well, I don't care, I just wanted to know if a Magma is enough to make a foldable instance.
09:02 <merijn> halogenandtoast: Well, I guess the first one is easier to make a lens for
09:03 <merijn> halogenandtoast: The second would require prisms?
09:03 <eatman> srhb: I don't think I'm good enogh at Haskell in order to patch any package right now.
09:04 <srhb> eatman: Can you use groupoids instead?
09:04 <srhb> Isn't that the same thing?
09:04 <srhb> Er, semigroupoids
09:04 <eatman> Don't know it but I'll have a look.
09:04 <eatman> Ah , semigroup ok.
09:04 <srhb> https://hackage.haskell.org/package/semigroupoids
09:04 <halogenandtoast> merijn: interesting, I'll mess around with changing the types now that I have a working instance.
09:04 <eatman> Well, if you've a semigroup, you've a Magma.
09:05 <srhb> Really? I thought magma needed associativity
09:05 <eatman> Nop, I guess not.
09:05 <phz_> a Magma doesn’t have associativity
09:05 <phz_> it’s a semigroup without it, IIRC
09:05 <srhb> Oh, it's the other way around.
09:05 <merijn> Isn't the lack of associativity what distinguishes a magma from a semigroup?
09:05 <phz_> yep
09:05 <srhb> Right, thanks :)
09:05 <eatman> Yep.
09:06 <* srhb> cries
09:06 <srhb> Never speak too soon in #haskell :-)
09:06 <phz_> srhb: though, you’re the first person I hear talking about magma here
09:06 <phz_> I didn’t know such an abstraction was interesting
09:06 <phz_> :D
09:06 <srhb> phz_: Then you missed eatman doing so, since that's what I'm responding to ;-)
09:07 jespada joined
09:07 <eatman> So, I guess that if I've a Magma (with the <> internal law), I can make it foldable cna't I?
09:07 teggi joined
09:07 cschneid_ joined
09:07 <eatman> phz_: Yeah, Magma are not so ommon.
09:07 <phz_> eatman: well, that’s contrary
09:07 <phz_> they’re so common we don’t need them
09:07 wroathe joined
09:08 <eatman> True.
09:08 <phz_> you can’t reason correctly with something that abstract, IMHO ^^
09:08 <eatman> Yes, not enough constraints.
09:08 <phz_> a list over concatenation is a magma, numbers over product or addition are magmas, etc.
09:09 <phz_> I tend to stop at Semigroup
09:09 <phz_> for NonEmpty
09:09 zcourts_ joined
09:09 <phz_> because NonEmpty is the free semigroup for anything
09:09 <eatman> phz_: Sum and Prod are Magams becouse they're Monoids.
09:10 <eatman> I mean, the law is assossiative.
09:10 <phz_> eatman: yes
09:10 <phz_> but they’re magmas first ;)
09:10 <eatman> Yep.
09:10 <phz_> I mean
09:10 bhiliyam joined
09:10 <phz_> I don’t know a thing that is a magma only
09:10 <eatman> So, in the end : How can I get the Magams?
09:10 <phz_> and I can’t see a scenario in which I’d like to work with magma only
09:10 <phz_> I couldn’t do much
09:10 <phz_> like
09:11 <phz_> doMagmaWork :: (Magma a, Other b) => a -> a -> b
09:11 <phz_> you can’t do much here
09:11 <phz_> what do you mean get?
09:11 <eatman> stack install magma.
09:11 <phz_> I think they’re in semigroupoids
09:11 <eatman> Ho... I'll look at that.
09:12 <phz_> or
09:12 <phz_> @hoogle magma
09:12 <lambdabot> Control.Lens.Iso magma :: LensLike (Mafic a b) s t a b -> Iso s u (Magma Int t b a) (Magma j u c c)
09:12 <lambdabot> package magma
09:12 <lambdabot> module Control.Lens.Internal.Magma
09:12 <phz_> there’s a magma package
09:12 <phz_> I’m a bit disappointed though
09:12 <phz_> it’s not from edwardk
09:12 <phz_> what is going on?!
09:12 <phz_> :D
09:12 <eatman> So, stack install what ?
09:12 <phz_> stack install magma
09:13 <eatman> Nop profunctors-5.2 must match >=3.2 && <5.2 (latest applicable is 5.1.2)
09:13 <phz_> if they’re not part of stackage
09:13 jespada joined
09:13 yellowj joined
09:13 <phz_> you’ll have to pinpoint them in your stack.yaml
09:13 <eatman> I've none here.
09:13 <phz_> haha
09:14 <phz_> there’s a BinaryTree type constructor in that package
09:14 fre joined
09:14 <phz_> why do you need magmas in the first place?
09:14 <phz_> I’m curious now
09:14 <eatman> I'm just doing some tests in /tmp.
09:14 <phz_> alright
09:14 <eatman> phz_: I wanted to try to fold using <>
09:15 <eatman> I'm reading the "Haskell from first principle" book and wanted to try some things out.
09:15 <ph88_> pacak, should i use a mutable or immutable vector ?
09:16 <phz_> eatman: magmas are not very spread in the ecosystem, I’d say
09:16 <pacak> ph88_: I'd go for immutable one. Mutable will require to perform any operations incluing reading in IO or ST monad.
09:16 <phz_> you should stick to Semigroup
09:16 <phz_> if you have a very good reason not to want associativity
09:16 <phz_> you should use a Magma
09:16 <phz_> but that sounds crazy :D
09:17 <phz_> semigroups are very common in Haskell
09:17 <phz_> I think they’re in base now?
09:17 <phz_> https://hackage.haskell.org/package/base-4.9.1.0/docs/Data-Semigroup.html
09:17 <phz_> they are!
09:17 <Iceland_jack> They are, along with Data.List.NonEmpty
09:17 <phz_> see
09:17 <phz_> nothing to stack install ;)
09:17 mszczygiel joined
09:17 acidjnk22 joined
09:17 <Iceland_jack> I'll start a gang for people who hate associativity
09:17 <Iceland_jack> I'll call it.. http://bulbapedia.bulbagarden.net/wiki/Team_Magma
09:18 <phz_> Iceland_jack: call it the MR
09:18 <phz_> MagmaRacists
09:18 wroathe joined
09:18 <Iceland_jack> I may need a better PR dep :)
09:18 <halogenandtoast> I'm really wondering how the name Magma came about
09:19 <phz_> halogenandtoast: it’s exotic
09:19 <eatman> Ok, I know that I don't NEED them, it was just "for fun".
09:19 eacameron joined
09:19 <phz_> eatman: well, use the magma package then
09:19 <phz_> though, last update is form 2015
09:19 <Iceland_jack> halogenandtoast: A lot of abstract algebra names are, for lack of better word, BS :)
09:19 <phz_> not sure you can build it against a recent LTS stackage
09:19 <Iceland_jack> Relevant: http://english.stackexchange.com/questions/63210/etymology-of-magma-in-abstract-algebra
09:20 <phz_> Iceland_jack: don’t say that
09:20 <ph88_> pacak, sorry for stupid questions, but how can i write a loop on the line parser ?
09:20 <eatman> Yes, So the question was about How to install it using stack.
09:20 <phz_> I love the algebraic names
09:20 <Iceland_jack> fine: arbitrary
09:20 <phz_> right, thank you ♥
09:20 <halogenandtoast> Thanks for the link
09:20 <phz_> eatman: stack install magma
09:20 <srhb> ph88_: The line parser?
09:20 <phz_> in your project
09:20 <halogenandtoast> Is there any "good" way to clean this up?
09:20 <halogenandtoast> parsePosition s = case readMaybe <$> words s of
09:20 <halogenandtoast> [x, y] -> (,) <$> (subtract 1 <$> x) <*> (subtract 1 <$> y)
09:20 <phz_> if it fails
09:20 <halogenandtoast> _ -> Nothing
09:20 <phz_> wait.
09:20 <pacak> ph88_: write a parser for one line, read a chunk, feed it to parse (many line), parse will return parsed data and leftovers.
09:21 <phz_> eatman: magma doesn’t seem to live in stackage, so you have to add it to the extra packages field in your stack.yaml
09:21 narendraj9 joined
09:21 locallycompact joined
09:22 <eatman> Ok, so I definitly need a stack.yaml file.
09:22 <phz_> sure you do
09:22 <phz_> stack init
09:22 <phz_> if you have a .cabal file
09:22 <srhb> I think they are working with the "global" environment
09:22 <ph88_> pacak, that parser will return [[Double]] i think
09:22 <srhb> So I assume it would be ~/.stack/something
09:22 <ph88_> pacak, maybe it will be easier to have state in the parser ?
09:22 <ph88_> and also faster
09:23 <phz_> extra-deps: ["magma-0.4.0.0"]
09:23 <phz_> stack install magma
09:23 <phz_> you should have it now.
09:23 <pacak> ph88_: If chunk is small enough GC for [[Double]] will be cheap. Once you get this [[Double]] you pack that into Vector Double or [Vector Double] depending on your data shape.
09:23 <phz_> when a package doesn’t belong to any LTS / nightly / whatever snapshot of stackage, you have to declare it as an extra-dep
09:24 <phz_> so that stack look it up in hackage for you
09:24 <ph88_> pacak, maybe i can use this ? https://hackage.haskell.org/package/attoparsec-0.13.1.0/docs/Data-Attoparsec-ByteString.html#v:scan
09:24 <ph88_> pacak, or this http://stackoverflow.com/a/30508695
09:25 <eatman> Thanks ph88_ I'll give it a try.
09:25 <ph88_> ???
09:25 <pacak> ph88_: Scan will return you a ByteString - which is probably not something you want.
09:25 <ph88_> oh ok
09:25 <ph88_> what about StateT ?
09:26 <ph88_> i could push the Doubles directly onto the vector and not put them in linked list first
09:26 <pacak> StateT foo Parser will give you Parser inside State, not State inside Parser.
09:27 <ph88_> and that's not what i want ?
09:27 <pacak> ph88_: You can't push them directly to the vector since you don't know upfront amount to allocate
09:28 wroathe joined
09:28 <pacak> ph88_: StateT Foo Parser is a state that can also parse, not parser that can have state.
09:28 filterfish joined
09:29 <phz_> merijn: https://github.com/bos/aeson/pull/541 (why I wanted instance documentation) cc phadej
09:29 Wizek_ joined
09:31 <maerwald> slightly offtopic, but potentially not. I'm reading about propagating refinement types through higher order functions via pre/post-conditions: https://www.microsoft.com/en-us/research/publication/pre-post-conditions-security-typechecking/ ...then I wondered how much of protocol verification can one actually do on type level. I mean... we're kind of assuming here that all the important protocol logic is somehow expressed in the type system (directly o
09:32 hurkan joined
09:32 <ph88_> pacak, i was using readFile from https://hackage.haskell.org/package/bytestring-0.10.8.1/docs/Data-ByteString-Lazy.html but to read in chunks i think i will need to use another (maybe strict) function
09:32 <halogenandtoast> This seems like a very beginner question so I feel derpy for asking, but if I have [Maybe Int] how can I apply (Int -> Int) to it?
09:32 <srhb> halogenandtoast: fmap more!
09:33 <halogenandtoast> (a -> b) -> [f a] -> [f b]
09:33 <halogenandtoast> fmap . fmap ?
09:33 <ph88_> anyone know a function to read a file in chunks ?
09:33 <srhb> halogenandtoast: Yep.
09:33 <eatman> phz_: The stack.yaml file is not ok for me.
09:34 <halogenandtoast> srhb: but my eyes!
09:34 <eatman> Anyway, not a real problem.
09:34 lopex joined
09:34 <pacak> ph88_: enumFile from iteratees. https://hackage.haskell.org/package/iteratee-0.8.4.6/docs/Data-Iteratee-IO-Fd.html
09:34 bjz joined
09:34 <pacak> ph88_: There should be something in conduit/pipes/whatever
09:34 marfoldi joined
09:35 <pacak> Or you can simply open a handle and use hGetSome
09:35 xtreak joined
09:36 narendraj9 joined
09:36 <srhb> halogenandtoast: Awh, it's not that bad... :-)
09:36 <ph88_> pacak, i still have a last resort if hGetSome fails https://youtu.be/-nr59jF7JHU
09:37 <srhb> halogenandtoast: When you get to fmap . fmap .fmap you really start to wish for "exponentiation" of function composition.
09:37 <srhb> Then you are allowed to be sad. ;-)
09:37 <phz_> eatman: hm?
09:37 <phz_> not okay for you?
09:37 <phz_> then edit it! :)
09:38 wroathe joined
09:39 <halogenandtoast> srhb: I'm assuming you just write a helper function fmap3 = fmap . fmap . famp
09:39 <halogenandtoast> s/famp/fmap/
09:39 chichou joined
09:39 mattyw joined
09:39 <halogenandtoast> and then promptly hate yourself for it.
09:39 dynrzk joined
09:39 stphrolland joined
09:39 <pacak> halogenandtoast: How would you call this: fmap fmap $ fmap fmap fmap?
09:39 SimpleL joined
09:40 gottcha joined
09:40 <halogenandtoast> pacak: f2fmap3
09:40 <pacak> Or fmap (<*>) $ fmap (<*>)?
09:40 filterfish joined
09:40 <pacak> That's something one of my collegues srsly considers to add.
09:40 <halogenandtoast> actually I'm changing my roll, fffmap = fmap . fmap . fmap
09:41 nick123 joined
09:41 <tdammers> something like an indexed monoid would be great
09:41 teggi_ joined
09:41 revprez_atlanta joined
09:41 <halogenandtoast> fStarMoMoneyfStar = fmap (<*>) $ fmap (<*>)
09:41 <tdammers> then you could mconcat (replicate 3 fmap)
09:41 <pacak> ph88_: It won't fail, it will simply look ugly.
09:42 <opqdonut> tdammers: :D
09:42 <halogenandtoast> next derpy question [Maybe a] -> Maybe [a] ?
09:42 <opqdonut> halogenandtoast: sequence
09:42 <opqdonut> :t sequence
09:42 <lambdabot> (Monad m, Traversable t) => t (m a) -> m (t a)
09:42 <halogenandtoast> aww snap
09:42 sphinxo joined
09:42 <opqdonut> m = Maybe, t = []
09:43 <pacak> :t sequenceAa
09:43 <pacak> :t sequenceA
09:43 <lambdabot> error:
09:43 <lambdabot> • Variable not in scope: sequenceAa
09:43 <lambdabot> • Perhaps you meant one of these:
09:43 <lambdabot> (Applicative f, Traversable t) => t (f a) -> f (t a)
09:43 <halogenandtoast> thanks opqdonut haven't used it yet
09:43 <halogenandtoast> this is a glorious day
09:43 <ph88_> pacak, do i need this too ? https://hackage.haskell.org/package/conduit-extra-1.1.15/docs/Data-Conduit-Attoparsec.html
09:44 <maerwald> I don't even understwand why it should be Maybe [a] and not simply [a]
09:44 <pacak> ph88_: I'm not sure about conduits.
09:45 <tdammers> maerwald: what should, sequence?
09:45 <tdammers> maerwald: [Maybe a] -> [a] also exists, it's called catMaybes
09:45 <ph88_> pacak, if it will work, or what functions to use ?
09:45 <maerwald> I know
09:45 <maerwald> I don't see a use case for [Maybe a] -> Maybe [a] is what I am saiyng
09:45 <opqdonut> :t catMaybes
09:45 <pacak> ph88_: It will work, I just don't know how to use it myself.
09:45 <lambdabot> [Maybe a] -> [a]
09:46 <opqdonut> catMaybes is the more specific function
09:46 <maerwald> for other monads its a different thing
09:46 zcourts joined
09:46 <pacak> @src catMaybes
09:46 <lambdabot> catMaybes ls = [x | Just x <- ls]
09:46 <ph88_> ok
09:46 <halogenandtoast> maerwald: trying to do something like this
09:46 <halogenandtoast> parsePosition s = toTuple <$> sequence (fmap (subtract 1) . readMaybe <$> words s)
09:46 <halogenandtoast> toTuple [x, y] = Just (x, y)
09:46 <halogenandtoast> toTuple _ = Nothing
09:47 <halogenandtoast> to convert a string "1 2" into Just (1, 2)
09:47 <halogenandtoast> err
09:47 <halogenandtoast> Just (0, 1)
09:48 <halogenandtoast> but I'm just derping my way through types at the moment.
09:48 wroathe joined
09:48 <ph88_> maerwald, what are you asking about the paper
09:49 <maerwald> ph88_: they're assuming the protocol logic maps to the types. How do you know it does and does so consistently that you don't need design/spec-level verification?
09:52 <maerwald> (and... imagine process communication, then it goes even more out of the window)
09:52 <ph88_> maerwald, you still need to verify that, but after you verified the type level constructs you can reuse the types if you want to do another implementation on the same protocol
09:53 narendraj9 joined
09:53 <maerwald> so "Operating at the level of source code ensures that both design and implementation flaws will be caught" is basically a bit over the top then I guess
09:53 <tdammers> maerwald: first, it would be more effort to disallow calling sequence on Maybe while keeping it around for other monads
09:54 <maerwald> tdammers: haha
09:54 <tdammers> maerwald: second, if you actually use Maybe monadically, sequence makes enough sense as it is
09:54 <maerwald> you could do it with refinement types xD
09:54 <halogenandtoast> thanks all, time for dinner and then boardgames.
09:55 <maerwald> reusing "type frames" for different implementations is an interesting idea though
09:55 <ph88_> maerwald, check this out http://wiki.clean.cs.ru.nl/images/e/e7/2017-FP-Dag-TDD-Sessions.pdf
09:55 <ph88_> Type-Driven Verification of Communicating Systems
09:56 <ph88_> oh ye i remember they are called Session Types
09:56 <maerwald> does that make something like PROMELA unnecessary?
09:56 <tdammers> maerwald: generally speaking though, restricting the use of lawful functions just because you can't think of a way to make them useful is a bit idiotic IMO
09:56 <maerwald> tdammers: :*
09:56 <tdammers> :t pure x >> a
09:56 <lambdabot> error:
09:56 <lambdabot> • Couldn't match expected type ‘m b’ with actual type ‘Expr’
09:56 <lambdabot> • In the second argument of ‘(>>)’, namely ‘a’
09:57 <tdammers> wat
09:57 <tdammers> anyway, pure x >> a is perfectly lawful, nothing wrong with it, but it's not useful at all
09:57 <tdammers> should we prohibit it? I think not.
09:57 <ph88_> maerwald, i'm pretty sure that when they talk about preventing design and implementation flaws they talk about what you want to do with the protocol AFTER it has been layed out in the type system
09:57 zariuq joined
09:58 <maerwald> ph88_: the thing is, I can't think of a way to examine inter-process comunication state space within just the type system of the client/server implementation
09:58 <ph88_> what you mean state space ?
09:59 <ph88_> the possible amount of states ?
09:59 <maerwald> yeah, arising from the protocol, or even the implementation
10:00 <maerwald> depending on when what message got somewhere
10:00 <maerwald> which is what you can model in promela for example, but that's explicit
10:00 rcat joined
10:00 <ph88_> maerwald, when you have a communication protocol, not just what matters is the state at one point, but the sequences of different states
10:00 <maerwald> sure
10:01 <ph88_> maerwald, i think for a single state you can read the types, but i'm not sure about that
10:01 <ph88_> if you talk about what are all the possible sequences of state my program can find itself in .. it's a hard problem i think .. i remember the busy beaver
10:02 <maerwald> you'd basically need refinement types for the state of the client you don't know about :P
10:02 <maerwald> which is a funny thought, actually
10:03 <maerwald> s/client/process/
10:03 <ph88_> not sure i follow there .. the possible state should be encoded in the types .. and the actual state is on runtime ..
10:03 <ph88_> maybe i should read the paper :P
10:03 <ph88_> off to lunch
10:04 sdothum joined
10:05 jeltsch joined
10:07 ysahil joined
10:08 <maerwald> ph88_: it's not just about your own state though, which is why you model client and server in promela and can watch all possible states of the two during each asynchronous process communication. Exploring all possible internal states too, depending on the order of messages.
10:08 <maerwald> and that's not encoded in the type system imo, because it involves more than one process
10:08 ysahil joined
10:08 BartAdv joined
10:09 wroathe joined
10:11 bhiliyam joined
10:11 <maerwald> or to put it simpler: you can't tell your protocol is deadlock free just because your implementation is totally type-verified
10:12 <tdammers> doesn't that depend on the type system, and what kind of constraints it can express?
10:18 <Jinxit> are 'some' and 'many' useful outside of parsers?
10:19 xtreak joined
10:19 augur joined
10:19 mattyw joined
10:22 xtreak joined
10:26 vaibhavsagar joined
10:27 acidjnk22 joined
10:27 nilof joined
10:28 <nilof> Are there any cases where You want to use the lazy version of foldl instead of the strict one, or lazy foldr ?
10:28 <srhb> nilof: If you're implementing foldr in terms of foldl I guess.
10:28 <srhb> But yeah, you still lose laziness there.
10:29 <* srhb> can't think of a good reason
10:29 <magthe> I'm looking around for examples of how to do 'multipart/x-mixed-replace' responses in any of the Haskell web libs/frameworks... I'm not finding much though... anyone in here who can offer me a pointer?
10:31 unK_ joined
10:34 zcourts joined
10:35 ddere joined
10:35 silver joined
10:35 xtreak joined
10:36 <nilof> So lets see if I understood monad transformers, is say, maybeT Identity isomorphic to Maybe ?
10:36 <merijn> nilof: Correct
10:37 <merijn> nilof: In fact, State/Reader/Writer from transformers are literally just StateT/ReaderT/WriterT over Identity
10:37 fotonzade joined
10:38 <shiona> I assume the only reason for Maybe to not share that is to allow for easier-to-understand error messages
10:38 <merijn> shiona: Well, it's also because Maybe is defined inside Prelude, while MaybeT is not in base
10:38 hamid joined
10:39 wroathe joined
10:39 <merijn> Additionally, you often want to pattern match on Maybe (unlike the ones mentioned above) which would become more annoying if it was defined using Identity
10:40 <* ski> would like it if `newtypes' could have multiple definitions, as long as they're consistent
10:40 bennofs joined
10:40 <merijn> ski: How would that help?
10:41 <nilof> Can you redefine any monad as a monad transformer and get back the monad instance from transformer on identity?
10:41 <nilof> Or are there exceptions?
10:41 <ventonegro> the whole point of `newtype` is to create a new type :)
10:41 <ventonegro> newtype ID = ID String
10:42 <merijn> nilof: I think that should hold for any monad that has a transformer, but I don't think all monads can be turned into transformers
10:42 <nilof> ignoring the issue of pattern matching
10:42 <nilof> ah ok
10:42 <ski> (iow both `newtype State s a = State (s -> (a,s))' and `type State s = StateT s Identity; newtype StateT s m a = StateT (s -> m (a,s))', in this case)
10:42 ubsan_ joined
10:42 <merijn> nilof: Consider IO/STM/ST, those can't (at least not obviously) be turned into transformers
10:42 <Iceland_jack> ski: If data families could have polymorphic return types (not data instances) we could get something like that
10:42 <Iceland_jack> where the newtype in question was dispatched on based on kind
10:43 <Iceland_jack> well, could be tagged by Symbol I suppose
10:43 <merijn> ski: If I ever get around to inventing my own language, dealing with newtypes for class selection would be one of the main focuses to improve
10:44 xtreak joined
10:46 fizruk joined
10:46 Axman6 joined
10:46 robotroll joined
10:48 caumeslasal joined
10:49 wroathe joined
10:51 <maerwald> tdammers: but how would you know that in e.g. a p2p system. You implement the client and do state transitions based on input and whatnot. But you don't see beyond your own internal state as soon as it becomes real-world (multiple clients talking to each other).
10:52 revprez_atlanta joined
10:54 <maerwald> can you infer the whole internal state of a remote based on the message it sent? Maybe in some cases, but consistently?
10:57 cpup joined
10:58 <ph88_> anyone know how i can make a conduit Producer from stdin ?
10:59 doomlord joined
10:59 hamid left
11:00 <Axman6> isn't that already defined somewhere?
11:01 mtesseract joined
11:01 yellowj joined
11:02 xtreak joined
11:02 Snircle joined
11:02 <Axman6> https://hackage.haskell.org/package/conduit-combinators-1.1.1/docs/Data-Conduit-Combinators.html#v:stdin exists
11:03 mthek joined
11:04 Iceland_jack joined
11:04 zcourts_ joined
11:04 <ph88_> oh combinators
11:05 chichou joined
11:05 bjs_ joined
11:08 xfix_ joined
11:09 nh2 joined
11:10 wroathe joined
11:12 bhiliyam joined
11:14 Salih joined
11:14 zcourts joined
11:15 fXl joined
11:16 m0rphism joined
11:16 danza joined
11:17 silentcontrib joined
11:18 cschneid_ joined
11:18 Achylles joined
11:19 dcz__ joined
11:22 samrat joined
11:23 Mysterious_Light joined
11:23 inkbottle joined
11:23 oisdk joined
11:24 Mysterious_Ligh1 joined
11:25 ixti joined
11:26 <ertes> ph88_: CET/CEST
11:26 Destol joined
11:26 <ertes> currently the latter
11:26 <Jinxit> when doing applicative parsing, is it possible to check that two different parses both match on the next token?
11:26 <ph88_> :P
11:27 <tsahyt> Is there some variation of djinn/exference that can work on a file and row/column, and takes import information into account?
11:28 <tsahyt> or even better, knows what is in scope at that position
11:28 <inkbottle> [newbie] On debian I have the choice between "haskell-platform" and "stack": I guess there is nothing wrong going one way or the other...
11:28 augur joined
11:29 <opqdonut> inkbottle: yeah. for a newbie haskell-platform might be nicer
11:29 <opqdonut> less complexity
11:29 <opqdonut> for "real" development, stack is great
11:29 <inkbottle> OK
11:30 <opqdonut> but they don't conflict in any way, you can use both
11:30 wroathe joined
11:30 <inkbottle> thanks
11:30 <opqdonut> (stack does sandboxed installations of ghc and libraries like python virtualenv or npm)
11:30 dhil joined
11:31 <inkbottle> sandboxed=userspace?
11:31 <opqdonut> yeah
11:31 <inkbottle> OK
11:32 insitu joined
11:33 indi_ joined
11:34 silentcontrib_ joined
11:34 mekeor joined
11:35 nmattia joined
11:35 acarrico joined
11:37 nighty-- joined
11:37 JuanDaugherty joined
11:39 Gurkenglas joined
11:42 _sg joined
11:44 NeverDie_ joined
11:45 fotonzade joined
11:46 narendraj9 joined
11:47 <ph88_> what's the difference between Source/Producer and Sink/Consumer in conduit ?
11:47 benl23 joined
11:47 MindlessDrone joined
11:48 Mysterious_Light joined
11:49 <bennofs> ph88_: I think you can pipe input into a Producer if you wish without a type error, but the Producer will ignore it and never read it
11:50 <bennofs> ph88_: whereas a Source requires the input type to be (), so it can only be used at the start of the chain
11:50 <ph88_> oh
11:52 Wuzzy joined
11:52 fizbin joined
11:53 SimpleL joined
11:53 asmyers joined
11:54 wroathe joined
11:55 Achylles joined
11:55 phaji joined
11:56 Itkovian joined
11:56 MindlessDrone joined
11:57 insitu joined
11:57 mbuf joined
11:59 adolby joined
11:59 thatguy joined
11:59 narendraj9 joined
12:00 a143753 joined
12:02 asthasr joined
12:05 zeroed joined
12:05 zeroed joined
12:05 wroathe joined
12:06 Licen joined
12:07 <Licen> ciao
12:07 <Licen> !list
12:07 revprez_atlanta joined
12:08 Licen left
12:08 jship joined
12:09 zariuq joined
12:09 fizruk joined
12:09 rcschm joined
12:11 carlosda1 joined
12:13 bhiliyam joined
12:13 halogenandtoast joined
12:13 <ph88_> what is this MonadResource m0 here and what can i pick for it ? https://bpaste.net/show/83867d9333bf
12:14 theelous3 joined
12:14 MindlessDrone joined
12:14 mattyw joined
12:14 <Axman6> ResourceT is the standard choice
12:16 chichou joined
12:16 yellowj joined
12:17 augur joined
12:17 tmciver joined
12:17 Mysterious_Light joined
12:17 Mysterious_Light joined
12:18 bl0w3d_0ut joined
12:18 Bane^ joined
12:19 <bennofs> ph88_: it's basically a monad that allows you to run IO actions at the end to cleanup resources
12:19 <bennofs> iirc
12:19 ubsan_ joined
12:19 <jasondockers_> Do we prefer to create return types instead of directly returning a tuple? like `type Whatever = (A,B)`?
12:20 <ph88_> what can i put as argument to ResourceT ?
12:20 <bennofs> jasondockers_: probably better to do data Whatever = Whatever { descriptiveNameForA :: A, descriptiveNameForB :: B }
12:20 <ph88_> IO ?
12:20 dibblego joined
12:20 dibblego joined
12:20 <bennofs> ph88_: yea
12:20 <jasondockers_> bennofs, ah, okay. so returning bare tuples isn't usually preferable?
12:21 netheranthem joined
12:21 <bennofs> jasondockers_: well for simple things you can return a tuple directly
12:21 <merijn> jasondockers_: "It Depends (TM)"
12:21 <jasondockers_> heh, okay.
12:21 Mysterious_Light joined
12:21 jeltsch joined
12:21 <merijn> jasondockers_: However, if you do returna tuple directly, then I would avoid type aliasing it
12:21 <jasondockers_> I guess it doesn't really matter. I'm just going through data structures exercises.
12:22 <merijn> i.e. either return (A,B) or define a custome type Whatever, but don't alias (A,B) to Whatever, because that leaves me guessing
12:22 <jasondockers_> merijn, alright
12:23 Lord_of_Life joined
12:25 wroathe joined
12:26 augur joined
12:27 bollu joined
12:29 selthas joined
12:30 mtesseract joined
12:31 Gurkenglas joined
12:33 Itkovian joined
12:34 anuxivm joined
12:35 <mutsig> I'm trying to get my head around parallelization. If I have a list `lst` of expensive computations, would "foldr par () lst" be a suitable way perform those computations in parallel?
12:36 dan_f joined
12:36 <opqdonut> that should work IIRC, as long as you force the result
12:36 augur joined
12:36 <opqdonut> but I recommend starting with Control.Parallel.Strategies
12:36 <opqdonut> raw `par` usage is hard to get right
12:37 <halogenandtoast> As a quick survery, how many of you put two new lines between functions?
12:38 <halogenandtoast> s/survery/survey/
12:38 <mutsig> Ok, I was hoping to not have to deal with NFData, but perhaps that's easier after all...
12:38 <bennofs> halogenandtoast: i put one
12:38 mkoenig joined
12:38 <mutsig> halogenandtoast: two here
12:40 <codedmart> Is there a way to do something like `someField -~ 1` for lens of only if `_someField` is `> 0`?
12:40 <codedmart> So basically I don't want `someField` to ever be less then 0.
12:41 anuxivm left
12:41 <opqdonut> codedmart: I'd just define a subtractOneButDontGoNegative function and map that
12:41 <Athas> mutsig: NFData is your fate if you want to parallelise Haskell.
12:42 <Athas> Or else a very very good operational understanding.
12:42 yellowj joined
12:42 <Athas> But I mean, some Haskell bigwigs wrote a paper about a new model of parallelism (the Par monads), and the magic sauce was pretty much deepseq'ing everything.
12:42 nomicflux joined
12:42 <bennofs> codedmart: i'd do someField -~ max 0 . subtract 1
12:42 <mutsig> Athas: Ok. So be it... I'll go for NFData.
12:43 <bennofs> s/-~/%~
12:43 bollu joined
12:44 anuxivm joined
12:44 <halogenandtoast> bennofs: mutsig thanks, so far that's 50/50
12:44 wroathe joined
12:45 insitu joined
12:45 <Athas> halogenandtoast: one line here. Or sometimes zero, for where-bound one-liners.
12:45 <codedmart> Thank!
12:46 jeltsch left
12:47 Yuras joined
12:47 bollu joined
12:47 jeltsch joined
12:48 lithie joined
12:49 wei2912 joined
12:49 deni left
12:50 fotonzade joined
12:54 <ph88_> how can i control the chunksize with conduit >
12:55 fizbin joined
12:55 augur joined
12:55 Axman6 joined
12:55 Axman6 joined
12:56 fizbin joined
12:56 <lyxia> mutsig: what kind of computations are in your list? NFData is unnecessary if their WHNF is their NF, like primitive numerical types.
12:57 <c_wraith> NFData also isn't harmful if WHNF is their normal form, because rnf will just be seq
12:57 <c_wraith> The problem is when rnf is recursive but doesn't need to be due to details of how the value is generated
12:58 blocus joined
12:58 mada joined
12:58 brandonstiles joined
12:58 <ph88_> i would like to use the conduit Producer and give it to the parser, then put numbers in a vector, run calculations on them and write the results back to a file .. not sure how i can tie the code together, i have this at the moment https://bpaste.net/show/007ef13dfa75
12:58 jleon joined
12:59 thatguy joined
13:00 dcoutts_ joined
13:01 <mutsig> lyxia: Well, it isn't primetives, but I thought of making them Text, since thats the final result, for printing. Right now WHNF /= NF.
13:02 jathan joined
13:03 rcschm joined
13:04 wroathe joined
13:05 kosorith joined
13:05 selthas joined
13:06 slacker joined
13:07 mbw joined
13:07 ragepandemic joined
13:08 halogenandtoast joined
13:08 ventonegro joined
13:08 ubsan_ joined
13:08 ChristopherBurg joined
13:10 cpennington joined
13:10 mthek joined
13:12 Argue_ joined
13:12 <mbw> I have a question about Haskell/GHC performance. There are a lot of wiki entries, blogposts, stackoverflow answers etc. which claim that GHC-compiled code was on par with hand-optimized C or even Fortran. Often they come with links to benchmarks to the "Great Language Shootout", which doesn't exist anymore and is called "The Benchmark Game", because someone was offended apparently. However, browsing this
13:12 <mbw> site doesn't make it look like these claims are true at all, at least not anymore. Assuming they were in the past, are there good reasons for this (appart from manpower)? Like performance regressions in newer GHC versions, larger vector registers that GHC can't use or something like that?
13:13 fakenerd joined
13:14 bhiliyam joined
13:15 carlosda1 joined
13:15 wroathe joined
13:16 biglambda joined
13:16 xall joined
13:17 <Philonous> mbw, Well, benchmarking is hard. Haskell used to fare OK in the shootout (generally withing an order of magnitude of Java/C), but AFAIK nobody is investing much tie into that any more. Part of the problem is that it's pretty meaningless. Just because some carefully optimized program runs as fast as another carefully optimized program means that the typical program you would write runs as fast.
13:17 <merijn> mbw: It's not really so much an issue of GHC regressions as much as "it depends on the code you write"
13:17 <Philonous> investing much time*
13:17 <Philonous> doesn't mean*
13:17 <merijn> mbw: Comparing speed of languages is kinda pointless, since a lot of things depending on the optimisation of the program
13:17 <merijn> mbw: What is "this site"?
13:18 <merijn> It also depends strongly on the benchmark
13:18 iAmerikan joined
13:18 <reactormonk[m]> Weren't there some libraries to run code on the GPU too?
13:19 <merijn> reactormonk[m]: You mean accelerate?
13:19 <lieven> mbw: here's a recent article about a neat haskell solution to a problem: https://byorgey.wordpress.com/2017/01/27/advent-of-code-16-solution-an-algebra-of-bitstrings/
13:19 <srhb> merijn: The computer language benchmarks game, I think: http://benchmarksgame.alioth.debian.org/
13:20 ysahil joined
13:20 <lieven> mbw: once you see this solution youc an code it in another language fairly easily. but thinking in haskell makes it more likely you come up with such a solution.
13:20 <Athas> Philonous: the Haskell programs also used to be really ugly.
13:20 <Philonous> Athas, That too
13:20 jbiesnecker joined
13:21 richi235 joined
13:21 eschnett joined
13:21 <Athas> mbw: Haskell is pretty fast for the things that Haskell is good at (symbolic/tree/list processing). It has higher overheads than C unless you program in a very weird (low-level) style. It cannot reasonably match or beat C or Fortran for loopy numeric code.
13:21 jeltsch joined
13:21 coltfred joined
13:21 <Philonous> mbw, It's really hard to say that a language is "faster" than another. Consider python. You wouldn't expect an interpreted language to fare well with heavy numerical computations. And yet it does thanks to carefully crafted libraries that offload the number crunching to C.
13:22 <Athas> The interesting part about Haskell is that you can generally program at a very high and compositional level, and expect the compiler to remove a good bit of the overhead.
13:22 <Athas> In other languages, you tend to create specialised implementations if you want performance. In Haskell, you can re-use components and still get performance.
13:22 <mbw> You are right that it's maybe a little childish. Still, people strongly believe in things like "Garbage Collection makes everything slow" or something like that. The specific site that caused me to ask this was the performance article on the wiki: https://wiki.haskell.org/Performance/GHC. Especially the first paragraph sound very opinionated. Further down: "This entry in fact runs faster than hand optimised
13:22 <Athas> In the benchmarks game, everyone specialises everything, so it doesn't matter.
13:22 <mbw> (and vectorised) GCC!".
13:22 oisdk joined
13:23 <mbw> Also, even if you consider these things pointless, you still get an opportunity to learn more about the language's implementation.
13:23 <Athas> There is a lot of ridiculous hype about Haskell performance.
13:23 vydd joined
13:23 vydd joined
13:24 kdfarn joined
13:24 <cocreature> I thought java and recently go stopped the “gc makes everything slow” attitude
13:24 doomlord joined
13:24 <Philonous> mbw, There where examples of idiomatic (GHC-compiled) Haskell that ended up running faster than heavily hand-optimized C code. But those cherry-picked examples don't tell you much except maybe that GHC can sometimes do a good job of producing fast machine code even without resorting to tricks like moving your heavy lifting to C
13:25 wroathe joined
13:25 kuribas joined
13:25 <Athas> Philonous: do you know of any examples?
13:25 <srhb> A much better point to make about Haskell, I think, personally, is that general performance is pretty damn good and when it's not good enough, it's fairly easy to lift things over in C or something instead.
13:25 <srhb> That keeps me happy.
13:26 <Athas> Depends on what you are doing. Haskell performance is generally pretty good for things that cannot be fast (like working with pointer-heavy structures).
13:26 <mbw> In my opinion, people should emphasize the productivity/performance ratio, maybe. And stop ending sentences with exclamation marks and talking about things like "aggressive optimizations" and "going down to the bare metal" :/
13:26 <Athas> If you are doing things that _can_ be fast (numerical or array-heavy code), Haskell is generally not very good (with a few exceptions, like Repa or vector for simple cases).
13:26 <* EvanR> is being persuaded with this gratuitous banter to lift his C code to haskell
13:26 <srhb> Oh, sure, all my number crunching (which, honestly, I don't anymore do now that uni is over) was in something else, like a fortran or c library.
13:26 <srhb> EvanR: :P
13:26 <Philonous> Athas, I'm sorry, I can't seem to find it any more. I think it was something about using conduits/pipes for data streaming
13:27 <cocreature> mbw: I think most people would agree with that (myself included) :)
13:27 <srhb> mbw: If you're wrangling huge matrices, it might matter to you. Then again, people talk about "language speed" and never consider their different needs.
13:27 <Athas> Philonous: oh, if it's IO code, then I easily believe it can beat C. GHC has a pretty good IO manager, and Haskell is great for reasoning about IO.
13:27 <srhb> mbw: (So yeah, I basically agree, I guess.)
13:27 <kuribas> unsafePerformIO makes my head hurt... I am trying to set debug messages of with a IORef, it doesn't seem to work...
13:28 <eschnett> if you’re wrangling large matrices, then nothing beats numpy. that is, the libraries that numpy uses. which can be called from haskell just fine.
13:28 <opqdonut> kuribas: why not Debug.Trace?
13:28 <srhb> eschnett: fasta, blas, that kind of stuff.
13:28 <Athas> You can beat BLAS/Lapack with fusion, sometimes.
13:28 thatguy joined
13:28 <srhb> Athas: That sounds fun!
13:28 <kuribas> opqdonut: I want to turn them off...
13:29 <opqdonut> ah
13:29 <Athas> srhb: it is! It's not even that hard. If you want to sum N matrices with BLAS, then you usually end up manifesting the N-1 intermediate results to memory, which is slow (even if the addition itself will be fast).
13:29 <Athas> With fusion, those intermediates could go away. It's the one big advantage languages (including Haskell) have over optimised libraries.
13:29 bennofs joined
13:30 <srhb> Huh, interesting.
13:30 <Athas> ...unless, of course, the library has a specialised routine for just this task.
13:30 <kuribas> opqdonut: What I am doing is I am calculating the intersection of a large number of circles, and if there is an error, remove every circle that doesn't remove the error. But I don't want a log (100s of MB) for every iteration.
13:30 <Athas> (And you know it's there and you use it.)
13:30 <srhb> Yeah, but then that would be doing the job of the fusion anyway
13:30 mtesseract joined
13:30 <mbw> Athas: Or you do your homework and come up with a better algorithm :)
13:30 <srhb> mbw: :P
13:31 <kuribas> I think haskell is quite good at numeric code.
13:31 <kuribas> But it cannot beat C, without SSE, etc...
13:32 <Athas> It's not _terrible_. And the code itself can be nice to look at. But it's not very fast, in my experience.
13:32 <cocreature> -fllvm is often really helpful for numeric code
13:32 <Athas> Although it's hard to find examples of people using it in anger, so there is little evidence one way or the other.
13:32 Achylles joined
13:33 <kuribas> Athas: i am writing a numerical library, but I have no comparison with C...
13:33 <Athas> kuribas: which numerical library?
13:33 clrnd joined
13:33 <kuribas> Athas: https://hackage.haskell.org/package/cubicbezier
13:33 nick123 joined
13:34 <Athas> Cool! Are you using vector for the heavy lifting?
13:34 meba joined
13:34 <mbw> I think one thing where haskell shines is it's surrounding culture of equational reasoning, emphasis on purity etc. And I think there are number crunchers out there that appreciate that. There is a paper about GPU programming in the financial sector where people prototype in haskell, apply homomorphism theorems etc. etc. and implement it in Fortran.
13:34 bennofs1 joined
13:34 <kuribas> athan: sometimes...
13:35 wroathe joined
13:35 <Athas> mbw: definitely Haskell is very very good for *expressing* the algorithms (even if multidimensional arrays can be awkward). Only the performance can be a problem.
13:35 significance joined
13:35 MindlessDrone joined
13:35 <Athas> Numerical algorithms are often well-behaved with respect to functional purity, too.
13:36 <cocreature> if performance becomes a problem you can always try making a dsl that generates C/llvm/whatever :)
13:36 <mbw> Sadly, equational reasoning is not much use when you have to parallelize Fortran77 code with several nested routines that each do IO and modify blank common blocks. If you don't know what blank common blocks are, think nasal demons.
13:36 <cocreature> e.g. accelerate
13:36 ystael joined
13:36 thatguyfrombefor joined
13:37 <Athas> mbw: ugh. I have the naive hope that it wasn't written like that because the programmer *wanted* to...
13:37 <merijn> cocreature: Honestly accelerate isn't too great for GPU stuff, except maybe simple matrix stuff
13:37 <Athas> cocreature: that's a good approach, but it doesn't seem to perform as well in practice as in theory.
13:38 <cocreature> merijn: well as always it depends on your requirements :)
13:38 <Athas> Maybe it could be made to work, but an interesting case is that the vector library is much more used than Repa, despite Repa in principle being faster and more powerful.
13:38 <tsahyt> merijn: in what way is it not too great? performance?
13:39 <merijn> tsahyt: Performance, yes
13:39 <mbw> Athas: Computational chemistry. I.e. not "programmers" per se, a codebase dating back to times where it was cheaper to save previously computed integrals on tape (er, disk) and read it back again. Also as we all know, compiler warnings are just recommendations and probably bugs anyway.
13:39 <tsahyt> is there even any way to utilize the GPU well in haskell?
13:39 <tsahyt> bonus points for it being a sane way, not some inline-c hackery or so
13:39 chip_ joined
13:40 shayan_ joined
13:40 <merijn> tsahyt: Calling existing kernels from Haskell? Sure. Kernels written in Haskell? Not really
13:40 <chip_> is there a way to see the code behind a certain module function?
13:40 <Athas> tsahyt: Obsidian, maybe. It's a fairly clean model, but low-level (i.e. doesn't hide the GPU architecture).
13:40 phyrex1an joined
13:40 <opqdonut> chip_: click on "Source" in the haddock documentation is the most reliable way
13:40 <chip_> for example, i want to see how intercalate works in Data.List
13:40 <tsahyt> @hackage obsidian
13:40 <lambdabot> http://hackage.haskell.org/package/obsidian
13:41 <tsahyt> oh, capital O
13:41 <Athas> mbw: my condolences.
13:41 <opqdonut> chip_: so https://hackage.haskell.org/package/base-4.9.1.0/docs/Data-List.html -> https://hackage.haskell.org/package/base-4.9.1.0/docs/src/Data.OldList.html#intercalate
13:41 <tsahyt> merijn: I suppose where accelerate fails is the lack of a good optimizing compiler step then?
13:41 blocus joined
13:41 <Athas> I think Obsidian is still research-quality, though.
13:41 <Athas> tsahyt: yes, but Accelerate is also kind of restricted in expressivity (e.g. no nested parallelism).
13:42 <merijn> tsahyt: Naah, it fails in "abstracts away hardware details", since "hardware details" is where you get the performance :)
13:42 <mbw> Athas: There are source files you can only translate with O0 (compiler bug). At one point they deleted all comments to safe space. You know, makes the program run faster, probably.
13:42 <mbw> *save
13:42 <chip_> thank you @opqdonut
13:42 <opqdonut> np
13:42 <tsahyt> merijn: it's not like haskell as such would liberally offer up hardware details in general, and still you can write decently performant code in many cases
13:42 <Athas> mbw: maybe those comments made the difference of whether the code would fit on a floppy.
13:42 <merijn> mbw: A development version of GHC once had a bug where it deleted any source file that contained a type error ;)
13:42 <mbw> haha
13:43 <Athas> merijn: they should bring that back as --hardcore-mode.
13:43 <tsahyt> --hardcore-mode would seriously break my workflow
13:43 <tsahyt> every typed hole is a type error in principle
13:43 eacameron joined
13:43 <tsahyt> I could never get anything done at all
13:43 <mbw> Haskell is the Dark Souls of programming after all.
13:43 <Athas> flymake would be suicide.
13:44 <ystael> mbw: meaning if you get a type error once, your next compile has to be successful or it deletes your whole program?
13:44 <tsahyt> mbw: Haskell is more the civilization of programming. "just one more abstraction"...
13:45 <merijn> tsahyt: Not if you use -fdefer-typed-holes ;)
13:45 `^_^v joined
13:45 wroathe joined
13:45 mattyw joined
13:45 <tsahyt> ah.. --python-mode
13:46 nick_h joined
13:46 <merijn> tsahyt: No, that's -fdefer-type-errors
13:46 <merijn> tsahyt: -fdefer-typed-holes only defers typed holes so you can test code that has holes in it :)
13:46 zar[m] joined
13:46 <tsahyt> I never found much use for that tbh. If it has a hole in it, I can't really test it most of the time anyhow, since it will just run into that hole.
13:47 <merijn> tsahyt: That assumes you're testing the code path with the hole :)
13:47 <kuribas> Any idea why this doesn't work? http://lpaste.net/354510
13:47 <Athas> tsahyt: when it comes to optimising compilers, it's important to remember that you don't have to beat the best hand-optimised code to have something useful, you just have to beat the code that humans tend to write.
13:47 <merijn> tsahyt: Maybe you have a hole for error-handling (since you didn't implement it yet) but wanna see if the rest works
13:47 <merijn> kuribas: Can you be more specific than "doesn't work"? :)
13:48 <kuribas> enableTrace is "enableTrace t = unsafePerformIO $ writeIORef traceOn t"
13:48 <kuribas> merijn: it shouldn't output debug messages...
13:48 bl0w3d_0ut joined
13:48 <tsahyt> Athas: I suppose that's true, but then you realize that numeric computing is full of libraries that have been optimized to death. things like fftw, or lapack.
13:48 <kuribas> merijn: because of enableTrace False
13:48 <Athas> tsahyt: ah, but a compiler can optimise composition, which those libraries can't!
13:48 <Athas> Sometimes that can give you enough of an edge.
13:49 <tsahyt> Athas: that is true indeed. GHC can even inline and perform such optimizations across module and even package boundaries.
13:49 <tsahyt> at least afaik
13:49 <Athas> Indeed, that's why it compiles so slowly.
13:49 <tsahyt> the downside is of course that you end up with ginormous executables at times
13:49 <merijn> kuribas: It's not clear to me why "enableTrace False" wouldn't output debug? That seems to only write to an IORef? Nothing there seems to output anything at all?
13:50 <tsahyt> my little gtk doc viewer compiles to a massive 50M...
13:50 <mbw> kuribas: By the way, I got it down to perform within 40% or so of the equivalent c++ code. If the elapsed time were an indicator, it would be exactly on par. Sadly, there is a 100ms difference between total time and elapsed time and I don't know where it's coming from.
13:50 <tsahyt> tbh I find that much worse than the compile times. although those got really really bad with the gi-gtk code that was using lots of overloaded labels
13:50 <Athas> Not bad. My current project compiles to 20MiB, and that's over 40k SLOC of Haskell.
13:50 <tsahyt> I don't know why exactly, but those really slow compilation down to a crawl
13:50 <kuribas> merijn: http://lpaste.net/354510#a354511
13:50 <kuribas> mbw: that's great!
13:50 <tsahyt> Athas: it depends a lot on the amount of dependencies you have
13:50 <merijn> tsahyt: Have you tried using split-objs?
13:51 <tsahyt> I haven't, I just ended up using -dynamic :P
13:51 <mbw> I should probably blog about it, like the cool kids do.
13:51 biglambda joined
13:51 <merijn> tsahyt: How does -dynamic help?
13:51 mtesseract joined
13:51 <merijn> tsahyt: That just changes from 50M single executable to 50MB executable + libraries
13:51 <tsahyt> with the file size? well almost all of it is dependencies that are statically linked
13:51 <bennofs> merijn, tsahyt: split-sections is faster than split-objects (compile time)
13:51 <joe9> I am using the package for writing to a socket https://hackage.haskell.org/package/connection-0.2.8/docs/Network-Connection.html . Whenever there is a byte of "\a", the bytestring is being split into multiple chunks. This is breaking the interface of the legacy app that I am connecting to. Is there a raw socket interface that is widely used?
13:51 <joe9> to avoid such an issue.
13:51 <merijn> tsahyt: Well yes, but switching from static to dynamic linking doesn't shrink the amount of binary required...
13:52 <tsahyt> merijn: well I have the library binaries lying around anyhow
13:52 eacameron joined
13:52 <tsahyt> so bottom line I do save some space
13:53 <tsahyt> I'll try split objects
13:54 fizbin joined
13:54 NyanPasu joined
13:55 <kuribas> merijn: the IORef should switch error reporting on/off
13:55 wroathe joined
13:55 <kuribas> merijn: the trace I mean
13:56 <merijn> kuribas: Honestly, I have no clue what'll happen
13:56 <merijn> @quote not.a.bug
13:56 <lambdabot> Lemmih says: "I don't understand why my code acts weird when I use unsafePerformIO" is not a bug.
13:56 <tsahyt> that did not seem to help at all
13:56 <mbw> Still, since there is some activity now, I'll try to ask this again. If I profile and application and I see a computationally expensive function at the top, and if it is something general like "basicUnsafeRead" or something. How can I find out where it is called most often? .prof files tend to be a little unwieldy in my opinion and don't compare to call graphs.
13:56 infinity0 joined
13:56 jbiesnecker joined
13:56 <opqdonut> mbw: scroll down in the prof file and you'll see the call tree
13:57 mtesseract joined
13:57 <opqdonut> mbw: see https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/profiling.html
13:57 samrat joined
13:57 <opqdonut> mbw: (search for "The usefulness of cost-centre stacks")
13:57 <mbw> opqdonut: That is true in principal, but with deeply nested functions living inside nested modules, everything scrolls off to the right...
13:58 eacameron joined
13:58 <kuribas> mbw: I use flamingra
13:58 <opqdonut> mbw: you mean the output gets truncated somehow? haven't seen that
13:58 ogrady joined
13:59 <mbw> No not truncated. The lines just become very long. So I either have to decrease the font size, or do some grep/awk-foo or something.
13:59 <opqdonut> right
13:59 <mbw> kuribas: What is flamingra?
13:59 SimpleL joined
13:59 <kuribas> https://hackage.haskell.org/package/flamingra
13:59 adolby joined
13:59 dan_f joined
14:00 plutoniix joined
14:00 a3Dman joined
14:00 <opqdonut> mbw: you could try manual cost centers
14:00 {emptyset} joined
14:00 Achylles joined
14:00 <opqdonut> mbw: or something like -fprof-auto-top
14:00 plutoniix joined
14:00 boxscape joined
14:01 stoopkid joined
14:02 <mbw> opqdonut: Do you know how to make that work with stack? There's "stack build --profile", but I think it uses -auto-all or whatever it's called now.
14:02 robkennedy joined
14:02 fizbin joined
14:02 carlomagno1 joined
14:02 <mbw> kuribas: Thanks, I'll try that too.
14:03 <opqdonut> mbw: I guess you could try --ghc-options, but I don't know
14:03 cap86 joined
14:03 ryantrinkle joined
14:04 <shapr> GOOD MORNING!
14:04 <Athas> Hello!
14:04 <mbw> Well hi there.
14:04 cap86 left
14:05 SimpleL joined
14:05 wroathe joined
14:05 simukis_ joined
14:08 <cocreature> mbw: I use https://github.com/fpco/ghc-prof-flamegraph which looks similar to the one kuribas linked to
14:08 <Athas> cocreature: that one doesn't work with huge .prof files, does it?
14:08 mthek joined
14:09 <cocreature> Athas: I haven’t encountered any problems but I also haven’t tried feeding it gigantic .prof files :)
14:09 <cocreature> Athas: what makes you think it doesn’t work?
14:09 <Athas> cocreature: naive use of String functions.
14:09 <mbw> I haven't even heard about FlameGraph until now.
14:09 <Athas> But maybe I'm wrong!
14:11 binaryplease joined
14:12 NeverDie_ joined
14:13 burtons joined
14:13 <cocreature> mbw: it’s quite popular in the C/C++ crowd
14:14 Yuras joined
14:14 significance joined
14:14 bhiliyam joined
14:14 infinity0 joined
14:15 wroathe joined
14:17 revprez_atlanta joined
14:17 <merijn> Meh, give me VTune instead :p
14:18 <mbw> I have a 1-year trial version installed (which I can't use anymore) and find it annoying to use. Still, the optimization output of icc is pretty great.
14:19 <mbw> But I think I installed the cluster-edition by accident, so it's my own damn fault.
14:20 eacameron joined
14:21 nick_h joined
14:21 ysahil joined
14:22 Boarders joined
14:22 chlong joined
14:22 takle joined
14:23 <Boarders> I have just got a copy of the book Real World Haskell but read somewhere online that a lot of the code in the book no longer works, to what extent is that the case?
14:24 a143753 joined
14:24 ph88^ joined
14:25 <mbw> Boarders: I think there is an answer on SO: https://stackoverflow.com/questions/23727768/which-parts-of-real-world-haskell-are-now-obsolete-or-considered-bad-practice . Practically speaking, the book still has its merits and the online version http://book.realworldhaskell.org/read/ has comments below every other paragraph where people describe what as changed and workarounds.
14:25 simukis_ joined
14:26 wroathe joined
14:28 <merijn> Boarders: A lot of the code won't work when copy pasted, since, for example Parsec has evolved since RWH was published. But the underlying explanation of Parsec is still relevant, so understanding the new Parsec docs after reading RWH should be pretty trivial
14:28 <boxscape> what's the infix level of `op` infix style?
14:28 <merijn> boxscape: It depends :p
14:28 <boxscape> ah..
14:28 <boxscape> on what?
14:29 <merijn> boxscape: You can specify it the same way you can for infix operators
14:29 <boxscape> ah, I see
14:29 <merijn> boxscape: i.e. "infixl 4 `op`"
14:29 <boxscape> what is the default then?
14:29 <boxscape> if you don't set it
14:29 <merijn> boxscape: infixl 9
14:29 <boxscape> ok, thanks
14:29 <merijn> For both operators and `` notation
14:29 <boxscape> ah, interesting
14:30 iAmerikan joined
14:30 mstruebing joined
14:30 richi235 joined
14:30 carlosda1 joined
14:30 <Boarders> thanks merijn and mbw
14:31 Luke joined
14:32 Yuras joined
14:32 Lord_of_Life joined
14:32 mizu_no_oto_work joined
14:32 ubsan_ joined
14:32 coltfred joined
14:33 baamonde joined
14:33 Sampuka joined
14:36 wroathe joined
14:37 Lord_of_Life joined
14:38 mrijkeboer joined
14:39 _sg joined
14:41 Snircle joined
14:41 nick123 joined
14:44 b4ff3r joined
14:45 jbiesnecker joined
14:46 ubsan_ joined
14:47 camm joined
14:49 Khisanth joined
14:49 cdg joined
14:49 iulian joined
14:49 <camm> Hello. Do you know how can I parse the Yesod Routes and use them in an application that doesn
14:50 <camm> 't need the context of MonadHandler
14:50 dylukes joined
14:50 burtons_ joined
14:55 raycoll joined
14:55 flatmap13 joined
14:55 <tdammers> maerwald: oh, you mean deadlocked at the protocol level... no, I don't think you can do that
14:55 <tdammers> maerwald: I guess you could design the protocol to never deadlock, and use a type system to verify this
14:56 wroathe joined
14:57 zariuq joined
14:59 infandum joined
15:00 MoALTz joined
15:00 <infandum> In optparse-generic, why can't I have a nested (non-recursive) ADT as generically derived?
15:00 gcross_ joined
15:01 <infandum> It says in the documentation that you can't have nested records, but says nothing about things like data Traffic = Green | Yellow OtherType | Red
15:03 eazar001 joined
15:03 <infandum> Even without that, just having a String type with read x :: Traffic does compile, but complains when running it that "OtherType" is an invalid argument when called with program --input "Yellow OtherType" (where that othertype is one of those types
15:04 doomlord joined
15:05 fizbin1 joined
15:05 <Jinxit> i have multiple data structures forming an AST together (mutually recursive), what is the best way to introduce annotation to all constructors?
15:05 <infandum> Nevermind, I just realized that it's due to eval, the lil' devil
15:06 cap86 joined
15:07 fizbin joined
15:08 darlan joined
15:08 raichoo joined
15:09 <joe9> it is a pita to load all the modules in the project that I am working on with :m + . Is there a project specific ghci file/command that can help? I noticed that if I add a .ghci and put a :m+ module name, it does not work (says that the modules are not loaded yet)
15:09 futuristic joined
15:09 <Jinxit> joe9: i use stack with "stack ghci"
15:09 cyborg-one joined
15:10 <lyxia> Jinxit: I'd define the AST via Fix
15:10 <joe9> Jinxit: That is what I am using too. I can see the modules getting loaded. but, they are not in the context. For example, I do not have getCurrentTime
15:10 <joe9> Jinxit: I have to do :m +Data.Time before I can use it.
15:11 <lyxia> Jinxit: then you can just insert metadata via a separate functor
15:11 whaletechno joined
15:11 <Jinxit> lyxia: got a link or example or something?
15:11 <Jinxit> not familiar with Fix
15:11 <lyxia> type AST = Fix ASTF ; type AnnotatedAST = Fix (AnnotationF :.: ASTF)
15:12 cschneid_ joined
15:12 govg joined
15:12 <Jinxit> where ASTF is what?
15:13 ystael_ joined
15:14 <lyxia> you take "data AST", you rename it to "data ASTF a" and in every occurence of AST in a constructor you replace it by a.
15:14 <lyxia> https://www.reddit.com/r/haskell/comments/4x22f9/labelling_ast_nodes_with_locations/
15:14 <lyxia> Cofree is another solution
15:15 SpaceGazebo3 joined
15:15 bhiliyam joined
15:16 <Jinxit> i'll check out that thread, thanks
15:17 wroathe joined
15:17 mtesseract joined
15:18 <Jinxit> lyxia: i see what you mean now i think, but only if my AST is one big sum type. what if it's multiple data declarations? ( http://lpaste.net/2642574045857447936 )
15:20 <lyxia> hmmm it becomes tricky to do with fix if you want to annotate every node no matter its type
15:21 <Jinxit> i could be doing this in a very odd way i guess, i'm just going on gut feeling :)
15:21 PennyNeko joined
15:21 <Jinxit> but i wanted the type system to prohibit invalid ASTs as much as possible
15:22 SpaceGazebo3 joined
15:22 {emptyset} joined
15:23 osa1 joined
15:23 osa1 joined
15:23 <Jinxit> my first instinct was to parameterize all types on some 'a', and let the user (me) supply the annotation type that way
15:23 <lyxia> you can also open the recursion with a parameter f of kind (* -> *). data Statement i f = Assignment (f (TargetExpr f)) (f (SourceExpr f)) | ... ;
15:24 mazeinmaze_ joined
15:24 <lyxia> oh right that is simpler, I just dislike having fields with the same meaning in different constructors.
15:24 <lyxia> haskell-src-exts does what you said
15:26 <Jinxit> because you could theoretically build them using different 'a'?
15:27 jao joined
15:27 sharkbabyxiang joined
15:29 chlong_ joined
15:29 <lyxia> No. I mean that since they are the same, why should they occur in different places? Basically factor out Either (a, b) (a, c) into (a, Either b c).
15:30 <Jinxit> aha
15:30 NeverDie joined
15:31 <ph88^> how can i go from float 32 bits to integer 32 bits ?
15:32 carlosda1 joined
15:33 trism joined
15:33 <lyxia> floor?
15:34 <hexagoxel> ph88^: like reinterpret_cast?
15:34 <ph88^> i'm not familiar with reinterpret_cast
15:35 <mbw> ph88^ reinterpret_cast is a C++ thing.
15:36 <mbw> And most certainly not what you want. It means just "reinterpreting" bits in a different way.
15:36 <camm> Does anyone know how to generate a route from a Resource in Yesod (https://hackage.haskell.org/package/yesod-routes-1.2.0.7/docs/Yesod-Routes-TH.html#t:Resource)?
15:37 wroathe joined
15:37 fizbin joined
15:38 mda1 joined
15:39 mattyw joined
15:40 <nshepperd_> ph88^: there are a few different ways to turn a float into Int, such as rounding. Which are you talking about?
15:41 <hexagoxel> ph88^: btw the ring buffer benchmark from yesterday has one significant error: `seq` does not force the elements of a list.
15:42 mattyw joined
15:42 ralu joined
15:42 raichoo joined
15:43 bjz joined
15:43 allenj12 joined
15:43 <ph88^> hexagoxel, which benchmark the one from ertes ?
15:43 <ph88^> nshepperd_, truncating
15:43 <hexagoxel> ph88^: no, the old one
15:44 <ph88^> hexagoxel, the one from the blog ?
15:44 <hexagoxel> yes
15:44 a3Dman joined
15:44 jbiesnecker joined
15:44 chlong joined
15:45 steeze joined
15:45 <ph88^> well i already had concluded by various comments that it wasn't the greatest code there :P
15:45 <mbw> ph88^: Which one is your block if I might ask?
15:45 <mbw> *blog
15:45 <hexagoxel> good :)
15:45 <nshepperd_> ph88^: then you probably want one of the RealFrac methods
15:46 <ph88^> it's not my blog, but we were refering to https://johnlato.blogspot.nl/2011/07/circular-buffers.html
15:46 <nshepperd_> 'truncate' for instance
15:47 <mbw> Isn't there a goto ring buffer on hackage or something?
15:47 <ph88^> mbw, yeah there is actually :P but ertes was beating performance and we had fun with it
15:48 <mbw> Ah so it's a golfing thing :)
15:48 des_ joined
15:48 <ph88^> why does this program yield 3212 https://ideone.com/5fH6E2 in c i get different results https://ideone.com/U0elfF the difference in these numbers occur already at 9 bits which should be well within the 32 or 64 bits precision
15:49 jstimpfle joined
15:50 <ph88^> 0.321300 = 0b0,010100100 1000000101101111000000000110100011011011100010111010110010
15:50 SimpleL joined
15:50 <ph88^> 0.321200 = 0b0,010100100 0111010001010011100011101111001101001101011010100001011000
15:50 <ertes> hexagoxel: the element is already forced
15:50 mizu_no_oto_work joined
15:50 <ertes> it's an Int generated from mwc-random
15:51 <hexagoxel> ertes: but isn't it supposed to force the values at those random indices?
15:51 Chaze joined
15:52 <nshepperd_> ph88^: presumably it's 0.3213000000001... vs 0.32129999999997... or something
15:52 <ertes> hexagoxel: no, because they are already computed… if you seq them, nothing changes
15:52 SpinTensor joined
15:53 <hexagoxel> ertes: but there is a difference between computing indices and values at those indices, no?
15:53 <nshepperd_> Truncate throws away the fractional part. Maybe you want 'round' instead
15:53 <ertes> hexagoxel: ah, no, the indices aren't random
15:53 <ertes> the values themselves are random, and they are already computed
15:53 cdg_ joined
15:54 <ertes> yesterday i have verified that it doesn't make a difference, but it didn't expect it to either
15:54 thatguyfrombefor joined
15:54 _ashbreeze_ joined
15:54 <ertes> s/it didn't/i didn't/
15:55 <boxscape> http://lpaste.net/354516 something like this isn't in the lens library, is it? `alongside` is similar, but not quite the same
15:56 <bennofs> boxscape: that is not in the lens library because the result won't satisfy the lens laws in the general case
15:56 <boxscape> ah, I see, thanks
15:56 <bennofs> boxscape: combine _1 _1 would break the lens laws for example
15:56 <boxscape> ok, that makes sense
15:56 free_beard joined
15:56 <ph88^> ertes, is the ring-buffer ready? :P
15:57 oleksiyp joined
15:57 Sampuka joined
15:57 wroathe joined
15:58 <camm> Maybe, someone of you know how to transform a [Piece typ] (http://hackage.haskell.org/package/yesod-routes-1.2.0.7/docs/Yesod-Routes-TH.html#t:Piece) into a route?
15:58 <hexagoxel> ertes: well nothing is random, because the "random" indices are precomputed anyways. but forcing the elements should still make a difference, given non-constant-time access for Seq.
15:59 sharkbabyxiang joined
15:59 boombanana joined
15:59 cmsmcq joined
16:00 hiredman joined
16:00 Sonderblade joined
16:00 <bennofs> Hmm, I just noticed that stack does not fully lockdown the build plan. It uses hfsevents on mac and hinotify on linux
16:00 infinity0 joined
16:00 BobLoblaw joined
16:01 <bennofs> I guess there is no way to improve on this?
16:01 cdg joined
16:03 Sonolin joined
16:03 <hexagoxel> ertes: there is no need to discuss that benchmark if it is obsolete anyways, still i'd be interested if my criticism is indeed wrong.
16:03 BobLoblaw left
16:04 <ertes> i'm happy to discuss this later… i have to go now
16:05 <ertes> ph88^: no, but i'm still planning to do it today
16:05 <ph88^> sweet, there is no rush, but i'm just curious to see what you come up with :D
16:06 darkSeid_ joined
16:07 wroathe joined
16:11 raichoo joined
16:11 NeverDie_ joined
16:13 Gurkenglas joined
16:13 mstruebing joined
16:13 futuristic joined
16:14 Croniamental joined
16:16 mohsen_ joined
16:16 bhiliyam joined
16:17 rkfmqf joined
16:18 Luke joined
16:18 wroathe joined
16:18 jbiesnecker joined
16:21 fizruk joined
16:21 <NemesisD> what is the official name for a type alias associated with a typeclass, e.g. class Foo a where type Bar a
16:21 mceier joined
16:22 <Iceland_jack> that's an associated type FAMILY
16:22 iAmerikan joined
16:22 <Iceland_jack> or type function
16:23 aarvar joined
16:24 <NemesisD> Iceland_jack: i'm noticing some ambiguity issues, for instance class Job a where type JobOutput a; mkOutput :: JobOutput a -> SomethingElse, I get expected type JobOutput a0 -> RawJobOutput but got JobOutput a -> RawJobOutput
16:24 <NemesisD> erm s/RawJobOutput/SomethingElse/g
16:24 fizbin joined
16:25 <Iceland_jack> NemesisD: type families aren't necessarily injective
16:25 <Iceland_jack> you can have (type JobOutput A = Int) and (type JobOutput B = Int)
16:25 <Jinxit> why is it that you can't pattern match on any constructor? i realize it doesn't always make sense, but sometimes it does
16:26 mtesseract joined
16:26 <Iceland_jack> if you pass an Int to a function (JobOutput a -> ...) is (a ~ A) or (a ~ B)
16:26 <NemesisD> Iceland_jack i've seen that term come up from ghc and i'm not sure what it means. should i be using a multi param typeclass and fundeps or something?
16:26 <Jinxit> data Foo = Bar a | Baz a, someMap f (b a) = b (f a)
16:26 <Jinxit> like so
16:26 <Iceland_jack> NemesisD: Will JobOutput ever map two types to the same type?
16:27 cdg joined
16:27 <Iceland_jack> If not, you can define it as (type JobOutput a = res | res -> a) and it will work
16:27 <NemesisD> Iceland_jack: no, for every input there is exactly 1 associated output type
16:27 <Iceland_jack> no two inputs map to the same output?
16:27 <NemesisD> correct
16:27 acarrico joined
16:28 <Iceland_jack> okay then you can enable TypeFamilyDependencies
16:28 yoyo__ joined
16:28 wroathe joined
16:28 <NemesisD> Iceland_jack: is this preferable to just a multiparam typeclass class Job i o | o -> i where mkOutput :: o -> SomethingElse?
16:29 <Iceland_jack> It's the more modern version
16:30 <Iceland_jack> although there are some things multiparam can do that it can't, I don't know details
16:30 <Iceland_jack> (you can always add a Proxy argument, or use AmbiguousTypes)
16:30 <Iceland_jack> using AmbiguousType means you have to use TypeApplications to specify the type with @Int)
16:31 splanch joined
16:31 <NemesisD> i'll give multi param type classes a try and see if i run into usability problems, since its more familiar
16:31 <Iceland_jack> okay
16:31 <Iceland_jack> afk
16:31 <ickabob> is
16:32 carlosda1 joined
16:33 richi235 joined
16:33 oleksiyp joined
16:34 tathougies joined
16:34 revprez_atlanta joined
16:35 pavwgi joined
16:36 the_2nd joined
16:36 <the_2nd> Is there no Alternative instance for Either?
16:36 {emptyset} joined
16:38 eacameron joined
16:38 <the_2nd> No instance for (GHC.Base.Alternative (Either MyErrorType))
16:38 <the_2nd> arising from a use of ‘<|>’
16:38 wroathe joined
16:39 _sg joined
16:39 <the_2nd> am I missing something?
16:40 <geekosaur> you want Except, not Either
16:40 shutdown_-h_now joined
16:41 Achylles joined
16:44 <Zemyla> Hm, would it be possible at all for Haskell to special-case the form of a strict Maybe-like constructor?
16:44 t7 joined
16:44 Berra joined
16:45 camm left
16:45 dhil joined
16:45 <Zemyla> Wait, no. I was thinking that it might be possible to have, if data MaybeS a = NothingS | JustS !a, to basically have pointers to it be isomorphic to a union NULL, but what if a is a pointer type of that kind? :V
16:46 binaryplease joined
16:47 <geekosaur> sounds like you want to get down and dirty with the RuntimeRep stuff going on in ghc8
16:47 kosorith joined
16:47 obadz joined
16:49 <the_2nd> geekosaur, the error now changed to
16:49 <the_2nd> No instance for (Monoid MyErrorType) arising from a use of ‘<|>’
16:49 wroathe joined
16:49 katychuang_ joined
16:49 <the_2nd> I guess I have to include <|> from somewhere else? (currently Control.Applicative)
16:50 sleffy joined
16:50 <the_2nd> type MyEither a = Except MyErrorType a
16:50 <the_2nd> where MyErrorType is just a SumType
16:53 fizbin joined
16:54 <ysahil> Hey, I wanted to add command line interface to my IRC bot using forkIO.Can someone describe exactly how do we achieve this?
16:54 <the_2nd> geekosaur, the syntax here is a bit more complex
16:54 <the_2nd> I guess I assumed something that was only true for Maybe
16:54 <the_2nd> one sec, pasting
16:54 cpup joined
16:55 <the_2nd> geekosaur, all functions are of the MyEither type http://lpaste.net/8449282552019025920
16:55 <the_2nd> seems like the combination of <|> and do seems to create problems
16:56 <ysahil> maxbound ::Int
16:56 fizbin joined
16:57 <MarcelineVQ> it's the instance for Alternative for Except that matters in regards to the error you got
16:57 <geekosaur> there is not enough here for me to know what is going on
16:57 al-damiri joined
16:57 codygman_ joined
16:58 <the_2nd> geekosaur, type annotations for the used functions + type of MyEither?
16:58 burtons joined
16:59 wroathe joined
16:59 jgertm joined
16:59 significance joined
17:00 SpaceGazebo3 joined
17:01 ziocroc joined
17:02 sigmundv joined
17:03 flatmap13 joined
17:03 flatmap13 joined
17:04 <the_2nd> geekosaur, MarcelineVQ this should contain most of it : http://lpaste.net/5066810134982819840
17:04 <MarcelineVQ> when you use <|> with Except the instance of Alternative you're using is (Functor m, Monad m, Monoid e) => Alternative (ExceptT e m) where m is something called Identity when you use Except instead of ExceptT, it can be said that you're using (Monoid e) => Alternative (Except e) which says that the first type you provide Except must have a Monoid instance
17:05 <MarcelineVQ> that's a bit much at once but what it comes down to is that Except needs a way to combine the values it collects, which Monoid provides
17:05 <the_2nd> MarcelineVQ, is there a way around it? Why doesn't it abort on the first failure?
17:06 fizbin joined
17:06 <MarcelineVQ> So you either need to have a monoid instance for MyErrorType, or use a type that already has one, like a list [MyErrorType]
17:06 <the_2nd> I guess using a list would be better
17:06 cpup joined
17:07 <MarcelineVQ> it does abort, that didn't compile, I'm not quite sure what you're asking
17:07 <the_2nd> I mean your suggestion with [MyErrorType]
17:08 <the_2nd> I guess the alternative would be to simply use a string
17:09 replay joined
17:09 insitu joined
17:09 iAmerikan joined
17:10 <MarcelineVQ> I've not used Except so​ I don't have advice to offer on it but I understand that using a list to collect your error type is an easy way to go
17:10 Swizec joined
17:10 <MarcelineVQ> something like this perhaps type MyErrors a = Except [MyErrorType] a
17:11 <the_2nd> MarcelineVQ, yep exactly. I got it to compile. Thanks a lot
17:15 mstruebing joined
17:17 bhiliyam joined
17:18 augur joined
17:20 Luke joined
17:20 dawehner_ joined
17:22 kian joined
17:22 kian joined
17:23 vydd joined
17:23 vydd joined
17:24 initiumdoeslinux joined
17:24 {emptyset} joined
17:24 srcerer joined
17:24 contextfree joined
17:25 contextfree left
17:25 path[l] joined
17:26 dfranke joined
17:28 revprez_atlanta joined
17:28 hamishmack joined
17:29 burtons joined
17:29 wroathe joined
17:30 <jophish> Keep up the hard work, QuickCheck: "Gave up after 0 tests"
17:32 <monochrom> haha
17:32 <kadoban> Heh
17:33 gcross_ joined
17:33 carlosda1 joined
17:34 biglambda joined
17:34 gcross_ joined
17:36 Mysterious_Light joined
17:37 raichoo joined
17:37 govg joined
17:38 pera joined
17:39 sharkbabyxiang joined
17:41 path[l] joined
17:43 hackebeilchen joined
17:44 kafke joined
17:44 Robin_Jadoul joined
17:45 rotaerk joined
17:45 Cthalupa joined
17:49 cables joined
17:49 anuxivm left
17:50 mtesseract joined
17:50 chenshen joined
17:50 moth joined
17:52 cpup joined
17:55 JuanMiguel joined
17:56 Kreest__ joined
17:58 significance joined
17:59 Luke joined
17:59 Cthalupa joined
18:00 wroathe joined
18:02 cdg joined
18:02 jaspervdj joined
18:03 justin2 joined
18:04 stef204 joined
18:04 ryxai joined
18:08 sellout- joined
18:09 dhil joined
18:09 BlueRavenGT joined
18:10 sharkbabyxiang joined
18:10 wroathe joined
18:11 path[l] joined
18:14 Yuras joined
18:15 ccomb joined
18:16 snowalpaca joined
18:17 orbifx joined
18:18 bhiliyam joined
18:18 mattp__ joined
18:19 Robin_Jadoul joined
18:19 t0by joined
18:19 t0by joined
18:20 wroathe joined
18:20 locallycompact joined
18:21 oisdk joined
18:22 mda1 joined
18:23 merijn joined
18:25 iulian joined
18:28 mda1 joined
18:28 revprez_atlanta joined
18:29 kafke joined
18:29 jgertm joined
18:30 Sonderblade joined
18:31 chaosmasttter joined
18:32 soLucien joined
18:34 carlosda1 joined
18:35 srbaker_ joined
18:37 meoblast001 joined
18:38 rubenwardy joined
18:38 fizruk joined
18:39 <rubenwardy> Hi! I'd like help with monoids and types: https://gist.github.com/rubenwardy/0ce4b0be4c0b56e9e3b5a8e9482be831
18:39 HappyEnte joined
18:39 <rubenwardy> basically I want to make it so different types conform to those functions
18:39 fakenerd joined
18:40 <rubenwardy> but there's a syntax error on the instance declaration line
18:40 <rubenwardy> ‘PState’ is applied to too many type arguments
18:40 <rubenwardy> In the instance declaration for ‘StateM (PState n)’
18:40 Mysterious_Light joined
18:40 <rubenwardy> is it possible to use Monoids with types? Or does it need to be a constructor?
18:40 <glguy> rubenwardy: Your paste doesn't appear to have anything to do with monoids
18:40 <glguy> You can't apply the type PState to n, it has kind *, it doesn't take a parameter
18:41 <rubenwardy> what's that structure called then?
18:41 <glguy> Also PState is a type synonym, you shouldn't be making an instance for it
18:41 geekosaur joined
18:41 <glguy> You can't put type signatures (lines 8 and 11) in an instance declaration without a language extension
18:42 fotonzade joined
18:43 <rubenwardy> I want to make both (String->Integer) and [(String,Integer),[Integer]) conform to an "interface" as you will, so I can make a future function generic (with no need to C+P)
18:44 <rubenwardy> I can't change the definition of PState, but I could wrap it up - but I feel like that's not very clean
18:44 DrMentats joined
18:45 {emptyset} joined
18:45 wroathe joined
18:45 hhhhhhhh joined
18:45 <hhhhhhhh> > ghci
18:45 <lambdabot> error: Variable not in scope: ghci
18:45 <hhhhhhhh> GHCi, version 7.10.3: http://www.haskell.org/ghc/ :? for help
18:45 <hhhhhhhh> ghc: panic! (the 'impossible' happened)
18:45 <hhhhhhhh> (GHC version 7.10.3 for x86_64-unknown-openbsd):
18:45 <hhhhhhhh> interactiveUI:setBuffering2
18:45 <hhhhhhhh> anyone know what to do about that :d
18:45 <glguy> don't type "> ghci"?
18:45 <cocreature> hhhhhhhh: upgrade ghc and see if you can reproduce it with 8.0.2?
18:45 <c_wraith> what os are you on?
18:46 <cocreature> glguy: well that shouldn’t cause a ghc panic
18:46 <hhhhhhhh> c_wraith: openbsd 6.1
18:46 <glguy> cocreature: I didn't realize at first that the rest of that was a pasted error message, I read it as lambdabot output
18:46 nagyf joined
18:46 kafke joined
18:47 <cocreature> there was some discussion about ghc on openbsd on ghc-devs a day ago but I haven’t read what it was about
18:47 <hhhhhhhh> cocreature: openbsd only has 7.10.3 in the ports tree
18:47 zero_byte joined
18:48 Vivek joined
18:48 insitu joined
18:48 <c_wraith> hhhhhhhh, report an upstream bug. clearly something is broken in how ghc is packaged.
18:49 <c_wraith> hhhhhhhh, but it looks like ports isn't doing anything interesting
18:49 <maerwald> you mean a downstream bug
18:49 <c_wraith> err, yes
18:49 <c_wraith> hhhhhhhh, try just installing a more recent binary distribution of ghc
18:49 <cocreature> a coupstream bug
18:50 <cocreature> hhhhhhhh: you can find a build of 8.0.2 here https://downloads.haskell.org/~ghc/8.0.2/
18:51 <c_wraith> hhhhhhhh, you can (and should) install it user-local, so it doesn't interfere with anything from portage
18:52 codesoup joined
18:52 SpaceGazebo3 joined
18:53 Icewing joined
18:53 ysahil joined
18:53 epsilonhalbe joined
18:55 <hhhhhhhh> that doesn't appear to actually contain any binaries :d
18:55 wroathe joined
18:55 significance joined
18:55 <hhhhhhhh> and the configure script doesn't work
18:56 oisdk joined
18:57 kadoban joined
18:57 kafke joined
18:58 SpaceGazebo3 joined
18:59 mtesseract joined
18:59 cyborg-one joined
19:01 firef1y joined
19:02 HKei joined
19:03 path[l] joined
19:05 wroathe joined
19:06 takuan joined
19:08 cmsmcq joined
19:08 JagaJaga joined
19:09 flatmap13 joined
19:09 <tsahyt> is there a library implementing something like data Some (x :: k -> *) = forall a. Some (x a)?
19:10 <jle`> tsahyt: there are several floating around
19:10 <tsahyt> Hoogle is not very helpful unfortunately
19:10 <jle`> tsahyt: the one i normally use is from http://hackage.haskell.org/package/type-combinators-0.2.4.3/docs/Type-Class-Higher.html#t:Some
19:11 <jle`> type-combinators
19:11 <jle`> but another popular one is in dependent-sum
19:11 <jle`> http://hackage.haskell.org/package/dependent-sum-0.4/docs/Data-Some.html
19:11 <jle`> since it integrates with dependent-map
19:11 blocus joined
19:11 <tsahyt> thanks
19:11 <tsahyt> the first one looks exactly like what I had in mind, with versions for arities other than 1
19:11 darjeeling_ joined
19:12 kazagistar joined
19:12 <jle`> the two are identical, but i often find myself using a lot of type-combinators functionality in general, so i just use that one
19:12 ysahil joined
19:12 ChaiTRex joined
19:13 <tsahyt> I should take a closer look at that package. I've never used it
19:13 cmsmcq joined
19:14 <jle`> it's basically all of the typical type-level combinators you run into when doing normal dependently typed stuff in haskell, like hvecs, indexors, generic products, etc.
19:14 <jle`> all of the inductive versions
19:14 SpaceGazebo3 joined
19:15 Jonathan___ joined
19:16 cpennington joined
19:17 significance joined
19:17 ner0x652 joined
19:18 eschnett joined
19:19 bhiliyam joined
19:21 Apocalisp joined
19:22 iomonad joined
19:23 richi235 joined
19:25 wroathe joined
19:26 jgertm joined
19:26 BartAdv joined
19:28 alx741 joined
19:29 <joe9> any experiences with liquid haskell? Is it used widely? It seems a step down from dependent types. but, probably better a good idea to use it for existing code without breaking anything.
19:29 <c_wraith> I much prefer Rich Eisenberg's "basic" type level programming examples. though they might require a new ghc release to work..
19:29 <emc2> so, forgive my ignorance, but I've finally decided to take the plunge and convert my projects over to Stack
19:30 <emc2> how do I actually publish a project so that it's available to Stack?
19:30 alx741 joined
19:30 <jackhill> emc2: you mean so that its availbe via Stackage?
19:30 <emc2> I uploaded a new rev of the first of the series (HUnit-Plus) to hackage last night, but it seems that stack isn't picking it up
19:31 <c_wraith> https://m.youtube.com/watch?v=soKl1IslU-I here are his examples...
19:31 <emc2> yeah
19:32 <tsahyt> emc2: stackage requires manual adding
19:32 <MarcelineVQ> c_wraith: https://www.youtube.com/watch?v=P4Io2CRpwyg is pretty neato too
19:32 <emc2> more generally, 'stack test' on projects that depend on HUnit-Plus complains about having no specified version
19:32 <tsahyt> https://github.com/fpco/stackage#add-your-package
19:32 <emc2> but google (or rather, duckduckgo) doesn't seem to produce any guide
19:32 <c_wraith> MarcelineVQ, ooh, thanks. I haven't seen this one.
19:33 <MarcelineVQ> stephanie focuses on trees in that one iirc
19:33 <tsahyt> emc2: until your package is on stackage, you'll need to specify a version under extra-deps in your stack.yaml
19:34 significance joined
19:34 <tsahyt> i.e. HUnit-Plus-2.0.0
19:34 <c_wraith> I haven't seen any of her talks yet. I'm happy to come across one, because of all the great ghc type system work she's been leading.
19:34 <MarcelineVQ> hehe yeah, well she's richard's sup afaik, or whatever the term is in the academic world
19:34 ziocroc2 joined
19:35 carlosda1 joined
19:35 <ezyang> advisor
19:35 <c_wraith> she was until he got his degree and moved to another university. :)
19:36 <MarcelineVQ> :>
19:36 wroathe joined
19:36 <cocreature> iirc nomeata is now working there
19:36 ButterflyOfFire joined
19:36 sternmull joined
19:36 <MarcelineVQ> yeah, actually I still have to watch https://www.youtube.com/watch?v=jcL4bp4FMUw
19:37 robotroll joined
19:37 <cocreature> heh that’s on my list as well :)
19:40 <joe9> anyone has an Arbitrary instance for Text or Bytestring that does not generate NULL's ?
19:40 Zialus joined
19:41 psychicist__ joined
19:41 csraghunandan joined
19:42 csraghunandan joined
19:42 {emptyset} joined
19:43 <Cale> joe9: Note that rather than a separate Arbitrary instance, you can use forAll with a generator that filters out NULLs
19:45 <Cale> something like forAll (BS.filter (/= 0) <$> arbitrary) (\s -> ...)
19:45 <joe9> Cale, Thanks, will try to do it.
19:46 <cocreature> joe9: if you do want to write an instance "suchThat" might come in hand
19:46 <cocreature> *handy
19:46 nbro_ joined
19:46 wroathe joined
19:46 <joe9> Cale, I have a bunch of data types using the Text data type. But, all these Text's cannot have Null values. I plan on having a newtype NonNullText and then use the above Arbitrary instance for it. good idea? or, is there a better way of going about it.
19:47 <Cale> That's a reasonable idea. You might find the newtype wrappers a little annoying depending on what you're doing.
19:47 <Cale> But it'll work
19:48 Swizec joined
19:48 <joe9> cocreature: Thanks , will check suchThat.
19:48 <joe9> Cale, Thanks.
19:49 ysahil joined
19:49 gabluc joined
19:50 <joe9> cocreature: suchThat is a very good idea. Thanks again.
19:50 Swizec joined
19:51 kafke joined
19:51 <cocreature> joe9: I was in a pretty similar situations recently and was very happy to discover that “suchThat” exists :)
19:52 oisdk joined
19:52 iAmerikan joined
19:52 WarmCookie joined
19:53 <WarmCookie> Cale: ping :3
19:54 <WarmCookie> Guess what I just received? :D (Spoiler: http://i.imgur.com/mthYv7d.jpg)
19:54 markus_ joined
19:54 ryxai joined
19:54 <cocreature> WarmCookie: good choice :)
19:54 cfricke joined
19:55 <WarmCookie> cocreature: I think you made the original recommendation actually :P
19:55 <cocreature> I did? I don’t even remember :)
19:56 gabluc joined
19:57 wroathe joined
19:57 <thimoteus> nice!
19:58 rubenwardy left
20:00 <mniip> is that a second order checkerboard
20:01 revprez_atlanta joined
20:01 chaosmasttter joined
20:03 iAmerikan joined
20:04 <DrMentats> so, I recently got started with haskell and purely functional programming in general and I'm still getting used to it
20:04 <DrMentats> so I was wondering if this is the right place to ask for some more "practical," amateurish advice?
20:04 oisdk joined
20:04 <brynedwardz> Sure is
20:05 JagaJaga joined
20:05 <DrMentats> cool
20:05 bollu joined
20:05 <Tuplanolla> We also have #haskell-beginner if you feel overwhelmed by the types in here, DrMentats.
20:05 <merijn> DrMentats: This is the place to ask anything from practical amateurish to "impractical, theoretical and professional" :p
20:06 <WarmCookie> * #haskell-beginners (plurial)
20:06 wroathe joined
20:06 <Tuplanolla> You can tell I don't go there very often, WarmCookie.
20:06 <DrMentats> thanks, guys
20:07 <merijn> I think being overwhelmed here is a good way to learn by osmosis :p
20:07 <WarmCookie> In the end, it's the same people. As long as we're aware of the level of the question, we'll answer accordingly.
20:07 Zialus joined
20:07 <DrMentats> well, type theory still overwhelms me quite a bit, but hopefully I'll get the hang of it at some point
20:08 <tolt> Is there an easy way to hide a list of imports in the repl? I'd like to have some more room....
20:08 <Tuplanolla> You can `:set prompt`, tolt.
20:09 cschneid_ joined
20:09 <tolt> ah thanks! Tuplanolla
20:09 <Tuplanolla> What operating system are you using, tolt?
20:09 <tolt> debian
20:09 <joe9> Cale, cocreature: as an fyi, http://dpaste.com/3N9W3Q5 this is what I ended up with. Thanks.
20:09 <Tuplanolla> Try this one, tolt: `:set prompt "\ESC[37m\x2508\x2504\x254c\x2500\x254c\x2504\x2508 \ESC[93m\x03c2( \x361\ESC[92;1m\xb0\ESC[91m \x35c\ESC[93;22m\x296 \x361\ESC[32;1m\xb0\ESC[93;22m)\x0242\ESC[37m \x2508\x2504\x254c\x2500\x254c\x2504\x2508\ESC[0m\n"`
20:10 <Tuplanolla> Debian should have the fonts for it.
20:10 fotonzade joined
20:10 <tolt> lol Tuplanolla
20:10 <WarmCookie> tolt: You should be able to create a ~/.ghc/ghci.conf file with `set prompt ">"` in it to make it permanent then.
20:11 <tolt> Yeah. I just couldn't remember the way to change the prompt. I imported a lot of things and had no room to see anything!
20:11 cdg joined
20:13 zeroed joined
20:13 zeroed joined
20:13 <merijn> WarmCookie: Clearly the right way to do things is: https://github.com/merijn/dotfiles/blob/master/dotfiles/ghci#L1
20:14 taksuyu joined
20:15 unK_ joined
20:15 ner0x652 joined
20:16 <sm> merijn: that's nice, but I think I'd need "λ> " to see it as a prompt
20:16 wroathe joined
20:17 tathougies joined
20:18 mizu_no_oto_work joined
20:18 locallycompact joined
20:18 <sm> incidentally, I wish you could exit ghci with ctrl-d. Now I see why it appears to work sometimes (stty echo gets set in my emacs shell)
20:19 fDev2179 joined
20:20 <koala_man> sm: can't you?
20:20 bhiliyam joined
20:20 <sm> woah. It's only when in emacs, isn't it
20:21 <sm> stupid shell-mode
20:21 <Sornaensis> today I put haskell in a toaster
20:22 flatmap13 joined
20:23 balor joined
20:24 IanKelling joined
20:25 <hexagoxel> testing some new monad-is-just-$FOOD theory?
20:25 tdfirth joined
20:25 peterbecich joined
20:26 fizbin joined
20:27 wroathe joined
20:27 path[l] joined
20:29 cur8or joined
20:30 cmsmcq joined
20:32 iAmerikan joined
20:32 vtomole joined
20:32 significance joined
20:32 <johnw> has anyone used z3 to build a register allocator?
20:33 Guest16115 joined
20:33 <zv> johnw: donald knuth describes the process in his latest fascicle of 'The Art of Computer Programming'
20:33 <zv> Under the heading of graph coloring
20:33 <johnw> is this only available in print?
20:33 <zv> No, it's available on his website for free
20:33 <johnw> thanks!
20:34 <zv> The Art of Computer Programming Volume 4, Fascicle 6: "Satisfiability"
20:34 <johnw> I have a theoretical machine with multiple execution "slots", and where each operation can have variable latency (e.g., may occupy multiple execution "steps"), and I want to build execution plans based on criteria like "early as possible" and "late as possible"
20:34 <zv> if you are intent on doing it in z3, it depends on if you want to use the API or write your solution in SMTLIB/Datalog/etc
20:34 <johnw> I'd rather do it in Haskell
20:35 carlosda1 joined
20:35 insitu joined
20:36 takle joined
20:36 twanvl joined
20:36 <zv> i personally dont understand sbv, but you could make a good run of it.
20:36 skeuomorf joined
20:36 <johnw> Tikhon Jelvis was recommending that I bypass sbv and just using the haskell-z3 bindings
20:37 wroathe joined
20:39 <Tuplanolla> What do you get when you halve an "octet"? A "quad"?
20:39 <mniip> nibble
20:40 <Tuplanolla> Is that actually half a byte or half an octet?
20:40 <pmn> yes
20:40 ryxai joined
20:40 <mniip> https://en.wikipedia.org/wiki/Nibble
20:41 <zv> it doesn't seem sensical to half a byte, so I would assume octet
20:41 <Tuplanolla> Thank you.
20:41 <pmn> half-byte or semi-octet
20:41 <mniip> half-half-halfword
20:42 <mniip> or even half-half-half-halfword on some
20:42 <pmn> we can abbreviate each 'half' as 'ha'
20:43 Guest15237 joined
20:43 beanbagula joined
20:43 <kazagistar> "roflword"
20:46 bjz joined
20:46 sphinxo joined
20:47 wroathe joined
20:49 <nbro_> hey guys
20:50 <nbro_> what’s the name of the <- in a do block, i.e. the symbol that binds an action’s result to a variable?
20:52 oleksiyp joined
20:53 <johnw> it's sugar for bind, where the result is given a name: x <- foo == foo >>= \x -> ...
20:55 cmsmcq joined
20:55 <nbro_> johnw: I’m asking if there’s a specific name that you give to that symbol
20:55 <glguy> It doesn't have a name, "<-" is just part of the syntax of do expressions.
20:55 <nbro_> can I call it an operator?
20:56 <glguy> No, it's not an operator
20:56 hendrik_ joined
20:56 <nbro_> glguy: what’s it then?
20:56 <glguy> it part of the syntax of do expressions
20:56 <Tuplanolla> Maybe "bind syntax" if you insist giving it a name, nbro_.
20:57 <nbro_> glguy: so it’s part of a do expression in the same way that in is part of the let … in … expression?!
20:57 <glguy> yeah
20:57 <nbro_> another unrelated question
20:58 anuxivm joined
20:58 <nbro_> I have read that IO actions can only be performed in the main, but there are exceptions, which ones?
20:58 Mysterious_Light joined
20:58 <nbro_> (not so unrelated, actually)
20:59 <johnw> unsafePerformIO is probably the main exception
20:59 <merijn> nbro_: The only exception is "if you use unsafeX"
20:59 <johnw> (I couldn't resist)
20:59 <merijn> nbro_: Other than that, there aren't any
20:59 <glguy> Foreign exports lead to actions that are run outside of main
20:59 <glguy> There doesn't even need to be a Haskell main with foreign exports
20:59 <merijn> glguy: Only if control flow doesn't start in Haskell main?
21:00 <glguy> foreign exports are a bit of a peer to main for being entry points into Haskell, like main they run in their own bound thread
21:02 path[l] joined
21:04 <johnw> is there an "N Color Theorem" for arbitrary dimensions?
21:04 doomlord joined
21:05 cpup joined
21:06 <merijn> johnw: I dunno what your problems are, but I'm glad I'm not having them ;)
21:06 <johnw> this last one was just a curiosity :)
21:06 <johnw> since I'm reading that fascile that I was referred to earlier
21:06 <Tuplanolla> That certainly sounds fun, johnw.
21:06 halogenandtoast joined
21:07 Deadhand joined
21:07 <johnw> right now I just need to learn how to express the input to z3 for the theoretical machine I mentioned above
21:07 <Tuplanolla> I recently spent some time on classical mechanics in arbitrary dimensions.
21:07 wroathe joined
21:07 <Tuplanolla> I need a blog so I can write about these silly adventures.
21:08 <johnw> you do, so that I can read them
21:08 <Tuplanolla> I can tell you now that the highlight was the infinite-dimensional the moment of inertia.
21:08 <johnw> I call that moment "8am"
21:09 cables joined
21:10 <Tuplanolla> For example for a r-radius m-mass ball it approaches that of a r-distance m-mass point perpendicular to the axis of rotation.
21:11 orbifx joined
21:11 JuanDaugherty joined
21:13 <nbro_> another question
21:14 <nbro_> is main considered a special name in Haskell, right?
21:14 <johnw> yes, it's what the linker looks for
21:16 <merijn> nbro_: Not "more special" than, e.g. main in C, though
21:16 <merijn> nbro_: And you can simply invoke the main action in other actions
21:17 <c_wraith> you can name something main at the top level in every module, and you can name a local declaration main any time.
21:17 cmsmcq joined
21:17 <c_wraith> so it's really not very special.
21:17 <glguy> (and you can tell GHC to use a different name)
21:18 <nbro_> merijn: you can invoke the main action in other actions? but isn’t the main action the entry point of an Haskell program?
21:18 <c_wraith> nbro_, that doesn't make it special.
21:19 <glguy> main = putStrLn "Keep looping" >> replicateM 2 main
21:19 <c_wraith> nbro_, it's still an IO action that can be used just like any other IO action.
21:19 <Tuplanolla> Does the C standard prohibit calling `main` again?
21:19 <merijn> nbro_: What glguy wrote, you can simply invoke it recursively
21:19 <merijn> Tuplanolla: Don't think so
21:19 <c_wraith> Tuplanolla, nope.
21:20 flatmap13 joined
21:20 Edith joined
21:20 <Tuplanolla> Something did!
21:20 <c_wraith> Tuplanolla, look up the famous 12 days of Christmas from ioccc
21:20 <nbro_> merijn: you mean we can invoke it infinitely
21:20 flatmap13 joined
21:20 <merijn> nbro_: Sure. Probably not very useful, but you can
21:20 <nbro_> ok
21:21 bhiliyam joined
21:21 splanch joined
21:21 cpup joined
21:23 <c_wraith> Tuplanolla, http://udel.edu/~mm/xmas/
21:24 <Tuplanolla> I have the entire IOCCC archive already, c_wraith.
21:24 cschneid_ joined
21:24 <Tuplanolla> It's a must-have on any system.
21:25 <nbro_> a few days ago I said in another chat that IO in haskell is performed using monads
21:25 <c_wraith> Tuplanolla, then why did you ask if main could be recursive in C? I think that feature is used more there than in all other software. :)
21:25 <nbro_> but someone which is also part of this channel got angry
21:25 <nbro_> because apparently that’s wrong
21:25 <c_wraith> nbro_, nah. monad is just a handy abstraction that IO values support.
21:25 <Tuplanolla> I recalled that it was left undefined by the standard, but usually allowed by implementation for consistency, c_wraith.
21:26 <nbro_> c_wraith: can you clarify you better?
21:26 <c_wraith> nbro_, the important part is that IO actions are values.
21:26 <Tuplanolla> The no-recursive-main idea must originate from somewhere.
21:26 mda1 joined
21:27 <c_wraith> nbro_, that's how you get purity and interaction with the world at the same time.
21:27 burtons_ joined
21:27 <c_wraith> nbro_, you define IO values as representing system interaction, but inert in and of themselves.
21:27 dreco joined
21:28 wroathe joined
21:28 <c_wraith> nbro_, and then the linker is responsible for connecting up the runtime to execute the instructions within the IO value named main.
21:28 <nbro_> c_wraith: of course I understood that using monads is a way to get purity from an unpure world, but I do not understand what exactly do you mean with "io values support monads"
21:28 <c_wraith> nbro_, monads have nothing to do with purity.
21:29 <c_wraith> nbro_, you can have monads in languages that don't enforce purity. like.. um, well, Scala.
21:29 <johnw> monads can be used to embed certain notions within a pure context, but they are not themselves related to purity
21:29 <nbro_> c_wraith: of course I understood you can have monads in a language that doesn’t enforce purity
21:30 <nbro_> that’s no my doubt
21:30 <nbro_> of course!
21:30 <nbro_> I understood what monads is
21:30 <nbro_> but in haskell, if aren’t monads which provide purity when performing IO, then what’s that?
21:30 <Tuplanolla> Just the `IO` type, nbro_.
21:30 <c_wraith> the IO type provides purity when using IO
21:31 <nbro_> you mean Monad IO?
21:31 <c_wraith> the fact that it can be made a monad is 100% irrelevant
21:31 <c_wraith> no, I mean IO
21:31 SpaceGazebo3 joined
21:31 <nbro_> :t IO
21:31 <lambdabot> error:
21:31 <lambdabot> • Data constructor not in scope: IO
21:31 <lambdabot> • Perhaps you meant ‘In’ (imported from Lambdabot.Plugin.Haskell.Eval.Trusted)
21:31 <johnw> also, the specification of IO actions is totally pure; it's the execution of them at runtime which can involved effects outside the program
21:31 <c_wraith> with zero uses if the word monad.
21:31 <nbro_> :k IO
21:31 <lambdabot> * -> *
21:31 <nbro_> :i IO
21:31 qzo joined
21:32 codygman_ joined
21:33 <c_wraith> nbro_, are you able to concatenate lists because [a] is an instance of Monoid?
21:33 <Tuplanolla> @google haskell i/o is not a monad
21:33 <lambdabot> https://www.haskell.org/tutorial/io.html
21:33 <Tuplanolla> No, bad lambdabot.
21:33 caumeslasal joined
21:34 <Tuplanolla> @google haskell "i/o is not a monad"
21:34 <lambdabot> http://r6.ca/blog/20110520T220201Z.html
21:34 <Tuplanolla> Check that one out, nbro_.
21:34 hoknamahn joined
21:34 bjz joined
21:35 <nbro_> Tuplanolla: ok, I will read it ;)
21:35 <nbro_> but now my question is
21:35 <nbro_> why is the monad word mentioned when talking about IO?
21:35 <Tuplanolla> You've moved on to the hard questions now.
21:36 <nbro_> for example, it’s very clear the usefulness of monads in maybe
21:36 <nbro_> :t maybe
21:36 <lambdabot> b -> (a -> b) -> Maybe a -> b
21:36 <Sornaensis> nbro_: monads are used for sequencing IO
21:36 <Sornaensis> well the idea
21:37 <c_wraith> nbro_, because lots of people make haskell sound harder than it is.
21:37 <c_wraith> nbro_, anyone who focuses on Monads is making it harder for themselves (and everyone they talk to) to learn haskell.
21:37 cpup joined
21:38 wroathe joined
21:38 lordcirth joined
21:38 <nbro_> c_wraith: monads are not difficult, what’s difficult is interpreting ambiguous statements
21:39 <MarcelineVQ> nbro_: hmm? Monad isn't involved in the maybe function
21:40 <Tuplanolla> You could as well say "list monoid" or "product bifunctor", nbro_.
21:40 <c_wraith> monads are a level of abstraction most people aren't equipped to handle immediately, as beginners, because it depends on ideas they're not yet comfortable with.
21:40 <Tuplanolla> It's superfluous, not ambiguous.
21:40 <c_wraith> so when a beginner thinks Monad is important and demands they must learn what it is first, they are making things harder for themselves.
21:41 cmsmcq joined
21:41 {emptyset} joined
21:41 <c_wraith> so when you say things like IO uses monads, you are helping to convince beginners that haskell is harder than it is.
21:42 acarrico joined
21:42 <nbro_> c_wraith: well, I think people should learn well the concepts that are discussed most when first approaching a language, and that’s the case of monads in haskell
21:43 fakenerd joined
21:43 <c_wraith> nbro_, it's almost pointless to try to learn monads as used in Haskell before you're comfortable with parametric polymorphism and higher-kinded type variables.
21:44 <c_wraith> you just don't have the base knowledge to make sense of the type of (>>=) without those.
21:44 burtons joined
21:45 <nbro_> c_wraith: of course you should learn the prerequisites first
21:45 mengu joined
21:45 <mengu> hi all
21:45 <mengu> i was reading this post https://aphyr.com/posts/342-typing-the-technical-interview
21:45 <c_wraith> nbro_, but you can write a lot of haskell without ever knowing what a monad is.
21:45 BamiGoreng joined
21:45 SpaceGazebo3 joined
21:45 <mengu> i saw this line "class First list x | list -> x ". did some digging turns out it is called functional dependency
21:45 <ggVGc> you can write monads too without really knowing what a monad is!
21:46 <mengu> so what exactly this is doing?
21:47 <c_wraith> nbro_, but every time you talk about how important monads are, you contribute to the impression that haskell is weird and arcane and demands you know everything before you start.
21:47 <c_wraith> mengu, in general, or in the context of that (comedic) article?
21:47 <mengu> c_wraith: in general
21:47 <lordcirth> mengu, that blog is great
21:48 <mengu> lordcirth: i loved the hexing post
21:48 <mengu> cuz i could understand it lol
21:48 <mengu> but cannot move on before understanding this line :D
21:48 wroathe joined
21:48 <c_wraith> a functional dependency tells ghc that if it knows some of the parameters to the multi-parameter type class, the rest can be figured out from what it knows.
21:49 codygman_ joined
21:49 bjz joined
21:49 <mengu> so when it only has list, it can figure out x?
21:49 <c_wraith> this is different from a multi-parameter type class without a functional dependency, where it has to know every type argument to figure out which instance to use.
21:49 <c_wraith> mengu, yes
21:50 <mengu> c_wraith: that's why he defined two instances
21:50 <mengu> instance First Nil Nil
21:50 <mengu> instance First (Cons x more) x
21:50 <mengu> this is actually how ghc knows it?
21:50 <c_wraith> ghc does a bit of trickery.. it just assumes it will know, and figures it out later. :)
21:51 <mengu> okay, did not make any sense lol
21:51 darjeeling_ joined
21:51 <c_wraith> yeah, it's... kind of odd at first.
21:51 <c_wraith> also, the way it's being used within the context of that post is more... abused.
21:51 <c_wraith> it's being used to create type level functions.
21:52 <c_wraith> which you can kind of claim they always do, but that's usually not the point.
21:52 <mengu> he's actually using types whereas he could use functions, imho
21:53 <c_wraith> I'm not sure it's a he, but that's the whole point of that post. everything is being done at the type level just to be ridiculous
21:53 safe joined
21:53 hiratara joined
21:53 <mengu> yup, it's a he
21:54 codygman_ joined
21:54 <Tuplanolla> This reads like Prolog with the return value there as an argument.
21:55 <c_wraith> the hexing example is completely ridiculous because people using clojure do not really write custom classloaders to load optimized byte code written by hand in hex.
21:55 <c_wraith> the typing example is ridiculous because people using haskell don't really write their whole program at the type level.
21:56 <ystael> c_wraith: more importantly, i want to know where i can sign up to program with a coven of seiðkonur
21:57 <c_wraith> ystael, that is the most important question. I wish I knew.
21:58 wroathe joined
22:01 SpaceGazebo3 joined
22:02 JeanCarloMachado joined
22:02 cmsmcq joined
22:03 <nbro_> Tuplanolla: in tha article you mentioned, it says: "A model of I/O is a data type, not a data type constructor." what’s the difference? Even though I could infer from the info in the same article, reading a precise definition gives you a better understanding and you memorize better
22:04 <nbro_> (not you)
22:04 <nbro_> lol
22:04 <nbro_> (I wanted to say that it’s mentioned)
22:04 <Tuplanolla> It may have kind `*` instead of `* -> *` as we have it, nbro_.
22:06 ryxai joined
22:06 <nbro_> when you say "it" you’re referring to the data type or data type constructor? the data type constructors, in one example, is "data IO a"
22:06 <nbro_> :k IO
22:06 <lambdabot> * -> *
22:06 replay joined
22:06 revprez_atlanta joined
22:07 <Tuplanolla> They're saying the type parameter is not essential to the concept of io itself, nbro_.
22:07 <Tuplanolla> Don't read too deep into it.
22:07 path[l] joined
22:08 <nbro_> ok
22:08 <nbro_> one more question
22:08 <nbro_> it’s also stated that: "All we have done is add a parameter to Stop to hold a polymorphic value. The resulting data type IO ()"
22:08 <nbro_> why is the resulting type IO ()
22:08 <nbro_> why ()?
22:09 <nbro_> :t ()
22:09 <lambdabot> ()
22:09 <nbro_> :i ()
22:09 <Tuplanolla> You ought to finish the sentence before asking questions, nbro_.
22:09 bjz joined
22:10 <nbro_> I finished the reading the sentence
22:10 <nbro_> it doesn’t tell you why the resulting type is IO ()
22:11 <sphinxo> So I want to use: https://hackage.haskell.org/package/transformers-0.5.4.0/docs/Control-Applicative-Lift.html to accumulate errors as I typecheck
22:12 <sphinxo> I need to write a monoid instance for my error data type?
22:12 <Tuplanolla> The unit type is there just to pose an example, nbro_. It doesn't say the type argument has to always be `()`.
22:12 <sphinxo> ( more specifically this: https://hackage.haskell.org/package/transformers-0.5.4.0/docs/Control-Applicative-Lift.html#t:Errors )
22:13 <nbro_> Tuplanolla: then that article is very ambiguous
22:13 zero_byte joined
22:13 <sphinxo> ahh wait, I can just do: type ValidatorM = Errors [ValidationError]
22:14 <sphinxo> and then failure [SomeError]
22:14 <c_wraith> sphinxo, yeah. pre-existing instances. :)
22:14 isenmann joined
22:15 hololeap joined
22:15 ebzzry joined
22:15 <nbro_> for example, this sentence is full of ambiguities "These combinators satisfy the monad laws, so this data type constructor IO is a monad, even though the type modeling input and output, which is IO ()"
22:15 <hololeap> I'm hitting an error I don't quite understand: https://gist.github.com/hololeap/281c9af389e1278b04c64791aa52dae9
22:15 DataComputist joined
22:16 <Gurkenglas> hololeap, add {-# LANGUAGE FlexibleContexts #-} at the top of the file
22:17 <Tuplanolla> Hmm. I don't see it, nbro_.
22:17 <hololeap> Gurkenglas: is that necessary though? i have used the MonadState class before and didn't have to use that pragma
22:18 <Gurkenglas> hololeap, you can also add a type signature to process that does not involve MonadState
22:18 wroathe joined
22:19 frankpf joined
22:19 <nbro_> Tuplanolla: "even though the type modeling input and output, which is IO ()" is not understandable because "the type modeling input and output" is not defined
22:19 <c_wraith> hololeap, there is a bit of a new thing in ghc 8.. before that, you could leave out extensions that enabled types that appeared implicitly in your terms, if they never appeared explicitly.
22:20 Apocalisp joined
22:20 <nbro_> IO(), again, if that’s an example, it’s still not understandable why one would choose () instead of another type as argument to IO
22:20 <c_wraith> hololeap, as of ghc 8, you need to enable the extension if any term has an inferred type that requires it.
22:20 <Tuplanolla> They chose `IO ()`, because it's isomorphic to `Dialogue2`, nbro_.
22:21 <c_wraith> hololeap, this mostly (only?) applies to Flexible contexts and FlexibleInstances
22:21 <Tuplanolla> It all goes back to simply offering a different representation for the original `Dialogue`.
22:21 <hololeap> I just added `process :: CardSet -> CardM String` above the process definition. It's kind of silly that I have to do that or use a pragma, IMO
22:21 bhiliyam joined
22:23 <c_wraith> hololeap, why is that? the inferred type is illegal without the pragma.
22:23 cmsmcq joined
22:23 beanbagula joined
22:24 <nbro_> Tuplanolla: I understood that Haskell has algebraic data types and those one can have morphisms between them, but in this case, in a high level description, what would be a morphism between IO() and Dialogue2?
22:24 <hololeap> since `get` is returining a CardSet, and `processCard` is returning a CardM String, it seems obvious that the type signature of `process` would be `CardSet -> CardM String`. i obviously don't understand something here
22:24 <nbro_> *and thus
22:25 Rodya_ joined
22:25 a3Dman joined
22:25 a3Dman joined
22:25 <nbro_> after this I’ll stop bothering you :D
22:26 <c_wraith> hololeap, what part of that definition allows it to infer the return type is CardM String?
22:27 <hololeap> `processCard c = get >>= process`. if processCard has a type declaration that says it returns CardM String, wouldn't it follow that `process` also returns it since it is last in the bind chain?
22:28 burtons joined
22:28 <Tuplanolla> Let `f` be such that `f (StopIO ()) = Stop2; f (ReadChanIO str cont) = ReadChan2 str (f . cont); ...`, nbro_.
22:28 <c_wraith> hololeap, what part of the definition of process is that specific?
22:29 wroathe joined
22:29 <c_wraith> hololeap, all I see in process are a couple MonadState operations. not enough context to pin things down further.
22:30 dyreshark joined
22:31 ryxai joined
22:31 hiratara joined
22:31 <hololeap> c_wraith: I'm not trying to argue, but I just don't see how it's ambiguous. `processCard` returns a CardM String, and that would mean that `process` also returns a CardM String
22:32 <hololeap> let me just upload the whole thing...
22:35 Shatnerz0 joined
22:37 <nbro_> the craft of understanding when to delve deeper
22:37 carlosda1 joined
22:37 path[l] joined
22:38 darjeeling_ joined
22:38 <EvanR> we must go deeper
22:39 wroathe joined
22:39 <hololeap> c_wraith: ok, it's compiling now. my question is why do i need to explicitly give the type signature for `process` on line 82: https://gist.github.com/hololeap/281c9af389e1278b04c64791aa52dae9
22:39 <nbro_> EvanR: if possible, but we need a good scheduler
22:41 Sgeo joined
22:42 <c_wraith> hololeap, look at what the type inference has to go on. you use (>>), pure, modify, and retry.
22:42 strykerkkd joined
22:42 <c_wraith> hololeap, none of those are specific to CardM
22:42 Sgeo joined
22:43 <sphinxo> safe (!!) to use?
22:43 <c_wraith> hololeap, so all it knows is a bunch of constraints.. MonadState, Applicative, Monad, whatever retry is from..
22:43 <sphinxo> or maybe I should use arrays or vector?
22:43 <nbro_> lol, linux uses a completely fair scheduler
22:43 <nbro_> ahah
22:43 <nbro_> that’s kind of a paradox
22:44 <c_wraith> hololeap, but no concrete type.
22:44 darpan joined
22:44 <darpan> whats up folks
22:45 bjz joined
22:45 <hololeap> c_wraith: ok, i'm starting to see the picture. but, since CardM is just a synonym of sorts, and `StateT CardSet IO` is the only StaetT transformer in the stack, what else would `get` return other than CardSet?
22:45 Nik05 joined
22:45 <darpan> can anyone recommend a good books on learning categories w/ Haskell or the otherway around
22:46 <c_wraith> hololeap, well, it does know it returns a CardSet. there is enough to infer that. and that's actually the problem. it knows one concrete argument to MonadState, but not the other.
22:46 beanbagula joined
22:47 <c_wraith> hololeap, in order to express a constraint with two type arguments where one is concrete and the other is polymorphic, you need to enable FlexibleContexts
22:47 <hololeap> the only other thing i added to the type definition was that it returns CardM String and that should be obvious given the type of `processCard`. _that_ is where i don't see the ambiguity
22:48 <EvanR> darpan: not sure thats a great way... categories via haskell is kind of like looking through a insect eye lens
22:49 wroathe joined
22:49 <darpan> EvanR: yeah I guess you're right. I have some books I'm trying to get around to on category theory but I learn through interacting with things so I figured I'd try to see if I can include Haskell :P
22:50 karce joined
22:50 fDev2179 left
22:50 <hololeap> `processCard c = get >>= process :: Card -> CardM String` ... it's obvious what `process` returns just from this line
22:53 <EvanR> darpan: i did some category theory with agda
22:53 <c_wraith> hololeap, oh! you're actually running into let-generalization.
22:53 <darpan> EvanR oooh that's interesting, I didnt know something like this existed
22:54 <c_wraith> hololeap, bindings made in a let expression or where clause are made polymorphic, regardless of the context in which they are used.
22:54 <c_wraith> hololeap, that's part of the hindley-milner type inference algorithm.
22:55 <c_wraith> > let f x = x in (f 1, f ()) -- hololeap
22:55 <lambdabot> (1,())
22:56 Jesin joined
22:56 <c_wraith> hololeap, without let-generalization, that wouldn't type check
22:56 Koterpillar joined
22:57 sellout- joined
22:57 <c_wraith> hololeap, that's why knowing the type of processCard doesn't monomorphize the type of process
22:57 richi235 joined
22:58 <sphinxo> Why might this be occuring? Module ‘Data.Sequence’ does not export ‘lookup’
22:58 <sphinxo> - containers >=0.5 && <0.6
22:58 <barrucadu> sphinxo: Data.Sequence.lookup was introduced in 0.5.8, see the comment: https://hackage.haskell.org/package/containers-0.5.10.2/docs/Data-Sequence.html#v:lookup
22:58 <barrucadu> Is your version older than that?
22:59 <sphinxo> ahh, I would guess so, thanks
22:59 nick123 joined
22:59 stoopkid joined
23:00 <hololeap> c_wraith: ok, i can see that. is `where` a sugared version of `let`?
23:01 <sphinxo> containers-0.5.7.1 must match ==0.5.8
23:02 <sphinxo> ( have updated my cabal file, on stack build )
23:03 <c_wraith> hololeap, yeah. scoping rules and syntax are a bit different, but they both map down to let expressions in ghc's core
23:03 path[l] joined
23:03 <sphinxo> Oh I need to update my stack resolver?
23:04 <hololeap> c_wraith: i understand a lot better now, thanks!
23:04 <Koterpillar> you don't need version constraints in cabal file if you're using stack
23:04 <Koterpillar> ^ sphinxo
23:04 lambda-11235 joined
23:04 <kadoban> Well, for development you don't. Eventually it's nice to put them in for cabal-install people
23:05 <sphinxo> looks like 5.7.1 is the latest for my resolver 7.20: https://www.stackage.org/lts-7.20/package/containers-0.5.7.1
23:05 jmcarthur joined
23:05 <Koterpillar> you can override a version via extra-packages
23:06 <Koterpillar> sorry, extra-deps
23:06 <sphinxo> ahh that's what that is all about
23:07 beanbagula joined
23:07 <sphinxo> ( just understands this for the first time )
23:08 <Koterpillar> well, extra-deps can _add_ packages to a resolver
23:08 <Koterpillar> but they can also override versions for existing
23:09 ChaiTRex joined
23:10 <c_wraith> hololeap, if it makes you feel any better, it took me a while to understand exactly why it was blowing up, too. :)
23:12 nakal joined
23:13 adolby joined
23:13 markus1189 joined
23:14 markus1199 joined
23:14 {emptyset} joined
23:15 hexfive joined
23:15 <DrMentats> hey, say I want to make something like: class Named t where name :: String
23:15 <DrMentats> I understand why it doesn't make sense
23:15 <DrMentats> but is there any way to attach information to types like that?
23:15 <Koterpillar> class Named t where name :: proxy t -> String
23:16 <DrMentats> ohh
23:16 <DrMentats> I need to check that
23:16 <DrMentats> thanks
23:16 <Tuplanolla> Note that `proxy` is a type variable too, DrMentats.
23:16 <Koterpillar> you can call this as, for example, name (proxy :: Proxy Int)
23:16 <Koterpillar> or name ([] :: [Int])
23:16 theDon_ joined
23:17 <DrMentats> I see. does this require any extensions?
23:17 <Koterpillar> or if you already have something of that type, name [1] (note that this is for Int, not [Int])
23:17 <Koterpillar> no, just checked
23:17 <DrMentats> very interesting
23:19 <Koterpillar> the data type Proxy is in Data.Proxy, I think: data Proxy a = Proxy; proxy = Proxy
23:19 <Koterpillar> but see above, 'proxy' is anything of kind (* -> *)
23:20 wroathe joined
23:21 fizbin joined
23:21 gmhafiz joined
23:22 bhiliyam joined
23:25 beanbagula joined
23:25 seagreen joined
23:26 wroathe joined
23:26 ddere joined
23:27 path[l] joined
23:28 JeanCarloMachado joined
23:29 gmhafiz joined
23:29 <c_wraith> DrMentats, if you're comfortable restricting yourself to ghc 8+, there is a more direct solution involving -XTypeApplications and -XAllowAmbiguousTypes
23:32 Majiir joined
23:33 dan_f joined
23:35 Jesin joined
23:37 joe9 joined
23:38 bhiliyam joined
23:38 carlosda1 joined
23:39 dreco joined
23:39 et09 joined
23:40 <et09> hey, if someone has 3 minutes and could spare some professional advice in PM, i'd appreciate
23:43 cschneid_ joined
23:46 beanbagula joined
23:46 et09 left
23:47 acarrico joined
23:47 indi_ joined
23:47 <Jinxit> got some typeclass issues: http://lpaste.net/9221708763524759552
23:47 <Jinxit> any idea what i'm doing wrong?
23:48 <joe9> can someone please help with this parsing: > (t :: UTCTime) <- (parseTimeM False defaultTimeLocale "%Y%m%d %H:%M:%s%Q %Z" ) "20170411 23:37:06.662591551 UTC"
23:48 <joe9> 1970-01-01 00:00:06.662591551 UTC
23:48 <joe9> is what it is getting parsed as
23:48 <joe9> any suggestions on what I am missing, please?
23:48 Majiir joined
23:49 sleffy joined
23:49 gmhafiz_ joined
23:49 <glguy> joe9: Don't use '%s'
23:50 <glguy> use %S
23:50 <joe9> glguy: That worked like a charm. Thanks.
23:51 <glguy> Jinxit: The 'i' in instance Walkable (Root i a) is unrelated to th 'i' in walk :: Walker i a -> t -> t
23:51 <Jinxit> how do i relate them?
23:52 charco joined
23:52 nomicflux joined
23:52 jasondockers_ joined
23:53 <glguy> you can either rearrange your types so that it's: class Walkable t where walk :: Walker i a -> t i a -> t i a
23:53 <glguy> or project the 'i' out of t using a type family, or using a functional dependency
23:53 Lord_of_Life joined
23:54 <Jinxit> i can't do the former since some of the implementations will only have a, not i a
23:54 <Jinxit> unless i misunderstood
23:56 DTZUZU joined
23:57 significance joined
23:58 YongJoon joined