<    April 2017    >
Su Mo Tu We Th Fr Sa  
 2  3  4  5  6  7  8  
 9 10 11 12 13 14 15  
16 17 18 19 20 21 22  
23 24 25 26 27 28 29  
00:00 maffh joined
00:00 <monochrom> fragamus: I am too lazy to install Stack. Could you post a sample output?
00:01 cpennington joined
00:02 cpup joined
00:02 lambda-11235 joined
00:02 infinity0 joined
00:02 <erisco> I think fragamus is still working on it and just wants us for the moral support
00:03 plot joined
00:03 <monochrom> Ah then there is a perfect despair.com poster for this... :)
00:05 <monochrom> https://despair.com/collections/posters/products/aspiration
00:05 infinity0 joined
00:05 Rodya_ joined
00:06 <glguy> aspiration: the action or process of drawing breath.
00:07 erikd joined
00:07 ehsanullahjan joined
00:08 infinity0 joined
00:08 <monochrom> The motivational speech has been cancelled because the speaker was hopitalized for an aspiratory infection. :)
00:09 <Eduard_Munteanu> Hehe.
00:09 nathanic joined
00:10 <* hodapp> smacks monochrom
00:10 infinity0 joined
00:12 <fragamus> ok I added that sample
00:12 <fragamus> https://gist.github.com/fragamus/6a54eb38952aaeefdf32a5e0636cec11
00:12 <fragamus> in a comment to the gist
00:12 <* Welkin> hands hodapp his app
00:12 <Welkin> hold this for me
00:12 oisdk joined
00:13 <monochrom> Ah then what Eduard_Munteanu said. You keep recursion on . so you never run the else-branch so you never increase the number state.
00:13 <monochrom> s/recursion/recursing/
00:14 <Welkin> is anyone using nix on mac os sierra? o.o
00:14 <Welkin> I can't get it working
00:14 <hodapp> Welkin: that level of pun density is inappropriate, sir.
00:14 <monochrom> No that's not right.
00:15 sophiag joined
00:15 geekosaur joined
00:15 mizu_no_oto joined
00:15 Aruro joined
00:15 <monochrom> What is the type of ls?
00:17 oisdk joined
00:17 robkennedy joined
00:17 <monochrom> What does view do and what is its type?
00:18 <geekosaur> they're both from the Turtle package
00:18 <iqubic> What is the Turtle package?
00:18 <c_wraith> turtle is a package for writing shell scripts in haskell
00:18 peterbecich joined
00:18 <iqubic> Oh. I thought it was a Graphics package.
00:19 barbos joined
00:19 <c_wraith> it was a pun on "shell". Graphics would also have made sense, for a different reason.
00:20 <monochrom> I'm sure someone will make a graphics library and call it "Shell" because it puns on "turtle". And that will complete the confusion. :)
00:20 <fragamus> i simplified it: https://gist.github.com/fragamus/6a54eb38952aaeefdf32a5e0636cec11
00:20 <fragamus> same as before though
00:21 biglambda joined
00:21 <iqubic> monochrom: You may or may not be familiar with turtle graphics, but basically you use sequential commands to tell the code where to draw.
00:21 <geekosaur> and justify the pun because portableGraphicsIsHell
00:22 <Eduard_Munteanu> fragamus, that no longer recurses
00:22 <monochrom> I am actually not sure who is printing the "((),1)" at all.
00:22 mithrandeer joined
00:22 <fragamus> yeah but the lstree does the recursion to traverse the tree
00:22 cpup joined
00:23 <monochrom> Does lstree call filePathProducer? Does ls call filePathProducer?
00:24 <monochrom> Also, the "extra" information "ls recurses" still doesn't explain who is printing the "((),1)" at all.
00:24 <Eduard_Munteanu> As far as I can tell, it should call modify just once.
00:24 {emptyset} joined
00:24 <c_wraith> I think it's a nondeterministic monad
00:24 snowalpaca joined
00:27 jao joined
00:27 <monochrom> I have a hunch that in general "StateT X (your nondeterministic monad here)" the behaviour is to fork the initial state over the multiple branches.
00:27 <fragamus> yes c_wraith
00:27 <fragamus> oh man that sucks
00:27 <fragamus> anything i can do about it
00:28 <monochrom> Use an IORef.
00:28 <fragamus> looking that up
00:28 bjz joined
00:29 <monochrom> This is why StateT is fake state. The illusion is burst under forkIO and [].
00:29 <fragamus> the IORef thing looks very naughty
00:29 <iqubic> Why is StateT bad?
00:30 <monochrom> Because you misread.
00:30 <monochrom> But I guess Elizer would misread too.
00:31 <c_wraith> :t join (,) . (+1)
00:31 <lambdabot> Num b => b -> (b, b)
00:32 rblaze1 joined
00:32 cpup joined
00:33 <fragamus> so non-fake state really requires IO it seems
00:34 jmcarthur joined
00:34 <monochrom> Or maybe Turtle already has a similar service so you don't have to touch IO directly.
00:34 newhoggy joined
00:35 MrWoohoo joined
00:35 <monochrom> I am still too lazy to read Turtle doc.
00:35 mtn joined
00:35 <monochrom> despair.com is so much more fun...
00:35 <iqubic> > let x = join (,) . (+1) in x 5
00:35 <lambdabot> (6,6)
00:35 <iqubic> I see how that works
00:36 <iqubic> :t join
00:36 <mtn> Hi! Any chance I could get some guidance figuring out why my ghci is broken?
00:36 <lambdabot> Monad m => m (m a) -> m a
00:36 <iqubic> mtn: What seems to be the issue?
00:36 <monochrom> Chance is proportional to information divulged.
00:36 <mtn> So I installed it through stack based on the instructions provided at https://github.com/bitemyapp/learnhaskell
00:37 <iqubic> Sure.
00:37 <iqubic> What is wrong with that?
00:37 <mtn> When I run `stack ghci file.hs` for example, I see "Warning: Couldn't find a component for file target path/to/file. Attempting to load anyway."
00:37 <mtn> And the file fails to load
00:38 <mtn> I found the source on github but couldn't decipher it
00:38 <iqubic> mtn: I get the same error.
00:38 <iqubic> Though I wouldn't call that broken.
00:38 <mtn> iqubic: What do you mean by that? :P
00:38 <iqubic> What directory are you in when you start the repl?
00:39 <mtn> I'm in the directory contiaining the file I want to run
00:39 <mtn> or load, rather
00:39 <iqubic> Oh, well then I have no idea what's wrong
00:39 <MarcelineVQ> it still loads the file yeah?
00:40 <MarcelineVQ> oh you said it does fail after all
00:40 <mtn> Nope, it doesn't
00:40 sproingie joined
00:40 <iqubic> What do you mean it doesn't?
00:40 <fragamus> Turtle seems to be lacking any state
00:40 <c_wraith> mtn: what does it do if you just use ghci instead of stack ghci?
00:40 <mtn> Though it doesn't display any other error message or anything
00:41 <mtn> c_wraith: I don't have any other ghci. I currently have ghci as an alias for stack ghci
00:41 <iqubic> I think that's an issue then.
00:41 <c_wraith> mtn: stack doesn't have its own ghci. It's definitely installed on your system
00:41 <mtn> c_wraith: And if I remove the alias, it results in "command not found", so it's not conflicting
00:41 <c_wraith> mtn: though apparently not in your path
00:41 <iqubic> mtn, that's your issue.
00:41 <MarcelineVQ> use stack exec ghci -- foo.hs to load a file like normal ghci
00:41 <iqubic> I think.
00:41 <mtn> Oh, that makes sense
00:42 <MarcelineVQ> stack ghci works in a project sense and you're not in a project, I suspect
00:42 <mtn> Yea, that's right. If I run which stack ghci, something comes up, but nothing if I run which ghci
00:42 <iqubic> Do you have a stack project created already?
00:42 Hunter1 joined
00:43 <mtn> iqubic: Nope, I was just testing it on individual files
00:43 <iqubic> mtn, that's your issue.
00:43 <MarcelineVQ> that should probably be stack exec -- which ghci
00:43 <fragamus> monochrom that is startling about stateT being fake state. Perhaps there's some fundamental principle that forces state to be in IO
00:43 <iqubic> If you want to run "stack ghci" then you need a stack project.
00:44 <mtn> MarcelineVQ: Oh I see, I think that's the location of my ghci
00:44 <mtn> Should I be adding that to my path?
00:44 <MarcelineVQ> no
00:44 <mtn> Sorry, pretty clueless
00:44 <iqubic> You should update your path so that you can run regular ghci, without the alias.
00:45 <iqubic> What is the output of "which ghci"?
00:45 <monochrom> fragamus: To be fair, IO is too big, but what you're looking at is something like "you can't just combine a quiet engine with a high-power engine to get a quiet high-power engine"
00:45 <mtn> iqubic: None
00:45 <monochrom> (Tony Hoare's analogy!)
00:46 <MarcelineVQ> mtn: https://docs.haskellstack.org/en/stable/GUIDE/#ghci-the-repl
00:46 <Eduard_Munteanu> Nice.
00:46 <geekosaur> fragamus, the question here is not really state. it's _shared_ state
00:47 <fragamus> well i just hadn't thought about this enough
00:47 <monochrom> Yeah, you can't just combine a state monad and a nondet monad to get...
00:47 <geekosaur> if the monad is doing something that causes the state to be shared, then the private state model of State will not work
00:47 <MarcelineVQ> though that won't say anything that wasn't just said, it's a link to docs where you can learn more about stack in general. short story if you don't have a system level ghc and you installed your ghc with stack you use stack commands to interact with it
00:47 <geekosaur> you need a shared state model, which is what STRef and IORef provide
00:47 <fragamus> my monad is quiet though
00:47 a3Dman joined
00:47 <monochrom> :)
00:47 <Eduard_Munteanu> You could probably make it work if you had the nondet monad as a transformer *over* StateT.
00:47 JeanCarloMachado joined
00:48 <fragamus> I think Turtle wants to be at the bottom
00:48 <monochrom> You need state to be deeply integrated as part of the nondet mechanism. They have inseparable interactions.
00:48 <geekosaur> Turtle is a fancy IO monad, so yes
00:48 <MarcelineVQ> the only path you should add manually is ~/.local/bin because stack will place certain executables you install via stack there
00:49 <geekosaur> monochrom, actually I'd say that combination worked perfectly: fragamus got a non-deterministic state monad. But that's rarely what one wants...
00:50 <fragamus> and its quiet
00:50 <monochrom> Yeah, in "you need state to be..." I mean the common expectation of state.
00:51 <mtn> iqubic: MarcelineVQ: Thanks for the help guys!
00:52 jsgrant__ joined
00:52 ziyourenxiang joined
00:52 takle joined
00:53 <iqubic> mtn: Have you solved your issues?
00:53 <monochrom> Tangential: I know how to add incremental parsing and yield to parsec, but it has to be ParsecT Cont rather than ContT Parsec.
00:53 <fragamus> these IORefs are like the apple in the garden of eden
00:53 <fragamus> I never tried one before
00:54 <monochrom> If Steve Jobs found out where Eden is, would he open an Apple Store there? :)
00:55 Moto-chan joined
00:55 Moto-chan joined
00:55 <monochrom> Oh I have a cunning plan! Create a tmp file. Put your state in the tmp file.
00:55 <iqubic> monochrom: Yes, he would
00:55 happyfeet joined
00:56 <monochrom> Or environment variable!
00:56 <mtn> iqubic: Not quite yet. I'm looking at https://wiki.haskell.org/Haskell_in_5_steps at the moment
00:56 <mtn> iqubic: What confuses me is that they seem to only say to get stack and then include a header in each file so it runs, I think
00:56 roconnor joined
00:56 <happyfeet> hey there, anyone here can help me with catamorphisms?
00:57 <iqubic> mtn: You don't need any headers at all.
00:57 JLP1 joined
00:57 <iqubic> Not sure why anyone would say that you need that.
00:57 <mtn> iqubic: I assume this isn't the full story: https://haskell-lang.org/get-started/osx ?
00:58 <mtn> iqubic: Becuase I already have stack, but if no ghci (or at least no ghci in path, and I'm not sure where it might be"
00:59 <iqubic> Yeah, you should have ghci.
00:59 <mtn> Am I missing something, or should it come with stack and automatically be in path?
01:00 ystael joined
01:02 <sm> mtn: "ghci" may not be in your PATH, but "stack ghci" should run one stack has installed
01:03 oisdk joined
01:03 <mtn> sm: Right. Does `stack ghci` bringing up a ghci instance imply that I have ghci installed somewhere?
01:03 <sm> yes, "stack exec -- which ghci" shows where
01:03 m0cesta joined
01:04 <mtn> sm: Oh okay. And should I add what is returned to my path?
01:04 <geekosaur> the problem is, running it from outside of stack is problematic
01:04 <MarcelineVQ> mtn: to reiterate from earlier, to load a specific single file from the command line it's stack exec ghci -- myfile.hs and alternatively you can type stack ghci and use :load
01:04 <sm> no, you probably shouldn't
01:04 <geekosaur> because stack also sets up package visibility, and if you chaneg that outside of stack you can get (mostly nasty) surprises
01:04 ertes joined
01:04 <geekosaur> you should let stack manage it
01:04 <mtn> Oh okay. Sorry if I'm going in circles
01:05 <mtn> I'm not quite understanding what I need to do to have just `ghci` work though
01:05 <sm> better to alias "ghci" to "stack ghci"; or, do a manual installation of ghc/ghci yourself for use apart from stack
01:05 ephemeral joined
01:05 <MarcelineVQ> you can alias stack exec ghci if you like
01:05 <mtn> Right; I had an alias previously. The reason I started looking into this was that file loading failed
01:05 <MarcelineVQ> stack ghci isn't the same thing as stack exec ghci in the case of wanting to load a specific file
01:06 <mtn> perhaps alias stack exec ghci -- as ghci?
01:06 <mtn> that loads files as expected
01:07 Rodya_ joined
01:09 thunderrd_ joined
01:09 unyu joined
01:10 a3Dman joined
01:10 <mtn> Unrelated, and sorry for these boring trouble-shooting problems. Syntastic doesn't seem to work (vim plugin) for haskell, though I installed hlint through stack
01:11 <mtn> Does anyone use the plugin and have any idea why that might be? Hlint comes up as the active checker on :SyntasticInfo
01:11 <m0cesta> I just can't understand: http://rosettacode.org/wiki/Combinations#Haskell (see "Dynamic programming" section)
01:11 <MarcelineVQ> have a gander at http://www.stephendiehl.com/posts/vim_2016.html if you haven't, I don't use vim myself
01:11 ubsan_ joined
01:12 <mtn> MarcelineVQ: Thanks again!
01:13 mjora7 joined
01:13 isBEKaml joined
01:15 newhoggy_ joined
01:17 arpl left
01:17 <geekosaur> oy, tying the knot. yes. that will break your brain
01:17 justanotheruser joined
01:17 scottj joined
01:18 Moto-chan joined
01:18 Moto-chan joined
01:18 gugah joined
01:19 takle joined
01:20 <lyxia> m0cesta: Do you know dynamic programming? Though I don't think you actually gain much from dynamic programming anyway for this problem...
01:20 homesitter joined
01:21 newhoggy joined
01:21 wroathe joined
01:22 <geekosaur> m0cesta, what's going on here is that combsBySize produces each comb by length as a lazy list. if an element of that list is demanded, it will be computed then; and siunce the computation is recursive, that reuses the earlier computations because combsBySize is shared across all of the recursive calls
01:23 <geekosaur> this is a bit tricky and relies crucially on both laziness and (the way ghc implements) sharing.
01:24 justanotheruser joined
01:24 MP2E joined
01:24 haskcat joined
01:24 <m0cesta> Oh, I think I'm getting the idea
01:24 justanotheruser joined
01:25 mjora7 joined
01:25 <geekosaur> https://wiki.haskell.org/Tying_the_Knot has some discussion of the basic idea
01:25 <haskcat> If `f :: a -> Int`, then (from the theoretical/lambda calculus point of view), is `f`'s type `a -> Int`, or is that merely shorthand for saying that there are a FAMILY of f's who have type `String -> Int`, `Int -> Int`, and so on..
01:26 <haskcat> Put differently, is `a` an object in Hask?
01:26 takle joined
01:26 newhoggy_ joined
01:26 replay joined
01:26 meba joined
01:27 <geekosaur> a is a set of objects in Hask, I think?
01:27 Supersonic112_ joined
01:27 mithrandeer joined
01:30 barbos joined
01:30 <erisco> a function's output also being its input
01:31 <erisco> a true ouroboros
01:33 a3Dman joined
01:34 newhoggy joined
01:35 sleffy joined
01:37 jsgrant- joined
01:39 binaryplease joined
01:39 newhoggy_ joined
01:40 eacameron joined
01:41 ChaiTRex joined
01:41 mithrandeer joined
01:41 uuplusu joined
01:43 rblaze1 joined
01:45 eacameron joined
01:46 Aruro joined
01:46 jao joined
01:47 augur joined
01:47 mithrandeer joined
01:48 eacamero_ joined
01:49 Rodya_ joined
01:50 utdemir joined
01:51 takle joined
01:53 <iqubic> Anyone know why I'm being told that ghc-mod is not being found, when using emacs?
01:54 <utdemir> iqubic: Emacs' PATH and shell's PATH variable are weirdly different. You can try `exec-path-from-shell.el`.
01:54 <benzrf> iqubic: is it installed? is it in your PATH/
01:54 <iqubic> I have ghc-mod installed.
01:55 <iqubic> I think it's in my path, yeah.
01:56 <utdemir> iqubic: You can try adding ghc-mod's path to your exec-path: https://www.emacswiki.org/emacs/ExecPath
01:56 <athan> I think phantom types could be kinda cool in STM: `writeTVar :: ... -> STM (Writes eff) ()`, `readTVar :: ... -> STM (Reads eff) ()`
01:57 PennyNeko joined
01:57 <athan> where `Writes` is a sparse type family, and there includes 3 type symbols: `ReadOnly`, `WriteOnly`, and `ReadWrite`
01:57 xcmw joined
01:58 <athan> i.e. `type family Writes WriteOnly = WriteOnly; Writes ReadWrite = ReadWrite` or something
01:59 descender joined
02:00 uuplusu joined
02:00 <athan> you could probably make it even crazier, where it has a mapping of STM-capable variables (TVars, TChans, etc), and can list whether or not they're being read from or written to
02:00 hucksy_ joined
02:00 ystael joined
02:01 fragamus joined
02:02 erikd joined
02:04 uuplusu joined
02:04 takle joined
02:04 <utdemir> Hey. I'm writing a TH function that generates a Servant API definition. However, it requires enabling -XDataKinds wherver you use that TH function. Is there any way to remove that requirement? Can I construct a Symbol without enabling DataKinds? Since I'm generating that with TH, it should not need to be pretty, it only needs to work without -XDataKinds.
02:04 <utdemir> I currently only need DataKinds because I need to construct a Symbol.
02:05 sleffy joined
02:06 <glguy> utdemir: You'll need to turn on the extension
02:08 <geekosaur> A Symbol is a type-level list; type level lists require DataKinds. "Pretty" does not matter; the machinery being available/enabled matters and that requires the extension
02:11 watabou_ joined
02:11 ludat joined
02:12 <utdemir> glguy: geekosaur: What about if I implement type level lists myself using something like `data Nil; data Cons a b`, and on a seperate module, I write a type family from my lists and type-level lists (DataKinds enabled there), and I can use that type level function in modules without enabling DataKinds right?
02:13 louispan joined
02:13 mithrandeer joined
02:13 <glguy> that won't help much with Symbols
02:14 <utdemir> glguy: Okay, thanks :(. Have a nice day.
02:14 <geekosaur> also I think while ghc used to allow some things to be used without enabling the extentoion at the use site, that is now considered a bug
02:14 homesitter joined
02:15 <utdemir> geekosaur: But it's kinda ugly to tell users of a library to "enable those extensions before using this TH function"/.
02:16 Moto-chan joined
02:17 byorgey joined
02:17 wroathe joined
02:17 <geekosaur> (a) arguably if it's possible for Symbols to be used at all there, it should already be enabled (b) TH has never *not* been ugly
02:19 vikraman joined
02:21 utdemir` joined
02:21 <fragamus> I needed streaming effects and composability, so I used pipes. I needed handy directory tree traversal so I used Turtle.lstree. I needed to have a function composed in the pipeline to count objects passing through, and do something at a certain frequency. I thought I could manage a counter in there. It didn;t work. I thought I would use StateT. it didnt work. The reason had to do with the non-determinism in Turtle.Shell.
02:21 <fragamus> I was screwed before I started. I ended up using an IORef and it works now. Where did I go wrong? How could I have avoided this? What Book would have helped?
02:22 mjora7 joined
02:23 cyborg-one joined
02:24 <Eduard_Munteanu> fragamus, I think you were bitten by too much magic in turtle, possibly not being adequately explained.
02:25 <iqubic> What even is Turtle?
02:27 ystael joined
02:28 crobbins joined
02:30 mjora7 joined
02:30 <lyxia> fragamus: looking at your latest attempt with State, maybe you just lack experience with monad transformers.
02:30 Beetny joined
02:31 Argue joined
02:31 <fragamus> Yes I had an inkling that there was non-determinism - I had reasoned that part out, but I couldnt fathom that state and non-determinism don't play well together
02:31 mithrandeer joined
02:32 <lyxia> I don't think non-determinism is the actual issue... StateT s [] can be useful.
02:33 ublubu joined
02:34 <geekosaur> don't State discussions make it clear it'[s just passing and returning extra parameters? I'd expect it to be fairly clear that if something is not passing and returning that parameter in a linear chain, the result will not behave like State
02:34 a3Dman joined
02:34 a3Dman joined
02:35 takle joined
02:35 tromp joined
02:36 louispan joined
02:36 wroathe joined
02:36 <lyxia> that's some intuition fragamus didn't have, so I guess that fact is not so clear
02:37 cpup joined
02:38 zero_byte joined
02:39 Hunter1 joined
02:39 <Eduard_Munteanu> Is there a tool these days that autogenerates FFI definitions from header files? Or should I go the old-fashioned way with c2hs et. al?
02:41 sproingie joined
02:42 takle joined
02:43 <fragamus> there was forkIO in Turtle's non-determinism; that wasn't clear to me and it broke my stateT
02:43 exferenceBot joined
02:44 JuanDaugherty joined
02:44 Moto-chan joined
02:45 ptvirgo joined
02:45 wroathe joined
02:47 uuplusu_ joined
02:47 <lyxia> the red flag was that you runStateT before applying view. So your action was always being run with the same initial state.
02:48 hexagoxel joined
02:48 eacamero_ joined
02:49 <lyxia> this means that the mistake can be spotted without knowing how turtle works
02:51 m0cesta joined
02:52 robatosan joined
02:53 eacameron joined
02:53 aarvar joined
02:54 uuplusu joined
02:56 dunx joined
02:56 wroathe joined
02:57 eacamero_ joined
02:57 osa1_ joined
02:59 a3Dman joined
03:06 sgronblo joined
03:06 wroathe joined
03:07 mbuf joined
03:08 Argue joined
03:13 otto_s_ joined
03:16 augur joined
03:16 a3Dman joined
03:17 felixsch_ joined
03:17 mithrandeer joined
03:17 augur joined
03:19 <fragamus> view has to be at the bottom of the stack like IO
03:20 <fragamus> Shell is the monad
03:21 mjora7 joined
03:23 uuplusu_ joined
03:26 wroathe joined
03:27 biglambda joined
03:27 <lyxia> and that makes it incompatible with StateT
03:27 <lyxia> at least in the way you expected it to work
03:28 butterthebuddha joined
03:29 <iqubic> Are we still talking about Turtle?
03:29 <iqubic> What's wrong with Turtle?
03:31 a3Dman joined
03:31 kazagistar joined
03:33 nicknovi1 joined
03:34 kyren joined
03:35 newhoggy joined
03:36 Rodya_ joined
03:37 mizu_no_oto joined
03:37 wroathe joined
03:39 <monochrom> fragamus: You may enjoy this simpler example:
03:39 <fragamus> : o
03:39 <monochrom> > runStateT (do { x <- [3, 10]; modify (+ x) }) 0
03:39 <lambdabot> error:
03:39 <lambdabot> • Couldn't match type ‘[]’ with ‘StateT s m’
03:39 <lambdabot> Expected type: StateT s m s
03:39 <monochrom> Oh!
03:39 <monochrom> > runStateT (do { x <- lift [3, 10]; modify (+ x) }) 0
03:39 <lambdabot> [((),3),((),10)]
03:40 <monochrom> So this is the behaviour of StateT Integer [].
03:40 <fragamus> that's nice and concise
03:40 <monochrom> Shell is a bit more (closer to StateT Integer (ListT IO)) but I think plain [] illustrates the point sufficiently.
03:40 tromp joined
03:41 <fragamus> wait what is the end state
03:41 <monochrom> There are two end states. 3 and 10 respectively.
03:41 <fragamus> oh right
03:42 <monochrom> When you do modify (+ 10) it restarts from the initial 0 and isn't aware that there was a "previous" (modify +3)
03:42 butterth_ joined
03:42 <monochrom> You don't get one single 13, you get [3, 10]
03:42 <monochrom> Initial state is forked over the two branches.
03:43 butterth_ left
03:43 <monochrom> It's why I conjectured that in general "StateT (a nondet monad here)" is not going to let the state interact with the nondet.
03:43 sssilver joined
03:44 biglambda joined
03:44 <fragamus> so zooming out a sec, I don;t think that having streaming effectful pipes where one of the pipes is a counter that does some effect periodically is an unreasonable thing to want. What would be the most idiomatic way to get that
03:44 <fragamus> well think and answer some time in the future if you like
03:45 <fragamus> the IORef makes me want to take a shower but it's working
03:45 <monochrom> That depends on the exact semantics of "streaming effectful pipes". This is a meaningful phrase that admits too many conflicting meanings.
03:46 cschneid_ joined
03:46 <fragamus> ok well Im using Pipes and Pipes.Core
03:46 Aruro joined
03:46 <monochrom> I think when the Turtle doc says "streaming" it's half truth and half concealing.
03:46 <fragamus> yeah thats true
03:46 <monochrom> Ah I don't actually know pipes. I don't know what to do there.
03:47 wroathe joined
03:47 <monochrom> But pipes doesn't do nondet so there is one fewer thing to worry about.
03:47 conal joined
03:48 takle joined
03:48 <fragamus> When you choose your composition operator Pipes decides how to connect stuff.
03:48 <fragamus> push vs pull etc
03:50 tromp joined
03:50 newhoggy joined
03:50 <iqubic> Is there a way to specify the type of the input to a lambda?
03:51 <iqubic> (\z a b -> z^2 + (a :+ b))
03:51 eacameron joined
03:51 <iqubic> I want to specify that z needs to be of type Complex Double
03:51 <lyxia> with ScopedTypeVariables \(z :: Double)
03:52 <iqubic> lyxia: I'd want \(z :: Complex Double)
03:52 <lyxia> uh, yeah
03:52 <iqubic> Will that work?
03:52 <Maxdamantus> (\z a b -> (z :: Complex Double)^2 + (a :+ b))
03:52 <lyxia> otherwise you do this indirectly by annotating the whole function, or one of the use sites of z
03:52 <lyxia> iqubic: it will
03:53 <iqubic> lyxia, z is only ever used in that lambda.
03:54 bjz joined
03:54 <lyxia> did what I said contradict that
03:55 <iqubic> No.
03:56 louispan joined
03:56 <iqubic> So I do that, and then I'm told that a is invalid
03:57 zv joined
03:57 wroathe joined
03:57 a3Dman joined
03:57 {emptyset} joined
03:59 forgottenone joined
04:01 pisomojado joined
04:02 newhoggy joined
04:02 flatmap13 joined
04:06 newhoggy joined
04:06 a3Dman joined
04:09 sleffy joined
04:09 Fylwind joined
04:10 <iqubic> What the difference between (^) and (**)?
04:10 <glguy> The types
04:10 <iqubic> :t (^)
04:10 <lambdabot> (Num a, Integral b) => a -> b -> a
04:10 <iqubic> :t (**)
04:10 <lambdabot> Floating a => a -> a -> a
04:11 <iqubic> Ah. Is that the only difference?
04:13 evtl joined
04:13 Argue joined
04:13 <iqubic> Which is easier to read: ((<= 2) . Magnitude) or (\z -> Magnitude z <= 2) ?
04:14 <iqubic> @pl (\z -> Magnitude z <= 2)
04:14 <lambdabot> (<= 2) . Magnitude
04:14 <rotaerk> (2 >=) . Magnitude
04:14 infinity0 joined
04:14 <iqubic> I think I like the second one better, and this is my code. I'll use the second one.
04:15 codesoup joined
04:15 newhoggy joined
04:17 sproingie joined
04:17 wroathe joined
04:18 sgronblo joined
04:19 <plot> q
04:20 a3Dman joined
04:20 kadoban joined
04:22 <iqubic> Isn't there a library for automatic differentiation? How does that library work exactly?
04:22 <iqubic> I don't mean how do I use that library. I mean, how does that library do the differentiation?
04:22 <glguy> What have you read about it so far?
04:24 newhoggy joined
04:24 <iqubic> I know that it takes an equation like ((x^2) + 7x) `div` (x) and finds the slope at a certain point.
04:24 <iqubic> So like if I gave it that equation and 7, it would find the instantaneous slop at x = 7
04:24 <glguy> There's stuff written online that you should be able to find using a search engine that will give you a lot more background than that
04:24 <iqubic> But *HOW* Does it do that.
04:25 Welkin joined
04:25 <iqubic> Can I pattern match on a complex number, or should I use RealPart, and ImagPart?
04:25 <iqubic> Sorry, realPart and imagPart
04:27 ichor joined
04:28 wroathe joined
04:29 newhoggy joined
04:30 modal joined
04:30 hexfive joined
04:31 nomicflux joined
04:31 connrs joined
04:31 BartAdv joined
04:32 mithrandeer joined
04:32 a3Dman joined
04:32 forgottenone joined
04:33 xcmw joined
04:34 kamog joined
04:35 sproingie joined
04:35 nomotif joined
04:36 takle joined
04:37 Rodya_ joined
04:38 newhoggy joined
04:39 <suzu> iqubic automatic differentiation works by using typeclass magic
04:40 <suzu> if i recall correctly, it was a typeclass defined on their internal ForwardDouble type
04:41 forgottenone joined
04:41 a3Dman joined
04:42 robatosan joined
04:44 sgfltx joined
04:44 <ertes> iqubic: you have a math background, right?
04:46 <suzu> ah here it is
04:46 <suzu> https://hackage.haskell.org/package/ad-4.3.3/docs/src/Numeric-AD-Internal-Forward-Double.html#ForwardDouble
04:46 <ertes> iqubic: if yes, you may be interested in this talk, and yes, it's relevant to your question: https://www.youtube.com/watch?v=zmhd8clDd_Y
04:46 <suzu> so a ForwardDouble is a pair (value, deriviative)
04:46 godel joined
04:46 <godel> !def zip
04:47 <ertes> @src zip
04:47 <lambdabot> zip (a:as) (b:bs) = (a,b) : zip as bs
04:47 <lambdabot> zip _ _ = []
04:47 <suzu> and then there's a Floating instance for ForwardDouble where sums and multiplication use the product rule and sum rule of calulus
04:47 tristanp joined
04:47 <suzu> and then there's some predefined values for pi and e^x and such
04:47 <godel> I'm trying to write zip without using explicit recursion
04:47 <godel> do you hace any idea of how to do that?
04:47 <godel> I tried using fold, but had no luck
04:48 wroathe joined
04:48 newhoggy joined
04:48 <suzu> you can do it with some maps godel
04:48 <suzu> a map and currying into a two-tuple..? i think
04:49 <godel> map (,)
04:49 <godel> mmm
04:49 <godel> I mean no
04:49 <ertes> godel: folds can be stateful, and you can have the second list as state, while folding the first
04:49 <ertes> godel: http://ertes.eu/tutorial/foldr.html#stateful-folds
04:49 <godel> I like suzus idea better i think
04:49 <suzu> lol yeah map with (,)
04:49 <suzu> twice
04:49 <suzu> its ghetto but it'll do it i think
04:50 <godel> tbh this is homework
04:50 <godel> but I've been thinking about it for a while
04:50 <ertes> suzu's suggestion is to imitate the Applicative instance of ZipList =)
04:51 <suzu> ¯\_(ツ)_/¯ if you dont want recursion you gotta do what you gotta do
04:51 <godel> yea, its without recursion
04:51 <godel> well, we can use things like map or foldr
04:52 <ertes> godel: remember that (,) is curried, as are most multi-arg functions in haskell
04:52 <godel> yes yes
04:52 <ertes> godel: check the type of (map (,)), and it should be fairly straightforward to do
04:52 <suzu> iirc currying (,) wasnt possible without some lang extn before
04:52 <suzu> i may be wrong
04:52 newhoggy_ joined
04:53 <suzu> err rather using (,) as a constructor wasnt always a thing?
04:53 <ertes> suzu: you may be referring to sections… tuple sections need an extension: TupleSections
04:53 <ertes> like: (, 5)
04:53 <suzu> yup that's it
04:53 <godel> yea
04:53 <godel> use zipwit
04:53 <godel> zipWith? but thats cheating I think
04:54 <godel> cause literally the next exercise tells me to implement zipWith (that's easy)
04:54 <suzu> don't use zip in your impl of zip
04:54 <godel> lol
04:54 <suzu> oh uh
04:54 <suzu> what
04:54 <suzu> lol okay
04:54 a3Dman joined
04:55 <godel> lol
04:55 <godel> if I have
04:55 <godel> map (,) xs where xs :: [a]
04:55 <godel> when map (,) xs :: [b -> (a,b)]
04:56 <ertes> godel: you're not going to use the fold approach, right?
04:56 flatmap13 joined
04:56 <godel> let me think a sec about that approach
04:56 <ertes> good, then i won't spoil it =)
04:59 <ertes> actually i don't think you can do it without a fold, unless you have other list functions at your disposal
05:00 <ertes> because the ZipList approach requires an equivalent to (<*>), which is pretty much zipWith already
05:00 <suzu> yeah i just tried this myself
05:00 <suzu> i need a zip to implement the zip
05:00 <suzu> lol
05:00 <suzu> i think the fold is the right way to go
05:00 <godel> a zipWith
05:00 <godel> zipWith ($)
05:00 <godel> lol
05:00 <suzu> yeah that'll do it
05:00 <godel> yea, I'm thinking it with fold
05:01 <godel> I like your post
05:01 <suzu> post?
05:01 <godel> ertes'
05:01 <ertes> thanks… also the section about stateful folds comes up often enough that i should perhaps write a self-contained version of it
05:01 <ertes> suzu: http://ertes.eu/tutorial/foldr.html#stateful-folds
05:01 <suzu> oh that!
05:01 <suzu> :)
05:02 <suzu> ertes do you write haskell professionally?
05:02 newhoggy joined
05:03 <ertes> suzu: yes, but it's just part of my job, not the main thing
05:04 wroathe joined
05:04 takle joined
05:05 louispan joined
05:05 <ertes> interestingly my fold approach yields a function that is more general than zipWith =)
05:06 <ertes> :t fAp
05:06 <lambdabot> Foldable t => t (t1 -> a) -> [t1] -> [a]
05:06 <ertes> that name is… unfortunate…
05:06 nomicflux joined
05:07 juiko joined
05:07 <ertes> @let data V3 a = V3 !a !a !a deriving (Eq, Foldable, Functor, Ord, Show, Traversable)
05:07 <lambdabot> Defined.
05:07 <ertes> > fAp (V3 sin cos tan) [1,2,3]
05:07 mmachenry joined
05:07 <lambdabot> [0.8414709848078965,-0.4161468365471424,-0.1425465430742778]
05:08 forgottenone joined
05:08 <godel> ok
05:08 <godel> ertes: you are a genius
05:08 Randy joined
05:08 <godel> I think I did it
05:08 <godel> it's very ugly though
05:08 <godel> let me type it ghci
05:08 <godel> to see if it works
05:09 newhoggy joined
05:09 <monochrom> ertes: It's because if you call Prelude's foldr it generalizes to Foldable in one parameter.
05:10 osa1 joined
05:10 osa1 joined
05:10 <monochrom> It would be nailed at [] last year.
05:11 <monochrom> Err maybe two years ago. Time flies like an arrow.
05:11 <ertes> yeah
05:11 <godel> armarPares = foldr (\a mas bs -> if null bs then [] else (a, head bs):(mas (tail bs))) (const []
05:11 <godel> it's in spanish but you get the idea
05:11 <godel> can it be done more elegantly
05:11 nomotif joined
05:11 <suzu> i see ertes
05:11 <ertes> godel: i suggest that you write an auxiliary function, but it's correct
05:11 <godel> btw thanks to this method I'm gonna be the king of this course now
05:11 <suzu> i note that your blog doesn't have your real name
05:11 <godel> thank you so much
05:11 <ertes> godel:
05:12 <ertes> :t let apF f go (x:xs) = f x : go xs; f _ _ [] = [] in foldr apF (const [])
05:12 <monochrom> You should not be using null-head-tail in this context. You should use pattern matching.
05:12 <lambdabot> Foldable t => t (t1 -> a) -> [t1] -> [a]
05:12 <suzu> i've always been considering writing something but don't want to air my real name out, lol
05:12 Argue_ joined
05:12 <ertes> suzu: it does under "legal information"
05:12 <ertes> suzu: because german law actually requires it
05:12 <monochrom> ertes is as realname as I care.
05:13 forgottenone joined
05:13 <suzu> on the website? wtf for real?
05:13 <ertes> but yeah, call me ertes =)
05:13 <suzu> can't stick it in WHOIS?
05:13 <suzu> or host your site in not-germany
05:13 <monochrom> The real difficulty is not realness, but rather uniqueness. ertes goes by a different name on haskell-cafe. That's the only hurdle.
05:13 <monochrom> Or rather, s/uniqueness/aliasing/
05:13 <MarcelineVQ> is it setre?
05:13 Randy joined
05:14 Randy joined
05:14 wroathe joined
05:14 <godel> ertes: I like this approach so much
05:14 <ertes> i could gamble, but we have lawyers ("abmahn-anwälte") who abuse the law to force money out of unwitting webmasters' pockets
05:14 <godel> one of the exercises was to write (++) w/o explicit recursion
05:14 <godel> (++) :: [a] -> [a] -> [a]
05:15 <godel> so what I was doing was to do
05:15 <ertes> monochrom: well, i do sign my cafe posts with "ertes" =)
05:15 <godel> (++) xs = foldr ...
05:15 <godel> but taking [a] -> ([a] -> [a])
05:15 <godel> and making foldr return functions
05:15 <godel> is brilliant
05:15 <monochrom> P.S. aliasing is also the #1 reason why reasoning about mutable data on the heap is so hard. If you see (for example C code, but not confined to C) " *p = 4; *q = 5; " you don't know what to predict because you aren't sure whether p and q are pointing to the same damn cell.
05:15 <suzu> stick yo func in the accumulator
05:15 <suzu> and modify as you go
05:15 <godel> it's great
05:16 <suzu> the state monad and several other things work similarly
05:16 <monochrom> And John Reynolds the Great barely started with solve it by his "separation logic" not long before he died.
05:16 <ertes> you can actually use StateT with foldr =)
05:16 <suzu> actually, not exactly - its a bit far off so scratch that analogy
05:16 <monochrom> s/with/to/
05:16 teggi joined
05:16 <ertes> but in most cases you can just use 'traverse_'
05:17 chc4 joined
05:17 <ertes> foldr is only required if the fold needs some state of its own in those cases
05:17 newhoggy joined
05:17 <ertes> :t foldr (\x go -> print x >> go) (pure ())
05:17 <lambdabot> (Show a, Foldable t) => t a -> IO ()
05:17 <ertes> :t traverse_ print
05:17 <lambdabot> (Show a, Foldable t) => t a -> IO ()
05:18 <ertes> and in most cases you can just factor the stateful part out of the fold
05:19 a3Dman joined
05:19 <ertes> :t foldr (\x go n -> if n > 0 then print x >> go (n - 1) else pure ()) (\_ -> pure ())
05:19 <lambdabot> (Show a, Num t1, Ord t1, Foldable t) => t a -> t1 -> IO ()
05:19 <ertes> :t flip $ foldr (\x go n -> if n > 0 then print x >> go (n - 1) else pure ()) (\_ -> pure ())
05:19 <lambdabot> (Show a, Num t1, Ord t1, Foldable t) => t1 -> t a -> IO ()
05:19 <ertes> :t \n -> traverse_ print . take n
05:19 <lambdabot> Show a => Int -> [a] -> IO ()
05:19 <ertes> state factored out
05:21 Xanather joined
05:24 wroathe joined
05:27 <iqubic> What the heck is StateT, and how does it differ from a regular State?
05:27 <johnw> iqubic: it's a monad transformer
05:28 <johnw> State s a = StateT s Identity a
05:28 <iqubic> :t state
05:28 <lambdabot> MonadState s m => (s -> (a, s)) -> m a
05:28 meba joined
05:28 <ertes> @src StateT
05:28 <lambdabot> Source not found. Where did you learn to type?
05:28 <iqubic> johnw: Why do we care about StateT, when we have State?
05:29 <johnw> sometimes you want to mix state and some other monad
05:29 FreeBirdLjj joined
05:29 <johnw> for example, IO
05:29 <iqubic> What does that mean?
05:29 <johnw> that way, your decision about what to do in IO can depend on the prevailing state
05:29 newhoggy joined
05:29 <ertes> @src State
05:29 <lambdabot> type State s = StateT s Identity
05:29 <lambdabot> --OR
05:29 <lambdabot> data State s a = State { runState :: s -> (a, s) }
05:29 <iqubic> Sure.
05:30 <iqubic> So a monad transformer let's change which monad you're using?
05:30 <iqubic> Like if you want to mix State and IO?
05:30 <ertes> iqubic: a monad transformer takes a monad and gives you a monad in return
05:30 <johnw> not so much change
05:30 <johnw> think of it like layering
05:30 <ertes> iqubic: MaybeT :: (* -> *) -> (* -> *)
05:30 <iqubic> Can I see an example of that in use?
05:30 <johnw> "state in the presence of another monad"
05:31 <ertes> for example (MaybeT IO) is like IO with an additional short-circuit effect
05:31 aarvar joined
05:31 <iqubic> I want to see an example of a monad transformer in Action.
05:32 <johnw> if you google "haskell monad transformer", you'll see many examples
05:32 <ertes> > execStateT (do x <- get; guard (even x); put (2*x)) 4 :: Maybe Integer
05:32 <lambdabot> Just 8
05:32 <ertes> > execStateT (do x <- get; guard (even x); put (2*x)) 5 :: Maybe Integer
05:32 <lambdabot> Nothing
05:32 <ertes> iqubic: example of (StateT Integer Maybe)
05:34 <iqubic> How the heck can you have a function that returns an IO (Maybe String)?
05:34 _sg joined
05:34 <godel> aw man
05:34 <godel> this is sick
05:34 <simony> :t guard
05:34 <lambdabot> Alternative f => Bool -> f ()
05:34 <iqubic> Oh, wait I see now.
05:34 safe joined
05:34 <ertes> > execStateT (do x <- get; put (x + 1) <|> put (x - 1)) 5 :: [Integer]
05:34 <c_wraith> iqubic: Any IO action that might produce a String, or might now
05:34 <lambdabot> [6,4]
05:34 <c_wraith> *not
05:34 <ertes> iqubic: example of (StateT Integer [])
05:35 wroathe joined
05:35 <ertes> it's a list monad with an additional branching state effect
05:35 <iqubic> What is <|>?
05:35 <ertes> you can modify the state in one way in one branch and in another way in another branch
05:35 <simony> in these cases, is the StateT the inner monad or outer?
05:35 <ertes> > "abc" <|> "def"
05:35 <lambdabot> "abcdef"
05:36 <iqubic> Why not just use :
05:36 <iqubic> Or ++?
05:36 <iqubic> well not : because it's the wrong type.
05:36 robotroll joined
05:36 <iqubic> :t (++)
05:36 <ertes> iqubic: because (<|>) is more general… it understands that there is a [] underneath StateT
05:36 <lambdabot> [a] -> [a] -> [a]
05:36 <johnw> simony: SateT is "outer", the underlying type is: s -> IO (a, s)
05:36 <iqubic> :t (<|>)
05:36 <lambdabot> Alternative f => f a -> f a -> f a
05:37 <iqubic> So, [] is an instance of Alternative?
05:37 <ertes> simony: it's a matter of perspective… i would just say: [] transformed by (StateT Integer), or (StateT Integer) applied to []
05:38 <jle`> iqubic: you can check on ghci :) :i []
05:38 takuan joined
05:38 <jle`> the documentation for Alternative also say as well
05:38 <ertes> iqubic: (StateT S []) is quite useful in search algorithms
05:39 <iqubic> Searching?
05:39 <ertes> yeah, imagine you have a tree-like branching search with some per-branch state
05:39 <iqubic> You mean like finding all values that return True from (a -> Bool)
05:41 isBEKaml joined
05:41 <ertes> no, that's too simple
05:42 newhoggy joined
05:42 <iqubic> It is??
05:43 <simony> :t execStateT (do x <- get; put (x + 1) <|> put (x - 1))
05:43 <lambdabot> (Num s, MonadPlus m) => s -> m s
05:44 xcmw joined
05:44 <simony> :t execStateT
05:44 <lambdabot> Monad m => StateT s m a -> s -> m s
05:45 isBEKaml joined
05:45 <iqubic> Why does that need the MonadPlus constraint?
05:46 newhoggy_ joined
05:47 <ertes> @let data BTree a = Leaf | Branch a (BTree a) (BTree a) deriving (Eq, Foldable, Functor, Ord, Show, Traversable)
05:47 <simony> i'm guessing it's because execState's Monad m constraint
05:47 <lambdabot> Defined.
05:47 <ertes> @let combPred p | not (p mempty) = const []; combPred p = flip execStateT mempty . go where go Leaf = pure (); go (Branch dx ls rs) = do x' <- get; let { x = x' <> dx} ; guard (p x); go ls <|> go rs
05:47 <lambdabot> Defined.
05:47 <ertes> :t combPred
05:47 <lambdabot> Monoid t => (t -> Bool) -> BTree t -> [t]
05:48 peterbecich joined
05:48 <ertes> iqubic: this one computes the monoid-sum of each path through a binary tree, leaving out branches where any intermediate result does not satisfy the given predicate
05:48 conal joined
05:49 <ertes> > combPred even (Branch 2 (Branch 4 Leaf Leaf) (Branch 6 (Branch 7 Leaf Leaf) Leaf))
05:49 <lambdabot> error:
05:49 <lambdabot> • Ambiguous type variable ‘a0’ arising from a use of ‘show_M232416788264...
05:49 <lambdabot> prevents the constraint ‘(Show a0)’ from being solved.
05:49 wroathe joined
05:49 <ertes> > combPred even (Branch 2 (Branch 4 Leaf Leaf) (Branch 6 (Branch 7 Leaf Leaf) Leaf)) :: [Sum Integer]
05:49 <lambdabot> error:
05:49 <lambdabot> • No instance for (Integral (Sum Integer))
05:49 <lambdabot> arising from a use of ‘even’
05:49 <ertes> oh, come on…
05:50 <ertes> > combPred (even . getSum) (Branch 2 (Branch 4 Leaf Leaf) (Branch 6 (Branch 7 Leaf Leaf) Leaf)) :: [Sum Integer]
05:50 <lambdabot> [Sum {getSum = 0},Sum {getSum = 0},Sum {getSum = 0}]
05:50 <ertes> that… looks wrong…
05:50 peterbecich joined
05:50 <ertes> i forgot to put the new state =)
05:50 <ertes> @let combPred' p | not (p mempty) = const []; combPred' p = flip execStateT mempty . go where go Leaf = pure (); go (Branch dx ls rs) = do x' <- get; let { x = x' <> dx} ; guard (p x); put x; go ls <|> go rs
05:51 <lambdabot> Defined.
05:51 <ertes> > combPred' (even . getSum) (Branch 2 (Branch 4 Leaf Leaf) (Branch 6 (Branch 7 Leaf Leaf) Leaf)) :: [Sum Integer]
05:51 <lambdabot> [Sum {getSum = 6},Sum {getSum = 6},Sum {getSum = 8}]
05:51 <ertes> sorry for the noise =)
05:51 <ertes> the branch with the 7 is ignored, because there was an odd intermediate result
05:53 <ertes> you can now query this: "give me the first result", and traversal is only done until the first result is found, or "give me the first ten results", "give me all results", etc.
05:53 <iqubic> That's really cool
05:53 newhoggy joined
05:55 danthemyth joined
05:55 sssilver joined
05:56 <ertes> welcome to the rabbit hole =)
05:57 <godel> question
05:57 <godel> I wrote transpose without explicit recursion
05:57 forgottenone joined
05:58 <godel> transpose :: [[Int]] -> [[Int]]
05:58 <godel> matrix transposition
05:58 <godel> transpose = foldr (zipWith (:)) (repeat [])
05:58 <godel> fairly easy
05:58 <godel> but what if the matrix was given as a (Int -> Int -> a)
05:58 <godel> so
05:59 <godel> transpose :: (Int -> Int -> a) -> (Int -> Int -> a)
05:59 <godel> oh
05:59 <godel> im DUMB
05:59 wroathe joined
05:59 <ertes> godel: you may want to go with the general type signature right away: [[a]] -> [[a]] -- it reduces the density of wrong implementations
05:59 jer1 joined
05:59 <godel> yes yes sorry
05:59 <godel> I don't know why I wrote int
06:00 <ertes> if you had wrote 'int', it would have been general =)
06:00 <godel> transpose f i j = f j i
06:00 <godel> right?
06:00 <ertes> yeah
06:00 <godel> transpose = flip ?
06:00 <godel> mmmmmm
06:00 <simony> flip?
06:01 <godel> yea lol that was what I was thinking
06:01 <simony> :P
06:01 <godel> but the question is
06:01 <godel> can I define a scheme like map for a function (a -> b) for example?
06:01 newhoggy joined
06:01 <godel> like what would fmap be for (->)
06:01 <ertes> godel: what's the type signature?
06:02 eklavya joined
06:02 <ertes> godel: write the type signature, and it may be fairly evident
06:03 <godel> m
06:03 <godel> lol
06:03 <ertes> godel: trivial even, because there is only one correct implementation of fmap for ((->) a)
06:03 <godel> (a -> b) -> (c -> a) -> (c -> b)
06:03 <godel> (.)
06:03 <godel> mmm
06:03 <ertes> s/correct/well-typed/
06:03 <godel> but what does that mean
06:04 <ertes> exactly what you said: fmap for functions is just composition
06:04 <ertes> given a function f, to modify its result by the function g, you postcompose g: g . f
06:04 <godel> ohhhhhh
06:04 <godel> right
06:04 <godel> so easy :P
06:04 <godel> thanks ertes
06:05 <johnw> "map over the image of 'f'"
06:10 newhoggy joined
06:11 a3Dman joined
06:18 ludat joined
06:18 newhoggy joined
06:19 JuanMiguel joined
06:20 wroathe joined
06:22 ner0x652 joined
06:22 xormor joined
06:25 typedrat joined
06:26 newhoggy joined
06:26 jbgi joined
06:27 takle joined
06:28 shyn joined
06:30 wroathe joined
06:31 connrs joined
06:32 lambdaman joined
06:35 a3Dman joined
06:35 robatosan joined
06:35 eacameron joined
06:38 louispan joined
06:40 eacamero_ joined
06:40 newhoggy joined
06:44 eacameron joined
06:46 takle joined
06:47 Levex joined
06:48 newhoggy joined
06:48 eacamero_ joined
06:50 erikd joined
06:52 vlatkoB joined
06:52 Levex joined
06:52 eacameron joined
06:55 raichoo joined
06:55 newhoggy joined
06:57 eacameron joined
07:00 Levex joined
07:00 lambdaman joined
07:01 <mjora7> Should $ be used in place of parens whenever possible?
07:01 <mjora7> Or is that frowned upon.
07:02 newhoggy joined
07:02 <liste> mjora7: parens are sometimes frowned upon, we're distancing ourselves from lisp ;)
07:02 <liste> but use whichever is most readable
07:02 mfukar joined
07:02 <liste> usually haskellers consider "a . b . c . d $ e" more readable than "(a (b (c (d e))))"
07:03 <mjora7> Ok, thanks!
07:03 mmn80 joined
07:04 Gurkenglas joined
07:04 <liste> it's curious how two pieces of code with so different syntactical mechanism (function application vs lists) end up looking similar
07:05 wroathe joined
07:05 <glguy> mjora7: no, you don't need to about parentheses whenever possible
07:06 <glguy> avoid*
07:06 ninjazoete joined
07:08 eacameron joined
07:08 blym joined
07:09 Denthir joined
07:09 takle joined
07:09 newhoggy joined
07:10 pyx joined
07:11 Kreest__ joined
07:12 tromp joined
07:13 vlatkoB_ joined
07:14 insitu joined
07:17 pungi-man joined
07:17 augur joined
07:19 text1 joined
07:19 newhoggy joined
07:23 takle joined
07:25 wroathe joined
07:26 newhoggy joined
07:27 danzimm joined
07:27 osa1_ joined
07:29 wires joined
07:32 newhoggy joined
07:32 blym_ joined
07:32 Kreest__ joined
07:35 osa1 joined
07:35 osa1 joined
07:36 wroathe joined
07:36 robatosan joined
07:37 Levex joined
07:38 connrs joined
07:40 newhoggy joined
07:41 blym_ joined
07:43 NeverDie_ joined
07:45 Ornedan joined
07:45 wroathe joined
07:47 cschneid_ joined
07:48 blym_ joined
07:49 xall joined
07:50 louispan joined
07:50 sproingie joined
07:50 sproingie joined
07:52 connrs joined
07:53 cpup joined
07:54 xcmw joined
07:55 blym_ joined
07:56 newhoggy joined
07:58 montik joined
08:00 barbos joined
08:01 _main_ joined
08:01 <johnw> next to ask: a . b . c . d $ e, or a $ b $ c $ d e ?
08:02 _main_ joined
08:04 _main_ joined
08:06 wroathe joined
08:06 blym_ joined
08:07 zero_byte joined
08:07 <evtl> johnw: The former, IMHO
08:07 sgronblo joined
08:09 <LiaoTao> johnw: Whatever minimizes the clutter!
08:10 <LiaoTao> :D
08:11 <geekosaur> context matters too: in xmonad layout hooks we're prone to use ($) to separate layout modifiers and (.) when needed within them
08:12 tromp joined
08:12 zariuq joined
08:14 newhoggy joined
08:14 augur joined
08:15 Argue__ joined
08:16 wroathe joined
08:18 connrs joined
08:19 xall_ joined
08:19 Argue_ joined
08:22 cschneid_ joined
08:23 Argue joined
08:23 blym_ joined
08:24 takle joined
08:24 Denthir joined
08:24 Mindless- joined
08:25 phyrex1an joined
08:25 m` joined
08:26 lep-delete joined
08:26 wroathe joined
08:27 gehmehgeh joined
08:30 takle joined
08:34 m0rphism1 joined
08:36 raichoo joined
08:37 gmcabrita joined
08:38 mettekou_ joined
08:41 raichoo joined
08:41 wires joined
08:43 Deewiant joined
08:43 blym_ joined
08:44 jutaro joined
08:44 wroathe joined
08:47 aarvar joined
08:47 baldrick joined
08:47 antfx joined
08:48 mettekou joined
08:50 oisdk joined
08:51 jabesed joined
08:51 Argue_ joined
08:52 dejanr joined
08:55 Elish joined
08:56 acidjnk22 joined
08:58 connrs joined
08:59 Argue__ joined
08:59 ner0x652 joined
09:01 barbos joined
09:02 mettekou_ joined
09:03 Argue joined
09:03 metteko__ joined
09:04 wroathe joined
09:05 seveg joined
09:06 robatosan joined
09:08 cfricke joined
09:08 mettekou joined
09:09 connrs joined
09:12 Jayflux joined
09:13 tromp joined
09:13 iomonad joined
09:16 mettekou joined
09:16 blym joined
09:16 jutaro joined
09:21 mettekou_ joined
09:22 richi235 joined
09:23 boombanana joined
09:23 barbos joined
09:23 tdfirth joined
09:25 doomlord joined
09:25 catsup joined
09:25 catsup joined
09:26 aib joined
09:28 blym_ joined
09:29 eacameron joined
09:29 danza joined
09:30 meba joined
09:32 eacameron joined
09:33 crave joined
09:33 mettekou joined
09:35 <Profpatsch> fast and loose matching on constructors, how to?
09:35 <johnw> hmm?
09:35 <Profpatsch> data Foo = A String | B Something | C … | D
09:35 <johnw> you want to pick "just B" if it's there?
09:35 <JuanDaugherty> hackage is down?
09:36 thc202 joined
09:36 <Profpatsch> parseFooToString :: Foo -> Maybe String
09:36 <Profpatsch> parseFooToString (A s) = s
09:36 blym_ joined
09:36 <Profpatsch> *Just s
09:36 <Profpatsch> parseFooToString _ = Nothing
09:36 <johnw> makePrisms ''Foo; parseFooToString = preview _A
09:36 <Profpatsch> parseFooToSomething …
09:36 <Profpatsch> Hm.
09:37 barbos left
09:37 <johnw> the lens library's prisms are really the way to do just what you want here
09:37 <Profpatsch> I see …
09:37 <johnw> and when you start mixing and matching lenses with prisms in deep structure, it's pure magic
09:37 newhoggy joined
09:38 <johnw> I have a project I was working on today that uses lenses in that way, heavily, also using the map/array accessors and state manipulators, and it made some code *so* easy to write that would have been an absolute nightmare otherwise
09:38 <Profpatsch> johnw: That’s basically also what you do when you want to transform NExprs in hnix
09:38 <johnw> yep
09:38 <johnw> do we use lens yet in hnix? we should
09:38 <Profpatsch> Probably, yes.
09:39 <Profpatsch> Better: Define Prisms without dependending on lens
09:39 mettekou_ joined
09:39 <johnw> in one module today I had this:
09:39 <johnw> _2 . at name . non (kind, M.empty) . _2 . at component . non M.empty . at meta ?= value
09:39 nilof joined
09:39 eacameron joined
09:39 <johnw> just thinking about the Haskell I'd have to write to mimick this makes my head ache
09:39 wroathe joined
09:40 <johnw> but with lens, I type it out just the way I'm thinking of the verb
09:40 <JuanDaugherty> (no hackage.org)
09:40 <srhb> I did not know about hnix. Is it being used for something in particular?
09:40 <johnw> srhb: some people tell me they use it every day
09:40 <srhb> johnw: I wonder what for. :)
09:40 <johnw> srhb: mostly, I think, for serious surgery on Nix files, or dynamically generating complex expressions
09:40 <* srhb> nods
09:40 <johnw> that's about all it can do right now
09:41 <johnw> shlevy is working on a Haskell version of the nix store
09:41 <srhb> Interesting! :)
09:41 <johnw> once we have that, we're inches away from an actual operating Nix
09:41 <srhb> That would be so cool.
09:41 <johnw> just need an evaluator to construct the derivation scripts
09:41 <srhb> I wonder if there's some not-too-complex corner I could bite at
09:41 besenwesen joined
09:41 <johnw> srhb: sure, there's plenty I'd say
09:41 <johnw> the parser need optimization
09:42 <johnw> there's notes in the GitHub issue on it about the problem
09:42 <srhb> johnw: I'll have a gander. Thank you :)
09:42 <johnw> and I wrote parsec-free to allow in depth analysis of what parsec is doing too much of
09:42 Glooomy joined
09:42 <johnw> thanks!
09:43 biglama joined
09:43 <Profpatsch> johnw: I’m not exactly in the lens flow (yet).
09:44 <johnw> Profpatsch: https://www.reddit.com/r/haskell/comments/66xqro/putting_lenses_to_work_talk_and_slides/
09:44 <Profpatsch> Especially with Traversals it’s kind of easy to do too loose matching I think.
09:44 <johnw> i don't use traversals nearly as much
09:44 <Profpatsch> Where you get [] and have no idea at which part of the chain it failed
09:44 <johnw> or least, I use the "I only want one thing" type of them
09:45 <Profpatsch> Maybe the same with deep prisms.
09:45 <johnw> you can guard your prisms accessors using "failing"
09:45 <johnw> [] ^?! failing (ix 1) (error "This list be too tiny")
09:45 <johnw> I do this a lot to get better stack traces of where my assumptions failed
09:45 eacameron joined
09:46 newhoggy joined
09:46 tsmish joined
09:48 mettekou joined
09:48 eacamero_ joined
09:49 Adeon joined
09:49 rockfordal joined
09:51 grayjoc joined
09:51 yellowj joined
09:54 beerdrop joined
09:54 kritzcreek joined
09:55 mettekou_ joined
09:55 jer1 joined
09:56 mettekou_ joined
09:57 simukis joined
09:58 bennofs joined
09:58 hurkan joined
09:59 wroathe joined
10:02 byte512 joined
10:02 LAZAR joined
10:03 <LAZAR> Does anyone know if / is overloaded to work with any kind of Num?
10:03 <Myrl-saki> Flycheck, which uses stack if it's installed is faster than stack build. Does this have something to do with `stack ghc` being faster than `stack build`?
10:03 <srhb> Does Hackage insert some kind of default bounds if the cabal file is missing them?
10:03 <johnw> :t (/)
10:03 <lambdabot> Fractional a => a -> a -> a
10:03 <LAZAR> Like in mean :: (Num a) => [a] -> Double; mean xs = (sum xs) / (length xs)
10:03 <johnw> srhb: not that I know of
10:03 <Myrl-saki> LAZAR: Nope.
10:03 <Myrl-saki> :t genericSum
10:03 <bennofs> srhb: i don't think it doe
10:03 <lambdabot> error: Variable not in scope: genericSum
10:03 <Myrl-saki> Oh no.
10:03 <Myrl-saki> :t genericLength
10:04 <lambdabot> Num i => [a] -> i
10:04 <srhb> johnw, bennofs: Hmm, okay, thanks.
10:04 <LAZAR> Hmm im trying to calculate a mean function so i want to divide the sum of any number array by its length
10:04 <Myrl-saki> LAZAR: You can't.
10:05 <LAZAR> Amazing
10:05 joeytwiddle joined
10:05 <Myrl-saki> LAZAR: Mmm.
10:05 <Myrl-saki> :t toFractional
10:05 <lambdabot> error:
10:05 <lambdabot> • Variable not in scope: toFractional
10:05 <lambdabot> • Perhaps you meant ‘toRational’ (imported from Prelude)
10:05 <bennofs> :t realToFrac
10:05 <lambdabot> (Fractional b, Real a) => a -> b
10:05 <Myrl-saki> > realToFrac 1
10:05 <lambdabot> 1.0
10:05 <Myrl-saki> > realToFrac (1 :: Int)
10:05 <lambdabot> 1.0
10:05 <bennofs> LAZAR: length returns an Int, so you need to convert that to a float with realToFrac
10:05 <Myrl-saki> bennofs: How does `Real` contrast with `Num`?
10:06 <bennofs> > let mean xs = xs / realToFrac (length xs) -- LAZAR
10:06 <lambdabot> <no location info>: error:
10:06 <lambdabot> not an expression: ‘let mean xs = xs / realToFrac (length xs) -- LAZAR’
10:06 <bennofs> > let mean xs = xs / realToFrac (length xs) in mean [1,2,3] -- LAZAR
10:06 <lambdabot> error:
10:06 <lambdabot> • Ambiguous type variable ‘a0’ arising from a use of ‘show_M575956214089...
10:06 <lambdabot> prevents the constraint ‘(Show a0)’ from being solved.
10:06 <Myrl-saki> bennofs: That still wouldn't work if xs is not Fractional.
10:06 <LAZAR> Indeed
10:06 <bennofs> LAZAR: then realToFrac sum xs as well
10:06 <LAZAR> So basically i cant generify it to Nums just to Fractional
10:06 <Myrl-saki> And realToFrac . length == genericLength, ish.
10:07 phyrex1an joined
10:07 robatosan joined
10:07 <LAZAR> Oh the boilerplate
10:07 <Myrl-saki> :t \xs -> realToFrac (sum xs) / genericLength xs
10:07 <lambdabot> (Real a1, Fractional a) => [a1] -> a
10:07 <Myrl-saki> LAZAR: If you're fine with that, at least.
10:08 <Myrl-saki> LAZAR: Turns out that I normally don't have a generalized mean function.
10:08 <Myrl-saki> lambdabot: And if I do, it's `Fractional a => [a] -> a`
10:09 <LAZAR> its just weird how generics are so cumbersome in haskell sometimes
10:09 wroathe joined
10:09 <bennofs> LAZAR: the Num hierarchy in haskell sucks
10:09 <Myrl-saki> :t (+)
10:09 <lambdabot> Num a => a -> a -> a
10:09 <Myrl-saki> ^ messed me up when I was starting.
10:11 <LAZAR> bennofs: i think its beacuse Num includes some esoteric stuff which does not support regular arithmetics defined on real numbers
10:11 <torstein> what does this mean: newtype s >> a = Named a
10:12 <LAZAR> It would be nice to have the classical math hierarchy: Complex -> Real -> Fractional -> Integer -> Natural
10:12 <srhb> LAZAR: There are alternative numerical towers in the wild, I think.
10:14 ccomb joined
10:15 fakenerd joined
10:15 <LAZAR> This works for Fractionals: mean :: (Fractional a) => [a] -> a mean xs = (sum xs) / (realToFrac (length xs))
10:16 <srhb> LAZAR: Side note, you're traversing xs twice there. You may want a different definition unless this is just example code :)
10:17 ninjazoete joined
10:17 <LAZAR> srhb: Well dont i have to traverse it twice?
10:17 <srhb> LAZAR: No, you can do a fold where you calculate the running sum and running length
10:18 oish joined
10:18 <LAZAR> oh well im doing the exercises from realworldhaskell and folds havent been introduced yet
10:18 <srhb> LAZAR: OK, great :)
10:18 <srhb> LAZAR: Just wanted to point it out.
10:18 piyush-kurur joined
10:19 wroathe joined
10:20 robatosan joined
10:22 flatmap13 joined
10:23 cschneid_ joined
10:24 mekeor joined
10:25 fenedor joined
10:28 justanotheruser joined
10:28 Yuras joined
10:28 mmn80 joined
10:28 justanotheruser joined
10:29 butterthebuddha joined
10:30 erikd joined
10:31 eklavya joined
10:31 justanotheruser joined
10:32 eacameron joined
10:33 mettekou joined
10:34 homesitter joined
10:38 cpennington joined
10:39 wroathe joined
10:41 zariuq joined
10:42 DocWinter joined
10:42 zeroed joined
10:42 zeroed joined
10:43 bjz_ joined
10:43 cfricke joined
10:44 raynold joined
10:44 eacameron joined
10:45 butterthebuddha joined
10:47 Denthir joined
10:47 jo`ve joined
10:48 robatosan joined
10:50 wroathe joined
10:50 newhoggy joined
10:51 blym joined
10:51 dm3 joined
10:54 erikd joined
10:54 vaibhavsagar joined
10:57 <torstein> is there any difference between: data Sing :: Color -> * where SRed :: Sing Red ;; and this: data Sing (c :: Color) where SRed :: Sing Red
10:57 reuben364 joined
10:58 anuxivm joined
10:58 twanvl joined
10:58 seveg joined
10:59 armyriad joined
11:01 Itkovian joined
11:02 Snircle joined
11:02 blym_ joined
11:03 bvad joined
11:04 mettekou_ joined
11:05 eacameron joined
11:05 metteko__ joined
11:05 Alex__ joined
11:08 _paul0 joined
11:10 wroathe joined
11:10 <cocreature> torstein: afaik there is no difference
11:10 romank joined
11:11 eacameron joined
11:12 romank joined
11:12 fenedor joined
11:14 DisruptiveNL joined
11:14 romank joined
11:15 blym_ joined
11:15 armyriad joined
11:16 eacameron joined
11:17 Ulrar joined
11:18 ziocroc joined
11:18 ziocroc2 joined
11:18 louispan joined
11:20 <lpaste> Ulrar pasted “map” at http://lpaste.net/355081
11:20 <Ulrar> Hi, I'm having some trouble with _mapM, and I'm not sure what I'm doing wrong
11:20 <Ulrar> sendMsg is from SimpleIRC, if that matters. It does perform IO
11:22 eacameron joined
11:23 <lyxia> you misspellt mapM_
11:23 homesitter joined
11:24 <lyxia> Ulrar: identifiers with a leading underscore which are not in scope are interpreted as "holes" for which GHC prints the expected type.
11:24 <Ulrar> Ah, you are right ..
11:24 <Ulrar> That's good to know
11:24 <Ulrar> Thanks !
11:24 binaryplease joined
11:25 <lyxia> if you're not expecting it, it's equivalent to "variable not in scope"
11:26 eacamero_ joined
11:27 <Ulrar> That make sense
11:27 <Ulrar> Don't know why I was thinking _ in front, guess it looks like _ <-
11:28 NyanPasu joined
11:29 erikd joined
11:30 xcmw joined
11:30 agjacome joined
11:32 noumenon joined
11:33 romank joined
11:35 agjacome joined
11:37 Sose_ joined
11:38 newhoggy joined
11:39 hoknamahn joined
11:40 plutoniix joined
11:40 sgronblo joined
11:45 wroathe joined
11:46 romank joined
11:46 newhoggy joined
11:49 blym_ joined
11:49 romank joined
11:51 dejanr joined
11:51 sproingie joined
11:51 sproingie joined
11:51 seveg joined
11:54 sdothum joined
11:54 sepp2k joined
11:55 eacameron joined
11:55 fakenerd joined
11:55 <LAZAR> How doI deconstruct this? data Tree a = Node a (Tree a) (Tree a) | Empty deriving (Show), like height Node x ltree rtree does not work
11:55 filterfish joined
11:55 wroathe joined
11:55 <dysfun> put parens around (Node x ltree)
11:56 cyborg-one joined
11:56 <LAZAR> dysfun: lol thanks
11:59 sampuka joined
11:59 newhoggy joined
12:00 JagaJaga joined
12:02 blym_ joined
12:02 <Alex__> Is it possible to take the head of a type?
12:02 romank joined
12:02 <cocreature> Alex__: what is that supposed to mean?
12:03 howdoi joined
12:05 asmyers joined
12:05 <Alex__> cocreature: https://pastebin.com/fNZW8vbw
12:05 newhoggy joined
12:05 romank joined
12:05 Discovery joined
12:05 No_Other_Names joined
12:05 <cocreature> Alex__: how is Graph defined
12:06 wroathe joined
12:06 gehmehgeh joined
12:06 <Alex__> cocreature: Woops, sorry. I'll add that, 1 sec
12:06 <cocreature> also the complete error message including the part of the code that GHC thinks is responsible is often useful
12:07 <Alex__> cocreature: https://pastebin.com/VN4pJPeU
12:07 eacameron joined
12:09 <cocreature> Alex__: it’s still not entirely clear to me what you are trying to do. your function is called “addVertex” suggesting that it should add a vertex to the graph but it returns a VertexID instead of a new graph
12:10 blym_ joined
12:10 <dysfun> what can i use to parse dates and times according to format strings?
12:10 <cocreature> :t parseTimeM
12:10 <lambdabot> error: Variable not in scope: parseTimeM
12:11 <cocreature> gnah, I’m really bad at guessing what lambdabot has in scope these days
12:11 notr00t joined
12:11 <cocreature> dysfun: anyway, that’s probably what you’re looking for
12:11 <dysfun> thanks
12:11 <Alex__> cocreature: Yeah, I had it so it returned a new graph at first but I want it to return the id of the vertex added to the graph
12:11 insitu joined
12:12 <cocreature> Alex__: you are aware that variables in Haskell are immutable, right? so you can’t modify the existing graph, you have to return a new graph
12:13 biglambda_ joined
12:14 cranej joined
12:14 __Myst__ joined
12:14 <__Myst__> Is the result of Data.Map.toList guaranteed to be sorted?
12:14 <cocreature> Alex__: you can return a new vertex id _and_ the modified graph by returning a tuple
12:15 chrissound joined
12:16 <Gurkenglas> Okay so I installed emacs and i went through like 40% of the tutorial before getting bored and then i somehow put the thing at the top of http://commercialhaskell.github.io/intero/#install into what i hope is an init file and at some point I ran stack new intero-demo and I opened its app directory in emacs and clicked on Main.hs and now how do I get it to show the error as in the gif in the previously linked page
12:16 <Gurkenglas> instead of https://gyazo.com/72d306af4b11c7bc36c12466aabfdcf6 ?
12:16 <cocreature> __Myst__: I think it is currently the case but the API doesn’t guarantee it. if you care about that use “toAscList” or “toDescList”
12:16 eacameron joined
12:16 <cocreature> yep currently toList = toAscList
12:16 <__Myst__> cocreature: thank you very much
12:17 t7 joined
12:17 <cocreature> but if you use toAscList it’s also easier to see that you depend on the output being sorted, so there is little reason to not use it :)
12:17 ajp_ joined
12:20 eacameron joined
12:20 locallycompact joined
12:20 erikd joined
12:20 sveit joined
12:20 wroathe joined
12:22 <Alex__> cocreature: Hmm, okay. But then I still have the problem with how I should go about returning the vertex id
12:24 newhoggy joined
12:24 <cocreature> Alex__: right, so let’s first fix the type signature. you want to return the modified graph and the VertexID so the type signature should be addVertex :: Graph a -> a -> (Graph a, VertexID)
12:25 leah2 joined
12:26 troydm joined
12:26 connrs joined
12:26 <Alex__> cocreature: Yeah, that I got :)
12:27 <chrissound> Hello! Does anyone know if any existing module for this sort of thing exists: a way to navigate to the (nth) window? (a single keybinding)
12:27 eacameron joined
12:27 <cocreature> Alex__: you probably want something like that http://lpaste.net/355082
12:27 beanbagula joined
12:28 ajp joined
12:30 dunx joined
12:30 wroathe joined
12:31 meba joined
12:32 <Alex__> cocreature: Okay thanks :) I'll see if it works
12:34 binaryplease1 joined
12:35 mt joined
12:35 moop joined
12:37 jonrh joined
12:38 kappter joined
12:38 dsm joined
12:38 sanjoyd joined
12:39 fuziontech joined
12:40 chriswk joined
12:40 <cocreature> does haddock support documenting non-record fields of a constructor?
12:40 <cocreature> I know I can document the complete constructor but I’d like to document a single field
12:40 ggherdov joined
12:41 <jophish> cocreature: you could try documenting the arguments in a constructor in a GADT
12:41 <jophish> I'm not confident that that'll work though
12:41 mettekou joined
12:41 carter joined
12:41 PatrickRobotham joined
12:41 <cocreature> jophish: also I don’t really want to switch to GADT syntax just to be able to annotate it :)
12:43 mettekou_ joined
12:43 jorendorff joined
12:43 feepo joined
12:43 mbrcknl joined
12:44 darthvorik joined
12:44 dstockwell joined
12:45 __Myst__ left
12:45 thi_ joined
12:46 gleber_ joined
12:47 paroxp joined
12:47 dgpratt joined
12:47 hodapp joined
12:48 saylu joined
12:48 rodarmor joined
12:49 hodapp joined
12:50 wroathe joined
12:50 rgrinberg joined
12:51 dpower joined
12:52 seveg joined
12:52 kritzcreek joined
12:52 <jophish> cocreature: you could use something like this: https://gist.github.com/dc7656578cb16d0d565cc4d4968192c3
12:52 <jophish> Note that the ::: operator is already defined in CLaSH.NamedTypes
12:53 w4and0er96 joined
12:53 dfeuer joined
12:53 <jophish> We use that quite a lot to annotate function arguments, but it works just as well for ADTs
12:53 <cocreature> jophish: tbh I’m not really looking for workarounds here. I was mostly wondering if I’m too stupid for haddock or if haddock really doesn’t support this. otherwise I’ll just document the constructor instead of the individual arguments :)
12:53 jxv joined
12:54 pringlescan joined
12:54 <jophish> cocreature: gotcha.
12:54 <jophish> as far as I know haddock doesn't support this
12:54 <cocreature> alright, thanks :)
12:55 <jophish> https://github.com/haskell/haddock/issues/95
12:55 kau joined
12:56 justanotheruser joined
12:56 <bennofs> cocreature: you can also give the arguments names
12:56 <bennofs> cocreature: like data A = A { foo :: Int, bar :: String }
12:57 <cocreature> bennofs: right, that’s the record syntax I mentioned
12:57 nh21 joined
12:57 <bennofs> cocreature: oh I missed the non-record part :)
12:57 <jophish> That's less nice when one has a sum type as nobody wants partial functions around
12:57 <cocreature> exactly
13:00 wroathe joined
13:01 jao joined
13:05 LiaoTao joined
13:09 noam_ joined
13:09 connrs joined
13:11 wroathe joined
13:12 romank joined
13:12 _Noble_Turk_ joined
13:14 eacameron joined
13:17 <reuben364> In the pipes library, is one of these types more powerful: (Producer a m r -> Producer b m r) or (Pipe a b m r)?
13:18 Denthir joined
13:18 pie_ joined
13:18 MitchellSalad joined
13:19 JeanCarloMachado joined
13:19 mettekou joined
13:21 sproingie joined
13:21 eacameron joined
13:22 ragepandemic joined
13:22 wroathe joined
13:22 xcmw joined
13:23 effectfully joined
13:23 mettekou_ joined
13:28 <lyxia> You can map the second one to the first one, but the other way seems difficult.
13:29 Itkovian joined
13:29 <Myrl-saki> What has `type Foo a = (a,a)` ?
13:29 <Gurkenglas> "type Producer b = Proxy X () () b", "type Pipe a b = Proxy () a () b". They don't unify. Did you mean the second one to be "Pipe a b m r -> Pipe a b m r"?
13:29 <Myrl-saki> And so on?
13:29 eacameron joined
13:29 <Gurkenglas> Myrl-saki, give me some more "and so on", not sure which direction you wanna generalize
13:29 <Myrl-saki> (a,a,a) ...
13:30 <Myrl-saki> Think V2, V3, but as a type synonym.
13:30 ragepandemic joined
13:30 <Gurkenglas> Why do you want that as a type synonym?
13:30 <Myrl-saki> I mean, we have V{2,3,*}
13:31 wroathe joined
13:31 systadmin joined
13:31 <reuben364> Gurkenglas: Sorry, I didn't mean in the sense of more specific. I mean in terms of obtaining one from the other.
13:31 <Myrl-saki> But I'm not working withu vectors.
13:31 <Myrl-saki> I'm working with repeating elements of fixed sizes.
13:34 <Gurkenglas> Control.Lens.Each gives you something to work with tuples of equally typed elements. Why do you want a type synonym here?
13:35 wei2912 joined
13:35 <Gurkenglas> One reason to not prefer (a,a) is that fmap goes only over the right half
13:35 <Gurkenglas> I'm having trouble setting up intero, anyone wanna hop on teamviewer and help?
13:36 meba joined
13:37 <lyxia> reuben364: The other way around (left to right) seems to assume that the argument Producer a m r is used linearly.
13:38 theelous3 joined
13:38 seveg joined
13:40 Aruro joined
13:41 homesitter joined
13:41 wroathe joined
13:41 vaibhavsagar joined
13:42 <reuben364> lyxia: I don't understand what you said. Is it that usage of Producers should be linear?
13:44 connrs joined
13:44 mda1 joined
13:45 romank joined
13:46 Hunter1 joined
13:46 <lyxia> reuben364: I'm just saying that functions (Producer a m r -> Producer b m r) that do not use their argument linearly cannot be represented as a Pipe a b m r.
13:47 <reuben364> Ah
13:49 <reuben364> Thanks
13:50 nh2 joined
13:50 tromp joined
13:50 meck joined
13:51 <reptar_> how can i specify that this tree is of type Tree Int? http://lpaste.net/8845755308144852992
13:52 Xenasis joined
13:53 <Gurkenglas> reptar_, your Branch 1 in lines 6 and 7 seems to take 3 arguments. Did you mean to put line 7 there?
13:53 <lyxia> reptar_: the actual problem is that fill is missing an argument
13:53 tomphp joined
13:54 <lyxia> reptar_: as for your question, (Branch 1 (...) (...) :: Tree Int)
13:54 drninjabatman_ left
13:55 <reptar_> lyxia: you are completely right :) thank you!
13:55 <Gurkenglas> Looks like I fell into the same trap here as the compiler. Listen to lyxia instead.
13:56 nomicflux joined
13:58 tromp joined
13:58 descender joined
13:59 <Myrl-saki> Gah.
13:59 <Myrl-saki> I'm going to need help now.
14:00 <Myrl-saki> I need lists.
14:00 <reuben364> [1,2,3]
14:00 <Myrl-saki> HVect, I think?
14:00 <Myrl-saki> What kind of stuff can I guarantee with HVect?
14:00 bennofs joined
14:01 <reuben364> You can guarentee each element has a certain type and that the list has a certain length.
14:01 <Myrl-saki> :t sequence
14:01 <lambdabot> (Monad m, Traversable t) => t (m a) -> m (t a)
14:01 <Myrl-saki> I see.
14:02 wroathe joined
14:02 Jinxit joined
14:02 bjz joined
14:02 <Xenasis> Probably a silly question, but how do I actually use libraries I download from cabal? That is, what do I add to my compilation string to GHC? I'm attempting to try Aeson but can't seem to google the solution to this
14:03 <bennofs> Xenasis: if you ran `cabal install aeson`, you shouldn't have to add anything to GHC, just import the module from the package
14:04 seveg joined
14:04 <Xenasis> That was what I did, hmm
14:04 jmcarthur joined
14:04 <Myrl-saki> Well. I'm stating the obvious here.
14:04 <Myrl-saki> But this is clearly way harder than I expected.
14:04 <bennofs> Xenasis: if the project is larger, I recommend creating a `.cabal` file for your project and making it a proper cabal project. This way, you also can use sandboxing so you don't get conflicts when multiple projects require different library versions
14:04 <Myrl-saki> Is there a better syntax for HVect? I'm using it for a library.
14:05 <reuben364> What do you aim to do with it?
14:05 <Xenasis> It should just be ~200 lines and a single file
14:05 <bennofs> Myrl-saki: i generally try to avoid heterognous collections. the api is just way too complicated
14:05 eacameron joined
14:05 <Myrl-saki> reuben364: My current code is
14:05 <Xenasis> Though yeah thanks for letting me know that it /should/ just work
14:05 <Xenasis> Will tinker with cabal
14:05 <bennofs> Xenasis: so you ran `cabal install aeson`, that suceeded and `import Data.Aeson` fails?
14:06 <Myrl-saki> reuben364: :: MonadFix m => [[a] -> m] -> m [a]
14:06 <Myrl-saki> reuben364: And I plan to rewrite that into HVect.
14:06 <Xenasis> I was pretty sure it succeeded but perhaps it didn't, though yes that is what happened I believe
14:07 <Myrl-saki> This is the current API. http://ix.io/sh0
14:07 <lyxia> Xenasis: are you using a sandbox
14:07 <Myrl-saki> (And yeah, that doesn't work, because heterogenous lists.)
14:07 <Xenasis> I'm not, I'll update everything in cabal and reinstall Aeson
14:08 <reuben364> Myrl-saki: And all you want to do is have a fixed length, right?
14:09 <Myrl-saki> reuben364: I think I should talk about what I want to fix rather than my current fix.
14:10 <Myrl-saki> reuben364: I'm using reflex-dom, and I'm working on a library for a CSS framework that maps the DOM's elements to the CSS framework's elements. The CSS framework has some "rules"(which are not really enforced, but I want to enforce them in this library.) One rule is that specific collection elements have to have specific children.
14:10 spatial joined
14:10 <Myrl-saki> reuben364: (I hope you get where the `:: MonadFix m => [[a] -> m a] -> m a` comes from now.
14:11 newhoggy joined
14:11 <reuben364> Myrl-saki: which function has that signature?
14:11 <reuben364>
14:11 <Myrl-saki> reuben364: I think I can get away by using GADT, instead.
14:11 <Myrl-saki> Ah, sure.
14:11 wildlander joined
14:12 wroathe joined
14:12 <Myrl-saki> :t \f -> sequence . traverse f
14:12 <lambdabot> (Applicative t, Traversable m, Traversable t, Monad m) => (a1 -> t a) -> m a1 -> m (t a)
14:12 <Myrl-saki> :t \ms -> mfix (\xs -> sequence . traverse ($ xs) $ ms)
14:12 <lambdabot> (Applicative t, Traversable m, Traversable t, MonadFix m) => m (t a -> t a) -> m (t a)
14:12 <Myrl-saki> reuben364: ^
14:13 Itkovian joined
14:13 <Myrl-saki> Why do I have a sequence there lol
14:14 <Myrl-saki> :t \ms -> mfix (\xs -> traverse ($ xs) ms)
14:14 <lambdabot> (Traversable t, MonadFix m) => t (t b -> m b) -> m (t b)
14:14 <Myrl-saki> Better.
14:14 Madars joined
14:16 <Myrl-saki> I think I can use HVectElim for one of these things.
14:16 Wuzzy joined
14:17 Argue joined
14:19 justanotheruser joined
14:20 <reuben364> Myrl-saki: At the point all I think I'm good for is being a rubber ducky.
14:21 <Myrl-saki> reuben364: Hahaha. Wel, we all need rubber duckies. :D
14:22 Itkovian_ joined
14:22 LAZAR joined
14:23 tomphp joined
14:23 sproingie joined
14:23 sproingie joined
14:24 xcmw joined
14:24 nh2 joined
14:24 justanotheruser joined
14:25 idy joined
14:25 cschneid_ joined
14:25 <LAZAR> Okay this works: changeName :: Person -> String -> Person where Person is an abstract data type. But what if I have State -> String -> Int -> State where State is a function String -> Int? How can I modify a function, like adding new state variables?
14:28 justanotheruser joined
14:28 ragepandemic joined
14:30 steven_ joined
14:30 logcat joined
14:31 justanotheruser joined
14:31 Hunter1 joined
14:31 justanotheruser joined
14:32 baldrick joined
14:32 wroathe joined
14:33 fragamus joined
14:34 <lyxia> the result is a function, so you can start by writing a lambda
14:35 <sproingie> LAZAR: for passing a function as a value, you'll want parens in the signature, e.g. State -> (String -> Int) -> State
14:36 thunderrd joined
14:37 <LAZAR> lyxia: yeah but my problem is i somehow want to store key-value pairs without hardcoding them... basically adding more cases to an existing function
14:37 <sproingie> Data.Map might come in handy
14:37 JuanMiguel joined
14:38 <lyxia> Data.Map won't help since State is a function type
14:38 eacameron joined
14:38 mr_sm1th joined
14:38 newhoggy joined
14:39 romank joined
14:39 <sproingie> it can certainly represent a mapping of Strings to Ints
14:39 jsgrant-_ joined
14:39 <LAZAR> Well according to the assignment i have to use functions: https://www.cis.upenn.edu/~cis194/spring15/hw/03-ADTs.pdf
14:40 <sproingie> well if there's constraints on the homework, then you're not allowed to use the full toolbox
14:40 <LAZAR> It seems they want to represent the state not as a data structure but as a polymorphic function
14:40 <LAZAR> Well im not doing it for homework but just for fun to learn it
14:41 mou joined
14:41 <LAZAR> I just have no clue how to extend a function at runtime by additional definitions
14:41 <lyxia> LAZAR: since the result is a function, you can do comparisons on the argument to decide what to return
14:41 leah2 joined
14:42 <sproingie> ah ok the assignment is different than what i thought you were doing
14:42 <lyxia> changeState state newKey newValue = \key -> if key == newKey then ... else ...
14:43 <LAZAR> lyxia: yeah but the result should be a polymorphic function so somehow you need to preserve the former definition
14:43 <sproingie> type State = [(String, Int)]
14:43 <sproingie> not as efficient as a Map, but it'll do
14:43 wroathe joined
14:44 <lyxia> LAZAR: where do you see a polymorphic function
14:44 <LAZAR> sproingie: well im not sure if state is supposed to be stored in an array... it seems they want me to create just overloaded definitions covering different args
14:44 EvilMachine joined
14:45 <sproingie> the assignment doesn't seem to constrain the implementation
14:45 <LAZAR> lyxia: the state returns integers for given strings, so you either modify a given function to cover additional patters or you create a new definition which is polymorphic
14:45 <lyxia> this is not what we call polymorphism.
14:45 <sproingie> you don't modify functions, you pass them different args
14:45 <lyxia> it's just a function
14:45 <LAZAR> sproingie: hmm in that case querying the state would be pretty inefficient? i would need to loop over the state and then get the value
14:46 <sproingie> oh it won't be efficient, no
14:46 <sproingie> it'll be fast enough for this though
14:46 robertkennedy joined
14:46 mda1 joined
14:46 <LAZAR> sproingie: look at the function signature tho... extend expects a single state to extend, not a list
14:46 <EvilMachine> Hi. What type class has operators equivalent to (<>) and (pure)? Because I can ("abc" <> "d") but I can’t ("abc" <> 'd'), so I need something like ("abc" <> pure 'd')… if you understand what I mean…
14:47 <sproingie> LAZAR: a list is a single thing
14:47 <sproingie> you've got a desired implementation stuck in your head, you need to get it unstuck
14:48 james1 joined
14:48 erikd joined
14:48 <sproingie> if you have a list of (Int, String), and a function that takes such a list, an int, and a string, the implementation is obvious
14:48 <LAZAR> sproingie: yeah but i cant insert a [state] into extend. i know i could easily store a state in any kind of data structure like lists, what confuses me is that they want me to hold the application state inside one single function
14:48 <lyxia> sproingie: "we define a State to be a function of type String -> Int"
14:48 <sproingie> in fact if it's a list of (a,b) and not any specific type, then there's only one possible implementation
14:48 <sproingie> *that* BTW is what polymorphism is
14:49 <lyxia> extend :: (String -> Int) -> String -> Int -> (String -> Int) is what the exercise is asking
14:49 <sproingie> @djinn [(a,b)] -> a -> b -> [(a,b)]
14:49 <lambdabot> Error: Undefined type []
14:49 <MarcelineVQ> > "abc" <> pure 'd'
14:49 <lambdabot> "abcd"
14:49 <EvilMachine> (Lol, ("abc" <> pure 'd') actually already works. But I don’t want to use something as complex as applicative.)
14:49 <LAZAR> lyxia: exact, it expects a function and changes this one
14:49 <sproingie> @djinn foo :: [(a,b)] -> a -> b -> [(a,b)]
14:49 <lambdabot> Cannot parse command
14:49 <sproingie> i lose
14:50 <EvilMachine> MarcelineVQ: So the question boils down to: What’s a simpler version of (pure) that doesn’t require all of Applicative?
14:50 <lyxia> LAZAR: what I wrote is part of the answer
14:50 <MarcelineVQ> > "abc" <> ['d']
14:50 <lambdabot> "abcd"
14:50 ehsanullahjan joined
14:50 eacameron joined
14:50 <EvilMachine> MarcelineVQ: Unfortunately, I need it to be as generic as possible.
14:50 <EvanR> EvilMachine: what laws would this "simpler" class follow
14:50 <lyxia> LAZAR: define a new function (\key -> ...) in terms of the old one (state)
14:51 <EvilMachine> EvanR: It would just have two operators. One like (pure) and one like (<>).
14:51 <EvanR> there used to be a class Pointed which was Applicative without <*>
14:51 netheranthem joined
14:52 <EvilMachine> EvanR: Did Pointed have a combinating operator?
14:52 <EvanR> EvilMachine: what is the type of these ops
14:52 wroathe joined
14:52 <LAZAR> lyxia: yeah i know i could just return a new function, that would be simple. but not to overwrite the old definition i would need to "break up" the old state and create a new function alltogether
14:52 <LAZAR> after extending the function body itself has to be rewritten at runtime
14:53 <sproingie> don't rewrite the function, just wrap it
14:53 <lyxia> something's wrong with this
14:53 <EvanR> or memoize
14:53 <sproingie> didn't realize it required State to be that function type
14:53 <EvilMachine> EvanR: I want a function that can put an element in a list/set/…, with the only condition being that that list/set/… is something, where on cas put elements (of that type) in.
14:53 <EvilMachine> cas=can
14:53 m0rphism2 joined
14:54 <lyxia> LAZAR: you return a new function, it IS that simple
14:54 <EvanR> youre about to fall into the "container" trap
14:54 <EvilMachine> EvanR: I know. :)
14:54 <EvanR> "clearly its a class for generic containers"
14:54 <lyxia> LAZAR: I don't understand why you're writing about overwriting anything
14:54 <EvanR> which means....
14:54 <sproingie> ah "we define a State to be a function of type String -> Int". i only tend to pay attention to the code parts
14:54 <EvilMachine> EvanR: I just corrected myself, including something like Applicative too.
14:54 newhoggy joined
14:54 <EvanR> huh?
14:54 <lyxia> LAZAR: Everything is immutable here
14:54 rkazak joined
14:55 <EvanR> EvilMachine: well, still, you should be able to produce types?
14:55 <EvilMachine> EvanR: So not just “put in” as in “container”, but also as in “apply to”
14:55 <EvanR> then you can worry about laws
14:55 <EvanR> or see that there can be no laws because its too polymorphic
14:55 <LAZAR> I define this simple Function f :: Int -> String and offer one definition f n | n == 5 = "Five | otherwise "Default". How would I extend this at runtime to cover an input of 4 = "Four"?
14:56 <lyxia> LAZAR: okay maybe we have a different idea of what it means to "return a new function"
14:56 <EvilMachine> EvanR: Well, in my case it is actually for the purpose of container managing. But I hoped I could get something more generic, and benefit from that. :)
14:56 ystael joined
14:56 <EvanR> i am skeptical that you will
14:56 <EvanR> especially if you dont have types for these operations
14:56 <lyxia> LAZAR: \n -> if n == 4 then "Four" else f n defines a new function that extends f.
14:57 <lyxia> LAZAR: there is no need to "overwrite" f
14:57 osa1_ joined
14:58 homesitter joined
14:58 <lyxia> LAZAR: you just define a new function from it and pass it around in various ways
14:58 <EvilMachine> EvanR: Why the judgmental self-fulfilling prophecy mood? I feel like you push me towards that stereotype that you despise, until I am that, and I am not stress-resilient enought to fight it. … I am very aware of the trap, and if anything, would prefer nudging in the other direction instead.
14:58 <sproingie> LAZAR: think of it this way: you have a function that if someone gives it "Four", it returns 4. now you want a new function, let's say mapping "Five" to 5, and if the input isn't "Five", try your old function. see how that works?
14:58 <EvanR> EvilMachine: the Set, Map, Array, Vector, etc etc etc APIs all tend to have similar operations and the same names. not just singleton and append.
14:58 <sproingie> LAZAR: you wouldn't use a pattern guard, just a plain old 'if'
14:58 <EvanR> but they arent part of a class because you cant give them a common type
14:59 <sproingie> looks like your base case is that any unresolved identifiers have a value of 0
14:59 <EvanR> and in your case, youre arbitrarily taking only two of the operations. why?
14:59 Goplat joined
14:59 <EvanR> in practice you cant make that code polymorphic on the entire API for all those containers, it just doesnt make sense
14:59 iomonad joined
14:59 <EvanR> this is where java and friends mess up
14:59 <EvilMachine> EvanR: Well, (CommonType RelatedType -> RelatedType -> CommonType RelatedType) would be the common type of their “add/apply/…” operation.
15:00 urodna joined
15:00 <EvanR> oh i misunderstood, i thought you were talking about pure
15:00 <EvilMachine> EvanR: it suffices to make it polymorphic on the CRUD operations.
15:00 <EvanR> not insert
15:00 Welkin joined
15:00 <EvilMachine> EvanR: Hmm, pure is needed in the case of <>.
15:00 <EvanR> now youre talking about more than 2
15:00 <EvanR> eh?
15:00 <EvilMachine> EvanR: Of course in general, it’s different.
15:01 <EvilMachine> EvanR: So you fell into the specialization trap too? ;)
15:01 <EvanR> in general... im just saying ive seen this kind of speculation a lot and it never goes anywhere good
15:01 justanotheruser joined
15:01 <EvilMachine> EvanR: I know. Don’t worry. I’m not that much of a newbie anymore. :)
15:01 <EvilMachine> EvanR: I would probably act the same way. ^^
15:02 <EvanR> "container" is an emotional thing it seems, not a mathematical abstraction
15:02 <EvilMachine> EvanR: Well thankfully!
15:02 <EvilMachine> EvanR: I’m not Spock, you know? :D
15:02 <sproingie> "emotional" seems a rather imprecise term
15:02 ner0x652 joined
15:02 chrissound joined
15:02 jer1 joined
15:02 <LAZAR> lyxia, sproingie : Thanks i guess that was what i was looking for... totally forgot. Extend would look like this: extend :: (Int -> String) -> Int -> String -> (Int -> String) extend f i s = (\n -> if n == i then s else f n)
15:03 <EvanR> right
15:03 <EvilMachine> sproingie: It is a very precise term though.
15:03 justanotheruser joined
15:03 <EvanR> is it?
15:03 <EvilMachine> EvanR: Yes. See: https://www.youtube.com/watch?v=KbacW1HVZVk (and part 2.
15:03 tomphp joined
15:03 <EvilMachine> )
15:03 justanotheruser joined
15:03 robotroll joined
15:04 <EvanR> what is the title of that
15:04 <Welkin> does anyone use stack with nix here?
15:04 khumba joined
15:04 <EvilMachine> EvanR: Antonio Damasio. Brain and mind: from medicine to society. 1/2
15:04 justanotheruser joined
15:04 <EvanR> how long
15:04 <EvilMachine> EvanR: He’s a neuroscientist, and this is a speech about the topic.
15:04 <sproingie> LAZAR: pretty much, though you'll want to initialize it with the base case that always returns zero. makes it so you'll largely be using it in curried form
15:05 <EvilMachine> EvanR: Too long. :)
15:05 <Welkin> last night I ran into a problem that I should have forseen: setting up on older project with nix, and it downloaded the latest packages for everything, but the API broke/changed with one of the libraries I'm using
15:05 <EvanR> mmkay
15:05 <EvilMachine> EvanR: More something for the evening.
15:05 <EvanR> youtube is too slow for me
15:05 <EvilMachine> EvanR: ~1h
15:05 <Welkin> I know this is a solved problem with stack (maybe there is a simple way to deal with it in nix too)
15:05 Argue_ joined
15:05 justanotheruser joined
15:05 <EvilMachine> EvanR: Yes, but I haven’t found it in a condensed written form yet. Nevermind then. :)
15:06 justanotheruser joined
15:06 justanotheruser joined
15:06 <EvanR> EvilMachine: clojures penchant for pretending a bunch of different data structures are really the same, relies on "container", but i had issues trying to actually program that way
15:06 tristanp joined
15:07 justanotheruser joined
15:07 <EvanR> and understanding what would happen when i used the container API
15:07 NikolajK joined
15:07 <LAZAR> sproingie: yeah thats part of the assignment too... i think building an interpreter is a good way to learn a language
15:07 <NikolajK> Is there a documentation for color codes in type system presentations?
15:07 <EvanR> maybe it the same issue as with having "one true number type"
15:07 <NikolajK> There seem to be some conventios
15:08 Argue__ joined
15:08 <EvanR> values are red, types are blue
15:08 <EvanR> (in idris repl)
15:09 plot joined
15:09 <lyxia> sounds like the start of a poem
15:09 justanotheruser joined
15:09 takle joined
15:10 <sproingie> "i learned a haskell and so can you"
15:10 justanotheruser joined
15:10 leah2 joined
15:10 <sproingie> ok let's not let me do poetry anymore
15:10 takle joined
15:11 umib0zu joined
15:11 justanotheruser joined
15:11 leah2 joined
15:11 takle joined
15:11 <EvanR> heres a question
15:11 sellout- joined
15:11 Argue joined
15:12 justanotheruser joined
15:12 <EvanR> if you issue a majorGC, to try and drop a lot of data, but you have still a single large object that you want to keep, can you somehow put that object in statis to hide it from the majorGC and save time duringn collection?
15:12 <MarcelineVQ> yes
15:13 connrs joined
15:13 <EvanR> stasis*
15:13 takle joined
15:13 justanotheruser joined
15:13 xall_ joined
15:13 <MarcelineVQ> https://downloads.haskell.org/~ghc/master/libraries/html/compact/Data-Compact.html
15:13 <EvanR> duuude
15:14 justanotheruser joined
15:14 gugah joined
15:14 justanotheruser joined
15:15 _Noble_tr joined
15:16 alx741 joined
15:16 <EvanR> GHC 8.2 and later
15:17 tromp joined
15:18 ertes joined
15:18 <Welkin> there is no 8.2
15:18 <Welkin> only 8.0.2
15:19 <EvanR> then these docs ....
15:19 <EvanR> are lying to me
15:19 <sproingie> 8.2 is the upcoming release
15:19 <MarcelineVQ> sure there is, it just happens to be called head currently, as the link suggests
15:19 <MarcelineVQ> *master
15:19 <EvanR> which link
15:20 <MarcelineVQ> the one you clicked on
15:20 <sproingie> ghc does that "odd unstable, even stable" thing linux used to do
15:20 takle joined
15:20 <EvanR> oh i dunno why i thought this was a normal library on hackage
15:20 <EvanR> its part of GHC
15:21 <Welkin> upcoming when?
15:21 <EvanR> so can these be used at all?
15:21 <sproingie> when it's done
15:21 <EvanR> Data.Compact
15:21 <JuanDaugherty> nowish
15:21 <EvilMachine> EvanR: well, the one true number type would have to be of literally infinite length. :))
15:22 <EvanR> types have a length?
15:22 <sproingie> store it on the infinite tape of your turing machine
15:22 <MarcelineVQ> EvanR: the in-dev version is really something like 8.1.somedate but that stuff should be available on it currently, I'd have to rebuild my local here to confirm
15:23 <EvanR> man i was excited to try and use this for my video game project
15:23 <EvanR> now the prospect of cross compiling experimental GHCs appears
15:23 <EvanR> good way to lose sanity i fear
15:23 <Welkin> does anyone know wtf happened to the AWS library?
15:23 <Welkin> o.o
15:24 <Welkin> it changed how it allows you to specify the aws region
15:24 <EvilMachine> EvanR: Inside RealWorld they do. :)
15:24 <EvanR> what are you talking about
15:24 <Welkin> either using a lens interface (which doesn't work?) or using `within`, which doesn't work either
15:24 <EvilMachine> sproingie: Oh, no problem then, I just use a virtual machine, and set it to “Turing machine” upon initialization.
15:24 <MarcelineVQ> EvanR: angerman in #ghc works on cross-compiling if it's a subject that interests you, probably bgamari too, can't recall
15:25 thatguy joined
15:30 <reuben364> How would I do the following in lens: extract a value from a monad transformer stack with statet using a prism and instead of using the monoid instance, run something in the monad if the value is missing?
15:31 <EvanR> MarcelineVQ: interests is probably the wrong word
15:31 <EvanR> but is #ghc really a good place to get support for that?
15:31 <reuben364> for example: someField . _Just %%= doSomething, except throw an error if it is nothing
15:32 <MarcelineVQ> in the mean time if youj want gc to not tread on you you can probably use ffi pointers, not really sure though
15:32 zero_byte joined
15:32 <MarcelineVQ> EvanR: idk about get support exactly, but certainly a more informed opinion
15:33 erikd joined
15:34 Levex joined
15:34 gehmehgeh joined
15:34 <Gurkenglas> :t preview -- I suppose a "(MonadReader s m, Alternative m) => Getting (First a) s a -> m a" version of this would help reuben
15:34 <lambdabot> MonadReader s m => Getting (First a) s a -> m (Maybe a)
15:34 ForgedPancake joined
15:35 takle joined
15:36 <Welkin> does anyone know where the hell I set envRegion in the AWS library?
15:36 spatial joined
15:36 <srhb> Welkin: Which library?
15:36 mohsen_ joined
15:36 brynedwards joined
15:36 <srhb> Welkin: Or rather, which package? aws?
15:36 <Welkin> http://hackage.haskell.org/package/amazonka-1.4.5/docs/Network-AWS.html#v:envRegion
15:36 <Welkin> http://hackage.haskell.org/package/amazonka-1.4.5/docs/Network-AWS-Env.html#v:within
15:37 <Welkin> either of those
15:37 <Welkin> I used to be able to set the region here http://hackage.haskell.org/package/amazonka-1.4.5/docs/Network-AWS.html#v:newEnv
15:37 <srhb> Oh, amazonka.
15:37 <JuanDaugherty> amazonka
15:38 jsgrant-_ joined
15:38 beerdrop joined
15:38 <Welkin> I tried setting it on the result from `newEnv` and get errors
15:39 <Welkin> I tried on the request object, and it had errors
15:39 <Welkin> "Could not deduce (AWS.HasEnv (IO AWS.Env)) arising from a use of ‘AWS.envRegion’"
15:40 Denthir joined
15:40 <EvanR> MarcelineVQ: ffi pointers? interesting
15:40 <EvanR> like, data is stored outside haskell but you can view it with unsafePerformIO (and the view is not kept around so gets GCd)
15:41 thunderrd joined
15:41 <Gurkenglas> How do I make intero make M-. jump to definitions even for library functions?
15:41 tromp joined
15:41 <Welkin> Gurkenglas: set up the keybinding in your .emacs file
15:41 mettekou joined
15:41 <Welkin> finally I got it to build...
15:41 <sproingie> that's the binding. the trick is making it jump to library functions
15:42 <Welkin> I had to set it on the AWS.Env object, not IO AWS.Env
15:42 <sproingie> i don't think intero can do that
15:42 Itkovian joined
15:42 <sproingie> i have a hard enough time convinving intero to jump to stuff that's defined in my project
15:43 farao_ joined
15:43 tomphp joined
15:44 roconnor joined
15:46 Argue_ joined
15:46 seveg joined
15:47 <spatial> Should be possible using hmatrix. (matrix1 == matrix2).mean()
15:47 {emptyset} joined
15:47 Itkovian joined
15:48 <Gurkenglas> I usually work with pieces of code instead of projects, and am not too familiar with all this project stuff. How would I go about taking code from, say, a stackoverflow question, and make intero let me work with it?
15:48 ubsan_ joined
15:48 mjora7 joined
15:48 <Gurkenglas> Ah, let's say stack scripts
15:48 <spatial> It is gives a matrix of ones and zeros. matrix1 == matrix 2 Mean is Sum of ones / Total No: of elements
15:49 <cheshircat> hello, does anyone know Diagrams? I'm wondering if there is a way to slice a diagram in half
15:49 <cheshircat> I could just create the pieces, but it would be easier to create the whole thing and then slice it at y intervals
15:50 skeuomorf joined
15:50 <Gurkenglas> cheshircat, would this be a separation of pixels to either side of a line or a separation of diagrams whose center points fall to either side of a line?
15:51 tomphp joined
15:51 ninjazoete joined
15:51 nwf joined
15:52 Argue__ joined
15:53 <cheshircat> separation of pixels
15:53 takle joined
15:54 <EvanR> gives you subpixels?
15:54 <Welkin> end the segregation
15:55 noctux joined
15:55 <cheshircat> huh?
15:55 JeanCarloMachado joined
15:56 <EvanR> cheshircat: you can slice up a bitmap image using vector operations
15:57 jsgrant-_ joined
15:57 systadmin joined
16:00 newhoggy joined
16:00 earldouglas joined
16:01 Camm joined
16:01 takle joined
16:01 matrium joined
16:01 justanotheruser joined
16:01 Camm left
16:03 jbgi joined
16:03 hseg joined
16:04 CareBearemcho joined
16:04 <hseg> Hi. I'm trying to list the values of a binary function on integers in a table. Is there a package that will do this? Or at least make all columns the same width?
16:04 anuxivm left
16:05 seveg joined
16:05 <EvanR> > printf "%5d %5d" 3 4
16:05 <cocreature> hseg: _all_ values? Integer is only bounded by your memory so there are a lof of values :)
16:05 <lambdabot> error:
16:05 <lambdabot> • Ambiguous type variable ‘a0’ arising from a use of ‘show_M617148618746...
16:05 <lambdabot> prevents the constraint ‘(Show a0)’ from being solved.
16:05 jlicht joined
16:05 <EvanR> > printf "%5d %5d" 3 4 :: String
16:06 iqubic joined
16:06 <lambdabot> " 3 4"
16:06 <EvanR> > printf "%5d %5d" 35 433 :: String
16:06 <lambdabot> " 35 433"
16:06 <hseg> Well, I'm using finite subsets.
16:06 <EvanR> theres also this https://hackage.haskell.org/package/boxes
16:06 <matrium> hi, what's the best way to model overlapping datatypes? e.g. in RDF a triple consists of a subject, predicate and object. The subject can be an IRI or a blank node, the predicate just an IRI and the object can be an IRI, a blank node or a literal. If I would use just a single data Node = IRI | Blank | Literal I wouldn't be able to check that a literal is not used as subject. If I would model three separate types, there would be a l
16:06 gedda joined
16:07 <hseg> EvanR: But I don't know the width in advance and don't want to have to fiddle with it.
16:07 <srhb> matrium: You got cut off at "there would be a lo"
16:07 <gedda> quick question, is there some way to write this cleanly without do? https://hastebin.com/iyugukegug.hs
16:07 <glguy> matrium: data RDF = RDF (Maybe IRI) IRI IRI
16:07 <cocreature> hseg: there is https://hackage.haskell.org/package/tabular and https://hackage.haskell.org/package/table-layout
16:07 justanotheruser joined
16:07 <EvanR> hseg: did you look at the boxes library i just linked
16:07 <matrium> srhb: "If I would model three separate types, there would be a lot of redundant/boilerplate code"
16:08 <srhb> :t liftM2 (++)
16:08 <lambdabot> Monad m => m [a] -> m [a] -> m [a]
16:08 justanotheruser joined
16:08 <srhb> gedda: That? ^
16:08 <hseg> cocreature: Thanks
16:08 justanotheruser joined
16:08 <gedda> srhb: Something like that yes, hmm..
16:08 justanotheruser joined
16:09 <EvanR> > printf "%5d %5d" 35 4388773 :: String
16:09 <lambdabot> " 35 4388773"
16:09 <EvanR> ouch
16:09 justanotheruser joined
16:10 <matrium> glguy: I don't quite get the point of that
16:11 Xenasis left
16:11 <glguy> matrium: Which part don't you understand?
16:11 Big_G joined
16:11 Kreest__ joined
16:11 justanotheruser joined
16:12 takle joined
16:12 <sproingie> which one is the maybe?
16:12 <matrium> that only allows (IRI, IRI, IRI) triples. But (Blank, IRI, Literal) is also a valid combination
16:13 <glguy> sproingie: The one that was optional, the subject
16:13 meandi_2 joined
16:13 <glguy> oh
16:13 <glguy> there were two options
16:13 <glguy> matrium: data RDF = RDF (Maybe IRI) IRI (Maybe IRI)
16:13 <sproingie> eh. i'd use typeclasses and instances
16:13 <hseg> cocreature: Unfortunately, I don't have access to a GHC under my control, so I only have ideone ATM, which doesn't support those classes.
16:13 <hseg> s/classes/packages/
16:13 <glguy> How would typeclasses help with making RDF values?
16:13 seveg joined
16:14 mithrandeer joined
16:14 <srhb> gedda: You may also be looking for applicative style, if that's not quite it?
16:14 <sproingie> it would help in declaring what various things are RDF triples
16:14 <EvanR> abuse of type classes
16:14 <sproingie> you don't even have to pick a single form
16:14 <hseg> Unless the fpcomplete ide is still up?
16:14 <srhb> > (++) <$> Just [1,2,3] <*> Just [4,5,6] -- gedda
16:14 <lambdabot> Just [1,2,3,4,5,6]
16:14 <matrium> glguy: The RDF thing is just an example. I'm looking for a general pattern for handling overlapping types
16:14 <glguy> sproingie: It probably isn't a good idea to have multiple types for the single concept of RDF triple
16:14 <sproingie> the class is a single concept
16:14 justanotheruser joined
16:15 <glguy> matrium: OK. this is an example of the pattern. You start with the common bits and then build up bigger types where you need more values
16:15 <sproingie> but yeah probably not too wise to have multiple representations going around to start with
16:15 <nshepperd_> matrium: I'd just use different types for these things and not worry about the "boilerplate"
16:15 <sproingie> might look at the existing rdf stuff. rdf4h maybe?
16:15 justanotheruser joined
16:15 JeanCarloMachado joined
16:16 tsw_ett joined
16:16 sleffy joined
16:16 justanotheruser joined
16:16 <matrium> nshepperd_: Ok, so something like a newtype for IRIs, BNodes and Literals and then something like "Subject = IRISubject IRI | BNodeSubject Bnode"
16:16 <sproingie> or just 'rdf'. https://hackage.haskell.org/package/rdf-
16:17 <nshepperd_> matrium: yes
16:17 <EvanR> i like their solution
16:17 <nshepperd_> You can share functions for handling IRIs and Bnodes
16:17 danthemyth joined
16:17 <EvanR> data Triple = Triple Subject Predicate Object
16:18 <EvanR> what you see is what you get
16:18 <matrium> looks very alike nshepperd_'s suggestions
16:18 augur joined
16:18 <EvanR> lovin it
16:18 <sproingie> looks like rdf has nicer types, rdf4h has better parsing
16:19 <sproingie> (in that it has parsers at all)
16:19 <matrium> sproingie: currently I'm using rdf4h, but I'm quite unsatisfied with the types
16:20 <matrium> in rdf4h Triple = Node Node Node and there is a runtime check for the allowed types
16:20 <EvanR> yuck
16:20 oisdk joined
16:20 tromp joined
16:21 richi235 joined
16:21 <sproingie> bleh. yeah, rdf seems to have richer types
16:22 <EvanR> rdf has parsers
16:23 nicknovi1 joined
16:23 <EvanR> attoparsec
16:23 <Welkin> ottoparsec
16:23 takle joined
16:24 <hpc> i am surprised there isn't a parsing library called au yet
16:24 <sproingie> yeah not as many parsers tho, looks like just n-quads, which is not a bad syntax
16:24 troydm joined
16:25 <sproingie> i always used turtle back when i was doing rdf stuff
16:25 <Welkin> lol
16:25 dm3 joined
16:25 bvad joined
16:25 <Welkin> template haskell in the servant template form stack
16:25 <Welkin> from*
16:26 deam joined
16:26 <Ulrar> Anyone knows of a package to parse a string as html and extract the text out of it ? Something to transform "<p>test</p>" into "test" for example
16:26 <Welkin> Ulrar: pandoc
16:27 <EvanR> tagsoup
16:27 Sigyn joined
16:27 tomphp joined
16:28 <EvanR> innerText :: StringLike str => [Tag str] -> str
16:28 <EvanR> Extract all text content from tags (similar to Verbatim found in HaXml)
16:29 <Ulrar> Ah, that looks promising thanks
16:29 <cheshircat> Thank you EvanR
16:32 oish joined
16:33 codesoup joined
16:33 takle joined
16:33 <Ulrar> It does exactly what I need it do to, perfect
16:34 meoblast001 joined
16:35 <EvanR> and my powers goin out
16:35 Boomerang joined
16:35 jluttine joined
16:35 eklavya joined
16:36 agerick joined
16:37 ystael joined
16:38 erisco joined
16:38 Costar joined
16:40 crave joined
16:40 marcopullo joined
16:40 nomicflux joined
16:44 flatmap13 joined
16:45 boxofdeath joined
16:47 <EvanR> just had an "interesting" idea. a haskell source file (with restrictions) could be considered a data structure. you could load this structure and operate on it like a Map or Graph. then save it back as haskell source file.
16:47 <EvanR> so you could have self modifying program
16:47 <iqubic> What do you mean?
16:48 <EvanR> example, if i have a module full of numeric parameters
16:48 <erisco> so you parse it, manipulate the AST, then write it out again
16:48 <EvanR> to adjust the numbers, you have a program to view the results
16:48 takle joined
16:49 <EvanR> but the final numbers are not a separate configuration file, it should be part of the code
16:49 Guest87 joined
16:49 <EvanR> and you might want to add more parameters later so it shouldnt be baked in forever
16:49 eacameron joined
16:50 cschneid_ joined
16:50 sdrodge joined
16:51 <EvanR> haskell source code-as-database
16:52 nomicflux joined
16:52 Rodya_ joined
16:56 torgdor joined
16:56 takle joined
16:58 bennofs joined
16:59 sproingie joined
16:59 sproingie joined
16:59 mithrandeer joined
17:00 <Ulrar> I'm having trouble depending on HTTP-Simple in a cabal file, I installed it and added it to the build-depends but when I do a cabal build it says Network.HTTP.Simple doesn't exist
17:00 homesitter joined
17:01 <Myrl-saki> columns_ :: MonadFix m => (HVect ((:) (HVectElim (Append as ts) (m a)) ts)) -> HVect as -> HVect (Append ((:) (HVectElim (Append as ts) (m a)) ts) as)
17:01 <Myrl-saki> Help
17:01 <Myrl-saki> lmao
17:01 sleffy joined
17:01 <Myrl-saki> I'm trying to make a type generic version of `:: [[a] -> m a] -> [a] -> m [a]`
17:02 epsilonhalbe joined
17:02 Digit joined
17:03 <Ulrar> Oh it's http-conduit ..
17:03 <Welkin> Mondad m, Traversable t => t (t a) -> m a -> t a -> m (t a)
17:03 <Welkin> ?
17:03 <Welkin> Monad*
17:03 <Myrl-saki> Welkin: By type generic, I mean heterogenous.
17:03 takle joined
17:03 <Welkin> oh
17:04 <Welkin> why do you want a heterogenous list?
17:04 <Myrl-saki> Welkin: Hard to explain.
17:04 <Myrl-saki> Welkin: Basically, I want to do an `mdo`.
17:04 chewzerita joined
17:04 <Myrl-saki> Welkin: But I also have to insert an `:: (Monad m) => m a -> m a` before everything.
17:05 <chewzerita> @pl \n x -> let w = div n x in (w, n - w * x)
17:05 <lambdabot> ap (ap . (ap (,) .) . (. (*)) . (.) . (-)) div
17:06 <Myrl-saki> Basically, I want to do `mdo { x <- f $ m0 [y, z]; y <- f $ m1 [x, z]; z <- f $ m2 [x, y]}` but I "need" it to be generic length.
17:06 <Welkin> what is that new record field extension called?
17:06 <Myrl-saki> Technically, I could do just that.
17:06 <Myrl-saki> I mean just write exactly what I wrote.
17:06 <EvanR> have you tried a FunList sort of thing
17:06 <Welkin> so we don't need to prefix our record field accessors with _ or a fully qualified name
17:06 jer1 joined
17:06 <Myrl-saki> But I don't trust the users to remember to place `f` the whole time.
17:07 <Myrl-saki> EvanR: What does FunList do/
17:07 <Welkin> found it https://ghc.haskell.org/trac/ghc/wiki/Records/OverloadedRecordFields/DuplicateRecordFields
17:07 <Welkin> does anyone use this now though? Does it work without issues?
17:09 drcode joined
17:10 plot joined
17:10 eacameron joined
17:11 <Myrl-saki> `t2 is untoucheable` what?
17:11 <c_wraith> Myrl-saki: that usually means an existential is involved somewhere.
17:12 <c_wraith> Welkin: it's really awkward right now, as there's almost no inference.
17:12 {emptyset} joined
17:12 <Myrl-saki> c_wraith: So, it's possible that I can't type a well-typed program?
17:13 <c_wraith> Myrl-saki: it's possible, but it's more likely it isn't actually well-typed. There are a bunch of subtleties. There are also small things you can often do to fix the situation.
17:13 <Welkin> c_wraith: so I should avoid using it for now?
17:13 montik joined
17:13 phyrex1an joined
17:14 <nshepperd> Myrl-saki: what stops you from just defining m0' = f . m0 and using m0'
17:14 <Myrl-saki> nshepperd: They can still write m0.
17:14 <c_wraith> Welkin: I found the current state to be too much work for too little benefit, but you might have a better use case than I did.
17:15 <Myrl-saki> http://ix.io/shM
17:15 <Myrl-saki> The two programs. :D
17:16 <nshepperd> Myrl-saki: so only expose m0' from your module?
17:16 <Myrl-saki> nshepperd: They should be able to use m0 anywhere else.
17:17 takle joined
17:17 eacameron joined
17:17 <Myrl-saki> Arbitrary requirements, I know.
17:18 <nshepperd> maybe m0' could be a different type to m0
17:18 <nshepperd> and you have to use f to convert from one to the other
17:18 <Myrl-saki> nshepperd: Mmm... possible.
17:18 doomlord joined
17:18 <Myrl-saki> nshepperd: The base library is FRP. Would it handle that well?
17:19 <Myrl-saki> nshepperd: I think I'll have problems with wiring if it's like that.
17:19 <nshepperd> no idea
17:19 <Myrl-saki> Hmmm... actually, probably not.
17:20 <Myrl-saki> nshepperd: Thanks. I'll consider that.
17:20 <EvanR> theres a library called FRP
17:20 <EvanR> ?
17:20 <Myrl-saki> EvanR: Nah. I'm using Reflex.
17:20 <EvanR> oh
17:20 <EvanR> Myrl-saki: youre trying to make a list of actions to represent a recursive do?
17:21 <Myrl-saki> EvanR: Mhm.
17:21 <EvanR> doesnt seem right
17:21 <monochrom> Oh, wxHaskell is not dead, there is a new version
17:21 ubsan_ joined
17:21 <Myrl-saki> EvanR: But I want to wrap the list of actions in everything.
17:21 <Myrl-saki> Err
17:21 <Myrl-saki> EvanR: I want to wrap the list of actions with something.
17:21 <EvanR> if its a mere list of actions, its not a monad or needing do notation
17:21 <monochrom> I hope next time when someone asks, I won't forget and say "wxHaskell hasn't been updated for years".
17:21 <EvanR> it would be a monoid
17:22 <Welkin> it can be :: [a]
17:22 <Welkin> or, [IO a]
17:22 <Myrl-saki> Basically.
17:22 <EvanR> [m ()]
17:22 <Welkin> oh yeah, it's heterogenous
17:22 <EvanR> i dont see why
17:22 <adamCS> Myrl-saki: You have a fixed length list of differently typed things and you would like to apply an action to them?
17:22 <Myrl-saki> I want to wrap everything in a `divClass str`
17:22 <EvanR> if youre trying to use the bound variables, then no, its not a list
17:23 Costar joined
17:23 <EvanR> its a free monad
17:23 <Myrl-saki> Then compose everything.
17:23 meba joined
17:23 godel joined
17:23 <adamCS> Myrl-saki: Right. I have EvanR's question. Are you trying to use the results from earlier in the list to do actions later?
17:24 <adamCS> Or just do something to each item in the list and then compose them?
17:24 <Myrl-saki> adamCS: The former.
17:24 <EvanR> so you dont have a list really
17:24 <Myrl-saki> adamCS: And I also have to do something to each list before doing the former.
17:24 takle joined
17:24 <Myrl-saki> to each item in the list*
17:25 <Welkin> the only reason that heterogenous lists/arrays work in languages like javascript is that it's really implemented as a hashmap/object
17:25 <Myrl-saki> before (mutually) recursively using the results.
17:25 <Welkin> wait, I guess that's not quite why
17:25 <adamCS> Yeah. That's more complicated. What are you actually trying to do? More specifically?
17:25 <Gurkenglas> I often have conversations with lambdabot to prepare a line for here. Can intero give me something better than that?
17:25 <EvanR> Welkin: its because they arent really hetero, everything has the same dynamic type
17:25 <Myrl-saki> I'll give the homogenous list version.
17:25 <Welkin> EvanR: sure, I just realized that too
17:26 <EvanR> real hetero lists are an advancement you get only with advanced type system
17:26 <Myrl-saki> adamCS: http://ix.io/shP
17:26 beanbagula joined
17:26 sampuka joined
17:26 <EvanR> and a quantum leap of logic out of stuff like js
17:26 <EvanR> like "what am i really going to do with this list"
17:27 wroathe joined
17:27 <adamCS> Myrl-saki: And the type "a" is fixed or you want that to be heterogenous?
17:27 maarhart joined
17:28 <Myrl-saki> adamCS: I want it to be heteorgenous.
17:28 insitu joined
17:28 <adamCS> And this is all so you can apply css to a table?
17:28 <EvanR> which requires answering what you intend to do with it
17:28 eacameron joined
17:28 <Myrl-saki> adamCS: Ish. :P
17:29 <EvanR> the answer may lead back to a homolist
17:29 tomphp joined
17:29 <Myrl-saki> EvanR: I'm thinking of using GADT, for this.
17:29 <Welkin> lol... what?
17:29 <Welkin> for css?
17:29 <monochrom> Yes. Even if you use an existential type, the exact design of the existential type still requires "what will you do with the content?"
17:30 <monochrom> And even OOP ways don't exempt you from that.
17:30 <Welkin> Myrl-saki: I don't understand you use case
17:30 <erisco> chewzerita, I came up with liftA3 (((&&&) id .) . flip (.) (*) . (.) . (-)) <$> const <*> flip const <*> div
17:30 <Myrl-saki> Welkin: For DOM, to be more exact.
17:30 <Welkin> your*
17:30 <Welkin> what exactly are you doing? What's the end result??
17:30 <EvanR> OOP = defer answering what you will do with it, and when it becomes apparent that what you did made no sense, dynamically detect the class and just get it done anyway, and go home
17:31 Denthir joined
17:31 <adamCS> I've done a bunch of stuff, with Reflex, for applying actions to a heterogenous list--usually obtained from a generic representation of a type and then putting that back together into the type, or leaving it as a hetero list of actions.
17:31 <EvanR> Myrl-saki: youre not using a dynamically typed DOM ?
17:31 bvad joined
17:32 <Gurkenglas> Requesting "Maybe (a, b) -> (Maybe a, Maybe b)". Probably something lensy.
17:32 <Myrl-saki> EvanR: That's something else I was considering, just for this specific case.
17:32 <cocreature> EvanR: I like the going home part
17:32 ragepandemic joined
17:32 eacameron joined
17:32 <erisco> chewzerita, which can be shortened to liftA2 (<*>) (((&&&) id .) . flip (.) (*) . (.) . (-)) div
17:32 erikd joined
17:32 takle joined
17:32 <Welkin> @unpl liftA2 (<*>) (((&&&) id .) . flip (.) (*) . (.) . (-)) div
17:32 <lambdabot> liftA2 (<*>) (\ x x0 -> (\ x1 -> x1) &&& \ x2 -> x - (x0 * x2)) div
17:33 <Myrl-saki> (Rather than use heterogenous list, just have dynamic results and arguments.)
17:33 <erisco> you don't really want to do pointless arithmetic
17:33 <Welkin> pointless is pointless
17:33 <Welkin> most of the time
17:33 <erisco> I like it
17:33 <Welkin> if you like to code golf and write code no one can understand
17:33 <EvanR> variables are cool
17:33 <erisco> I can
17:34 <erisco> well, that particular example isn't good, but it is a worthwhile exercise
17:34 <lordcirth> What annoys me is that 'pointless' style is full of points '.'
17:34 cschneid_ joined
17:34 <ski> @type maybe (Nothing,Nothing) (Just *** Just)
17:34 <lambdabot> Maybe (a1, a) -> (Maybe a1, Maybe a)
17:34 <lordcirth> Terrible naming
17:35 <erisco> tacit style
17:35 <Gurkenglas> chewzerita, erisco, it's divMod
17:35 <ski> in actual math, the composition symbol is ⌜∘⌝
17:35 connrs joined
17:35 <erisco> Gurkenglas, what is?
17:36 <ski> the "points" referred to are the input variables
17:36 <erisco> oh, the function, heh
17:36 <Gurkenglas> :t [\n x -> let w = div n x in (w, n - w * x), divMod]
17:36 <lambdabot> Integral t => [t -> t -> (t, t)]
17:36 <erisco> well I wasn't interested in the content... just the rewrites to make it pointless
17:36 <erisco> eh, the similarly of those types doesn't say enough
17:37 <erisco> :t [divMod, (,)]
17:37 <lambdabot> Integral a => [a -> a -> (a, a)]
17:37 <monochrom> @quote monochrom point\ free
17:37 <lambdabot> monochrom says: "point free" can be decomposed to: "point" refers to ".", "free" refers to using no "$". :)
17:37 wroathe joined
17:37 <monochrom> :)
17:38 <ski> @pl \f -> f x
17:38 <lambdabot> ($ x)
17:39 <Welkin> :t ($)
17:39 <lambdabot> (a -> b) -> a -> b
17:39 <Welkin> lol, it's `id`
17:39 dfranke joined
17:39 <monochrom> Yeah
17:39 <Welkin> those are fun tricks
17:39 <dysfun> wow, when they said "ghcjs will take a long time to build", they weren't kidding
17:39 eacameron joined
17:39 <monochrom> > not `id` False
17:39 <lambdabot> True
17:39 <Welkin> dysfun: you can install it in a couple minutes using reflex-platform
17:40 <Welkin> it downloads a cached binary
17:40 <Welkin> I never had any luck getting ghcjs to build properly, and I remember it taking 2-3 hours each time
17:40 <dysfun> this stack snapshot was supposed to
17:40 ystael joined
17:41 <dysfun> i was actually leaning towards transient rather than reflex
17:41 <Welkin> you can just use reflex-platform to install ghcjs
17:41 <Welkin> you don't have to use reflex
17:41 <Welkin> it is just a setup script
17:41 <dysfun> hrm
17:42 <dysfun> oh god, nix
17:42 gienah_ joined
17:42 <Welkin> lol
17:42 <dysfun> i think i'll pass
17:42 <Welkin> it's not that bad
17:42 <dysfun> i used it as a desktop for a couple of months
17:42 <dysfun> i was not a fan
17:42 <Welkin> just run the script and it drops you into the nix-shell
17:43 <* dysfun> wonders if haskell is the appropriate language to build a nix-like thing in
17:44 <Welkin> nix-like?
17:44 <dysfun> then again, most of what one does in nix is in IO anyway...
17:44 <erisco> and here is the derivation I did, so you can see the fun it is :) http://lpaste.net/6428620848659169280
17:45 <dysfun> well, the most painful thing about nix for me was the nix language
17:45 <Gurkenglas> Is there some notion of a traversal that leaves nothing untraversed?
17:45 <monochrom> dysfun: There is the IO angle, yes. But there is also the data structure angle, I mean "how to be less error-prone with your data structures" angle.
17:45 <Gurkenglas> In the sense that there is no further decoration in the thing traversed over
17:45 <dysfun> at least if everything is in IO there are no questions about how to compose everything
17:46 <lyxia> Gurkenglas: so, something excluding (,) and Either?
17:47 <Gurkenglas> Yep. Actually I think it's exactly Each, indicating Each is missing a method
17:47 wroathe joined
17:48 leat joined
17:48 <dysfun> woot, ghcjs built
17:49 <Welkin> dysfun: what are you creating?
17:49 biglambda joined
17:50 oleo joined
17:50 oleo joined
17:50 <monochrom> web browser :)
17:50 <dysfun> shiny calendaring
17:50 <Gurkenglas> spine :: Each s t a () => t -- Since we have all the information about t if we know its contents are all ()
17:51 <erisco> Fix (Compose Maybe (Join ((,,) a)))
17:51 <erisco> maybe that's not a pleasant way to work with binary trees... would views help? hrm
17:51 chetshah joined
17:52 NikolajK left
17:52 <monochrom> pattern synonyms will help. But yeah I didn't even see it's a binary tree.
17:52 <monochrom> Then again I don't know Join.
17:52 <lyxia> Gurkenglas: couldn't you have Each (x, a) (x, ()) a ()
17:52 <erisco> it does like little join for functions
17:52 <Gurkenglas> No, that's not an instance of each lyxia
17:52 <erisco> Join :: (a -> a -> *) -> a -> *
17:52 <Gurkenglas> *of Each
17:53 <lyxia> Oh I see, there are fundeps
17:53 <lyxia> but there *is* s b -> t
17:53 <lyxia> So actually I don't see
17:54 <Gurkenglas> I'm saying that Each does not currently specify all that it conceptually tries to
17:54 jmcarthur joined
17:54 Cogitabundus joined
17:54 <lyxia> Okay
17:55 dan_f joined
17:55 boxofdeath joined
17:55 <Gurkenglas> Only which of the equivalent additional methods should we add?
17:56 erikd joined
17:56 <Gurkenglas> Each s t () b => b -> t
17:57 <lyxia> how would that work with lists
17:57 Kreest_ joined
17:57 wroathe joined
17:57 <Gurkenglas> Shoot, you're right, I'm describing a subclass of Each
17:59 eacameron joined
18:00 <Gurkenglas> > each .~ 2 $ undefined :: (Int, Int) -- heh, it appears this already works where it makes sense
18:00 <lambdabot> (2,2)
18:00 maarhart joined
18:01 torstein joined
18:02 tristanp joined
18:02 tomphp joined
18:02 <erisco> monochrom, I made it a bit better
18:03 <erisco> monochrom, type Tree l f n = Fix (Compose (Either l) (Compose ((,) n) f))
18:03 <c_wraith> huh. The Each instance for (,) uses lazy pattern matching?
18:03 <erisco> type BinaryTree a = Tree () (Join (,)) a; type RoseTree a = Tree () [] a
18:03 whiteline_ joined
18:03 <erisco> a while ago, maybe a couple years ago, I genericised Data.Tree... I could try and dig it up but I am too lazy... just rethinking it :P
18:04 Jesin joined
18:04 bencryption joined
18:05 eacameron joined
18:05 <erisco> the point is that you can write all the algorithms more generically thanks to Foldable and Traversable and so forth
18:05 <Gurkenglas> erisco, I'd think RoseTree a = Tree Void [] a
18:05 <erisco> rose trees easily become a special case
18:05 tomphp joined
18:06 <Gurkenglas> erisco, know of Free and Cofree?
18:06 <erisco> no, that'd be wrong because then you cannot construct a leaf
18:06 ertes joined
18:06 augur joined
18:07 fizbin joined
18:07 <Gurkenglas> erisco, that's deliberate https://en.wikipedia.org/wiki/Rose_tree
18:07 <c_wraith> Rose trees are a special case of Cofree already...
18:08 JuanMiguel joined
18:08 wroathe joined
18:09 <erisco> weird, I don't remember them like that
18:09 <erisco> then I suppose so, yes
18:09 <iqubic> How does StateT Work?
18:09 <c_wraith> @src StateT
18:09 <lambdabot> Source not found.
18:10 <c_wraith> Well then. newtype StateT s m a = StateT { runStateT :: s -> m (a, s) }
18:10 <iqubic> Actually, let's start with a simple MonadTransformer: MaybeT
18:10 <c_wraith> in other words, a StateT value is a wrapper around a function.
18:11 <iqubic> Just so I can get a feel for MonadTransformers
18:11 zacharypch joined
18:11 <c_wraith> Ok. First step then.. Are you comfortable with the Monad instance for Maybe?
18:11 zak_ joined
18:11 <turnage> I want to introduce some random numbers to a project I'm working on which so far is mostly pure functions. Random numbers are ofc IO. I'm new to haskell and wondered what some approaches to this are? I would prefer not to change all the functions those numbers propagate to to IO.
18:12 <Gurkenglas> I've got three sketchtoy drawings of mine I regularly link to to explain State s, Maybe and StateT s Maybe, but ircbrowse is down, can someone find them?
18:12 <erisco> I see rose trees are an instance of Cofree, yup, neat
18:12 <Gurkenglas> It should be "sketchtoy" "State s" "Maybe" "StateT s" all in a single line with "Gurkenglas"
18:12 <c_wraith> turnage: don't use IO except for creating the seed. Just pass a generator around instead.
18:12 takle joined
18:12 <turnage> c_wraith: Ahhh. That's good.
18:12 eacameron joined
18:13 <iqubic> c_wraith: I understand how the Maybe Monad works.
18:13 <zacharypch> Hey working through the nicta course now, kind of stuck on Applicative. So applicatives are pure + <*>. what's <*> called?
18:13 <c_wraith> turnage: in some cases, you can get away with using randoms and just passing the infinite list around, too
18:13 <iqubic> How does the MaybeT Monad work/
18:14 <c_wraith> iqubic: so start with.. newtype MaybeT m a = MaybeT { runMaybeT :: m (Maybe a) }
18:14 <iqubic> Sure.
18:14 <iqubic> It's a Monad wrapped around a Maybe A
18:14 <c_wraith> iqubic: and see if you can write the following: instance Monad m => Monad (MaybeT m)
18:14 <ertes> helo
18:14 <erisco> Free also accounts for some trees
18:14 <c_wraith> iqubic: it almost all follows from the types
18:14 <iqubic> What does?
18:14 <erisco> we can be more general than them both, though
18:15 <c_wraith> iqubic: the Monad instance I suggested
18:15 <iqubic> The usage of MaybeT?
18:15 torstein_ joined
18:15 <iqubic> I'll try to right the MaybeT Monad Instance.
18:15 <c_wraith> iqubic: just try writing the Monad instance I suggested. I can't think of a better way to learn than just trying
18:15 <ertes> zacharypch: we sometimes call it "ap"
18:15 <turnage> c_wraith: Thanks!
18:15 <iqubic> I will
18:15 <ertes> zacharypch: because:
18:15 <ertes> :t ap
18:15 <lambdabot> Monad m => m (a -> b) -> m a -> m b
18:16 <iqubic> What is ap?
18:16 <chewzerita> @pl counter m = filter (not . hasDup . show) [1..m]
18:16 <chewzerita> @pl \m = [1..m]
18:16 <chewzerita> @pl \m -> [1..m]
18:16 Discovery joined
18:16 <lambdabot> counter = filter (not . hasDup . show) . enumFromTo 1
18:16 <lambdabot> (line 1, column 4):
18:16 <lambdabot> unexpected "="
18:16 <lambdabot> expecting operator, pattern or "->"
18:16 <lambdabot> enumFromTo 1
18:17 <ertes> iqubic: haskell has this kind of "wiki effect", where you want to learn one thing, but then something else catches your attention, and you diverge, ultimately learning neither
18:17 <ertes> iqubic: i suggest that you stick with learning monad transformers now =)
18:17 <iqubic> Yeah.
18:17 tomphp joined
18:17 <iqubic> ertes, I'll start with MonadTransformers
18:17 <Gurkenglas> zacharypch, you can read it ap and call it the sequential application operator
18:18 wroathe joined
18:19 <iqubic> How do I write the return function for MaybeT?
18:19 takle joined
18:19 crave joined
18:19 <ertes> iqubic: what is a (MaybeT m a)?
18:20 <ertes> try to come up with a sentence
18:20 <iqubic> It is a Monad containing a Maybe a
18:20 Guest87 joined
18:20 pwnz0r joined
18:20 <ertes> a monad doesn't contain
18:21 <ertes> let me rephrase the question
18:21 <ertes> what is a value of type (MaybeT m a)?
18:21 <iqubic> I don't know.
18:21 <ertes> it's an m-action with a result type of (Maybe a)
18:21 <iqubic> What's an m-action?
18:22 <ertes> so a (MaybeT IO Integer) is basically an IO (Maybe Integer)
18:22 <Welkin> monad transformer stacks are inside-out
18:22 <iqubic> I see.
18:22 <ertes> an IO action with a result type of (Maybe Integer)
18:22 <iqubic> So how do I write the return function for that?
18:22 <iqubic> Can I have MaybeT (Maybe Integer)?
18:22 <ertes> iqubic: return :: a -> MaybeT m a
18:22 <Welkin> iuhave you taken a look at the way they are written in mtl or transformers?
18:23 <iqubic> Welkin, I have not.
18:23 <ertes> iqubic: it takes a value and returns a pure (MaybeT m)-action with a result type of 'a'
18:23 <Welkin> read the sourcecode in base
18:23 sepp2k1 joined
18:23 <Welkin> it is very helpful to learn
18:23 <ertes> no, don't read the source code
18:23 <Welkin> it has tons of comments
18:23 mfukar joined
18:23 <ertes> it will spoil pretty much every monad transformer exercise =)
18:23 <iqubic> I'm trying to write the MaybeT monad instance without looking at the source
18:24 ezyang joined
18:24 <ertes> iqubic: write it piece by piece: it's a function, right?
18:24 <ertes> return x = _
18:24 <iqubic> Well, it needs to be of type MaybeT
18:25 <ertes> now load this into GHCi and look at the error GHC gives you… it will reveal the type of _
18:25 <zacharypch> ok, so i was trying to define <$>, and I arrived at `(<$>) g f = (pure g) <*> f`, but in testing when trying to use `Id 2` for example, it fails because there is not an instance of this Applicative for Id. I wanted to use syntax such as `(<$>) g (Just a) = Just (g a)`, i.e. `(<$>) g (f a) = pure (g a)`?
18:25 <ertes> iqubic: (the "_" is called a typed hole… GHC handles holes specially)
18:25 Aruro joined
18:26 <iqubic> So I should just plug that into ghc and see what type it gives me?
18:26 ChaiTRex joined
18:26 <ertes> yeah
18:27 Aruro_ joined
18:27 anuxivm joined
18:27 acidjnk22 joined
18:27 JeanCarloMachado joined
18:27 thetourist joined
18:27 <iqubic> What module contains MaybeT?
18:28 <cocreature> iqubic: Control.Monad.Trans.Maybe
18:28 wroathe joined
18:28 <cocreature> iqubic: hoogle is pretty good at answering this kind of question http://hoogle.haskell.org/?hoogle=MaybeT
18:29 <MarcelineVQ> note that if you just look at the answer you won't really learn it, better to ask more questions instead
18:30 <ertes> iqubic: define it yourself
18:30 <ertes> newtype MaybeT m a = MaybeT { runMaybeT :: m (Maybe a) }
18:30 <dmj`> iqubic: using typed holes can help
18:30 <dmj`> instance Monad m => Monad (MaybeT m a) where return a = _a
18:31 <dmj`> Monad (MaybeT m)*
18:31 <ertes> iqubic: you can't use the predefined one anyway, because that one already has a Monad instance
18:33 mr_sm1th joined
18:33 <lpaste> iqubic pasted “MaybeT Monad” at http://lpaste.net/355085
18:33 <iqubic> That's what I came up with.
18:33 <iqubic> Does that work?
18:34 <ertes> iqubic: does GHCi like it?
18:34 ubsan_ joined
18:34 <iqubic> GHCi loves it.
18:34 <ertes> it's also correct =)
18:34 <iqubic> Why does that work?
18:35 <ertes> (MaybeT m) is m with an extra short-circuiting effect
18:35 <iqubic> I cobbled that together by examining the types, but I have no idea how that works
18:35 <c_wraith> iqubic: welcome to using Haskell. :)
18:35 <c_wraith> iqubic: first you make it work, then you understand it
18:35 <c_wraith> sometimes there's a big gap in between :)
18:35 <ertes> look at your code and see what happens, if 'x' returns a Nothing
18:36 <iqubic> if x returns Nothing, then maybe_value = nothing
18:36 <c_wraith> edwardk describes the process as "using the compiler as a brain multiplier". You can write code you're not smart enough to write because the compiler makes sure you got it right.
18:36 <iqubic> Therefore we run return Nothing.
18:37 <ertes> iqubic: now 'f' is in a sense the "continuation", the action that should "follow" x
18:37 <ertes> iqubic: how do you use f, if x returns Nothing?
18:37 <iqubic> ertes: You can't
18:37 <ertes> iqubic: exactly… you don't use it at all
18:37 <iqubic> Right. Which Monad's return function is being called in return Nothing?
18:38 <iqubic> Is it m's
18:38 <ertes> iqubic: now try this with a real example… write the following action: getNonEmptyLine :: MaybeT IO String
18:38 <ertes> yes
18:38 <iqubic> ertes: I'm not sure how to use MaybeT in a real example.
18:38 <ertes> write getNonEmptyLine such that it only returns non-empty lines
18:38 <iqubic> And Nothing otherwise?
18:38 <ertes> if the user enters an empty line, it should "abort" (by returning Nothing)
18:38 Shatnerz joined
18:39 <dmj`> iqubic: providing explicit annotations can be really helpful as well
18:39 <dmj`> iqubic: http://lpaste.net/8231308482096136192
18:39 <dmj`> since most types are inferred, it’s easy to “gloss over” their definitions
18:39 <ertes> it's really unfortunate that you need ScopedTypeVariables for those annotations
18:40 <iqubic> What does RunMaybeT do?
18:40 <* ski> . o O ( `forever (liftIO putStrLn =<< getNonEmptyLine)' )
18:40 <ertes> but you can use InstanceSigs to write regular type signatures
18:40 <dmj`> ertes: agreed, oh and TypeInstanceSigs
18:40 <ertes> iqubic: look at its type
18:40 <dmj`> derp, instance sigs?
18:40 yellowj joined
18:40 <ertes> dmj`: InstanceSigs
18:40 ninjazoete joined
18:40 <iqubic> :t RunMaybeT
18:40 <lambdabot> error:
18:40 <lambdabot> • Data constructor not in scope: RunMaybeT
18:40 <lambdabot> • Perhaps you meant variable ‘runMaybeT’ (imported from Control.Monad.Trans.Maybe)
18:40 <dmj`> ertes: they all blur together at some point
18:41 <iqubic> :t runMaybeT
18:41 <lambdabot> MaybeT m a -> m (Maybe a)
18:41 <ertes> iqubic: do you see what it does?
18:41 <iqubic> I don't understand that.
18:41 <ertes> iqubic: you might call it "unwrapMaybeT"
18:41 ystael joined
18:41 insitu joined
18:42 <Aruro> iqubic: transofrmer is nothing else but a type wrapper, so functions are need to take stuff out
18:42 <iqubic> So it runs the m action?
18:42 <ertes> iqubic: imagine you had written this: newtype MaybeT m a = MaybeT (m (Maybe a))
18:42 <iqubic> Sure. Sounds good.
18:42 <ertes> iqubic: then you had written a function: runMaybeT (MaybeT c) = c
18:42 sillyotter joined
18:42 <ertes> it just removes the MaybeT constructor
18:42 <iqubic> Oh.
18:43 <ertes> the "run" bit of the name is just a convention
18:43 <dmj`> iqubic: when you define a data type like "data F a = F { unF :: a }” the first argument of the record field will always be its data constructor, in this case unF :: F a -> a, `runMaybeT` works the same way. MaybeT m a -> m (Maybe a)
18:43 <iqubic> So I use that, and then I can run the funtion.
18:43 <Aruro> iqubic: did u investigate haskell book's monad transformers chapter?
18:43 <iqubic> Aruro: No.
18:43 dm3 joined
18:43 <Aruro> iqubic: haskell wiki book, free good and nice
18:43 <ertes> iqubic: write getNonEmptyLine, then you will learn how to use runMaybeT
18:44 <iqubic> What's the tyoe signature I'm going for?
18:44 <ertes> iqubic: getNonEmptyLine :: MaybeT IO String
18:44 <iqubic> Wait, no inputs are taken?
18:44 <ertes> what inputs would you take?
18:45 tomphp joined
18:45 <iqubic> So that is an IO action that returns a Maybe Strign?
18:45 <iqubic> s/Strign/String
18:45 <ertes> yeah, except wrapped by MaybeT
18:45 <iqubic> Why not just us IO (Maybe String)?
18:45 <ertes> because then you would be using (>>=) of IO, not of (MaybeT IO)
18:45 <Aruro> iqubic: did you understand Maybe instance of a Monad? :)
18:46 <iqubic> Aruro: I did.
18:46 <Aruro> iqubic: so? Maybe + IO
18:46 <ertes> iqubic: the only reason you define the wrapper type is to be able to use a different Monad instance
18:46 <* ski> points upward to `forever' example
18:46 <iqubic> Wait. What the heck would MaybeT [] Integer be?
18:47 <iqubic> Because I think that's possible to have.
18:47 <ertes> iqubic: we can look at that later… focus =)
18:47 <iqubic> I will.
18:47 Gurkenglas joined
18:47 osa1_ joined
18:47 <ertes> iqubic: yes, it is possible… MaybeT will work with any monad
18:47 <Aruro> iqubic: why not wiki book, irc is not productive to learn
18:48 <ertes> iqubic: since that's how you defined it: "instance (Monad m) => Monad (MaybeT m)"
18:48 <simony> i think it's important to note that monads don't compose which is the motivation for transformers
18:48 wroathe joined
18:49 <simony> so the reason for that getNonEmptyLine is for further composition w/ other things that may be IO (Maybe a) type things. it probably isn't much interesting on its own?
18:50 <ertes> getNonEmptyLine is just an exercise… you wouldn't write/use it in practice, but you would just use 'guard'
18:50 doomlord joined
18:50 <ertes> do line <- liftIO getLine; guard (not (null line)); …
18:51 <iqubic> getNonEmptyLine = do line <- getLine; if line == "" then MaybeT $ return Nothing; else MaybeT $ return $ Just line
18:51 <iqubic> I really don't think my thing works.
18:51 <ertes> iqubic: feed it to GHCi
18:51 <ski> type error
18:51 <ski> (`IO' doesn't match `MaybeT IO')
18:52 <iqubic> What do you mean?
18:52 <iqubic> How should I write this function?
18:52 <ski> (it's not a function, it's an action)
18:52 <ertes> iqubic: type this into a source file after its type signature: getNonEmptyLine = _
18:52 <ski> `getLine' has type `IO String', so that whole `do'-expression must then have type `IO X', for some type `X'
18:52 <ertes> then see what GHCi tells you about _
18:53 <ski> but `if line == "" then MaybeT $ return Nothing; else MaybeT $ return $ Just line' has type `MaybeT IO String' ..
18:53 <iqubic> Ertes: I will try that.
18:53 markasoftware joined
18:53 <iqubic> ski: So my if statement is correct?
18:54 <ski> depends on what you mean by "correct"
18:54 <ertes> iqubic: once you have that keep in mind that there is only one way (apart from 'return') to construct a MaybeT action: the MaybeT constructor
18:54 esph joined
18:54 <ski> a type inconsistency involves at least two locations in the source. at least one of them needs to be changed in order to avoid the inconsistency
18:55 biglambda joined
18:55 <ski> sometimes one can solve the problem by either changing one location (and perhaps something more), or the other location (and perhaps something more)
18:55 <iqubic> Ertes: How would you write getNonEmptyLine? Using an if statement like I did.
18:56 iomonad joined
18:56 <ertes> iqubic: the 'if' is not the problem… it's fine to use it
18:56 insitu joined
18:56 <ski> iqubic : it's the interaction of that `if' (or rather the `then' and `else' branches of it) with the `getLine' (mediated by the surrounding `do'-expression) which causes the inconsistency here
18:56 <iqubic> So does my if statement have the right type?
18:57 erikd joined
18:57 <ski> depends on whether and how you change the rest of the definition
18:57 <iqubic> I have no idea how to fix that.
18:57 <ertes> iqubic: i strongly suggest that you tackle this problem piece by piece: don't start with a full non-solution and convert it into a solution, but start with an incomplete solution
18:57 <ertes> iqubic: again, type this: getNonEmptyLine = _
18:57 <ertes> i will show you how you can use GHCi to guide you to the correct solution
18:58 <iqubic> Alright. Do I type that into a new source file?
18:58 <ertes> iqubic: the one that contains your MaybeT implementation
18:58 <ski> i could say that your `if' has the right type. i could also say that it has the wrong type. it depends on how the rest of the code will be changed
18:58 <ski> possibly it will be simpler to follow ertes' recommendation
18:58 <Aruro> isnt there haskell-beginners channel?
18:58 wroathe joined
18:59 <dmj`> yea #haskell-beginners
18:59 <ski> beginner questions are welcome here
18:59 <iqubic> I'm supposed to put my MaybeT definition into a new file?
18:59 <iqubic> I can do that?
18:59 <iqubic> I can indeed do that.
18:59 <Aruro> ski: it becomes a good lesson
18:59 <Aruro> or a lecture
18:59 <* ski> nods
18:59 <ertes> iqubic: you should… i recommend always to use a real source file… dumping everything into GHCi gets unwieldy very quickly, and you can't easily change definitions
18:59 <iqubic> I'll do that.
19:01 yqt joined
19:01 <* ski> idly wonders whether iqubic instanced `MonadIO' yet
19:01 <ertes> ski: i don't think so
19:01 Madars joined
19:01 <iqubic> I haven't
19:01 <Aruro> somebody hates books ..
19:01 <* ski> likes books
19:01 <ertes> iqubic: once you have the source file, just load it into GHCi… whenever you make a change, just type ":r", and GHCi will reload
19:02 <iqubic> Alright, what does MaybeT look like.
19:03 <iqubic> Shouldn't it be a newtype
19:03 <ertes> iqubic: yes
19:03 <ertes> @src MaybeT
19:03 <lambdabot> Source not found. My mind is going. I can feel it.
19:03 <ski> <ertes> iqubic: imagine you had written this: newtype MaybeT m a = MaybeT (m (Maybe a))
19:03 <ertes> iqubic: use this one: newtype MaybeT m a = MaybeT { runMaybeT :: m (Maybe a) }
19:03 <ski> well, even
19:03 <ski> <ertes> newtype MaybeT m a = MaybeT { runMaybeT :: m (Maybe a) }
19:03 patbecich joined
19:03 <ertes> it gives you runMaybeT for free
19:04 dustinm joined
19:09 wroathe joined
19:09 jer1 joined
19:10 <iqubic> Alright so I've written out MaybeT in a source file. GHC-mod is telling me that I haven't written an applicative instance for MaybeT.
19:10 plot joined
19:10 <ertes> see, that's why you really need to use proper source files =)
19:10 <Aruro> neither u have writetn functor
19:11 <ertes> Monad is a subclass of Applicative: class (Applicative m) => Monad m
19:11 nomotif joined
19:11 tomphp joined
19:11 <iqubic> ertes: What would the Applicative Class for this look like?
19:11 Achylles joined
19:11 <ertes> iqubic: start by writing a Functor instance
19:11 <iqubic> What do I need in the Functor instance?
19:11 epsilonhalbe left
19:12 whiteline joined
19:12 <ertes> iqubic: you need to define 'fmap' for (MaybeT m)
19:12 <iqubic> How would that work?
19:12 chaosmasttter joined
19:12 <ertes> iqubic: class Functor f where fmap :: (a -> b) -> f a -> f b
19:12 <iqubic> Right.
19:12 <ertes> iqubic: now (f = MaybeT m)
19:13 <iqubic> And I need to write something like instance Monad m => Functor (MaybeT m)
19:13 <ertes> iqubic: you don't need m to be a monad to implement fmap
19:13 <ski> `Functor', not `Monad'
19:14 <* ski> 'd rename `m' to `f'
19:14 <Aruro> and people ask why haskell has a hight learning curve
19:14 <ertes> only Applicative and Monad need m to be a monad here
19:14 <koala_man> what's a good way of parsing regex where "$" can be both literal and an anchor? separate lexing pass that identifies contexts or just lookaheads?
19:15 <andrei> What's the right way to use makeLenses and makeFields on external data types that don't have fields? I'd like to somehow provide my own names for their arguments.
19:16 xcmw joined
19:16 oish joined
19:16 <iqubic> So what type signature do I need for fmap?
19:16 texasmynsted joined
19:16 kamyar joined
19:16 <ertes> iqubic: i told you
19:16 <ski> ertes already gave the signature for `fmap'
19:16 <kamyar> Hi all
19:16 <ski> you just need to specialize it, as indicated
19:17 <kamyar> Just a somehwat simple question:
19:17 skeet70 joined
19:17 <kamyar> (*3) <$> Just 7 gis Just 21
19:17 <kamyar> gives
19:18 <kamyar> Sorry! Solved!
19:18 <ski> heh, ok
19:18 <ertes> =)
19:19 <iqubic> So How will I specialize this?
19:19 <ski> old trick of realizing how to solve a problem, when figuring out how to explain it
19:19 <ertes> iqubic: f = MaybeT m
19:19 wroathe joined
19:19 <iqubic> sure.
19:20 <iqubic> I realize that.
19:20 <ski> good
19:20 <ertes> iqubic: if (f = MaybeT m), then what's the type of fmap for (MaybeT m)?
19:20 <iqubic> :t fmap
19:20 <lambdabot> Functor f => (a -> b) -> f a -> f b
19:21 takle joined
19:21 <iqubic> (a -> b) -> MaybeT m a -> MaybeT m b
19:21 <ertes> iqubic: correct
19:21 mohsen_1 joined
19:22 <Myrl-saki> EvanR: I gave it some thought.
19:22 justanotheruser joined
19:22 <Myrl-saki> EvanR: columns :: (forall a. (m b -> m (a, b)) -> m (a, b)) -> m b
19:22 <iqubic> but how do I do anything with that?
19:22 <ertes> iqubic: well, first you need to implement it =)
19:23 <ski> follow the types
19:23 <Myrl-saki> That'd make sense, right?
19:23 forgottenone joined
19:23 <Myrl-saki> (What I was doing.)
19:23 <Myrl-saki> Basically, I want to enforce the usage of the argument.
19:23 ehsanullahjan joined
19:23 <kamyar> ok
19:23 <ertes> iqubic: write the following template: instance (Functor m) => Functor (MaybeT m) where fmap f c = _
19:23 <kamyar> I get the question now:
19:23 <ertes> (ski: i don't want to rename m right now)
19:23 <kamyar> newtype TokenInfo = TokenInfo {token :: String}
19:24 <kamyar> Now I want to use TokenInfo on a IO String instead of String and get IO TokenINfo
19:24 jdt joined
19:24 <* ski> . o O ( "Follow the types. Follow Follow Follow Follow Follow the types!" )
19:25 <Myrl-saki> I actually worked.
19:25 <ertes> iqubic: comment out the Monad instance, so GHCi doesn't yell at you
19:25 <ski> kamyar : use `fmap' or `<$>' ?
19:25 <kamyar> ski: Does not work!
19:25 <Myrl-saki> I think "just follow the types" is some kind of subliminal Haskell message. :D
19:25 <monochrom> "Follow the types, wherever they lead you." -- Neil DeGrasse Typson
19:25 <ertes> kamyar: TokenInfo :: String -> TokenInfo
19:26 <iqubic> If I unbox a MaybeT and it turns out to be a Nothing, what do I do then?
19:26 <kamyar> ertes: Now I want IO String -> IO TokenInfo
19:26 <ski> @remember NeilDeGrasseTypson "Follow the types, wherever they lead you."
19:26 <lambdabot> Okay.
19:26 <ski> kamyar : does too !
19:26 <ertes> kamyar: yeah… there is a function for that
19:27 <ertes> kamyar: ski told you two of its many names
19:27 darjeeling_ joined
19:27 <kamyar> ertes: Does not work!
19:27 <kamyar> TokenInfo <$> IO "test"
19:27 <ski> it works in *my* head ..
19:27 <ertes> kamyar: well: fmap TokenInfo :: IO String -> IO TokenInfo
19:27 <kamyar> Data constructor not in scope: IO :: [Char] -> f String
19:27 <ski> `IO' is a type, it shouldn't be put in value expressions
19:27 <ertes> kamyar: what's 'IO "test"'?
19:28 <iqubic> What do I do with fmap if the MaybeT given happens to be Nothing?
19:28 <ski> (this is what you get, by naming data constructors and type constructors the same ..)
19:28 <kamyar> ertes: Yes u r right.
19:28 <ertes> iqubic: nothing
19:28 micmus joined
19:28 <kamyar> I have to send main code
19:28 <ski> ertes : beat me to it :)
19:28 <iqubic> So how do I write that Ertes?
19:28 <Myrl-saki> columns :: MonadWidget t m => [Text] -> (forall a. ([Text] -> m b -> m (a, b)) -> m (a, b)) -> m b
19:28 <Myrl-saki> Is there a better way to enforce the usage of the passed function?
19:29 Hunter1 joined
19:29 <Myrl-saki> I'm currently doing `(,) undefined <$> divClass (T.unwords $ "column":classes) inner`
19:29 <Myrl-saki> For the passed function.
19:29 <ertes> iqubic: if the action returns Nothing, just return Nothing
19:29 wroathe joined
19:29 takle joined
19:29 <ertes> iqubic: much like fmap for Maybe does
19:29 <ertes> > fmap (^2) Nothing
19:29 <lambdabot> Nothing
19:29 <ski> kamyar : the `Functor m' constraint on the `instance' declaration should give you a hint that you'll probably need to use `fmap' for `m' somewhere ..
19:29 <iqubic> But I don't have the return function availible to me when writing fmap.
19:30 <ski> er, sorry, that was meant for iqubic
19:30 xcmw joined
19:30 <ski> you don't need `return'
19:30 flatmap13 joined
19:30 <ertes> Myrl-saki: i'm answering without any context: if you want to ensure that a function is used, use either parametricity, or create a type, values of which can only be returned by that function
19:30 <ertes> iqubic: you do have fmap
19:30 <ertes> because m is a Functor
19:30 <iqubic> So...?
19:30 <iqubic> I don't understand what to do?
19:31 <iqubic> I know that I have fmap.
19:31 <ertes> iqubic: fmap f (MaybeT c) = MaybeT (_ c) -- you need to do something to c, right?
19:31 <iqubic> I don't see how that helps me.
19:31 <Myrl-saki> ertes: Am I not using parametricity there? (with te forall a.)
19:31 <ski> iqubic : consider `fmap f c = ?0', what is the expected type of the "hole" `?0' (not actual syntax) ?
19:31 nh2 joined
19:31 <iqubic> The hole needs type MaybeT m b
19:32 <iqubic> where b is the result of f.
19:32 <ski> yes, how do you construct a value of that type ?
19:32 <ertes> iqubic: feel free to type what i gave you as the definition of fmap
19:32 <ertes> then GHCi will give you a type for _
19:33 <ski> ertes jumped slightly ahead. feel free to continue from either
19:33 jkachmar joined
19:33 jkachmar joined
19:34 <iqubic> Looks like I need something of MaybeT m a -> m (MaybeT b)
19:34 <iqubic> That will fill my hole properly.
19:34 <ski> yep
19:34 tomphp joined
19:35 <ski> now, what's the type of `c' ?
19:35 <iqubic> Now, how do I get that?
19:35 <ertes> not quite
19:35 <ski> ertes : they used a mixture of both ..
19:35 <ertes> the type iqubic gave is a kind error
19:35 mjora7 joined
19:35 <ski> they probably just mistyped it over here
19:36 <* ski> looks at iqubic
19:36 <ertes> yeah, but it makes me wonder whether they continued from your point or mine =)
19:36 <ski> <ski> ertes : they used a mixture of both ..
19:36 <iqubic> ertes, I just put it into GHCi. I need MaybeT m a -> m (MaybeT b)
19:36 <ski> (as i said ..)
19:36 <ertes> iqubic: don't put it into GHCi though… write it into your source file
19:37 <iqubic> Alright. What I have so far is this: fmap f x = MaybeT $ (_ x)
19:37 <ski> `$' is redundant there
19:37 <ertes> the ($) is not necessary
19:37 <iqubic> Yeah I know.
19:37 <ski> now, what's the type of `x' ?
19:37 <iqubic> x is MaybeT m a
19:37 <ski> can you match on it ?
19:38 <iqubic> Possible.
19:38 mjora7_ joined
19:38 <iqubic> Not sure how.
19:38 <ertes> do you happen to have a function of type (MaybeT m a -> m (Maybe a))?
19:38 <ski> iqubic : how would you construct a value of type `MaybeT m a' ?
19:38 <iqubic> ertes: Isn't that just fmap
19:38 <ertes> nope
19:39 <iqubic> ertes: It's runMaybeT
19:39 <* ski> points out to iqubic that they're trying to *write* `fmap' at the moment ;)
19:39 <ertes> iqubic: the problem here is that 'x' is still MaybeT-wrapped, but you need the underlying (m (Maybe a))
19:39 <ertes> and there are two ways to "unwrap" MaybeT
19:39 <iqubic> ertes: I'm going to use runMaybeT
19:39 wroathe joined
19:39 <ertes> yeah, that's one option
19:39 <ertes> here is one that is a bit nicer: fmap f (MaybeT c) = MaybeT (_ c)
19:40 fotonzade joined
19:40 <ertes> at least if our senses of aesthetics are compatible =)
19:40 m0rphism2 joined
19:40 Denthir joined
19:40 <ski> (generally, it's usually nicer to pattern-match, if you can do so in a non-contrived way)
19:40 tomphp joined
19:41 <iqubic> Alright. I now have this: fmap f (MaybeT x) = MaybeT $ (_ x)
19:41 systemfault joined
19:41 <ertes> iqubic: now what does GHCi tell you about _?
19:41 <iqubic> To fill in the hole I need something of type m (Maybe a) -> m (Maybe b)
19:41 <iqubic> How will I get that?
19:41 <ertes> yeah… and there is a way to construct such a function, right?
19:41 <ertes> because m is a Functor
19:42 ystael joined
19:42 <iqubic> I think there is.
19:42 <iqubic> :t fmap
19:42 <lambdabot> Functor f => (a -> b) -> f a -> f b
19:43 <ertes> yeah, and what are 'f', 'a' and 'b' in this case?
19:43 thetourist joined
19:43 <iqubic> f is MaybeT. a and b are just the input and output of my function f from fmap f (MaybeT x)
19:43 <ertes> nope
19:44 <Myrl-saki> Is there something like Vault, but doesn't require IO/ST?
19:44 <iqubic> No? Ertes, how am I wrong?
19:44 <ertes> Myrl-saki: Map _ Dynamic
19:44 <Myrl-saki> ertes: I'm not sure if I should...
19:44 <Myrl-saki> =_=
19:45 <Myrl-saki> ertes: But that seems correct though. :(
19:45 <ertes> iqubic: see, you need an (m (Maybe a) -> m (Maybe b))
19:45 <ski> iqubic : the `f' in `fmap' would not be `MaybeT' in your situation
19:45 JeanCarloMachado joined
19:45 <ertes> iqubic: so a function that, given an m-action returns another m-action
19:45 theos1 joined
19:45 <ertes> Myrl-saki: you might be able to use dependent-map
19:45 <iqubic> Isn't that just fmap.
19:45 zariuq joined
19:46 <ertes> iqubic: yeah, but not fmap for (MaybeT m)
19:46 byorgey joined
19:46 <ertes> f is not (MaybeT m) here
19:46 <iqubic> It's fmap for the m in instance functor m => (MaybeT m)
19:46 <Myrl-saki> ertes: Thanks. :D
19:46 <ertes> iqubic: exactly
19:46 <ertes> iqubic: now what are 'a' and 'b'?
19:46 <iqubic> I don't know.
19:47 <ertes> iqubic: you do… let's use different names to make it less confusing:
19:47 <ertes> fmap :: (x -> y) -> m x -> m y
19:47 <iqubic> Alright.
19:47 <ertes> you need: m (Maybe a) -> m (Maybe b)
19:47 <iqubic> Okay?
19:47 <ertes> using which x and y would give you such a function?
19:48 <iqubic> a and b?
19:48 <ertes> iqubic: nope
19:48 <iqubic> Can you just tell me.
19:49 <ertes> iqubic: i'll give you a hint:
19:49 <iqubic> I have no effing clue here.
19:49 <ertes> fmap f :: m x -> m y
19:49 <ertes> where f :: x -> y
19:49 <iqubic> Alright.
19:49 <ertes> you need:
19:49 <iqubic> So what f do I use?
19:49 <ski> (better to rename `f')
19:49 <ertes> oh, yeah
19:49 <ertes> fmap g :: m x -> m y
19:49 <ertes> where g :: x -> y
19:49 <ertes> you need:
19:49 wroathe joined
19:49 <iqubic> Sure. Sounds good.
19:49 <ertes> fmap g :: m (Maybe a) -> m (Maybe b)
19:50 <ski> solve the equation
19:50 <ertes> what are x and y?
19:50 <ski> m (Maybe a) -> m (Maybe b) = m x -> m y
19:50 <iqubic> Maybe a and Maybe b?
19:50 <ertes> yeah
19:50 <ski> (treat `m',`a',`b' as constants, if you care about that)
19:50 <ertes> so the missing piece is g
19:50 <iqubic> Alright where do I get the Maybe a and Maybe b?
19:50 <ski> what type will `g' have then ?
19:51 <iqubic> g will have type Maybe a -> Maybe b
19:51 <ski> right
19:51 <ertes> fmap f (MaybeT x) = MaybeT (fmap _g x)
19:51 thetourist joined
19:51 <ertes> now GHCi will confirm that: _g :: Maybe a -> Maybe b
19:51 <ski> now, can you write `_g' ?
19:51 pradeepkumar joined
19:51 flatmap13 joined
19:51 <ski> (or fill the hole, if you prefer that terminology)
19:52 <ertes> for that you might find it useful that Maybe is also a functor
19:52 xcmw joined
19:52 <ski> (one could also use plain pattern-matching)
19:53 osa1 joined
19:53 osa1 joined
19:53 <iqubic> Alright. I need to write a function of type Maybe a into Maybe b
19:53 <ski> yes. given which pieces of information ?
19:53 <iqubic> given a function f of type (a -> b)
19:53 <iqubic> and Maybe a
19:54 <iqubic> I think I can do that
19:54 chaosmasttter joined
19:54 <* ski> nods
19:54 <dmj`> @typ fmap :: (a -> b) -> Maybe a -> Maybe b
19:54 <lambdabot> (a -> b) -> Maybe a -> Maybe b
19:54 mada joined
19:54 <iqubic> Wait, what I just described sounds a lot like fmap.
19:54 <ski> <ertes> for that you might find it useful that Maybe is also a functor
19:54 <iqubic> LOL
19:55 <ertes> iqubic: yeah, you're staring to see the patterns =)
19:55 <ertes> the matrix is revealing itself to you =)
19:56 <ski> with some practice, you should be able to play this game of "figure out type of hole, plug it partially, repeat" without asking the interactor for the types as much
19:57 <ertes> Myrl-saki: i made a few experiments, and i think that Vault can only be safe as it is in IO/ST
19:57 <iqubic> Well I think I just wrote fmap for MaybeT
19:57 pie_ joined
19:57 <iqubic> GHCi likes it.
19:57 <ertes> Myrl-saki: otherwise you really need something like dependent-map or just live with dynamic typing
19:58 <ertes> iqubic: great… it was a long way, but this will really help you in the future
19:58 <iqubic> :t fmap f (MaybeT x) = MaybeT $ fmap (fmap f) x
19:58 <lambdabot> error:
19:58 <lambdabot> parse error on input ‘=’
19:58 <lambdabot> Perhaps you need a 'let' in a 'do' block?
19:58 <iqubic> fmap f (MaybeT x) = MaybeT $ fmap (fmap f) x
19:58 <iqubic> Is that correct.
19:58 <iqubic> ??
19:58 <ertes> iqubic: yeah
19:59 <iqubic> Now, how the heck does that work?
19:59 <iqubic> Why do I need fmap twice?
19:59 <Myrl-saki> ertes: I see.
19:59 <ertes> iqubic: because you have two functor layers to cross
19:59 <iqubic> I do? Which layers?
19:59 <ertes> iqubic: one is the m layer, the other is the Maybe layer
19:59 <iqubic> Ah. I see.
20:00 wroathe joined
20:00 <iqubic> Now. Time to work on the applicative instance.
20:00 <ertes> iqubic: now write the Applicative instance: instance (Monad m) => Applicative (MaybeT m)
20:00 justanotheruser joined
20:01 <iqubic> Well, Pure was simple as heck.
20:01 <ertes> iqubic: once you wrote 'pure', you can remove 'return' from the Monad instance… they are the same function
20:02 <iqubic> I just stole the definition from the return function.
20:02 <ertes> 'return' defaults to: return = pure
20:03 ehsanullahjan joined
20:03 <iqubic> Now for f <*> x I need a something of type MaybeT m b
20:03 Itkovian joined
20:03 <iqubic> where m is monad and b is err... somthing.
20:03 <ertes> iqubic: yeah, and since 'f' and 'x' are both MaybeT-valued, you can pattern-match right away
20:03 <ertes> MaybeT cf <*> MaybeT cx = _
20:03 <iqubic> :t <*>
20:03 <lambdabot> error: parse error on input ‘<*>’
20:03 safe joined
20:03 <iqubic> :t (<*>)
20:03 <lambdabot> Applicative f => f (a -> b) -> f a -> f b
20:04 <iqubic> Isn't this the exact same as fmap from here?
20:04 <c_wraith> not quite.
20:04 <c_wraith> the (a -> b) is inside an f
20:04 <iqubic> so I extract that, then it becomes the same as fmap.
20:05 <c_wraith> In your case, yes.
20:05 <ertes> iqubic: there are actually two possible semantics for (<*>)… keep in mind that you want short-circuiting semantics
20:05 <c_wraith> There are cases where there's nothing to extract, which makes it more interesting :)
20:05 <ertes> i.e. if the first action returns Nothing, the second action should be ignored
20:06 latro`a joined
20:06 <ski> (three possible, i suppose)
20:06 <iqubic> ertes, only on of the inputs of <*> is an action.
20:06 <ertes> yeah, at least two
20:06 <ertes> iqubic: no, both are
20:06 <ertes> look at the type
20:06 <iqubic> I see the action of (a -> b) and the action of a
20:08 <ski> yep
20:08 bl0w3d_0ut joined
20:08 <iqubic> So what do I do with <*>?
20:08 beanbagula joined
20:08 <ertes> iqubic: use the same approach as before
20:08 <ski> run action, check result ?
20:08 <ertes> MaybeT cf <*> MaybeT cx = _
20:09 <ertes> if you think that the first layer of _ is obvious, just fill it in and leave a new hole
20:09 <iqubic> I need something of type m (Maybe b)
20:09 <ski> yes
20:09 <ertes> does GHCi agree?
20:10 emerson joined
20:10 wroathe joined
20:10 <iqubic> ertes, I'm only going to list the type signature after checking it with GHCi
20:10 <ertes> ok, now there is only one way to get a value of type 'b'
20:11 <iqubic> run the function f.
20:11 <iqubic> That's the only way to do it.
20:11 <ertes> the way you wrote it 'f' is not a function
20:11 <iqubic> where f comes from MaybeT f <*> MaybeT x
20:11 <ertes> i suggest that you rename it to cf or something
20:11 <iqubic> I will
20:12 vydd joined
20:12 vydd joined
20:12 <iqubic> So I need to run cf to get a result of b.
20:12 plot joined
20:12 <ertes> cf gives you a result of what type?
20:12 umib0zu joined
20:13 <iqubic> Maybe b
20:13 laserpants joined
20:14 BartAdv joined
20:14 <iqubic> Now what do I do with that Maybe b?
20:15 <Lokathor> pattern match on it
20:16 <iqubic> I'll try that.
20:16 <Lokathor> i haven't been following along one bit, but that's my default response
20:16 <Lokathor> you might want a smarter funciton than that, depending on context :P
20:16 <ij> I've a record R with a field F and an «F -> Maybe F». How do I make this into «R -> Maybe R»?
20:16 beerdrop joined
20:17 <laserpants> In haddock, I am trying to create a link to an anchor, but there seems to be no way to change the link description. Is there some other way to create a link to some point within the same page? E.g., to a title == MyTitle, or using the $ annotation?
20:17 <ertes> iqubic: wrong
20:17 <ertes> cf has a different result type
20:17 <glguy> ij: Apply the lens corresponding to that field to that function
20:17 <iqubic> Right. It appears to be m (Maybe b)
20:17 <iqubic> Where m is a monad
20:18 <glguy> ij: For example: _1 :: (a -> Maybe a) -> (a,b) -> Maybe (a,b)
20:18 <ertes> iqubic: nope, but you don't need to guess here… look at the hole error GHCi reports
20:18 <ertes> iqubic: it actually shows you the type of 'cf'
20:19 <iqubic> Right. m (Maybe (a -> b)) is the type of cf
20:20 <ertes> iqubic: so: MaybeT cf <*> MaybeT cx = MaybeT (do mf <- cf; _)
20:20 wroathe joined
20:20 <ertes> iqubic: you can use do-notation, because m is a monad
20:21 <iqubic> Right.
20:22 xcmw joined
20:22 <iqubic> How do I get a value of m (Maybe b)
20:23 <EvanR> :t return Nothing
20:23 <lambdabot> Monad m => m (Maybe a)
20:23 <iqubic> Oh. I see what to do.
20:23 dm3 joined
20:25 <iqubic> Wait, no. No I don't/
20:26 <ertes> iqubic: first you need to check whether cf actually gave you a function by pattern-matching on mf
20:26 mithrandeer joined
20:26 <ij> glguy, Huh! So no Control.Lens functions, I just use lens. Wow.
20:27 <iqubic> So I pattern match on mf and get either a Nothing or a Just val.
20:27 <iqubic> What do I do with those?
20:27 <ski> think about what you *can* do in each case
20:28 <iqubic> Well in the case of Nothing, I can't do anything.
20:28 Achylles joined
20:28 <ski> well, you have to give a result of .. which type ?
20:28 <glguy> ij: If you want to use something from Control.Lens, you can use traverseOf (which is implemented as 'id')
20:28 <iqubic> I have to give a result of m (Maybe b)
20:29 <ski> yes
20:29 <ertes> iqubic: what are your option to get a value of type 'b'?
20:29 oish joined
20:29 <ertes> *options
20:29 arpl joined
20:29 dm3 joined
20:29 <iqubic> Ertes, I don't know.
20:30 <ertes> iqubic: is there anything that would give you a value of type 'b'?
20:30 <* ski> . o O ( "What, you mean a european option or an american option?" )
20:30 <iqubic> I think that mf would give me a type of b
20:31 <ertes> iqubic: if it happens to be Just, it gives you a function that returns a 'b'
20:31 <ertes> iqubic: what if it's Nothing?
20:32 <iqubic> I can only do return Nothing.
20:32 <ertes> yeah
20:32 <iqubic> But what do I do if I get a Just?
20:32 tromp joined
20:32 <ertes> well, you could run cx, but you couldn't do anything with its result
20:32 <ertes> first handle the Nothing case
20:32 <ertes> leave a hole for the Just case
20:34 <iqubic> Alright, I have narrowed down my type holes to needing something of type a.
20:34 <iqubic> I have the function of (a -> b)
20:34 <iqubic> but now I need the a to supply it.
20:34 <ertes> correct, now in the Just case you might be able to construct something of type 'a'
20:34 <ertes> that's where cx comes in
20:34 <ertes> (or whatever you called it)
20:35 Denthir joined
20:35 <iqubic> Yeah. But how do I unbox that
20:35 <ertes> paste what you have right now
20:35 <iqubic> cx currently has the type of m (Maybe a)
20:36 <ertes> so: you need an (m (Maybe b)), and you have an (m (Maybe a))
20:36 <ertes> as well as a function of type (a -> b)
20:36 <ertes> does that sound familiar?
20:36 <iqubic> http://termbin.com/mnak
20:36 Hunter1 joined
20:37 <iqubic> That hole has type a
20:37 <ertes> return to this: Just func -> _
20:37 <ertes> there is no way to get an 'a' there
20:37 <* ski> suggests reverting `return $ Just $ func _' back to `_', continuing from there with this new information
20:38 <ertes> you solved your way into a dead end =)
20:38 <iqubic> If I have Just func -> _ then I need something of type m (Maybe B)
20:38 <ertes> yeah
20:38 <ski> now you know that you'll probably need `cx' in there
20:39 <ertes> you have (cx :: m (Maybe a)), and you need (m (Maybe b))
20:39 <ski> how can you use it, in a sensible way ?
20:39 <ertes> you also have (func :: a -> b)
20:39 <iqubic> Bind?
20:39 <ertes> does that sound familiar?
20:39 <ski> that's one way
20:40 <iqubic> No. I don't think that bind works
20:40 hexfive joined
20:40 <ertes> "you have an X, and you need a Y" is basically the same as: "you need an X -> Y"
20:40 <iqubic> Sure.
20:40 <iqubic> How do I do that?
20:40 <ertes> so you have: func :: a -> b
20:40 <iqubic> I just use func?
20:40 <ertes> and you need: m (Maybe a) -> m (Maybe b)
20:40 <ski> remember the `Functor' instance ?
20:40 nesscaffe joined
20:41 {emptyset} joined
20:41 <ski> (but bind will too work)
20:41 <ertes> in other words: you need to do something to cx
20:41 <ertes> Just func -> _ cx
20:41 <iqubic> Yeah. I remeber the functor instance.
20:41 <ertes> this might ring a bell
20:42 <iqubic> Do I use fmap?
20:42 <ertes> well, is m a Functor?
20:42 <iqubic> Yes.
20:42 <iqubic> It is.
20:42 <ertes> then you can use fmap
20:43 ystael joined
20:43 <iqubic> but What do I use fmap on?
20:43 <iqubic> What is the type of func?
20:43 <ertes> Just func -> _ cx
20:43 <ertes> _ :: m (Maybe a) -> m (Maybe b)
20:43 <ertes> does that help?
20:43 <ski> what is the type of `mf' ?
20:44 <ertes> (not sure how mf is helpful here)
20:44 verement joined
20:44 <ski> ("<iqubic> What is the type of func?")
20:44 <ertes> ah
20:44 <ertes> overlooked
20:44 <iqubic> How do I get something that is Maybe a -> Maybe b?
20:45 <ertes> iqubic: well, if you had an (a -> b), you could use the fact that Maybe is a functor
20:45 <lyxia> http://lpaste.net/355086 Look ma, no brackets! (Warning, abuse of syntax)
20:45 <iqubic> I just got it.
20:46 <Myrl-saki> Holes are awesome once you learn to use them.
20:47 <iqubic> http://termbin.com/lhag
20:47 <* ski> has fond memories of Alfa
20:47 <iqubic> That's what the three instances look like now.
20:47 <iqubic> And GHCi claims that their all correct.
20:47 <ertes> iqubic: you made it
20:47 <ski> looks right
20:47 <iqubic> Now, what does this thing actually do??
20:48 <iqubic> Why is this MaybeT useful?
20:48 <ertes> GHCi only claims that they are well-typed, but yes, they are indeed correct
20:48 <ertes> iqubic: now that you have those, we can return to the original exercise
20:48 <ski> iqubic : try my `forever' example (after also making a `MonadIO' instance) ?
20:48 <ertes> iqubic: getNonEmptyLine :: MaybeT IO String
20:48 zeroed joined
20:48 zeroed joined
20:48 umib0zu joined
20:48 <ski> (and after completing that exercise, yes)
20:48 mjora7 joined
20:49 wroathe joined
20:49 <Myrl-saki> ertes: TBF, you'd most likely be using `:: IO (Maybe String)` :P
20:49 <ertes> Myrl-saki: depends… i'm quite a regular user of MaybeT
20:49 <Myrl-saki> ertes: For IO ops?
20:49 <ertes> Myrl-saki: yeah
20:49 <Myrl-saki> ertes: Interesting.
20:49 <Myrl-saki> ertes: That does make sense though.
20:50 <Myrl-saki> Isn't MaybeT a newtype?
20:50 <ertes> it is
20:50 <ertes> @src MaybeT
20:50 <lambdabot> Source not found. Sorry about this, I know it's a bit silly.
20:51 <Myrl-saki> newtype MaybeT m a = MaybeT { runMaybeT :: m (Maybe a) }` IIRC?
20:51 <iqubic> Alright, what is MonadIO?
20:51 <ski> class Monad m => MonadIO m
20:51 <ski> where
20:51 <ski> liftIO :: IO a -> m a
20:51 <ertes> iqubic: have you completed getNonEmptyLine?
20:52 <iqubic> No.
20:52 <glguy> > do 1 + 2; * do 3 + 4 -- lyxia, you can use the semicolon to get things back on one line
20:52 <ski> do that first
20:52 <iqubic> I have not tried that.
20:52 <lambdabot> 21
20:52 <ertes> iqubic: then do that first… you're very easy to distract =)
20:52 <Myrl-saki> glguy: wow.
20:52 <iqubic> I will do that first
20:53 <ertes> you can also line up the operator with the 'do's
20:53 Aruro_ joined
20:53 <Myrl-saki> Can you nest dos without brackets?
20:54 <ertes> > do do do do Nothing
20:54 <lambdabot> Nothing
20:54 <Myrl-saki> > do 1 + do 2
20:54 <lambdabot> 3
20:54 <Myrl-saki> Reeee
20:54 <Myrl-saki> > do 1 + do 2;; * 4
20:54 <ertes> yeah, that one nests
20:54 <lambdabot> 9
20:54 <Myrl-saki> I'm scared.
20:54 <iqubic> Alright, why is it that I can't just write "do line <- getLine"
20:54 ehsanullahjan joined
20:55 <ertes> (do 1 + do 2) = do 1 + (do 2)
20:55 <iqubic> Apparently type IO /= type MaybeT IO
20:55 <Myrl-saki> (Of course.)
20:55 <ertes> iqubic: getNonEmptyLine = _ -- how do you construct a MaybeT again?
20:55 <iqubic> MaybeT
20:55 <iqubic> I use the data constructor
20:56 <ertes> iqubic: getNonEmptyLine = MaybeT _ -- correct… now continue from here
20:56 insitu joined
20:56 zeroed joined
20:56 tomphp joined
20:56 <Myrl-saki> iqubic: Do you know what to put inside MaybeT?
20:56 <Myrl-saki> (Look at the type, it will help.)
20:56 <iqubic> Looks like I need something of IO (Maybe String)
20:57 <iqubic> if that seems right.
20:57 <ertes> iqubic: yeah
20:57 <Myrl-saki> ;)
20:57 <ertes> iqubic: just try it on your own… remember that _ is just a plain old IO action with a result of type (Maybe String)
20:58 <ertes> it's no longer related to MaybeT in any way
20:58 JoshS joined
20:58 <iqubic> Got it.
20:58 ertesx joined
20:59 wroathe joined
20:59 <ertesx> disconnected… <ertes> iqubic: just try it on your own… remember that _ is just a plain old IO action with a result of type (Maybe String) <ertes> it's no longer related to MaybeT in any way
20:59 homesitter joined
21:01 <lyxia> glguy: how fun
21:01 <iqubic> How do I use that action I just wrote?
21:01 <iqubic> I want to test it.
21:02 <Aruro> :t do 1
21:02 <lambdabot> Num t => t
21:02 <Aruro> :t return 1
21:02 <lambdabot> (Num a, Monad m) => m a
21:02 <iqubic> http://termbin.com/ae4j
21:03 <iqubic> Does that look like the right implementation of getNextNonEmptyLine?
21:03 bjz joined
21:04 turist joined
21:04 <iqubic> I think it's right, but I don't know how to test that.
21:06 skeuomorf joined
21:06 <glguy> Aruro: The 'do' in do-notation does not introduce a Monad constraint per se
21:08 <ertes> iqubic: main = runMaybeT getNonEmptyLine >>= print
21:08 <iqubic> Does my function work?
21:09 <ertes> iqubic: it's correct, but you can write it slightly more nicely
21:09 <iqubic> How?
21:09 <ertes> iqubic: do line <- getLine; pure (if null line then Nothing else Just line)
21:09 wroathe joined
21:10 <ertes> there are nicer ways than that, but those require introducing new functions
21:10 <ski> (factoring out the `return')
21:11 <iqubic> I did factor out the return.
21:11 <iqubic> And changed line == "" to null line
21:13 <pikajude> hlint will tell you about that btw
21:13 robatosan joined
21:13 <pikajude> if you're using `== ""`
21:13 <iqubic> I don't use hlint
21:13 <pikajude> hmmm
21:13 <pikajude> it may be time
21:13 jer1 joined
21:13 ccomb joined
21:14 <ertes> iqubic: you're fine… hlint does warn about some useful things, but it's also highly opinionated as to what makes good haskell coding style
21:14 <pikajude> ok fair
21:14 <Aruro> null vs =="", thats the problem
21:15 newhoggy joined
21:16 <Aruro> :t null
21:16 <lambdabot> Foldable t => t a -> Bool
21:16 <Aruro> :t (==)
21:16 <lambdabot> Eq a => a -> a -> Bool
21:16 <ertes> most of the suggestions *i* get from hlint trigger my bullshit alarm =)
21:16 ystael joined
21:16 <Aruro> why hlint hates lambdas that the question
21:17 <ertes> every time it wants me to remove "unnecessary parentheses" or "why not fromMaybe"
21:17 <kadoban> For me it's about 50/25/25 good ideas/bullshit/kinda meh but sure
21:19 wroathe joined
21:20 <ertes> for me it's 20/80 bullshit/"leave me alone, i'll do that later"
21:21 <kadoban> I know you can change wtf it hints to you, but I've never gotten around to actually seeing if I could improve its advice that way.
21:21 <kadoban> "improve" as-in closer to my personal preferences that is
21:22 Fendor joined
21:22 <iqubic> So, what more do I need to know about Monad Transformers?
21:22 texasmynsted joined
21:22 <ertes> iqubic: you haven't really "used" MaybeT yet
21:23 blbrown_win3 joined
21:23 <iqubic> But I wrote getNextNonEmptyLine :: MaybeT IO String
21:23 <iqubic> That's got to count for something.
21:23 <ertes> iqubic: now comes the interesting part: you need to implement a MonadTrans instance, which you can import from Control.Monad.Trans.Class
21:24 <iqubic> What is MonadTrans?
21:24 <ertes> class MonadTrans t where lift :: (Monad m) => m a -> t m a
21:24 <iqubic> Should I write this in a source file?
21:24 <ski> always
21:24 <ertes> just keep writing to the file you had
21:24 meba joined
21:24 <Aruro> i think new file is needed
21:25 Digit joined
21:25 seanparsons joined
21:25 <iqubic> Aruro, why do you say that?
21:25 <ertes> because Aruro wants you to write orphan instances =)
21:25 <iqubic> ertes: what do you want me to create?
21:25 <ertes> iqubic: instance MonadTrans MaybeT
21:25 newhoggy joined
21:25 cschneid_ joined
21:25 <iqubic> Does that require an import?
21:26 <ertes> iqubic: import Control.Monad.Trans.Class
21:26 <ski> @index MonadTrans
21:26 <lambdabot> Control.Monad.Trans.Class
21:26 reggie_ joined
21:27 <iqubic> Do I need any constraints on that?
21:27 <ertes> you don't have any type variables to constrain
21:28 doomlord joined
21:28 <iqubic> So, how does lift work?
21:29 tomphp joined
21:29 <ertes> first of all let's understand what it does:
21:29 <ski> figure out the specialized type of `lift', for your instance
21:29 moth joined
21:29 <ertes> example instantiation: lift :: IO a -> MaybeT IO a
21:29 <ertes> iqubic: does that answer your question?
21:29 wroathe joined
21:30 <iqubic> How hard is that to write?
21:30 arpl left
21:30 <ertes> it's fairly straightforward given your experience
21:30 <iqubic> :t lift
21:30 <lambdabot> (Monad m, MonadTrans t) => m a -> t m a
21:30 <ski> not hard, if you've understood the process you did before
21:30 <ski> it's probably good practice
21:31 <ertes> use the usual hole-by-hole approach again
21:31 JeanCarloMachado joined
21:31 <ertes> lift c = _
21:31 <iqubic> MaybeT m a
21:31 <ski> perhaps you can figure out the types of the holes yourself, this time ?
21:31 <iqubic> How do I get that?
21:31 <ertes> well, remember how to construct MaybeT
21:32 m1ng0sfear joined
21:32 <iqubic> How do I get something of type m (Maybe a)?
21:33 <ertes> iqubic: what do you have?
21:33 <iqubic> an m a
21:33 <ski> so you want to go `m a -> m (Maybe a)'
21:33 <iqubic> yes I do.
21:33 <ski> now .. how could you do such a thing ?
21:33 <ertes> so you have (m a), but you need (m (Maybe a)), which means that you need to do something to c again
21:34 <* ski> looks at scrollback
21:34 <iqubic> Sure.
21:34 augur joined
21:34 <ertes> if you Just had a function of type (a -> Maybe a), you could…
21:35 <* ski> sees what ertes did there ..
21:35 texasmynsted joined
21:35 <iqubic> I have a function of a -> a Maybe a
21:35 <iqubic> It's called Just
21:35 <ski> yes. how to proceed, then ?
21:36 Elhamer joined
21:36 <iqubic> I don't know.
21:37 asm89 joined
21:37 <ski> you have `Just :: a -> Maybe a'. you want to get a `m a -> m (Maybe a)'
21:37 <ski> have you done something similar to this in the past ?
21:38 <iqubic> Is this fmap?
21:38 <ertes> depends: is m a functor?
21:38 <iqubic> Yes.
21:38 <iqubic> It is.
21:38 <ertes> how do you know?
21:38 <iqubic> I don't
21:39 <ski> what do you know about `m' ?
21:39 <iqubic> Nothing really.
21:39 <ertes> let's review the class definition
21:39 <ertes> @src MonadTrans
21:39 <lambdabot> Source not found. You type like i drive.
21:39 <ski> what is the (specialized) type signature of `lift' here ?
21:39 <iqubic> Monad m
21:39 <ertes> you got it, tsunderebot…
21:39 <ski> iqubic : yep .. and ?
21:39 wroathe joined
21:40 <iqubic> MonadTrans t
21:40 <ertes> iqubic: ski wants you to give a full type signature for lift specialised to t = MaybeT
21:40 <iqubic> I don't know how to write that.
21:40 <ski> well, i wanted
21:40 thetourist joined
21:41 <ertes> lift :: (Monad m) => …
21:41 thetourist joined
21:41 <ski> iqubic : anyway, `m' is known to be an instance of `Monad'. what does that buy us ?
21:42 <ski> @src Monad
21:42 <lambdabot> class Applicative m => Monad m where
21:42 <lambdabot> -- Note: Applicative wasn't a superclass before GHC 7.10
21:42 <lambdabot> (>>=) :: m a -> (a -> m b) -> m b
21:42 <lambdabot> (>>) :: m a -> m b -> m b
21:42 <lambdabot> return :: a -> m a
21:42 <lambdabot> fail :: String -> m a
21:42 <ski> @src Applicative
21:42 <lambdabot> class Functor f => Applicative f where
21:42 <lambdabot> pure :: a -> f a
21:42 <lambdabot> (<*>) :: f (a -> b) -> f a -> f b
21:42 thetourist joined
21:42 aidan` joined
21:42 <iqubic> Ski, it buys us fmap, <*>, return, and >>=
21:42 <ski> right
21:42 <aidan`> \exit
21:43 <aidan`>
21:43 <ski> an instance of `Monad' is already an instance of `Applicative', and thus also of `Monad'
21:43 <ski> so you do have `fmap' for `m'
21:43 thetourist joined
21:43 cyborg-one joined
21:43 <ski> so you know the answer to
21:43 <ski> <ertes> depends: is m a functor?
21:44 thetourist joined
21:44 <ski> (.. er, and thus also of `Functor', i meant to say. and taht buys us `fmap' for `m')
21:44 <iqubic> WHy does fmap help us again?
21:45 <ertes> iqubic: lift c = MaybeT (_ c)
21:45 <ertes> _ :: m a -> m (Maybe a)
21:45 <ertes> you happen to have an: a -> Maybe a
21:45 <ertes> and m is a functor
21:46 <iqubic> Now I just need an a -> maybe a
21:46 <ertes> you have one
21:47 <iqubic> got it
21:47 <ski> <iqubic> I have a function of a -> a Maybe a
21:47 <iqubic> lift c = MaybeT $ fmap Just c
21:47 <EvanR> a maybe a
21:47 <ski> right
21:47 <iqubic> Now, why the heck does that help me?
21:47 <ski> that wasn't so hard, now was it ?
21:47 <EvanR> does not compute (kind check)
21:47 <iqubic> EvanR: GHC is fine with it
21:47 <EvanR> oh i was thinking a (maybe a)
21:47 <ertes> iqubic: now you can actually *use* MaybeT: 'lift' lets you… well… "lift" an IO action into MaybeT IO
21:48 <ski> btw, note that `return = Just' in the `Maybe' case
21:48 <iqubic> I see.
21:48 <ski> so, instead of `Just', you could say `return', if you wanted to ..
21:48 {emptyset} joined
21:48 <* ski> . o O ( `forever (liftIO putStrLn =<< getNonEmptyLine)' )
21:49 xcmw joined
21:49 <ertes> iqubic: so you can write something like: do lift (putStrLn "Say something!"); ln1 <- getNonEmptyLine; lift (putStrLn "Say something else!"); ln2 <- getNonEmptyLine; lift (do putStrLn "You said:"; putStrLn ln1; putStrLn ln2)
21:49 <iqubic> ertes: what would that do?
21:49 <ski> try it ?
21:49 <ertes> iqubic: if at any point the user enters an empty line, the whole thing short-circuits
21:50 <ertes> iqubic: give this action a name: testMaybeT
21:50 wroathe joined
21:50 <ertes> then try it: main = do runMaybeT testMaybeT; pure ()
21:50 <iqubic> I will try that.
21:50 ublubu joined
21:50 <iqubic> Why do you need the pure () at the end?
21:50 <ski> you don't
21:50 <ertes> next try ski's example, but replace "liftIO" by "lift"
21:51 <ertes> you do, if you're like me and always write type signatures for top-level definitions =)
21:51 <ertes> main :: IO ()
21:51 <ertes> runMaybeT testMaybeT :: IO (Maybe ())
21:51 <ski> just write `main :: IO (Maybe ())' instead :)
21:51 kamog joined
21:51 <iqubic> What should I write to test this?
21:51 <ertes> iqubic: in GHCi just type: :main
21:52 <ski> ertes gave code for testing `testMaybeT'
21:52 <ertes> in fact you can ignore my testing code and just type this directly into GHCi: runMaybeT testMaybeT
21:53 hiratara joined
21:53 jmcarthur joined
21:54 <torstein_> what does this mean? newtype s >> a = Named a
21:54 <ertes> torstein_: you're defining a type named (>>)
21:54 <ski> `(>>)' is an infix type operator
21:55 justan0theruser joined
21:56 beanbagula joined
21:57 newhoggy joined
21:57 simukis joined
21:59 simukis joined
22:00 <iqubic> I love that testMaybeT thing
22:00 simukis joined
22:00 wroathe joined
22:02 <ertes> iqubic: try ski's example, too
22:02 <iqubic> And we could not have made the action short-circuit if we had just used IO (Maybe ())
22:02 dm3 joined
22:02 <iqubic> We had to use MaybeT IO ()
22:02 <ertes> runMaybeT (forever (lift . putStrLn =<< getNonEmptyLine))
22:02 <iqubic> what was ski's example?
22:02 irithor joined
22:03 <irithor> Hello, anyone there?
22:03 <ertes> i took the liberty of fixing a bug =)
22:03 <ertes> iqubic: well, you can short-circuit, but you need to do it implicitly
22:03 <ertes> *explicitly
22:03 <ertes> with MaybeT it's implicit in the semantics of (>>=)
22:03 <irithor> Just starting out learning Functional Programming and stumbled across this group. I'm good at OO programming - are there any good resources out there to help?
22:04 <iqubic> ertes: GHCi doesn't like that. Not in scope forever MaybeT IO () -> MaybeT m a
22:04 <ertes> hi and welcome, irithor!
22:04 <irithor> Hi there :)
22:04 <ertes> iqubic: import Control.Monad
22:04 <kadoban> irithor: I quite like http://haskellbook.com/ (warning: it's not free). There's other free resources that are okay
22:04 erikd joined
22:05 meoblast001 joined
22:05 <MonadHendrix> TIL i can do `x, y, z :: Integer`
22:05 <* MonadHendrix> rejoices
22:05 simukis_ joined
22:05 <irithor> Thanks kadoban! I will check that one out.
22:05 <kadoban> Haah, yeah. Not used too much, but it works well some places.
22:05 <ertes> irithor: the first step is to be open-minded… you will not be doing OO in haskell
22:05 <iqubic> ertes. I like that a lot too.
22:06 <iqubic> I like the forever thing a lot
22:06 <ertes> irithor: it's a very different way to solve software engineering problems
22:06 <glguy> MonadHendrix: That works both in records and when making normal definitions
22:06 <irithor> Ok I understand, I'll clear my head - go on
22:06 m1ng0sfear joined
22:06 <iqubic> Do you have GHC installed?
22:06 <iqubic> DO you have GHCi?
22:07 <irithor> Installing it now!
22:07 <ertes> irithor: are you going to *learn* haskell, or do you just want to get a feeling for what it's like?
22:08 soniku joined
22:08 <irithor> I just want to get a feeling. I'm studying functional programming for my degree you see, and I thought learning a functional language could help me to grasp the theory.
22:08 <ertes> (biased opinion: you should learn it) =)
22:08 Koterpillar joined
22:08 <MonadHendrix> glguy: cool, i just used it to make flycheck shut up with -Wmissing-signatures :p
22:08 <MonadHendrix> instead of having three separate type signatures
22:08 <ertes> irithor: actually i think these are fine in either case: https://www.seas.upenn.edu/~cis194/spring13/lectures.html
22:09 <* MonadHendrix> king of compromise
22:09 Tharbakim joined
22:09 Tharbakim joined
22:09 <kadoban> Sounds important, learning a function language.
22:09 <EvanR> irithor: youre about the enter a world...
22:09 <EvanR> er... dang
22:09 <EvanR> functional programming rocks
22:10 <ertes> irithor: if you have 10 minutes, here is also a funny demo: https://www.youtube.com/watch?v=RqvCNb7fKsg
22:10 <irithor> Thanks! I'm watching now.
22:10 wroathe joined
22:11 justanotheruser joined
22:11 <Tuplanolla> Has anyone just so happened to use CiNii?
22:11 <MonadHendrix> possibly the best haskell video ever
22:11 <MonadHendrix> hfeflflfo
22:12 rightfold joined
22:12 cloudhead joined
22:12 <rightfold> What is the newtype wrapper for IO for which (<*>) does parallelism called?
22:12 justanotheruser joined
22:13 plot joined
22:13 <rightfold> In PureScript it's ParAff, but in Haskell ParIO *seems* to be different (as it also has a Monad instance)
22:13 <ertes> rightfold: https://hackage.haskell.org/package/async-
22:13 <rightfold> ertes: Thanks a lot, seems to be it! (Y)
22:13 justanotheruser joined
22:16 Sose_ joined
22:17 carlomagno joined
22:17 justanotheruser joined
22:17 <irithor> Hahahahaha, Swedish greeting.
22:18 augur joined
22:18 <iqubic> How does that last function work?
22:18 mithrandeer joined
22:18 <iqubic> The one in the video that appears to be infinite?
22:19 justanotheruser joined
22:19 <ertes> it's not infinite
22:19 <ertes> he's applying 'very' to 'very'
22:19 wizwizwizwiz joined
22:20 <iqubic> So why does that make a super super long string?
22:20 <ertes> @let very f = f . f . f
22:20 <lambdabot> Defined.
22:20 <ertes> > very very f
22:20 <lambdabot> error:
22:20 <lambdabot> • No instance for (Typeable b0)
22:20 <lambdabot> arising from a use of ‘show_M158506368030085294131433’
22:20 <ertes> > very very f :: Expr
22:20 <lambdabot> error:
22:20 <lambdabot> • Couldn't match expected type ‘Expr’ with actual type ‘b0 -> b0’
22:20 <lambdabot> • Probable cause: ‘very’ is applied to too few arguments
22:20 <ertes> oh…
22:20 <ertes> > very very f x :: Expr
22:20 <lambdabot> f (f (f (f (f (f (f (f (f (f (f (f (f (f (f (f (f (f (f (f (f (f (f (f (f (f...
22:20 aarvar joined
22:20 <iqubic> How is that not infinite?
22:20 wroathe joined
22:20 <iqubic> It is, isn't it?
22:21 <ertes> graham's number is also not infinite =)
22:21 <iqubic> How many times does that apply f?
22:21 <c_wraith> I'd guess 81
22:21 <ertes> 27 times, i think
22:21 <iqubic> I think it's 27
22:21 <ertes> iqubic: very very f = very (very (very f)) = very (very (f . f . f)) = very (f . f . f . f . f . f . f . f . f)
22:21 <c_wraith> Oh, I think I associated backwards
22:22 <MarcelineVQ> > very very (+1) 0
22:22 <lambdabot> 27
22:22 <iqubic> It's 27 times then
22:22 <ertes> it's not even that large
22:22 <rightfold> pi is infinite, 27 > pi, therefore 27 is infinite :troll:
22:22 <ertes> he just aborted it very quickly
22:22 <iqubic> LOL
22:23 mithrandeer joined
22:23 <ertes> > very very very (+1) 0
22:23 <lambdabot> *Exception: stack overflow
22:23 <irithor> lol
22:23 <int-e> now which is larger, very very very f x, or very (very very) f x
22:24 <rightfold> (.) is associative
22:24 <rightfold> I think they're the same
22:24 <MarcelineVQ> rightfold: try them :>
22:24 <int-e> well, they're not the same.
22:24 <ertes> no, i don't think so
22:24 <rightfold> OK
22:24 <int-e> > very (very very) (+1) 0 -- this might still work, actually.
22:25 <lambdabot> 19683
22:25 <MarcelineVQ> it will
22:25 <int-e> > 3^27 -- very very very (+1) 0
22:25 <lambdabot> 7625597484987
22:25 <ertes> it's a bit like knuth's up arrow
22:25 <ertes> explodes very quickly
22:25 <iqubic> Yeah. I get that.
22:25 <int-e> ertes: very much so ;-)
22:26 <int-e> (it helps to know that `very` is the Church numeral 3)
22:26 <irithor> I'm cracking up at this video. Brilliant.
22:27 Wizek joined
22:28 <iqubic> Alright, now that I understand MaybeT, what more is there to understand about Monad Transformers?
22:28 <ertes> iqubic: well, first familiarise yourself with the others
22:28 <ertes> StateT is a particularly useful one
22:29 <iqubic> How the heck does StateT work.
22:29 <ertes> remember State?
22:29 <iqubic> I understand State as a Monad.
22:29 <iqubic> But not StateT
22:29 <ertes> newtype StateT s m a = StateT { runStateT :: s -> m (a, s) }
22:29 <ertes> adds a state effect to m
22:29 meoblast001 joined
22:29 bollu joined
22:30 <iqubic> Can I see an example?
22:30 <iqubic> Or do you want me to go through and write the functor, applicative, and monad instances?
22:30 wroathe joined
22:31 <Tuplanolla> Don't overthink it, iqubic. It's a rather trivial generalization.
22:31 <ertes> > runStateT (do x <- get; when (x == 0) (lift Nothing); put (2*x)) 15
22:31 <lambdabot> Just ((),30)
22:31 <ertes> > runStateT (do x <- get; when (x == 0) (lift Nothing); put (2*x)) 0
22:31 <lambdabot> Nothing
22:31 <iqubic> What do those do?
22:31 hiratara joined
22:32 <ertes> iqubic: that's StateT over Maybe
22:32 Aeroxam joined
22:32 <ertes> Maybe is a short-circuiting monad, and StateT makes it stateful
22:32 tromp joined
22:33 geppettodivacin joined
22:33 <ertes> this is really easy to see, if you just look at the definition: an action of type (StateT S Maybe A) is basically a function of S that returns (Maybe (A, S))
22:33 <iqubic> I understand.
22:34 <rightfold> The implementation is a lot like that of State, but roughly, you replace in some places id by pure, ($) by (=<<), and (.) by (<=<)
22:34 <ertes> similarly you can equip IO with state: StateT S IO
22:34 <iqubic> How does that work?
22:34 <ertes> StateT S IO A ≃ S -> IO (A, S)
22:35 bjz joined
22:35 <iqubic> Can I see an example of StateT IO A in action?
22:36 saep joined
22:36 <rightfold> incr = do { old <- get; liftIO (print old); modify (+ 1) }
22:36 <ertes> iqubic: try to come up with one yourself
22:37 <ertes> iqubic: remember that (StateT s) is a monad transformer, so you can use 'lift'
22:37 <iqubic> rightfold: Does that add one to the state, and print out the old value?
22:38 bjz joined
22:38 alpounet joined
22:38 <glguy> iqubic: You can try these things in GHCi
22:39 <glguy> There you'll be able to try running it with different parameters to see what happens
22:39 <iqubic> What do I need to import to have access to the liftIO function?
22:40 <glguy> If you're not sure what to import, Hoogle and Google are both effective for looking it up
22:40 dedicated joined
22:40 augur joined
22:40 strykerkkd joined
22:41 wroathe joined
22:42 <glguy> another good tool is: /msg lamdabot ?index some_function_here
22:42 <iqubic> @index liftIO
22:42 <lambdabot> Control.Monad.IO.Class
22:42 fizbin joined
22:43 <iqubic> GHCi really hates this: incr = do { old <- get; liftIO (print old); modify (+ 1) }
22:44 <glguy> iqubic: GHCi doesn't have emotions
22:44 <wizwizwizwiz> except the glory emotion
22:45 <iqubic> Yeah, but it won't accept that function
22:45 <iqubic> @index modify
22:45 <lambdabot> Control.Monad.Trans.State.Strict, Control.Monad.Trans.State.Lazy, Control.Monad.Trans.State, Control.Monad.Trans.RWS.Strict, Control.Monad.Trans.RWS.Lazy, Control.Monad.Trans.RWS
22:45 <wizwizwizwiz> and since pride is a side effect of glory, it also has pride
22:45 Hunter1 joined
22:45 <wizwizwizwiz> because haskell uses the glory monad
22:45 tv joined
22:45 <glguy> iqubic: It's not a function; and we can't read your screen. If you need help understanding an error you can ask about the error message
22:46 <glguy> wizwizwizwiz: That was all removed in GHC 8, unfortunately
22:46 robotroll joined
22:47 gehmehgeh joined
22:47 <wizwizwizwiz> but it's still part of the string libraries
22:48 <wizwizwizwiz> why would i use haskell over irdis? irdis looks like it has more awesome
22:49 <iqubic> What is irdis?
22:49 <davean> wizwizwizwiz: idris is more restrictive, it depends on the balance appropriate to what you're wroking on
22:49 <iqubic> Question: Haskell or Lisp?
22:49 <davean> iqubic: Lisp
22:49 newhoggy joined
22:50 erikd joined
22:50 <iqubic> Why lisp?
22:50 <iqubic> Why not haskell?
22:50 <glguy> No, the topic of the channel is Haskell
22:50 <wizwizwizwiz> irdis is strict by default
22:50 <davean> homoiconic, I really miss that
22:50 <iqubic> Lisp GUIs must be a pain in the ass to work with.
22:50 <davean> wizwizwizwiz: yah, which is really annoying
22:50 <wizwizwizwiz> orly?
22:50 <wizwizwizwiz> i thought the haskell community thought lazy by default was a bad idea
22:50 <davean> wizwizwizwiz: well, it ruins a lot of composability
22:50 <davean> wizwizwizwiz: uh no
22:51 <glguy> No, lazy by default is well regarded by the community
22:51 <wizwizwizwiz> interesting
22:52 <davean> its usually only people learning the language who don't realize how important non-strictness is because they don't understand whats actually happening in their code yet
22:52 <wizwizwizwiz> i am just generally concerned about things which can introduce massive sudden latency
22:52 <wizwizwizwiz> you know a > 1 msec pause etc
22:53 Aruro joined
22:53 cheshircat joined
22:53 drcode joined
22:55 electrostat joined
22:56 wroathe joined
22:57 torgdor joined
22:58 nicknovi1 joined
22:59 sleffy joined
23:00 stevenxl joined
23:04 jer1 joined
23:06 drdo joined
23:07 baetheus joined
23:07 Aruro joined
23:07 nuclx joined
23:07 LiaoTao joined
23:09 soniku joined
23:10 butterthebuddha joined
23:12 Uakh joined
23:12 ystael joined
23:12 Uakh joined
23:13 fxrs joined
23:14 meoblast001 joined
23:15 Uakh joined
23:16 monarch_ joined
23:17 nomotif joined
23:17 _sg joined
23:21 justan0theruser joined
23:21 wroathe joined
23:22 doomlord joined
23:24 zero_byte joined
23:25 geekosaur joined
23:26 t7 joined
23:27 wroathe joined
23:28 soniku joined
23:29 suzu joined
23:29 soniku joined
23:29 fizbin joined
23:29 geekosaur joined
23:31 filterfish joined
23:31 noam joined
23:33 tromp joined
23:33 torstein_ joined
23:35 Gacrux joined
23:35 Gacrux left
23:36 drcode joined
23:36 patbecich joined
23:37 ericsagnes joined
23:37 JeanCarloMachado joined
23:38 lpaste joined
23:41 biglambda joined
23:42 drcode joined
23:42 patbecich joined
23:42 tobiasBora joined
23:42 <tobiasBora> Hello,
23:42 <stevenxl> Hi folks. I'm blanking on the name of this concept, but when I have a function whose type signature is (a -> b -> a), and another function whose type signature is (b -> a -> b), these are the same.
23:43 <stevenxl> I'm trying to look it up but can't find the name for this.
23:43 <tobiasBora> I'd need an efficient database access
23:43 <suzu> stevenxl: isomorphism?
23:43 <tobiasBora> with pool access
23:43 <tobiasBora> Is there any example to do that ?
23:43 <MarcelineVQ> alpha equivalence
23:43 <geekosaur> ^
23:44 <stevenxl> Ah yes alpha equivalence.
23:44 <stevenxl> Thank you!!
23:44 <tobiasBora> I saw https://hackage.haskell.org/package/resource-pool- and HDBC, not sure how good it is
23:44 gugah joined
23:45 <Gurkenglas> alpha equivalence of signature1 and signature2 is equivalent to (((undefined :: signature1) :: signature2) :: signature1) compiling, right?
23:47 abrar joined
23:47 <Ieuan> Hi, I'm working through this https://wiki.haskell.org/Parsing_a_simple_imperative_language howto, but I'm getting an error when I try to run the code
23:47 nakal joined
23:47 takle joined
23:48 <Ieuan> The code I've copied is here: https://pastebin.com/UY3V32qw - it's telling me there's a "parse error on input 'return'" online 81
23:48 cpennington joined
23:48 <Ieuan> s/81/80/
23:48 <Ieuan> s/online/on line/
23:49 markus1209 joined
23:49 thetourist joined
23:49 ChaiTRex joined
23:49 markus1219 joined
23:50 <geekosaur> all of the do expressions lost leading spaces
23:50 <geekosaur> after the first line
23:51 trevorriles_ joined
23:51 <geekosaur> actually lost exactly one leading space. so for example the "cond <- bExpression" needs to line up directly under the "reserved "if"" on the previous line
23:51 Fubar^ joined
23:51 bjz joined
23:52 filterfish joined
23:52 <Ieuan> Ah, I'll try and fix that, cheers
23:52 <glguy> Ieuan: You can look at the wiki page you copied this from originally to see what it's supposed to look like
23:53 <Ieuan> Yeah, I was a little lazy copying the whitespace - didn't think haskell was too fussy; I'm gonna go double check everything else too now, thanks
23:53 rhodesd joined
23:54 aarvar joined
23:54 theDon_ joined
23:54 thetourist joined
23:54 robatosan joined
23:55 <Ieuan> That works fine now, thanks!
23:55 hodapp joined
23:56 Volt_ joined
23:56 infinity0_ joined
23:56 infinity0_ joined
23:56 tromp joined
23:57 wroathe joined
23:58 kay joined
23:58 louispan joined
23:59 kvda joined
23:59 m1ng0sfear joined
23:59 bjz joined