<     May 2017     >
Su Mo Tu We Th Fr Sa  
    1  2  3  4  5  6  
 7  8  9 10 11 12 13  
14 15 16 17 18 19 20  
21 22 23 24 25 26 27  
28 29 30 31
00:00 bydo joined
00:07 romank joined
00:12 romank joined
00:13 diegs_ joined
00:14 malaclyps joined
00:17 Big_G joined
00:17 romank joined
00:20 takle joined
00:25 cschneid_ joined
00:26 jship joined
00:28 juanpaucar joined
00:34 takle joined
00:39 romank joined
00:40 takle joined
00:50 mac10688 joined
00:51 romank joined
00:59 vmeson joined
01:01 vaibhavsagar joined
01:02 romank joined
01:02 dxld joined
01:05 im0nde_ joined
01:08 hphuoc25 joined
01:12 romank joined
01:13 ngastyle joined
01:17 <coredump> qu1j0t3: yes, Lambda Calculus
01:19 halogenandtoast joined
01:21 <qu1j0t3> eh I don't know about online talk, but the LC chapter in Kogge's "Architecture of Symbolic COmputers" is pretty thorough
01:27 romank joined
01:27 juanpaucar joined
01:32 malaclyps joined
01:33 mac10688 joined
01:51 malaclyps joined
02:00 romank joined
02:19 cschneid_ joined
02:22 dni- joined
02:27 juanpaucar joined
02:32 ngastyle joined
02:34 <saylu> Hey folks -- I'm trying to send an authorized POST request to a Google API using hoauth2. To do this, I'm meant to send a value of type `PostBody`, which is a synonym for `[(ByteString, ByteString)]`.
02:34 <saylu> Relevant docs are here
02:34 <saylu> https://www.stackage.org/haddock/lts-8.15/hoauth2-0.5.7/Network-OAuth-OAuth2-Internal.html#t:PostBody
02:35 <saylu> I'm assuming the tuples are meant to be key/value pairs.
02:36 <saylu> But I have a fairly nested JSON body, and there's no additional information here on what to do in that case. Been trying different things and I'm getting "bad request" errors (I can just use query params and get info back, so the auth is OK). There isn't any more detail on this in the hoauth2 package.
02:36 <saylu> Any ideas?
02:42 takle joined
02:43 exferenceBot joined
02:44 cschnei__ joined
02:47 hexagoxel joined
02:51 juanpaucar joined
02:56 sherub1 joined
02:59 ngastyle joined
03:02 taksuyu joined
03:04 malaclyps joined
03:13 ngastyle joined
03:16 cschneid_ joined
03:21 taksuyu joined
03:21 hphuoc25 joined
03:25 saussure joined
03:44 mac10688 joined
03:55 hphuoc25 joined
03:58 diegs_ joined
04:06 blissdev joined
04:10 romank joined
04:11 wei2912 joined
04:12 dni- joined
04:16 saussure joined
04:20 <coredump> qu1j0t3: thanks. I am trying to find it on an electronic format I can buy/loan
04:20 louispan joined
04:22 takle joined
04:25 saussure joined
04:43 saussure joined
04:44 govg joined
04:45 martingale joined
04:52 romank joined
04:55 louispan joined
05:01 juanpaucar joined
05:04 louispan joined
05:05 romank joined
05:06 seangrove joined
05:08 takle joined
05:09 saussure joined
05:10 nullcone joined
05:10 romank joined
05:11 meandi_2 joined
05:18 saussure joined
05:19 hphuoc25 joined
05:20 yellowj joined
05:29 hphuoc25 joined
05:32 texasmynsted joined
05:34 Rakkattakka joined
05:35 mstruebing joined
05:36 saussure joined
05:39 takle joined
05:45 saussure joined
05:46 ThomasLocke joined
05:50 takle joined
05:55 merijn joined
06:01 dni- joined
06:03 saussure joined
06:04 juanpaucar joined
06:06 systemfault joined
06:09 louispan joined
06:09 sherub1 joined
06:12 cur8or joined
06:15 takle joined
06:17 vaibhavsagar_ joined
06:20 haskelleksah joined
06:20 louispan joined
06:22 saussure joined
06:30 takle joined
06:34 govg joined
06:39 louispan joined
06:40 saussure joined
06:41 takle joined
06:51 takle joined
06:56 ThomasLocke joined
06:58 saussure joined
06:58 slomo joined
07:00 louispan joined
07:03 stef204 joined
07:03 louispan joined
07:04 juanpaucar joined
07:07 takle joined
07:08 louispan joined
07:12 thc202 joined
07:15 bvad joined
07:16 saussure joined
07:18 takle joined
07:21 louispan joined
07:22 louispan joined
07:29 cur8or joined
07:33 eminhi joined
07:34 saussure joined
07:34 takle joined
07:40 takle joined
07:41 hphuoc25 joined
07:50 dni- joined
07:50 moei joined
07:50 moei joined
07:52 saussure joined
07:53 galderz joined
07:56 takle joined
08:00 grdryn joined
08:01 cschneid_ joined
08:02 louispan joined
08:08 c4r50nz joined
08:09 juanpaucar joined
08:10 saussure joined
08:12 takle joined
08:15 romank joined
08:17 aphorisme joined
08:19 CacoS joined
08:19 ali_bush joined
08:19 ali_bush joined
08:19 <aphorisme> Hello! What is needed to run an executable compiled on machine A on machine B? Or: is there any option for ghc to compile it in such a way, that nothing is needed but the executable (considering the same OS, or almost: "linux/windows/mac")?
08:24 <MarcelineVQ> that's often called deployment, I think, there's some things for that none of which I've used
08:26 fbergmann joined
08:26 colt44 joined
08:29 irrequietus joined
08:29 <aphorisme> so that means: it depends?
08:32 hphuoc25 joined
08:32 hphuoc25_ joined
08:33 merijn joined
08:37 <halogenandtoast> aphorisme: I usually just use a Docker environment that matches my target
08:38 <halogenandtoast> There are some ways to cross compile with GHC but it's a difficult path
08:38 <halogenandtoast> and I wouldn't know the first thing about it
08:39 <halogenandtoast> The term you are looking for is cross compiling
08:39 <halogenandtoast> though
08:39 <merijn> If at all possible, I'd just grab a VM and compile in there, rather than cross-compiling :)
08:44 <aphorisme> and if compiled within the VM I could just ship the binary?
08:44 <halogenandtoast> aphorisme: that has been my experience
08:44 takle joined
08:45 <merijn> aphorisme: Yes
08:45 <aphorisme> thank you very much. : )
08:45 <halogenandtoast> I suppose if there are shared libraries
08:45 <halogenandtoast> you might have some troubles if the target doesn't have them
08:45 <merijn> aphorisme: If your VM is set to the same architectur (i.e. x86 or amd64) and using the same OS versions you should be able to just copy/paste the executable
08:46 <merijn> aphorisme: By default GHC statically links all haskell libraries (hence people complain about big binaries, but you don't have to deal with shipping libraries!)
08:46 <merijn> You might have to install/arrange C/other shared libraries to be installed, though
08:46 <aphorisme> Well, in fact the program is a simple one, no fancy external dependencies as far as I can tell. Considering docker: I would need some connection to the deployment server, or?
08:46 <merijn> aphorisme: What do you wanna compile for?
08:47 <halogenandtoast> aphorisme: for my case, I have a deploy script that builds in docker (stack has an option for this) and then a scp to the server
08:47 <merijn> oh, a personal VPS?
08:48 <merijn> Then I would definitely just grab like, VirtualBox, install a copy of whatever your VPS uses and just built in the VM
08:48 <aphorisme> I have Windows Server 2016 and some Linux SuSE I guess. But these are machines with restricted internet connection.
08:48 <merijn> docker seems rather overcomplicating things, unless you plan to be distributing the binary *a lot* (and even then...)
08:49 <aphorisme> it really is more like a small script, collecting some data.
08:49 <merijn> aphorisme: And you've got a working cabal/stack/whatever setup?
08:50 <aphorisme> well; not on the target machines. That's the problem. : /
08:50 <halogenandtoast> merijn: I've always found docker easier than virtualbox, granted I have control over my VPS's OS so I just make it the same as the default stack one
08:50 <halogenandtoast> then all I do is set docker: true in my stack.yaml
08:50 takle joined
08:50 <halogenandtoast> and I hate Docker...
08:51 <merijn> halogenandtoast: honestly, I'm still not sold on why docker exists in the first place, let alone why the hell you would overcomplicate a simple project with it...
08:51 <halogenandtoast> merijn: try coordinating between a bunch of other devs who don't know what they are doing
08:51 <halogenandtoast> having to distribute the VM is a pain
08:52 <halogenandtoast> granted Vagrant can solve that problem
08:52 <merijn> halogenandtoast: Sure, but we're talking single dev project right now, no? :)
08:52 <halogenandtoast> merijn: yes sure.
08:52 <merijn> halogenandtoast: to be fair "I just set "docker: true" in my stack.yaml" <- I don't use stack either, so maybe that's it :p
08:53 <halogenandtoast> merijn: yeah for simple stuff being able to just change that setting was amazing
08:53 <halogenandtoast> I wouldn't have even tried docker otherwise
08:53 <halogenandtoast> All Docker has ever done for me is use all my disk space.
08:54 xificurC joined
08:55 <merijn> brb
08:56 merijn joined
08:58 <merijn> Anyway, my personal solution here would be: 1) Get some kinda of virtualisation software (VirtualBox is a good free one), 2) Create a new vm with you target archeticture and install the target OS, 3) install cabal/stack/whatever you use as normal, 4) build a binary from your haskell, 5) copy it to the target machine
08:58 <aphorisme> I'll give it a try. Thanks. : )
09:00 takle joined
09:12 govg joined
09:12 juanpaucar joined
09:13 irrequietus joined
09:16 romank joined
09:16 takle joined
09:17 <c4r50nz> I'm trying to generate a shared library using Haskell and call its function in C. However even though I already called `hs_init`, when trying to call function it still complains "call hs_init() first". What am I missing here?
09:17 <c4r50nz> the C code is here: https://pastebin.com/6gj2QfEY compiled with `ghc test.c -ldl -no-hs-main`
09:18 <merijn> I think you need to call hs_add_root too
09:18 <merijn> https://gist.github.com/merijn/4a0fee2b3a5ef3476aa4
09:20 takle_ joined
09:22 Xion_ joined
09:26 <xificurC> there's so much to read and learn I decided it's time to dive into a problem and learn more as I go. I want to write a small lisp with the help of haskell. The first thing to play around would be a parser. What is the recommended parser library for parsing a programming language? A quick web search brought megaparsec at the top of the list with som
09:26 <xificurC> e comparisons, which will obviously be one-sided :)
09:27 netheranthem joined
09:28 <merijn> megaparsec is a reasonable enough starting point
09:28 <merijn> It fixes some historical warts of parsec
09:28 qu1j0t3 joined
09:28 <merijn> Attoparsec is aimed at speed, but does that by sacrificing the ability print reasonable parser errors. Trifecta is nice and has pretty errors, but is confusing to learn
09:30 <xificurC> merijn: you're saying I picked the "right" choice? What do you know
09:31 <c4r50nz> merijn: it seems the result is the same. It works when I call the function directly, but when creating a function via dlopen and dlsym it's not.
09:31 <merijn> c4r50nz: Can you show the haskell code that goes with it?
09:32 <c4r50nz> sure, a sec
09:37 <c4r50nz> I also updated the C code. Haskell: https://pastebin.com/8745GvbM C: https://pastebin.com/eJYK9p6d output is appended
09:38 <merijn> hmmm, why are you using -dynamic?
09:39 <merijn> oh, wait
09:39 <merijn> Reading it wrong :)
09:39 dni- joined
09:39 <merijn> c4r50nz: Try calling hs_init after dl opening the haskell library?
09:40 <c4r50nz> tried but still the same :(
09:40 <merijn> Or at the very least call "add-root" after opening the library
09:40 <merijn> hmmm
09:40 <merijn> what's line 18 doing there in the C file?
09:41 <c4r50nz> it's calling the haskell function directly
09:41 <c4r50nz> since it's compiled with hask.o
09:41 <merijn> c4r50nz: So you're *both* linking *and* DL opening the same library?
09:41 louispan joined
09:42 <c4r50nz> yes, this is for testing. eventually I want to just use dlopen
09:42 <merijn> What happens if you only do one or the other?
09:48 <c4r50nz> merijn: just tried. I get `__stginit_M` symbol from dlsym and call `hs_add_root` with it, but still the same
09:49 <c4r50nz> are you able to reproduce this in your environment?
09:50 <merijn> I haven't tried, but I'm assuming you're on linux, so I doubt me reproducing will help you much, as the OSX linker setup is completely different :)
09:50 <c4r50nz> OK :)
09:50 zero_byte joined
09:52 grdryn joined
09:58 romank joined
10:06 <c4r50nz> It turns out I also need to supply `-dynamic` flag when compiling C code. It's working now.
10:06 yellowj joined
10:10 takle joined
10:13 sherub1 joined
10:17 juanpaucar joined
10:26 saussure joined
10:27 grdryn joined
10:45 romank joined
10:47 hphuoc25 joined
11:15 halogenandtoast joined
11:16 juanpaucar joined
11:28 dni- joined
11:36 saussure joined
11:38 yellowj joined
11:41 saussure joined
11:46 saussure joined
11:50 takle joined
11:57 govg joined
12:00 Gurkenglas joined
12:00 takle joined
12:02 cschneid_ joined
12:04 saussure joined
12:05 fotonzade joined
12:15 saussure joined
12:16 juanpaucar joined
12:30 pilne joined
12:30 galderz joined
12:33 saussure joined
12:39 saussure joined
12:40 hphuoc25 joined
12:40 takle joined
12:41 yellowj joined
12:44 saussure joined
12:45 yellowj joined
12:47 sherub1 joined
12:49 saussure joined
12:53 im0nde joined
12:54 saussure joined
12:54 argent0 joined
13:02 juanpaucar joined
13:05 colt44 joined
13:05 saussure joined
13:07 WarmCookie joined
13:09 juanpaucar joined
13:10 diegs_ joined
13:14 eminhi joined
13:17 dni- joined
13:17 zero_byte joined
13:19 jathan_ joined
13:27 Big_G joined
13:30 nullcone joined
13:30 takle joined
13:35 juanpaucar joined
13:43 saussure joined
13:46 juanpaucar joined
13:50 haskell-noob joined
13:52 <haskell-noob> I'm currently reading "Haskell Programming" by Christopher Allen and Julie Moronuki to get a solid grasp on functional programming.
13:53 jathan joined
13:53 <haskell-noob> Any recommendations for a good Haskell IDE when I get to the point where I want to start playing with code?
13:53 <haskell-noob> I'm on a Windows 7 platform, but have easy access to CentOS 7 too.
13:54 <merijn> haskell-noob: Do you have a favourite editor already?
13:54 <merijn> If yes, I would just use that
13:55 <haskell-noob> For Java I love my IntelliJ, but wasn't sure about the Haskell plug-in for that environment since it uses Scala to implement the Haskell language.
13:55 <merijn> Most people (at least on IRC) seems to be: 33% vim, 33% emacs, 33% other (EclipseFP, Sublime, Atom, whatever)
13:56 <haskell-noob> Ha! Ha! Thanks, but I'll pass on the VIM and emacs. Longtime vi fan here for linux environments.
13:56 <merijn> Vim/emacs are probably the best supported in terms of fancy tooling, but tbh I mostly didn't use that at first anyway
13:56 <haskell-noob> But thanks for the stats. Good to know!
13:57 <haskell-noob> The EclipseFP and Sublime environments looked interesting to me, too (included in that 33% other you mentioned)
13:57 <merijn> And if you're not using vim/emacs I think the other editors are roughly equally supported/broken :p
13:58 <haskell-noob> I tried installing Leksah this morning. It looked like it had promise, but the latest good Windows build from Github is missing a libunistring-2.dll
13:58 <haskell-noob> Benefits of linux - no DLL hell
13:59 <merijn> I would classify Leksah and Yi more as "experiments in implementing an editor in Haskell" than a serious editor. I think they see only VERY marginal real use
13:59 <haskell-noob> Super feedback, merijn! Thank you for the insight!
14:00 <haskell-noob> I like Eclipse after IntelliJ, I might go the EclipseFP route.
14:02 <haskell-noob> If I have a complete breakdown, I can use vim and then spend an hour trying to figure out how to exit out of vim. ;)
14:03 <merijn> The benefit of learning vim is that you never have to ask "which editor/IDE should I use?", because the answer is always "vim!" ;)
14:05 <haskell-noob> Nicely played.
14:08 halogenandtoast joined
14:10 takle joined
14:15 wei2912 joined
14:34 mac10688 joined
14:42 saussure joined
14:54 carlomagno joined
14:58 carlomagno joined
15:01 cschneid_ joined
15:06 dni- joined
15:16 takle joined
15:19 Cale joined
15:28 LKoen joined
15:52 kadoban joined
15:52 CacoS joined
16:02 fbergmann joined
16:06 eminhi joined
16:19 pbrant joined
16:22 Sose joined
16:31 brezel joined
16:31 teqwve joined
16:32 navilan joined
16:33 louispan joined
16:38 mengu joined
16:41 zero_byte joined
16:46 bydo joined
16:46 hphuoc25 joined
16:54 saussure joined
16:55 dni- joined
16:56 Deide joined
17:14 grizwako joined
17:20 haskelleksah joined
17:28 pilne joined
17:30 saussure joined
17:32 juanpaucar joined
17:33 kritzcreek joined
17:51 efeuska joined
17:55 kupak joined
17:57 delexi joined
17:58 ianandrich joined
18:00 takle joined
18:02 n_blownapart joined
18:03 <n_blownapart> hi I have a 32bit linux machine . I don't know emacs / spacemacs *at all* and need a simple editor for haskell. suggestions please. I can use Atom and the haskell-ide fairly well but don't want that on this little machine.
18:07 juanpaucar joined
18:10 <MarcelineVQ> give ghcid a try and see if you like it
18:10 <MarcelineVQ> it's not an editr but it's a lightweight way to see if you're coding correctly, and then you can just use any old editor you like without worrying about ide's and plugins and such
18:11 conal joined
18:15 juanpaucar joined
18:16 fotonzade joined
18:21 juanpaucar joined
18:26 saussure joined
18:37 saussure joined
18:43 dni- joined
18:44 peterbecich joined
18:45 prophile joined
18:46 peterbecich joined
18:47 hphuoc25 joined
18:57 conal joined
19:01 aarvar joined
19:10 systemfault joined
19:11 Prutheus joined
19:12 takle joined
19:13 merijn joined
19:15 Gurkenglas joined
19:23 juanpaucar joined
19:25 patbecich joined
19:27 takle joined
19:31 conal joined
19:35 dni- joined
19:37 <saylu> Hey folks
19:37 <saylu> I've got a strange error.
19:37 <saylu> https://pasteboard.co/cdVJc6gWn.png
19:37 <saylu> I'm trying to encode an `AccessToken` from `hoauth2` and write it out to a file. However, I get the error that there is no instance for 'toJSON' for the type
19:37 <saylu> However, it definitely does have one:
19:37 <saylu> https://hackage.haskell.org/package/hoauth2-1.2.0/docs/Network-OAuth-OAuth2-Internal.html#t:AccessToken
19:37 eHammarstrom joined
19:38 <merijn> saylu: oh! $10 says I can guess the issue without looking at the code!
19:38 <saylu> What's more, in this same program I successfully use the 'fromJSON' instance
19:38 ngastyle joined
19:38 <merijn> saylu: Are you sure you're using version 1.2.0 of the hoauth2 package?
19:38 <saylu> I am
19:38 <saylu> indeed
19:38 <saylu> oh
19:38 <saylu> no
19:38 <saylu> i'm not totally sure
19:39 <merijn> saylu: I'd check that first, and then check if your version actually has that instance ;)
19:39 <merijn> saylu: Cabal or stack?
19:39 <saylu> Stack, with LTS 8.15
19:39 <saylu> which uses....
19:39 <saylu> 0.5.7?
19:39 <saylu> huh
19:39 <merijn> Ah, I don't really know stuck, so I can't say how to check
19:39 <saylu> https://www.stackage.org/lts-8.15/package/hoauth2-0.5.7
19:39 <merijn> But, eh...that sounds like it might be an issue ;)
19:39 <saylu> that's a bit annoying
19:39 <merijn> I think you can tell it to use a newer version, but I don't know how
19:40 <saylu> that would explain several other issues, too!
19:40 <saylu> i can have it use the latest nightly, which does have 1.2
19:40 takle joined
19:40 <merijn> saylu: Golden rule: If GHC says an instance doesn't exist and the docs say it does. Check your versions ;)
19:40 <eHammarstrom> So I've been reading about identities lately, can I say, get the identity of * using an identity function? And further, does this id function work on monoids, because they contain an identity from what I understand?
19:41 <merijn> eHammarstrom: can you clarify in what context you've been reading about identities?
19:41 <saylu> https://github.com/commercialhaskell/stack/blob/master/doc/faq.md#i-need-to-use-a-different-version-of-a-package-than-what-is-provided-by-the-lts-haskell-snapshot-im-using-what-should-i-do
19:41 <saylu> merijn: if you are curious about this
19:41 <saylu> thanks, I'll keep that in mind!
19:41 <merijn> saylu: I'm a grumpy curmudgeon, so I'm still using cabal, since it's always worked for me and I'm too lazy to learn new tools ;)
19:42 <eHammarstrom> merijn: 2 contexts, monoids for which an identity is the `base case` or `null case` of the monoid. And identity where 1 is the identity of multiplication. Does that make sense?
19:42 mstruebing joined
19:43 <merijn> eHammarstrom: In a mathematical sense the identity element is an element of a set, that, for a specific operation does "nothing" that is if we have a binary operation '*' and an identity element 'e', then: 'x * e = x = e * x', that is' combining the identity element using the operation it's the identity for "does nothing"
19:44 <merijn> eHammarstrom: Something doesn't have to actually be an identity in both cases, you can have scenarios where we speak of a "left identity", i.e. "e * x = x" or a right identity "x * e = x"
19:44 <merijn> eHammarstrom: Monoids require the identity element to be both left AND right identity for that monoid
19:44 <saylu> Oh god
19:44 <saylu> well
19:44 <saylu> that is fixed now, but lots of other stuff just broke
19:44 <saylu> what a mess :p
19:45 <merijn> saylu: Dependencies suck, I feel your pain ;)
19:45 <eHammarstrom> merijn: I see, that makes sense! So an identity for a monoid is basically a left and right compliant identity and 1 would be a left and right identity of multiplication
19:45 <merijn> saylu: Monoids are actually triples of 1) a set of elements, 2) a binary operation, and 3) an identity (left and right!) element for that operation
19:46 <merijn> eh
19:46 <merijn> that was for eHammarstrom :p
19:46 <merijn> eHammarstrom: Right
19:46 <merijn> eHammarstrom: The interesting thing is that the set of natural numbers has more than 1 monoid
19:46 <merijn> eHammarstrom: We have the triple (natural numbers, multiplication, 1) which is a monoid
19:46 <eHammarstrom> So monoids for now are an abstract thing that I might be able to reason about. But what are some concrete examples of monoids in Haskell, I might've been using them without knowing?
19:47 <merijn> But, we also have (natural numbers, addition, 0)
19:47 <merijn> eHammarstrom: Lists are monoids for example
19:47 <merijn> eHammarstrom: Can you guess the binary operation and identity element?
19:48 daniel___ joined
19:48 <saylu> new question merijn, if you know this --
19:48 <eHammarstrom> id [] and append ++?
19:48 <saylu> any way to represent this -- "urn:ietf:wg:oauth:2.0:oob" as a URI ByteString?
19:48 hphuoc25 joined
19:49 <merijn> eHammarstrom: Correct :)
19:49 <merijn> eHammarstrom: Actually, there's two list monoids (in fact, every monoid, by definition has at least one other monoid!)
19:50 <merijn> saylu: Not a clue, sorry :)
19:50 <eHammarstrom> merijn: I don't think I see how a monoid has another monoid
19:50 <merijn> eHammarstrom: Well, the binary operation has to be associative, right?
19:51 <eHammarstrom> yes
19:51 <merijn> eHammarstrom: That is, "a <> (b <> c) = (a <> b) <> c"
19:51 <eHammarstrom> I follow
19:51 <merijn> eHammarstrom: Well, suppose we do "flip (<>)" would that still be a monoid?
19:51 conal joined
19:52 <eHammarstrom> Does flip here mean we would get something like (b <> c) <> a? If so, I don't think so. Monoids are not commutative?
19:52 <merijn> :t flip
19:52 <lambdabot> (a -> b -> c) -> b -> a -> c
19:52 <merijn> flip is basically: \x y -> y <> x
19:53 <merijn> They're not commutative, no. But does flip invalidate the associativity?
19:53 <merijn> > [1,2,3] <> [4,5,6]
19:53 <lambdabot> [1,2,3,4,5,6]
19:53 <merijn> Actually, that's a bit example to change
19:53 <eHammarstrom> No because the flip is like a reverse so we would still churn it down to the same result?
19:54 <eHammarstrom> full reverse that is
19:54 <merijn> @check \(x :: [Int]) y z -> (x <> y) <> z == x <> (y <> z)
19:54 <lambdabot> <unknown>.hs:1:15:ScopedTypeVariables language extension is not enabled. Ple...
19:54 <merijn> hmmm
19:54 <eHammarstrom> :t <>
19:54 <lambdabot> error: parse error on input ‘<>’
19:54 <eHammarstrom> What operator is <>?
19:55 <eHammarstrom> Haven't used it yet :)
19:55 <merijn> <> is just (m)append, i.e the binary operator of a Monoid
19:55 <merijn> :t (<>)
19:55 <lambdabot> Monoid m => m -> m -> m
19:55 <eHammarstrom> Alright, then I'm still with you
19:55 <merijn> @check let testCase :: [Int] -> [Int] -> [Int] -> Bool; testCase x y z = x <> (y <> z) == (x <> y) <> z in test
19:55 <lambdabot> error:
19:55 <lambdabot> • Variable not in scope: test • Perhaps you meant one of these: ‘text’ (impo...
19:55 <merijn> @check let testCase :: [Int] -> [Int] -> [Int] -> Bool; testCase x y z = x <> (y <> z) == (x <> y) <> z in testCase
19:55 <lambdabot> +++ OK, passed 100 tests.
19:56 <eHammarstrom> Is that QuickCheck in action?
19:56 <merijn> That runs quickcheck to pass random input to a function and check if it's always True. So it's a kinda basic "is this law right" test
19:56 saussure joined
19:56 <merijn> @check let (<>) = flip mappend; testCase :: [Int] -> [Int] -> [Int] -> Bool; testCase x y z = x <> (y <> z) == (x <> y) <> z in testCase
19:56 <lambdabot> +++ OK, passed 100 tests.
19:57 <merijn> We replace <> with "flip mappend" and the test still pass :)
19:57 <merijn> In fact, in the module Data.Monoid we have "newtype Dual a = Dual a" which does exactly this. Replace a monoid with it's flipped version
19:57 <eHammarstrom> Which is an implication that foldr and foldl are both applicative?
19:57 <merijn> > Dual [1,2,3] <> Dual [4,5,6]
19:57 <lambdabot> Dual {getDual = [4,5,6,1,2,3]}
19:58 <merijn> > getDual $ Dual [1,2,3] <> Dual [4,5,6] -- with unwrapping
19:58 <lambdabot> [4,5,6,1,2,3]
19:58 <merijn> eHammarstrom: You're earlier remark of commutativity, if a monoid is commutative, then "x <> y" and "Dual x <> Dual y" should give the same result
19:59 <merijn> s/You're/Your
19:59 conal joined
20:00 dni-_ joined
20:00 <merijn> eHammarstrom: Tekmo wrote some interesting articles about functional "design patterns", including monoids: https://www.reddit.com/r/haskell/comments/5r271m/haskell_design_patterns/dd3x2gt/
20:00 <eHammarstrom> Thanks! I really appreciate reading material
20:00 <merijn> eHammarstrom: Final neat trick, before I head towards bed
20:01 <merijn> eHammarstrom: There's a very nifty monoid in base
20:01 <merijn> "instance Monoid r => Monoid (a -> r)", i.e. any function that takes an 'a' and returns a Monoid, is a monoid...
20:02 <merijn> :t mconcat
20:02 <lambdabot> Monoid a => [a] -> a
20:02 <eHammarstrom> Makes sense
20:02 <merijn> mconcat just mappend an entire list
20:03 <merijn> :t [(\x -> 1:x:2:[]), (\x -> x:x:[]), (\x -> [1])]
20:03 <lambdabot> Num a => [a -> [a]]
20:03 <merijn> :t mconcat [(\x -> 1:x:2:[]), (\x -> x:x:[]), (\x -> [1])]
20:03 <lambdabot> Num a => a -> [a]
20:03 <merijn> > mconcat [(\x -> 1:x:2:[]), (\x -> x:x:[]), (\x -> [1])] 42
20:03 <lambdabot> [1,42,2,42,42,1]
20:03 <merijn> It's very nice for grouping multiple functions together :)
20:04 <eHammarstrom> So you're applying 42 to all functions, which are monoids?
20:04 <eHammarstrom> Or is it because the functions returns a monoid that it is a monoid?
20:04 <eHammarstrom> I think that is what you wrote in other words
20:05 <merijn> eHammarstrom: Well, we have a bunch of function that take an 'a' and produce a Monoid (don't care which), so mappend basically says "well, we can mconcat those functions by giving them all the exact same argument and mconcat'ing the result"
20:05 <merijn> The neatest trick is: data Ordering = LT | EQ | GT
20:05 <eHammarstrom> Because we know they're monoids, neat!
20:05 <merijn> That's a datatype for comparisons, which is also a monoid
20:05 <merijn> > LT <> GT
20:05 <lambdabot> LT
20:05 <merijn> > LT <> EQ
20:05 <lambdabot> LT
20:05 <merijn> > EQ <> GT
20:05 <lambdabot> GT
20:06 <merijn> Basically, if returns the left side, unless the left side is EQ, then it returns the right.
20:06 <merijn> Which means you can combine ordering functions by simply "mconcat" a list of comparison functions
20:06 <merijn> @let data Test a b c = Test a b c
20:07 <lambdabot> Defined.
20:07 <merijn> @undefine
20:07 <lambdabot> Undefined.
20:07 <merijn> @let data Test a b c = Test a b c deriving (Show)
20:07 <lambdabot> Defined.
20:07 <merijn> hmm, I keep messing this up :p
20:07 <merijn> @undefine
20:07 <lambdabot> Undefined.
20:07 <eHammarstrom> Why does mappend of LT <> GT return LT?
20:07 <merijn> @let data Test a b c = Test { getA :: a, getB :: b, getC :: c } deriving (Show)
20:07 <lambdabot> Defined.
20:08 <merijn> eHammarstrom: Do you know lexicographical ordering?
20:08 <merijn> eHammarstrom: i.e. you compare first letters, then if those are equaul you compare 2nd, etc.?
20:08 <eHammarstrom> Yes, that's how names are ordered usually, correct?
20:08 <eHammarstrom> And stuff.
20:09 <merijn> Yeah
20:09 <merijn> Well, consider "x <> y" to be the 1st and 2nd position comparisons
20:09 <merijn> If the 1st position is LT, then the total is LT, even if the 2nd is GT
20:09 <merijn> :t comparing
20:09 <lambdabot> Ord a => (b -> a) -> b -> b -> Ordering
20:10 <eHammarstrom> Yes, that makes sense.
20:10 <eHammarstrom> clicked
20:10 <merijn> comparing takes two "unordered things" and a function that converts to an ordered thing, and makes a comparison
20:10 <merijn> :t sortBY
20:10 <lambdabot> error:
20:10 <lambdabot> • Variable not in scope: sortBY
20:10 <lambdabot> • Perhaps you meant one of these:
20:10 <merijn> :t sortBy
20:10 <lambdabot> (a -> a -> Ordering) -> [a] -> [a]
20:10 <merijn> > sortBy (comparing getA) [Test 1 True 'c', Test 5 False 'a', Test 3 True 'b']
20:10 <lambdabot> [Test {getA = 1, getB = True, getC = 'c'},Test {getA = 3, getB = True, getC ...
20:11 <merijn> > sortBy (comparing getB) [Test 1 True 'c', Test 5 False 'a', Test 3 True 'b']
20:11 <lambdabot> [Test {getA = 5, getB = False, getC = 'a'},Test {getA = 1, getB = True, getC...
20:11 <merijn> Magic trick:
20:11 <merijn> > sortBy (comparing getB <> comparing getA) [Test 1 True 'c', Test 5 False 'a', Test 3 True 'b']
20:11 <lambdabot> [Test {getA = 5, getB = False, getC = 'a'},Test {getA = 1, getB = True, getC...
20:11 <eHammarstrom> So if we have a list of comparisons to be made, can we mconcat these and throw the resulting comparison into a comparing?
20:11 <merijn> Multi-column sorting in like a handful of words :)
20:12 <merijn> That first compares the middle argument and uses the 'a' as a tie breaker :)
20:12 <merijn> Of course you could have an arbitrarily complex list of comparing variations that you mconcat together!
20:13 <eHammarstrom> wow
20:14 <eHammarstrom> other languages must surely utilize monoids?
20:14 <eHammarstrom> this is the greatest thing ever
20:16 <merijn> eHammarstrom: The thing is, without typeclasses/type inference it becomes kinda inconvenient to use
20:17 <merijn> So there's people using it in other languages (hell, I do), but it's never quite as convenient and simple as in Haskell :)
20:17 <Xion_> eHammarstrom: Not as an explicit concept, but this usage of monoidal structure is common for sorting, e.g. https://doc.rust-lang.org/std/cmp/enum.Ordering.html#method.then
20:17 <merijn> Anyway, now it's bedtime for me :)
20:17 <Akii> gn merijn
20:17 HallaSurvivor joined
20:17 <merijn> @quote beaky monoids
20:17 <lambdabot> beaky says: i love monoids / they are so easy
20:17 <merijn> :)
20:18 <eHammarstrom> Thanks a lot merijn!
20:18 <Akii> monoids are awesome
20:18 <Akii> @karma+ merijn
20:18 <lambdabot> merijn's karma raised to 56.
20:19 ocramius joined
20:19 <Akii> welcome!
20:19 <Akii> :D
20:19 <ocramius> hello! \o/
20:19 romank joined
20:19 <ocramius> I'm reading about kinds in "learn you a haskell": I was wondering if there are any other kinds other than `*`?
20:20 <Akii> :k Mabye
20:20 <lambdabot> error:
20:20 <lambdabot> Not in scope: type constructor or class ‘Mabye’
20:20 <lambdabot> Perhaps you meant ‘Maybe’ (imported from Data.Maybe)
20:20 <Akii> :k Maybe
20:20 <Akii> >_>
20:20 <lambdabot> * -> *
20:20 <ocramius> yeah, but I mean if there's a concrete kind that isn't `*`
20:20 <Xion_> :k ReaderT
20:20 <lambdabot> * -> (k -> *) -> k -> *
20:20 <Akii> and then there is the DataKinds extension which brings Types to kinds
20:22 Prutheus joined
20:22 <Akii> currently trying to read this blog post http://www.parsonsmatt.org/2017/04/26/basic_type_level_programming_in_haskell.html
20:23 romank joined
20:24 <ocramius> Akii: hmm, so `k` is a variable there?
20:24 <ocramius> uh, sorry, that was for Xion_
20:25 <Akii> seeing this for the first time :o
20:25 <ocramius> yup, sorry for pinging you
20:26 <Akii> np ^^
20:26 <ocramius> I was really interested in seeing where this rabbit hole leads
20:26 <thang1> Yeah... Don't worry too much about it, Akii :p type level programming in Haskell is really messy
20:26 nullcone joined
20:26 <ocramius> Yes, but that's where the kinky stuff is... As someone that always wrote code generators for PHP, I feel the greed
20:26 <Akii> thang1: I'm not ready for my next interview if I can't program fizz buzz on the type level
20:27 saussure joined
20:27 <thang1> pffh, nobody really uses type level programming for real programming yet
20:27 <ocramius> *yet*
20:27 <Akii> I've seen people write incredibly low performing web servers
20:27 <* ocramius> adds greed
20:27 <Akii> on the type level
20:27 <thang1> Even Idris, etc., it's all really unexplored territory at this point in time and people still don't really know what we're going to do with it
20:28 <Akii> sounds like fun!
20:28 <thang1> See, dependent types (aka type level programming) is used to verify correctness by reducing the possible correct values (at the type level) to 1
20:29 <thang1> It loads a ton of complexity onto the programmer and necessitates a lot of hand holding with the compiler and type checker. It also tends to (for now) reduce expressiveness of code, tank code reuse, tank programmer productivity, and do a lot of other things.
20:30 Rakkattakka joined
20:30 <thang1> Where I think it's going is I think it's going to end up in a spectrum where the tools are there when you want/need them and they help the common programmer out, but I don't really forsee dependent types being used much by "regular programmers" explicitly. I see them being used by library writers and people who demand extremely high levels of correctness
20:31 conal joined
20:31 <thang1> Sort of like the situation with type annotations in Haskell now. Everything is strongly typed in Haskell, but you can use the language without ever typing of your types out (for the most part). You get all the safety of types but with very few verbosity and hand-holding drawbacks
20:32 <Akii> I do agree, I think. Just an explorer here :D
20:32 <thang1> Nothing wrong with that :p I like exploring too
20:33 <thang1> My particular interest lies with functional logical programming in addition to dependent types
20:33 <ocramius> thang1: same here - I do like the exploration
20:33 <ocramius> I'm not even able to yet open a file and write to it with haskell - I'm doing GHCI during my train trips
20:33 <Akii> the fact that my mind immediately produced an inapropriate joke is worrying me
20:33 <ocramius> but it still fascinates me
20:34 <thang1> Well the thing with Haskell is that certain things that are trivial in other languages are non trivial in Haskell
20:34 <thang1> any interaction with the outside world is generally "non trivial" in Haskell (or, well, it'll become trivial once you learn Haskell to even an intermediate level, but it's not "week two of programming class" trivial like it is in imperative languages)
20:35 <thang1> But... something like this is trivial in Haskell:
20:35 <thang1> > sum . takeWhile (<100) $ filter even [1..]
20:35 <lambdabot> 2450
20:37 <ocramius> yup
20:37 <ocramius> the tiling problem was interesting/quick to solve
20:37 <thang1> tiling problem?
20:38 <ocramius> Eh, can't remember where it was, but basically "find any number of L-shaped figures (of width 1) that fill a rectangle divided into squares of the same widht"
20:38 <ocramius> and then there was the additional complexity of excluding a few black spots
20:38 <ocramius> it's NP complete AFAIK, but the haskell solution sold me on the language
20:39 <thang1> ooooh the solution with the tardis monad right?
20:40 takle joined
20:40 <ocramius> thang1: no monad - I just did some list comprehension stuff
20:41 <ocramius> it was like... Haskell day 1 :D
20:41 <ocramius> for me a Monad is still a word with too many talks attached to it
20:42 <thang1> http://rubyquiz.com/quiz33.html is this the problem?
20:43 Prutheus joined
20:45 <ocramius> something like this, yarp
20:45 <ocramius> still, took me a long time to actually find the time to do this studying thing :P
20:46 <ocramius> ok, that said, sorry for all the fuss. Will try to stick around here: would love to learn some HS :-)
20:47 <Akii> @karma+ ocramius
20:47 <lambdabot> ocramius's karma raised to 1.
20:47 <Akii> :D
20:47 <ocramius> Dat karma is mutable >.<
20:47 <Akii> and regularly deleted afaik
20:47 <ocramius> good
20:49 hphuoc25 joined
20:53 <MarcelineVQ> @karma+ ocramius
20:53 <lambdabot> ocramius's karma raised to 2.
20:56 takle joined
20:57 malaclyps joined
21:00 takle joined
21:01 <eHammarstrom> :t foldr
21:01 <lambdabot> Foldable t => (a -> b -> b) -> b -> t a -> b
21:02 <Akii> cool function
21:03 <thang1> foldr is great
21:03 <eHammarstrom> So, I read about Fold on haskell's wiki and they make a comparison with reduce. If I would want to write a sum with reduce in Clojure I would say (reduce + xs). How do I do this with a fold in Haskell?
21:03 <eHammarstrom> Akii: made me laugh
21:03 <eHammarstrom> out loud that is, like a nutter
21:03 <thang1> > foldr (+) [1..50]
21:03 <lambdabot> error:
21:03 <lambdabot> • No instance for (Typeable t0)
21:03 <lambdabot> arising from a use of ‘show_M555693984035080430418279’
21:03 <thang1> whoops
21:03 <thang1> > foldr (+) 0 [1..50]
21:04 <lambdabot> 1275
21:04 <eHammarstrom> I see, I was missing the initial value.
21:04 <thang1> foldr (operation) (base case) (data structure)
21:04 <thang1> there's a foldr1 which has no base case but blows up on an empty list
21:04 <thang1> > foldr (+) 0 []
21:04 <lambdabot> 0
21:04 <Akii> > foldr1 (+) [1..50]
21:04 <lambdabot> 1275
21:04 <thang1> >foldr1 (+) 0 []
21:04 <Akii> faster
21:04 <thang1> > foldr1 (+) 0 []
21:04 <lambdabot> error:
21:04 <lambdabot> • Could not deduce (Num (t1 ([t0] -> t3)))
21:04 <lambdabot> from the context: (Num ([t2] -> t3),
21:05 <Akii> wat
21:05 <Akii> :t foldr1
21:05 <lambdabot> Foldable t => (a -> a -> a) -> t a -> a
21:05 <thang1> Look at the types :)
21:05 <thang1> :t foldr
21:05 <lambdabot> Foldable t => (a -> b -> b) -> b -> t a -> b
21:05 <thang1> foldr1 has a a a ta a. foldr has a b b b ta b
21:05 <thang1> That is, foldr requires a base case because it's a total function (it works on an empty data structure or a non empty one)
21:06 <thang1> foldr1 is more optimized and requires no base case, but it blows up (throws an error) on an empty data structure
21:06 <Akii> `foldr1 (+) 0 []`
21:06 <Akii> you still applied one argument too many
21:06 <Akii> > foldr (+) []
21:06 <lambdabot> error:
21:06 <lambdabot> • No instance for (Typeable t0)
21:06 <lambdabot> arising from a use of ‘show_M562790231880742199018450’
21:06 <Akii> boom!
21:06 <Akii> no? oh well
21:07 <eHammarstrom> Reading type definitions is still strange to me, how do I figure the 2nd b in foldr is a base case and what what does the t a -> b mean? I get that we get the result of type b in the end but what's up with t a?
21:07 <eHammarstrom> :t foldr
21:07 <lambdabot> Foldable t => (a -> b -> b) -> b -> t a -> b
21:07 <Akii> clearly a type issue, screams for NonEmpty
21:07 <eHammarstrom> third B that is
21:07 <thang1> (a -> b -> b) -- This is "a function that takes an a and a b and returns a b"
21:07 <Xion_> There should be a fold version somewhere that doesn't need the initial value if it folds over monoids
21:07 <eHammarstrom> That part I get
21:07 <thang1> example: (+)
21:07 <Xion_> :t mconcat
21:07 <lambdabot> Monoid a => [a] -> a
21:07 <Xion_> This one I think.
21:07 <Akii> a more simple version of this is `foldr :: (a -> b -> b) -> b -> [a] -> b`
21:08 <thang1> b -- The base case. You know this is the base case because this is what's outputted if t a is empty
21:08 <thang1> t a is just a generalized version of [a]
21:08 <eHammarstrom> (a -> b -> b) and final b are the graspable parts. Does t a mean that we have to apply it to something 'foldable' called a?
21:08 <thang1> So if you have, for example, a binary tree that "implements Foldable", you can just type foldr (+) 0 (my binary tree)
21:09 <Akii> :i Foldable
21:09 <Akii> hmpf, ghci is your friend then xD
21:09 <thang1> But if the t a was [a] then it would fail on the binary tree because a binary tree is not a list. You would have to type something like toList (my binary tree)
21:09 <eHammarstrom> How do I read out 't a'? a of type foldable?
21:10 <eHammarstrom> And further, does :i mention all the methods I have to implement? And also, do you call them methods or simply functions?
21:10 <thang1> I read it as "a data structure that implements Foldable" personally, but a of type foldable is also valid. "a foldable 'a'" would be a bit more correct
21:11 <eHammarstrom> Makes sense
21:11 <thang1> :i Foldable will show you the class Foldable and all the "methods" in the class (I think this is the correct terminology... methods makes sense to me, anyway :p )
21:12 <thang1> so Foldable has fold, foldMap, foldr, foldl, ... and so on
21:12 <thang1> In order to make your data type have Foldable, the /minimum/ amount of methods required to be implemented is defined by {-# MINIMUMAL #-} and is foldMap and foldr
21:12 <eHammarstrom> Oh, cool!
21:13 <thang1> foldr1, foldr', foldl, foldl', foldl1, etc., can all be derived from foldr
21:13 <thang1> foldMap is an extremely general and beautiful case of a lot of things. Length can be written in terms of a foldMap, for example
21:14 <eHammarstrom> Does the foldMap | foldr part mean I can implement one of them?
21:14 takle joined
21:14 <eHammarstrom> and foldMap does sound more general given that it takes a monoid
21:15 <eHammarstrom> and merijn just blew my mind on monoids
21:15 <thang1> I believe it means you have to implement both... Lemme check
21:16 <thang1> ah nope, it means or
21:16 <eHammarstrom> instinctively read it as 'or' given |
21:17 <thang1> You can implement either foldr or foldMap and get the entire foldable
21:17 <eHammarstrom> foldMap _seems_ like it would be a 'stronger' foldable
21:17 <thang1> Wanna know the nuts part?
21:17 <eHammarstrom> shoot
21:17 <thang1> Using some fancy extensions, you can generalize derivation to automatically derive foldable for your data types
21:18 juanpaucar joined
21:18 <thang1> So I can make a binary tree and tell the compiler to derive foldable and then fold over the binary tree without having to write any of that myself
21:18 <eHammarstrom> How would it know how to fold my data types? I haven't even started reading about data types in haskell yet. I get sidetracked all the time, everything is a shade of cool
21:19 stevenxl joined
21:19 <thang1> https://ocharles.org.uk/blog/guest-posts/2014-12-15-deriving.html behold the magic
21:20 <thang1> Skip to the foldable part and lemme know hwere you get lost
21:20 takle joined
21:23 <eHammarstrom> What's a functor and is Nil an identity value?
21:23 <eHammarstrom> Oh nbm
21:23 <eHammarstrom> nvm
21:23 <eHammarstrom> on the Nil part
21:23 saussure joined
21:24 juanpaucar joined
21:26 <eHammarstrom> my haskell fu is not on par with this yet, bookmarked it
21:26 <thang1> So the list is being written with Nil and Cons. In normal haskell syntax [] is an empty list and : is cons
21:26 <eHammarstrom> Yes, familiar with both
21:26 <thang1> a : b : c : d : [] is the same as a Cons b Cons c Cons d Cons Nil
21:26 <thang1> the foldable instance is telling the compiler how to fold a list
21:27 <thang1> so foldr _ z Nil = z. Or, alternatively, foldr on [a] is a
21:28 <thang1> foldr on any list with more than 1 element (next line of the definition): You apply f to the head of the list and then recursively call foldr on the rest of the list
21:29 <eHammarstrom> How do I read out this part `f x (foldr f z xs)` can we do this because (foldr f z xs) is of type a in z a.k.a [a]?
21:29 <thang1> so foldr (+) [1..3] would be 1 + (foldr (+) [2..3])
21:30 <thang1> and then you go down the next level and get 1 + 2 + (foldr (+) [3]). Then you get 1 + 2 + 3
21:30 <thang1> z is the base case here
21:30 <thang1> :t foldr
21:30 <lambdabot> Foldable t => (a -> b -> b) -> b -> t a -> b
21:31 <eHammarstrom> Yeah, I just don't see how the example of the list makes it mechanical in a way that we can automate
21:31 <thang1> > foldr (+) 0 [1..3] -- (+) == f, 0 == z, [1..3] == (Cons 1 [2..3])
21:31 <lambdabot> 6
21:32 <thang1> If you write out a foldable instance for data types enough times, you realize you're doing literally the same thing over and over
21:32 <thang1> Given a recursive data type with a Terminal (in this case, Nil) and a recursive case of the data Type (Cons)
21:33 <thang1> Well, foldr on an empty List is always going to just be the base case. An empty list is one that just has that terminal
21:33 <eHammarstrom> So the mechanical part would be the same as my textual replacement of `List` to `Type` and `z` to "type base"?
21:33 <thang1> In a way
21:34 <eHammarstrom> What do we call the type of z?
21:34 <thang1> A common definition for data BinaryTree a = Leaf | (Left a) a (Right a) . It looks something vaguely like this
21:35 <eHammarstrom> Does haskell inferr that z is of type List because of `instance Foldable List`?
21:35 <eHammarstrom> Nevermind
21:36 takle joined
21:37 <thang1> data BinaryTree a = Leaf | Node (BinaryTree a) a (BinaryTree a) -- there we go, I knew I was forgetting a small detail
21:37 <thang1> :t foldr
21:37 <lambdabot> Foldable t => (a -> b -> b) -> b -> t a -> b
21:37 <thang1> It doesn't really need to care what type z is because as long as foldr _ z _ = z then it's fine
21:38 <eHammarstrom> Yeah, figured
21:38 <thang1> But check out the definition for binary tree
21:38 <thang1> You have a Terminal, and then a recursive constructor (Node)
21:39 <thang1> So foldr _ z Leaf = z
21:39 <eHammarstrom> Nil in the List example and Leaf are called terminals? `end of data type`?
21:39 <thang1> they're called terminals in context free grammars. Sorry, forgot that wasn't introduced anywhere. (context free grammars aren't relevant here)
21:40 <thang1> Nil and Leaf are "terminals" in the sense that there's no 'a' in them
21:40 <thang1> There's nothing to expand, they're just that
21:41 <thang1> List a could have some value inside the list, but Nil has no value inside of it, it's just itself. More haskell-like terminology for that would be "nullary constructor"
21:41 <eHammarstrom> Alright, thanks a lot for going above and beyond with folding ++karma. I really have to hit the bed now
21:42 <thang1> But the second foldr would be: foldr f z (Leaf left x right)
21:42 <eHammarstrom> Aye
21:42 <thang1> Can you sorta see how the compiler can probably figure out how to do that automatically?
21:43 <eHammarstrom> Yes
21:44 <thang1> neat, so hopefully driving (Foldable) isn't black magic to you anymore :)
21:44 <eHammarstrom> It is not!
21:44 <eHammarstrom> Cheers
21:44 <thang1> np, see ya, sleep well
21:44 <eHammarstrom> gn
21:50 carlomagno joined
21:53 hiratara joined
21:54 diegs_ joined
22:01 juanpaucar joined
22:04 conal joined
22:05 zacts joined
22:06 carlomagno1 joined
22:07 juanpaucar joined
22:10 martingale joined
22:12 juanpaucar joined
22:12 conal joined
22:13 haskelleksah joined
22:17 Gurkenglas joined
22:18 mheinzel joined
22:31 hiratara joined
22:42 ngastyle joined
22:42 mac10688 joined
22:46 carlomagno joined
22:49 saussure joined
23:00 im0nde joined
23:00 malaclyps joined
23:07 oscarftoro joined
23:08 mheinzel joined
23:21 louispan joined
23:48 Pupnik joined
23:49 juanpaucar joined
23:53 juanpaucar joined