<    March 2017    >
Su Mo Tu We Th Fr Sa  
          1  2  3  4  
 5  6  7  8  9 10 11  
12 13 14 15 16 17 18  
19 20 21 22 23 _2_4 25  
26 27 28 29 30 31
00:00 CurryWurst joined
00:01 soLucien joined
00:01 ecmuller joined
00:02 nakal joined
00:02 xcmw joined
00:02 marcopullo joined
00:05 ystael joined
00:05 vlnts_ left
00:06 ttoe joined
00:08 theDon_ joined
00:11 sssilver joined
00:12 lambda-11235 joined
00:12 travula_ joined
00:12 pleax joined
00:13 coltfred_ joined
00:14 uglyfigurine joined
00:16 Berra joined
00:18 dan_f joined
00:19 Rizy joined
00:19 sssilver joined
00:20 mson joined
00:22 chreekat left
00:23 fDev2179 joined
00:29 esad joined
00:31 faberbrain joined
00:31 ericsagnes joined
00:35 sam2 joined
00:35 mtncoder joined
00:35 whald joined
00:36 robertkennedy joined
00:36 fDev2179 left
00:37 tag joined
00:37 robkennedy joined
00:37 RGamma joined
00:38 kefin joined
00:39 CurryWurst joined
00:40 minn joined
00:40 cmdd joined
00:41 CurryWurst joined
00:43 ziocroc2 joined
00:44 CurryWurst joined
00:44 xcmw joined
00:46 snowalpaca joined
00:49 surelyourejoking joined
00:50 darjeeling_ joined
00:51 fxrs joined
00:53 CurryWurst joined
00:53 vtomole joined
00:55 aarvar joined
00:56 Bhootrk_ joined
00:56 CurryWurst joined
00:57 markus1189 joined
00:58 markus1199 joined
00:59 CurryWurst joined
01:00 nakal_ joined
01:01 twanvl joined
01:01 CurryWurst joined
01:02 brynedwa1ds joined
01:02 teto joined
01:03 systadmin joined
01:04 cydparser joined
01:04 PennyNeko joined
01:05 lally joined
01:05 CurryWurst joined
01:05 bsima joined
01:06 ystael joined
01:06 meoblast001 joined
01:06 <* bsima> always feels refreshed when hacking on haskell code
01:06 <teto> how to escape quotes in a String plz ?
01:07 <hpc> > '"':[]
01:07 <geekosaur> > text "hi\"lo"
01:07 <lambdabot> "\""
01:07 <lambdabot> hi"lo
01:07 CurryWurst joined
01:07 <geekosaur> note that hpc's applied Show to the result (ghci does this also) and is not what is actually in the String, but a source representation of it
01:08 <hpc> but it is syntactically how you would write a string containing only a double quote
01:08 <hpc> (well, technically they both are)
01:08 <teto> filehubut with a function ? it's to save different strings in a csv
01:09 <geekosaur> you should be using a csv library
01:10 e14 joined
01:11 <teto> sry huge lags: is there any function to just do the escape String -> String ?
01:11 <geekosaur> show but this will not do the right thing
01:11 <geekosaur> well, it will for some cases. again use a csv library to do this right
01:12 CurryWurst joined
01:12 <hpc> yeah, that's the right answer for this situation
01:12 <geekosaur> if you are utterly lazy and don't mind it exploding because it produces Haskell strings instead of what CSV consumers expect, you can cheat and use show. which I expect means you will do so and then wonder why it sometimes explodes
01:12 <hpc> CSV string quoting is different from haskell string quoting
01:13 <geekosaur> CSV is not actually trivial
01:13 pleax joined
01:13 <geekosaur> (it's better than it used to be but it's still something of a sewer)
01:13 Frankablu joined
01:13 e14 joined
01:14 <hpc> csv is worse than it used to be, if you consider that there's other formats out there that aren't garbage ;)
01:15 CurryWurst joined
01:15 <teto> to be clearer, I read from a csv file (saved with cassava) and then write to a lua script, I just want to escape ", i.e. replace " with \"
01:15 <* geekosaur> is remembering spending part of 1995 trying to convince (employee theCustomer) that no, just because program A produces "CSV" and program B can read "CSV" does not mean program B understands what program A produces
01:16 <geekosaur> then you need to be certain the strings are sufficiently valid Lua source that you can get away with just that replacement
01:16 coltfred joined
01:17 rkazak_ joined
01:17 <teto> I don't need it to be robust, I will edit the final lua script by hand. It's just a pretext to learn haskell :)
01:18 <geekosaur> as I said earlier, show is the cheaty solution
01:18 <geekosaur> > show $ "ab" ++ ['"'] ++ "cd"
01:18 <lambdabot> "\"ab\\\"cd\""
01:19 <geekosaur> hm, roght, that show-d twice
01:19 <geekosaur> > text $ show $ "ab" ++ ['"'] ++ "cd"
01:19 <lambdabot> "ab\"cd"
01:19 inferno-cop joined
01:19 Micamo joined
01:19 <geekosaur> ("text" is a lambdabot hack. if you are doing this in ghci, use putStrLn)
01:19 <teto> geekosaur indeed perfect, sry I had not understood I could get away with it ^^
01:20 CurryWurst joined
01:22 CurryWurst joined
01:25 jsgrant- joined
01:26 CurryWurst joined
01:28 e14 joined
01:31 fizruk joined
01:32 Rizy joined
01:32 johnmendonca joined
01:36 prophile joined
01:38 Edith joined
01:40 onecoder779981 joined
01:42 onecoder779981 left
01:42 ramzifu joined
01:42 <Profpatsch> johnw: Yes, maybe that.
01:43 hsyl20 joined
01:43 <Profpatsch> Anyway, as you can see in the paste, I just went with NExpr and “type-cast” the constructors when I need more specific types.
01:44 <Profpatsch> I was surprised how helpful the non-exhaustive pattern match errors were, together with taceShowId.
01:44 lally joined
01:45 <Profpatsch> Those are basically asserts if I think about it.
01:46 <Profpatsch> like isStr (Fix (NStr s)) = s
01:46 <Profpatsch> Now, maybe it’s possible to create a function that can create these kinds of structural asserts.
01:47 <Profpatsch> Probably with pattern aliases.
01:47 <Profpatsch> Or Template Haskell if needbe.
01:47 bjz joined
01:49 <Profpatsch> the manual way would be something like
01:49 <Profpatsch> isStr (Fix (NStr s)) = s
01:49 FreeBirdLjj joined
01:50 kav joined
01:50 <Profpatsch> isStr sth = error $ showShortened sth <> " is not a NStr"
01:51 revtintin joined
01:51 MoronMan joined
01:51 doodlehaus joined
01:55 sternmull joined
01:56 rekahsoft joined
01:57 jsgrant- joined
01:59 xcmw joined
01:59 sobaken joined
02:02 hiWorld joined
02:04 uglyfigurine joined
02:05 ratzes joined
02:07 ystael joined
02:08 mkoenig_ joined
02:08 marcopullo joined
02:09 Apocalisp joined
02:09 kav joined
02:10 <ratzes> any conduits parser experts here? I'm trying to parse a super large sql file (insert lines) and output one vector of values, everything i've tried has blown through my memory
02:10 path[l] joined
02:11 <lyxia> How large is the file, how large is the vector, how large is your memory?
02:12 <ratzes> i have a 5gb and a 48gb, 5gb file is going to be 13mil data types with an int and a smallish text. I have 16 gigs, but would like to keep it as flat as possible
02:13 dsantiago joined
02:13 eacameron joined
02:14 pleax joined
02:15 <lyxia> ratzes: do you have some code to work on?
02:17 infinity0_ joined
02:17 infinity0_ joined
02:17 sdothum joined
02:17 <ratzes> i have an attoparsec parser that works on each line of the file and im using conduits to split the file into lines
02:17 <ratzes> i tried to yield a list and concat it down into a vector, i've tried yielding vectors (also lists) and using conduits vectorbuilder
02:19 <ratzes> each method blows right past my memory limits, I got it parsing flat (22mb) when i only count entries
02:19 michael4 joined
02:20 infinity0 joined
02:22 gcross_ joined
02:22 infinity0 joined
02:25 infinity0 joined
02:25 infinity0 joined
02:26 FreeBirdLjj joined
02:27 netheranthem joined
02:27 Heasummn joined
02:27 ffilozov joined
02:27 deepfire` joined
02:28 infinity0 joined
02:28 M0r0nM4N joined
02:30 <allenj12> whats the best way to get a random subList of a list? [a] -> b -> Rvar [a]
02:30 <allenj12> where b is the size of the sublist
02:30 <lyxia> take b
02:31 sternmull1 joined
02:31 infinity0 joined
02:31 <allenj12> shuffle then take?
02:32 <allenj12> i thought there might be an actualy function i would be missing
02:32 <lyxia> hmmm that's a good idea if your shuffle is lazy or if you are going to take many elements
02:32 <ratzes> contiguous sublist?
02:33 argent0 joined
02:33 faberbrain joined
02:34 <allenj12> it dosnt have to be a a "chunk" of the original array. like calling choice alot and puting the results into a list
02:35 <allenj12> i saw the function sampleSeq but its for sequences, just wish there was on for lists without having to do a conversion
02:35 <allenj12> im really dumb, there is just a sample function....
02:36 <ratzes> lol and they use sampleSeq and fromList so its not O(n*b)
02:38 Guest34521 joined
02:40 <allenj12> i noticed that too... i mean its fine from now, but why would they do that?
02:40 <allenj12> fine for now*
02:40 <ratzes> because you can put it into a structure to index in O(1) time
02:40 <ratzes> oh, wait seqs are finger trees
02:41 <ratzes> so O(log n)
02:41 <allenj12> oooo
02:41 <ratzes> thats why you get the O(m*log n) and the other +n is from loading it into the seq
02:42 anuxivm left
02:43 kanishka joined
02:43 snowalpaca joined
02:44 markasoftware joined
02:44 FreeBirdLjj joined
02:44 systemfault joined
02:45 tennix joined
02:46 connrs joined
02:50 systadmin joined
02:50 P1RATEZ joined
02:51 lordcirth joined
02:55 e14 joined
03:00 hucksy joined
03:06 systadmin joined
03:07 ystael joined
03:10 uglyfigurine joined
03:12 roboguy` joined
03:13 pavonia joined
03:14 marsam joined
03:14 lally joined
03:14 pleax joined
03:14 raycoll joined
03:15 xall joined
03:16 marsam left
03:19 Goplat joined
03:20 Wizek joined
03:20 Wizek_ joined
03:21 raycoll joined
03:21 <allenj12> if i need to "unpack" two different monad to do a compution, is it possible to do that in one function. i.e if i have rlist <-
03:21 <allenj12> woops one sec
03:22 hexagoxel joined
03:22 eacameron joined
03:23 <allenj12> rlist <- genRandList :: IO [Int] then i wanna take a sample of that list which by itself would look like s <- sample rlist :: RVar a
03:23 xcmw joined
03:24 Wizek_ joined
03:24 <allenj12> how do i do this but obviously type correctly
03:24 <allenj12> someFunc = do
03:24 <allenj12> rlist <- genRandList 7
03:24 <allenj12> s <- sample 3 rlist
03:24 <allenj12> putStrLn $ show $ rlist
03:25 <allenj12> and rlist at the last line would be s, my b
03:26 roboguy` joined
03:26 <allenj12> should i just create a new function?
03:28 roboguy` joined
03:28 path[l] joined
03:28 <MarcelineVQ> what is sample from
03:28 raycoll joined
03:29 <allenj12> https://hackage.haskell.org/package/random-extras-0.19/docs/Data-Random-Extras.html
03:29 <allenj12> random-extras
03:29 <allenj12> but the basics of the question is what is the best way when you need to extract from two differently typed monads to do a computation
03:35 <lpaste_> allenj12 pasted “Dealing with two monads” at http://lpaste.net/353409
03:36 <allenj12> i made an lpaste if it helps
03:36 <johnmendonca> allenj12: i think you want to just say let s = sample 3 rlist
03:37 <allenj12> but how would i print it? its still wrapped in Rvar?
03:37 <ski> allenj12 : i suppose you might need to use something like `runRVar' on the result of `sample'
03:38 <ski> allenj12 : .. in order to get an `IO'-action, i.e.
03:38 diegoksp joined
03:39 <allenj12> hmm dont know if that function exists
03:39 centril joined
03:40 <ski> allenj12 : see <https://hackage.haskell.org/package/random-fu->, apparently
03:40 <jle`> allenj12: working with "two monads" inside a do block usually winds up being finding a way to have them both work in some common denominator monad
03:40 <jle`> in this case IO works; converta ll your actions to IO
03:41 djapo_ joined
03:41 <allenj12> jle`: hmmm so write a wrapper function to turn the result of sample to Rvar? is there an example?
03:43 <ski> the result is already `RVar [a]'
03:44 Jesin joined
03:44 <ski> the "wrapper function" `runRVar' could possibly turn it into `IO [a]', given also a random source argument
03:44 bjz joined
03:45 <allenj12> thats actually kinda confusing, since sample uses the default global source of randomness
03:47 fabianhu joined
03:48 <ski> i'd suspect "default global source of randomness" here means the source provided to it by `runRVar', or any similar operation
03:48 wei2912 joined
03:50 <MarcelineVQ> it's the source provided by the relevant MonadRandom iirc, a compatible line for your s in the IO monad might look like: s <- runRVar (sample 3 rlist) StdRandom
03:50 xaviergmail joined
03:51 <MarcelineVQ> random-fu is a little much to take in at once :X could do with more examples at the top for sure
03:52 <allenj12> so there runrvar will convert to IO? im assuming this is because of stdrandom specifically?
03:53 rekahsoft joined
03:53 exferenceBot joined
03:53 <MarcelineVQ> idk, the docs say this about it https://hackage.haskell.org/package/random-fu- and IO has a MonadRandom instance
03:54 <MarcelineVQ> er, MonadRandom has an IO instance :>
03:55 Jeanne-Kamikaze joined
03:58 hexagoxel joined
03:59 <allenj12> this is kinda confusing haha :D
04:00 <c_wraith> It's not the easiest starting point.
04:00 anry joined
04:02 <johnmendonca> runRVar :: RandomSource m s => RVar a -> s -> m a
04:03 <johnmendonca> in this case m will become IO because it is in IO do block
04:03 <allenj12> ah gotcha
04:04 systadmin joined
04:04 <allenj12> also what is this error message? • Data constructor not in scope: StdRandom
04:04 <allenj12> • Perhaps you want to add ‘StdRandom’ to the import list
04:04 <allenj12> in the import of ‘Data.Random’
04:04 <allenj12> i did the import Data.Random(StdRandom) and it gives me that.
04:05 <allenj12> i feel like its telling me to do something I already did
04:07 <tswett> Hey everyone. I haven't written much Haskell in, oh, about 15 years?
04:07 <tswett> No, that's a little too long. I was 9 then.
04:08 <tswett> Anyway, I've been playing around with Scala. One of the interesting things about Scala is that classes ("ordinary" classes, not typeclasses) can have types as members, so you might have, say, a class called Graph, such that if g is a Graph, then g.Node is a type.
04:08 ystael joined
04:08 <tswett> I read about GHC's extensions and that made me wonder if I can manipulate Haskell into doing something vaguely similar.
04:09 sam2 joined
04:09 <tswett> So here comes my question.
04:09 <tswett> Here's some stuff I wrote: http://rextester.com/JJRFT92091
04:10 <tswett> A typeclass called Vector, and two types, VectorSpace1 and VectorSpace2. Instances of Vector are vector spaces, essentially. VectorSpace1 and VectorSpace2 are both supposed to represent arbitrary vector spaces, but they're implemented differently.
04:11 <tswett> Both of them use existential quantification. A VectorSpace1 simply contains functions with the same types as the members of Vector. A VectorSpace2 just contains a Proxy, but its type variable is constrained to be an instance of Vector.
04:11 <tswett> The question: can a VectorSpace1 be turned into a VectorSpace2?
04:12 enitiz joined
04:12 bjz joined
04:14 path[l] joined
04:15 the|auriscope joined
04:17 pleax joined
04:17 <MarcelineVQ> allenj12: import Data.Random (runRVar, StdRandom(..)) the (..) says to import the data constructors of StdRandom
04:19 <ski> tswett : would require a `reflection'-like trick, i suspect
04:19 <allenj12> MarcelineVQ: ty
04:20 <tswett> ski: yeah, I looked at Data.Reflection. It definitely seems like the sort of thing that would do it, but I can't figure out how.
04:21 <ski> the implementation uses `unsafeCoerce'
04:22 <ski> tswett : the (or a) basic problem is that one can't put `instance' declarations in `let'/`where'
04:22 ertes joined
04:23 <ski> and even if one could, i think one'd have to have restrictions on when it's possible, and i'm not sure what you want here would fall within such restrictions
04:23 nshepperd joined
04:24 Frankablu joined
04:24 wtetzner joined
04:24 mizu_no_oto joined
04:24 <ski> (making an `instance' declaration for a type that's also declared locally should be ok, i think. but in general not for ones that are visible to third parties. and presumably there could be problems with trying to add instances on existentially hidden types, which is what you'd want here)
04:25 <tswett> If you could do that, I think you'd want to say something like: convert1to2 space = let { instance Vector (the "v" inside of "space") where (...) } in VectorSpace2 (Proxy :: Proxy (that "v" again))
04:25 <ski> yep
04:25 <tswett> And you can't do that, of course.
04:25 <ski> `ScopedTypeVariables' should be needed here, as well
04:27 <tswett> So we'd need an actual instance declaration in order to convert to VectorSpace2.
04:27 <ski> (.. there could be problems with existentials, since with GADTs, sometimes you can recover the hidden type again -- and so conflicting instances could "clash")
04:27 jtcs joined
04:28 <tswett> Let me try to remember hwo I was trying to define a type that could have an actual instance.
04:28 <ski> (hm, perhaps there could be problems even if it's not recovered. thinking about stuff like `Set v', where the structure invariant depends on the `Ord v' instance used)
04:29 <tswett> data VectorOf space = Reifies space VectorSpace1 => VectorOf (that pesky "v" again)
04:30 <tswett> Then if we ignore the issue of the "v", the instance declaration you'd need is just...
04:32 <tswett> instance Reifies space VectorSpace1 => Vector (VectorOf space) where { length = vsLength (reflect (Proxy :: Proxy space)); ... }
04:32 mizu_no_oto_work joined
04:32 jsgrant- joined
04:33 <tswett> "length _ =", rather, because you need to ignore an argument.
04:33 steeze joined
04:35 faberbrain joined
04:35 <ski> hm .. and the other two methods ?
04:38 <tswett> fromIndArrayMaybe = vsFromIndArrayMaybe (reflect (Proxy :: Proxy space)); toIndArray = vsToIndArray (reflect (Proxy :: Proxy space))
04:38 <tswett> Ummm.
04:38 <tswett> First off, can I use a "where" clause here to avoid writing (reflect (Proxy :: Proxy space)) three times?
04:39 <tswett> Second, I'm forgetting to deal with the wrapping that VectorOf provides.
04:40 cobreadmonster joined
04:40 <tswett> fromIndArrayMaybe = fmap VectorOf vsFromIndArrayMaybe (reflect ...); toIndArray (VectorOf x) = vsToIndArray (reflect ...) x
04:40 <tswett> That looks better.
04:40 <ski> unfortunately, i don't think you can
04:40 uglyfigurine joined
04:40 <tswett> This is fmap for Maybe.
04:40 <ski> for some reason, one can't write e.g. `instance Eq Foo where [(==),(/=)] = undefined'
04:41 <* ski> has no idea why
04:41 <cobreadmonster> How do I get command line arguments in Haskell?
04:41 raycoll joined
04:41 <ski> @type getArgs
04:41 <lambdabot> error: Variable not in scope: getArgs
04:41 <ski> @hoogle getArgs
04:41 <lambdabot> System.Environment getArgs :: IO [String]
04:41 <lambdabot> System.Posix.Env.ByteString getArgs :: IO [ByteString]
04:41 <lambdabot> System.Environment.Compat getArgs :: IO [String]
04:41 theelous3 joined
04:41 <ski> @hoogle getProgName
04:41 <lambdabot> System.Environment getProgName :: IO String
04:41 <lambdabot> System.Environment.Compat getProgName :: IO String
04:42 <ski> @hoogle getFullArgs
04:42 <lambdabot> GHC.Environment getFullArgs :: IO [String]
04:42 <cobreadmonster> ski: Is there a way I can get the whole string? So that spaces become significant?
04:42 <geekosaur> only on Windows
04:43 <cobreadmonster> geekosaur: as in?
04:43 <geekosaur> unixes *do not pass* the command line as a single line. at all
04:43 <tswett> Under Linux, your program can't even see the spaces, so there's no way to access the spaces. Under Windows, there's definitely some API call which tells you about the spaces.
04:44 <geekosaur> I don't know what the win32 call would be, see if there's documentation in the win32 package
04:44 <geekosaur> on unixlikes, the shell parses the command line to a list of strings and passes that to the exec syscall
04:44 Jesin joined
04:44 <tswett> Looks like the Windows API call would be GetCommandLine. https://msdn.microsoft.com/en-us/library/windows/desktop/ms683156(v=vs.85).aspx
04:45 otto_s_ joined
04:46 <tswett> So I think I *almost* have a way to convert VectorSpace1 to VectorSpace 2. The only missing part is in that data declaration:
04:46 connrs joined
04:46 <tswett> data VectorOf space = Reifies space VectorSpace1 => VectorOf (the "v" from the VectorSpace1)
04:47 sobaken_ joined
04:48 sobaken_ joined
04:50 <ski> hm, i suppose you need some kind of dependent types
04:50 <tswett> GHC doesn't have those at all, does it?
04:50 <ski> something like `vsV (reflect (Proxy :: Proxy space))' would extract the type `v', if `vsV :: VectorSpace1 -> *'
04:51 <ski> it doesn't
04:51 Xanather joined
04:52 <ski> imagining something like `data VectorSpace1 = VectorSpace1 { vsV :: *,vsLength :: Int,vsFromIndArrayMaybe :: IndArray -> Maybe vsV,vsToIndArray :: vsV -> IndArray }'
04:52 ramzifu joined
04:52 <* ski> supposes Scala is allowing something like that
04:52 <tswett> Sure does.
04:52 <tswett> Lemme see, that's something like...
04:53 santoast joined
04:53 <tswett> trait VectorSpace1 { type vsV; def vsLength: Int; def vsFromIndArrayMaybe(array: IndArray): Maybe[vsV]; def vsToIndArray(vector: vsV): IndArray }
04:53 <tswett> I'm ignoring several facts about Scala, here, like I'm pretty sure Maybe is called Option in Scala.
04:54 <tswett> Then if you have a value space: VectorSpace1, then space.vsV is a type.
04:54 <ski> right
04:55 <ski> so type expressions can depend on value expressions
04:55 buttons840 joined
04:55 <tswett> Yep. It's a very limited form of dependent typing.
04:55 <ski> (and not just that data types gets reflected as data kinds on the next level, as in GHC)
04:56 mizu_no_oto joined
04:56 mac10688 joined
04:57 <tswett> I think you can cheat and say:
04:57 <tswett> data VectorOf space = Reifies space VectorSpace1 => VectorOf Any
04:58 <tswett> And don't expose the data constructor, and unsafeCoerce as necessary.
04:58 cmdd joined
04:59 <tswett> And that raises a question: if VectorOf isn't exposed, how *do* you create a VectorOf?
05:00 sobaken joined
05:00 lithie joined
05:02 cschneid_ joined
05:03 castlelore joined
05:03 <tswett> Here's something I might want to implement: indArrayToVectorOfMaybe :: forall space. Reifies space VectorSpace1 => Proxy space -> IndArray -> Maybe (VectorOf space)
05:04 <tswett> I'm starting to repeat myself a little. An implementation I might want to write would be:
05:04 pasukon joined
05:05 <tswett> indArrayToVectorOfMaybe Proxy array = fmap VectorOf (vsFromIndArrayMaybe (reflect (Proxy :: Proxy space)) array)
05:05 MoronMan joined
05:06 thunderrd joined
05:06 <tswett> But that doesn't seem to work because VectorOf can't have a type that allows it to accept that.
05:07 sobaken_ joined
05:08 bjz_ joined
05:09 ystael joined
05:11 ebcz joined
05:16 xcmw joined
05:17 <jle`> is there a nice way to get a list of all executables specified by a cabal file
05:17 <jle`> maybe using stack?
05:17 <tswett> Oooh. I just read this thing, and I think I understand the trick behind reflection now. https://www.schoolofhaskell.com/user/thoughtpolice/using-reflection
05:17 uglyfigurine joined
05:17 hexagoxel joined
05:17 steeze joined
05:17 <tswett> A typeclass is essentially just a type that the compiler only lets you have one value of. At compile time, class constraints get turned into "real" parameters.
05:18 pleax joined
05:19 <tswett> Reflection uses unsafeCoerce to pass this parameter in explicitly instead of having it passed implicitly, like it normally is.
05:21 Micamo joined
05:21 Destol joined
05:23 lenstr joined
05:23 <MarcelineVQ> jle`: Cabal can tell you, how are you intending to get the list though? cli? with Cabal you could do somethig like map fst . condExecutables <$> readPackageDescription normal "foo.cabal"
05:24 slimyb8lls joined
05:24 <jle`> MarcelineVQ: was going to get it from the command line for usage in a shakefile/makefile
05:24 <jle`> i could load in Cabal because i'm using Shake
05:25 <jle`> but a CLI method might be nice as well
05:25 <jle`> thanks very much, that's probably what i'll be using if there's no cli way :)
05:26 <MarcelineVQ> nb that one line requires 3 seperate imports :X
05:26 <MarcelineVQ> Cabal is quite split up :>
05:31 doomlord joined
05:36 surelyourejoking joined
05:37 lally joined
05:41 bo joined
05:41 grayhatter joined
05:42 louispan joined
05:43 <bo> hey guys quick question i'm a freshman cs student who's already solid in java and python. Should I add something functional like haskell or sure up my C/C++ thanks
05:43 oaaao joined
05:44 <johnw> bo: is your main interest to find a job, or to better understand computer science principles?
05:45 <grayhatter> bo, as someone who knows C, Python, hates java, and tolerates php. -> stay far away from haskell
05:45 <bo> definitely CS principles. My ultimate ambition is to go to graduate school for machine learning
05:45 mzf joined
05:46 <bo> grayhatter: haha why is that is it the paradigm shift or is it something with haskell
05:46 <grayhatter> trying to learn haskell is the most painful thing I've ever started. not a single person can explain (in a mannor I can understand) how to make haskell do what I want it to (IO)
05:47 <jle`> bo: i think haskell is a good investment for a cs student :)
05:47 <grayhatter> jle`: I strongly disagree
05:47 <jle`> not only does it help you see things in new ways, but programming haskell is a delight
05:48 <jle`> and my haskell programs tend to be my most maintainable and correct ones
05:48 <grayhatter> haskell is great for a seasoned programmer with at the very least a little knowledge about more advanced concepts
05:48 <bo> grayhatter: aren't some problems easier to solve form a functional point of view as jle' is alluding to
05:48 <grayhatter> otherwise it's a hard language to learn, filled with plenty of fustration
05:48 <grayhatter> fustration isn't something you should suggest a CS student start with
05:48 M0r0nM4N joined
05:49 <grayhatter> jle`: well sure, because if it's not 100% it won't even compile
05:49 <jle`> moving errors from runtime to compiletime improves my productivity a lot :)
05:49 <grayhatter> that's like saying, I tend to drive the most consistantly when I'm the conductor of a train
05:49 <grayhatter> well, no s#!+
05:50 <jle`> that's a good metaphor
05:50 <jle`> if i could have train tracks pre-built for all my programs
05:50 Destol joined
05:50 <jle`> i'd be happy
05:50 <grayhatter> lol
05:50 <* grayhatter> points at python
05:50 <MarcelineVQ> idk about that, it's more like saying my survival rate on the road increases with a car tested before leaving the factory
05:51 <jle`> python is the opposite of haskell in this sense, heh. you can run almost any program, and the language does pretty much nothing to help you write correct programs
05:51 <zcourts> bo: as a former CS student I highly recommend Haskell. Not only is it good to learn on its own but even a basic understanding of some of the common idioms and principles helped me be better at other languages including Java and has been great for the shift I made to Scala a few year ago.
05:51 <jle`> if haskell is like conducting a train then python is like driving a monster truck
05:51 <jle`> except w/o the protection
05:51 danthemyth joined
05:52 <jle`> a monster truck that if you ever veer off slightly the whole truck explodes :)
05:52 <grayhatter> MarcelineVQ: sure, but when I just need it to roll down the street, I don't really need to have airbags the pass NHTSA specs
05:52 <MarcelineVQ> ymmv, I'd want that on my street.
05:52 <tswett> bo: learning Haskell probably involves learning a lot of concepts that you won't learn from Java and C++.
05:52 <MarcelineVQ> other drivers are crazy you see
05:52 <jle`> haskell definitely excels in situations where maintainability and scalability are important
05:52 <grayhatter> jle`: nah, you're thinking of java, that's the one that explodes randomly
05:52 <tswett> bo: if you want to learn the stuff Haskell will teach you, learn Haskell. If you don't want to learn that stuff, don't learn Haskell.
05:53 <bo> very interesting discussion guys. Thanks for the advice zcourts It seems that exposing myself to some Haskell will be good for me
05:53 pickle_ joined
05:53 <jle`> i learned haskell to expand my mind but i ended up staying because i like writing correct programs
05:53 <grayhatter> bo: I'm smarter for having started with haskell
05:53 <grayhatter> that said
05:53 <bo> I don't mind working through some frustration either ;)
05:53 <grayhatter> I HATE haskell
05:54 mhealy joined
05:54 <tswett> grayhatter: let me know if you're willing to let me try to teach you. :)
05:54 <jle`> when i'm writing haskell, most of my code ends up writing itself, and i have to keep track of a lot less things in my head
05:54 <tswett> I like to think I'm good at explaining things.
05:54 <grayhatter> tswett: I'm all in
05:54 <jle`> i write haskell because i'm not smart or clever enough to write python, java, c++
05:54 <grayhatter> I've actually started to get better at working it out on my own
05:54 <zcourts> bo: one way to work your way up with it is to work through the 99 problems https://wiki.haskell.org/H-99:_Ninety-Nine_Haskell_Problems
05:54 <tswett> grayhatter: well, how can I help?
05:55 redmq joined
05:55 <zcourts> or have a read of http://learnyouahaskell.com/chapters
05:55 <grayhatter> but currently, I'm trying to figure out monads
05:55 <tswett> grayhatter: fwiw, I've always thought that understanding monads before understanding I/O is the wrong way around.
05:56 <grayhatter> everything I read makes me think they should be at least partially interchangeable, and other things I've read make me think monads are like python objects where one is just another with different/extra features
05:56 <grayhatter> https://github.com/GrayHatter/devbot/blob/master/devbot.hs#L78
05:56 <jle`> for me, trying to learn about monads didn't really help at all
05:57 <bo> zcourts: Thanks for the links. I'll definitly use them to help speed up my learning. How powerful is Haskell. Is it more suited for math like R or MATLAB, or should you build GUIs with it
05:57 <grayhatter> I'm trying to convert the ReaderT into a StatefulMonadThatICanChangeTheData
05:57 <jle`> i just used them
05:57 <grayhatter> so that data Bot will hold a list of channels that I can append to
05:57 guardianN left
05:58 <tswett> Sounds like StateT, then.
05:58 <grayhatter> tswett: yeah, I tried swapping that out, but never figured out how to solve the type errors
05:58 <grayhatter> no matter what I tried I got type IO ((), Bot) doesnt match IO ()
05:59 <buttons840> grayhatter: have you memorized the type of (>>=)? i've gained many intuitions from thinking about it, although by itself it will not help you understand
05:59 <tswett> grayhatter: hmm, right.
05:59 <grayhatter> buttons840: no
06:00 <grayhatter> in my head `a >>= b` is `evaluate function a, and pipe the output into thing b`
06:00 <zcourts> bo: you can do any of the above with it, however as others may point out you'll find some tasks easier than others to achieve (I guess as with any language). I've found that the difficulties I have with Haskell are usually with bending it to fit the paradigm of another lang/framework that I'm familiar with but actually when I have to write a solution from scratch and its designed in and for Haskell I have a much easier time.
06:00 sobaken joined
06:01 <buttons840> :t (>>=)
06:01 <lambdabot> Monad m => m a -> (a -> m b) -> m b
06:01 sobaken joined
06:01 <tswett> grayhatter: for what it's worth, you can probably do this incrementally. Start by defining type StateNet = StateT Bot IO, and gradually replace occurrences of Net with StateNet elsewhere.
06:01 <grayhatter> buttons840: you have no idea how unhelful that is
06:02 <buttons840> grayhatter: i am a novice myself, and still don't know that i fully understand monads, so i might know :) -- i would agree it's not an adequet explanation of things by itself, but IMHO it will pay off to memorize it
06:03 <tswett> Define a function Net a -> StateNet a, too, to help with the transition.
06:04 <buttons840> grayhatter:do you know what a typeclass is?
06:04 xaviergmail joined
06:04 <bo> zcourts: sweet thanks for the info
06:04 <grayhatter> pretend I don't
06:06 <buttons840> a Monad is a typeclass -- a typeclass is a group of functions that work only with specific type, a function that is part of a typeclass will only work on types which "implement" that typeclass
06:07 <buttons840> grayhatter: i wouldn't worry about knowing how to create your own typeclasses or instances right now
06:08 raycoll joined
06:09 <tswett> grayhatter: for what it's worth, I think I can suggest a find-and-replace that will replace ReaderT with StateT in your entire program, with no type errors in the result.
06:09 <grayhatter> tswett: nah, I'd rather figure it out
06:10 ystael joined
06:10 <grayhatter> ctrl c/v is how I got stuck with ReaderT in the first place
06:10 <tswett> All right.
06:10 <buttons840> grayhatter: so a Monad is a typeclass, a Monad (in it's concrete haskell impelementation at least) is a collection of functions which only work on specific types -- when someone talks about the IO Monad what they really mean is that the IO type can be used with the Monad functions
06:10 <tswett> I already finished typing it out, but I hit ctrl-x instead of enter for you. :D
06:11 uglyfigurine joined
06:11 Rainb joined
06:12 <grayhatter> buttons840: I don't mean to encourage you to stop
06:12 <grayhatter> but I've read hours about monads
06:12 <grayhatter> from dozens of sources
06:13 takuan joined
06:13 <grayhatter> I'm pretty sure I understand what you're saying
06:13 <grayhatter> but it's not at all helpful in my understanding
06:13 <grayhatter> I have a strong suspision that no one really understands monads
06:13 hexagoxel joined
06:14 <grayhatter> tswett | Define a function Net a -> StateNet a, too, to help with the transition.
06:14 <grayhatter> you can tell me how to write that function though
06:14 <grayhatter> you can tell me how to write that function though
06:14 <grayhatter> (wrong window(
06:15 michael4 joined
06:15 YongJoon_ joined
06:16 <buttons840> grayhatter: ok, I'm not a great teacher -- the point I was working up to was that (>>=) is essentially the only Monad function, if it makes sense to implement (>>=) for a type, that type is a Monad
06:16 <tswett> grayhatter: sure, lemme see.
06:17 <grayhatter> buttons840: can you explain this line to me https://github.com/GrayHatter/devbot/blob/master/devbot.hs#L93
06:18 <tswett> migrate :: Net a -> StateNet a; migrate (ReaderT reader) = StateT (\state -> do result <- reader state; return (result, state))
06:18 <tswett> That ought to do it.
06:18 pleax joined
06:18 louispan joined
06:19 ftop joined
06:20 <grayhatter> lol
06:21 bo left
06:21 <grayhatter> I have NO idea how any of that works
06:23 ahri joined
06:23 <tswett> Yeah, it's a little abstract...
06:25 <tswett> Here, let me give you the beginning of an explanation, and you can tell me whether or not it sounds helpful.
06:25 <tswett> We want to write this function:
06:25 <ahri> i'm learning haskell, and am trying to understand why my recursive function https://gist.github.com/ahri/95ebcf45d8bbc2c3321b8d338c2f92ea#file-game-hs-L9 ends up inverting my 2d list. i've highlighted one of the lines "at fault" -- i can easily "fix" the problem by changing my use of (:) to instead swap the params around and use ++, but this means wrapping inside another list, and... well i just can't see
06:26 <ahri> how my function is wrong as-is, so i don't want to just fix it without that understanding. can anyone explain what i've done wrong?
06:26 xall joined
06:26 <tswett> migrate :: ReaderT Bot IO a -> StateT Bot IO a
06:26 <tswett> migrate (ReaderT reader) = ???
06:26 <tswett> Now, the definition of ReaderT tells us that "reader" is going to have the type Bot -> IO a here.
06:27 <tswett> We have to construct something of type StateT Bot IO a. We can always do that using the StateT constructor, so:
06:27 <tswett> migrate (ReaderT reader) = StateT (???)
06:27 <tswett> grayhatter: does this sound like it'll be helpful?
06:29 mda1 joined
06:29 M0r0nM4N joined
06:30 FreeBirdLjj joined
06:31 uglyfigurine joined
06:32 teggi joined
06:33 uglyfigu_ joined
06:33 infinity0 joined
06:36 buttons840 joined
06:36 faberbrain joined
06:37 Destol joined
06:37 <buttons840> grayhatter: to answer you: no, i cannot explain that line, i am not familiar enough with monad transformers
06:40 <grayhatter> tswett: sure
06:40 <grayhatter> (sorry had to step away)
06:44 <tswett> Lemme pause for a moment with my own question.
06:44 <tswett> I think I've almost successfully implemented that whole VectorSpace thing I had going on, but I'm confused by what's happening now.
06:44 <tswett> http://rextester.com/LHE56858
06:45 Sam_ joined
06:45 <tswett> They're all close variations on: "Could not deduce (Reifies s0 (VectorImpl v1)) arising from a use of ‘reflect’ from the context (Reifies space (VectorImpl v))"
06:46 <tswett> And they all say that s0 and v1 are ambiguous, so I assume the compiler would be able to deduce that stuff, if it knew that s0 and v1 were supposed to be space and v.
06:46 <geekosaur> sounds like you need either asTypeOf or ScopedTypeVariables
06:47 connrs joined
06:47 <tswett> geekosaur: ahh, ScopedTypeVariables is what I was looking for. Thanks!
06:47 Xanather joined
06:47 <tswett> grayhatter: all right, lemme continue.
06:47 <geekosaur> remember that you must explicitly forall the type variables you want in scope in the definition (space and v, here)
06:48 hackebeilchen joined
06:48 <tswett> Here's where we're at:
06:48 <tswett> migrate :: ReaderT Bot IO a -> StateT Bot IO a
06:48 <tswett> migrate (ReaderT reader) = StateT (???)
06:48 <tswett> And we know that reader :: Bot -> IO a.
06:49 darjeeling_ joined
06:49 <grayhatter> what is a
06:49 travula_ joined
06:49 <geekosaur> here it helps to remember that ReaderT and StateT are *functions*
06:49 <grayhatter> that's one of the things that gets me about haskell
06:49 osa1 joined
06:50 <tswett> Okay, what does ??? need to be? We look at the definition of StateT, and it tells us that the type we need is Bot -> IO (a, Bot).
06:50 <grayhatter> I under stand A -> B
06:50 <grayhatter> put in A, get out B
06:50 <tswett> grayhatter: "a" here is a type parameter. When we're using migrate, we can substitute any type in for "a".
06:51 <tswett> Inside of migrate, all we know is that "a" is some type.
06:51 <the|auriscope> this also means that you know that you won't be manipulating it directly, because you can't
06:51 <geekosaur> grayhatter, it's the result of a function, we don't care what it is here, we just need to know how to invoke the function
06:51 <tswett> grayhatter: does that answer your question?
06:52 <geekosaur> @unmtl ReaderT Bot IO a
06:52 <lambdabot> Bot -> IO a
06:52 romanandreg joined
06:53 <grayhatter> geekosaur: sure
06:53 <grayhatter> ahh
06:53 <grayhatter> okay
06:53 <geekosaur> tswett, the problem here is you want to transform Bot -> IO a into Bot -> IO (a, Bot)
06:53 <romanandreg> has anyone know if one can set cabal flags (for package in development) to an intero (or stack ghc) session?
06:53 <romanandreg> stack ghci
06:54 <grayhatter> ReaderT Bot IO a is a construct saying a "ReaderT, holding a Bot, Holding ID"
06:54 <geekosaur> this might be running the ReaderT and repackaging the result, or it could be impossible
06:54 <grayhatter> yes?
06:54 <geekosaur> did you see the @unmtl I did?
06:54 <geekosaur> ReaderT is a newtype for a function
06:54 <geekosaur> it doesn't contain anything
06:54 <geekosaur> you pass it a Bot, it produces an IO a
06:54 <tswett> geekosaur: that's what I said. :)
06:55 <grayhatter> okay
06:55 <grayhatter> but how does Pure -> IO
06:56 <grayhatter> how do I turn Bot -> IO a
06:56 <geekosaur> :t fmap (,?x)
06:56 <lambdabot> (?x::t1, Functor f) => f t -> f (t, t1)
06:57 <tswett> grayhatter: well, the smart-aleck answer to that question is: however you want.
06:57 <tswett> grayhatter: let me see if I can find an example of where you're already doing that.
06:58 <grayhatter> tswett: or,
06:59 <grayhatter> explain how I pass a String -> ... -> Net () And get a Net () back out?
06:59 <grayhatter> eg. privMsg
06:59 <grayhatter> https://github.com/GrayHatter/devbot/blob/master/devbot.hs#L183
06:59 <grayhatter> give strings, get Net ()
07:00 <geekosaur> :t \(ReaderT r) -> StateT (\bot -> fmap (, bot) (r bot))
07:00 <lambdabot> Functor m => ReaderT t m a -> StateT t m a
07:00 <tswett> grayhatter: well, privMsg delegates the work of coming up with a "Net ()" to "write".
07:01 <grayhatter> tswett: sure
07:01 <grayhatter> explain `write` then
07:01 <geekosaur> note that this cannot change a ReaderT that reads the Bot into one that updates the Bot; you cannot deconstruct the function and change it to one that does updates, you can only copy the Bot through
07:01 <grayhatter> geekosaur: you're about as helpful as Hoogle
07:02 <grayhatter> and the worst part, is I know I'm supposed to understand what you're telling me, but I just cant -_-
07:02 <geekosaur> those last 2 things I sent were not for you, they were answering tswett's original question
07:02 <tswett> grayhatter: so, in "write", you might say that the core question is: how does it turn a "String" into an "IO ()"?
07:02 arun_t joined
07:02 <grayhatter> yes please!
07:03 <geekosaur> but tbh I am not sure what you are asking, you have a function, it is not a container it is a function
07:03 Destol joined
07:03 <grayhatter> geekosaur: sure, then I'm thinking about it all wrong
07:03 <geekosaur> you *pass* it something, it does not *contain* something. you cannot know what the function does
07:03 <tswett> grayhatter: and the short answer is, it delegates *that* work to the hPrintf function.
07:03 <tswett> @type hPrintf
07:03 <lambdabot> HPrintfType r => GHC.IO.Handle.Types.Handle -> String -> r
07:03 <geekosaur> you just have the function, the only thing you can do is apply it or wrap it in something else
07:03 <tswett> Um, that's not the type signature I was expecting.
07:04 <geekosaur> heh
07:04 ner0x652 joined
07:04 <geekosaur> I'm not sure what you were expecting, but I'd advise avoiding printf/hPrintf for examples
07:05 <geekosaur> it's a typeclass hack, it *will* confuse yoi
07:05 <geekosaur> *you
07:06 <tswett> grayhatter: so, the way hPrintf is being *used* is: hPrintf :: Handle -> String -> String -> String -> IO ()
07:06 neuromancer42 joined
07:07 <tswett> grayhatter: so you might be wondering, how does hPrintf turn all that stuff into an "IO ()"?
07:07 <grayhatter> I think I know. But I was very wrong about monads, so now I am
07:09 <tswett> grayhatter: want me to try to explain?
07:09 <grayhatter> tell me if I'm close
07:10 Raptor8m3 joined
07:10 <neuromancer42> Has anyone met this? I tried the `rpar` program in the `parconc-examples` package, the resulting time ranges from 0.86s-0.88s to 1.40s-1.46s. Is this normal?
07:10 <grayhatter> hPrintf is and IO function in of it self, and because it was called from (in a convoluted way) main. It's able to acces the IO in main
07:10 ystael joined
07:11 BartAdv joined
07:11 <grayhatter> so it's just passing the original IO of the binary back to main
07:11 <grayhatter> am I close?
07:11 travula_ joined
07:11 xcmw joined
07:11 <tswett> grayhatter: hmm... I'd say that sounds pretty close, at least.
07:12 <grayhatter> so I know where IO comes from, now how do I get Bot
07:12 <tswett> I would describe hPrintf as being "an IO function in and of itself", yeah. And because it's being called, in a convoluted way, from main, it's able to actually perform I/O actions.
07:12 <geekosaur> you don't get Bot
07:13 <geekosaur> not directly
07:13 <grayhatter> I get Net (), which is Bot -> IO
07:13 <geekosaur> you are being passed (a newtype of) a function, you are producing (a newtype of) a function
07:13 <geekosaur> the trick is, your function *takes* a Bot
07:13 <geekosaur> so you wrap it in a function that takes a Bot, and now you can invoke the function you are passed with that Bot and also do other things with it
07:14 <grayhatter> even thought it's not explicitly stating that?
07:14 <grayhatter> OH
07:14 <geekosaur> *now* you can go look at those two lines, particularly the first one
07:15 <geekosaur> I unwrapped the ReaderT to get the function, then wrote my own function to wrap around it that receives a Bot, invokes the ReaderT-d function with it, and then fmap-s the Bot into the result so it conforms to a StateT function... and wrapped that function in StateT
07:16 <geekosaur> since the ReaderT-d function produces IO a, I need to use fmap to push the tuple constructor with the copy of Bot "inside" the IO
07:16 M0r0nM4N joined
07:16 <geekosaur> (oh, btw, that code probably needs TupleSections extension, it can be rewritten without it though)
07:17 <tswett> grayhatter: had an epiphany?
07:17 <geekosaur> :t \(ReaderT r) -> StateT (\bot -> fmap (flip (,) bot) (r bot)) -- no longer needs TupleSections
07:17 <lambdabot> Functor m => ReaderT t m a -> StateT t m a
07:17 <grayhatter> tswett: yeah, it's like a python decorator
07:18 <grayhatter> (I hope)
07:18 <tswett> Hmm. I know about decorators in Python, but I'm not sure which connection you're seeing.
07:19 <grayhatter> the function isn't really getting called, it's being replaced with a monad, that dose "stuff" to the function, then returns what it wants
07:19 pleax joined
07:19 <grayhatter> in this case, Net ()
07:20 <geekosaur> no, the only way the monad is relevant is that we need fmap to get the copy of the Bot where it needs to be
07:20 <geekosaur> we're defining a wrapper function over the original one
07:21 <geekosaur> so we can intercept whatever Bot was being passed to the original one, and do something extra with it after passing it on to the original function
07:22 <geekosaur> :t \(ReaderT ?r) -> StateT (\bot -> fmap (flip (,) bot) (r bot))
07:22 <lambdabot> error: Parse error in pattern: ?r
07:22 <geekosaur> whoops
07:23 <geekosaur> :t \(ReaderT (r :: _)) -> StateT (\bot -> fmap (flip (,) bot) (r bot))
07:23 <lambdabot> error:
07:23 <lambdabot> • Found type wildcard ‘_’ standing for ‘t -> m a’
07:23 <lambdabot> Where: ‘m’ is a rigid type variable bound by
07:24 <geekosaur> deliberate error here :p
07:24 <tswett> Then it wasn't really an error, was it? :)
07:24 <geekosaur> it's only an error instead of a warning because it's in a :t
07:25 <tswett> I'm just making a joke based on the fact that by the ordinary definition of "error", there's no such thing as a deliberate error.
07:25 zar joined
07:26 <tswett> grayhatter: I need to go to bed. Hope I was able to help a little bit!
07:26 <grayhatter> you were
07:26 <grayhatter> I'm sitting here about to pass out myself
07:26 vlatkoB joined
07:26 <grayhatter> I think I need to come back to this tomorrow
07:26 <grayhatter> tswett: geekosaur thanks for you help guys
07:26 <geekosaur> r :: Bot -> IO a
07:27 <johnw> is Will Fancher here?
07:27 <geekosaur> \bot -> fmap (flip (,) bot) (r bot) :: Bot -> IO (a, Bot)
07:27 connrs joined
07:28 <geekosaur> the (r bot) is where I invoke the original function r with the Bot that my function receives, which is what r is expecting
07:29 <geekosaur> this produces an (IO a), but I need (IO (a,Bot)), so I use fmap to add to the IO chain something that turns a into (a,Bot) --- namely, flip (,) bot
07:29 <geekosaur> (,) is the 2-tuple constructor; it takes two parameters. I need bot to be the second, so I use flip to invert the parameters (,) receives (bot and a)
07:30 bjz joined
07:30 <geekosaur> (flip (,) bot) could also be written: \a b -> (b,a)
07:31 <geekosaur> so now I have a wrapper for a ReaderT function that is suitable to be a StateT function, and I can wrap it in the StateT constructor
07:32 Destol joined
07:35 zcourts_ joined
07:38 venkat24 joined
07:38 neuromancer42 left
07:39 hexagoxel joined
07:41 zariuq joined
07:41 neuromancer42 joined
07:42 fizruk joined
07:43 `Guest00000 joined
07:43 schjetne joined
07:51 soLucien joined
07:52 schjetne_ joined
07:53 marcopullo joined
07:53 danthemyth joined
07:53 electrostat joined
07:56 schjetne joined
07:57 xall joined
07:57 biglama joined
08:02 raichoo joined
08:03 marcopullo joined
08:03 neuromancer42 left
08:05 hazmat_ joined
08:10 ragepandemic joined
08:10 hexagoxel joined
08:11 calincru joined
08:11 ystael joined
08:12 mmn80 joined
08:13 schjetne joined
08:13 marcopul_ joined
08:14 Rizy joined
08:16 xmonader joined
08:17 schjetne joined
08:19 xinming_ joined
08:20 doudouwang12128 joined
08:20 pleax joined
08:21 doudouwang12138 joined
08:21 simukis__ joined
08:22 pasukon joined
08:22 kau joined
08:24 cschneid_ joined
08:27 deepfire` joined
08:27 sidei_ joined
08:28 permegreen joined
08:29 Kreest__ joined
08:30 sidei joined
08:30 doudouwang12563 joined
08:31 pleax joined
08:32 zero_byte joined
08:37 plutoniix joined
08:38 faberbrain joined
08:39 erisco joined
08:41 t0by joined
08:41 t0by joined
08:41 Rizy joined
08:41 doudouwang joined
08:42 Sh4rPEYE joined
08:42 hiThisIsMe joined
08:43 FreeBirdLjj joined
08:44 <Sh4rPEYE> Hi! I'm looking for a way to install and use IHaskell, because I love IPython. The problem is it depends on old version of packages... And I'm not really a hacker, so that was the final hurdle. Could somebody help me?
08:44 Jackneill joined
08:48 skeuomorf joined
08:50 permagreen joined
08:51 hazmat_ joined
08:52 ner0x652 joined
08:52 schjetne_ joined
08:55 simendsjo joined
08:55 wei2912 joined
08:57 merijn joined
08:58 sternmull joined
09:02 jutaro joined
09:03 <pacak> Sh4rPEYE: I think haskell works better if you use it as it supposed to be used. But if you have any specific errors - I can try to help
09:04 <jle`> pacak: what does that mean lol. is ihaskell not a legitimate way of using haskell?
09:04 owiecc joined
09:05 <geekosaur> I think you may want to try iHaskell from its git repo, the last release is a year old but git was last updated about a month ago
09:05 <pacak> jle`: I think tried using it a while ago. It's strange.
09:06 hexagoxel joined
09:06 <jle`> i don't think you can say that it's not how haskell is meant to be used, though
09:07 Dembel joined
09:09 <geekosaur> ghci isn't exactly how haskell was meant to be used either :p
09:09 xaviergmail joined
09:09 Detrumi joined
09:12 ystael joined
09:14 bab joined
09:16 ragepandemic joined
09:17 tsahyt joined
09:17 <dmwit> Sh4rPEYE: I installed iHaskell recently from the git repo following the instructions in their README. It seemed to work well, though you will need an older GHC; GHC 8 is not supported at the moment.
09:17 <tsahyt> are there examples of types that are both monads and comonads?
09:18 <dmwit> Writer
09:18 xall joined
09:18 tomphp joined
09:18 uglyfigurine joined
09:20 anton__ joined
09:20 <dmwit> Identity, I suppose
09:20 <tsahyt> I see
09:20 Kreest_ joined
09:21 FjordPrefect joined
09:22 cschneid_ joined
09:22 <dmwit> I bet you can make non-empty lists into a Monad. Perhaps they are a Comonad, too, in some way.
09:23 certainty joined
09:23 <edwardk> non-empty lists are a comonad, basically tails without [] in the result
09:23 <edwardk> with head as extract
09:23 <edwardk> aka Cofree Maybe
09:23 <dibblego> Tree
09:24 <tsahyt> edwardk: is there a particular reason why head is chosen as extract rather than say last?
09:24 <edwardk> tsahyt: see the streams package for the option to have both causal and anti-causal streams where it takes inits/last basically
09:24 <geekosaur> if it's nonempty then head is always defined. last may not be if it;'s an infinite list
09:25 <edwardk> but the short answer is performance, head is O(1), last is O(n)
09:25 <dmwit> last is fine for non-empty snoc lists ;-)
09:25 <edwardk> and also head (and tails) terminates for infinite streams
09:25 <tsahyt> well that makes sense of course
09:26 <edwardk> the streams package bundles nonempty snoc-lists for the causal last/init form and normal nonempty lists for anti-causal streams
09:26 mbuf joined
09:27 prophile joined
09:27 <edwardk> if you have no final entry like data Stream a = a :- Stream a -- then the monad is isomorphic to (Natural ->) -- its a zipping reader monad. and the comonad is basically Traced (Sum Natural) which is also Natural -> .... but ensuring the monoid used to glue together functions is (+)
09:28 <dmwit> Oh yes, byorgey has a nice post on Reader comonads and their connection to monoids.
09:28 <dmwit> So that's another good example.
09:28 <edwardk> watch out the co-reader is really (,) e so the terminology is a mess =
09:28 <edwardk> =P
09:28 <dmwit> Good thing I didn't say co-reader then!
09:29 <edwardk> hence why i picked arbitrary'ish names for the various comonad transformers in the comonad package
09:29 <edwardk> as CoFoo basically told you nothing
09:30 <edwardk> and showing that they are _actually_ dual turned out to be rather more difficult than expected, so i didn't believe it for a lon time =)
09:30 <edwardk> er long
09:32 tfc joined
09:32 sidei joined
09:32 tfc joined
09:32 marmalod1 joined
09:34 chaosmasttter joined
09:35 albertus1 joined
09:42 schjetne joined
09:43 boombanana joined
09:43 fetter_oml joined
09:43 louispan joined
09:44 silver joined
09:45 certainty joined
09:46 __main__ joined
09:47 sidei_ joined
09:48 schjetne_ joined
09:52 Cassiopaya joined
09:52 danvet joined
09:55 baldrick1 joined
09:58 thc202 joined
09:58 louispan joined
09:59 mszczygiel joined
10:03 Dembel joined
10:05 tsmish joined
10:06 uglyfigurine joined
10:07 Sh4rPEYE joined
10:08 oisdk joined
10:10 hexagoxel joined
10:11 <Sh4rPEYE> I have some connection issues, so I don't know if my last message got through: I'd like to learn Haskell on mac, preferably without a big IDE. I thought the notebooks might be the best way, but if I have to use old compiler with them... Not so clean and elegant anymore. What are the other options, and what are the best ones in your opinion?
10:12 <dmwit> I don't think that message got through before now.
10:12 <dmwit> Personally, vim+ghci has worked well for me.
10:13 ystael joined
10:13 <dmwit> Some folks like ghcid. There are also various integrations with vim and emacs, but I don't really use them much.
10:13 <infinity0> is there a way to specify your own wrap-operators like [] ?
10:13 <dmwit> Not really. There are quasiquoters, which would let you write `[myOp| ... |]`.
10:14 <dmwit> You define `myOp`.
10:14 tsmish joined
10:14 <dmwit> But they are quite heavyweight compared to other operators in Haskell: you have to do your own parsing of `...`, for example.
10:14 <Sh4rPEYE> I'm not really profficient with vim/emacs.
10:14 ericsagnes joined
10:14 <infinity0> ah, ok
10:15 <dmwit> There is also a somewhat standard trick for multi-arity infix operators, in case you haven't seen it you might find it sufficient.
10:15 <dmwit> > let (-|) = (,); (x, y) |-> z = 100*x + 10*y + z in 3 -|4|-> 5
10:15 <lambdabot> 345
10:16 <Sh4rPEYE> I'll probably stick to VSCode + ghci. Thanks for help though :-)
10:16 Rizy joined
10:16 <infinity0> dmwit: i see thanks, i'll have a play with it :)
10:17 hackebeilchen1 joined
10:19 <Sh4rPEYE> And somewhat off-topic question. I'll use the Haskell Proramming book + do some Rosalind excersizes. Is there some Haskell algorithms/cookbook you could recommend for a beginner?
10:19 t7 joined
10:19 JeanCarloMachado joined
10:19 <dmwit> Folks often recommend RWH, which I would classify very much as cookbook-style.
10:19 <dmwit> ?where RWH
10:19 <lambdabot> http://www.realworldhaskell.org/blog/ http://book.realworldhaskell.org/read/
10:20 <Sh4rPEYE> Somewhere I read is outdated... It's from 2008, isn't it
10:20 <Sh4rPEYE> If you say it'ß useable still, better for me :-D
10:20 <sm> there's HTAC, https://leanpub.com/haskell-cookbook
10:20 hackebeilchen joined
10:20 <dmwit> There are a few chapters that obsoleted themselves by becoming Hackage packages.
10:21 <Sh4rPEYE> Ok, thanks
10:23 hackebeilchen1 joined
10:24 _ashbreeze_ joined
10:25 hackebeilchen joined
10:28 hackebeilchen2 joined
10:30 louispan joined
10:31 marfoldi joined
10:33 louispan joined
10:35 Maxdamantus joined
10:35 osa1_ joined
10:38 louispan joined
10:39 leat joined
10:40 faberbrain joined
10:43 fizruk joined
10:43 louispan joined
10:47 Enigmagic joined
10:47 lep-delete joined
10:47 xcmw joined
10:47 pleax joined
10:50 jaseemabid joined
10:51 g0d355__ joined
10:52 <jaseemabid> I've a monad transformer stack with State and Either; `type Result a = StateT Env (ExceptT String Identity) a`. I'm absolutely lost on how to run this transformer and extract the value a. Any pointers? I've been starting at incomprehensible mil errors since last ~4 hours.
10:53 <* jaseemabid> needs help
10:54 <jaseemabid> I couldn't make any of the `runStateT` or `runExceptT` examples work so far.
10:56 danthemyth joined
10:56 <mauke> :t runExceptT
10:56 <lambdabot> ExceptT e m a -> m (Either e a)
10:56 <mauke> :t runStateT
10:56 <lambdabot> StateT s m a -> s -> m (a, s)
10:57 <mauke> :t runIdentity (runExceptT (runStateT ?foo ?env))
10:57 <lambdabot> (?foo::StateT s (ExceptT e Identity) a, ?env::s) => Either e (a, s)
10:58 <jaseemabid> mauke, The types _sort of_ makes sense, but I've probably tried all combinations of it by now :/
10:59 <mauke> what do you mean, combinations
10:59 <mauke> what I typed there is how you do it
10:59 _ashbreeze_ joined
11:00 osa1 joined
11:01 owiecc joined
11:01 <chilversc> what exactly is the context in a tpye signature? this mentions it but does not explain it https://wiki.haskell.org/Type_signature
11:02 <mauke> basically a list of class constraints
11:02 bjz joined
11:02 prkc joined
11:02 <mauke> in the example Num a means that a has to be an instance of Num
11:03 <jaseemabid> Ah. So you runStateT and get rid of the state and get the except value. The runExceptT and get the Either and then runIdentity to get the `a`
11:03 <chilversc> so why isn't that just, [t] -> Num a; instead of Num a => [t] -> a?
11:03 bennofs joined
11:03 <chilversc> or, [t] -> Num ?
11:03 <jaseemabid> mauke, Something like `runIdentity $ runExceptT $ runStateT (progn undefined) undefined` gives me `Either String (Scheme, Env)`; which is close enough to what i wanted
11:03 dev-Zero_ joined
11:03 <mauke> jaseemabid: no, you get Either String (a, Env)
11:04 qqwy joined
11:04 <mauke> there isn't necessarily an 'a' in there
11:04 <qqwy> Good morning everyone!
11:04 <mauke> chilversc: because Num isn't a type
11:04 <jaseemabid> mauke, Yeah. The a is a fixed type Scheme for me here.
11:05 <mauke> :t evalStateT
11:05 <lambdabot> Monad m => StateT s m a -> s -> m a
11:05 <mauke> ^ if you don't care about the final state
11:05 <mauke> but you still have to deal with the absence of Scheme because of ExcepT
11:05 <mauke> +t
11:05 <qqwy> I am looking for a function that does `Data.List.inits` and `Data.List.tails` at the same time (for clarity: [a] -> [([a],[a])])
11:06 <qqwy> That is, it returns all the different ways to split a list into two sublists
11:06 <ski> chilversc : `Num' is not a concrete type. it's a type predicate. `[t] -> Num a' and `[t] -> Num' are nonsense, doesn't kind check
11:06 <mauke> :t inits &&& tails
11:06 <lambdabot> [a] -> ([[a]], [[a]])
11:07 <qqwy> :t foo list = zip (heads list) (tails list)
11:07 <lambdabot> error:
11:07 <lambdabot> parse error on input ‘=’
11:07 <lambdabot> Perhaps you need a 'let' in a 'do' block?
11:07 <mauke> :t uncurry zip . inits &&& tails
11:07 <lambdabot> error:
11:07 <lambdabot> • Couldn't match type ‘[[a1]]’ with ‘([a], [b])’
11:07 <lambdabot> Expected type: [a1] -> ([a], [b])
11:07 <qqwy> :t let foo list = zip (heads list) (tails list)
11:07 <lambdabot> <no location info>: error:
11:07 <lambdabot> not an expression: ‘let foo list = zip (heads list) (tails list)’
11:07 <mauke> :t uncurry zip . (inits &&& tails)
11:07 <lambdabot> [a] -> [([a], [a])]
11:07 <qqwy> Obviously I am looking for something that computes both of them at the same time, rather than iterating twice over the list.
11:08 <qqwy> ^^'
11:08 <qqwy> By the way, where is `&&&` defined? Applicative or something?
11:08 <mauke> @hoogle &&&
11:08 <lambdabot> Control.Arrow (&&&) :: Arrow a => a b c -> a b c' -> a b (c, c')
11:08 <lambdabot> Data.Constraint (&&&) :: (a :- b) -> (a :- c) -> a :- (b, c)
11:08 <lambdabot> Data.Tuple.Extra (&&&) :: (a -> b) -> (a -> c) -> a -> (b, c)
11:09 <jaseemabid> mauke, that seems to have worked. Thanks a lot :)
11:09 <chilversc> ah, so Num a =>; says that a will be some kind of number, with out restricting it to be an Int
11:10 <* qqwy> is astonished by @lambdabot's prowess
11:10 <qqwy> Thank you, mauke!
11:11 nomotif joined
11:11 <ski> @type let split xs = ([],xs) : case xs of [] -> []; x:xs -> map (first (x:)) (split xs) in split
11:11 <lambdabot> [t] -> [([t], [t])]
11:11 <ski> @type let split [] = [([],[])]; split xs0@(x:xs) = ([],xs0) : map (first (x:)) (split xs) in split
11:11 <lambdabot> [t] -> [([t], [t])]
11:11 sunnny joined
11:12 <ski> chilversc : yep
11:13 <mauke> :t (==)
11:13 <lambdabot> Eq a => a -> a -> Bool
11:14 ystael joined
11:14 Rizy joined
11:14 <qqwy> :t first
11:14 <lambdabot> Arrow a => a b c -> a (b, d) (c, d)
11:15 Unhammer joined
11:15 <ski> instead of `first (x:)', i could have said `\(front,back) -> (x:front,back)'
11:15 <qqwy> Wow
11:15 <qqwy> Where can I read more about how to work with the Control.Arrow functions?
11:16 <ski> (or one could use a list comprehension)
11:16 <qqwy> they look so useful
11:16 <qqwy> although slightly obfuscating, possibly ^^'
11:16 <mauke> replace all 'Arrow a' by '->'
11:16 <mauke> that's the only thing I use them for anyway
11:16 <qqwy> Thank you very much, ski!
11:17 bab joined
11:17 <qqwy> So Control.Arrow contains all kinds of magic functions to alter the way you can sequence functions together?
11:17 <ski> qqwy : lists can be used for "nondeterministic computation". `split' above is an example of that, computing all possible ways to cut a list in two pieces
11:17 <qqwy> mind = blown
11:18 <ski> `Control.Arrow' contain a few handy functions for writing pointless code
11:19 nek0 joined
11:19 <ski> ("pointless", or "pointfree", as opposed to "pointful", because the "points", i.e. the input values on which the functions operate, aren't visible. the most basic such functions are `id', the identity function, and `(.)', function composition. there's also `const' and `flip' in the `Prelude')
11:20 <ski> @src (->) first
11:20 <lambdabot> first f = f *** id
11:20 <ski> @src (->) (***)
11:20 <lambdabot> (f *** g) ~(x,y) = (f x, g y)
11:20 <qqwy> @src ~
11:20 <lambdabot> Source not found. Just what do you think you're doing Dave?
11:20 sid_fules joined
11:20 <ski> that's lazy pattern-matching
11:21 <ski> it can sometimes make a difference
11:21 <qqwy> O_O Lazy... pattern matching? Wow
11:21 <ski> it delays the matching of the pattern it is applied to, until a variable bound by that pattern is demanded (forced)
11:21 <qqwy> Does it matter for efficiency, or is it mostly to have correct handling of _|_ ?
11:22 <ski> and then the pattern had better match, since otherwise you get a run-time failure (as opposed to trying the next alternative, which would happen if you didn't use `~')
11:22 <ski> sometimes it's the difference between terminating and nonterminating code
11:22 <ski> i'm not sure whether you count that among the former, the latter, or both :)
11:22 <qqwy> Ah, so it is like saying "trust me, it will match, but since you'll only need the result later, lets not expand it yet"
11:23 <ski> right
11:23 <qqwy> True, true :')
11:23 <ski> @src partition
11:23 <lambdabot> partition p xs = foldr (select p) ([],[]) xs
11:23 <lambdabot> where select p x ~(ts,fs) | p x = (x:ts,fs)
11:23 <lambdabot> | otherwise = (ts, x:fs)
11:23 <ski> > (take 4 *** take 4) (partition even [0 ..])
11:23 <lambdabot> ([0,2,4,6],[1,3,5,7])
11:24 <ski> @let partition' p xs = foldr (select p) ([],[]) xs where select p x (ts,fs) | p x = (x:ts,fs) | otherwise (ts,x:fs)
11:24 <lambdabot> Parse failed: Parse error: EOF
11:24 constarwu joined
11:24 <ski> @let partition' p xs = foldr (select p) ([],[]) xs where select p x (ts,fs) | p x = (x:ts,fs) | otherwise = (ts,x:fs)
11:24 <lambdabot> Defined.
11:24 <ski> > (take 4 *** take 4) (partition' even [0 ..])
11:24 <lambdabot> (*Exception: stack overflow
11:24 <ski> this is an example where the lack of `~' causes nontermination
11:25 <ski> since without `~', it waits to produce an output element until it has traversed to the end -- which will never happen with an infinite list
11:26 <qqwy> Ah, because it tries to fill in the pattern match at that time
11:26 <qqwy> even though you might only use part of that match later on
11:26 <qqwy> Nice! Very important to know
11:26 <ski> the problem is that if we force the matching of the pattern `(ts,fs)' right now, that will force the recursive call in `foldr' right now, which runs down an infinite path in a tree, with no return
11:26 <ski> but with `~' on that pattern, it works out fine
11:27 <ski> (the `take 4 *** take 4' is just a quick way to cut off the ends of the two result lists, in order to see that you get results for both lists. otherwise it would never get to showing the second list, since the first (and second) are infinite)
11:29 <ski> qqwy : if you're doing tying-the-knot tricks, passing back an output of a call as an input to the same call, then often `~' can also be critical
11:29 <ski> (e.g. if you're using `fix' to produce a pair .. of two lists or whatever)
11:30 <qqwy> Awesome
11:30 <ski> > (take 4 *** take 4) (fix (\ ~(xs,ys) -> (0:ys,map (1+) xs)))
11:30 <lambdabot> ([0,1,2,3],[1,2,3,4])
11:30 <ski> > (take 4 *** take 4) (fix (\(xs,ys) -> (0:ys,map (1+) xs)))
11:30 <qqwy> My 'tying the knot' has until now been only about building simple cyclic structures, as well as an on-line longest common subsequence algorithm
11:30 <lambdabot> mueval-core: Time limit exceeded
11:31 <qqwy> marvellous stuff :D
11:32 <qqwy> Please enlighten me: How can you write `foo list = zip list (tail list)` using pointless style?
11:32 mmn80 joined
11:32 <AWizzArd> Is there a compiler switch that turns on warnings when I introduce a local var which shadows another one?
11:32 <ski> @pointless foo list = zip list (tail list)
11:32 <lambdabot> foo = ap zip tail
11:32 <ski> @quote zip`ap`tail
11:32 <lambdabot> quicksilver says: zip`ap`tail - the Aztec god of consecutive numbers
11:33 nakal joined
11:33 <qqwy> @type ap
11:33 <ski> that's using the `(a ->)' instance of `Monad'
11:33 <lambdabot> Monad m => m (a -> b) -> m a -> m b
11:33 <ski> replace `m' there with `(rho ->)', say, and you get `(rho -> a -> b) -> (rho -> a) -> (rho -> b)'
11:33 <ski> this is also known as the "S combinator" (see SKI combinators)
11:34 <qqwy> :D!!!
11:34 <ski> @type liftA2 zip id tail -- one can also do this
11:34 <lambdabot> [a] -> [(a, a)]
11:35 <ski> (or with `liftM2' instead of `liftA2')
11:35 lukaramu joined
11:35 <qqwy> Actually we only need the applicative instance of (a -> ) here, right?
11:36 <ski> (`const' is the `K' combinator, and `id' the `I' combinator. `flip' is the `C' combinator, and `(.)' the `B' combinator)
11:36 <ski> yes
11:36 <ski> the applicative version of `ap' is `(<*>)'
11:36 <qqwy> Ah, of course
11:36 <ski> `ap' was invented before `Applicative'
11:36 <qqwy> I've seen that one before
11:37 robotroll joined
11:37 <ski> AWizzArd : try `-fwarn-name-shadowing' ?
11:38 caumeslasal joined
11:38 <ski> anyway, the `pointless' (`pl' for short) lambdabot command quite often produces unreadable incantations
11:39 Gurkenglas joined
11:39 <ski> usually i prefer deriving the incantation myself
11:40 mohsen_ joined
11:40 <ski> @type join id
11:40 <lambdabot> error:
11:40 <lambdabot> • Occurs check: cannot construct the infinite type: m ~ (->) (m a)
11:40 <lambdabot> Expected type: m (m a)
11:41 Berra joined
11:41 <ski> oh, sorry, not `id'
11:41 sidei__ joined
11:41 <ski> @type \f x -> join f x -- forcing it to set `m' to `(t ->)'
11:41 <lambdabot> (t -> t -> t1) -> t -> t1
11:42 cspollard joined
11:42 <ski> in pointless incantations, this use of `join' is quite common
11:42 nmattia joined
11:42 <qqwy> I love how these are called incantations :-)
11:43 <qqwy> @type join
11:43 <lambdabot> Monad m => m (m a) -> m a
11:43 <qqwy> Ah, yes, of course, that one
11:44 <ski> there's a fine line between a nice or cute pointless expression, and one which risks being incomprehensible or requiring too much thought to decipher
11:45 <ski> this line isn't in the same place for everybody, but it exists nonetheless. one shouldn't make code too pointless
11:45 <ski> some people may be comfortable reading `(foo .) . bar . (baz .)', say; while some won't
11:46 <qqwy> I wholeheartedly agree
11:46 <ski> a lot of the pointless expressions people show in here wouldn't be put in actual (non-throwaway) code
11:46 <ski> but it can serve as a kind of mental gymnastics
11:48 <ski> @where SEC
11:48 <lambdabot> http://conal.net/blog/posts/semantic-editor-combinators/
11:48 <ski> might also be relevant, here
11:50 JeanCarloMachado joined
11:51 ziocroc2 joined
11:55 bernouli joined
11:55 mr_sm1th joined
11:56 danthemyth joined
11:58 Dembel joined
11:59 <qqwy> @ps
11:59 <qqwy> currentProblemCost (lhs, rhs) = (fst (head lhs)) * fst (head rhs) * snd (last rhs)
11:59 <lambdabot> (line 1, column 1):
11:59 <lambdabot> unexpected end of input
11:59 <lambdabot> expecting white space, "()", natural, identifier, lambda abstraction or expression
11:59 cyborg-one joined
11:59 <qqwy> @ps currentProblemCost (lhs, rhs) = (fst (head lhs)) * fst (head rhs) * snd (last rhs)
11:59 <lambdabot> currentProblemCost = uncurry ((`ap` (snd . last)) . ((*) .) . (. (fst . head)) . (*) . fst . head)
12:00 <qqwy> Indeed, that becomes unreadable very quickly
12:00 <qqwy> ^^"
12:04 ph88 joined
12:05 laserpants joined
12:05 Jackneill joined
12:07 <laserpants> I am looking at this wiki page: https://wiki.haskell.org/The_Fibonacci_sequence where it says "The fix used here has to be implemented through sharing, fix f = xs where xs = f xs, not code replication, fix f = f (fix f), to avoid quadratic behaviour."
12:07 <ph88> hi all
12:08 <ph88> can someone help me with lens ?
12:09 <ph88> i have this code http://lpaste.net/353242 and now instead of maximmum i like to search the structure with a predicate, and then change the value of the last value that matches the predicate and then get the same structure back with that one value changed
12:09 <laserpants> Why does the latter lead to quadratic behaviour?
12:09 <ski> currentProblemCost = uncurry (*) . second (uncurry (*)) . ((fst . head) *** (fst . head) &&& (snd . last)) -- qqwy
12:11 <chilversc> bah, just spent 10 minutes trying to see why it wasn't working only to realise I had [x:xs] not (x:xs)
12:11 <cocreature> ph88: are you looking for "findOf"?
12:12 <cocreature> oh no nvm
12:12 <ph88> cocreature, not sure what functions to use and how .. i saw a few functions that possibly can be of help like lastOf and holesOf
12:13 soLucien joined
12:13 <cocreature> ph88: the problem with lastOf is that it only allows you to get the value not modify it
12:13 <cocreature> ph88: "filtered" is close but it will modify all values that match the predicate not only the first one
12:14 <ph88> cocreature, yes i saw this too by the description of the functions .. but i don't know how to do it and which functions to use
12:14 ystael joined
12:15 <ski> laserpants : iiuc, with the "replication" version, you get repeatedly nested calls `scanl', deeper and deeper the longer you go. cf. left-associated `(++)'
12:15 JagaJaga joined
12:16 <cocreature> > over (traverse . filtered even) (+1) [1,2,3,4]
12:16 <lambdabot> [1,3,3,5]
12:16 <cocreature> ph88: so that’s how you modify all values matching a predicate
12:16 <cocreature> I’m not sure how to restrict it to the first one
12:16 <cocreature> (or the last one)
12:16 <laserpants> ski: i see ..
12:17 <ski> with sharing, you only have one `scanl' call active at any time
12:17 kuribas joined
12:18 <ph88> cocreature, ya me neither .. i've looked throught the functions and the only function i could find related to last value is lastOf, and as you say it's not the right function for me :(
12:20 <Cale> > over (singular (traverse . filtered even)) (+1) [1,2,3,4]
12:20 <lambdabot> mueval-core: Time limit exceeded
12:20 <Cale> > over (singular (traverse . filtered even)) (+1) [1,2,3,4]
12:20 <lambdabot> [1,3,3,4]
12:20 augur joined
12:20 rotcpy joined
12:21 <ph88> Cale, that looks nice, but i would like to change the last value, not the first
12:21 FullyFunctional joined
12:21 Gurkenglas joined
12:22 sid_fules joined
12:24 <AWizzArd> Is there a way to allow multiple objects in case cases?
12:24 magneticduck joined
12:24 <cocreature> AWizzArd: you can match on a tuple of the values
12:24 <AWizzArd> case x of … if x is 1 or 2 or 3, *then* I want to return x+10
12:25 <Cale> case x of _ | x `elem` [1,2,3] -> ...
12:25 <sternmull> or a let-binding that is used by all the cases
12:27 <ski> unfortunately no disjunctive patterns in Haskell
12:27 lep_ joined
12:27 <cocreature> luckily osa1 is working on implementing them so we might get them in 8.4 :)
12:27 <AWizzArd> I also read about -XMultiWayIf
12:28 <osa1> cocreature: I'm working on that right now :)
12:28 mohsen_ joined
12:28 <cocreature> osa1: thanks for doing that! I’m really looking forward to using it
12:29 <ski> osa1 : the binding set being the intersection of the ones of the child patterns, yes ?
12:29 <ski> or requiring them to have the same binding set ?
12:30 <osa1> ski: yes
12:30 <ski> which ? :)
12:30 <osa1> ski: including coercions and existentials
12:30 <osa1> all sub-patterns must bind same variables, coercions and existentials included
12:30 <ski> no local guards, i guess
12:31 augur joined
12:31 <ski> i suppose there's no work on generalizing `@' to conjunctive patterns (e.g. useful with views) ?
12:31 <osa1> guards are same as before except there are two possible semantics depending on whether you want to try other alternatives or not in case of a guard match failure
12:31 <osa1> I'm not sure what does local guards mean though
12:32 <ski> well, i'd opt for trying the other alternative ..
12:32 Elish joined
12:33 <osa1> I'm currently implementing that version. extending the formal semantics for that is harder but in the implementation it's about the same in terms of implementation complexity
12:33 <ski> i mean like `(Left (x,y) when x >= 0) | (Right (_,y,_))', if `|' here is disjunctive pattern, and `when' is a local guard
12:33 <osa1> oh right. no that's not in the roadmap
12:33 <ski> `x' here is only available for use in the local guard
12:33 <* ski> nods
12:34 <osa1> conjunctive patterns would also be interesting. I'm guessing that you can only specify the shapes in those patterns, right? i.e. no bindings
12:35 <osa1> or you could do something like a non-linear pattern e.g. you can use same variable multiple times and those desugar to `(==)` guards
12:36 <ski> on this topic, one could also consider patterns `if <expr> then <pat> else <pat>' (and similarly with `case') and `let <expr> = <pat> in <pat>'. the `let' pattern here matching the value with the body pattern, binding variables which are used to evaluate the expression, which is matched with the other pattern
12:37 <ph88> be right back
12:38 <ski> osa1 : consider `(viewl -> x :> xs) @ (viewr -> ys :< y)'
12:38 oisdk joined
12:39 <ski> er, flip `:>' and `:<'
12:39 k0001_ joined
12:40 <osa1> if I understand correctly that's like `| x :> xs <- viewl <fresh>, ys :< y <- viewr <fresh> -> ...` where <fresh> is the argument, right?
12:41 <ski> (also slightly related is allowing `if',`case', and `let' (in SML, this is `local'-`in'-`end') as declarations)
12:41 xaviergmail joined
12:41 roxxik joined
12:41 dmwit_ joined
12:41 <ski> osa1 : yes
12:41 <ski> using view patterns (or pattern synonyms) is the main use for conjuctive patterns, afaik
12:41 ph88 joined
12:42 <osa1> interesting. you know any languages that support conjunctive patterns?
12:42 faberbrain joined
12:42 <ski> hm .. Mercury, i think
12:43 bjz_ joined
12:43 <ski> right, <https://www.mercurylang.org/information/doc-latest/mercury_ref/Unification-expressions.html>
12:44 <ski> this is in some sense "easier" in Mercury, since there's no syntactic distinction between patterns and expressions there
12:44 <ski> (otoh, there's a static analysis and checking mechanism of insts and modes (and determinisms) to make up for this)
12:46 epsilonhalbe joined
12:46 <ski> i've wanted `let' for declarations many times in Haskell. `if'/`case' also some times
12:47 <ski> `if' and `let' as patterns is more a thought-experiment, to see how much of expression constructions one can sensibly bring over to patterns
12:47 djfo joined
12:48 <ski> .. i've also pondered allowing (certain stylized uses of) `case' for definiendums (left-hand-sides)
12:48 <ph88> ski, yesterday i read something fascinating
12:49 <ph88> that type system is related to logic programming
12:49 <ski> yes
12:49 <ph88> https://en.wikibooks.org/wiki/Haskell/The_Curry%E2%80%93Howard_isomorphism
12:49 <ph88> i already had a feeling about this
12:49 <ski> unification is a core part of logic programming
12:49 mimi_vx_ joined
12:50 <ski> when reading type system inference rules, it helps to have some experience with logic programming. especially knowing about multiple modes of predicates
12:50 <cocreature> curry-howard is not really about logic programming, it’s about constructive logic
12:50 esad joined
12:50 <ph88> i want to get into logic programming too
12:50 <ph88> it seems very useful
12:51 <ski> i'd suggest starting with Prolog, despite it being old and having many flaws
12:51 <ski> most of the learning material is in terms of Prolog, or a Prolog-derivative
12:51 <ph88> look at this https://www.youtube.com/watch?v=eQL48qYDwp4 ski
12:51 ncyellow joined
12:51 twanvl joined
12:52 <ph88> ski, yeah i saw there are quite a few interesting language, some people like mercury or logtalk, but maybe just prolog is the best because of being the most well known
12:52 <ski> Mercury <https://www.mercurylang.org/> is a more modern logic programming language, also supporting functions, having a module system (!), static type checking, parametric polymorphism, algebraic data types, type classes, existentials, &c.
12:52 mimi_vx_ joined
12:52 <ph88> ya i know
12:53 oish joined
12:53 <cocreature> minikanren is also worth a look because of its simplicity
12:53 <ph88> seems attractive
12:53 <ph88> i actually found a implementation of minikanren in php :P
12:53 <ph88> watch that youtube though, it's very interesting
12:54 <ski> however, Mercury is also less flexible than Prolog. some things are harder or impossible to do in Mercury, that are easy or possible in Prolog
12:54 <dmiles> hrrm "Propositions are types" .. but are "Types actually Propositions"?
12:54 <ski> otoh, it's easier to get into trouble in Prolog, due to dynamic type checking, no static mode, determinism (especially this) checking
12:54 <ski> you might perhaps find "Re: Mercury in academic teaching?" by Richard A. O'Keefe in 2006-10-(09|10) at <http://www.mercurylang.org/list-archives/users/2006-October/004000.html>,<http://www.mercurylang.org/list-archives/users/2006-October/004011.html> interesting re which to start learning
12:55 <* ski> also finds those posts interesting from a more general standpoint
12:55 <ski> dmiles : in a generalized sense, they are :)
12:55 <ph88> ski, you wanna write a game bot with me with prolog ?
12:56 robotroll joined
12:57 danthemyth joined
12:57 <ski> there's also the language Oz <http://mozart.github.io/>,<http://mozart.github.io/mozart-v1/doc-1.4.0/>, which is used in the book
12:57 <ski> @where CTM
12:57 <lambdabot> "Concepts, Techniques, and Models of Computer Programming", by Peter Van Roy,Seif Haridi, at <http://www.info.ucl.ac.be/~pvr/book.html>
12:58 <ski> which can be considered as a kind of update on SICP. it teaches different programming paradigm (of interest is e.g. "declarative concurrency", using dataflow variables for synchronization and communication between threads of execution)
12:59 ph88 joined
12:59 <ski> Oz is at the core a logic programming language (without backtracking), onto which layers have been added to support more paradigms
12:59 <ph88> got d/c for a moment ^^
12:59 oish joined
13:00 <dmiles> i wonder how OZ compares to Poplog
13:00 <ski> of interest here is also Constraint Programming. which is perhaps most easily handled in combination with Logic Programming : Constraint Logic Programming (CLP)
13:00 <* ski> should check out Poplog some time
13:00 <ph88> i think not too many things at once :P
13:00 tsmish joined
13:01 <ph88> ski, have you tried clingo? i'm trying to find some opinions on it
13:03 mimi_vx_ joined
13:03 <ski> dmiles : in a restricted sense, propositions can be seen as those types that have at most one proof (and where biimplication implies equality)
13:05 stef204 joined
13:07 <dmiles> ski: hrm.
13:08 <dmiles> ph88: oh neat clingo website pointed out to me that ASP has a standardization effort
13:08 <ski> functional programming corresponds to proof reduction (simplification). logic programming corresponds to proof search
13:08 <ski> ph88 : haven't heard of clingo
13:09 MindlessDrone joined
13:09 <* ski> . o O ( <https://en.wikipedia.org/wiki/Answer_set_programming> )
13:09 <ph88> ski, https://potassco.org/
13:09 <dmiles> ASP is very easy to implment in prolog
13:10 <dmiles> so something i should study is extra things prolgo forgot
13:10 <ph88> then what does it offer on top of prolog ?
13:10 <ph88> it seems some people went out and invented some really cool new stuff
13:10 <ph88> but what is good about it ?
13:11 <ski> dmiles : .. when i say "at most one proof", i mean basically "at most one canonical / most reduced proof". there's an equational theory of proofs (being functional programming, more or less), that explains when two proofs are equivalent (equal)
13:11 <dmiles> ph88: well ASP simplies prolog qand in doing that i belive frees it up to add new features
13:12 <dmiles> simplifies*
13:12 <Hafydd> ph88: ASP is more suitable for hard problems, requiring very large sets of possible solutions to be searched, than Prolog is.
13:12 FullyFunctional left
13:12 paolino joined
13:13 <dmiles> ski: hrrm i see some benefit then i think
13:13 <ski> logic programming results from making the proof search more efficient and predictable, by introducing a focus, and by restricting the allowed classes of formulae to keep completeness in spite of the restriction on the search strategy
13:14 <dmiles> (i mean often the things i need to do in logic (though its more the logicains problem) is prove two instances are of the same type.. i suppose that would meant they had the same proofs
13:14 <dmiles> )
13:14 emc2 joined
13:15 ystael joined
13:15 <dmiles> ski: was that last sentence about ASP or C-H ?
13:16 <ski> (re minikanren, also see the book "The Reasoned Schemer")
13:16 <Hafydd> ph88: http://www.cs.uni-potsdam.de/~torsten/Papers/asp4ki.pdf is a good introduction.
13:16 <dmiles> (ok yeah i interpreted your last statement about relatinal programing :P )
13:16 <ski> well. more related to C-H, i suppose. though i didn't read about it in connection to that
13:17 <ski> dmiles : some of the papers on lambdaProlog talks more about how to see logic programming as relating to proof search
13:18 <ph88> Hafydd, i already saw a pretty extensive introduction, but since i don't know prolog i don't know what are the differences between them
13:19 sidei joined
13:19 sidei_ joined
13:19 sidei__ joined
13:20 <* ski> . o O ( attribute grammars )
13:20 jmcarthur joined
13:23 <dmiles> hrrm figure 21 of http://www.cs.uni-potsdam.de/~torsten/Papers/asp4ki.pdf is awesome.. i didnt know ASP undertstand it needed to have multiple understands of negation
13:24 <dmiles> didnt know ASP undertstood we needed to have multiple understandings of strong negation
13:24 ompaul joined
13:25 <dmiles> oh yeah cardinality contraints ASP is free to have (beyond prolog)
13:26 wei2912 joined
13:26 ninja_in_neopren joined
13:27 <dmiles> also lack of clause order prefernce in ASP is not avaiable in prolog (unless one really codes it)
13:27 soLucien joined
13:27 zygentoma joined
13:28 <ph88> no idea what you're talking about :P
13:28 <kritzcreek_> How would I write a Recognizer with lexer-applicative that recognizes `<-` not followed by another symbol character and differentiates it from `<->`
13:28 <kritzcreek_> ?
13:29 <dmiles> Well what i am saying ph88, is ASP does offer some things that prolog by default makes hard to implment
13:29 <ph88> sounds good :P
13:30 xcmw joined
13:30 <dmiles> but i been implementing those hard things :P.. so gawd.. i think i migh have ASP soon
13:31 Rizy joined
13:31 dev-Zero_ joined
13:31 <ph88> dmiles, please keep me posted about your experiences !
13:32 <ph88> i have to go, bye guys
13:32 gcross_ joined
13:33 <dmiles> oh very neat https://www.mat.unical.it/ricca/aspide/
13:33 <Hafydd> Knowing ASP but not Prolog is a pretty high level of programming hipster.
13:34 lukaramu_ joined
13:34 <dmiles> well from what i can tell ASP is slightly less crippling that Datalog might be
13:34 <kgadek> FYI: https://www.reddit.com/r/rust/comments/5yo24a/meta_rust_jealousy/
13:34 <kgadek> > So I just met Simon Peyton Jones (creator of Haskell) and chatted with him for a bit. Asked him his thoughts on Rust and he said he thinks it seems exciting and he was jealous of the great community we have. Just thought I would let you guys know :)
13:34 <lambdabot> <hint>:1:43: error: parse error on input ‘of’
13:34 sid_fules joined
13:35 <dmiles> (i am ony assuming though at this point)
13:36 <dmiles> Crippling = how hard it is to write applications
13:39 desku joined
13:40 mkbucc joined
13:40 <dmiles> Less Crippling = if i had a prolog prgram if it is possible to port to ASP standard
13:40 Wizek joined
13:40 Wizek_ joined
13:42 BartAdv joined
13:45 sdothum joined
13:46 dev-Zer__ joined
13:49 HoierM joined
13:50 revtintin joined
13:51 Rizy joined
13:51 jomg joined
13:53 ThomasLocke joined
13:54 teppic joined
13:56 <Hafydd> data Crippling =
13:57 <Hafydd> You can't port Prolog effects to ASP...
13:58 steeze joined
13:58 <dmiles> Like no assert/retract ?
13:59 <Hafydd> I mean things like I/O.
14:00 <dmiles> ah
14:00 <Hafydd> But I'm sure there are other Prolog semantics that would not be trivial to port, like cutting.
14:00 <dmiles> is "Ordered Disjunction" a way to create clauses that stop (sort of like cut) ?
14:02 <dmiles> i was assuming it starts and running the disjuct list and on first success it cuts
14:02 oisdk joined
14:02 <dmiles> i was assuming it starts out running over the disjuncts and on first success, it stops (therefore like a cut)
14:03 <Hafydd> No, in principle it finds all solutions, although you might only look at the first one. In that way, I suppose ordered disjunctions might do something vaguely similar to cutting.
14:03 thunderrd joined
14:04 ner0x652 joined
14:05 <dmiles> Can compund terms be put inside pred arguements?
14:06 <Athas> Urgh, for the first time, I've been bitten by the Foldable/Traversable integration with the Prelude.
14:07 <Hafydd> dmiles: yes. The ASP solver first expands all possible ground terms, possibly including nested terms, and instantiates each rule with each assignment of terms.
14:08 <Hafydd> (For this reason, the set of ground terms must be finite.)
14:08 fizruk joined
14:08 <dmiles> are there anonmous unyfiers? like _ ?
14:09 mbuf joined
14:09 <dmiles> are there anonymous unifiers like loves(joe,_).
14:10 raynold joined
14:10 <dmiles> (i meant it as a dont care .. in one system that is truely "dont care" i might want to treat Prop= loves(joe,_), knows(sue,Prop).
14:11 <dmiles> )
14:11 <Hafydd> dmiles: I don't know about newer versions of Clingo, but those weren't in the version I used; and if they are, they would be a syntactic sugar.
14:11 <Hafydd> dmiles: it would have to expand to something like: loves(joe, P) :- person(P).
14:11 <Hafydd> Or :- loves(joe, P), person(P).
14:11 <dmiles> (i might want to treat Prop= loves(joe,_), knows(sue,Prop)... as Ground!)
14:11 zar joined
14:11 <dmiles> ok that is awesome
14:12 <* ski> . o O ( existential quantification )
14:12 <dmiles> ski thats secretly probly what i was hoping :P
14:12 <dmiles> Hafydd. right it would really only be things that met arg2 restriction of loves/2
14:14 <dmiles> the thing that makes prolog no fun is i have to make a skolem for existentials
14:14 <dmiles> (which why i added the truely "dont care" vars to SWI-Prolog's VM)
14:15 <* ski> isn't sure whether dmiles wanted `knows(sue,Prop)' to be treated as a clause/resource, or as a goal
14:15 <dmiles> (they do care .. becasue i put constraints onto the dont care)
14:15 pera joined
14:15 <dmiles> (which is why they are existentiual and no longer universal in meaning)
14:16 ystael joined
14:16 lingeeal joined
14:16 <dmiles> 'knows(sue,Prop)' as a goal
14:16 <Hafydd> Oh, they were in the version I used, actually, but I didn't use them much because they often make a program less efficient (i.e. with a large number of ground terms) when you don't constrain the variables.
14:16 <dmiles> loves(joe,_) as a resource?
14:17 <Hafydd> Er... a large number of ground rules, I mean.
14:17 epsilonhalbe left
14:17 <dmiles> Hafydd: hrrm .. sounds like they are just interating as naively as prolgo in that usecase
14:18 <dmiles> iterating*
14:18 <dmiles> (binding all 4 billion Persons to arg2)
14:18 neo85 joined
14:18 <Hafydd> dmiles: I don't think any better way of doing it is known. For some problems, that's all we can do.
14:18 psychicist__ joined
14:18 <Hafydd> dmiles: but Clingo does take some shortcuts.
14:19 keutoi joined
14:20 tfc joined
14:20 <dmiles> shortcuts? (i know what you mean) but do tell
14:20 neo85 left
14:21 lingeeal joined
14:21 caumeslasal joined
14:22 lingeeal joined
14:22 <ski> dmiles : i was thinking about `knows(sue,some [P] ( person(P),loves(joe,P) ))' .. but then when you mentioned skolems, i was wondering whether you were instead considering this as a clause/resource, rather than as a goal
14:23 <dmiles> ski: i sorta mixed and conflated the two topics
14:23 lingeeal joined
14:23 <ski> ok
14:23 <dmiles> the next question might have been knows(sue,some [P] ( person(P),loves(joe,P) ))
14:24 <kuribas> is there a better way of sequence_ $ iterate n action?
14:24 sid_fules joined
14:24 <dmiles> actualy.. we an "Answer Set" might actualy decide we needed "some"
14:24 <kuribas> erm "sequence_ $ replicate n action?"
14:24 stef204 joined
14:24 <ski> (where i was treating your `Prop= loves(joe,_)' as intending to express `Prop = some [P] ( person(P),loves(joe,P) )' (assuming that `P' in `loves(joe,P)' has `person(P)' as a presupposition))
14:25 <ski> @src replicateM_
14:25 <lambdabot> replicateM_ n x = sequence_ (replicate n x)
14:25 Fendor joined
14:25 <kuribas> right
14:25 <kuribas> :t replicateM_
14:25 <lambdabot> Applicative m => Int -> m a -> m ()
14:26 <dmiles> ski: oh what i actualy was wondering about is some [Prop] All [P]
14:26 <ski> (`Applicative' there used to be `Monad', hence the `M')
14:26 Wuzzy joined
14:26 <dmiles> (Prop being a variable .. I was wondering is some Prop that matched loves(joe,_) existed
14:27 <ski> (i didn't really follow "which why i added ..")
14:27 alx741 joined
14:27 <joneshf-laptop> I'm trying to use opaleye. I'd like to count the number of rows in a table based on an id, so I tried to write `foo :: QueryArr Id (Column PGInt8)`. I see `countRows`, but it only works with a `Query a`, not `QueryArr a b`. I next thought to make a function `foo' :: Id -> Query (Column PGInt8)`, but I don't understand how to use this in arrow syntax. It says `id not in scope`. Any thoughts?
14:27 Eduard_Munteanu joined
14:27 doodlehaus joined
14:28 <dmiles> and by loves(joe,_) .. i guess i meant "At least 1"
14:29 <Eduard_Munteanu> I wonder why people aren't running Hakyll or other static site generators at compile-time, a-la Yesod. Interpolating Haskell expressions is nice.
14:29 <ski> yes, aka `some'
14:29 JoshS joined
14:30 mizu_no_oto joined
14:31 <* ski> has no idea about `opaleye', but would possibly try looking for an operation corresponding to "GROUP BY" ?
14:31 <dmiles> so in the case of a query to knows(sue,( person(P),loves(joe,P))). I wouldnt be suprised if P was a skolem like some(P, knows(sue,( person(P),loves(joe,P))))
14:32 <dmiles> I mean the answer set that came back was: P = some(P, knows(sue,( person(P),loves(joe,P))));
14:33 <ski> (confusing two different `P' variables ?)
14:33 <dmiles> based on the query: ?- knows(sue,loves(joe,P)). % added person/1
14:34 <ski> dmiles : recall the "de re" vs. "de dicto" distinction. you can't move the existential past the modality like that without changing meaning
14:35 marcopullo joined
14:35 <dmiles> yeah.. i supposed the anwer might really be ... P = some(A, knows(sue,( person(A),loves(joe,A))))
14:35 <ski> (so they question then is which meaning did you intend)
14:35 <joneshf-laptop> ski, unfortunately `groupBy` also works only with `Query a`. All of these aggregations are defined to only work with `Query a` rather than `QueryArr a b`. Something about invalid sql possibly being generated.
14:35 <dmiles> query: ?- knows(sue,loves(joe,P)).  % returns P = some(A, knows(sue,( person(A),loves(joe,A))))
14:35 <ski> joneshf-laptop : then i'm sorry for not being able to give any more useful hunch ..
14:35 <joneshf-laptop> ski, no worries, I definitely appreciate it!
14:36 <dmiles> (if the systerm had proof at least)
14:36 <* ski> . o O ( <https://en.wikipedia.org/wiki/De_dicto_and_de_re> )
14:37 <dmiles> if example if joe had once killed the omly woman he ever loved the result would have come back as P = some(A, dead(A), merdered(joe,A), knows(sue,( person(A),loves(joe,A)))).
14:38 cdg joined
14:38 <dmiles> still anonymnous skolem because we dont actualyl know whom she was
14:38 <joneshf-laptop> I feel like my problem is more that I don't understand arrow syntax than anything else.
14:39 <Hafydd> dmiles: for example, during ground, rules with an contradiction on their right-hand side are omitted from the output, as in this program:
14:39 <Hafydd> p(a). q(X) :- p(X), not p(X).
14:39 <joneshf-laptop> Like, I don't know how to apply a value to a function in arrow syntax.
14:39 <Hafydd> The ground program for that is just: p(a).
14:39 xaviergmail joined
14:39 <ski> dmiles : well, it doesn't express the "only" part
14:40 elenh_ joined
14:40 <elenh_> www.greekircnet.gr
14:40 elenh_ left
14:40 zcourts joined
14:41 <ski> dmiles : in the `some [A] ( ...,knows(sue,...) )' case, Sue has someone in particular in mind. in the `knows(sue,some [A] ( ...,...) )' case, Sue doesn't necessarily have someone in particular in mind
14:41 max3 joined
14:41 <max3> is there a way to get code formatted like the compiler sees it? with braces and ;
14:41 <ski> the former is "de re", the latter is "de dicto"
14:41 <Hafydd> Or: "p. :- p." is grounded to: "p. :-.".
14:42 <Hafydd> And a program containing ":-." has no solutions.
14:44 faberbrain joined
14:44 <dmiles> (oh, my assumption.. sorry to keep adding.. is Sue might have assumed he practiced on at least one person yet didnt know he killed her)
14:44 <* ski> isn't sure whether `-ddump-ds' will dump an AST, a parse tree, or concrete syntax
14:44 <dmiles> (oh, my assumption.. sorry to keep adding.. is Sue might have assumed he practiced on at least one person (becasue he was a good kisser) yet didnt know he killed her)
14:44 Sampuka joined
14:45 <Eduard_Munteanu> max3, try ghc -ddump-parsed
14:45 <dmiles> but yeah knows(sue,some [A]).
14:45 <max3> Eduard_Munteanu, no way to do it for just one file?
14:45 <Hafydd> But that's not possible for programs like this: "a(x). p(X) :- a(X), not q(X). q(X) :- a(X), not p(X).". That grounds to the same program with X replaced by x everywhere, and its solutions are: "a(x) p(x)" and "a(x) q(x)".
14:45 <Eduard_Munteanu> max3, ghc -ddump-parsed foo.hs
14:46 <max3> Eduard_Munteanu, it won't try to compile?
14:46 <Eduard_Munteanu> It will.
14:46 <Eduard_Munteanu> But I think the dumping occurs early enough.
14:46 <dmiles> Hafydd: that is awesome ASP stays smart about the negations
14:47 <max3> -nope
14:47 <max3> Eduard_Munteanu, nope
14:48 <ski> (`-E' ?)
14:49 <Eduard_Munteanu> max3, try what ski said
14:50 <max3> nothing happened?
14:50 <ski> Hafydd : how is "solution" defined here ?
14:51 <Hafydd> ski: it means an answer set, which is a set of ground propositions consistent with all of the rules and maximal with respect to set inclusion.
14:51 tfc joined
14:51 <max3> Eduard_Munteanu, where does the dump go?
14:51 <max3> ah
14:52 <ski> joneshf-laptop : you need to distinguish between ordinarily bound variables, and arrow-bound ones. you can't use one of the latter freely in an application
14:52 <Eduard_Munteanu> max3, oh, try this... ghc -c -ddump-parsed module.hs
14:52 <Eduard_Munteanu> This works for me.
14:53 <ski> Hafydd : and some relevancy condition ?
14:53 <max3> it tries to comile
14:53 <max3> ah
14:53 <max3> okay
14:53 <max3> thanks
14:53 grayjoc joined
14:53 <Eduard_Munteanu> There should be parser output nevertheless.
14:53 <max3> yes
14:54 <dmiles> (also btw.. something about an "Answer Set" for each binding iterated out.. we have to assume even if the annonymous woman in my exanple.. this women if she wasnt annonymous (say a ground term) would have to have acted as if she was pysically asserted in the database)
14:54 <Hafydd> ski: oh, yes, well, it also has to occur as the ground left-hand side of some rule in the program.
14:54 <* ski> nods
14:55 <ski> and the argument terms presumably have to be relevant, drawn from some finite domain presumably, perhaps derived automatically from the program
14:55 <joneshf-laptop> ski, what do you mean by "distinguish"?
14:57 <dmiles> (so the the shizzy/cool thing i was after is if an anonmous woman could be qualifed as being a ground term .. for the grounded-only phase .. i know this would be an awefull lot to ask!)
14:57 <ski> joneshf-laptop : you can't have `proc x -> do y <- f -< x; z <- g y -< (); ...', e.g. -- `y' here is an "internal" variable, can't be used in the arrow expression `g y'
14:57 <Hafydd> ski: yes: during grounding, the possible values of the ground terms in the head (the LHS) of each rule is determined by the body.
14:58 <ski> mhm
14:58 <joneshf-laptop> ski, sure.
14:58 <Hafydd> And if that isn't possible, it's an error.
14:58 oisdk joined
14:58 danthemyth joined
14:59 <Hafydd> ("p(X) :- not q(X)."
14:59 <joneshf-laptop> ski, that's almost exactly what I'm trying to do.
14:59 <Hafydd> is an erroneous program, for example.)
14:59 <ski> (well, skolems are in some sense ground .. but i'm not sure what you're thinking of would be a skolem)
14:59 thunderrd joined
14:59 <joneshf-laptop> ski, But clearly there's some disconnect. I'm just not sure how to do what I want.
14:59 <ski> joneshf-laptop : if there's an `ArrowApply' instance, then there's some alternative syntax (was it `-<<' ?) that can be used)
15:00 sunnny left
15:00 <ski> joneshf-laptop : perhaps it's an oversight in the coverage of the library
15:00 <dmiles> (the reason i call them skolems is in some prolog systems.. the way you make the woman a real entity is to put in a fake "sk1")
15:01 zar joined
15:01 <ski> (existential quantifiction in goals, as well as universal quantification in clauses, create logic variables. otoh universal quantification in goals, as well as existential quantification in clauses, creates skolems)
15:01 <ski> (.. i'm not quite sure how modalities would interact with this, though)
15:02 robertkennedy joined
15:02 stoopkid joined
15:03 <dmiles> so assert(some [W] (killed(joe,W),loved(joe,W)). ==> physically might put into the KB: killed(joe,sk1). loved(joe,sk1). person(sk1).
15:03 Prutheus joined
15:03 eacameron joined
15:03 <ski> in linear logic, there's a difference between the clause (resource) `{some [X] p(X)}.' ({}/1 being the "of course" modality, related to "necessary", "knows", "believes", "henceforth", "always", &c.) and the clause (resource) `some [X] {p(X)}.'
15:04 <joneshf-laptop> ski, wow, that does work. Thanks! I'll see if it's law abiding before actually using it though.
15:05 <ski> er, sorry, that should be `all', not `some' (`X' being a logic variable here, not a skolem)
15:05 <ski> with the former `?- p(a),p(b).' succeeds. with the latter it doesn't. `?- p(a),p(a).' succeeds with either version, though
15:06 wtetzner joined
15:06 <ski> `all [X] {p(X)}.' acts like a partially instantiated clause, that is instantiated (grounded) by the first call. `{all [X] p(X)}.' otoh behaves in the traditional Prolog way, each new call producing a fresh logic variable `X'
15:07 <* qqwy> is back
15:07 <qqwy> Hey hey, everyoen
15:07 <qqwy> everyone*
15:07 zero_byte joined
15:07 <ski> ("of course" allows the program to use the resource as many times as it likes to)
15:07 <* ski> is forward
15:08 <* qqwy> winks cheerfully at ski, although he might see it as `skniw'
15:08 <dmiles> "all [X] {p(X)}" vs "some [X] {p(X)}" ... funny i hadnt thought before that some was easier to interpret than all
15:08 <qqwy> I am working on implementing https://en.wikipedia.org/wiki/Matrix_chain_multiplication in Haskell.
15:08 Croniamental joined
15:08 <qqwy> There is nice pseudocode there, but it is written in a very imperative fashion
15:08 danharaj joined
15:09 <dmiles> 'some' is less work to nterpret than 'all'
15:09 <ski> dmiles : i'm sorry, imagine i had written `some' in both these clauses
15:09 <ski> *sigh*
15:09 <qqwy> I wonder if there are ways to write this in Haskell that either uses tables as well, or uses a different kind of memoization.
15:09 <ski> `all'
15:09 grayjoc joined
15:10 <ski> dmiles : i agree with your assert/1 and skolem thing
15:10 <dmiles> ski: no worries i get things i type backwards more often than you
15:10 <qqwy> it might be possible to write something similar using STArrays or something, but those are very much black magic to me
15:10 <qqwy> About getting things backwards btw: Snoc lists are interesting creatures
15:11 <qqwy> :-)
15:11 deepfire` joined
15:12 <ski> "Algebra of Programming" by Richard Bird and Oege de Moor talks about them, iirc
15:13 <ski> also mentioning `associativeFoldMap :: (r -> r -> r) -> (a -> r) -> r -> [a] -> r' (where `[a]' is to be interpreted as any representation of a sequence)
15:13 <dmiles> so assert(all [P] some [S] (person(P) & soul(S) & hasA(P,S)) physically might put into the KB: soul(sk2(P)):-person(P). hasA(P,sk2(P)).
15:13 <ski> one might wonder why throw a `map' (the `a -> r' part) into it .. but it makes it easier to do equational reasoning and refactoring
15:13 <dmiles> oops hasA(P,sk2(P)):- person(P).
15:14 <c_wraith> ski: how does that differ from foldMap? Just that it takes the pair of monoidal operations instead of using a Monoid instance?
15:14 <ski> (note that `exists a. ([a],a -> r)' (coyoneda) is isomorphic to `[r]')
15:15 <ski> c_wraith : yes, possibly associating the sequence in some other way than the obvious
15:15 sid_fules joined
15:15 jaseemabid joined
15:16 fizruk joined
15:16 Prutheus joined
15:16 <ski> dmiles : `all [P] ( person(P) => some [S] ( soul(S),has_a(P,S) ) )' ?
15:17 ystael joined
15:17 <dmiles> yes
15:17 <dmiles> becomes: soul(sk2(P)):-person(P).  hasA(P,sk2(P)):-person(P).
15:17 <ski> i was just thinking that :)
15:17 <dmiles> i often think omitting the Body "person(P)" makes for a faster engine..
15:18 <dmiles> since the term "sk2(_)." would still mean: soul(sk2(_)). hasA(P,sk2(P)).
15:18 <ski> well, it can be considered a matter of type checking .. or partial deduction
15:19 <* ski> would like to see a logic programming system with presuppositions (built-in, preferably)
15:19 <dmiles> sk2(_) <- type checking.. anyhting allowed in arg1 of sk2.. must be a person
15:19 FjordPrefect joined
15:19 <dmiles> sk2(_) tersm need to fit only into places souls can be
15:20 <ski> qqwy : (top-down) dynamic programming can often be done in a nice way by defining an array (or other data structure) recursively
15:20 <dmiles> whats neat is that Hafydd says ASP "expects" that these assumptions would need to be met
15:20 <ski> (note, not populating the array by a recursive loop. defining the array itself recursively)
15:21 jaseemab` joined
15:21 <ski> and i'm talking about immutable arrays
15:21 <qqwy> sky: Could you show me an example?
15:21 <qqwy> Immutable arrays feel somewhat hard to manage
15:23 eacameron joined
15:23 <ski> > let fibs6 = listArray (0,6) [case n of 0 -> 0; 1 -> 1; _ -> fibs6 ! (n-1) + fibs6 ! (n-2) | n <- range (0,6)] in fibs6
15:23 <lambdabot> array (0,6) [(0,0),(1,1),(2,1),(3,2),(4,3),(5,5),(6,8)]
15:24 <ski> @let tabulate :: Ix i => (i,i) -> (i -> e) -> Array i e; tabulate ix f = listArray ix [f i | i <- range ix]
15:24 <lambdabot> Defined.
15:24 <ski> > let fibs6 = tabulate (0,6) $ \n -> case n of 0 -> 0; 1 -> 1; _ -> fibs6 ! (n-1) + fibs6 ! (n-2) in fibs6
15:24 <lambdabot> array (0,6) [(0,0),(1,1),(2,1),(3,2),(4,3),(5,5),(6,8)]
15:25 <jaseemab`> Heyo! I've been working on a lisp interpreter and just refactored the code to use a monad transformer to manage state and errors. The code looks a bit odd overall. Can someone please take a look at https://github.com/jaseemabid/lisper/blob/master/src/Lisper/Eval.hs and tell me if I'm doing anything fundamentally stupid?
15:26 robkennedy joined
15:26 <ski> @let memoArr :: Ix i => (i,i) -> (i -> e) -> (i -> e); memoArr ix f = (tabulate ix f !)
15:26 <lambdabot> Defined.
15:26 <ski> > let (memoArr (0,6) -> fib6) = \n -> case n of 0 -> 0; 1 -> 1; _ -> fib6 (n-1) + fib6 (n-2) in fib6 6
15:26 rekahsoft joined
15:26 <lambdabot> 8
15:27 <jaseemabid`> Very flaky connection here. Just in case anyone wants to share feedback and I get dropped off the IRC, please drop an email at jaseemabid@gmail.com
15:27 <qqwy> What is the final `in fibs6` part for here?
15:27 <ski> to evaluate the array
15:27 ragepandemic joined
15:27 <ski> instead one could pick one or a few elements (e.g. the last one)
15:28 <qqwy> Ah, I see
15:28 <ski> @let memoArrFix :: Ix i => (i,i) -> ((i -> e) -> (i -> e)) -> (i -> e); memoArr ix ff = fix (memoArr ix . ff)
15:28 <lambdabot> .L.hs:162:1: error:
15:28 <lambdabot> The type signature for ‘memoArrFix’ lacks an accompanying binding
15:28 <ski> @let memoArrFix :: Ix i => (i,i) -> ((i -> e) -> (i -> e)) -> (i -> e); memoArrFix ix ff = fix (memoArr ix . ff)
15:28 <lambdabot> Defined.
15:28 <jaseemabid`> mauke: /ping. The comments you said a while ago helped. Thanks.
15:29 <ski> > (memoArrFix (0,6) `flip` 6) $ \fib6 n -> case n of 0 -> 0; 1 -> 1; _ -> fib6 (n-1) + fib6 (n-2)
15:29 <lambdabot> 8
15:30 thunderrd joined
15:30 <qqwy> If you just run this in ghci, it will get progressively slower for the higher numbers, so it seems that it does not memoize (What did I do wrong?)
15:30 <qqwy>
15:30 <qqwy> let fibsn n = listArray (0,n) [case k of 0 -> 0; 1 -> 1; _ -> fibsn n ! (k-1) + fibsn n ! (k-2) | k <- range (0,n)]
15:30 <ski> qqwy : anyway, it works just as well with a two-dimensional array. it's *top-down* dynamic programming, meaning that there isn't an a priori selected scheduling of in which order to compute the elements. instead it's all demand driven, but results for the subproblems are cached in the array (or other data structure, perhaps an infinite list or something)
15:31 <qqwy> @let fibsn n = listArray (0,n) [case k of 0 -> 0; 1 -> 1; _ -> fibsn n !
15:31 <qqwy> (k-1) + fibsn n ! (k-2) | k <- range (0,n)]
15:31 <lambdabot> Parse failed: Parse error in expression: fibsn n !
15:31 Copperis joined
15:31 <ski> qqwy : you need to say `let fibsn n = arr where arr = listArray ...'
15:31 <qqwy> @let fibsn n = listArray (0,n) [case k of 0 -> 0; 1 -> 1; _ -> fibsn n ! (k-1) + fibsn n ! (k-2) | k <- range (0,n)]
15:31 <lambdabot> Defined.
15:31 <ski> otherwise the recursive calls to `fibsn' will recompute the array
15:31 <qqwy> Ah, I see
15:31 <ski> (you can use `fix' instead of `where' there, if you prefer)
15:32 <ski> the point of `tabulate',&c. above is to make the code look nicer, closer to the non-DP version
15:33 cfricke joined
15:33 <ski> one weakness is that there's no premature GC of values computed in earlier stages, which aren't needed anymore
15:33 <ski> all the previous values are kept in this fibonacci example, not just the previous two
15:34 <qqwy> So in the case of e.g. Fibonacci, one would use a list instead because you only ever need to access (n-1) and (n02) to build the rest, so accessing the `100`-th element of that list will make sure there are only ever three made, before the oldest of these three is GC'd?
15:34 zar joined
15:34 <ski> if you do approximate string search, then you get a two-dimensional array, each element being defined in terms of the three element, to the left, above, and to the left of above
15:35 <ski> so we get some kind of fringe moving from the top left corner to the bottom right, which contains the information that's actually needed to progress
15:35 <ski> but it's harder to describe this accurately
15:36 <qqwy> Yep
15:37 <ski> what you're talking about fibonacci i suppose is `fibs = 0 : 1 : zipWith (+) fibs (tail fibs)'
15:37 <qqwy> I wrote something that searches for the longest commong subsequence, but works on lists instead of arrays
15:37 <qqwy> https://gist.github.com/Qqwy/905736aba1dc0b2d324de69f545b42ea
15:37 <qqwy> Yes, indeed
15:37 thunderrd joined
15:38 Apocalisp joined
15:40 thunderrd joined
15:40 <ski> qqwy : hm, i'd suggest not using `Show' like that ..
15:40 zcourts joined
15:42 sidei joined
15:42 <qqwy> ski: It was meant to be a quick and dirty example to show my professor that building such an algorithm on-line was possible, because she wouldn't believe me
15:43 <ski> ok. as long as you're aware that `Show' isn't meant for that kind of thing
15:43 <ski> "on-line" in which sense ?
15:43 <qqwy> In that this algorithm allows you to find the longest common subsequence between two strings while gradually adding more characters to the ends of either string.
15:43 jaseemabid` joined
15:44 <qqwy> It will compute the LCS of the first part of the string before the rest is known
15:44 psychicist__ joined
15:44 <qqwy> The only thing that 'changes' when you add another character, is that an extra row or column is added to this matrix, and finally the path back to the root might be different.
15:44 <ski> ah, so it's incremental
15:44 <qqwy> Yes
15:44 <qqwy> Is incremental the colloqial term for an algorithm like this?
15:45 beerdrop joined
15:45 <ski> probably both terms are in use
15:45 <qqwy> I find the term 'on-line' to be somewhat overloaded myself as well... :S
15:45 <qqwy> https://en.wikipedia.org/wiki/Online_algorithm
15:45 <ski> "incremental" is used to describe `map' e.g., as opposed to `reverse' which is "bulky"
15:46 elon1 joined
15:46 <qqwy> Anyhow, to be sure: Is `Show' only meant to print representations that you can `Read' back in?
15:46 <ski> `reverse' produces no output until it has reached the end of the input. `map' produces outputs as soon as it is "passed" input elements
15:46 <* qqwy> nods
15:47 simukis__ joined
15:47 <ski> `Show' is foremost meant for debugging purposes. it's sometimes also used as a quick-and-dirty serialization format
15:47 zariuq joined
15:48 <ski> i'd say that i expect `show' to give a string representation of an expression that (in an appropriate environment) evaluates to a value equal to the input value
15:48 <ski> and, if there's a `Read' instance, i expect `read (show x) == x = True', for finite `x'
15:48 mada joined
15:48 beerdrop left
15:48 <ski> this, unfortunately, doesn't always hold, even for the standard library
15:49 <ski> but it's the ideal i'd like us to strive towards
15:49 <ski> a `Show' instance doesn't have to show the internal representation, leaking detail about unexported constructors (abstract data types)
15:49 <qqwy> I see :-)
15:50 <ski> it could just as well generate an expression in terms of the exported abstract operations
15:50 <ski> > listArray (0,2) [True,False,False]
15:50 <lambdabot> array (0,2) [(0,True),(1,False),(2,False)]
15:50 <ski> the other things that should be said here are : `Show' instances (and `Read' instances) are meant to work together
15:51 <ski> if i get an instance `Show Foo', i automatically get an instance `Show (Maybe Foo)' as well (and similarly for tuples, lists, &c.)
15:51 <ski> so if `Show Foo' is using some custom output format, not Haskell syntax, then `Show (Maybe Foo)' will be a strange mixture
15:52 <qqwy> If you want to build a humanly readable 'fancy' string output, is there a typeclass in the standard library for that?
15:52 <ski> this is the other reason why i'm urging people not to put custom formats in `Show'
15:52 <ski> afair, there isn't a standard one for that
15:53 <ski> i should also mention that if you're making a custom `Show' instance, you should in almost all cases define `showsPrec', not `shows' or `show'
15:53 <qqwy> ! This is the first time I hear about the function `showsPrec'
15:53 <ski> and you should use `showParen' (and `showString',`showChar',&c.) to define it
15:53 <ski> similarly for `Read' (`readsPrec',`readParen',`lex',&c.)
15:54 robotroll joined
15:54 <ski> `showsPrec' is for communicating to `Show' the current precedence level of the surrounding context, in order to allow it to determine whether it needs to add some extra brackets wrapping or not
15:54 sidei_ joined
15:54 <ski> show x = shows x ""
15:55 <ski> shows = showsPrec 0
15:55 <ski> `shows' assumes we start at level `0'
15:55 <ski> let's take
15:55 <ski> @src Maybe
15:55 <lambdabot> data Maybe a = Nothing | Just a
15:55 <ski> the derived instance is
15:55 <ski> instance Show a => Show (Maybe a)
15:55 <ski> where
15:56 <ski> showsPrec p Nothing = showString "Nothing"
15:56 <ski> showsPrec p (Just a ) = showParen (p > 10)
15:56 <ski> $ showString "Just "
15:56 <ski> . showsPrec 11 a
15:57 <ski> in the `Nothing' case, we never need to wrap brackets, so no need for `showParen' there
15:57 jaseemabid` joined
15:58 <ski> `10' is the conceptual precedence level of application, which is thought of as an implicit operator inbetween `Just' and `a'. it determines the precedence level of *this* expression `Just a' to be `10'
15:58 <ski> is the surrounding level is greater, we add wrapping brackets
15:59 beerdrop joined
15:59 fold4 joined
15:59 Gurkenglas joined
15:59 <ski> let's take an example with an actual operator
16:00 anuxivm joined
16:00 <qqwy> Ah!
16:00 <ski> @src Complex
16:00 <lambdabot> data (RealFloat a) => Complex a = !a :+ !a
16:00 <ski> here we have
16:00 <ski> infix 6 :+
16:00 <ski> we get
16:00 <ski> showsPrec p (x :+ y) = showParen (p > 6)
16:00 <ski> $ showsPrec 7 x
16:01 <ski> . showString " :+ "
16:01 <ski> . showsPrec 7 y
16:01 <ski> why `7' ?
16:01 <ski> well, `:+' is neither left-associative nor right-associative
16:01 <ski> so we need to increment the precedence level (`6') for both calls to `showsPrec'
16:02 <ski> if `:+' had been left-associative, then we wouldn't have incremented for `x'
16:02 <ski> if it had been right-associative, then we wouldn't have incremented for `y'
16:02 moth joined
16:03 <ski> since applicative is left-associative, we increment for `a', but conceptually not for `Just'. however that doesn't require a call to `showsPrec', so we don't actually pass `10' on anyway there
16:03 <ski> qqwy : the story with `readsPrec' is similar
16:04 revprez joined
16:04 theelous3 joined
16:05 <ski> s/applicative/application/
16:05 danthemyth joined
16:05 eacameron joined
16:05 sid_fules joined
16:06 <ski> qqwy : for `Read', `lex' is generally used to grab the next token, matching on it
16:06 <ski> qqwy : .. i hope what i said makes any sense
16:06 marsam joined
16:06 thunderrd joined
16:07 jaseemabid` joined
16:07 <qqwy> Yes, it does
16:08 <qqwy> :-)
16:08 <qqwy> Parsing is a subject that I know (too?) much about. ^^'
16:08 owiecc joined
16:08 psychici1t__ joined
16:11 jutaro joined
16:11 <qqwy> I asked Programmers.StackExchange about the difference between Parser Combinators and Parser Generators once.
16:11 xcmw joined
16:11 <qqwy> And then, since the answers were very sparse and/or opinionated, I decided to do some research myself
16:11 <qqwy> And finally I answered my own question
16:12 <qqwy> In much detail.
16:12 <c_wraith> Isn't the biggest difference that parser combinators are hosted in the language but generators are external tools?
16:12 <qqwy> which was then promptly downvoted by someone `because the other answers are shorter' :'|
16:12 codesoup joined
16:13 <qqwy> c_wraith: Sort of. Generators decouple the generation step from the compilation, which indeed means that the language of the generator could be a different one, but the reason they are used historically is because turning a top-down grammar into a bottom-up recursive Finite State Automaton is something you can not easily do manually
16:14 <qqwy> Back in the day it was believe that bottom-up parsing was better (faster, more memory efficient, less problems with non-terminating recursion) but nowadays we know that all of these issues can also be resolved in other ways, creating even stronger 'generalized' parsers that even allow to work on ambiguous input grammar.
16:15 <qqwy> If you try to optimize for developer efficieny, a parser combinator is definitely the way to go because maintaining a parser generator is a highly specialized field. But of course when 'using' either of these tools, this does not matter much.
16:15 BlueRavenGT joined
16:15 xaviergmail joined
16:15 <qqwy> Parser Combinators are more flexible in that you can use all the tools of the host language, as well as altering the grammar 'on the fly' (such as reading what tokens are known as 'verbs' from a database) which is impossible when you generate your parser from a grammar beforehand using a parser generator
16:16 <qqwy> Something like that
16:16 <qqwy> All right, I'll stop now ^^'
16:16 gienah joined
16:17 jaseemabid` joined
16:17 ystael joined
16:18 grayjoc joined
16:18 max3 joined
16:18 <qqwy> Hmm... Translating nested for-loops that alter a 2d-array into a functional program that works on immutable arrays is proving more difficult than I'd like.
16:18 <Eduard_Munteanu> Unfortunately it doesn't seem you can derive unparsers from parser combinators, like attribute grammars can.
16:18 grayjoc joined
16:19 <qqwy> `unparsers'?
16:19 beerdrop left
16:19 <Eduard_Munteanu> qqwy, printers
16:19 <qqwy> (antiparsers? coparsers?)
16:19 Qommand0r joined
16:19 <qqwy> :-)
16:20 <Eduard_Munteanu> And some things are easier done bottom-up.
16:20 <qqwy> Really? I'd think that this might be possible if you write your parser combinator properly
16:20 <qqwy> That is very true
16:20 <ski> qqwy : *nod*, applicative vs. monadic parsers
16:20 Xanather joined
16:21 rwnd joined
16:21 zero_byte joined
16:21 rwnd left
16:22 <* ski> . o O ( "Applicative vs Monadic build systems" by Neil D. Mitchell (ndm) in 2014-07-23 at <http://neilmitchell.blogspot.se/2014/07/applicative-vs-monadic-build-systems.html> )
16:22 FjordPrefect joined
16:22 <* qqwy> bookmarked!
16:23 Deide joined
16:23 owiecc joined
16:24 grayjoc joined
16:25 Jesin joined
16:28 govg joined
16:28 grayjoc joined
16:29 SCHAAP137 joined
16:29 sh0rug0ru joined
16:30 vektorweg1 joined
16:31 zargoertzel joined
16:34 mson joined
16:35 alx741_ joined
16:35 marfoldi joined
16:36 thunderrd joined
16:36 alx741_ joined
16:36 keutoi left
16:37 keutoi joined
16:38 urodna joined
16:39 bab joined
16:39 fotonzade joined
16:39 bernouli joined
16:41 zcourts joined
16:42 enitiz joined
16:46 beerdrop joined
16:47 systemfault joined
16:47 grayjoc joined
16:48 thunderrd joined
16:48 whaletechno joined
16:48 benjic joined
16:48 travula_ joined
16:49 eacameron joined
16:49 eacameron joined
16:50 jsgrant- joined
16:51 nakal_ joined
16:52 albertus1 joined
16:54 zero_byte joined
16:56 iomonad joined
16:57 Guest92605 joined
16:57 benjic joined
16:59 mmn80 joined
16:59 doodlehaus joined
17:00 janitor1 joined
17:01 <ertes> @let paraOver l = join . l . const
17:01 <lambdabot> Defined.
17:01 sepp2k joined
17:02 <ertes> > paraOver _1 (liftA2 (+) (^. _1) (^. _2)) (3, 5)
17:02 <lambdabot> (8,5)
17:02 gugah joined
17:03 <ertes> (Lens s t a b) instaniated at (f = (->) s) lets one access the original data, which i found useful
17:03 <ertes> at least in state monads
17:04 <ertes> @let (~+~) = liftA2 (+)
17:04 <lambdabot> Defined.
17:04 <ertes> > paraOver _1 (fst ~+~ snd) (3, 5)
17:04 <lambdabot> (8,5)
17:05 sam2 joined
17:05 <ertes> does that exist in the lens library, and i'm just overlooking it?
17:06 Sonderblade joined
17:07 Volt_ joined
17:08 <ertes> (the inspiration for the name "paraOver" came from paramorphisms)
17:08 <kuribas> is there a way to catch exceptions in pure code?
17:08 ebsen joined
17:09 <ertes> kuribas: nope, unless they are explicit (e.g. Maybe)
17:09 <kuribas> ertes: neither nothing unsafe?
17:09 mda1 joined
17:09 <ertes> kuribas: well, you could use unsafePerformIO, but you will get into semantics hell very quickly, if you do that
17:10 dude142 joined
17:10 <kuribas> I am now keeping a log, and I would like to see the log when the algorithm hangs...
17:10 psychicist__ joined
17:10 <ertes> kuribas: what about Debug.Trace?
17:11 <kuribas> ertes: I did that before, but I wasn't sure of the order...
17:11 elon1 joined
17:11 <kuribas> but I could write out the log, and reset it every loop...
17:11 <kuribas> ok, I'll try this
17:12 <ertes> kuribas: if your log is sufficiently lazy, you can print it while the algorithm is running… one of the rare use cases of (in fact lazy) Writer
17:12 <ertes> but if you're going to use a monad anyway, might as well use IO
17:12 zero_byte joined
17:12 <kuribas> it's part of my state, which is strict...
17:14 <ertes> kuribas: write your algorithm with effect classes and add MonadIO during debugging… later you can just remove that constraint
17:14 <ertes> myAlg :: (MonadState S m, MonadIO m) => A -> B -> m C
17:14 <kuribas> right...
17:15 louispan joined
17:15 <kuribas> is using CPP for that good style?
17:15 <ertes> just using MonadState is as good as using a pure state monad, but lets you instantiate freely
17:15 jomg joined
17:16 <ertes> CPP might get ugly quickly… however, one slightly overengineered solution would be to create MonadDebug with two instance monads: Debug and NoDebug
17:16 <ertes> class MonadDebug m where debug :: String -> m ()
17:16 <ertes> instance (Monad m) => MonadDebug (NoDebugT m)
17:16 <ertes> instance (MonadIO m) => MonadDebug (DebugT m)
17:17 <kuribas> I hope my algorithm will get specialized to State...
17:17 <ertes> myAlg :: (MonadState S m, MonadDebug m) => …
17:17 soLucien joined
17:18 <ertes> well, NoDebug is pretty much IdentityT, so the compiler's result will be a pure state monad
17:18 ystael joined
17:18 <ertes> StateT s (NoDebugT Identity) a ≃ State s a
17:19 zcourts joined
17:19 <kuribas> ertes: I'd want ghc to optimize the class away though...
17:20 <ertes> kuribas: i'm pretty sure it will
17:20 <kuribas> right, I'll try this...
17:20 anton___ joined
17:21 <ertes> most likely 'debug' of NoDebugT will be inlined (you can force it to be sure), along with (>>=), which should make both vanish
17:21 janitor1 joined
17:21 manjaro-kde5 joined
17:21 <ertes> kuribas: actually there is a simpler solution, and CPP might work for that:
17:22 manlet joined
17:22 <ertes> in the debugging case: type MonadMyAlg m = (MonadState S m, MonadIO m)
17:22 <ertes> debug :: (MonadIO m) => String -> m ()
17:22 <ertes> in the non-debugging case: type MonadMyAlg m = (MonadState S m)
17:22 <ertes> debug :: (Monad m) => String -> m ()
17:23 <ertes> without a class
17:23 desktop joined
17:23 <kuribas> ok...
17:23 bennofs joined
17:24 sid_fules joined
17:25 crobbins joined
17:27 sagax joined
17:28 owiecc joined
17:30 mbuf joined
17:30 xcmw joined
17:30 _sg joined
17:31 zariuq joined
17:31 psychici1t__ joined
17:35 <chilversc> can I make ghci print each item in a list on a separate line?
17:36 <c_wraith> sort of.
17:36 <Rembane> chilversc: mapM_ print xs
17:36 <chilversc> thanks
17:36 <c_wraith> that's not really making ghci do it - it's doing it yourself. But it's short! :)
17:37 <Rembane> ghci helpeth those who helpeth themselves.
17:38 <chilversc> yeah at first I thought I'd use unlines map show, and gchi helpfully went "1\n2\n3"
17:38 doodlehaus joined
17:39 <monochrom> putStrLn (unlines map show)
17:40 muesli4 joined
17:40 <Tuplanolla> That's two kinds of wrong.
17:41 rkazak_ joined
17:42 <cocreature> chilversc: unlines is fine, just use putStrLn instead of print
17:42 sidei joined
17:42 <c_wraith> cocreature: not a lot of beginners realize that ghci uses print
17:43 xaviergmail joined
17:43 <chilversc> I'm just playing around with exercises from real world haskell at the moment, havn't even got up to i/o yet
17:43 <cocreature> yeah I remember being confused about this as well
17:43 rkazak_ joined
17:45 zero_byte joined
17:45 <tapirus> style question, suppose I have a function that always takes an (unwieldly) number of integers, say a,b,c,d,t,x,y
17:46 faberbrain joined
17:47 <tapirus> I could write the type signature as f :: Int -> Int -> Int -> Int -> Int -> Int -> Int -> Double, or I could write it as f :: [Int] -> Double and have f [a,b,c,d,t,x,y] = etc. on the next line
17:47 <tapirus> the latter is less unwieldy, but would it be considered stylistically to be a bad choice, because reading the type signature might lead someone to assume that it's a function that works on a variable length array?
17:47 <byorgey> tapirus: yes.
17:47 <c_wraith> tapirus: is there some relationship between the numbers?
17:47 Sampuka joined
17:48 <c_wraith> tapirus: because the best solution is to package the numbers into semantically-meaningful data types
17:48 <byorgey> tapirus: why does the function take so many arguments? You might consider creating some kind of record or other data structure to hold them all together.
17:48 <tapirus> well in this case, I'm computing a t_i which is a function of t_0 and a bunch of parameters (there's actually no x,y in my example, I just added them in to accentuate the point)
17:49 <tapirus> but basically the way to go would be to wrap the parameters in some datatype or type synonym?
17:49 <byorgey> right, so make a record type data Parameters = Params { numWidgets :: Int, tolerance :: Int, x :: Int, y :: Int, ... } and then pass one of those to your function. Bonus, they now have names.
17:49 elon1 joined
17:49 <tapirus> lovely
17:50 augur joined
17:50 <byorgey> you could also perhaps define defaultParams :: Parameters
17:50 gk- joined
17:50 <byorgey> and then you can call your function like f (defaultParams { x = 6 }) to only override the x parameter with a non-default value
17:51 <byorgey> I don't know if this makes sense for your function in particular but it can sometimes be a nice approach.
17:52 boombanana joined
17:52 venkat24 joined
17:53 mfukar joined
17:53 <tapirus> cool :) yeah that makes sense
17:53 gk- joined
17:55 sidei_ joined
17:55 ertesx joined
17:56 nomicflux joined
17:57 tsmish joined
17:58 gk- joined
18:00 <ertes> tapirus: if the function is commutative or "linear" in a way, then just listing the arguments the way you did, and even a list, would be fine
18:00 boombanana joined
18:01 Goplat joined
18:01 <ertes> commutative: the position of each argument doesn't matter at all
18:01 <ertes> linear: only the relative positions of the arguments to each other matter, not the absolute position
18:02 ziocroc2 joined
18:02 doodlehaus joined
18:02 connrs joined
18:03 marekw2143 joined
18:03 <marekw2143> hello, why here: https://bitbucket.org/chessRepo/c7/src/87445b8c9b042ea2b816adc7052b869bc4593dd0/main.hs?at=master&fileviewer=file-view-default#main.hs-168
18:03 <marekw2143> I just cannot put "let ... in"
18:03 <marekw2143> and have to be "if .. else" ?
18:03 <ertes> tapirus: example: a bezier curve takes four points, and it would be fine to take all of those points as individual arguments (instead of a record type)
18:03 Aruro joined
18:04 <marekw2143> from my knowledge, "let ... in" is an expression , just like "if ... else .. "is
18:04 <kuribas> @hoogle exit
18:04 <lambdabot> Graphics.UI.GLUT.Initialization exit :: MonadIO m => m ()
18:04 <lambdabot> Shelly exit :: Int -> Sh a
18:04 <lambdabot> Shelly.Lifted exit :: MonadSh m => Int -> m a
18:04 gk- joined
18:04 eazar001 joined
18:05 <barrucadu> marekw2143: I don't understand your question.
18:05 <lyxia> marekw2143: what exactly would you want to write here
18:06 <marekw2143> lyxia, : "let nextBoards = ; nextStates = .. in (if .. else )"
18:06 <tapirus> ertes: gotcha :)
18:06 <marekw2143> instead of "if .. else (let nextBoards = ; nextStates .. = in (if .. else ) "
18:06 <marekw2143> the outer most "if else" seems needed for program to compile
18:07 <lyxia> marekw2143: it's not.
18:07 joelwallis joined
18:07 danthemyth joined
18:07 <ertes> marekw2143: you need to indent the 'in', because you're in a do-block
18:07 meck_ joined
18:07 <ertes> marekw2143: but you can also just leave the 'in' out… do-notation will desugar it appropriately
18:08 <ertes> (do let X; Y) = let X in (do Y)
18:09 <ertes> marekw2143: do-notation supports 'then' and 'else' unindented for 'if', but does not support unindented 'in' for 'let', because that would be ambiguous
18:10 <marekw2143> yyy, so I have to just indent "in" ?
18:10 <ertes> marekw2143: it would probably be stylistically better to just leave it out entirely
18:10 <ertes> do let …; if … then … else
18:11 <tapirus> ertes: gotcha :)
18:11 <tapirus> whoops
18:11 joelwallis left
18:11 sid_fules joined
18:12 darjeeling_ joined
18:12 <marekw2143> https://bitbucket.org/chessRepo/c7/src/bb78b67f99d08b5802049c564e33a487b767f501/main.hs?at=master&fileviewer=file-view-default#main.hs-171
18:12 <marekw2143> now I've removed unwanted "if else"
18:13 dev-Zero_ joined
18:13 meck joined
18:13 <ertes> marekw2143: remove line 168 and unindent lines 169-172 by 4 spaces
18:13 <marekw2143> it works here: https://bitbucket.org/chessRepo/c7/src/04a029be3c7eb21651d9d49956a0fc27f15c6d74/main.hs?at=master&fileviewer=file-view-default#main.hs-171
18:14 fragamus joined
18:14 xkapastel joined
18:14 psychicist__ joined
18:14 <ertes> marekw2143: now remove line 169 and unindent lines 169-172 by 8 spaces =)
18:14 <ertes> whoops
18:14 <ertes> marekw2143: now remove line 168 and unindent lines 169-172 by 8 spaces =)
18:14 zar joined
18:15 <ertes> marekw2143: http://lpaste.net/353430
18:15 prophile joined
18:16 <marekw2143> ertes, thanks
18:16 <marekw2143> works now
18:16 <ertes> marekw2143: of course you might as well write: return (if lastCheckingState state then nextStates else map addNextStates nextStates)
18:16 <marekw2143> yep
18:17 <monochrom> That may be too lazy.
18:17 <marekw2143> the whole "if else" is to add eventually some subtree
18:17 <ertes> it's a reader, so it shouldn't matter
18:17 <marekw2143> ertes, thanks for pointing out "reader"
18:17 jsgrant- joined
18:18 <marekw2143> since I'm just wondering whether it's good place to use it there
18:18 <ertes> marekw2143: it's not
18:18 eazar001 joined
18:18 <ertes> marekw2143: Reader is just (->)
18:18 <marekw2143> ?
18:19 <marekw2143> I mean reader monad , so that in 3 lines I'm asking for some "constant" data
18:19 <ertes> marekw2143: (Reader e a) is just (e -> a) in disguise
18:19 ystael joined
18:19 xcmw joined
18:19 <marekw2143> yes
18:19 <ertes> marekw2143: i'd just use a function there
18:20 <marekw2143> ok. I've used reader at last from educational pov ;)
18:20 <marekw2143> but if reader is not usefull there (seems not usefull as I had to either fmpa functions like in brd <- board <$> ask
18:20 <marekw2143> or I've made whoMoves of type REader
18:20 <marekw2143> so where is reader usefull?
18:21 <ertes> marekw2143: here is a nice trick… you probably know the instance:
18:21 <ertes> instance Monad (Reader e)
18:21 <ertes> you get exactly the same instance for (->):
18:21 <ertes> instance Monad ((->) e)
18:21 JagaJaga joined
18:21 gk- joined
18:21 meoblast001 joined
18:21 _sg joined
18:22 <ertes> if you change the type signature to (GameState -> [GameState]), it should still work
18:22 <ertes> but now 'ask' is just 'id'
18:22 jao joined
18:22 <kuribas> ertes: thank, this works great! I have SweepMonadM = State SweepState or in the debug version SweepMonadM = StateT SweepState IO. Later I use unsafePerformIO on the state.
18:22 gk- joined
18:22 <ertes> ask :: Reader e e -- for Reader
18:22 <ertes> ask :: (->) e e -- for (->)
18:22 <monochrom> > (do { x <- cos; y <- sin; return (x :+ y) }) 0.1
18:22 <lambdabot> 0.9950041652780258 :+ 9.983341664682815e-2
18:23 inad922 joined
18:24 <ertes> kuribas: yeah, unsafePerformIO has all the sweets
18:24 sid_fules joined
18:24 <ertes> it's luring you into semantics hell =)
18:24 <kuribas> ertes: and thanks to IO everything is in order...
18:24 <marekw2143> btw, (-> e) is just a "function monad" ?
18:25 <kuribas> ertes: this is just for debugging ...
18:25 raycoll joined
18:25 <ertes> marekw2143: if we refer to it as a monad, a common term is just "reader monad"
18:25 <monochrom> Debugging is semantics hell. Or semantic hell.
18:25 <monochrom> Also:
18:25 <monochrom> @quote monochrom debug
18:25 <lambdabot> monochrom says: it was fun debugging Debug :)
18:25 oberstein joined
18:25 <ertes> hehe
18:26 <marekw2143> ertes, thanks
18:26 <ertes> marekw2143: if you want to be precise, just state the type itself
18:26 <ertes> "((->) e) monad" is fine
18:26 gk- joined
18:26 <marekw2143> ((->) e) - there e is environment
18:26 <ertes> ergument
18:27 slack1256 joined
18:27 <monochrom> To be fair, we don't say "the State Int monad" either. We just say "the State monad".
18:27 <marekw2143> ergument ?
18:27 gk- joined
18:27 <ertes> marekw2143: kidding =)
18:27 <ertes> feel free to call it whatever you like… i just say: "the argument type"
18:27 <marekw2143> oik :)
18:28 <marekw2143> I've just looked for definition of instance Monad ((-r) r)
18:28 <marekw2143> it seems at last similar to instance Reader e monad
18:28 <ertes> marekw2143: it's the same as for Reader, except all the newtype wrapping and unwrapping is gone
18:28 <marekw2143> yep
18:28 <marekw2143> so where is REader usefull ?
18:29 <monochrom> marekw2143: It seems the source code of GHC.Base has it.
18:29 <ertes> marekw2143: some people find ReaderT useful from time to time (FWIW i don't), but Reader is literally useless
18:30 <ertes> fun fact: for ((->) e) both 'ask' and 'asks' are 'id' =)
18:31 seveg joined
18:31 <monochrom> Reader is useful for Googling and for word-centric people.
18:31 <monochrom> "Word-centric people" means they don't understand "1 + 2" but they understand "add one two".
18:31 sid_fules joined
18:31 <marekw2143> maybe in MonadTransformers its usefull ?
18:32 <ertes> marekw2143: Reader e = ReaderT e Identity
18:32 gk-- joined
18:32 <ertes> it's usually defined that way, too
18:32 <ertes> so it's more of a byproduct of ReaderT
18:32 <lyxia> it's only defined for consistency
18:33 <ertes> you get Reader, because it's a special case of ReaderT, and because it's conventional to have the Identity special case explicitly defined
18:33 <ertes> type State s = StateT s Identity
18:34 gk-- joined
18:35 Fairy joined
18:36 nomotif joined
18:38 mac10688 joined
18:38 shayan_ joined
18:39 Gloomy joined
18:40 sh0rug0ru joined
18:40 sidei joined
18:44 jmcarthur joined
18:44 eacameron joined
18:48 faberbrain joined
18:48 ragepandemic joined
18:50 shafox joined
18:50 Einwq joined
18:50 psychicist__ joined
18:52 xcmw joined
18:53 <qqwy> Hey guys
18:54 <qqwy> After a lot of fiddling, I was able to translate the imperative algorithm of calculating the optimal chaining in a matrix multiplication
18:54 <qqwy> but my resulting program still is very slow
18:54 <qqwy> I wonder how it could be made more efficient
18:54 <qqwy> https://gist.github.com/Qqwy/2ac3ef54c914d096803318e77fe637a1
18:54 <Rembane> qqwy: Have you profiled it?
18:54 teurastaja joined
18:54 <qqwy> This implements this pseudocode: https://en.wikipedia.org/wiki/Matrix_chain_multiplication
18:55 <qqwy> (And yes, the naming for the different subfunctions is still rather bad)
18:55 <qqwy> I have not yes profiled it manually. I will do so as well, but I was wondering if there are any naïve things I am doing here that might 'jump out' to you experts.
18:56 psychicist__ joined
18:56 <Rembane> qqwy: Hard to say, things that seem slow when you look at them could be fast after run through GHC.
18:56 tfc joined
18:56 <Rembane> qqwy: And vice versa.
18:57 JuanDaugherty joined
18:57 <qqwy> Very true
18:59 JJ15 joined
18:59 sidei_ joined
19:03 Fairy left
19:03 Aruro joined
19:04 <qqwy> Holy hell... if I try to run my program on a large-ish input, it swiftly eats more than 2 GB RAM
19:04 <qqwy> O.O
19:06 MindlessDrone joined
19:06 bjz joined
19:07 <thoughtpolice> glguy: Have you ever thought about supporting comments in something like the language-lua parse tree? (I would have filed a GH issue but your fork does not have issue tracking enabled.) My motivation is I'd like to use it for a simple tool to parse comments and generate some docs.
19:07 <thoughtpolice> Maybe just hand-rolling something would be easier for this specific case, since I don't think I care about much more than that (for this, at least)
19:08 <Sornaensis> qqwy: define large-ish
19:08 <Sornaensis> are you doing string operations?
19:09 tfc joined
19:09 <glguy> thoughpolice: I'll have to fix the issue tracker. I haven't thought about it, but it might be worth exploring
19:09 <qqwy> large-ish means reading 400 input dimensions
19:09 owiecc joined
19:09 <qqwy> i.e. calling computeMinimalMatrixChain with a list of 400 Ints
19:10 <Sornaensis> neat, how much memory would you expect that to use
19:11 <ertes> ok, paraOver seems redundant
19:11 <ertes> @let paraFst f xy' = (\x -> (x, snd xy')) <$> f xy'
19:11 <lambdabot> Defined.
19:11 romanandreg joined
19:11 <ertes> > over paraFst (fst ~+~ snd) (3, 5)
19:12 <lambdabot> (8,5)
19:12 <qqwy> The algorithm is supposed to run in O(n²) memory usage
19:13 <qqwy> so I'd expect +- 400*400 ints = 160000 ints
19:13 <thoughtpolice> glguy: OK, cool. Yes, I'm not exactly sure what it would look like in the parse tree, but fundamentally I "only" need to basically A) Find function defns in a module and B) look at the comment prior to that decl. I'm not sure if I'll have time to take a go at this soon but I can file an issue so nobody forgets.
19:13 <ertes> although one advantage of paraFst is that it doesn't require special para-lenses
19:13 <qqwy> which would be 10.2 megabytes
19:13 <ertes> s/paraFst/paraOver/
19:13 <thoughtpolice> glguy: (I might want the full parser in another tool, which is just a linter, and I don't care about comments for that. Only just for this thing)
19:14 ncyellow left
19:14 <MarcelineVQ> ertes: how do you guys remember all these symbols and names :>
19:14 <ertes> MarcelineVQ: which ones tripped you up? i think i used fairly standard terminology
19:15 path[l] joined
19:15 schjetne joined
19:15 osa1 joined
19:15 <ertes> (~+~) i just defined as (liftA2 (+)) earlier =)
19:16 <ertes> i would have used (<+>), but that one is already wasted for ArrowPlus
19:17 <qqwy> Hmm
19:17 <qqwy> It seems that rewriting the list comprehension to `map` did the trick, and made the program use more than 50 times less memory, as well as resulting in a huge speed boost
19:17 <qqwy> o.o
19:18 <MarcelineVQ> ertes: Normal case of coming in late to a convo and trying to be funny, I'll scroll up and do some learning :>
19:18 <ertes> ah =)
19:18 <ertes> well, lens is…
19:18 <ertes> :t confusing
19:18 <lambdabot> Applicative f => LensLike (Data.Functor.Day.Curried.Curried (Data.Functor.Yoneda.Yoneda f) (Data.Functor.Yoneda.Yoneda f)) s t a b -> LensLike f s t a b
19:18 <barrucadu> qqwy: Probably when you used the explicit "map" some rewrite rules fired which you missed out on before, which allowed much better optimisation: https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#rewrite-rules
19:19 <Sornaensis> are list comprehensions ever useful
19:19 Prutheus joined
19:19 <barrucadu> Sornaensis: I think they can be easier to read if you're doing a couple of maps and filters in one go
19:19 sid_fules joined
19:20 <cocreature> Sornaensis: depends on how you define “useful”. they don’t provide anything that you can’t write otherwise but the syntax can be more readable in some cases
19:20 ystael joined
19:20 <Sornaensis> easier than do notation?
19:20 <ertes> > [ x + y | x' <- [0..10], let x = x^2, guard (x /= x'), y <- [x..10] ]
19:20 <lambdabot> error:
19:20 <lambdabot> • Couldn't match expected type ‘Bool’ with actual type ‘f0 ()’
19:20 <lambdabot> • In the expression: guard (x /= x')
19:20 <ertes> whoops
19:20 <ertes> > [ x + y | x' <- [0..10], let x = x^2, x /= x', y <- [x..10] ]
19:20 <lambdabot> mueval-core: Time limit exceeded
19:20 <ertes> > [ x + y | x' <- [0..10], let x = x'^2, x /= x', y <- [x..10] ]
19:20 <lambdabot> [8,9,10,11,12,13,14,18,19]
19:21 <ertes> Sornaensis: sometimes it's just more concise and saves you from having to import Control.Monad
19:21 dev-Zero_ joined
19:21 <ertes> > do x' <- [0..10]; let { x = x'^2 }; guard (x /= x'); y <- [x..10]; pure (x + y)
19:22 CountryNerd joined
19:22 <lambdabot> [8,9,10,11,12,13,14,18,19]
19:22 <barrucadu> I find do-notation for lists more confusing, but that's because I never use it, so I always do a double-take when I see it.
19:23 <ertes> if 'guard' were in Prelude, i'd probably never use list comprehensions
19:23 chaosmasttter joined
19:23 JeanCarloMachado joined
19:23 xcmw joined
19:24 <ertes> the set-notation style is a bit awkward, because you have to read the definition part in order and then jump to the result part… with do-notation it's top-down all the way
19:24 cyborg-one joined
19:25 emc2 joined
19:26 schjetne joined
19:28 jutaro joined
19:29 marcopullo joined
19:29 mda1 joined
19:32 wildlander joined
19:33 robotroll joined
19:34 Guest32509 joined
19:35 k0001_ joined
19:36 elon1 joined
19:36 major` joined
19:37 _sg joined
19:40 zero_byte joined
19:40 m0rphism joined
19:40 variable joined
19:41 eschnett joined
19:42 funkshun joined
19:43 <pavonia> When you have a lots of data types each with parsers and pretty-printers, is it more common to have three modules Types, Parsers and Printers; or to have a lot of small modules for each type with its corresponding printers and parsers in it?
19:43 <pavonia> Or perhaps something third
19:44 <hpc> i like writing one ADT per modul and naming it something like AbstractParserFactory ;)
19:44 nomicflux joined
19:44 <hpc> but usually the first one, if you have things that parsers and printers will both depend on
19:44 xcmw joined
19:44 <hpc> because you need something that both of them can import without making a cyclic dependency
19:47 <pavonia> Is that AbstractParserFactory a thing in Haskell?
19:48 Wizek_ joined
19:49 <geekosaur> not usually except as a joke
19:49 slackR joined
19:49 <tdammers> you could also say it's a thing, but nobody bothers naming it because it's trivial
19:50 slackR left
19:50 Mon_Ouie joined
19:51 cereal_killer_ joined
19:51 sdothum joined
19:53 zenware joined
19:55 Salih_ joined
19:56 asthasr joined
19:58 zcourts joined
19:58 Fairy joined
20:00 <Tuplanolla> "What's this design pattern called?" "It's a function."
20:01 <geekosaur> .oO { bengloarafurd ford }
20:01 hseg joined
20:01 hseg joined
20:01 osa1 joined
20:01 osa1 joined
20:03 <Rotaerk> wat?
20:03 <mac10688> Anyone good with reactive-banana? I feel like it's an easy concept until I start reading the docs.
20:03 brh joined
20:03 <hseg> Hi. I'm trying to create an infix constructor, and the report is a bit unclear on what characters are valid there. Am I parsing it correctly as being : followed by any Unicode symbol or punctuation except an enumerated list of symbols and an enumerated list of operators?
20:04 <qqwy> hseg: Anything that would make a valid infix operator in Haskell would also be a valid infix constructor, IIRC
20:04 <hpc> an infix constructor is something that follows the rules of any other infix operator, with a "capital symbol" at the front
20:04 <hpc> much like regular constructors are identifiers that are capitalized
20:04 <hpc> the only "capital symbol" is ':'
20:05 tomphp joined
20:05 <qqwy> This list might help: http://stackoverflow.com/questions/10548170/what-characters-are-permitted-for-haskell-operators
20:05 fizruk joined
20:07 chaosmasttter joined
20:07 ajaXHorseman joined
20:07 <hseg> Thanks. I suppose letterlike codepoints are forbidden in symbols, then?
20:08 e14 joined
20:08 <qqwy> Yes, I believe so
20:09 jncunha joined
20:09 <hseg> Too bad. I wanted to abuse syntax and write :+i√2 for the constructor of Q(i√2)
20:09 slackR joined
20:09 <ertes> mac10688: what's your question?
20:09 <hseg> Eh. Was a hack anyway
20:09 <MarcelineVQ> @let data Foo a b = a `Foo` b
20:09 <lambdabot> Defined.
20:10 <monochrom> Well, the "2" will also get into the way.
20:10 <hseg> That works.
20:10 <hseg> Yup
20:10 <mac10688> ertes, I want to program the game of life but I'm trying to figure out how to do it with frp. Where each tick of the second will send an event
20:10 <mac10688> ertes, 1. how do I wire up a tick of a second to send an event 2. How do I wire up listeners to the event?
20:10 <hseg> However, MarcelineVQ's solution would work - define a conid infix
20:10 esad joined
20:11 Copperis joined
20:11 <ertes> mac10688: well, GoL is a rather boring use case for FRP, because it's essentially just an accumE
20:11 dan_f joined
20:11 Fairy joined
20:11 <ertes> mac10688: r-b is split into two interfaces: an application interface and a framework interface
20:12 <ertes> mac10688: if you use r-b directly, you write both an application and the framework that binds the application to the real world
20:12 <ertes> the latter is the interface you find in Reactive.Banana.Frameworks
20:13 <ertes> mac10688: there are a number of ways to create a root event (one that isn't derived from other events/behaviours, but is actually a real-world thing)
20:13 <ertes> so much for that…
20:13 mac10688 joined
20:13 sid_fules joined
20:14 <mac10688> ertes, I'm sorry, my computer crashed after you said gol would be a boring example and to just use accume
20:14 <mac10688> I'm ok with a boring example though, I just want to use a small example to see how it works
20:14 <ertes> mac10688: r-b is split into two interfaces: an application interface and a framework interface… if you use r-b directly, you write both an application and the framework that binds the application to the real world… the latter is the interface you find in Reactive.Banana.Frameworks
20:14 <ertes> mac10688: there are a number of ways to create a root event (one that isn't derived from other events/behaviours, but is actually a real-world thing)
20:15 <ertes> mac10688: the most common and generally recommended way for r-b is fromAddHandler, which also indicates that r-b is mostly meant to bind to callback-based UI libraries
20:15 <MarcelineVQ> hseg: note that the defintion notation doesn't have an impact in this case. a `Foo` b is just Foo a b in the same way as map f x is f`map`x You can define it as data Foo a b = Foo a b and at the use site say 'c' `Foo` 3 if you like or Foo 'c' 3
20:16 <mac10688> yeah I've seen those fromAddHandler functions, but I have trouble wrapping my head around them
20:16 <ertes> mac10688: do you understand the AddHandler type?
20:17 <mac10688> not really. I see the register function, that takes a Handler type and gives back an IO (IO ())
20:18 <ertes> mac10688: let's say your application is basically just an infinite loop
20:18 <mac10688> ok
20:18 serendependy joined
20:19 <ertes> but at each iteration an event occurs, like a "tick" event… feel free to add a threadDelay to that loop to get some loose control over timing
20:19 <ertes> mac10688: i suggest that we move this into #haskell-game, otherwise we drown everything else =)
20:19 zero_byte joined
20:19 <hseg> MarcelineVQ: Sure. Although I note that the precedence is not what I expected, as e.g. 2*3 `Foo` 3+5 parses as (2*(3`Foo` 3))+5, not (2*3) `Foo` (3+5)
20:20 <mac10688> ok ertes
20:20 <hseg> At least, GHC complains according to the former parse, and entering the latter parse explicitly causes it to shut up
20:20 honeymead joined
20:20 ystael joined
20:21 <MarcelineVQ> hseg: it has function precedence, which iirc is infixl 9 when infix, you can define a precedence you prefer with a line like infixr 3 `Foo`
20:21 gesh joined
20:21 <MarcelineVQ> e.g in ghci data Foo a b = a `Foo` b; infixr 3 `Foo`
20:22 permacula189 joined
20:22 sternmull joined
20:22 <hseg> MarcelineVQ: Sorry, missed everything since my comment about getting GHC to shut up.
20:23 <MarcelineVQ> hseg: it has function precedence, which iirc is infixl 9 when infix, you can define a precedence you prefer with a line like infixr 3 `Foo` e.g in ghci data Foo a b = a `Foo` b; infixr 3 `Foo`
20:23 treehaqr joined
20:24 <MarcelineVQ> also I think I​ didn't see a line about ghc being noisy
20:24 <MarcelineVQ> oh there it is, I'm just blind
20:24 <hseg> Ah. Yeah looks like fixity 5 should do the trick.
20:25 <hseg> Although looking at the fixity table for the Prelude, it looks a bit odd that the fixities for operators in two different domains would be comparable.
20:26 JeanCarloMachado joined
20:26 <hseg> Wouldn't it make more sense to be able to define a fixity class (e.g. Arith, List, Ord, Bool), define the ordering between operators within a class, then define the ordering between classes?
20:27 <hseg> (I'm probably overengineering this, and should just get used to it)
20:27 <MarcelineVQ> I don't know much about that, in general ( ) are straightforward enough that sounds like a bit much though
20:27 augur joined
20:28 <MarcelineVQ> If it bothers you it's worth exploring though, that's how we get new things :>
20:28 <hseg> :)
20:28 <hseg> Will put it on my weekend project list.
20:29 <hseg> Reason why this annoys me now - there is no way to make something bind more tightly than : but less than +.
20:29 funkshun joined
20:30 <benzrf> time for rational fixity
20:30 <MarcelineVQ> Did you make a Num instance for lists?
20:30 <benzrf> :>
20:30 lukaramu joined
20:30 <hseg> So if I were to e.g. reimplement Complex, there is no way to write a + b :+ c + d : a :+ b : [] with parse ((a+b) :+ (c+d)) : (a :+ b) : []
20:31 <hseg> No, I didn't make a Num instance for lists, but I am potentially consing complex expressions onto them
20:31 shafox joined
20:31 <qqwy> Interesting. When replacing the boxed arrays with unboxed arrays, my program compiles without problem, but when run it returns `programname: <<loop>>`
20:32 <qqwy> So it seems that the array is made in order, and that this is stricter than my algorithm requires. But I am curious as to how/why it prints `<<loop>>`
20:32 <hseg> benzrf: That's a solution in a direction that's less flexible, and IMHO less Haskelly than what I suggested. Then again, I'm no authority.
20:32 <benzrf> i was being facetious :)
20:32 <MarcelineVQ> hmm, in the mean time maybe you can redefine the fixity for :+ for your module
20:32 <hseg> Yeah, I did. infix 3.
20:33 <hseg> For the moment, I don't have list code, so it's not biting me yet.
20:33 grayjoc joined
20:33 sam2 joined
20:35 esad joined
20:36 psychicist__ joined
20:36 <michalrus> glguy: hey, just writing to thank you for that suggestion with `data T a b = MkT (a -> (b, T a b))`, I took this route for my “list of functions with state”. But I’ve also got a question… I remember you suggested `data T a b = MkT (a -> (b, a -> T a b))`—why the additional `a ->` if `T a b` already encodes a function from `a`? I implemented the first version and it seems to work well. :)
20:37 kolko joined
20:38 Ring0` joined
20:38 Ring0` joined
20:38 cgag joined
20:38 meoblast001 joined
20:38 sid_fules joined
20:38 <cgag> trying to build ghc and running into make[1]: *** No rule to make target '/opt/ghc/8.0.2/libinclude/Rts.h', needed by 'compiler/stage1/build/ghci/keepCAFsForGHCi.o'. Stop.
20:38 <cgag> from the ghc-8.0.2 source distribution
20:38 <cgag> anyone dealt with that?
20:40 <cgag> alternitavely, anyone have a workaround for this: "unable to decommit memory: Invalid argument"? I'm pretty sure it's from running a container with ghc built on a recent kernel, but running on 4.4. Currently attempting to build ghc and everything myself but would be happy to not need to.
20:41 <geekosaur> shouldn't it be recovering from that and using a backup method?
20:41 romanandreg joined
20:41 <geekosaur> (I don't think you can currently force an x86-64 ghc to use the old allocator)
20:42 fabianhu_ joined
20:44 <ski> michalrus : synchronous stream processor is one name for that, btw
20:45 alx741 joined
20:46 seagreen joined
20:47 <geekosaur> cgag, if you don;t get an answer here, you can try in #ghc
20:47 <MarcelineVQ> cgag: what are your build steps after extracting from the source archive?
20:48 aarvar joined
20:49 faberbrain joined
20:49 <cgag> MarcelineVQ: ./boot && ./configure && make
20:50 marsam joined
20:50 <michalrus> ski: thank you, I’ll Google™ that. (:
20:51 psychicist__ joined
20:51 <ski> you could also compare with "transducer"
20:51 <MarcelineVQ> if you're using the source distro you shouldn't need to do ./boot idk if that matters though
20:52 <cgag> yeah i wans't doing that initially but i thew it in after failing
20:52 Fairy joined
20:52 <cgag> geekosaur: i'll drop this in #ghc, thanks
20:52 <MarcelineVQ> alrighty, I'd ask in #ghc then
20:52 <michalrus> Mhm. :)
20:52 <MarcelineVQ> be sure to mention your OS and arch
20:53 romanandreg joined
20:53 <MarcelineVQ> and where you're getting the source from, such as http://downloads.haskell.org/~ghc/8.0.2/ghc-8.0.2-src.tar.xz
20:55 <cgag> will do, thanks
20:56 Heasummn joined
20:57 robertkennedy joined
20:59 grayjoc joined
20:59 alx741_ joined
21:00 alx741_ joined
21:02 the|auriscope joined
21:06 jutaro joined
21:06 eacameron joined
21:08 esad joined
21:10 ikke joined
21:13 Myrl-saki joined
21:15 gienah_ joined
21:18 AndreasK joined
21:21 ystael joined
21:21 eacameron joined
21:22 hseg joined
21:22 <lpaste_> hseg pasted “Program loops. Why?” at http://lpaste.net/353434
21:23 <hseg> For some reason, this code snippet loops.
21:23 <qqwy> Ah!
21:23 <qqwy> Using STArrays is actually really easy :o
21:23 <qqwy>
21:23 <qqwy> matrixChainOrder :: UArray Int Int -> Int -> UArray (Int, Int) Int
21:23 <qqwy> matrixChainOrder dims n = runST $ do
21:23 <qqwy> memo <- newArray ((1,1),(n,n)) 0 :: ST s (STUArray s (Int, Int) Int)
21:23 <qqwy> forM_ [1..n] $ \i -> do
21:23 <qqwy> writeArray memo (i,i) 0
21:23 Rodya_ joined
21:23 <qqwy> forM_ [2..n] $ \l -> do
21:23 <qqwy> forM_ [1..(n-l+1)] $ \i -> do
21:23 <qqwy> let j = i + l - 1
21:23 <Tuplanolla> Nice.
21:23 <hseg> Don't see why - it should have a call pprint twice when on each element of x.
21:24 alx741 joined
21:24 <hseg> *it should call pprint*
21:25 <Tuplanolla> Add parentheses to your `if`, hseg.
21:25 <hseg> Oh? How is it parsing it, then?
21:26 <Tuplanolla> I'm not sure if it works the way you intend, but it looks a bit suspicious.
21:26 <Tuplanolla> The `else` part spans to the end.
21:26 hsk3 joined
21:26 darjeeling_ joined
21:26 <hseg> Yes... Intention is to pprint the a part, then if b is nonzero pprint the b part.
21:27 <hsk3> What is blaze-react https://www.youtube.com/watch?v=4nTnC0t7pzY
21:27 <hsk3> and how does it compare to reflex? https://www.youtube.com/watch?v=92eXGvHFbzs
21:27 <hsk3> O notice both rely on GHCJS.
21:27 <hsk3> s/O/I
21:28 <Tuplanolla> I don't see the problem then. That would require more focus.
21:28 sid_fules joined
21:29 stef204 joined
21:29 sam2 joined
21:31 JoshS joined
21:31 <hexagoxel> hseg: a*c-2*b*d `ISqrt2` b*d === a*c-2*b*(d `ISqrt2` b)*d
21:32 <hexagoxel> nevermind, you have infix 3..
21:32 <hseg> Oh? Shouldn't my infix 3 `ISqrt2` declaration have fixed that?
21:32 <MarcelineVQ> ehehe
21:32 <MarcelineVQ> negate x = -1 * x
21:32 <hseg> I suspect it's the fromInteger implementation that's at fault.
21:32 <hseg> Well... *blushes*
21:33 <hexagoxel> hseg: just pepper trace statements everywhere, and see what gets spammed
21:33 <MarcelineVQ> my laugh is how my ide handle that line, not about the line itself
21:34 <hseg> Oh?
21:35 <MarcelineVQ> yeah it thinks you meant x as in x :: [QiSqrt2] it's not somehting that actually seems to matter though, just an oddity with the ide since it compiles. Howver I noticed it sticks on the first negative number and negate uses * so I'd be looking at negate and *
21:35 Jesin joined
21:35 zero_byte joined
21:35 fresheyeball joined
21:35 <hseg> MarcelineVQ: You are correct, removing the -1 terms causes the program to stop looping.
21:36 <Tuplanolla> Is it that `-1 * x` turns into `negate (fromIntegral 1 * x)`?
21:36 oish joined
21:37 raichoo joined
21:37 <hseg> .... That's probably it. Replacing it by (fromInteger (-1)) * x works
21:38 <monochrom> Hmm that's strange.
21:38 <hseg> That's because I defined fromInteger = (`ISqrt2` fromInteger 0) . fromInteger
21:39 <hseg> So there's only recursion into the Num Ratio instance.
21:39 <Tuplanolla> More reasons to use `NegativeLiterals`.
21:39 <hseg> NegativeLiterals?
21:41 manjaro-kde5 joined
21:41 <MarcelineVQ> hseg: https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#negative-literals
21:42 <zenware> If I was going to give a lecture on some property or feature of Haskell, to a technical audience, what would this crowd recommend I get them excited about?
21:42 <hseg> Yup, NegativeLiterals + writing spaces before differences makes this work.
21:42 atomi joined
21:43 <hseg> NegativeLiterals seems useful, with small cost.
21:44 bjz joined
21:45 eacameron joined
21:46 cross joined
21:46 <monochrom> Interesting, -1*x is read as -(1*x) therefore negate(1*x)
21:46 sid_fules joined
21:46 <hseg> WTF? Moral of this story: Don't use negative literals?
21:47 ajaXHorseman joined
21:47 prophile joined
21:47 whiteline joined
21:47 <geekosaur> safest to parenthesize them always
21:47 <monochrom> I am still looking into the Haskell 2010 Report for why this happens :)
21:47 <int-e> you can write fromInteger (-1) * x ...
21:47 psychicist__ joined
21:47 Lord_of_Life joined
21:48 <geekosaur> because unary - does not have its own precedence, it uses the precedence of infix (-)
21:48 <int-e> there are no negative literals in that grammar/tokenizer.
21:48 <geekosaur> so it's lower precedence than the (*)
21:49 <monochrom> Yeah, even (-1)*x becomes just negate(fromInteger 1)*x, all using your Num methods.
21:49 <int-e> I mean, even (-1)*x will be (negate (fromInteger 1)) * x, which is silly
21:49 <int-e> (hmm, that stereo effect)
21:49 <hseg> Which is why NegativeLiterals was recommended.
21:51 gesh joined
21:52 <hseg> ... And suddenly I realize I made a computational error and didn't need to be able to calculate over Q(sqrt(-2))
21:52 <monochrom> OK, two rules from the Haskell Report: "infixexp -> lexp qop infixexp | - infixexp | lexp", and "unary - will always refer to the negate function defined in the Prelude"
21:52 <int-e> okay, I checked that with NegativeLiterals you actually get fromInteger (-1) * x from -1*x. sweet.
21:52 hiratara joined
21:52 argent0 joined
21:53 Fairy joined
21:53 <int-e> but not from - 1 * x, so it's whitespace sensitive.
21:53 <monochrom> So unary - at the beginning is going to bind more loosely than infix operators. And then it's translated to a negate call.
21:54 <hseg> Yeah, makes much more sense. Of course, it simultaneously forbids x-1 (parses as x (-1))
21:54 <int-e> and in fact, - -1 * x becomes a valid expression
21:54 <ertes> you could just use 'negate'
21:54 <monochrom> Well yeah, even with NegativeLiterals, first you have to get past the tokenizer. Tokenizer is not going to declare "- 1" as "one token" at a whim.
21:54 <hseg> int-e: What do -1 * x and - -1 * x parse to?
21:54 eacameron joined
21:55 <int-e> hseg: with NegativeLiterals they get desugared to fromInteger (-1) * x and negate (fromInteger (-1) * x), respectively.
21:55 <hseg> Oh. That's the parses I expected, but not what I interpreted your statements as saying.
21:55 romanandreg joined
21:56 caumeslasal joined
21:56 <monochrom> Isn't it exciting to be a language lawyer? :)
21:56 Prutheus joined
21:57 sedeki joined
21:58 <monochrom> Oh oops, the grammar rule does not dictate looser or tighter binding. The extra clause "Prefix negation has the same precedence as the infix operator - defined in the Prelude" does.
21:58 <hseg> monochrom: Alas, 'tis our curse as programmers. Our interlocutors don't handle ambiguity well.
21:58 avn joined
21:59 <monochrom> We need a Supreme Court ruling! <duck>
21:59 cloudhead joined
21:59 nut joined
22:00 steshaw joined
22:00 Lazersmoke joined
22:00 doodlehaus joined
22:00 <nut> Im using emacs, how can i list the defitions(data and functions etc) in the current buffer ?
22:01 <nut> and then helm goto it
22:01 <romanandreg> So, I've been following tips from this blogpost to get fancier outputs from GHCi (http://teh.id.au/posts/2017/02/13/interactive-print/index.html), but I would like to know how to handle package dependencies required for this features without including them in my project's cabal file (using stack)
22:01 <romanandreg> any pointers?
22:02 Fairy joined
22:03 <romanandreg> or, if having it in my project's cabal file, having a way to point them as development dependencies (leiningen style)
22:03 louispan joined
22:04 zcourts joined
22:06 zariuq joined
22:08 sid_fules joined
22:08 zcourts joined
22:09 robkennedy joined
22:10 Fairy joined
22:11 mkoenig joined
22:11 hazmat_ joined
22:12 tag joined
22:13 Mon_Ouie joined
22:15 Fairy joined
22:15 gugah joined
22:15 oisdk_ joined
22:16 manjaro-kde5 joined
22:16 <romanandreg> ok, by doing `:set -package show-pretty` I was able to make it work on the repl without explicit dependency on the cabal project
22:17 <Tuplanolla> Does it persist over module reloads, romanandreg?
22:17 <romanandreg> let me check
22:17 eacameron joined
22:17 atomi joined
22:18 <romanandreg> Tuplanolla: no it doesn't seem to –_–'
22:18 nilg joined
22:18 <Tuplanolla> I'll keep avoiding this problem then.
22:18 <romanandreg> I guess everytime I want pretty printing I will have to execute a command
22:18 <romanandreg> this seems
22:18 <romanandreg> annoying
22:20 doomlord joined
22:20 m0rphism joined
22:21 roboguy` joined
22:21 gesh joined
22:22 ystael joined
22:22 <lyxia> stack ghci --ghci-options "-package show-pretty"
22:24 <lyxia> or use a .ghci file
22:24 manjaro-kde5_ joined
22:25 darjeeling_ joined
22:27 mhealy joined
22:27 manjaro-kde5 joined
22:28 robertkennedy joined
22:31 hiratara joined
22:33 manjaro-kde5 joined
22:34 xaviergmail joined
22:34 mounty joined
22:35 zariuq joined
22:40 romanandreg joined
22:40 cereal_killer_ joined
22:40 sid_fules joined
22:41 grumble joined
22:42 raycoll joined
22:44 prkc joined
22:45 Voldenet joined
22:45 Voldenet joined
22:45 Shatnerz joined
22:46 danharaj joined
22:46 <MarcelineVQ> "<lyxia> stack ghci --ghci-options "-package show-pretty"" shorthand: stack ghci --package show-pretty
22:52 cosmodanger joined
22:56 Bocemb joined
22:57 Fairy joined
22:58 Guest82886 joined
23:00 robkennedy joined
23:00 sid_fules joined
23:02 winston1 joined
23:02 oisdk joined
23:03 marsam left
23:04 Noldorin joined
23:05 <Bocemb> Hi there! I've got a performance question. I define a standard list data type: (data List a = Nil | Cons a (List a) deriving Foldable) but it appears to be 8 times slower than built-in lists when doing something like length [1..1000000]. Are built-in lists treated specially? Is there a way to get closer to build-in lists using a custom list data type? Thanks!
23:06 eacameron joined
23:06 louispan joined
23:06 <Bocemb> To be more specific, here is how I build the lists: build k = case k of { 0 -> Nil; k -> Cons k (m $ k - 1)} and the same code for build-in lists but using [] and (:) instead of Nil and Cons
23:07 <Eduard_Munteanu> Bocemb, there are rewrite rules for builtin lists which may reduce the overhead (sometimes there isn't even a list to begin with)
23:07 <geekosaur> Bocemb, there is a *lot* of rewriting done for the builtins. you can dig them out of the ghc source and reproduce them for your type, but that will be annoying and painful (as will examining the Core and trying to reinvent them)
23:08 <Bocemb> Eduard_Munteanu: I see, thank you
23:08 <Bocemb> geekosaur: Right, thank you too
23:08 <Bocemb> I was just unsure whether I'm doing something wrong
23:08 <Eduard_Munteanu> Also see... https://hackage.haskell.org/package/stream-fusion-
23:08 <geekosaur> ghc attempts to fuse list operations into streams, and if it does so fully then the whole list can disappear as Eduard_Munteanu said
23:09 <geekosaur> just a generate ==> process ==> output stream pipeline
23:09 anuxivm joined
23:09 <Bocemb> I see. I was hoping some kind of fusion can also happen with simple data types like List
23:09 AndiK joined
23:09 <Bocemb> (automatically with -O2)
23:10 <Eduard_Munteanu> It is kinda sad it doesn't work with generic traversals.
23:10 justanotheruser joined
23:10 <geekosaur> there's a little of that, but mostly ghc depends on rewrite rules
23:11 <Eduard_Munteanu> It might make sense for List, Stream and perhaps some trees, not sure about others.
23:11 <geekosaur> ^
23:11 <geekosaur> there's only so much you can do without altering strictness etc.
23:11 tfc joined
23:12 <Bocemb> OK, thanks. I'll look into rewrite rules. My actual data type is quite similar to tree and I was wondering how come my implementation is so slow compared to lists :-) It's clear now
23:14 slo joined
23:14 robertkennedy joined
23:15 <Eduard_Munteanu> For stream processing, conduits may be of interest to you.
23:16 eacameron joined
23:16 CRM114 joined
23:16 <Bocemb> Eduard_Munteanu: it's more of a container data structure, but in this particular benchmark I'm consuming it in a stream fashion
23:17 <Bocemb> (although, presumably all containers are supposed to be consumed by some folds)
23:18 tomphp joined
23:19 sid_fules joined
23:20 louispan joined
23:20 romanandreg joined
23:20 eacameron joined
23:20 <hexagoxel> does the import-Prelude-last trick to avoid warnings not work when it has "hiding.." stuff?
23:23 ystael joined
23:24 Varis joined
23:24 <tnks> when edwardk says "Yoneda f is in some sense smaller than Codensity f" what exactly is the best way to formalize "bigger"?
23:25 <tnks> I always I feel I'm inferring what's meant, and worry that I'm imprecise/incorrect.
23:25 Edith joined
23:27 <tnks> actually, I think it's just about a homomorphism, and not an isomorphism.
23:27 Jeanne-Kamikaze joined
23:28 eacameron joined
23:30 <johnw> tnks: I think it's like the fact that Free f a is bigger than f a, because there are values of Free f a you can distinguish between that are indistinguishable when reduced to their mutually equivalent f a
23:30 <johnw> so to prove what he said about Yoneda and Codensity, you'd just need to find two such Codensity constructions
23:31 jomg joined
23:31 <johnw> ah
23:31 tromp joined
23:31 <johnw> it's because Yoneda f a is isomorphic to f a, and hence bijective, while Codensity f a is larger than f a, and hence surjective
23:31 Boomerang joined
23:32 <tnks> johnw: okay, this is all jiving with what my intuition is.
23:34 Gurkenglas_ joined
23:35 Goplat joined
23:37 bjz joined
23:37 eacameron joined
23:40 oisdk joined
23:42 carlomagno joined
23:44 xaviergmail joined
23:45 zcourts joined
23:45 marfoldi joined
23:46 marcopullo joined
23:47 Rainb joined
23:48 hive-mind joined
23:48 jao joined
23:49 cyborg-one joined
23:49 sid_fules joined
23:51 sid_fules joined
23:51 faberbrain joined
23:54 romanandreg joined
23:55 <ski> `Yoneda f a' isn't iso to `f a', for any old `f'. only for functors `f'
23:55 sepp2k joined
23:55 <ski> (likewise with `Coyoneda f a' vs. `f a')
23:55 contiver joined
23:55 <ski> `Yoneda' can be thought of as some kind of interior, while `Coyoneda' would then be closure
23:56 sid_fules joined
23:57 <ski> (specifically, upper interior resp. upper closure)
23:57 <ski> we can go `Yoneda f >---> f', for any `f', and also `f >---> Coyoneda f', for any `f'
23:58 <ski> to go in the other directions, we need `f' to be a functor
23:58 louispan joined
23:58 sillyotter joined
23:58 <ski> i suspect this is more or less what edwardk meant by that "Yoneda f is in some sense smaller than Codensity f"
23:58 <ski> tnks,johnw ^