<    April 2017    >
Su Mo Tu We Th Fr Sa  
                   1  
 2  3  4  5  6  7  8  
 9 10 11 12 13 14 15  
16 17 18 19 20 21 22  
23 24 25 26 27 28 29  
30
00:00 KiChjang joined
00:00 <greymalkin> Haha, I've been using `sequence` for months now and only today did the penny drop that I could use it with maybe values too.
00:00 <KiChjang> okay, i'm going to ask the most FAQ ever, why learn haskell?
00:01 <c_wraith> KiChjang, because it's different. :)
00:01 <glguy> Learning Haskell is about the only way to successfully write programs in Haskell
00:01 <c_wraith> KiChjang, there are lots of more specific benefits, but the most important one is that it's really different.
00:01 <KiChjang> hmph, i think brainfuck is very different but i don't see myself learning it
00:02 <c_wraith> KiChjang, do you ever feel like every language you know is a skin over the same couple ideas?
00:02 <KiChjang> yeah, sort of, especially when it comes with OOP languages
00:02 <c_wraith> KiChjang, even brainfuck is a (minimal) skin over procedural ideas.
00:03 <KiChjang> you mean haskell isn't a turing-complete language?
00:03 <* geekosaur> cannot see where you got that
00:03 <c_wraith> it is, but its core ideas come from lambda calculus rather than Turing machines.
00:04 <c_wraith> and sure, we all know they are equivalent - but it doesn't mean that using them is the same.
00:04 <pacak> KiChjang: Haskell is obviously superior to other languages.
00:04 <KiChjang> i had my go with OCaml before but it wasn't very pleasant
00:04 <KiChjang> mostly because the person i worked with had very strict coding standards and styles
00:05 <c_wraith> as to whether haskell is better than any other language.. that's just opinion. what isn't opinion is that haskell doesn't let you work in half-measures. you need to commit to a different approach.
00:05 abcdefg joined
00:05 <* KiChjang> wonders if he just walked into a cult
00:05 <c_wraith> I'd say Prolog is a language with that same quality in a different direction.
00:05 <MarcelineVQ> pacak: whether that's true or not it's a hard line to make people believe stated that way
00:06 <c_wraith> you can't treat prolog like it's not a logic language.
00:06 <KiChjang> prolog is something i can relate with
00:06 <KiChjang> tried that before, the problems that it's trying to solve is definitely different than the traditional ones
00:06 <c_wraith> I don't know if that's a pun, but if it is, I appreciate it. :)
00:07 <pacak> MarcelineVQ: I don't want to make other people to belive, only those who can understand that for themselves. It helps to avoid shitstorms like one about Foldable instance for pair recently in cafe
00:07 <pacak> > length (1,2)
00:07 <lambdabot> 1
00:08 <KiChjang> i've often heard haskell is like THE go-to language when it comes to FP
00:08 <c_wraith> KiChjang, for what it's worth, I'd say haskell is actually a usable and practical language, at least as good as most languages for most jobs. but that's opinion. :)
00:08 Criggie1 joined
00:08 <c_wraith> yeah, people point at haskell because you don't get back doors.
00:09 <c_wraith> you have to learn the new stuff.
00:09 bergey joined
00:09 nick123 joined
00:09 <pacak> c_wraith: unsafeCoerce, unsafePerformIO, goto monad....
00:09 <KiChjang> oh no
00:09 <KiChjang> the M word
00:09 <KiChjang> what is a monad?
00:09 <dyreshark> it's simply a monoid in the category of endofunctors /s
00:09 <c_wraith> pacak, and as much as those exist, they still don't let you pretend you're not using haskell.
00:10 <Tuplanolla> Does lambdabot have the burrito link?
00:10 <glguy> It's an abstraction that won't make sense yet if you haven't started learning Haskell, generally
00:10 <pacak> KiChjang: Something to describe computations and how you can compose them.
00:10 <c_wraith> KiChjang, Monad is a distraction. getting into the details too early will just bog you down.
00:10 <glguy> Tuplanolla: hopefuly not
00:10 <EvanR> Monad is a type class. What's a type class? Learn haskell
00:10 <MarcelineVQ> @where burrito -- Tuplanolla: which one? :O
00:11 <lambdabot> http://byorgey.wordpress.com/2009/01/12/abstraction-intuition-and-the-monad-tutorial-fallacy/
00:11 biglambda joined
00:11 eacameron joined
00:11 <Tuplanolla> The Fud one, MarcelineVQ.
00:11 <c_wraith> KiChjang, worrying about monad before picking up the more basic bits is like worrying about multiple inheritance before you even know what a class is.
00:12 <c_wraith> Oh hey. "multiple inheritance" is also an m-word! :)
00:12 <Cale> Ironically, one of the things you'll want to know about before trying to understand Monad is also named "class"
00:12 <EvanR> i though about "whats a class, really" earlier but didnt want to bring it up
00:12 Welkin joined
00:12 <EvanR> like, in C++
00:13 <EvanR> that cant be a good answer to the question
00:13 <Cale> (but it's not the same as an OO class, it's type classes)
00:13 <Welkin> or javascript classes
00:13 <Welkin> which are just dictionaries
00:13 hive-mind joined
00:14 <c_wraith> KiChjang, which is not to say that monad is hard, useless, or really anything else.. there is just a knowledge base necessary before it makes sense.
00:14 {emptyset} joined
00:17 <c_wraith> KiChjang, and for what it's worth, all the other descriptions were correct - it's a pattern for composing certain values that has really nice properties in practice.
00:17 <adamCS> KiChang: Not sure if this is only my experience but Haskell seems to reward generalization more than some other languages. Code gets easier to write as you try to generalize it, often clearer, and often without any penalty in performance. But that might be true of any language that so embraces polymorphism and something like Haskell's typeclasses.
00:18 <EvanR> typeclasses are ok but not really the core workhorse of reusability i think
00:18 <KiChjang> great, i've had a couple of instances in OCaml where code gets decoupled and generalized, but the end result is confusion
00:18 <EvanR> they just let you use the same name for different things
00:19 <EvanR> (and do wild-ass type level programming, in an advanced course)
00:19 <KiChjang> because there are many different functions that have the same type signature but do very different things and i end up not knowing which one to use
00:19 <Welkin> say goodbye to your SingeltonFactoryManagerFactory :D
00:20 <Welkin> functions all the things
00:20 <bergey> Type classes also let us write code that is parametric over a subset of Haskell types. That's great for reuse.
00:20 <t7> go's typesystem is better
00:20 <c_wraith> KiChjang, one nice thing about haskell is that as you learn the type system, you learn how types can really restrict what a function can do if used properly. it's nice, because it becomes a form of machine-checked documentation.
00:21 <EvanR> its not really parametric in the sense of parametric polymorphism
00:21 <EvanR> its equivalent to passing in a record of functions
00:21 <Welkin> t7: trying to start a flamewar? Won't work here
00:21 <t7> just a funny joke
00:22 <KiChjang> so this is like going back to the drawing board again
00:22 <KiChjang> starting from what types are supposed to mean mathematically
00:22 <Welkin> t7: a funny joke would have been "javascript's type system is better"
00:22 <c_wraith> KiChjang, it is indeed.
00:22 <EvanR> yeah, what do types mean
00:22 <Welkin> which is also funny because, other than the type system, javascript is a really nice language compared to almost everything else
00:23 <adamCS> KiChjang; (sorry I mistyped your name!). I don't know OCaml so I can't speak to the differences. And I agree with EvanR that typeclasses, are just a record of functions with some syntactic sugar. But either don't always see my way to that equivalence or the syntactic sugar is strong. Either way, Haskell imposes some discipline and grants some freedoms--like any language--but the combination works nicely for some tasks/peopl
00:23 <adamCS> e.
00:23 Gurkenglas_ joined
00:23 <adamCS> Welkin: :)
00:23 <Welkin> functions in functions that produce functions that ...
00:23 <t7> Welkin: wut
00:23 <Welkin> I function all the things in js
00:24 <EvanR> if only javascript didnt need gynastics to do concurrency, nevermind
00:24 <KiChjang> IIFE in JS could be quite trippy
00:24 <Welkin> you don't do concurrency in the browser
00:24 <EvanR> yes you do
00:24 <KiChjang> you do with web workers
00:24 <t7> YOU dont
00:24 <glguy> The merits and flaws of Go and Javascript and the other non-Haskell languages are out of scope on #haskell
00:25 orbifx joined
00:26 <Gurkenglas_> (a -> Dynamic) (Dynamic -> b)
00:27 <EvanR> by the power of category theory, we conclude that is impossible
00:27 <EvanR> since its (a -> b)
00:27 <Gurkenglas_> Whoops. Is there a version of Dynamic such that the question "How do I check whether two given functions of types (a -> Dynamic) and (Dynamic -> b) compose?" makes sense?
00:27 <abcdefg> /part
00:27 abcdefg left
00:28 Krymise joined
00:28 <Welkin> not greyskull?
00:28 <glguy> Gurkenglas_: The type 'Dynamic -> b' claims to be able to handle all Dynamic values. You'd need to encode failure somehow. 'Dynamic -> Maybe b' or something
00:28 <geekosaur> Gurkenglas_, that works to some extent with the current version, assuming you know what a and b are in that situation
00:28 bhiliyam joined
00:29 robertkennedy joined
00:29 vaibhavsagar joined
00:29 <geekosaur> with current Dynamic that means concrete types only. 8.2 will have type-indexed Typeable, which Dynamic is built on, but I don't know offhand how that will affect any such test
00:30 crobbins joined
00:30 eacameron joined
00:31 <geekosaur> if you don't have any idea what a and/or b are, the question is ill-formed regardless of type system
00:31 <Gurkenglas_> To rephrase: I want D such that each value of (a -> D) or (D -> a) produces/consumes values of only one actual type each
00:32 <glguy> Gurkenglas_: Then you don't want Dynamic, you need something that doesn't hide the types
00:33 <glguy> data T a = forall b. C (a -> b) -- stuff like this so that you know there's exactly one type that it returns
00:33 Sampuka_ joined
00:34 splanch joined
00:34 stef204 joined
00:34 yrdz joined
00:35 cmsmcq joined
00:35 <glguy> The important part is that the type of the result of the function is quantified outside of the function, so we know that it doesn't depend on the argument to the function
00:36 eacameron joined
00:39 ebzzry joined
00:40 KiChjang left
00:41 Gurkengl1s_ joined
00:41 indi_ joined
00:42 <fragamus> putStr $ join $ map ( (++"o\n") . (\n->replicate n ' ') . (20+) . round . (*20) . sin . (*0.25)) [0..]
00:42 <fragamus> it might be my imagination but I think this gets slower as time goes on
00:43 <EvanR> replicate takes longer the bigger n is, then youre appending to the end of a [Char]
00:44 <EvanR> but sin is bounded...
00:44 <fragamus> the replicate is from 0 to 40
00:44 andyhuzhill joined
00:44 <fragamus> yeah
00:45 <fragamus> im running it on an amazon micro so maybe im just experiencing bandwidth stuff
00:45 <EvanR> i changed join to concat and haha it works
00:45 <EvanR> sine wave!
00:46 <EvanR> its flickering so much it looks like double helix DNA
00:46 <fragamus> cool
00:47 <EvanR> not slowing down (ghci)
00:47 takle joined
00:47 <Gurkengl1s_> Hmm. Can eval know what b is in order to typecheck a string at runtime?
00:48 <Gurkengl1s_> in the "data T a = forall b." scenario
00:48 <EvanR> types dont exist at runtime, but Typeable does
00:49 <Gurkengl1s_> kthx
00:49 j2j joined
00:49 <Gurkengl1s_> Can I restrict T to Typeable a? "data T a = forall b. Typeable b => ..."?
00:51 <fragamus> @EvanR does concatMap bring any improvement
00:51 <lambdabot> Unknown command, try @list
00:51 sanett joined
00:51 <fragamus> EvanR does concatMap bring any improvement
00:51 <EvanR> @src concatMap
00:51 <lambdabot> concatMap f = foldr ((++) . f) []
00:52 <Welkin> concatMap is concat . map
00:52 <fragamus> i guess not
00:52 <EvanR> i hope not, plus i dont see it needing any improvement
00:52 <EvanR> its friggin fast
00:53 <fragamus> yeah im teaching some kids to code and im setting up byobu to have lots of visually stimulating panes because this is the ADD videogame crowd
00:54 bjz joined
00:54 <Welkin> not SUBTRACT?
00:54 <geekosaur> Gurkengl1s_, you can with a GADT, otherwise you want the restriction at use sites
00:54 <Welkin> what is byobu?
00:54 bollu joined
00:54 <fragamus> its tmux and screen
00:54 <Welkin> is it a chinese version?
00:55 <fragamus> dunno man
01:00 <pacak> Welkin: japanese
01:00 mrjake joined
01:00 <pacak> Welkin: 屏風
01:01 cmsmcq joined
01:02 raycoll joined
01:03 nighty-- joined
01:03 codesoup joined
01:05 tomboy64 joined
01:05 takle joined
01:05 ali_bush joined
01:05 ali_bush joined
01:05 stoopkid joined
01:06 LiamM joined
01:07 fizbin joined
01:07 mekeor joined
01:07 <LiamM> I'm seeing a few dead links for download different versions of ghc 8.0.2: e.g. https://downloads.haskell.org/~ghc/8.0.2/ghc-8.0.2-src.tar.xz
01:07 <LiamM> Anybody know what's up with that?
01:08 mrjake left
01:09 nick123 joined
01:10 Rodya_ joined
01:10 fizbin joined
01:12 richi235 joined
01:13 wroathe joined
01:14 brynedwards joined
01:15 LiamM left
01:20 mac10688 joined
01:22 fizbin joined
01:23 takle joined
01:25 cmsmcq joined
01:26 bjz joined
01:29 dan_f joined
01:29 bhiliyam joined
01:30 ebzzry joined
01:30 uglyfigurine joined
01:30 holla joined
01:31 takle joined
01:31 joneshf-laptop joined
01:34 fizbin joined
01:35 oisdk joined
01:35 biglambda joined
01:36 Stanley00 joined
01:39 ChaiTRex joined
01:39 darjeeling_ joined
01:40 takle joined
01:41 holla joined
01:42 fakenerd joined
01:42 Jeanne-Kamikaze joined
01:43 uglyfigurine joined
01:44 path[l] joined
01:46 Natch joined
01:46 MP2E joined
01:47 permagreen joined
01:49 bollu joined
01:49 imalsogreg left
01:49 takle joined
01:50 mkoenig joined
01:51 cmsmcq joined
01:54 revprez_atlanta joined
01:56 path[l] joined
01:57 leif joined
01:57 leifmetcalf joined
02:00 hucksy joined
02:00 sanett joined
02:03 ziyourenxiang joined
02:04 raycoll joined
02:04 robkennedy joined
02:04 eacameron joined
02:05 mac10688 joined
02:05 mizu_no_oto_work joined
02:06 Goplat joined
02:07 takle joined
02:07 splanch joined
02:07 coltfred joined
02:09 eacamero_ joined
02:09 shayan_ joined
02:10 nick123 joined
02:12 Itkovian joined
02:12 darjeeling_ joined
02:14 alunduil joined
02:14 <sophiag> basic (i think) question about list comprehensions... i have one like so: eval a r = [l | x <- a, y <- r, let l = ListVal (permuteList x), (fromJustAmbVal . reqAmbVal y) l] but only want permuteList called *once* for every element in a rather than once for every time elements in a and r match. i also want the guard applied to the nested lists inside the permutations rather than to the list *of* permutations. how would i achieve that?
02:15 takle joined
02:15 sanett joined
02:15 uglyfigurine joined
02:15 <Cale> You could put a let before the y <- r
02:16 {emptyset} joined
02:17 beerdrop joined
02:17 <Cale> [l | x <- a, let {p = permuteList x}, y <- r, let {l = ListVal p}, fromJustAmbVal . reqAmbVal y $ l]
02:17 <Cale> btw, what is reqAmbVal?
02:18 <Cale> You can put a pattern on the left of a <-
02:18 <Cale> and elements not matching the pattern will be discarded
02:18 <Cale> > [x | Right x <- [Left 1, Right "hello", Left 2, Right "there"]]
02:18 <lambdabot> ["hello","there"]
02:19 <sophiag> reqAmbVal is a field in Require. could have been better named...
02:19 <Cale> ah
02:20 calvinx joined
02:20 <sophiag> actually i'm going to rename it :p
02:20 <Cale> fromJustAmbVal sounds similar to fromJust, which is a function I usually try to avoid
02:21 ubsan_ joined
02:21 <Cale> but its type is quite different from context
02:21 <sophiag> one sec...let me circle back and change some things
02:21 flatmap13 joined
02:22 infinity0_ joined
02:22 infinity0_ joined
02:23 <sophiag> Cale: i'm unfamiliar with that let syntax
02:23 darjeeling_ joined
02:24 aarvar joined
02:24 infinity0 joined
02:24 <sophiag> hmm also it still doesn't solve the problem
02:24 <sophiag> (meaning the first problem: multiple permutations for elements in a)
02:25 takle joined
02:26 chichou joined
02:26 Sose_ joined
02:27 infinity0 joined
02:30 infinity0 joined
02:30 sleffy joined
02:30 fakenerd joined
02:30 fakenerd_ joined
02:30 bhiliyam joined
02:31 <sophiag> regarding the second issue it would seem i'd want something like "map (fromJustAmbVal . reqVal y) l" except that throws a type error
02:31 rgrinberg joined
02:32 infinity0 joined
02:33 uglyfigurine joined
02:34 Destol joined
02:35 infinity0 joined
02:37 pavonia joined
02:37 sleffy joined
02:39 JeanCarloMachado joined
02:39 Wuzzy joined
02:39 cmsmcq joined
02:42 srnty joined
02:43 bollu joined
02:43 tathougies joined
02:44 indi_ joined
02:44 takle joined
02:46 Snircle_ joined
02:47 uglyfigurine joined
02:48 Shatnerz0 joined
02:49 fakenerd joined
02:50 Argue_ joined
02:56 meandi_2 joined
03:00 takle joined
03:02 exferenceBot joined
03:05 leifmetcalf joined
03:06 hexagoxel joined
03:09 gottcha joined
03:11 danthemyth joined
03:11 nick123 joined
03:12 takle joined
03:13 lambda-11235 joined
03:15 uglyfigurine joined
03:15 sdothum joined
03:15 bjz joined
03:16 felixsch_ joined
03:17 adamrk joined
03:18 BlueRavenGT joined
03:20 flatmap13 joined
03:20 raycoll joined
03:20 nomicflux joined
03:20 darlan joined
03:24 safe joined
03:27 ubsan_ joined
03:30 vlatkoB joined
03:30 jdnavarro joined
03:31 iqubic joined
03:31 adamrbk joined
03:31 bhiliyam joined
03:31 ubsan_ joined
03:31 fakenerd joined
03:31 <iqubic> How are people doing?
03:32 eacameron joined
03:32 raycoll joined
03:33 otto_s joined
03:35 teggi joined
03:35 sleffy joined
03:36 hamishmack joined
03:37 bollu joined
03:38 matthewbauer joined
03:38 takle joined
03:39 eacameron joined
03:39 raycoll joined
03:40 dogui joined
03:42 dan_f joined
03:42 uglyfigurine joined
03:42 mizu_no_oto joined
03:43 Itkovian joined
03:47 matthewbauer joined
03:50 systemfault joined
03:53 ubsan_ joined
03:54 alx741 joined
03:55 sanett joined
03:56 <xaimus_> dl
03:56 uglyfigurine joined
03:58 sanett joined
04:01 eklavya joined
04:01 thunderrd joined
04:03 dogui joined
04:05 wroathe joined
04:07 snowalpaca joined
04:07 pmn joined
04:09 thunderrd joined
04:09 uglyfigurine joined
04:11 wroathe joined
04:12 nick123 joined
04:12 mbuf joined
04:13 sanett joined
04:13 nomicflux joined
04:14 takle joined
04:21 flump joined
04:23 uglyfigurine joined
04:28 jmcarthur joined
04:28 takle joined
04:30 jsgrant_ joined
04:31 bollu joined
04:31 bhiliyam joined
04:36 edvorg joined
04:37 serendependy joined
04:40 takle joined
04:43 hamishmack joined
04:47 nick123 joined
04:48 indi_ joined
04:52 skeuomorf joined
04:56 hexfive joined
04:56 takle joined
04:57 seagreen joined
05:00 insitu joined
05:00 uglyfigurine joined
05:01 matthewbauer joined
05:03 systemfault joined
05:04 takle joined
05:04 <pacak> Suppose I have a typeclass StorageSize a with method size :: a -> Int, where size of Bool is 1, size of Word64 is 8 and size of ByteString is BS.length. How would you go about computing StorageSize for let's say (a, b) (generics or otherwise) if you want to have sizes for things like (Int, Int) computed at compile time?
05:05 Argue__ joined
05:06 <glguy> if you only want to determine the size based on the type, it's better to have size :: proxy a -> Int
05:06 <glguy> yes, you can use GHC.Generics to derive sizes for product types
05:07 sanitypassing joined
05:07 dec0n joined
05:08 cyborg-one joined
05:08 <pacak> glguy: That will work for things with constant sizes but won't work with (Int, ByteString) for example
05:08 <glguy> right
05:09 <pacak> Ideally I want something to make a function that will try to calculate size for variable sized objects and add some constants
05:09 <pacak> But ghc compiles things like (a :: Int, b :: ByteString, c :: Int) as (8 + length b + 8)
05:10 <pacak> Constants won't be folded
05:11 Sgeo_ joined
05:11 <pacak> I know how to implement that with TH, but not sure how to approach this with generics
05:11 danthemyth joined
05:11 <pacak> or simple monoidal compositon
05:13 Itkovian joined
05:13 uglyfigurine joined
05:16 halogenandtoast joined
05:16 <glguy> You have to write your generics function to arrange the terms in the way you want them arranged
05:17 <glguy> so if that means accumulating the "constants" in one place, you'd write a function that does that
05:17 <pacak> Hmm... Right, I guess that'll work.
05:17 Swizec joined
05:18 <glguy> Your typeclass would need to help distinguish things that are constant from things that are not
05:18 <glguy> size :: a -> (Int,Int) -- (constant part, variable part)
05:19 <pacak> Thanks for the tip, I'll try :)
05:20 athan joined
05:22 takle joined
05:23 <athan> How do I declare an instance to overlap in GHC 8?
05:24 <glguy> athan: You can search for Overlapping Instance in the GHC users guide search box
05:24 <athan> right on :) thanks glguy
05:25 <glguy> There are pragmas that you can add after the keyword instance
05:26 Xanather joined
05:27 <athan> hm, it seems that declaring the most "vague" instance as {-# OVERLAPPING #-} doesn't defeat my error
05:27 andrewhn51 joined
05:27 <athan> GHC also states that the instance itself is [overlapping], so I at least applied the pragma :x
05:28 fakenerd joined
05:28 fotonzade joined
05:29 ericmathison joined
05:29 <glguy> The very general (vague?) instance should be OVERLAPPABLE
05:29 <halogenandtoast> What is the purpose of overlapping?
05:30 <glguy> halogenandtoast: Are you asking about the purpose of overlapping instances in general?
05:32 <halogenandtoast> glguy: Yes
05:32 bhiliyam joined
05:33 <glguy> Under normal Haskell rules they aren't needed. Instances are always provided for a type constructor applied to zero or more type variables: instance SomeClass (SomeConstructor x y z...)
05:33 <glguy> but once you relax that you can provide instances where one is more general than the other
05:33 <glguy> instance SomeClass (SomeConstructor x y z...); instance SomeClass (SomeConstructor x Char z...)
05:34 pwnz0r joined
05:34 <glguy> where you intended for that second instance to be prefered when y is Char and to use the first otherwise
05:34 <glguy> Maybe you have an implementation that works for lists in general: instance C [a]
05:34 <glguy> but a special one for strings
05:35 <glguy> instance C [Char]
05:36 filterfish__ joined
05:36 uglyfigurine joined
05:38 riaqn joined
05:38 riaqn joined
05:38 robertkennedy joined
05:38 <geekosaur> this does come at a potential price though; the ghc manual points out how this can make the type system unsound
05:39 splanch joined
05:40 darjeeling_ joined
05:41 Guest16115 joined
05:44 <halogenandtoast> glguy: Thanks, interesting
05:45 Argue_ joined
05:47 <sophiag> i feel a bit silly asking this, but i'm trying to debug something by breaking it down into the simplest cases and wondering why this list comprehension isn't typechecking: [l | x <- [[1,2,3],[4,5,6]], y <- [(\x -> x /= [1,2,3]), (\x -> x /= [2,1,3]),(\x -> x /= [6,5,4])], let l = permutations x, map y l]
05:48 <glguy> sophiag: You've got a stray 'map y l' at the end there
05:48 <glguy> When you have a bare expression like that in a list comprehension it needs to have type Bool
05:48 <sophiag> yeah, i realize that's a problem. it doesn't typecheck without it, though, so i left it because i don't understand why it's a problem
05:49 <sophiag> but shouldn't it be matching elements in y?
05:49 caumeslasal joined
05:50 <sophiag> i get the same problem with, for example: [l | x <- [[1,2,3],[4,5,6]], y <- [[1,2,3],[2,1,3],[6,5,4]], let l = permutations x, l /= y]
05:50 uglyfigurine joined
05:50 <glguy> You can't compare l and y with /=, they don't have the same type
05:50 <glguy> :t permutations
05:50 <lambdabot> [a] -> [[a]]
05:51 <glguy> :t (/=)
05:51 <sophiag> could i throw in a map there tho?
05:51 <lambdabot> Eq a => a -> a -> Bool
05:51 JeanCarloMachado joined
05:51 kazagistar joined
05:52 <sophiag> shouldn't this be ok? [l | x <- [[1,2,3],[4,5,6]], y <- [[1,2,3],[2,1,3],[6,5,4]], let l = permutations x, map (/= y) l]
05:52 <geekosaur> no, the result is [Bool]
05:52 <glguy> no, map (/= y) l doesn't have type Bool
05:52 <sophiag> ah ok. my intention was to apply a guard
05:53 <sophiag> basically to filter each of the permutations of x by the contents of y
05:53 <geekosaur> > [l | x <- [[1,2,3],[4,5,6]], y <- [[1,2,3],[2,1,3],[6,5,4]], l <- permutations x, l /= y]
05:53 <glguy> instead of map you can use any or all.
05:53 <lambdabot> [[2,1,3],[3,2,1],[2,3,1],[3,1,2],[1,3,2],[1,2,3],[3,2,1],[2,3,1],[3,1,2],[1,...
05:53 <geekosaur> hm, no
05:54 <* geekosaur> should not atempt this when half asleep
05:54 <sophiag> geekosaur: so that's what i was trying to get to typecheck so i could diagnose exactly that problem
05:54 <* geekosaur> slinks away
05:54 <glguy> To determine if one list is a permutation of another I'd recommend comparing the sorted versions of each
05:54 indi_ joined
05:54 insitu joined
05:54 <glguy> > all (0 ==) [1..10]
05:54 <lambdabot> False
05:54 <sophiag> glguy: no, not exactly. whether any elements in a permutation of one list are equal to boolean constaints in another
05:54 revprez_atlanta joined
05:55 <glguy> > any (5 ==) [1..10]
05:55 <lambdabot> True
05:55 <sophiag> in other words, i'd like to filter the permutations of every element in x by all the element in y
05:56 <sophiag> so basically my understanding is what geekosaur tried should work, yet it doesn't...
05:57 <sophiag> i assume maybe because it's not matching the nested lists in each l with each nested list in y?
05:57 Argue__ joined
05:59 azahi joined
05:59 fakenerd joined
06:00 <redpoppies> hi guys
06:00 <redpoppies> can anyone help with wreg : https://paste.gnome.org/pers66acy
06:00 <redpoppies> *wreq
06:00 <glguy> > [ permutations x \\ [[1,2,3],[2,1,3],[6,5,4]] | x <- [[1,2,3],[4,5,6]] ]
06:00 <lambdabot> [[[3,2,1],[2,3,1],[3,1,2],[1,3,2]],[[4,5,6],[5,4,6],[5,6,4],[6,4,5],[4,6,5]]]
06:00 <redpoppies> assume a let at the beginning
06:01 <redpoppies> it returns an empty answer although the equivalent curl request does return what it should
06:01 takuan joined
06:01 <redpoppies> my only assumption is that payload is not properly sent
06:01 <cocreature> redpoppies: could you show us the exact curl request that you used?
06:01 <redpoppies> but that would not explain the 200 status, because vision does fail on incorrect format
06:02 <redpoppies> curl -v -H "Content-Type: application/json" -d @/home/adrian/Desktop/gvreq.txt https://vision.googleapis.com/v1/images:annotate?key=mykeyhere
06:02 <sophiag> glguy: thanks. so \\ is like a guard in list comprehensions?
06:02 <redpoppies> hi @cocreature, my kind of guy :)
06:03 <glguy> No, (x \\ y) removes the elements of y from x
06:03 <sophiag> oh. great
06:03 <glguy> http://hackage.haskell.org/package/base-4.9.0.0/docs/Data-List.html#v:-92--92-
06:03 <pacak> @src (\\)
06:03 <lambdabot> (\\) = foldl (flip delete)
06:03 <sophiag> ah ok
06:03 <cocreature> redpoppies: what’s the content of gvreq.txt?
06:03 <sophiag> my actual use case is a list of lambdas i want to filter by though
06:04 <redpoppies> a json payload equivalent to the string in the pastebin link
06:04 <redpoppies> practically a base64 encoded image with some metadata
06:04 thimoteus joined
06:04 <cocreature> redpoppies: so then it seems like your curl request doesn’t make a multipart request?
06:04 <cocreature> while your wreq request does?
06:04 <glguy> sophiag: then it would be good to learn about any and all , which an be found on that same page
06:05 <redpoppies> @cocreature, no multipart on wreq either
06:05 <lambdabot> Unknown command, try @list
06:05 <glguy> redpoppies: @ is for bot commands
06:05 <cocreature> redpoppies: "partBS" is a multipart request
06:05 <sophiag> glguy: thanks. i'll play with it for a bit
06:05 <redpoppies> really, the docs say it adds no headers
06:05 <redpoppies> glguy, thanks, apologies
06:06 hurkan joined
06:07 <redpoppies> cocreature, so how do i send a normal payload? i see no function
06:08 <cocreature> redpoppies: postWith accepts any payload that is an instance of Postable
06:08 <cocreature> redpoppies: that includes aeson’s Value and ByteString
06:08 <cocreature> so either build a Value or just use your bytestring directly
06:08 <redpoppies> ok, thanks, I will try that, missed it in the docs
06:08 <redpoppies> i will let you know
06:08 <cocreature> the aeson solution is probably better since you don’t need to mess around with encoding your value as json
06:09 meandi_2 joined
06:09 <cocreature> i.e. you can’t screw up parenthesis and things like that
06:09 <redpoppies> cool, it works, thank you again
06:09 <cocreature> np
06:09 <redpoppies> kind of silly for me not to realize that
06:10 <cocreature> we all make mistakes :)
06:10 <redpoppies> i should be out here more often to help out too where i can
06:10 <redpoppies> you guys have been amazing
06:11 <halogenandtoast> @src (//)
06:11 <lambdabot> arr@(Array l u _) // ies = unsafeReplace arr [(index (l,u) i, e) | (i, e) <- ies]
06:12 zeroed joined
06:13 wroathe joined
06:16 Gurkenglas_ joined
06:17 freusque joined
06:19 bollu joined
06:19 glguy joined
06:20 fakenerd joined
06:21 Gurkenglas_ joined
06:21 minn joined
06:22 shayan_ joined
06:23 <sophiag> glguy: it's the last function here that i'm stuck on: http://lpaste.net/354572
06:24 <sophiag> it always seems to return multiple permutations of each element in a for as many as are in r plus isn't actually filtering them
06:25 <sophiag> this is not to mention matching the Maybe Strings in each...i don't think the second to last statement is actually doing what i want. i'd rather have it be like "if ambTag x == reqTag y then ..." except i can't do that in a list comprehension
06:25 ragepanda joined
06:26 zeroed joined
06:27 chichou joined
06:27 <orion> If I'm writing a Free Monad based DSL and I want to represent a "Plus" command which can take any Num, how would I write my AST?
06:28 howdoi joined
06:28 Itkovian joined
06:31 bab joined
06:31 uglyfigurine joined
06:31 <orion> Normally I'd write something like: data AST next = Plus Integer Integer (Integer -> next) deriving Functor -- but I want to generalize it for all Num-like types.
06:32 Argue joined
06:32 forgottenone joined
06:32 Guest34989 joined
06:32 burtons joined
06:33 <Guest34989> hey guys how are things going with my favorite programming language...
06:33 <Guest34989> java!
06:33 bhiliyam joined
06:35 <rinon> is there a haskell implementation on top of the JVM? that'd be kinda cool
06:35 <thimoteus> yes, look at frege
06:35 <cocreature> rinon: http://eta-lang.org/
06:35 <pacak> rinon: There is https://github.com/typelead/eta
06:37 infinity0 joined
06:37 <rightfold> orion: data AST n next = Plus n n (n -> next); then add a Num constraint to the interpreter
06:38 <rinon> cool :)
06:38 MoALTz joined
06:39 <orion> rightfold: Thank you.
06:39 fakenerd joined
06:40 <rightfold> other option would be data AST :: * -> * where Plus :: Num n => n -> n -> (n -> next) -> Plus next
06:40 <rightfold> But I'm not sure how usable that is
06:40 <rightfold> Eh that last Plus should be AST
06:41 <rightfold> But with this GADT you could use different number types in the same action
06:41 <cocreature> I don’t think the existential/GADT approach works here
06:41 <rightfold> Yeah there are probably issues
06:42 <cocreature> you can’t do anything if you know that something is an instance of Num apart from combining it with other things that are Num
06:42 <cocreature> but you can’t inspect or convert it to anything else
06:42 <cocreature> so it’s mostly useless in the (n -> next) function
06:42 <rightfold> Coyoneda Identity
06:43 vydd joined
06:44 eacameron joined
06:46 <rightfold> orion: if you write a Bifunctor AST instance then you can change the number type with lmap, might be useful
06:47 magneticduck joined
06:49 baldrick joined
06:49 eacameron joined
06:50 slomo joined
06:52 jedws joined
06:52 guiben joined
06:53 Kreest__ joined
06:53 ericmathison joined
06:53 guiben joined
06:53 sz0 joined
06:54 eacameron joined
06:54 uglyfigurine joined
06:55 zcourts joined
06:57 <Guest34989> haskell's curry
06:57 takle joined
06:57 <Theophane> I'm hungry now. :(
06:58 <cocreature> Theophane: I’ve heard that eating can help with that
06:59 <tsahyt> Theophane: may I interest you in the tortilla endofunctor?
06:59 eacameron joined
07:00 Itkovian joined
07:00 <cocreature> tsahyt: is that an endofunctor on the general category of food or only on some subcategory?
07:00 <Theophane> cocreature: yeah can't really eat right now, I'm an amphitheatre
07:00 <Theophane> tsahyt: tell me more about this :P
07:00 <Theophane> With your most sophisticated french accent!
07:00 Argue_ joined
07:02 <MarcelineVQ> le crêpe aux tumeric
07:02 <Theophane> :')
07:02 Swizec joined
07:03 <cocreature> Theophane: are you _at_ an amphitheatre or are you an amphitheatre yourself? I didn’t know amphitheatres could talk :)
07:03 <rightfold> It's time to get up and work
07:03 eacameron joined
07:04 <tsahyt> cocreature: I guess it maps only to the subcategory of food that is wrapped in a tortilla
07:04 <Theophane> cocreature: :') sorry, I'm at one
07:04 <orion> rightfold: Interesting. Do you know of any examples?
07:04 mszczygiel joined
07:04 ubsan_ joined
07:04 <cocreature> tsahyt: but I guess there is no restriction on its domain?
07:05 <tsahyt> no, anything can be wrapped in a tortilla
07:05 <cocreature> nice
07:05 <tsahyt> given a sufficiently strong press, you can also merge tortillas, so you get T (T a) -> T a
07:07 <Theophane> did you folks read Aphyr's "Typing the technical interview"? =)
07:08 <tsahyt> was that the one that solved n-queens on the type level?
07:08 <rightfold> orion: e.g. lmap fromInteger, to convert AST Integer next to AST Double next
07:09 <Theophane> tsahyt: Y E S
07:09 <rightfold> I think GHC doesn't support Bifunctor deriving yet
07:09 <Theophane> :D
07:09 <tsahyt> that was quite nice
07:09 ens_ joined
07:09 eacameron joined
07:10 takle joined
07:10 <tsahyt> not too surprising that it's possible, given that this is a thing: http://hackage.haskell.org/package/register-machine-typelevel
07:11 <cocreature> rightfold: now I want bifunctor deriving
07:11 <orion> rightfold: I see. Would I have to put a Bifunctor constraint anywhere?
07:11 mmn80 joined
07:11 vlatkoB_ joined
07:11 <rightfold> No
07:11 <orion> Interesting.
07:11 <cocreature> not even generic-deriving seems to support bifunctor
07:12 CoderPuppy joined
07:12 <cocreature> seems like I’ll need to write that myself :)
07:12 <cocreature> ah no https://hackage.haskell.org/package/bifunctors-5.4.1/docs/Data-Bifunctor-TH.html#v:deriveBifunctor
07:13 TheLemonMan joined
07:13 bollu joined
07:13 Itkovian joined
07:13 eacamero_ joined
07:13 <rightfold> Add Contravariant and Profunctor deriving while you're at it
07:14 <rightfold> Derive everything
07:15 <cocreature> I use contravariant and profunctor a lot less than I use bifunctor so I don’t care too much about this :)
07:16 tomboy64 joined
07:17 uglyfigurine joined
07:17 seveg joined
07:17 pmn joined
07:17 takle joined
07:18 <tsahyt> Idris has this concept of decidable predicates. Is this even possible in Haskell? e.g. data Dec (p :: Type) :: Type where { Yes :: p -> Dec p; No :: (p -> Void) -> Dec p }
07:18 <tsahyt> the yes part is pretty trivial, it's the No part that I can't figure out
07:19 <tsahyt> in Idris you can use impossible to denote that a pattern cannot ever be matched
07:19 linelevel joined
07:19 <tsahyt> now GHC does have this inaccessible code analysis for GADTs at least since the GADTs meet their match paper. so I was wondering whether I could leverage that somehow
07:19 hybrid joined
07:19 kdfine joined
07:19 <tsahyt> the concrete use case here is to decide that a size indexed structure is empty or non-empty
07:20 <tsahyt> and if it's non-empty, ideally refine it's index n via n ~ m + 1, although the quantification of m might be another problem entirely
07:20 castlelore joined
07:20 <tsahyt> otherwise, at least bring a 1 <= n constraint into scope
07:20 CurryWurst joined
07:21 sanett joined
07:22 Swizec joined
07:22 Destol joined
07:23 eacameron joined
07:23 aarvar joined
07:23 logicmoo joined
07:24 halogenandtoast joined
07:27 richi235 joined
07:27 Itkovian joined
07:28 ohsix joined
07:29 eacameron joined
07:30 t7 joined
07:30 uglyfigurine joined
07:33 eacamero_ joined
07:34 takle joined
07:34 bhiliyam joined
07:37 dh joined
07:37 <xormor> I have learned some Haskell! :-)
07:37 <xormor> I like it as much as I like C and C++, and it is more handy in mathematics than C and C++. Assembly is best for creating machine dependent quick, small programs but Haskell is super for math.
07:38 eacameron joined
07:41 ph88 joined
07:41 fotonzade joined
07:41 Guest74592 joined
07:41 sanett_ joined
07:44 uglyfigurine joined
07:47 <halogenandtoast> Haskell is super for many things
07:47 <halogenandtoast> not just math
07:47 thc202 joined
07:47 <hc> haskell is super for generating assembly code for machine dependent quick, small programs ;-)
07:48 fizruk joined
07:48 eacameron joined
07:49 <jle`> haskell is my favorite way to generate assembly code
07:53 niklasb joined
07:53 redpoppies joined
07:53 uglyfigurine joined
07:55 ninjazoete joined
07:55 filterfish joined
07:56 <xormor> jle`, wow! how is that possible?
07:56 <xormor> jle`, how do I create assembly code with haskell?
07:56 <jle`> sorry by assembly code i really meant bytecode
07:56 <xormor> hc, how?
07:56 <xormor> jle`, I see...
07:57 <xormor> jle`, so is the bytecode runnable in GNU/Linux, MS-DOS (DosBox) or Windows (WINE)?
07:57 indi_ joined
07:57 <jle`> whatever you want :o
07:57 <jle`> there are many backends
07:57 <xormor> great
07:58 <xormor> I want to do it. The last time I was this excited about a programming language was in the 1990's when I learned C and C++.
07:58 takle joined
07:58 hive-mind joined
08:00 xall joined
08:00 jedws joined
08:01 Argue__ joined
08:02 dan_f joined
08:03 <rightfold> GHC can generate machine code
08:04 <rightfold> You don't have to use the bytecode interpreter
08:04 fizruk joined
08:04 eklavya joined
08:05 doomlord joined
08:05 <hc> xormor: ivory, for example
08:05 hybrid joined
08:06 <hc> xormor: http://hackage.haskell.org/package/ivory
08:07 meba joined
08:07 uglyfigurine joined
08:07 bollu joined
08:08 Axman6 joined
08:11 darjeeling_ joined
08:12 yellowj joined
08:13 Denthir joined
08:13 eacameron joined
08:14 lep-delete joined
08:15 meoblast001 joined
08:16 Rodenbach joined
08:16 Berra joined
08:17 fakenerd joined
08:17 <Guest34989> guys
08:17 <Guest34989> whats the best language
08:17 <tsahyt> maths
08:17 vydd joined
08:17 vydd joined
08:17 <Philonous> icelandic
08:18 Aune joined
08:18 <Guest34989> programming language
08:18 <Guest34989> that is
08:18 <hc> does neurolinguistic programming count as programming to you? ;)
08:19 niklasb joined
08:19 <Guest34989> hc: shove it into /dev/null
08:20 <TheLemonMan> best language for doing what?
08:20 <xormor> Guest34989, I like: C, C++, Haskell (that I have newly learned), and amd64 and x86 assembly languages.
08:20 <Gurkenglas_> Can I have stack let import statements just work without me specifying what packages they came from?
08:20 chichou joined
08:20 <xormor> Guest34989, Turbo Pascal was a good language in the 1980's and BASIC in the 1980's.
08:21 raichoo joined
08:21 <xormor> Guest34989, Turbo Pascal in the '90's I meant.
08:21 <geekosaur> Gurkenglas_, since stack is specifically a repeatable builds tool, I doubt it
08:21 <Guest34989> TheLemonMan: general purpose
08:22 <TheLemonMan> Guest34989, there's no silver bullet
08:22 <tsahyt> is either (const Nothing) Just :: Either a b -> Maybe b already defined somewhere?
08:22 <tsahyt> @hoogle Either a b -> Maybe b
08:22 <lambdabot> Data.Either.Combinators leftToMaybe :: Either a b -> Maybe a
08:22 <lambdabot> Agda.Utils.Either maybeLeft :: Either a b -> Maybe a
08:22 <lambdabot> Music.Theory.Either fromLeft :: Either a b -> Maybe a
08:22 <xormor> Guest34989, try C, C++ or Haskell. or even Java or JavaScript for web programming.
08:24 takle joined
08:24 iomonad joined
08:25 <Guest34989> why does haskell io need iomonad
08:26 <Guest34989> iomonad: no offense
08:26 mfukar joined
08:28 <TheLemonMan> Guest34989, https://wiki.haskell.org/IO_inside
08:28 <Guest34989> looks nasty
08:29 <ongy> stack does repeatable builds? as in hash equivalent builds?
08:29 dhil joined
08:30 <ongy> the way IO is handled looks really annoying until you understand it and use it for some time. Then it feels pretty good. At least that's how it went for me
08:30 uglyfigurine joined
08:30 <tsahyt> Guest34989: you could do IO without monads too. Haskell predates its own use of Monads.
08:30 <Gurkenglas_> Can I let System.Eval.Haskell's eval import modules that didn't exist at compile time?
08:30 <tsahyt> it just turns out that monads are a very nice abstraction to handle IO
08:32 jaspervdj joined
08:32 piyush-kurur left
08:32 John[Lisbeth] joined
08:32 <John[Lisbeth]> is a monad a way of representing mutability in a purely functional way?
08:33 <tsahyt> John[Lisbeth]: monads can be used to model mutable state
08:33 <John[Lisbeth]> can you model mutable state in a purely functional way without monads?
08:34 <tsahyt> I'm pretty sure you could use continuations instead, but I've never looked into that
08:35 <tsahyt> mutable state in general can be modeled adequately through functions that take a state and return a state (in addition to whatever else they return), e.g. s -> (s, a) for some state type s
08:35 bhiliyam joined
08:35 <tsahyt> what monads bring to the table is an elegant way of working with those functions
08:36 Guest57265 joined
08:37 takle joined
08:38 sanett joined
08:38 Denthir joined
08:39 srbaker joined
08:41 Wizek_ joined
08:41 Heffalump joined
08:42 <markus1209> to test my understanding: are type constructors not surjective because we go from Type -> Type and all of the right hand side Type are Maybe xyz, therefore e.g. Int is not in the codomain for Maybe
08:42 zar joined
08:42 <Heffalump> anyone know where the source of ghc 8.2.1 rc1 is? I'm getting 404 errors from the links at https://downloads.haskell.org/~ghc/8.2.1-rc1/
08:43 <markus1209> * if we take the Maybe type constructor as an example
08:43 Orion3k joined
08:44 orbifx joined
08:44 fakenerd joined
08:45 NikolajK joined
08:46 <tsahyt> markus1209: sounds about right. for Type -> Type to be surjective, you'd need an input for all outputs.
08:46 JoshS joined
08:48 <tsahyt> but as you said, Maybe only maps to a subset of all possible types. by virtue of being a functor, the image of Maybe is a subcategory of Hask unless I'm much mistaken
08:48 marr joined
08:48 uglyfigurine joined
08:48 <tsahyt> and it's a proper subcategory
08:50 <tsahyt> type constructors should be injective though. given T a ~ T b, you should be able to deduce that a ~ b. this is not true for type families.
08:50 <tsahyt> or even type synonyms I think.
08:50 Argue joined
08:52 chichou joined
08:52 kamog joined
08:53 takle joined
08:55 govg joined
08:56 <Gurkenglas_> Is "#!/usr/bin/env stack" why all my error line numbers seem to be off by one?
08:56 <NikolajK> Why is
08:56 <NikolajK> Type : Type 1 while (Type, Type) : (Type 1, Type 1).
08:56 <NikolajK> Not sure if that's the right place for Idris, but the response times there are longer than my online times.
08:56 <NikolajK> not*
08:56 <NikolajK> (Type, Type) : (Type, Type) says the interactive enviroment, and I don't get it
08:56 <tsahyt> NikolajK: I've also been unable to get Type 1 : Type 2, so there's that
08:57 <NikolajK> I can stomache that, if we think of code being in Type and the rest is meta
08:57 eacameron joined
08:58 <markus1209> tsahyt: thanks ;)
09:01 mtesseract joined
09:01 bollu joined
09:02 <Gurkenglas_> (Never mind, I didn't recompile the file after deleting the line.)
09:03 bennofs joined
09:05 zero_byte joined
09:08 Avogadro joined
09:09 takle joined
09:09 eacameron joined
09:11 nirvinm1 joined
09:15 laz joined
09:15 lush joined
09:15 eacameron joined
09:16 takle joined
09:18 mikecheck joined
09:19 azahi joined
09:19 fakenerd joined
09:20 uglyfigurine joined
09:21 skeuomorf joined
09:22 cow_2001 joined
09:22 kritzcreek_ joined
09:22 <cow_2001> woah! an israeli asked an haskell question! :D https://stackoverflow.com/questions/43347582/permission-denied-when-reading-from-clipboard
09:23 Xanather joined
09:23 John[Lisbeth] joined
09:23 Itkovian joined
09:23 <John[Lisbeth]> A monad can be a function true or false?
09:23 dan_f joined
09:23 <TheLemonMan> it is an algebric structure, so no
09:24 eacameron joined
09:24 <Philonous> (-> r) is a Monad
09:24 nirvinm joined
09:24 takle joined
09:24 <Philonous> ((->) r) I mean
09:24 <John[Lisbeth]> it is impossible to create a function that is a monad?
09:24 ziocroc joined
09:24 <Philonous> John[Lisbeth], Monads have kind * -> *, functions have kind *, so no.
09:25 <Philonous> I mean yes, it's impossible
09:25 <John[Lisbeth]> Can a monad have a name?
09:25 nirvinm1 joined
09:25 <TheLemonMan> of course
09:25 filterfish joined
09:25 <John[Lisbeth]> can you name a monad f and can you name a monad g ?
09:26 <rightfold> "The I/O monad", "the maybe monad", "the list monad"
09:26 <Guest34989> sure it's called a monad
09:26 <John[Lisbeth]> Can you apply a monad f to a monad g?
09:26 <TheLemonMan> those questions sound a lot like homework
09:27 <John[Lisbeth]> I am self taught
09:27 <megaTherion> yeah he is working his sheet off
09:27 <megaTherion> ...and you guys fall for it :D
09:27 <rightfold> Technically when you say "the X monad", it means "the Monad (X ...) instance", but it may refer to "X" itself in everyday speak
09:27 <John[Lisbeth]> I am simply asking logical questions which I think are most likely to help me figur eout what a monad is
09:28 <TheLemonMan> you can compose monads, applying monads make little or no sense
09:29 <rightfold> Composing monads doesn't always give a monad
09:29 uglyfigurine joined
09:29 <John[Lisbeth]> I can name a function f and I can name a function g and I can say f(g)=c. But can I similarly have a monad named t and a monad named p and say t(p)=g AND p(t)=g ? Is that what makes them different?
09:29 <rightfold> `newtype Compose f g a = Compose (f (g a))` has no `(Monad f, Monad g) => Monad (Compose f g)` instance
09:29 <rightfold> It has an `Applicative` instance though
09:30 eacameron joined
09:30 <TheLemonMan> yeah, I'm not well versed in the monad algebra
09:30 <John[Lisbeth]> For a monad f and a monad g is it always true that g(f) = f(g) ?
09:31 <rightfold> Which is useful for, for example effectful validation. `Compose IO (AccValidation e)`
09:31 <Athas> Uh, in Haskell it is unlikely that you can apply a monad to another, unless it is a transformer.
09:31 <Philonous> It's not unlikely, it's impossible. The kinds don't match
09:32 <Athas> Yeah, you're right.
09:33 takle joined
09:35 <rightfold> Impossibly implies unlikely :)
09:35 <Philonous> Fair enough ;)
09:35 bhiliyam joined
09:36 daniel-s joined
09:37 NikolajK joined
09:40 Swizec joined
09:41 MrRicecake joined
09:41 Swizec joined
09:42 Swizec joined
09:42 Itkovian joined
09:42 Swizec joined
09:43 uglyfigurine joined
09:48 <John[Lisbeth]> a monad is a function that takes a function and binds it to another function
09:49 jeltsch joined
09:49 stearnsi joined
09:49 <Philonous> That's not true. A Monad (in Haskell) is a data type that implements a certain type class.
09:49 <tsahyt> TheLemonMan: the fact that monads don't compose in general is why we have monad transformers
09:49 laz joined
09:50 shayan_ joined
09:50 eacameron joined
09:50 fakenerd joined
09:51 netheranthem joined
09:51 <John[Lisbeth]> if monads don't compose then what do they do
09:52 <tsahyt> they provide (>>=). anything for which you can define (>>=) and return (but that's also in Applicative) such that it obeys a set of laws is a monad
09:52 <tsahyt> the same goes for join, which is an alternative way to define monads
09:52 <tsahyt> but not the one used in haskell
09:54 <John[Lisbeth]> bind is a function that takes a monad and takes a function which returns a value that is a monad
09:54 bennofs joined
09:54 <tsahyt> :t (>>=)
09:54 <lambdabot> Monad m => m a -> (a -> m b) -> m b
09:55 twanvl joined
09:55 <tsahyt> kinda sorta, although "takes a monad" and "value that is a monad" sound very off. you can think of 'm a' as a value in a monad, but really it's the image of a under the functor m.
09:55 bollu joined
09:56 <tsahyt> :k Maybe
09:56 <lambdabot> * -> *
09:56 revprez_atlanta joined
09:56 <tsahyt> as an example, note that Maybe takes a type to another type
09:57 <John[Lisbeth]> :t Monad
09:57 <lambdabot> error: Data constructor not in scope: Monad
09:57 <tsahyt> Maybe Int is a type in its own right. it's the image of Int under Maybe.
09:57 <tsahyt> and Maybe is a functor. it's also an instance of the Monad class, so (>>=) is defined on it
09:57 anderson joined
09:57 <tsahyt> for Maybe, you'd get (>>=) :: Maybe a -> (a -> Maybe b) -> Maybe b.
09:57 Zialus joined
09:58 <Athas> :info Monad
09:58 <tsahyt> Athas: lambdabot doesn't do info
09:58 <Athas> Too bad.
09:58 <tsahyt> it'd spam the channel I think
09:58 <rightfold> Monad exists because it has both many instances and many use cases. It is no more special than other interfaces that have these two properties, such as Ord.
09:58 <tsahyt> John[Lisbeth]: for Maybe in particular, using join for construction provides better insight imo
09:58 <tsahyt> join :: Maybe (Maybe a) -> Maybe a
09:59 nighty-- joined
09:59 <* geekosaur> prefers lists for that, because there's a fairly obvious mapping map <-> fmap, concat <-> join
09:59 <seequ_> > Maybe 5 >>= \x -> Maybe (2 * x)
09:59 <lambdabot> error:
09:59 <lambdabot> • Data constructor not in scope: Maybe :: Integer -> m Integer
09:59 <lambdabot> • Perhaps you meant variable ‘maybe’ (imported from Data.Maybe)error:
09:59 AspiringEngineer joined
09:59 <seequ_> whoops
10:00 <seequ_> > Just 5 >>= \x -> Just (2 * x)
10:00 <lambdabot> Just 10
10:00 indi_ joined
10:00 <tsahyt> :t \x f -> join (fmap f x)
10:00 <lambdabot> Monad m => m a1 -> (a1 -> m a) -> m a
10:00 <halogenandtoast> > (*) <$> Just 5 <*> Just 2
10:00 <lambdabot> Just 10
10:00 <halogenandtoast> (* 2) <$> Just 5
10:00 <halogenandtoast> > (* 2) <$> Just 5
10:00 <lambdabot> Just 10
10:01 _sg joined
10:02 <tsahyt> find (> 4) <$> Just [1..10]
10:02 <tsahyt> > find (> 4) <$> Just [1..10]
10:02 <lambdabot> Just (Just 5)
10:02 <halogenandtoast> lol
10:02 <tsahyt> > join (find (> 4) <$> Just [1..10])
10:02 <lambdabot> Just 5
10:03 <seequ_> > Just [1..10] >>= find (> 4)
10:03 <lambdabot> Just 5
10:03 <Athas> So, what happens if I have a type with more than two type parameters, so I cannot use Bifunctor?
10:03 <tsahyt> Athas: do you want to be able to map over all of them?
10:04 <rightfold> Athas: Trifunctor
10:04 <Athas> rightfold: when does it stop?
10:05 <Athas> I don't actually have this problem right now, but I was wondering.
10:05 <tsahyt> I'm not sure there even is a Trifunctor class
10:05 <rightfold> Whenever you need
10:05 <tsahyt> but there's a library for generating fmap etc for functors of any arity
10:05 <tsahyt> http://hackage.haskell.org/package/genifunctors
10:05 sharkbabyxiang joined
10:05 <rightfold> tsahyt: It conceptually does, at least
10:05 <tsahyt> rightfold: yes, but I've never seen one in Haskell
10:05 <rightfold> Same
10:05 <tsahyt> nor did I ever need one. I hardly ever need Bifunctors either
10:06 mtesseract joined
10:06 <Athas> There is one on Hackage, but it's kind of obscure.
10:06 <rightfold> There's Clown and Joker to lift Functor to Bifunctor
10:06 <tsahyt> the only time I needed Bi{functor,traversable,foldable} was when dealing with a large AST type that was parameterized over its symbol and signature type, so I could register the data with a C lib before passing it, and still construct the AST in pure code before.
10:06 <Gurkenglas_> Athas, I think the general case is adressed by lens
10:07 <tsahyt> the answer is always lens
10:07 <Athas> Probably. Well, I'll deal with those type errors when I get there.
10:07 hackebeilchen joined
10:07 <rightfold> tsahyt: I just used lmap on an either
10:08 <tsahyt> I hardly ever use Either either.
10:08 <Athas> I'm only just now adding Bitraversable instances to my project instead of having tons of boilerplate for AST traversal.
10:08 <Athas> We'll see whether it works well!
10:08 <rightfold> tsahyt: :)
10:08 <tsahyt> and when I do, I do it for composability of error conditions. and once you lmap on it, you're now in a different monad
10:08 <rightfold> ExceptT with newtype unwrap
10:08 meba joined
10:08 <tsahyt> which makes composition a bit harder
10:08 frangor joined
10:08 <tsahyt> although I just used it for a hacky existential
10:09 <tsahyt> https://github.com/tsahyt/indexed-set/blob/master/src/Data/Set/Indexed.hs#L249
10:09 <rightfold> I needed a natural transformation Either String ~> Either Error
10:09 <tsahyt> yes, that sounds like lmap
10:10 albertus1 joined
10:11 <tsahyt> so I spent a few hours wrapping most of Data.Set into this cardinality indexed set type, and now I forgot what I actually wanted to do with it
10:11 <tsahyt> I'm still not sure whether it's even remotely usable, since a lot of it requires existentials
10:12 <tsahyt> I guess the most useful part of it may turn out to be the index based access, because that's now type safe. but probably also a pain to use.
10:13 <rightfold> tsahyt: very cool
10:13 oisdk joined
10:14 <rightfold> Like singleton :: a -> Set '1 a?
10:14 fizruk joined
10:14 mtesseract joined
10:14 <rightfold> Oh I see the GH link now
10:15 <tsahyt> rightfold: yes it provides that
10:15 <tsahyt> but the problem is with functions like union
10:15 <tsahyt> there's no way to deduce the cardinality of the output purely by that of the inputs
10:15 <tsahyt> the best I can do is provide bounds, but I'm not sure that's even useful at all
10:16 Kreest_ joined
10:16 <tsahyt> to give a definitive answer, I'd either need to inspect the sets at type level, which is somewhere between impossible and massive pita, or at least a proper dependent pair return type
10:17 <tsahyt> I also lose some instances, because mappend :: Set 1 a -> Set 1 a -> Set 1 a doesn't make any sense at all
10:17 <tsahyt> same for semigroup of course
10:18 <rightfold> tsahyt: how efficient (compile time wise) are these type level nats?
10:18 <tsahyt> I've never noticed them making much a difference in terms of compile times
10:18 <rightfold> Nice!
10:18 <tsahyt> GHC doesn't treat them as inductively defined
10:18 <tsahyt> and indeed they actually aren't, which makes it harder to write inductive proofs with them
10:18 <tsahyt> compared to say Nat in idris
10:18 <rightfold> We use type level nats in PureScript and it's kinda slow
10:19 <tsahyt> defined as Nat = Z | S Nat?
10:19 <rightfold> Also reifying to value level is O(n) which is lame
10:19 <rightfold> Well as data Z :: Type and data S :: Type -> Type
10:19 <tsahyt> reification to the value level for TypeLits should be O(1), but it depends on passing the KnownNat dictionary around, so I think there might still be some overhead
10:19 <rightfold> Then type classes for functions 🤓
10:19 uglyfigurine joined
10:20 <rightfold> Haskell's DataKinds are better
10:20 <tsahyt> they're currently just not extremely useful yet
10:20 balor joined
10:20 <tsahyt> with -XDependentHaskell or whatever it will end up being called they should become much more useful I think
10:21 <tsahyt> but so far we've at least gotten a nice length indexed vector library out of them, as well as servant.
10:21 <tsahyt> and many hours of "why won't you compile" for me
10:21 <rightfold> :3
10:21 orbifx joined
10:21 eacameron joined
10:22 <tsahyt> which is why you'll see in this library that I either don't bother at all, since the ISet constructor will readily construct me sets of *any* cardinality I tell it to, or use some unsafe trickery to provide constraints for the bounds etc
10:23 Itkovian joined
10:23 Iceland_jack joined
10:23 <tsahyt> the former works mostly because there's no connection between the type level nat and the actual value. it's a phantom parameter.
10:24 fakenerd joined
10:24 dan_f joined
10:24 binaryplease joined
10:25 <Gurkenglas_> Do I have to use zoom to get the full power of %%~ in =-land?
10:25 danthemyth joined
10:25 bollu joined
10:25 shane joined
10:26 forgottenone joined
10:27 _sg2 joined
10:27 NikolajK left
10:28 Yuras joined
10:28 mtesseract joined
10:29 jomg joined
10:31 MrRicecake joined
10:33 shane joined
10:33 <Gurkenglas_> ie what should I write instead of "l %%= maybe (empty :: MaybeT (StateT S M) ()) pure . f"?
10:34 xormor joined
10:36 <LuciusVorenus> Haskell seems quite mathematical.
10:36 <LuciusVorenus> How do I learn it properly without being a math expert?
10:36 bhiliyam joined
10:36 <Athas> You just treat it as a programming language.
10:36 <mauke> uh, just write code
10:37 <Athas> Only some libraries are described in mathematical terms. Most are just like libraries in any other language.
10:37 zcourts joined
10:37 seveg joined
10:37 <Athas> You just have to treat names like 'Monad' and 'Functor' as APIs, rather than worry about how they map to mathematical concepts.
10:37 Fairy joined
10:41 <tsahyt> is there a deeper reason behind idris being strict by default than "that's what we wanted"?
10:41 <rightfold> tsahyt: ease of implementation
10:41 <tsahyt> I still count that as "that's what we wanted"
10:41 <Athas> SPJ says that the next Haskell will be strict, so maybe that's why!
10:41 <rightfold> Then no
10:41 <tsahyt> Athas: then I'll stick to the current one, as much as I respect spj
10:41 <Athas> To fulfil the prophecy.
10:43 sanett joined
10:43 yellowj joined
10:44 sanett joined
10:45 <tsahyt> Athas: I think it's very very unlikely that Haskell itself will become a strict-by-default language. Laziness is part of the reason why Haskell exists in the first place. it was meant as a research language for purely functional languages with lazy evaluation semantics.
10:45 agjacome joined
10:45 <Athas> tsahyt: right, he was talking about the successor of Haskell.
10:45 <Rodenbach> http://learnyouahaskell.com/for-a-few-monads-more#state shows an example of how to use the state monad. One such snippet is: pop = State $ \(x:xs) -> (x,xs) – Haskell (Intero) complains here and asks me if I mean StateT. Was something renamed since the book was written?
10:45 <Athas> And I think he actually said that it would be strict *by default*, but still support laziness.
10:46 <Athas> I don't think this is a controversial POV. Most people seem to think that some form of parametric strictness will be developed (so a function can be polymorphic in evaluation order).
10:46 <tsahyt> I prefer the opposite
10:46 meoblast001 joined
10:46 <rightfold> Rodenbach: "State s a" is a type alias for "StateT s Identity a"
10:47 <rightfold> And StateT is a data constructor of StateT
10:47 <Rodenbach> I do `import Control.Monad.State` and it tells me that `State` is not in scope.
10:47 <rightfold> The State type or the State constructor?
10:48 <rightfold> Maybe that book was written for an older version of the library.
10:48 <Rodenbach> rightfold: yes, I think Learn you a Haskell was written in 2011.
10:48 <tsahyt> Athas: many people seem to prefer strictness by default, but I've found laziness to be much less of a pain than strictness. I'd rather place a few strictness annotations around my code than litter everything with laziness annotations such that I have to care less.
10:49 <shane> Rodenbach: you probably want just: state
10:49 <tsahyt> which is really the point. I use haskell because I acknowledge my own ineptness.
10:49 <Rodenbach> The book suggests to import Control.Monad.State and then use the State data constructor.
10:49 <tsahyt> laziness allows me to be more lazy most of the time, so to speak
10:49 <rightfold> So you probably want something like "pop = StateT $ \(x : xs) -> pure (x, xs)"
10:49 <shane> instead of State
10:49 <rightfold> Ah yeah, "state"
10:49 <shane> State is only a type alias
10:50 Itkovian joined
10:50 wildlander joined
10:50 <shane> whereas state is StateT specialized to the identity monad
10:50 <tsahyt> e.g. the way I can just dump things out into where bindings, order them in any way I please, etc.
10:50 GreySunshine joined
10:50 Jackneill joined
10:50 <tsahyt> Athas: relevant edwardk post https://www.reddit.com/r/haskell/comments/5xge0v/today_i_used_laziness_for/deia53t/
10:51 wildlander joined
10:51 augur joined
10:52 ysahil joined
10:53 Denthir joined
10:53 fakenerd joined
10:53 <shane> Rodenbach: pop = state $ \(x:xs) -> (x, xs) should also work
10:53 <Rodenbach> Good, thanks.
10:53 <Rodenbach> Yes, works.
10:54 Sampuka_ joined
10:55 zcourts joined
10:56 vaibhavsagar joined
10:57 fotonzade joined
10:57 fotonzade joined
10:59 Icewing joined
11:00 oisdk joined
11:02 tushigushi joined
11:02 <Gurkenglas_> Does System.Eval.Haskell work nowadays? These two machines throw "user error (Use of GHC's environment variable GHC_PACKAGE_PATH is incompatible with Cabal. Use the flag --package-db to specify a package database (it can be used multiple times).)" as a response to 'eval "2+2" []'. (What package do I use for eval?)
11:02 chlong joined
11:02 Fairy joined
11:03 jomg joined
11:04 Iceland_jack joined
11:05 Argue joined
11:05 <GreySunshine> Hello guys, Is there an irc channel or mailing list for emacs's haskell-mode. I could not find anything here (https://wiki.haskell.org/IRC_channel#Related_channels) and the link here is broken (http://projects.haskell.org/haskellmode-emacs/)
11:07 <bollu> jle`: ping
11:09 wei2912 joined
11:10 <Philonous> GreySunshine, #haskell-emacs
11:11 forgottenone joined
11:11 <geekosaur> GreySunshine, projects.haskell.org is the graveyyard, that list shut down in mid-2016
11:11 insitu joined
11:11 <geekosaur> https://github.com/haskell/haskell-mode might be of interest
11:12 <geekosaur> although I see it hs a mailing list link that points to the same graveyard :/
11:12 <geekosaur> I wonder if anyone told them projects.h.o is going away and everything formerly on it is in archive mode
11:13 suds13_ joined
11:14 sillyotter joined
11:16 bjz_ joined
11:19 magneticduck joined
11:20 zar joined
11:22 pwnz0r joined
11:22 sepp2k joined
11:24 forgottenone joined
11:26 adamrbk joined
11:26 Remavas-Hex joined
11:29 seveg joined
11:29 Yuras joined
11:30 Avogadro joined
11:31 teggi joined
11:32 splanch joined
11:33 fakenerd_ joined
11:35 featherlessbiped joined
11:35 fizruk joined
11:35 anuxivm joined
11:35 shayan_ joined
11:36 eklavya joined
11:37 <magneticduck> suppose I wanted to make a datatype representing a process to enumerate values of a type a
11:37 bhiliyam joined
11:37 <magneticduck> a first try would be "data Enumeration a = Enumeration Integer (Integer -> a)"
11:38 <magneticduck> but it would be nice if Enumeration could be Monad-like -- so perhaps I won't always know the length of the enumeration before-hand
11:38 dhil joined
11:39 <magneticduck> and some things are hard to enumerate, so I'd like to use a state machine: so I try "data Enumeration s a = Enumeration s (s -> Maybe s) (s -> a)"
11:39 bennofs joined
11:39 <magneticduck> but this free "s" type isn't important for anything besides the implementation, and it sort of gets in the way
11:40 Yuras joined
11:41 <magneticduck> maybe I'd try "data Enumeration a = Enumeration STATE (STATE -> Maybe STATE) (STATE -> a)" ... but it's inconvenient to have to choose some beforehand "STATE" for all my different enumeration-generating state machines to use
11:41 <magneticduck> what can I do?
11:42 <Philonous> Why not just [a] ?
11:42 <magneticduck> how would you instance Functor or Monad?
11:42 <tsahyt> [] is already a functor and a monad
11:42 biglambda joined
11:43 <magneticduck> oh I misunderstood
11:44 sanett joined
11:45 eacameron joined
11:45 dan_f joined
11:45 <magneticduck> lol
11:46 wei2912 joined
11:47 asmyers joined
11:47 <Philonous> > let fromState s0 nextS fromS = let go s = fromS s : (case nextS s of Nothing -> []; Just s' -> go s') in go s0
11:47 <lambdabot> <no location info>: error:
11:47 <lambdabot> not an expression: ‘let fromState s0 nextS fromS = let go s = fromS s : ...
11:47 <Philonous> > fromState s0 nextS fromS = let go s = fromS s : (case nextS s of Nothing -> []; Just s' -> go s') in go s0
11:47 <lambdabot> <hint>:1:26: error:
11:47 <lambdabot> parse error on input ‘=’
11:47 <lambdabot> Perhaps you need a 'let' in a 'do' block?
11:47 <magneticduck> yes, I see
11:48 <magneticduck> apparently I was trying to implement a lazy Haskell list without lazy Haskell lists
11:48 <hodapp> ML is that way, sir
11:49 acarrico joined
11:49 jao joined
11:50 <magneticduck> hm?
11:51 JagaJaga joined
11:51 <lush> is someone here that knows ContourTrees and may skim a little bit of code to tell me what's wrong about it? :-D
11:52 sanett joined
11:53 eacamero_ joined
11:56 ragepandemic joined
11:56 FALANXXX joined
11:56 coot joined
11:56 <FALANXXX> in haskell, what does it stand for? the variable i mean
11:56 <FALANXXX> 'it'
11:57 sdothum joined
11:57 <magneticduck> "it" is a clever encoding of the word "it"
11:57 <FALANXXX> lol i thought it would be an abbreviation
11:58 <FALANXXX> something like 'last' would have been more verbose
11:58 fizbin joined
11:58 emc2 joined
11:58 <magneticduck> theThing
11:59 <lyxia> in ghci it refers to the previous value
11:59 <lyxia> it doesn't mean anything in particular outside ghci, it is just a variable
12:02 fakenerd joined
12:02 Itkovian joined
12:03 eacameron joined
12:04 nirvinm joined
12:05 indi_ joined
12:06 sanett joined
12:06 sdothum joined
12:07 dram_phone joined
12:07 JuanDaugherty joined
12:08 srbaker joined
12:09 dfordivam joined
12:10 jedws joined
12:10 inkbottle joined
12:11 <lush> any computational topologists here?
12:12 fizbin joined
12:12 <inkbottle> I read '$' is a kind of parenthesis; however "return 3 >>= $ \x -> [x]" raises a parse error.
12:12 <FALANXXX> Okay I get lazy evaluation but can anyone explain this: let x = 1, bindings will show it's bound to _ (not evaluated yet). but even after i evaluate it by typing x in ghci, it remains being bound to _. Am I missing something?
12:13 <Philonous> inkbottle, ($) is a normal function. It's defined as f $ x = f x
12:13 <hpc> inkbottle: ($) is an operator with low precedence, not a syntactic substitute
12:13 <hpc> it has to appear where operators are legal
12:13 <Philonous> inkbottle, It can replace parens because of it's precedence
12:13 <inkbottle> OK
12:13 srbaker joined
12:13 <inkbottle> thx
12:13 oisdk joined
12:14 <FALANXXX> also even it seems to be bound to _.... weird
12:14 thetourist joined
12:14 <FALANXXX> i mean 'it' is bound to _ even after evaluation
12:14 nh2 joined
12:15 nirvinm1 left
12:16 JuanDaugherty left
12:16 fizbin1 joined
12:17 eacameron joined
12:18 mikecheck left
12:18 <alem0lars> is there a commandline arguments parser library that can be used to automatically generate autocomplete functions for known shells (like zsh) ?
12:19 <FALANXXX> Okay I get lazy evaluation but can anyone explain this: let x = 1, bindings will show it's bound to _ (not evaluated yet). but even after i evaluate it by typing x in ghci, it remains being bound to _. Am I missing something?
12:19 <lyxia> FALANXXX: x is going to be polymorphic, of type Num a => a
12:19 <hexagoxel> FALANXXX: _ does not mean "not evaluated yet".
12:20 <FALANXXX> What else does it mean? That was my best bet
12:20 <lyxia> every time you use it, a is newly instantiated, and you get a thunk.
12:21 <FALANXXX> i would just assume x to be bound after i assign it a value and use it
12:22 eacameron joined
12:22 wei2912 joined
12:23 <hexagoxel> FALANXXX: maybe _ is used to signify a polymorphic value, that, due to being polymorphic, has no better representation.
12:23 stef204 joined
12:23 GreySunshine joined
12:23 orbifx joined
12:23 Denthir joined
12:23 Tomsk joined
12:24 <FALANXXX> hexagoxel: that might be. it just seems to be super counterintuitive to make all variable declarations being polymorphic... basically negates the use of bindings
12:24 mtesseract joined
12:24 <* hexagoxel> never knew that :show bindings can indeed return information about a chunk being evaluated or not, interesting.
12:25 <lyxia> FALANXXX: are you perhaps using :sprint, try :sprint
12:26 <lyxia> FALANXXX: Also making all bindings polymorphic by default is also a specificity of GHCi which has -XNoMonomorphismRestriction by default, whereas ghc doesn't.
12:26 <FALANXXX> lyxia: what do you mean, im in ghci i dont verbosely print
12:26 <hexagoxel> wait, after i `:set -XMonomorphismRestriction` the behaviour with let is different? i thought that was the default.
12:27 <FALANXXX> basically i assign x = 1 and afterwards just enter x which assumingly evaluates x
12:27 <lyxia> FALANXXX: :print with a colon in front is a ghci command to show a value without forcing it
12:27 <lyxia> and you get _ ?
12:28 <lyxia> I get 1.
12:28 eacameron joined
12:28 <FALANXXX> https://codepaste.net/fgpf9m
12:28 <FALANXXX> Take a look at it
12:29 <OnkelTem> Hi all
12:29 <OnkelTem> I'm trying to use official docker image of Haskell but I can't compile examples from there. I get the same output as in this [not resolved] issue: https://github.com/freebroccolo/docker-haskell/issues/53
12:30 <lyxia> It is what I said, x being polymorphic with a Num constraint you can't force it further without specializing it first
12:30 <OnkelTem> Any ideas what's wrong?
12:30 <lyxia> which results in a new value
12:31 <OnkelTem> https://github.com/freebroccolo/docker-haskell/tree/master/examples/7.10/snap - here is the source
12:31 danthemyth joined
12:32 <hexagoxel> FALANXXX: maybe you want to `:set -XMonomorphismRestriction` to get monomorphic let-binds by default.
12:33 <hexagoxel> and _ apparently can mean both "unevaluated" and "unevaluated due to being polymorphic", which may be confusing.
12:33 <FALANXXX> hexagoxel: that is confusing indeed! so when i try thing outside of ghci it should work tho?
12:33 eacameron joined
12:34 <lyxia> because under the hood x :: Num a => a is actually a function
12:34 <hexagoxel> ^
12:34 Krymise joined
12:34 <hexagoxel> when you sprint, it defaults, i.e. automatically passes in the Num a dict. but the value returned is still a new thunk every time you do that.
12:35 <hexagoxel> which is unevaluated, even if you have forced a value previously returned from that "function".
12:36 <hexagoxel> you get better behaviour by either setting mmr, which makes it monomorphic by default, or by giving `x` a type signature and making it monomorphic that way.
12:36 <hexagoxel> i.e. let x = 1 :: Int
12:36 unK_ joined
12:36 forgottenone joined
12:37 <hexagoxel> with that definition, the behaviour is what one would expect normally.
12:37 <FALANXXX> hexagoxel: thanks for the type signature i was wondering all the time how you can use these in ghci
12:37 <lyxia> alem0lars: optparse-applicative has a Completer module, I have no idea what it's worth.
12:38 bhiliyam joined
12:38 <FALANXXX> can confirm it works
12:38 eacameron joined
12:40 <hexagoxel> FALANXXX: regarding difference between ghci/ghc: i think MMR is on by default in ghc, so i think it will be less likely to run into unexpected cases of non-sharing.
12:41 dsh joined
12:41 <hexagoxel> outside of ghci that is.
12:42 freusque joined
12:42 silver joined
12:43 Yuras joined
12:43 <laz> alem0lars: https://github.com/pcapriotti/optparse-applicative#bash-completion
12:44 thunderrd joined
12:45 MrRicecake joined
12:46 cbenz[m] joined
12:46 insitu joined
12:49 JeanCarloMachado joined
12:50 MrRicecake joined
12:51 cbenz[m] left
12:52 mkoenig joined
12:53 cpennington joined
12:53 fizbin joined
12:57 crobbins joined
12:58 MrRicecake joined
12:58 chichou joined
12:58 mmo joined
12:59 arquebus joined
12:59 <ysahil> In Haskell, can we use one do inside another do?
12:59 eacameron joined
13:00 forgottenone joined
13:00 insitu joined
13:00 <hexagoxel> > do do do True
13:00 <lambdabot> True
13:00 ccomb joined
13:01 fakenerd joined
13:02 dhil joined
13:02 freusque joined
13:02 oisdk joined
13:03 Elish joined
13:04 srbaker joined
13:05 Mon_Ouie joined
13:05 <mmo> Could somebody please help with creating a Gtk GUI window from an XML file? I have managed to create the XML read it with a builder and grab the mainWindow Object. However the type of the mainWindow seems to be to general to do anything with it. I have no idea how to preceed as I can't find any documentation or tutorial on this. I have the following code:
13:05 <mmo> https://github.com/marcelmoosbrugger/hsudoku/blob/master/src/Hsudoku.hs
13:05 arquebus joined
13:06 koitalel joined
13:07 azahi joined
13:08 eacameron joined
13:09 fizbin1 joined
13:09 <mmo> The window can be grabbed with "Gtk.builderGetObject" but somehow not be converted to a Window with "Gtk.toWindow"
13:09 oisdk joined
13:09 meba joined
13:12 nyuszika7h joined
13:12 nilof joined
13:13 eacameron joined
13:14 <hexagoxel> mmo: with gtk3, there is a `castToWindow` method; with gi-gtk i see GI.Gtk.castTo but it lacks docs..
13:15 mtesseract joined
13:15 <mmo> @hexagoxel: Ok thanks. I'll have a look at it. But what is the intention of "GI.Gtk.Objects.Window.toWindow" then?
13:15 <lambdabot> Unknown command, try @list
13:16 nbro joined
13:17 <mmo> hexagoxel: Ok thanks. I'll have a look at it. But what is the intention of "GI.Gtk.Objects.Window.toWindow" then?
13:18 <hexagoxel> mmo: upcasting from stuff like Dialog, Window, or Assistant, perhaps (in the gtk heirarchy.
13:18 <mmo> Ah ok. Thank you
13:18 <tsahyt> mmo: relevant piece of code from reactive-banana-gi-gtk https://github.com/mr/reactive-banana-gi-gtk/blob/master/reactive-banana-gi-gtk/src/Reactive/Banana/GI/Gtk.hs#L64
13:19 <tsahyt> there's a usage example here https://github.com/mr/reactive-banana-gi-gtk/blob/master/example/app/Main.hs#L48
13:19 eacameron joined
13:19 <tsahyt> I've found castB to be very useful, so you might want to grab that function. the library's license is public domain.
13:21 <mmo> tsahyt: Thanks for the tipp. But besides the missing cast is my way of creating the GUI correct? (I am new to GUIs in Haskell)
13:22 <tsahyt> I think so, I always just go by example files when dealing with GUIs. You'll have to call widgetShowAll (or something like that) to actually show the window.
13:22 Raddamu joined
13:23 pwnz0r joined
13:23 fizbin joined
13:24 sepp2k joined
13:27 eacameron joined
13:29 raichoo joined
13:31 cpup joined
13:33 eacameron joined
13:34 magneticduck joined
13:35 Argue joined
13:38 cpennington joined
13:38 bhiliyam joined
13:39 ebzzry joined
13:40 eacameron joined
13:40 coltfred joined
13:41 `^_^v joined
13:42 N0F4C3_47 joined
13:42 <N0F4C3_47> hello ?
13:43 <cocreature> hey N0F4C3_47
13:43 harfangk joined
13:43 <magneticduck> any quick examples of types that are Applicative but not Monad?
13:44 <cocreature> magneticduck: AccValidation
13:45 <N0F4C3_47> Is this the chaenel haxor ? sorry
13:45 <cocreature> this channel is about the Haskell programming language
13:45 <Theophane> :')
13:46 eacameron joined
13:46 <lyxia> magneticduck: ZipList, Const
13:46 <N0F4C3_47> ohh this chaenel is chaenel programing ?
13:47 <magneticduck> haskell -> hakell -> haker -> haxor
13:47 <N0F4C3_47> yeh i know ?
13:47 zar joined
13:48 <N0F4C3_47> Anyone know the link to download a web template?
13:49 mizu_no_oto joined
13:50 orbifx joined
13:50 TheLemonMan joined
13:50 <Theophane> hey, can someone remind me if (and how) I can use a custom template for `stack new`?
13:50 <tsahyt> Theophane: stack new <projectname> <templatename>
13:51 <tsahyt> see stack templates for names of templates
13:51 ystael joined
13:51 <Theophane> no, I mean
13:51 <Theophane> each time I use haskeleton I tweak some stuff, like the directory names, and stuff
13:52 <Theophane> how I can I tell stack "hey, use this custom template I made, plz"?
13:52 <lyxia> @let newtype I = I (forall a. Num a => a)
13:52 <lambdabot> .L.hs:209:1: error:
13:52 <lambdabot> Multiple declarations of ‘I’
13:52 <lambdabot> Declared at: .L.hs:207:1
13:52 <tsahyt> Theophane: local templates are at ~/.stack/templates
13:52 <lyxia> > I undefined `seq` ()
13:52 <lambdabot> ()
13:52 <Theophane> oh, neat, thanks tsahyt
13:52 theelous3 joined
13:53 eacameron joined
13:53 <cocreature> lyxia: huh, I didn’t expect that. but I also never thought about what happens in this case
13:53 <lyxia> I can understand why that evaluates but still that looks so wrong
13:55 NyanPasu joined
13:55 mmo left
13:57 govg joined
14:00 nh2 joined
14:00 metahumor joined
14:00 <metahumor> hi everyone!
14:01 <metahumor> is this the proper place to ask about GHC build-from-source configs?
14:02 <ongy> there's #ghc aswell, which might be a better shot, but this channel is generally ok for ghc questions
14:02 augur joined
14:02 <metahumor> cool, i'll try here i guess
14:02 <metahumor> i'm trying to get GHC working well (with stack) on Xenial through WSL
14:03 bjz joined
14:03 <ongy> WSL? that's the windows linux layer? Last I checked that didn't implement a required syscall for ghc.
14:03 <metahumor> and am having the 1 TB virtual mem allocation problem. i tried building from source, passing "./configure --disable-large-address-space", but the built GHC still allocs 1TB mem
14:03 <metahumor> i also tried making sure all the "#under USE_LARGE_ADDRESS_SPACE" lines were uncommented in the config.h and config.h.in
14:04 <metahumor> *#undef
14:04 <metahumor> the new Creators Update does implement it
14:04 uglyfigurine joined
14:04 <ongy> oh cool
14:05 zero_byte joined
14:05 mada joined
14:05 bollu joined
14:05 <metahumor> basically, `stack build` anything takes a pretty long time because Windows is unhappy with the large alloc, and I can't seem to figure out how to get the GHC build-from-source to respect "--disable-large-address-space"
14:05 NyanPasu joined
14:06 <metahumor> the GHC I pulled is from the git repo, 8.0.2
14:07 magneticduck joined
14:07 <ongy> erm, afaik that 1TB thing is the allocator that got introduced in 8.0)
14:07 <ongy> https://downloads.haskell.org/~ghc/master/users-guide/8.0.1-notes.html#runtime-system first point here. But I'm not sure how to disable it
14:07 indi_ joined
14:08 thi_ joined
14:08 Shara22 joined
14:08 osa1 joined
14:08 osa1 joined
14:10 <ongy> ah, should be the USE_LARGE_ADDRESS_SPACE. you probably want to complain about that in #ghc then
14:10 mizu_no_oto_work joined
14:11 Shara22 left
14:11 gugah joined
14:13 simukis_ joined
14:14 hc_ joined
14:16 fragamus joined
14:18 oisdk joined
14:19 Gurkenglas__ joined
14:19 Bob8989|2 joined
14:19 hc joined
14:19 zeroed joined
14:22 <metahumor> @ongy here's the WSL bug thread about the underlying issue
14:22 <lambdabot> Unknown command, try @list
14:22 <metahumor> https://github.com/Microsoft/BashOnWindows/issues/1671
14:22 mkoenig joined
14:22 <metahumor> ongy: here's the WSL bug thread about the underlying issue
14:22 <metahumor> i'm trying to find the reddit comments that suggested that build flag
14:23 robotroll joined
14:24 hc joined
14:25 <metahumor> here is the reddit comment: https://www.reddit.com/r/haskell/comments/64ixk6/stack_on_windows_subsystem_for_linux/dg41e6z/?context=10000
14:26 cyborg-one joined
14:26 fizruk joined
14:27 shwouchk joined
14:29 beanbagu1 joined
14:30 beeman joined
14:31 <metahumor> the #ghc channel suggests that the flag might not even fix it, so i'll just fall back to 7.10
14:31 <metahumor> thanks, ongy
14:33 Rodya_ joined
14:33 fotonzade joined
14:34 coltfred joined
14:34 revprez_atlanta joined
14:35 nh2 joined
14:37 Avogadro joined
14:37 nakal joined
14:38 mjhoy joined
14:39 bhiliyam joined
14:42 Arguggi joined
14:42 takle joined
14:42 oisdk joined
14:43 srbaker joined
14:44 SimpleL joined
14:45 takle_ joined
14:47 {emptyset} joined
14:47 pera joined
14:48 dpower joined
14:48 Denthir joined
14:51 greynix joined
14:51 thvu joined
14:53 boombanana joined
14:53 danke joined
14:57 dankeast joined
14:59 <OnkelTem> Hi all
14:59 <Sornaensis> o7
14:59 <OnkelTem> What web framework you'd recommend?
14:59 Denthir joined
14:59 AspiringEngineer joined
14:59 <OnkelTem> I read about snapframework, but isn't it outdated or something?
15:00 <Sornaensis> afaik it isn't
15:01 <Sornaensis> I've only taken a cursory look at it but it seems nice and straightforward. There is also scotty and yesod
15:01 <bennofs> OnkelTem: "Latest commit 5ef3883 16 days ago" https://github.com/snapframework/snap
15:02 <OnkelTem> Ok, I see. The reason why I thought it could be old is pretty naive - they use cabal in their docs
15:03 jship joined
15:03 <OnkelTem> while I was told - use stack
15:03 <Cale> OnkelTem: There are still people using cabal.
15:03 <Sornaensis> I use cabal now and again
15:03 <ertes> OnkelTem: i've never used stack even once
15:03 <OnkelTem> hehe
15:03 <Cale> Of course, meaning cabal install. Stack uses cabal the library.
15:03 <OnkelTem> so cabal is safe! good to know :)
15:04 LAZAR joined
15:04 hurkan joined
15:04 <ertes> to be fully honest i don't even know what problem stack solves
15:04 raycoll joined
15:05 <LAZAR> how do i return a kind of None value in haskell? Like i want to get the last element in a list but the list is empty, what should this return?
15:05 <Sornaensis> stack allows me to build stuff identically on the several systems I use without having to write separate configurations
15:05 <ertes> LAZAR: see Maybe
15:06 <mauke> safeLast :: [a] -> Maybe a
15:06 <LAZAR> ertes: i just ask because even builtin functions like last will not catch this case but throw an Exception instead
15:06 <ertes> LAZAR: yeah, it's an unfortunate historical mistake (at least in my opinion)
15:07 <Sornaensis> you can always install a better prelude
15:07 <Sornaensis> :D
15:07 crosleyt joined
15:07 <LAZAR> i just wonder which way is better, letting it crash (like last) or something else
15:07 <Cale> LAZAR: it really depends how sure you are that the list will be nonempty
15:08 <ertes> > foldr (const . Just) Nothing [1..10]
15:08 <lambdabot> Just 1
15:08 <Cale> and how much you don't care if your program dies if it is
15:08 <Sornaensis> lists should never be empty
15:08 <Sornaensis> D:
15:08 <ertes> > foldl (\_ -> Just) Nothing [1..10]
15:08 <lambdabot> Just 10
15:08 mojjo joined
15:09 <LAZAR> What would be the way to implement such function? Like when i use an if...else to check if the list is empty, what would I return?
15:09 <Sornaensis> :t safeLast
15:09 <lambdabot> error: Variable not in scope: safeLast
15:09 <ertes> LAZAR: first try with explicit recursion
15:09 <ertes> @let safeLast = foldl (\_ -> Just) Nothing
15:09 <lambdabot> Defined.
15:10 <mauke> LAZAR: avoid if/else for now
15:10 <Sornaensis> > safeLast []
15:10 <lambdabot> Nothing
15:10 <mauke> LAZAR: prefer pattern matching
15:10 <Sornaensis> s/ now/ever
15:10 <mauke> shh
15:10 hurkan joined
15:10 Bin4ry joined
15:10 codesoup joined
15:10 meba joined
15:10 jmcarthur joined
15:10 <LAZAR> Wouldnt be Nothing/Maybe a way to circumvent the rule that each expression should evaluate to something?
15:11 dbmikus joined
15:11 <ertes> LAZAR: Nothing is a something
15:11 <ertes> ironically enough
15:11 <Sornaensis> Maybe values are still values
15:11 <Sornaensis> exceptions are weird magic
15:11 eklavya joined
15:11 Denthir joined
15:11 <Sornaensis> :t error
15:11 <lambdabot> [Char] -> a
15:11 <ertes> LAZAR: the names don't really matter… Maybe is just another type you could have defined yourself: data Maybe a = Nothing | Just a
15:12 takle joined
15:12 <ertes> like a list type with at most one element
15:12 dankeast joined
15:12 minn joined
15:12 dbmikus joined
15:12 <ertes> data List a = Nil | Cons a (List a) -- in Maybe the latter, recursive field of Just is not there
15:12 osa1_ joined
15:13 <ertes> LAZAR: regarding what mauke said about avoiding 'if' you can read the first half of this subsection: LAZAR: read the first half of this section: http://ertes.eu/tutorial/foldr.html#heads-tails-and-a-digression
15:13 <ertes> whoops… too much copy/paste =)
15:14 halogenandtoast joined
15:14 <halogenandtoast> I can't figure out why this is wrong: fmap (map fst) . fmap (sortOn snd) . zip <$> getRandoms) <*> [1,2,3]
15:14 <halogenandtoast> Can anyone point me in the first direction
15:14 dbmikus joined
15:15 <halogenandtoast> Sorry the easier to read version: (fmap (map fst. sortOn snd) . zip <$> getRandoms) <*> [1,2,3]
15:16 <halogenandtoast> :t (fmap (map fst. sortOn snd) . zip <$> getRandoms)
15:16 <lambdabot> error:
15:16 <lambdabot> Variable not in scope: getRandoms :: f [b]
15:16 Geesee left
15:16 <metahumor> halogenandtoast: what are you trying to do?
15:16 SimpleL joined
15:16 Micamo joined
15:16 <halogenandtoast> metahumor: shuffle
15:16 <halogenandtoast> I know there are other ways
15:16 <ertes> halogenandtoast: what's the type of getRandoms?
15:16 <metahumor> @let getRandoms :: MonadRandom m => m [a]
15:16 <lambdabot> .L.hs:210:1: error:
15:16 <lambdabot> The type signature for ‘getRandoms’ lacks an accompanying binding
15:16 <lambdabot>
15:17 <metahumor> @let getRandoms :: MonadRandom m, Applicative m => m [a]
15:17 <lambdabot> Parse failed: Parse error: ,
15:17 <ertes> halogenandtoast: that's not quite the same type as [1,2,3]
15:17 <halogenandtoast> @import System.Random
15:17 <lambdabot> Unknown command, try @list
15:17 <metahumor> @let getRandoms :: (MonadRandom m, Applicative m) => m [a]
15:17 <lambdabot> .L.hs:210:1: error:
15:17 <lambdabot> The type signature for ‘getRandoms’ lacks an accompanying binding
15:17 <lambdabot>
15:17 <ertes> halogenandtoast: unless there is some OverloadedLists magic going on
15:17 <ertes> you're mixing up two applicative functors
15:17 <halogenandtoast> ertes: the type before <*> is (Random b, MonadRandom f, Ord b1) => f ([b1] -> [b])
15:17 <ertes> also the pattern (fmap f . zip) looks suspicious
15:18 <halogenandtoast> I'm just trying to play with the Random monad so I don't have to pass StdGen all the way down
15:18 <bennofs> :t \f -> fmap f . zip
15:18 <lambdabot> ([(a, b)] -> b1) -> [a] -> [b] -> b1
15:18 <bennofs> looks good to me
15:18 <ertes> halogenandtoast: are you trying to use (<*>) with the m functor or the list functor?
15:18 <metahumor> :t (((fmap fst) . (sortBy snd) . zip) <$> _)
15:18 <ertes> bennofs: not wrong, just suspicious
15:18 <halogenandtoast> ertes: with Rand
15:18 <bennofs> halogenandtoast: I think you want pure [1,2,3] instead of [1,2,3]
15:18 <lambdabot> error:
15:18 <lambdabot> • Couldn't match type ‘[b0] -> [(a0, b0)]’ with ‘[(a, b1)]’
15:18 <lambdabot> Expected type: [a0] -> [(a, b1)]
15:18 <ertes> halogenandtoast: then you probably want (pure [1,2,3])
15:18 <halogenandtoast> ertes: you're correct
15:18 <metahumor> yeah
15:19 <halogenandtoast> (fmap (map snd . sortOn fst) . zip <$> getRandoms) <*> pure [1,2,3]
15:19 dankeast left
15:19 <halogenandtoast> is what I wanted
15:19 cdg joined
15:19 <ertes> halogenandtoast: as a side note the mwc-random library has a very efficient shuffling function predefined
15:19 <metahumor> just my ignorance, why are there two levels of fmap?
15:19 <halogenandtoast> ertes: yeah I just wanted to play with the random monad
15:20 <halogenandtoast> :t fmap
15:20 <lambdabot> Functor f => (a -> b) -> f a -> f b
15:20 <halogenandtoast> :t (fmap . fmap)
15:20 <lambdabot> (Functor f, Functor f1) => (a -> b) -> f1 (f a) -> f1 (f b)
15:20 crobbins joined
15:20 <halogenandtoast> f1 = Rand, f = []
15:20 <metahumor> ah gotcha
15:20 <bennofs> metahumor: fmap f . g = pattern to compose f after two-arg g
15:20 <ertes> halogenandtoast: https://hackage.haskell.org/package/mwc-random-0.13.5.0/docs/System-Random-MWC-Distributions.html#g:5
15:20 hiredman joined
15:21 <halogenandtoast> ertes: cool, is that better than https://hackage.haskell.org/package/random-shuffle-0.0.4/docs/System-Random-Shuffle.html
15:21 <ertes> halogenandtoast: most likely
15:21 <halogenandtoast> is seems like there are more fancy words on your page
15:21 <ertes> almost certainly in fact
15:21 <halogenandtoast> PrimMonad, MVector, PrimState
15:22 <ertes> halogenandtoast: whenever you see an 'm' with a PrimMonad context, think of it as IO or (ST s)
15:22 <ertes> it's just a way to abstract over such "primitive monads"
15:22 nagyf joined
15:22 <halogenandtoast> Those sentences don't help me yet.
15:22 <halogenandtoast> I mean I "kind of" get it
15:23 <ertes> uniformShuffleM :: (Unbox a) => Vu.MVector s a -> Gen s -> ST s ()
15:24 <ertes> where: import qualified Data.Vector.Unboxed.Mutable as Vu
15:24 fotonzade joined
15:24 <Sornaensis> what is ST
15:24 <Sornaensis> and why do I feel like I need an adult
15:24 <halogenandtoast> But that function returns ST s () I assume I want a returned no?
15:24 <ertes> it abstracts over both the PrimMonad and the exact vector type (boxed, primitive, storable, unboxed vectors)
15:25 <ertes> mwc-random is an effectful library, unlike 'random'
15:25 nomicflux joined
15:25 <ertes> so you always use it in the context of some primitive monad
15:25 <ertes> you can still use it purely by using ST, but the actual generation of random numbers will be ST-effectful
15:26 descender joined
15:26 <ertes> Sornaensis: ST is a way to write a value using effects that are not observable from outside
15:27 <ertes> Sornaensis: for example you can use a mutable random number generator with a fixed seed, so the actual result is deterministic and does not depend on observable effects like reading a file
15:27 <halogenandtoast> Ha, the entire reason why I couldn't get my code to work earlier (mainly because I'm tired) is I went to hoogle and searched for "f (a -> b) -> a -> f b" and the first "result" was <*>
15:28 <halogenandtoast> and I used it without thinking
15:28 <ertes> > runST (do v <- newSTRef 5; modifySTRef v (+ 5); readSTRef v)
15:28 <lambdabot> 10
15:28 <halogenandtoast> without realizing it wasn't the same type signature that I had searched.
15:28 <ertes> Sornaensis: ^
15:28 uuplusu joined
15:29 Wedamm joined
15:29 takle joined
15:29 meba joined
15:30 <ertes> Sornaensis: unlike a state monad this one doesn't emulate mutable state using functions, but it does in fact use mutable variables and in-place update
15:30 <Sornaensis> neat
15:30 <halogenandtoast> ertes: that sounds terrible
15:30 <ertes> like a restricted subset of IO (it *is* in fact a restricted subset of IO)
15:30 <Sornaensis> is that easier than using state for rng
15:31 <ertes> Sornaensis: i would rather not compare them… they have some overlap in utility, but not much
15:31 <ertes> > evalState (state (randomR (0, 9))) (mkStdGen 50)
15:31 <lambdabot> 1
15:32 <ertes> > evalState (let c = liftA2 (:) (state (randomR (0, 9))) c) (mkStdGen 50)
15:32 <lambdabot> <hint>:1:57: error: parse error on input ‘)’
15:32 <ertes> > evalState (let c = liftA2 (:) (state (randomR (0, 9))) in c) (mkStdGen 50)
15:32 <lambdabot> error:
15:32 <lambdabot> • Couldn't match type ‘f0 [Integer] -> f0 [Integer]’
15:32 <lambdabot> with ‘StateT StdGen Identity a’
15:32 <ertes> > evalState (let c = liftA2 (:) (state (randomR (0, 9))) c in c) (mkStdGen 50)
15:32 <lambdabot> [1,9,0,8,9,9,3,3,1,8,8,7,3,4,2,7,7,2,0,0,0,3,0,4,3,2,3,1,9,8,4,3,7,6,3,5,9,6...
15:32 <ertes> sorry for the noise
15:34 gleber_ joined
15:35 stphrolland joined
15:35 <ertes> for example you can use StateT as a utility with lenses, something that ST would handle rather poorly
15:35 <Sornaensis> > evalState (let c = liftA2 (:) (state (randomR (0,9))) c in c) (mkStdGen 50)
15:35 <lambdabot> [1,9,0,8,9,9,3,3,1,8,8,7,3,4,2,7,7,2,0,0,0,3,0,4,3,2,3,1,9,8,4,3,7,6,3,5,9,6...
15:35 <Sornaensis> > evalState (let c = liftA2 (:) (state (randomR (0,9))) c in c) (mkStdGen 51)
15:35 <lambdabot> [5,5,2,7,7,9,6,6,0,8,8,2,6,5,4,5,7,3,1,2,4,6,0,3,6,4,1,5,9,5,3,8,0,1,6,7,1,7...
15:36 <Sornaensis> I forgot that mkStdGen was pure
15:36 <ertes> :t mkStdGen
15:36 <lambdabot> Int -> StdGen
15:36 cpennington joined
15:36 <halogenandtoast> huh really?
15:36 <halogenandtoast> :t newStdGen
15:36 <lambdabot> IO StdGen
15:36 <halogenandtoast> Ah I see
15:36 <Sornaensis> :t mkStdGen
15:36 <lambdabot> Int -> StdGen
15:36 <Sornaensis> :P
15:37 <halogenandtoast> It's pure, but useless :p
15:37 <ertes> newStdGen is just an abstraction over mkStdGen to fetch the seed from system sources
15:37 markasoftware joined
15:37 minn joined
15:38 <ertes> no, not useless… you can use it in cases where fixed seeds don't matter like primality testing, or where they can be even beneficial like test suites
15:38 <ertes> or anything where you need to be able to reproduce
15:38 <Sornaensis> primality testing random numbers? or using random numbers?
15:38 w4and0er96 joined
15:38 <ertes> some primality tests like the common millar-rabin test use randomness
15:39 <halogenandtoast> ertes: I was mostly kidding
15:39 <stphrolland> Hi, is there something existing that given two Maybe Bool, or even a list of Maybe Bool, would short-circuit if any Nothing is present, or perform a 'all' if all value are Just. ?
15:39 <LAZAR> How can I write a function that doubles any number regardless of whether its a double or an integer?
15:39 <rightfold> World generation in games is more fun if reproducible
15:39 <ertes> LAZAR: (2 *)
15:39 <Sornaensis> :t (2*)
15:39 <lambdabot> Num a => a -> a
15:39 <Sornaensis> polymorphism is a hell of a drug
15:39 <rightfold> stphrolland: and (== Just True)
15:40 <ertes> stphrolland: something like asum?
15:40 <rightfold> Or maybe it's called all
15:40 bhiliyam joined
15:40 <ertes> > asum [Just 1, Just 2, Nothing, Just 3]
15:40 <lambdabot> Just 1
15:40 <LAZAR> ertes: how is thissignature composed? where is the argument?
15:40 <ertes> ah, no
15:41 <Sornaensis> isn't that just applicative?
15:41 <stphrolland> i like the and (== Just True), it's so straigthforward... i'm ashamed ;-)
15:41 <ertes> :t traverse guard
15:41 <lambdabot> (Alternative f, Traversable t) => t Bool -> f (t ())
15:41 <bennofs> stphrolland: it's `all (== Just True)` actually
15:41 <bennofs> but same idea
15:41 trism joined
15:41 <rightfold> > map (all (== Just True)) [ [Just True, Nothing], [Just True, Just False], [Just True, Just True] ]
15:41 <lambdabot> [False,False,True]
15:42 Rodya_ joined
15:42 <ertes> > fmap (maybe False (const True)) . traverse guard $ Nothing : repeat (Just True)
15:42 <lambdabot> error:
15:42 <lambdabot> • Couldn't match expected type ‘Maybe Bool’
15:42 <lambdabot> with actual type ‘[Maybe Bool]’
15:42 srbaker joined
15:42 Argue_ joined
15:42 <ertes> > maybe False (const True) . traverse_ guard $ Nothing : repeat (Just True)
15:42 <lambdabot> error:
15:42 <lambdabot> • Couldn't match type ‘Maybe Bool’ with ‘Bool’
15:42 <lambdabot> Expected type: [Bool]
15:43 bodisiw joined
15:43 <ertes> :t maybe False (const True) . traverse_ guard
15:43 <lambdabot> Foldable t => t Bool -> Bool
15:43 <LAZAR> So when I have a function double = 2*, what would the Signature be? double :: (Num a) -> a?
15:43 <ertes> :t maybe False (const True) . traverse_ (>>= guard)
15:43 <lambdabot> Foldable t => t (Maybe Bool) -> Bool
15:44 <ertes> > maybe False (const True) . traverse_ (>>= guard) $ Nothing : repeat (Just True)
15:44 <lambdabot> False
15:44 <rightfold> LAZAR: Num a => a -> a
15:44 <ertes> stphrolland: but yeah, just use 'all (== Just True)'
15:44 <LAZAR> ertes: what does the => mean in this context?
15:44 <LAZAR> Looks like a 2 param function at first glance
15:45 <bennofs> ertes: that is... complicated
15:45 <ertes> LAZAR: it's a function of type (a -> a), where there is an instance (Num a), such that you can use (*) :: a -> a -> a
15:45 <mauke> LAZAR: the parens are not optional. it's (2 *)
15:45 <bennofs> ertes: maybe False and . sequence I could understand
15:45 <ertes> bennofs: i'm just playing around
15:45 <mauke> LAZAR: in general, the => separates class constraints from the rest of the type
15:45 <ertes> :t traverse_ (>>= guard)
15:45 <lambdabot> (Alternative f, Monad f, Foldable t) => t (f Bool) -> f ()
15:46 <ertes> bennofs: takes a list of actions and, if they result, passes their results to 'guard'
15:46 <ertes> the (>>=) takes care of handling Nothing, while 'guard' takes care of False
15:48 Krymise joined
15:48 Destol joined
15:48 connrs joined
15:49 <halogenandtoast> where does guard come from?
15:49 <Sornaensis> > map (fmap and . sequence) [ [Just True, Just False], [Nothing, Just True]]
15:49 <lambdabot> [Just False,Nothing]
15:49 insitu joined
15:49 mtesseract joined
15:49 minn joined
15:49 <Taneb> halogenandtoast, it lives in Control.Monad
15:50 <halogenandtoast> thanks Taneb
15:50 <mauke> @hoogle guard
15:50 <lambdabot> Control.Monad guard :: (Alternative f) => Bool -> f ()
15:50 <lambdabot> Monad guard :: Alternative f => Bool -> f ()
15:50 <lambdabot> Web.Simple.Controller.Trans guard :: Monad m => Bool -> ControllerT s m a -> ControllerT s m ()
15:50 urodna joined
15:50 JoshS joined
15:50 math932 joined
15:50 <halogenandtoast> mauke: yeah I asked, then realized I should hoogle
15:51 <Sornaensis> > sequence $ [Nothing] ++ [Just x | x <- [1..]]
15:51 <halogenandtoast> although lately it's been letting me down
15:51 <lambdabot> Nothing
15:51 <math932> What's the advantage of writing add :: (Int, Int) -> Int before writing add (x, y) = x + y? It works perfectly without that. Why would I specify the types?
15:51 <Sornaensis> it's neat how laziness allows you to test short circuiting
15:52 <mauke> halogenandtoast: there's also hayoo
15:52 <Sornaensis> math932: it's good form for top level definitions
15:52 <Sornaensis> allows people who are reading your code to see the types, not just the compiler
15:52 moth joined
15:52 <mauke> math932: it helps human readers, and it helps you get better error messages
15:52 <Sornaensis> mauke: also those are not the same
15:52 <math932> Sornaensis: I see. But then I could as well have written a comment, right?
15:52 <Sornaensis> + will work for any Num
15:53 <Sornaensis> add :: Num a => (a, a) -> a would be equivalent
15:53 <Sornaensis> math932: no because comments are not type checked
15:53 <Sornaensis> meaning they can lie
15:54 <mauke> math932: when you have a type error in your program, the compiler can tell things don't fit together, but it doesn't know what you intended to write
15:54 <math932> mauke: I see :)
15:54 <mauke> i.e. the compiler might infer a type you didn't want for your function, which then leads to weird errors elsewhere
15:54 <ertes> LAZAR: in haskell the notation (2 *) is short-hand for (\x -> 2 * x)
15:55 <ertes> so (2 *) is an actual function
15:55 <ertes> > (2 *) 5
15:55 <lambdabot> 10
15:55 osa1_ joined
15:55 <LAZAR> ertes: lol then it makes a bit more sense... i thought the argument went missing
15:55 gcross_ joined
15:56 <LAZAR> why is it sometimes necessary to write \x instead of plain x for the left side value?
15:56 <ertes> LAZAR: kind of… the argument is not missing, but actually abstracted over =)
15:56 <ertes> you always write "\x" to introduce a lambda
15:56 <mauke> \PARAMETERS -> BODY is the syntax for functions
15:57 <ertes> math932: think of type signatures as formal comments =)
15:57 <ertes> comments that both humans *and* the compiler can understand
15:57 <math932> ertes: Yeah :)
15:57 <LAZAR> mauke: wait why does it work without the backslash then? i can write a function definition with f x y = x + y
15:58 <ertes> math932: they are very often better than comments in prose… so much so that i sometimes have difficulty writing documentation for my code where i don't sound like a parrot
15:58 <ertes> because i find myself just repeating what the type signature already says in a more useful way
15:58 <math932> :D
15:59 <mauke> LAZAR: that's just syntactic sugar for f = \x y -> x + y
15:59 <mauke> LAZAR: which happens because there's more than one symbol on the left side of =
15:59 alx741 joined
15:59 <math932> ertes: I found some slides, where they mention length :: [a] -> Int as an example of a polymorphic function, but isn't this only a type signature? I mean, I couldn't use this, could I?
15:59 <math932> If I wanted to try it?
16:00 <qmm> i have never heard of Equal before. it was called a a lower-order abstraction similar to a semigroup or a monoid
16:00 <qmm> what is it?
16:00 <ertes> math932:
16:00 <ertes> > length [1..5]
16:00 <lambdabot> 5
16:00 <ertes> > length "hello world"
16:00 <lambdabot> 11
16:00 <math932> So basically, they add a type signature to a built-in length function?
16:00 <Sornaensis> Monoid under equality of terms?
16:01 <Sornaensis> @hoogle Equal
16:01 <math932> Or how does it know what length is?
16:01 <lambdabot> Graphics.Rendering.OpenGL.GL.PerFragment Equal :: ComparisonFunction
16:01 <lambdabot> Agda.Syntax.Concrete Equal :: Range -> Expr -> Expr -> Expr
16:01 <lambdabot> Data.SBV.Internals Equal :: Op
16:01 <math932> We didn't tell?
16:01 <ertes> math932: it's not "built in" the way you think it is… it's defined in haskell as a regular library function
16:01 <Sornaensis> wait that don't make sense
16:01 <math932> > length [False, True]
16:01 <lambdabot> 2
16:01 <math932> > length [1, 2, 3, 4]
16:01 <lambdabot> 4
16:01 <ertes> math932: in fact only few things in haskell are built in compared to other languages
16:01 <math932> Hm... so do I modify the library function by this type signature?
16:01 splanch joined
16:01 <Sornaensis> math932: do you know how pattern matching works?
16:02 <mauke> math932: no, the type signature is just added for clarity
16:02 <math932> Sornaensis: Well, I have seen a few examples, but I only started learning yesterday :)
16:02 <Sornaensis> ah ok
16:02 <mauke> that's its normal type
16:02 <ertes> math932: there is a utility module called Prelude that is imported implicitly, which gives you, among many other things, 'length'
16:02 <Sornaensis> most everything in haskell revolves around the concept of pattern matching
16:02 <math932> But isn't 'length' already polymorphic? Or did it become polymorphic because I did this?
16:02 <ertes> math932: it's as if you had written "import Prelude" in every module you write
16:02 <math932> Yeah :)
16:03 <Sornaensis> you can match any data type in haskell with its constructors
16:03 <ertes> math932: it was already polymorphic, because it has a type variable in its type
16:03 <ertes> 'id' is also polymorphic
16:03 <ertes> :t id
16:03 <lambdabot> a -> a
16:03 <Sornaensis> > (\(a:_) -> a) [3,4,5]
16:03 <lambdabot> 3
16:03 <ertes> math932: also the type you gave is a bit of a lie in modern haskell =)
16:03 <ertes> :t length
16:03 <lambdabot> Foldable t => t a -> Int
16:03 <Sornaensis> (:) is actually the `[a]` data type constructor
16:03 <ertes> that's the actual type
16:03 <ertes> > length (Just 5)
16:03 <lambdabot> 1
16:04 <math932> Haha :P
16:04 <ertes> incoming WAT – seemingly
16:04 <ertes> > length (1, 2)
16:04 <lambdabot> 1
16:04 <ertes> it's not really a WAT, because there is a logical reason why the length of a tuple is 1, but ignore that for now =)
16:05 <mauke> > length (length, length, [length, length])
16:05 <lambdabot> error:
16:05 <lambdabot> • No instance for (Foldable ((,,) (t0 a0 -> Int) (t1 a1 -> Int)))
16:05 <lambdabot> arising from a use of ‘length’
16:05 {emptyset} joined
16:05 <mauke> clearly
16:05 arw joined
16:05 <math932> :D
16:06 sz0 joined
16:06 <math932> @let second xs = head (tail xs)
16:06 <lambdabot> Defined.
16:06 <math932> second [1..5]
16:06 <math932> > second [1..5]
16:06 <lambdabot> error:
16:07 <lambdabot> Ambiguous occurrence ‘second’
16:07 <lambdabot> It could refer to either ‘Control.Arrow.second’,
16:07 <math932> Hm...
16:07 <mauke> @undefine
16:07 <lambdabot> Undefined.
16:07 <ertes> math932: use a different name
16:07 <mauke> better, don't use @let
16:07 <math932> Why?
16:07 <mauke> > let second xs = head (tail xs) in second [1..5]
16:07 <ertes> because lambdabot
16:07 <lambdabot> 2
16:07 bennofs1 joined
16:07 <mauke> because then you don't run into conflicts with existing functions
16:07 <ertes> (it has Control.Arrow imported, which has a function of the same name)
16:07 <Sornaensis> > e
16:07 <lambdabot> e
16:07 raf_ joined
16:08 <math932> http://i.imgur.com/xo4Ww8N.png - I was just trying to understand what each of these functions did (slides from an archived MOOC) :)
16:08 <math932> Some of them are fairly obvious though.
16:08 <math932> Most of them actually.
16:08 ragepandemic joined
16:08 <ertes> math932: you can use @let if you want, but the namespace of lambdabot is polluted by lots of imports
16:09 <raf_> how can I install the Haskell platform on mac in a custom directory (e.g in my home directory)?
16:09 <math932> Oh
16:09 <math932> So...
16:09 <math932> > second xs = head (tail xs)
16:09 <lambdabot> <hint>:1:11: error:
16:09 <lambdabot> parse error on input ‘=’
16:09 <lambdabot> Perhaps you need a 'let' in a 'do' block?
16:09 <math932> Better?
16:09 <math932> Hm. No?
16:09 <mauke> math932: see my example above
16:09 <math932> I still need to rename it?
16:09 eazar001 joined
16:09 <ertes> no, 'let' bindings shadow other names
16:09 <ertes> > let x = 5 in x + x
16:09 <lambdabot> 10
16:09 <ertes> even x is predefined in lambdabot =)
16:10 <Sornaensis> > (\0.3 -> True) 0.3
16:10 <math932> Oh.
16:10 <lambdabot> True
16:10 <Sornaensis> > (\0.3 -> True) (0.1 + 0.2)
16:10 <lambdabot> *Exception: <interactive>:3:2-13: Non-exhaustive patterns in lambda
16:10 <glguy> > 0.3 == 0.1 + 0.2
16:10 <math932> > let second xs = head (tail xs)
16:10 <lambdabot> False
16:10 <lambdabot> <no location info>: error:
16:10 <lambdabot> not an expression: ‘let second xs = head (tail xs)’
16:10 <ertes> but by using 'let' the outer 'x' is invisible ("shadowed") in the 'in' part
16:10 <math932> Haha. Oh, well...
16:10 Sonolin joined
16:10 <mauke> > (\0.3 -> True) (0.1 + 0.2 :: Rational)
16:10 <lambdabot> True
16:10 <ertes> math932: see mauke's example
16:10 <math932> But I guess it's supposed to return the second element in a list?
16:10 <Sornaensis> n, n
16:10 <mauke> math932: see my example above
16:11 <math932> [18:07] <mauke> > let second xs = head (tail xs) in second [1..5]
16:11 <math932> Oh, like this?
16:11 <mauke> yes
16:11 <ertes> math932: yeah: let DEFINITIONS in EXPRESSION
16:11 <mauke> :t let second xs = head (tail xs) in second
16:11 <lambdabot> [a] -> a
16:11 indi_ joined
16:11 <mauke> you can directly ask lambdabot for the type
16:13 Krymise joined
16:14 anRch joined
16:14 fotonzade joined
16:14 <math932> Nice :)
16:15 <math932> Thanks!
16:15 <ertes> math932: if these weren't already recommended to you, i highly recommend that you use these lecture notes: https://www.seas.upenn.edu/~cis194/spring13/lectures.html
16:15 augur joined
16:16 <ertes> math932: they have a good balance between explanations and exercises
16:16 <math932> Thanks, ertes :)
16:17 paroxp joined
16:17 RoyalNightGuard joined
16:18 <ertes> perhaps the only problem i have with it is the very late introduction of IO
16:19 <Sornaensis> meh the cool thing about haskell is you can learn so much before you even get to hello world
16:19 emmanuel_erc joined
16:20 <ertes> hello world? fac 0 = 1; fac n = n * fac (n - 1) -- you mean this?
16:20 <maerwald> ertes: I've thought about that too, but I don't see a reasonable way of introducing it earlier without falling back to metaphors and white lies
16:21 vaibhavsagar joined
16:22 <ertes> maerwald: i generally introduce syntax, basic types and polymorphism, then go straight to IO, because i found it beneficial to give beginning developers the tools to write interesting programs
16:22 <ertes> it has worked out very well so far
16:23 <ongy> ertes: how big are your groups?
16:23 <maerwald> without having introduced monads?
16:23 <ertes> ongy: 5-10 people
16:23 <math932> https://pastebin.com/bVKtyVPe - anyone who can spot the error here? :)
16:23 jeltsch joined
16:24 <ertes> maerwald: yeah, i do introduce (>>=) and 'pure' with specialised types (with a disclaimer that it's actually more general, "but ignore that for now, we'll revisit that")
16:24 <ongy> yea, that's a bit different than a lecture. I think for a lecture doing a lot of stuff, before IO makes kinda sense, but for teaching a few people IO early makes more sense (since questions can be handled reasonable well)
16:24 dhil joined
16:24 <ertes> math932: abs -42 = abs - 42
16:24 sleffy joined
16:24 <ertes> math932: abs (-42) = abs (negate 42)
16:24 jomg joined
16:25 <math932> Oh, brackets...
16:25 <math932> :D
16:25 <ertes> ongy: yeah, my workshops are usually more focussed than a generic lecture
16:25 <ertes> also i generally have *much* less time
16:25 <math932> Thanks, ertes
16:25 <ongy> 2nd difference. volunteers. It's easier to introduce "hard" (or rather weird) concepts with people that want to learn. Lecture should first grab attention, then do that
16:26 Rodya_ joined
16:26 <ertes> another important difference is that i can't exhaust the attention span of my attendees
16:26 bodisiw joined
16:26 <ongy> I don't quite know how to parse that. Do they have a longer span than what your time, or do you think you should not do that?
16:27 SimpleL joined
16:27 <ertes> ongy: i lure them in with a specific goal like "we're gonna write a game" or "we're gonna write a web app"
16:27 <ertes> then i have 9-12 hours to do that =)
16:27 <Sornaensis> oh
16:28 <Sornaensis> yea well that makes sense
16:28 <ertes> if the only thing they see for the first six hours is equations and type errors, i lose them
16:28 <ongy> write a game in 12h? And you get more than pong done?
16:28 <Sornaensis> do you do live coding
16:28 <Sornaensis> or do you come with something prebuilt
16:29 <Sornaensis> or both
16:29 <ertes> ongy: no, of course not
16:29 eklavya joined
16:29 <ertes> Sornaensis: everything is live
16:29 <ertes> i don't even have slides… all i have is an emacs org-file with a loose agenda =)
16:30 <ongy> I think I would have prefered that to the way I learned haskell. But lectures just give way different boundaries
16:30 <ertes> lectures can be slower-paced and much more in-depth
16:30 <Sornaensis> I would have preferred learning haskell from someone who knew it well
16:30 meba joined
16:30 oisdk joined
16:30 <ertes> and they can have a strict agenda as well
16:30 <Sornaensis> my uni prof was like taking the course with us so many people lost interest
16:31 ziocroc joined
16:31 <ongy> mandatory course for me :)
16:31 <ongy> not haskell, but functional programming. And I got lucky (I guess? I haven't tried anything new except rust since then)
16:32 <ertes> i think the most important aspect to keep your audience interested is playfulness… haskell is a tool to do fun stuff
16:32 beeman joined
16:32 mazeinmaze_ joined
16:32 <ertes> for some people the fun is in the math, but for others it's the result that matters =)
16:32 <ertes> for them haskell is just a tool… a unique tool, but a tool nonetheless
16:33 <ongy> I have fun with the type system
16:34 mtesseract joined
16:35 <ertes> ironically i have more fun with haskell in a workshop that is completely unrelated to haskell: a crypto workshop
16:35 beanbagula joined
16:36 <ertes> lens-based manipulation of a piece of text is always worth a few jaw drops… "what tool are you using?! it's amazing!" – "oh, it's just a programming language… it's called haskell"
16:36 <ongy> he. I was playing around with wrapping the linux crypto api (socket stuff) in haskell. Abstracting common things is hard in this area
16:37 eklavya joined
16:37 jgt joined
16:38 <ertes> i would like to see a working, maintained binding to NaCl or libsodium
16:39 <ongy> the state of crypto wrappers on hackage is scary. but I have a few things that I think should be done, that may be stupid
16:39 Camm joined
16:39 <sm> ertes, agreed on playfulness! It's easy to lose that in the haskell swamps
16:40 <jgt> hey folks, I have two lists of ByteStrings, and I'd like to find the common elements of the two lists. I know there is Data.List.intersect, but is that the most efficient way? My first list has ~55,000 elements. My second list has ~766,000 elements. It's taking a bit too much time to compute the result.
16:41 bhiliyam joined
16:41 <Sornaensis> ertes: lens operations on strings?
16:41 <Camm> Hello everyone. I've been reading the Typeclassopedia and it talks a lot about context and containers. I understand that containers are something that holds a value, for instances, data types like List and Maybe. However, I don't really understand what a context is. And why some people, somethimes says the context of List or the context of Maybe. Are they contexts too? why?
16:41 tathougies joined
16:41 <ertes> jgt: if the lists are sorted, you can write a fairly efficient intersection function… if not, use Data.Set
16:41 <ertes> Sornaensis: on Text actually
16:42 zeroed joined
16:42 zeroed joined
16:42 beeman joined
16:42 <Sornaensis> ertes: ah
16:42 <ertes> Camm: "context" is nothing formal really… we say stuff like: "(>>=) in the context of Maybe" to mean the semantics of (>>=) of the (Monad Maybe) instance
16:43 ragepandemic joined
16:43 dan_f joined
16:45 <ertes> Camm: it's easiest to ignore the informal terminology and focus on semantics
16:45 <Cale> A context is the thing which occurs to the left of a => at various places in the syntax, but that's probably not how they meant it.
16:46 negatratoron joined
16:46 nakal_ joined
16:46 <Cale> However, I too have trouble figuring out what people mean by "context" when they're talking about monads, it seems to stem from a way of thinking that's foreign to me.
16:47 <ertes> Camm: some older monad tutorials use the word "context" to abstract over things like "computation" and "container"… in essence they are trying to rename "Monad" to something else… i don't know if the typeclassopedia is doing it, but it's still a metaphor, and metaphors don't work here
16:47 <alanz> I regard "context" in this sense to mean whatever it is for the concrete version you are talking about.
16:47 Bin4ry joined
16:49 <LAZAR> Can someone tell me what is wrong with my function? Just a hint would be fine https://codepaste.net/szgrfm
16:49 systemfault joined
16:50 <ysahil> I have a function(say G(x)) which returns IO Text and Another Function (say F(X)) which takes Text. Can anyone Suggest how can we compose (F(G(X))???
16:50 minn joined
16:50 <ertes> ysahil: fmap
16:50 <ertes> fmap :: (a -> b) -> IO a -> IO b
16:50 shazow1 joined
16:50 <mauke> LAZAR: why do you think something's wrong?
16:51 <LAZAR> mauke: the output is wrong for numbers > 100
16:51 <mauke> LAZAR: your function should be recursive but it isn't
16:51 pringlescan joined
16:51 shwouchk joined
16:51 <Cale> Did you read the error that the compiler gave?
16:52 <Cale> oh, it didn't give an error :)
16:52 <Cale> Because you didn't just have this function sitting around
16:52 <ertes> not all wrong programs are ill-typed… yet…
16:52 <LAZAR> mauke: typos are just the worst of mistakes
16:53 treehaqr joined
16:53 <ertes> LAZAR: side note: if you use gists or lpaste.net, i can see your paste, too =)
16:54 dev-Zero joined
16:54 <Camm> Thank you guys.
16:54 dgpratt joined
16:57 <ysahil> Can we have a function of type signature IO Text -> Text???
16:57 <mauke> yes
16:58 <mauke> but you won't like it
16:58 <ysahil> mauke: Sorry, I didn't understand
16:58 <mauke> foo :: IO Text -> Text; foo x = "psych"
16:59 <ysahil> mauke: can we only make constant string functions using this?
17:00 chichou joined
17:00 <LAZAR> is there a way to access the last list elements like func (x,y,xs) = ... ? maybe (xs, secondlast, last)
17:00 orbifx joined
17:00 cdg joined
17:00 Swizec joined
17:00 <Cale> No efficient way. You could write a function to do it, but that's an unnatural way to access a list
17:01 <Cale> Usually the answer if you have to do a lot of such an operation is to either store the list in reverse order, or else use a different data structure.
17:01 <ysahil> mauke: can we only make constant string functions using this?
17:02 forgottenone joined
17:03 albertus1 joined
17:04 meghnath joined
17:04 koitalel joined
17:04 <jgt> ertes: you've saved my life
17:04 <monochrom> ysahil: You need to read my http://www.vex.net/~trebla/haskell/IO.xhtml
17:05 <koala_man> ysahil: you can't "get the Text out", no. there's not actually a Text inside it.
17:06 <mauke> ysahil: yes
17:06 cchalmers joined
17:06 <Cale> ysahil: You can run an action of type IO Text as part of another IO action though.
17:07 chbatey joined
17:07 <ysahil> Cale: I didn't understand the point you made
17:07 <Cale> ysahil: If you write v <- x in a do-block it means "execute the action x :: IO t, and whatever its result is, name that v"
17:07 <ertes> jgt: i have?
17:07 <Cale> and then the do-expression as a whole will have type IO s (it'll match the type of the last action in it)
17:08 <Cale> ysahil: A value of type IO t is not very much like a value of type t at all. It is a description of an action which could be taken that would result in a value of type t at the end, if it finishes normally.
17:09 <Cale> ysahil: i.e. the difference between IO String and String is like the difference between /bin/ls and a list of files in your home directory
17:09 <jgt> ertes: intersecting a ~55k list with a ~776k list pinned my CPU. Don't know how long the computation would have taken, because my HTTP request to it timed out. Turning my lists into sets first made the whole thing run in ~13s.
17:09 connrs joined
17:10 <ertes> jgt: ah, that… if you need to do this repeatedly you can probably do even better than that
17:11 Icewing joined
17:12 Denthir joined
17:13 balor joined
17:13 <jgt> ertes: I probably don't need to optimise it further for now, but it might be nice in the future
17:13 <jgt> unless there's low-hanging fruit I'm not seeing
17:13 <jgt> (which is likely, because I'm quite nooby)
17:14 <jgt> grateful if you'd share what else I should learn!
17:14 mikecaruso joined
17:15 <ertes> jgt: the first optimisation i'm thinking of is to get unrelated data out of the way
17:15 <ertes> turn (Set K) into (Map K A)
17:15 <tathougies> Is there a GHC extension that would let me do something like `type Foo = Bar Identity deriving (Show, Eq)`, as shorthand for `type Foo = Bar Identity; deriving instance Show Foo; deriving instance Eq Foo`. This would be useful when the instance for `Bar Identity` could be easily derived but not for other instantiations of `Bar`?
17:15 <ertes> the next is to get rid of expensive data types, e.g. replace String by Text
17:16 minn joined
17:16 <ertes> tathougies: 'type'? not 'newtype'?
17:16 <tathougies> @ertes yes, type not newtype.
17:16 <lambdabot> Unknown command, try @list
17:17 <tathougies> ertes: yes, type not newtype
17:17 <jgt> ertes: my data is coming out of Redis, so they're all ByteStrings
17:18 <tathougies> I know it's an odd request, but it's useful for one of my libraries that messes around with type families inside types. The context for the general instance `Show (Bar f)` is huge, and undecidable in general, but not for `Show (Bar Identity)`. `Bar Identity` is the only type most would want to Show or Eq though.
17:18 <tathougies> I feel it would be a nice addition if `TypeSynonymDeriving` let me add deriving instances to the type declaration instead of having to write 'deriving instance' time
17:18 <ertes> tathougies: why are you not deriving the instances for Bar instead of Foo?
17:19 <ertes> then StandaloneDeriving should suffice
17:19 nakal joined
17:19 <tathougies> like I said, the instance for `Bar f` is undecidable due to the constraints
17:19 <ertes> deriving instance Show (Bar Identity)
17:20 <tathougies> Yeah I can totally do that. I want to save on line space
17:20 <ertes> it's the same thing anyway, even in the presence of type families
17:20 <tathougies> I'm trying to minimize the number of lines users of my library will have to write
17:20 <tathougies> This is for my beam library: I'll show you This is for my beam library: https://github.com/tathougies/beam/blob/travis/beam-0500/beam-sqlite/examples/Chinook/Schema.hs
17:20 <tathougies> as you can see the `deriving instance` declarations get tedious, it would be much simpler to write them inline, and there wouldn't be any ambiguity (I think)
17:20 <ertes> i don't think there is a shorter way to write that
17:21 <ertes> if you derive for Bar, at least you don't need TypeSynonymInstances
17:21 Camm left
17:21 <tathougies> but then i need `UndecidableInstances` which is much scarier for library users to enable IMO
17:21 <tathougies> also unnecessary
17:21 <ertes> you don't need it for Foo?
17:22 <tathougies> nope
17:22 <ertes> wait, why would you need it? i can see that you would need FlexibleInstances, but not UndecidableInstances
17:22 <tathougies> Did you look at my example?
17:22 puregreen joined
17:22 <tathougies> the context for Show (ArtistT f) would be Show (Columnar f Int32), Show (Columnar f Text), which is undecidable according to GHC since Columnar is a type family
17:23 <tathougies> but since `Columnar Identity x ~ x`, the context for `Show (ArtistT f)` is statically `Show Int32` and `Show Text`, which are easily shown by the compiler
17:23 cmsmcq joined
17:24 <tathougies> thus, the compiler has no problem `deriving instance Show (ArtistT Identity)`, but forcing users to write out the full context and turn on undecidable instances is annoying, especially when most users only really want `Show`, `Eq`, etc instances for the types parameterized over Identity
17:24 CurryWurst joined
17:24 takle joined
17:25 theelous3_ joined
17:25 earldouglas joined
17:25 minn joined
17:26 <ertes> tathougies: without learning the whole beam library, what is the meaning of 'f' in (Columnar f)?
17:27 takle_ joined
17:27 <ertes> i.e. when is it not Identity?
17:28 <Sornaensis> ertes do you own any pets
17:28 takle joined
17:30 _sg joined
17:30 Jesin joined
17:31 meba joined
17:32 emc2 joined
17:32 <ertes> tathougies: (i'm trying to figure out whether you're doing something like this: <http://ertes.eu/tutorial/config-monoids.html>)
17:32 <tathougies> ertes: beam is a library for database access. `f` can be many things. For example, sometimes, it becomes `QExpr`, which means `Columnar QExpr x ~ QExpr x`. `QExpr` is a newtype over the type of SQL expressions where `x` is a phantom type parameter indicating the type of the result of the SQL expression when it's ultimately executed
17:32 <tathougies> othertimes, `f` is `TableField` which is a datatype tat describes how a field is stored in a table.
17:33 <ertes> Sornaensis: not sure how to respond to that
17:33 <tathougies> ertes: yes i am doing that, but with more convenience to the use
17:33 <tathougies> to the user*… namely using type families to avoid the newtype unwrapping for Identity
17:34 <tathougies> `f` can also be `Nullable g`. `Columnar (Nullable g) x ~ Columnar g (Maybe x)`. So there's quite a bit of complexity in the `Columnar` type family
17:34 <ertes> tathougies: reason i ask is that you can probably get rid of the type family altogether
17:34 <tathougies> no i do not want to do that
17:34 <tathougies> i have been down the road of manual newtype unwrapping and asking users to do that is too much
17:34 fizruk joined
17:36 ragepandemic joined
17:36 <tathougies> The entire point of `Columnar` is that when your type is applied to `Identity` you get a type whose fields are not newtypes or wrapped in anyway… just the 'normal' Haskell type you're trying to interface with your database
17:36 darlan joined
17:36 <tathougies> which is why i want a `deriving` clause on the end of my `type` synonyms :P
17:36 <LAZAR> Okay I solved this problem (doubling every other element in a list). The problem is: It was requested that the doubling takes place from right to left which seems super complicated... what would be the way to do this as requested? http://lpaste.net/354583
17:36 <Cale> Type synonyms can't have different instances from the types they're synonyms of though.
17:36 Swizec joined
17:37 <ertes> Cale: tathougies isn't asking for that though
17:37 oisdk joined
17:37 <Cale> Fair enough.
17:37 <TheLemonMan> LAZAR, are you writing a Luhn number checker?
17:37 <ertes> they're trying to trick GHC into doing partial type application with type synonyms, i think
17:37 <tathougies> Cale: what I want already exists. I just want more convenient syntax
17:37 <Cale> But if you want an instance for a newly defined synonym, you can write than instance before you introduce the synonym.
17:38 <ertes> i wouldn't even have known that you can abuse type families for that
17:38 hamishmack joined
17:38 pwnz0r joined
17:38 <LAZAR> TheLemonMan: yes
17:38 <Cale> that*
17:38 <LAZAR> TheLemonMan: i do not even get why they specifically request to do the doubling from right to left
17:39 <TheLemonMan> because that's how the algorithm works heh
17:39 <tathougies> ertes: that's the key feature of the library — using seemingly regular haskell types to represent the type over sql expressions, regular haskell values, column descriptions, whatever. The migrations framework included even lets the same type hold information on foreign references, etc. Nevertheless, you never want to actually show these types, as they are internal to the library. Users just want to be able to Show the types parameterized over Identity
17:39 <Cale> What is the type a synonym of?
17:39 <tathougies> Cale: https://github.com/tathougies/beam/blob/travis/beam-0500/beam-sqlite/examples/Chinook/Schema.hs
17:39 <tathougies> look at the type of ArtistT
17:39 <tathougies> see how we derive instances for Show Artist and Eq Artist, where Artist ~ ArtistT Identity?
17:40 <tathougies> GHC can do that
17:40 <tathougies> I was wondering if there was any syntax extension to let me add a deriving clause to the end of the type synonym declaration
17:40 <LAZAR> TheLemonMan: the problem is that while it is easy to do this with the (f:s:xs) syntax, it is very hard for me as a beginner to do this from right to left
17:40 <ertes> tathougies: to be honest i would most likely still go with the newtype approach and then just implement the necessary convenience features using generics, because they are entirely mechanical
17:40 bjz joined
17:40 <Cale> Ah, and it's not smart enough to derive the corresponding instance for ArtistT?
17:41 <ertes> tathougies: then users can just use regular deriving
17:41 <tathougies> ertes: the point is that users only have to write their data types once. The library internals can easily deal with newtype unwrapping. People who use the library don't want to have to change all their data types simply because they're using beam to serialize them. As it is now, you have to change your type, but then you can just define a synonym parameterized over Identity, and voila, you have your old non-beam type back
17:41 sellout- joined
17:41 <tathougies> Cale: GHC can do it if you give it the right context, but the type families make the context undecidable
17:41 bhiliyam joined
17:42 <ertes> tathougies: i understand that… that's also the point of the article i linked (you may want to skip to the "unifying phases" section)
17:42 <TheLemonMan> LAZAR, yep, but if you do all the steps together it only takes a couple of lines of code
17:42 <Cale> I see
17:42 <ertes> tathougies: i would do this: data ArtistT f = ArtistT { … field :: f Field } deriving …
17:43 connrs joined
17:43 <ertes> tathougies: the newtype wrappers can be eliminated by a combination of generics and lenses
17:43 JeanCarloMachado joined
17:43 <tathougies> ertes: i've done that before and got endless complaints from people using the library
17:43 <dmwit> :t foldr
17:43 <lambdabot> Foldable t => (a -> b -> b) -> b -> t a -> b
17:43 <LAZAR> TheLemonMan: well reverse (doubleEveryOther (reverse [1,2,3,4])) works but its ugly as hell
17:44 <tathougies> the lenses did not help. If you look at older versions of beam, you'll see i included methods to use Generic to derive lenses
17:44 <tathougies> still had uses complain
17:44 <metahumor> LAZAR: I don't think the order matters for your purposes -- the right to left was probably for systems that are little-endian
17:44 <dmwit> :t foldr (\(multiplier, list) x -> (3-multiplier, multiplier*x : list)) 1 [1,2,3]
17:44 <lambdabot> error:
17:44 <lambdabot> • Occurs check: cannot construct the infinite type: a ~ (a, [a])
17:44 <lambdabot> • In the second argument of ‘(*)’, namely ‘x’
17:44 <ertes> tathougies: well, now you're picking a point on the scale between inconvenient and evil =)
17:44 <metahumor> LAZAR: especially the original mechanical systems
17:44 <tathougies> lol, well people really like using the type synonyms
17:44 <dmwit> > foldr (\x (m, xs) -> (3-m, m*x : xs)) 1 [1, 2, 3]
17:44 <lambdabot> error:
17:44 <lambdabot> • Ambiguous type variable ‘a0’ arising from a use of ‘show_M416378450196...
17:44 <lambdabot> prevents the constraint ‘(Show a0)’ from being solved.
17:45 <LAZAR> metahumor: i just wondered why they specifically requested this... as if there were some sorts of trick to this really elegant in haskell
17:45 <MarcelineVQ> LAZAR: to make it harder
17:45 <tathougies> and honestly, i think that's best, because you really never interact with the other parameterizations of your tables. The library takes care of that for you
17:45 <tathougies> .oh well, i guess i'll stick with the deriving instance for now
17:45 umib0zu joined
17:45 <dmwit> > foldr (\x (m, xs) -> (3-m, m*x : xs)) (1, []) [8,7,6,5]
17:45 <lambdabot> (1,[16,7,12,5])
17:45 <LAZAR> MarcelineVQ: It just becomes ugler because i have to reverse twice
17:45 <dmwit> > foldr (\x (m, xs) -> (3-m, m*x : xs)) (1, []) [1,2,3]
17:45 <ertes> tathougies: yeah, you're already tricking the type class system to some extent
17:46 <lambdabot> (2,[1,4,3])
17:46 <dmwit> LAZAR: ^^
17:46 <Cale> It's kind of interesting that you can get away with this :)
17:46 <tathougies> it's not a trick, I swear! :P
17:46 <ertes> tathougies: BTW, these inevitable complexities are the reason why i gave up on database abstractions
17:46 replay joined
17:47 <tathougies> ertes: hmmm… beam so far has been a dream to use
17:47 <EvanR> databases deserve abstractions!
17:47 <metahumor> LAZAR: you don't need the second reverse
17:47 <Cale> ertes: Eventually we're going to figure it out, I promise
17:47 <EvanR> the backends though...
17:47 <ertes> hehe
17:47 <dmwit> > foldr (\x (m, xs) -> (1-m, shiftL m x : xs)) (1, []) [1,2,3]
17:47 <lambdabot> (0,[2,0,8])
17:47 <metahumor> LAZAR: what are you going to do with the results of the doubled array?
17:47 <dmwit> haha, whoops
17:47 <ezyang> "sqls are pretty good abstraction"
17:47 <EvanR> :(
17:48 <ertes> my approach is not to abstract over "databases", but model the application itself and then write backends using whatever database system
17:48 <dmwit> > foldr (\x (m, xs) -> (1-m, shiftL x m : xs)) (0, []) [1,2,3]
17:48 <lambdabot> (1,[1,4,3])
17:48 <ertes> nice bonus: i can write an STM-based implementation for testing
17:48 umib0zu joined
17:48 <LAZAR> metahumor: its just a luhn number checker
17:48 <MarcelineVQ> metahumor: it's an exercise http://cis.upenn.edu/~cis194/spring13/hw/01-intro.pdf
17:48 sproingie joined
17:48 <Cale> I think Ryan is right, we need a way to take ordinary looking Haskell code (perhaps with some pretty heavy restrictions on what you can write), and lift it to a somewhat arbitrary category (constrained based on what features of the language you used)
17:49 ebsen joined
17:50 <metahumor> you can do some crazy Fold magic for that checker if you want to limit the number of times you traverse the list
17:50 <dolio> Then you need a database system that's a good category.
17:50 <dolio> And not SQL.
17:50 <dmwit> metahumor: It's not even crazy. I posted how above.
17:50 augur joined
17:51 <Cale> dolio: Yeah, that's the other part of it, figuring out a convention for accessing a SQL database that lets us pretend that it's a good categorical one
17:51 <metahumor> :t shiftL
17:51 <lambdabot> Bits a => a -> Int -> a
17:51 <dmwit> Oh, maybe you mean for the whole checker and not just the "double every other number" part. In which case, okay, maybe. I've never tried it before.
17:51 sleffy joined
17:51 <metahumor> yeah that's what I meant
17:52 haskellnewbie joined
17:52 <dolio> Cale: The other problem is that there are no SQL databases.
17:52 <metahumor> for the "sum digits", "sum of sums", and "all"
17:52 <dolio> Except maybe Postgres.
17:53 <Cale> Postgres will do
17:53 <dolio> Well, I'm not even sure about it.
17:53 eacameron joined
17:53 <Cale> An abstract way to store bits will do, so long as we're still allowed to tell customers that we're using Postgres ;)
17:55 <TheLemonMan> LAZAR, if you fold the doubling + the truncation + the sum you end up with something like this (in Ocaml though) https://ptpb.pw/5Wwu
17:56 takle joined
17:57 significance joined
17:57 <significance> Why are monads always applicative functors? Is there some trivial way to get <*> from >>=?
17:57 cmsmcq joined
17:57 <dolio> Yes.
17:58 <rightfold> significance: (<*>) = ap
17:58 connrs joined
17:58 dan_ joined
17:58 skeuomorf joined
17:59 fizruk joined
17:59 <significance> thank you!
17:59 <metahumor> significance: but be careful, because (<*>) does not imply an ordering on the arguments, but `ap` does
17:59 raichoo joined
17:59 <metahumor> :t (<*>)
17:59 <lambdabot> Applicative f => f (a -> b) -> f a -> f b
18:00 <metahumor> :t ap
18:00 <lambdabot> Monad m => m (a -> b) -> m a -> m b
18:00 <significance> Is the ordering implied in the declaration of Monad?
18:00 <EvanR> imply ordering?
18:00 <EvanR> the look exactly the same except for f / m
18:00 <metahumor> significance: as in, the @f a@ effect could "happen" before @f (a -> b)@ for Applicative f
18:01 <metahumor> but never for Monad f
18:01 <EvanR> ordering of the effects
18:01 <EvanR> not arguments
18:01 <metahumor> yes, sorry, misphrased that
18:01 <significance> ahh, thank you!
18:01 srbaker joined
18:01 <metahumor> in general, people expect (<*>) and ap to order the effects the same way
18:02 <metahumor> the monad man will haunt you if you don't. maybe.
18:02 <significance> :%s/m/M ? :P
18:02 <EvanR> class MonadMan
18:03 takle joined
18:03 <significance> oh, haha, I was referring to Maybe
18:03 <significance> but the mirth holds :)
18:03 <significance> just to be clear, the @f a@ effect is the effect on a that is caused by being placed in an applicative?
18:05 Avogadro joined
18:05 mtesseract joined
18:07 <metahumor> :t [(++ "2"), (++ "3"), (const "1")]
18:07 raichoo joined
18:07 <lambdabot> [[Char] -> [Char]]
18:07 zero_byte joined
18:08 <metahumor> :t sequenceA [[(++ "2")], [(++ "3")], [(const "1")]]
18:08 <lambdabot> [[[Char] -> [Char]]]
18:09 binaryplease joined
18:10 fresheyeball joined
18:10 <metahumor> significance: yes. here's a nice blog post about how to utilize Applicatives for parsers
18:10 <metahumor> http://www.serpentine.com/blog/2008/02/06/the-basics-of-applicative-functors-put-to-practical-work/
18:10 ericmathison joined
18:10 <significance> thank you!!
18:10 <fresheyeball> is there a way to make a map and guarentee there is a key for each element of an ADT?
18:10 <fresheyeball> for example
18:10 <EvanR> theres something called a total map
18:10 <fresheyeball> data Foo = Bar | Baz
18:11 <EvanR> theres also a dependent map
18:11 <Cale> There's also just functions
18:11 <fresheyeball> I want to ensure that `Map Foo a` is complete and not have to deal with Maybes
18:11 <EvanR> yeah, Key -> Value
18:11 <fresheyeball> I know I could do it with a function, but I don't have total control over the api
18:11 <EvanR> what are the other restrictions then
18:11 <fresheyeball> EvanR: can you point me at total map and dependant map?
18:11 <cheater> you need dependant types for that fresheyeball
18:12 <fresheyeball> The api is looking for a `Map a b`
18:12 <EvanR> you dont need dependent types for this
18:12 <fresheyeball> And I make one with a literal of a list of tuples
18:12 <cheater> no? how would you do that EvanR?
18:12 <fresheyeball> and I want to compiler to yell at me if I extend the ADT
18:12 MrRicecake joined
18:12 <EvanR> we havent figured out all the arbitrary restrictions of this problem yet
18:13 <fresheyeball> cheater: is cheating
18:13 ertesx joined
18:13 <EvanR> so what is the actual api
18:13 <fresheyeball> is there a way I can convert a function from `a -> b` to a `Map a b`?
18:13 tomboy64 joined
18:13 <EvanR> wants a Map, returns a Map ?
18:13 <fresheyeball> Map is the input, so I need to make one
18:14 <fresheyeball> right now I just do `foo = Map.fromList [(Bar, 3), (Baz, 4)]`
18:14 <fresheyeball> but when I add to the ADT, the compiler is silent
18:14 <EvanR> you can make a smart constructor which checks that all keys are present and outputs a map
18:14 <Cale> :t M.fromSet
18:14 <lambdabot> (k -> a) -> S.Set k -> M.Map k a
18:14 <fresheyeball> Ooooo
18:15 <EvanR> you would still need to make the set of keys and make sure its complete
18:15 <fresheyeball> So I could use bounded to pull this off
18:15 <EvanR> one way to have the compiler check that is have a function that case analyzes your key type
18:15 <metahumor> significance: there's also this nice short answer showing how Applicative effect ordering might matter http://stackoverflow.com/a/23342577
18:15 <fresheyeball> data Foo = Bar | Baz deriving (Enum, Bounded)
18:15 <EvanR> if its not a complete case analysis, the compiler can warn
18:15 <fresheyeball> right!
18:15 <significance> ooh, sweet - thanks!
18:15 <EvanR> enum bounded could be used to do a runtime test that your arent complete
18:16 indi_ joined
18:16 <EvanR> which is not as nice
18:16 <fresheyeball> I am thinking I can write a function like this
18:17 <fresheyeball> makeCompleteMap :: (Enum k, Bounded k) => (k -> v) -> Map k v
18:17 <EvanR> what you can do is convert a total map to a map
18:17 <EvanR> yeah or that
18:18 <EvanR> if you add a new k, the case analysis in the k -> v will be a warning
18:18 <EvanR> until you fix it
18:18 <koala_man> how practical are the Haskell-to-JS compilers these days? are there other options if I want to write strongly typed functional code to run on a javascript engine?
18:18 <EvanR> it doesnt even need enum bounded
18:19 <metahumor> koala_man: typescript? purescript? elm?
18:19 <EvanR> ghcjs
18:20 <Sornaensis> ghcjs++
18:20 <fresheyeball> koala_man: we use ghcjs at work, and its lovely
18:20 <fresheyeball> koala_man: Purescript and Elm are also very nice
18:20 <fresheyeball> koala_man: Elm is the easiest to get going and has the most mature tools
18:20 <fresheyeball> koala_man: ghcjs has the nicest language and can be used for client server type sharing
18:21 <fresheyeball> EvanR: totalMap f = M.fromSet f [minBound..maxBound]
18:21 <koala_man> awesome info, thanks!
18:21 Velpoman joined
18:21 <fresheyeball> koala_man: I wrote a blog post on this http://mutanatum.com/posts/2017-01-12-Browser-FP-Head-to-Head.html
18:22 <koala_man> perfect :3
18:22 flump joined
18:24 <EvanR> fresheyeball: hmm yeah
18:24 <EvanR> i wanted a class specifically for enumerating all the elements
18:24 osa1_ joined
18:25 <Cale> If you have Bounded and Enum, you can try [minBound .. maxBound]
18:25 <EvanR> Enum, despite its name, doesnt do that really. adding bounded kind of fixes it but the whole thing is not as targeted as an abstraction
18:26 <EvanR> and doesnt work for stuff like Natural which doesnt have an upper bound
18:26 <EvanR> but does have an infinite list of its elements
18:27 <EvanR> allTheThings :: Enumerable a => [a]
18:27 <geekosaur> @hackage universe
18:27 <lambdabot> http://hackage.haskell.org/package/universe
18:27 ner0x652 joined
18:27 balor joined
18:27 <EvanR> nice
18:29 <EvanR> ~ * a Integer => Universe (Ratio a)
18:29 <EvanR> is this a haddock snafu or
18:30 <EvanR> and Universe doesnt have an instance for Natural built in :(
18:30 <geekosaur> haddock glitching over a kind
18:31 <geekosaur> and I think universe predates Natural; dunno if anyone's been maintaining it, for all the packages out there :/
18:31 meba joined
18:31 theelous3 joined
18:32 bennofs joined
18:33 <Tuplanolla> Is it possible to sanely communicate with a machine that has `CHAR_BIT > 8`?
18:33 <geekosaur> TYPE L 8 :)
18:33 <EvanR> theres no instance for Double, interesting
18:33 <geekosaur> (bit of internet history for you)
18:34 <geekosaur> anyway yes, but sometimes it takes some care. Tenex/Twenex systems had CHAR_BIT == 9 and were all over the early Internet
18:34 <EvanR> i guess Double is considered a (theoretically crippled) real number type in this case
18:34 <fresheyeball> EvanR: I think haveing a map with a key for every Natural would be a bad idea
18:34 <EvanR> your problem stems from the api not just taking a function
18:35 <EvanR> you can trivially convert a map into a function, but not the other way
18:35 <Tuplanolla> What even should happen if you send eight bits and eof to a machine that's expecting nine? Will there be padding or an early eof?
18:35 <fresheyeball> EvanR: well that may be the source of the pain. But I think its also reasonable to wish for a compiler warning for incompleteness of a Map
18:35 <EvanR> what machine takes 9 bits? is that an april fools joke?
18:36 <monochrom> I Googled for "type l 8" (with the double quotes), I got a list of how to do onramps with highways. http://www.dot.ca.gov/dist11/news/8impl/images/ex2.pdf
18:36 augur joined
18:36 <Tuplanolla> "Thought experiment". EvanR.
18:36 <EvanR> fresheyeball: you solved it in an adequate way, but a separate thing along these lines is, at some point i just wanted a class for enumerating all the values
18:36 chbatey joined
18:37 <fresheyeball> EvanR: I think that would be easy enough if they are bounded
18:37 <EvanR> Tuplanolla: since the internet is going to give them 8 bits per octet... i guess it would put a default value for the 9th bit
18:37 <fresheyeball> unbounded sounds hard because what would be the head of the list?
18:37 <EvanR> fresheyeball: what i was saying was, Enum + Bounded is a poor way to express that, because of the way Enum and Bounded really are in haskell
18:37 theelous3 joined
18:38 <EvanR> > [0..]
18:38 <lambdabot> [0,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,2...
18:38 <EvanR> 0 is the head of this list
18:38 <monochrom> Hrm, L means LOCAL
18:38 badmann joined
18:38 <fresheyeball> EvanR: I'm sorry, I'm not understanding
18:38 <fresheyeball> right, 0 is a bound
18:38 theelous3 left
18:38 <EvanR> Natural isnt an element of Bounded
18:38 <lpaste> aa pasted “a” at http://lpaste.net/354585
18:38 <EvanR> instance of
18:38 <fresheyeball> :i Natural
18:39 <fresheyeball> erp
18:39 <fresheyeball> how I do that in IRC?
18:39 <EvanR> also Rational is enumerable but not bounded
18:39 <Tuplanolla> @info Natural -- Not very helpful, fresheyeball.
18:39 <lambdabot> Natural
18:39 <geekosaur> you don't; it'd be too spammy
18:39 augur joined
18:39 <monochrom> geekosaur, your encyclopedic knowledge of ancient computers is creepy. :)
18:39 <fresheyeball> ok
18:39 <geekosaur> and @info is edit corrected to @undo
18:39 <lpaste> bb pasted “b” at http://lpaste.net/3418910391294492672
18:39 <Sornaensis> how do I embed a web browser into irc
18:39 <fresheyeball> so would you be happy with a class exposing a function like this?
18:40 <fresheyeball> startingWith :: a -> [a]
18:40 <badmann> is lpaste supposed to be this laggy?
18:40 <fresheyeball> startingWith x = [x..]
18:40 <EvanR> thats another bell and whistle on top of what it needs to do
18:40 <Tuplanolla> Sometimes, badmann.
18:40 <badmann> i remember it was laggy like a month ago
18:40 <EvanR> and requires Enum which is theoretically impossible for stuff that is infinite (because Int)
18:40 <geekosaur> lpaste is on a tiny vm instance iirc
18:40 <badmann> no point in using it instead of ix or pbp if its laggy..
18:40 <geekosaur> also I saw two pastes go by earlier
18:40 <fresheyeball> EvanR: right, we need atleast a minBound
18:41 <EvanR> fresheyeball: after enough haskell + etc, you start to notice these mathematical deficiencies ;)
18:41 <ertes> fresheyeball: you should revisit the reflex section, because it is misleading and in places plain wrong
18:41 <geekosaur> [14 18:38:43] <lpaste> aa pasted “a” at http://lpaste.net/354585
18:41 <EvanR> fresheyeball: rational has no minBound, neither does integer, but they are enumerable
18:41 <EvanR> see the universe package, exists already
18:41 <monochrom> aa pasted "a", and bb pasted "b". Will cc paste "c" soon? :)
18:41 <ertes> fresheyeball: "Reflex is highly composable and flexible, by mixing Monadic abstractions like crazy. This means developer discipline, as IO can be done anywhere in the code, and discrete state machines are common."
18:41 <EvanR> universe :: Universe a => [a]
18:41 <badmann> geekosaur: that was me i was trying to get a feel
18:41 <ertes> fresheyeball: that's pretty much complete non-sense
18:41 jomg joined
18:42 <badmann> are the pastes automatically deleted?
18:42 <Sornaensis> @hoogle a -> b
18:42 <lambdabot> Prelude id :: a -> a
18:42 <lambdabot> Data.Function id :: a -> a
18:42 <lambdabot> GHC.Exts breakpoint :: a -> a
18:42 <monochrom> No, I don't think the pastes are ever deleted.
18:42 <Sornaensis> >:{
18:42 <geekosaur> pastes live forever currently
18:42 <fresheyeball> ertes: can you expound on that?
18:42 <monochrom> Or at least, have ever been.
18:42 bhiliyam joined
18:42 <ertes> fresheyeball: not without explaining reflex
18:42 <EvanR> geekosaur: well, past pastes seem to have moved, ive noticed links on old forums going to the wrong paste
18:43 <EvanR> like the keys changed
18:43 <fresheyeball> ertes: I'm happy to hear the critcism
18:43 <fresheyeball> ertes: I use reflex at work, it what I do 8 hours a day
18:43 <geekosaur> several years ago lpaste lost its brain and got reset. everything since then has been stable
18:43 <fresheyeball> it's*
18:43 <metahumor> ertes: i think that snippet has "means" mean "monadic abstractions REQUIRE developer discipline to not use IO everywhere, in the sense that otherwise, you go crazy"
18:43 <ertes> fresheyeball: its semantics is pure
18:43 <monochrom> Oh, maybe that is why my paste of type inference of (.) (.) (.) is lost.
18:44 <monochrom> It was such a cool exercise.
18:44 <fresheyeball> ertes: what do you mean by that? Reflex is highly monadic and effectful
18:44 <fresheyeball> MonadWidget is monadic and needed to accomplish any work
18:44 <Sornaensis> :t (.) (.) (.) (.) (.) (.)
18:44 <lambdabot> (b1 -> b -> c) -> (a1 -> b1) -> a1 -> (a -> b) -> a -> c
18:44 <ertes> fresheyeball: now you're talking about reflex-dom
18:44 <fresheyeball> ertes: well to be fair, its an article about fp in the browser
18:45 <Tuplanolla> Was it like this, monochrom: convert to `(.)` to `fmap`, infer, specialize `fmap` to `(.)`?
18:45 <fresheyeball> Maybe I should be more clear the whole section is about Reflex Dom
18:45 <Sornaensis> :t fmap . fmap . fmap
18:45 <lambdabot> (Functor f, Functor f1, Functor f2) => (a -> b) -> f2 (f1 (f a)) -> f2 (f1 (f b))
18:45 <fresheyeball> I don't really think there is a clear path for using reflex in the browser without reflex-dom
18:45 <monochrom> No, I did it to (b -> c) -> (a -> b) -> (a -> c) directly.
18:45 <Tuplanolla> Wow, lewd.
18:45 <monochrom> Also, it would be fmap fmap fmap, without dots.
18:46 <fresheyeball> monochrom: thats one of the uglies tricks around
18:46 <EvanR> > fmap fmap . fmap . fmap fmap
18:46 mizu_no_oto joined
18:46 <lambdabot> error:
18:46 <lambdabot> • No instance for (Typeable f1)
18:46 <lambdabot> arising from a use of ‘show_M714224249303599581412308’
18:46 <fresheyeball> @type fmap fmap fmap
18:46 <lambdabot> (Functor f, Functor f1) => (a -> b) -> f1 (f a) -> f1 (f b)
18:46 <fresheyeball> @type fmap . fmap
18:46 <ertes> fresheyeball: everything else in your article seems fine to me, either because i agree, or because i don't have experience with the tools you mentioned… but to be honest the reflex section made me roll my eyes more than once, even on a sentence-by-sentence basis
18:46 <lambdabot> (Functor f, Functor f1) => (a -> b) -> f1 (f a) -> f1 (f b)
18:47 <monochrom> The original question was "(.) . (.)" but first thing I did was eliminating the infix to reduce confusion.
18:47 <fresheyeball> ertes: are most of your concerns based on the distinction between reflex and reflex-dom? Because I admit I used them interchangably and relied on the reader to know from context I mean reflex-dom
18:47 <monochrom> (Second thing was rename them to comp1 comp2 comp3.)
18:47 <geekosaur> anyway chrisdone passed lpaste on to someone else and there's a move to bring it under haskell.org admin, and hopefully it will be activeluy developed again and maybe get things like putting expiration dates on pastes
18:48 <ertes> fresheyeball: yeah, you shouldn't assume that… i'm using reflex, but i haven't used reflex-dom so far
18:48 <fresheyeball> ertes: most of the feedback I recieved was overwhelming positive. Or annoyance that I left out someone's favorite tech.
18:48 <fresheyeball> ertes: ok fair enough, I am happy to update the title of that section
18:48 <fresheyeball> ertes: question, because I've not used reflex without reflex-dom yet
18:49 <fresheyeball> ertes: is holdDyn a common thing in non-dom land?
18:49 <ertes> fresheyeball: but even in the context of reflex-dom it seems overly negative, as if you were trying to say: "you need to be super-careful with reflex-dom"
18:49 <fresheyeball> ertes: you do
18:49 <fresheyeball> ertes: absolutely
18:50 <ertes> fresheyeball: my use cases holdDyn is far less common than foldDyn
18:50 beerdrop joined
18:50 pandeiro joined
18:50 jao joined
18:50 bollu joined
18:50 <ertes> fresheyeball: i can't really tell due to my limited experience with reflex-dom, but the API looks pretty safe to me, to be honest
18:50 <fresheyeball> ertes: higher order inside MonadIO requires the most developer discipline of any pure language platform I've used
18:51 <ertes> as far as i can tell the only thing it does is to add automatic widget creation and management
18:51 <ertes> which of course requires IO
18:51 <fresheyeball> ertes: right, this is not the case with other models
18:51 ner0x652 joined
18:51 Dykam joined
18:51 <fresheyeball> in reflex-dom there is no way to track side effects in a guarenteed fashion
18:51 dfeuer joined
18:52 rodarmor joined
18:52 <fresheyeball> and infinite loops are unfortunately a common bug, and difficult to reason about
18:52 justanotheruser joined
18:52 <fresheyeball> don't get me wrong, I think reflex-dom is excellent
18:52 <fresheyeball> but that doesn't mean it doesn't have comparative flaws, which is clearly does
18:53 <ertes> hmm… reflex-dom, from an API standpoint, seems in line with every other FRP/UI framework i've seen so far or even created myself
18:53 <bennofs> the amount of knot-tying that reflex code requires is insane :)
18:53 <fresheyeball> ertes: I think UI frp api's might differ from backend ones
18:53 <bennofs> leads to easy infinite recursion, with MonadFix
18:53 cables joined
18:53 saylu joined
18:53 t0by joined
18:54 shane joined
18:54 <fresheyeball> bennofs: yes, MonadFix mdo stuff is what I meant by "discrete state machines are common"
18:54 <ertes> i mean: instead of creating a widget and then assigning event handlers and updating it, you create a widget and attach behaviours/events to it, and it returns events/behaviours
18:54 <fresheyeball> ertes: there are a ton of options here
18:54 bsima joined
18:54 <ertes> sure, you could also abstract away the whole process of creating widgets, essentially modelling the entire document as a single reactive system
18:54 Aruro joined
18:55 zeeb joined
18:55 <fresheyeball> you could sort of reify html and have a `Dynamic t HtmlThing` that get piped into a render
18:55 <fresheyeball> you can have an frp system that does not do IO inline at all, and would have a pure foldDyn
18:55 <ertes> but then you quickly find yourself emulating (main :: [Response] -> [Request]) in FRP, which is not nice to work with =)
18:55 <fresheyeball> or you could restrict the IO that can be performed using a free monad
18:56 <fresheyeball> and say only reflex IO can be done
18:56 <ertes> foldDyn *is* pure
18:56 <Sornaensis> > toDyn 5
18:56 <lambdabot> <<Integer>>
18:56 <fresheyeball> no its not
18:56 <fresheyeball> its does an allocation
18:56 <Sornaensis> > fromDyn (toDyn 5) :: Char
18:56 <lambdabot> error:
18:56 <lambdabot> • Couldn't match expected type ‘Char’ with actual type ‘a0 -> a0’
18:56 <lambdabot> • Probable cause: ‘fromDyn’ is applied to too few arguments
18:56 <fresheyeball> foldDyn :: (Reflex t, MonadHold t m, MonadFix m) => (a -> b -> b) -> b -> Event t a -> m (Dynamic t b)
18:56 <ertes> fresheyeball: so does Data.Vector.fromList
18:57 <ertes> allocation doesn't make something impure
18:57 <fresheyeball> sure, thats a fair point
18:57 <bsima> :t toDyn
18:57 <fresheyeball> you could hide the allocation by removing the m
18:57 <lambdabot> Typeable a => a -> Dynamic
18:57 <Sornaensis> > fromDynamic (toDyn 5) :: Char
18:57 <lambdabot> error:
18:57 <lambdabot> • Couldn't match expected type ‘Char’ with actual type ‘Maybe a0’
18:57 <lambdabot> • In the expression: fromDynamic (toDyn 5) :: Char
18:57 <Sornaensis> > fromDynamic (toDyn 5) :: Maybe Char
18:57 <lambdabot> Nothing
18:57 <ertes> the reason why foldDyn requires a monad is semantics: foldDyn is tied to a certain point in time
18:57 <fresheyeball> and it would be pure
18:57 <ertes> and time is not a first-class concept in reflex
18:57 <fresheyeball> ok sure
18:58 <ertes> it's modelled entirely by a monadic language
18:58 <fresheyeball> I'm just saying there an numerous ways around this problem, that done require allowing for liftIO
18:58 <fresheyeball> or having side effects on the dom inline with your code
18:58 <ertes> which problem?
18:58 <fresheyeball> having a reactive dom system
18:59 splanch joined
18:59 <fresheyeball> there is nothing about just having an frp UI system that requires that it have these problems baked in
18:59 <ertes> you mean something like 'brick', which models the whole application, including widget creation, purely?
18:59 dsfox1 left
19:00 <fresheyeball> ertes: I've not heard of brick, but sure
19:00 <ertes> 'brick' attempts to replace vty-ui
19:00 cchalmers joined
19:01 <ertes> to be honest i've tried using brick, but it was a horrible experience… i went back to vty-ui
19:01 <Tuplanolla> I liked it.
19:02 <fresheyeball> sure, so I think its fair to warn that Reflex requires discipline
19:02 <fresheyeball> I don't think its so much discipline that its bad or anyting
19:02 <fresheyeball> anything*
19:02 <ertes> fresheyeball: you're confusing reflex and reflex-dom again =)
19:02 <fresheyeball> I think reflex-dom is awesome
19:03 <fresheyeball> ertes: I know the differnce, we've established that, no need to beat up on me for trivial semantics
19:04 <ertes> if you prefer something like brick, then reflex-dom is not the right solution… but doing something like brick on the scale of a whole web app is bound to be problematic, at least in terms of performance, but more importantly in terms of flexibility
19:04 cmsmcq joined
19:05 <fresheyeball> ertes: I think reflex-dom is excellent for a reason :)
19:05 <fresheyeball> ertes: I also called it a hero in that article
19:05 epsilonhalbe joined
19:06 soLucien joined
19:06 sproingie joined
19:07 <ertes> fresheyeball: oh, and if it came across like that, i'm really not trying to be difficult or insulting… i'm trying to understand the problem you're talking about, and i think i understand it
19:07 <fresheyeball> ok cool
19:07 `^_^v joined
19:08 <fresheyeball> I will update the title of that section when I get around to it
19:08 <ertes> perhaps i just don't view it as a problem… in particular i don't view IO as problematic =)
19:08 <EvanR> i love that haskells standard date library has an algorithm for easter
19:08 katychuang_ joined
19:08 <fresheyeball> ertes: discipline is not necissarily a problem, but it is discipline
19:08 <EvanR> its like, the most arbitrary computation
19:09 <Aruro> EvanR: Yeah, like all cultures on earth need easter...
19:09 <Cale> reflex-brick?
19:09 <Cale> :)
19:09 <fresheyeball> ertes: as long as there is performUnsafeEvilFireTheMissilesAndTellNoOne
19:09 <fresheyeball> haskell requires more discipline than Elm
19:09 <fresheyeball> I still think Haskell is better :)
19:09 <* hexagoxel> has written a reflex wrapper around brick
19:10 <EvanR> unsafe fire the missile and tell no one is the easy one
19:10 <Cale> I wouldn't usually think of unsafePerformIO as part of the ordinary Haskell toolkit. It's more like 'last resort before we modify the compiler'
19:10 <Cale> and we *do* modify the compiler, so...
19:10 Denthir joined
19:10 <Cale> But yeah, not a day to day thing
19:10 <ertes> fresheyeball: well, it could be possible to limit the monads involved in reflex-dom not to allow IO, but that would be an arbitrary limitation without any real benefit
19:10 <bollu> Cale: unsafePerformIO is useful for writing FFI as well
19:11 <bollu> Cale: when the API is "theoretically pure" but the FFI taints it with IO
19:11 <EvanR> is unsafePerformIO appropriate in that case?
19:11 <EvanR> the FFI has a built in thing to declare it as pure
19:11 <monochrom> I think it is not so much discipline as how easy to reason. For example I am ready to admit that lazy evaluation causes more difficulty in reasoning how much time and space, and indeed by the time you go lazy I/O (e.g., getContents) it gets close to a black art.
19:11 MrLawrence joined
19:11 <bollu> EvanR: what? I didn't know this :O
19:11 <Sornaensis> you mean like converting a C math function into a pure haskell function?
19:11 <bollu> EvanR: well fuck, I think I need to and rewrite a bunch of code
19:12 <bollu> Sornaensis: yeah
19:12 <bollu> EvanR: link?
19:12 <EvanR> yes, import sine from math.h and hook it up as pure, ok hold on
19:12 cchalmers joined
19:12 <EvanR> https://en.wikibooks.org/wiki/Haskell/FFI#Calling_a_pure_C_function
19:12 <EvanR> you just dont put IO in the type sig
19:12 <monochrom> So for example if you are just writing 10 lines of code and you don't know that you're writing an infinite loop by mistake, that's some indication of difficulty to reason.
19:12 <bollu> EvanR: what if you need to call a "collection of functions" which are pure when taken together?
19:13 <thoughtpolice> EvanR: That doesn't work if your function is still conceptually pure, but might need e.g. a temporarily allocated memory buffer. This is a case where the FFI signature doesn't work; but unsafePerformIO does.
19:13 <Cale> EvanR: Well, sometimes you want to do some extra marshalling around the thing before it's properly a pure function, so you can't just import it at a non-IO type
19:13 <EvanR> yes unsafePerformIO is necessary sometimes when you have to do other stuff
19:13 <EvanR> but if its just pure, theres this
19:13 <Aruro> monochrom: in same way how haskell elders discourage naive recursion, its there but dont use it.
19:14 <Aruro> use fold and such.
19:14 <bollu> Cale, EvanR: can I do that with this? https://github.com/bollu/symengine.hs/blob/master/src/Symengine/BasicSym.hs#L106
19:14 <bollu> or this? https://github.com/bollu/symengine.hs/blob/master/src/Symengine/BasicSym.hs#L162
19:14 <monochrom> I don't quite agree that it's the same way, or rather the same degree.
19:14 <Sornaensis> Aruro: what's wrong with naïve recursion
19:14 <Aruro> Sornaensis: easy to do mistakes
19:14 <Aruro> sadly
19:15 <EvanR> i use it all the time, unless theres a canned pattern already implemented as a higher order function
19:15 <monochrom> For ordinary recursion there is a very good rule of thumb (refinable to exact condition) for termination. "The argument has to be 'smaller'."
19:15 <EvanR> for loops in IO too
19:15 mizu_no_oto_work joined
19:15 <monochrom> But it looks like with reflex you don't even have this much help.
19:16 <ongy> I feel like the work put into a fold is the same as naive recursion for me. Just that it's more thinking than typing, which I like better
19:16 <EvanR> the argument doesnt have to be smaller to ensure termination
19:16 <EvanR> it just does if it is
19:16 epsilonhalbe left
19:16 jgt joined
19:17 hybrid joined
19:18 <Aruro> also easier create leaks with naive recursion, i guess that was one of the reasons people discouraging it
19:18 <fresheyeball> ertes: EvanR: I agree limiting reflex-dom to disallow IO would not provide much benefit
19:18 <EvanR> i wasnt in that conversation
19:18 <fresheyeball> EvanR: appologizies
19:18 <EvanR> what is "naive recursion" ?
19:18 <fresheyeball> I wish weechat had spellcheck
19:19 <Aruro> EvanR: when u dont use folds and write like beginner?
19:19 <Aruro> and haskell does not like that.
19:19 <EvanR> when you use recursion but it ends up being inefficient in some way?
19:19 <Aruro> yeah
19:19 takle joined
19:19 <EvanR> hmm.
19:20 <Aruro> foldl' is classic example
19:20 <Aruro> of this trap
19:20 ragepandemic joined
19:20 <EvanR> so you wouldnt call the recursion that implements folds or list processing algorithms to be naive
19:21 <Aruro> beginners will rarely write it from first attempt
19:21 <EvanR> im not sure naive is the right word for inefficient
19:21 <Aruro> no, inefficiency is problem of language not writing style
19:22 <ongy> would anyone come up with the definition currently in GHC library on a first try?
19:22 <EvanR> hole in 1
19:22 <monochrom> No no no, I'm sure half of this is a few "elders" unreaonsably scaremongering against writing your own recursion, and the other half of this is the readers of said "elders" adding further misunderstandings.
19:23 <EvanR> oh yeah i forgot to even consider who the heck these elders are or if they exist
19:23 <Aruro> monochrom: u dont get it. to think like u u need time wasted on experimenting.
19:23 <EvanR> the cabal
19:23 <monochrom> For example it was foldl and foldr, the canned recursion, that would use more space than ideal. (And no, I refuse to say "space leak" which connotes not knowing why.)
19:23 <fresheyeball> what is wrong with foldl?
19:23 cyborg-one joined
19:24 ragepandemic joined
19:24 <monochrom> And until foldl' appeared, it is writing your own recursion that allowed you to place "seq" at the place you want to reduce space usage.
19:24 <bollu> who are the elders?
19:24 <MarcelineVQ> we don't speak of the elders
19:24 <Aruro> monochrom: seriously? writing recursion with seq? at beginner level?
19:24 <Aruro> good one
19:24 Wedamm joined
19:25 <Cale> fresheyeball: foldl without strictness analysis will result in accumulating large expressions before evaluating them -- if the function which it's applied to then pattern matches its argument, you can end up with a stack overflow
19:25 <monochrom> Seriously, no, I am not talking about beginners.
19:25 Itkovian joined
19:25 xdelv joined
19:25 <Cale> Usually strictness analysis (which gets turned on by -O) will catch that -- at least in most cases.
19:25 <EvanR> i guess Cale is pretty elderly
19:25 <Cale> But usually you don't want to leave it to chance.
19:26 <monochrom> And still, seriously, beginners need to learn how to write their own recursion too. Maybe without seq at first. But beginners would be not in a position to worry about space usage either.
19:26 <Tuplanolla> Glasgow Haskell Chance.
19:26 <fresheyeball> What would you advise instead of foldl?
19:26 <Cale> foldl'
19:26 <EvanR> bang patterns man
19:26 <EvanR> way better
19:26 <Cale> when the function doing the combining is strict
19:26 <fresheyeball> ouch
19:26 <Aruro> monochrom: if beginners will see all haskell mess from start, i doubt the will like it
19:26 <fresheyeball> thats no good
19:26 <Cale> fresheyeball: what?
19:26 <fresheyeball> the effiecent version is prime?
19:27 <Cale> Well, the stricter version is prime
19:27 <monochrom> I was a beginner and I took it.
19:27 <EvanR> its not about efficient, they act differently
19:27 <fresheyeball> the advisable version should be the cannonical version
19:27 bab joined
19:27 <monochrom> Also, the mess can't be hidden.
19:27 <Cale> foldl' might in other cases do more work than is necessary
19:27 <EvanR> and the unprimed one is just useful 0.0% of the time
19:27 <Cale> But usually it's the one you want, yes.
19:27 fkurkowski joined
19:27 chichou joined
19:27 <monochrom> You teach them foldr (hey they are "beginners"!), they enter "foldr (+) 0 whatever" in ghci, they will know.
19:27 <Cale> Actually foldl is just fine like 95% of the time or something
19:28 <Cale> so long as you turn on optimisations
19:28 dc0de joined
19:28 <Cale> The strictness analyser is pretty good at its job
19:28 <EvanR> i mean, specifically when you need lazy foldl
19:28 <EvanR> is rare to never
19:28 <Cale> reverse :)
19:28 <Cale> reverse and that's almost all :)
19:28 <ongy> Cale: when does the strict version do work, that's not required? for fold I actually don't know
19:28 shivansh joined
19:28 shivansh left
19:29 <monochrom> But I was not even talking about that. I was talking about how hard or easy it is to play safe when writing recursion.
19:29 <dolio> last
19:29 <Cale> Well, there are some other cases
19:29 <Cale> yeah
19:29 <ongy> ohhh, right. because reverse builds another list. So it can be more efficient, when we build another lazy structure and don't consume all of that?
19:30 <monochrom> Actually foldl and foldl' do the same thing if you use them for reverse.
19:30 <Cale> ongy: yeah
19:31 <Cale> monochrom: Is the code identical? It might be.
19:31 <monochrom> There is no difference between "f (x : y)" and "f $! (x : y)"
19:31 <EvanR> so you might need lazy foldl for last, and thats it
19:31 <monochrom> The code is not identical but I'm saying reverse's accumulator is in whnf by construction.
19:31 <Cale> ah, okay
19:31 <ongy> What difference does it make for last?
19:31 <Cale> Yeah, it's only a tiny bit worse... at worst :)
19:31 <LAZAR> Wow.... https://www.cis.upenn.edu/~cis194 just compare the 2013 with the 2016 version O.o the current version is like 100% worse with a focus on graphics to make it easier
19:32 cmsmcq joined
19:32 <Cale> Semantically, it's the same
19:32 <Cale> LAZAR: Each year is different
19:32 <monochrom> last is a bit problematic.
19:33 <LAZAR> lol the last is ENTIRELY different i mean for someone who has programmed quite a bit it feels like going back to Logo
19:33 <monochrom> err, I don't actually know how to use foldl for last. I'll have to see it before I can predict.
19:35 ninjazoete joined
19:36 <Cale> @src foldl1
19:36 <lambdabot> foldl1 f (x:xs) = foldl f x xs
19:36 <lambdabot> foldl1 _ [] = undefined
19:36 boombanana joined
19:37 Denthir joined
19:37 <Cale> > foldl1 (\_ x -> x) [1..10]
19:38 <lambdabot> 10
19:39 <monochrom> @type foldl
19:39 <lambdabot> Foldable t => (b -> a -> b) -> b -> t a -> b
19:40 gillesmajor joined
19:40 gillesmajor left
19:41 <monochrom> @src foldl
19:41 <lambdabot> foldl f z [] = z
19:41 <lambdabot> foldl f z (x:xs) = foldl f (f z x) xs
19:42 <monochrom> Oh that's interesting, foldl' will seq the individual items.
19:42 shivansh left
19:42 <monochrom> If you have "foldl' (\_ x -> x) undefined [undefined, undefined, 5]" for last, you won't get your 5.
19:42 Soft joined
19:43 bhiliyam joined
19:47 Rodya_ joined
19:47 meba joined
19:47 JeanCarloMachado joined
19:48 Tesseraction joined
19:51 thewormkill joined
19:52 <LAZAR> How do I load multiple source files in ghci?
19:52 ChaiTRex joined
19:54 tomboy64 joined
19:54 Eduard_Munteanu joined
19:55 cmsmcq joined
19:56 `^_^v joined
19:57 <Tuplanolla> Use `import`, LAZAR?
19:57 <LAZAR> like import file1 file2 file3?
19:58 <Tuplanolla> Like importing any other module.
19:58 <LAZAR> I only know :module and :load
19:59 <Tuplanolla> Have you never written `import Data.List` etc?
19:59 Denthir joined
20:00 insitu joined
20:00 richi235 joined
20:00 pera joined
20:01 oisdk joined
20:02 erisco joined
20:02 dhil joined
20:02 BartAdv joined
20:02 <LAZAR> nope, mainly used ghci by now
20:03 orbifx joined
20:03 <Tuplanolla> Well, you can do that. Give your module a name, put it into `Name.hs` and `import Name`.
20:03 <thoughtpolice> You can also do `:m+ Module.Name" fwiw
20:03 significance joined
20:04 <LAZAR> https://www.cis.upenn.edu/~cis194/spring15/lectures.html The first Expercise... you need to load the HW01Tests into GHCI
20:04 Sampuka_ joined
20:04 halogenandtoast joined
20:05 CoderPuppy joined
20:06 <LAZAR> when entering :module +HW10Tests it cant find the module even tho its in the same dir
20:06 jgt joined
20:06 <LAZAR> *HW01Tests
20:09 <monochrom> It's :load not :module for your own code.
20:10 <LAZAR> oh
20:10 <monochrom> Whereas it's :module or import for a library.
20:10 <LAZAR> wait but :load only loads one module? if i load one specific file, Prelude and any other ones will not be loaded any more
20:10 <monochrom> Also, my "your own" is inaccurate. It's whatever source code sitting right in front of you, include your own but also school's.
20:11 aarvar joined
20:11 <monochrom> That is not true.
20:11 <monochrom> And a simple test will show it.
20:11 jsgrant_ joined
20:11 <monochrom> :load something and ask about 4+5.
20:11 <Sornaensis> > 3 :+ 1
20:12 <lambdabot> 3 :+ 1
20:12 <Sornaensis> > 3 :+ 1 * 2
20:12 <lambdabot> 3 :+ 2
20:12 <Sornaensis> > (3 :+ 1) * 2
20:12 <lambdabot> 6.0 :+ 2.0
20:13 <LAZAR> Well after :load HW01Tests.hs and again :load myownfile.hs i can no longer access the files of HW01Tests
20:13 <Aruro> is there any extension which allows to write map (+1+2) list ?
20:14 permagreen joined
20:14 <Aruro> simplifying lambdas of the form \x->x+y+z
20:16 <monochrom> Does myownfile.hs import HW01Tests? Or the other way round?
20:16 <MarcelineVQ> :t (+1) . (+2)
20:16 <lambdabot> Num c => c -> c
20:16 <rightfold> I have written bytecode interpreters before, but never for a lazy language, and I would like to find out more on this matter. The GHC bytecode language and interpreter are quite complex, is there something similar and more educational out there?
20:16 Rodya_ joined
20:16 Snircle joined
20:16 peterbecich joined
20:17 Wizek_ joined
20:18 yellowj joined
20:18 <Aruro> MarcelineVQ: writing lambda becomes shorter than composition :)
20:18 cpup joined
20:18 yellowj joined
20:18 <Aruro> especially if number of terms grows
20:19 indi_ joined
20:20 oisdk joined
20:20 Wizek_ joined
20:21 chlong joined
20:21 maarhart joined
20:23 Gurkenglas__ joined
20:23 Denthir joined
20:23 justanotheruser joined
20:25 <LAZAR> Can someone help me with https://www.cis.upenn.edu/~cis194/spring15/hw/01-intro.pdf ? I have no idea how to import both my own and the testing files in ghci... it always tells me the test files are inaccessible from within ghci
20:26 cpennington joined
20:26 <mauke> how are you loading it?
20:26 <Aruro> LAZAR: u just said u have big programming experience :) or I overheard?
20:27 doomlord joined
20:27 tusj joined
20:28 jjBliss joined
20:28 <LAZAR> I literally said I have programmed quite a bit. I added an import to my file and GHCI loads them, yet they are not accessible
20:29 clmg joined
20:30 <clmg> Who likes puzzles? I have a tree and I am traversing it. I need to delete one branch using lenses. How?
20:30 <LAZAR> Aruro: http://lpaste.net/354589
20:30 <clmg> Specifially, one child of a parent needs to become the parent, and the other child needs to disappear
20:31 chichou joined
20:31 <dfeuer> clmg: if you really want to do that, I think you'll need to build the lens as you traverse the tree. But why do you want to do that with lenses?
20:31 <MarcelineVQ> can you lpaste the module that defines runTests?
20:32 <LAZAR> MarcelineVQ: Check the pdf, runTests should be defined in either of them (all of them are loaded)
20:32 beerdrop joined
20:32 <Aruro> LAZAR: something is not in scope, modules have been loaded
20:33 <LAZAR> runTests is in Testing
20:33 <Aruro> LAZAR: does it export it?
20:33 <LAZAR> it was listed when using _browse so i guess they are exported?
20:34 snowalpaca joined
20:35 <Aruro> before error u typed browse?
20:35 splanch joined
20:35 r33ky joined
20:35 <r33ky> hi
20:35 <dmwit> LAZAR: Which module exports `runTests` and `ex1Tests'?
20:36 <MarcelineVQ> try typeing import Testing in ghci after loading validate.hs
20:36 <dmwit> LAZAR: Currently, only `Main`s definitions are in scope (see the "*Main" prompt).
20:36 Itkovian joined
20:36 aarvar joined
20:36 <mauke> LAZAR: what's the first line of validate.hs?
20:37 dsh joined
20:37 <LAZAR> Here is the full outPut: http://lpaste.net/279110524199763968
20:38 <LAZAR> validate.hs starts with {-# OPTIONS_GHC -Wall #-} (newline) import HW01Tests()
20:38 biglambda joined
20:38 <monochrom> Yikes, don't put () there, it defeats the point of your import.
20:38 <erisco> that means to import nothing
20:38 <Aruro> LAZAR: do u need to do homework? read course and move on to real world
20:38 <mauke> Aruro: dude, stop
20:39 <mauke> what are you doing
20:39 <dmwit> LAZAR: Use `:m + Testing HW01Tests` to bring those module's exports into scope.
20:39 <monochrom> What is the assignment URL again?
20:39 <mauke> /lhttps://www.cis.upenn.edu/~cis194/spring15/hw/01-intro.pdf
20:39 <monochrom> Thanks.
20:39 <mauke> https://www.cis.upenn.edu/~cis194/spring15/hw/01-intro.pdf
20:39 <Aruro> mauke: towers of hanoi as first homework in haskell? what am i doing?
20:40 <Aruro> no first how to import export, how to use ghci
20:40 <Aruro> straight to math.
20:40 <mauke> Aruro: it looks like what you're doing is to annoy LAZAR
20:41 <mauke> or me
20:41 <Aruro> mauke: i asked if he has to do it? whats wrong with that?
20:41 xdelv joined
20:41 <LAZAR> Aruro: Lol check the date of the course please. ;-)
20:41 <LAZAR> Spring 2015
20:41 <monochrom> LAZAR: It looks like you should be able to just :load HW01Tests and have everything, because it already imports everything.
20:42 <mauke> ok, it might also be a language barrier issue
20:42 <monochrom> And you should be putting your solution in HW01.hs
20:42 <LAZAR> monochrom: well that would not import my own code right?
20:42 <LAZAR> oh well thats true
20:42 <LAZAR> but why is this such a hassle?
20:43 <monochrom> Because not following the assignment down to the letters?
20:43 <monochrom> To be sure, it can be done without following it exactly, but then you need to know much more about ghci.
20:44 bhiliyam joined
20:47 <Aruro> LAZAR: ironically these issues described in last lecture http://www.seas.upenn.edu/~cis194/spring15/lectures/13-building.html
20:47 zeroed joined
20:48 fotonzade joined
20:50 agocorona joined
20:52 <Aruro> LAZAR: you can consul also GHC manual (which is good) https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/ghci.html
20:52 leifmetcalf joined
20:53 xcmw joined
20:55 leifmetcalf joined
20:55 <Aruro> LAZAR: https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/ghci.html#what-s-really-in-scope-at-the-prompt
20:56 <EvanR> rightfold: the keywords for this is graph reduction machine, and theres a book on it "implementation of functional programming languages"
20:56 <rightfold> EvanR: thanks!
20:56 <EvanR> and its availble in electronic form for free https://www.microsoft.com/en-us/research/publication/the-implementation-of-functional-programming-languages/
20:57 <Cale> rightfold: also https://www.dcc.fc.up.pt/~pbv/aulas/linguagens/peytonjones92implementing.pdf
20:57 <EvanR> ghc itself has advanced past the material in the book but personally i need a foundation
20:57 hexfive joined
20:57 <rightfold> Cale: thanks!
20:58 ubsan_ joined
20:58 leifmetcalf joined
21:00 Destol joined
21:02 <Gurkenglas__> clmg, you telescope down into the parent node (similar to https://hackage.haskell.org/package/free-4.12.4/docs/Control-Comonad-Cofree.html#v:telescoped ) and %~ it by _rightChild?
21:03 Lestaty1 joined
21:03 adir joined
21:04 bjz joined
21:04 Itkovian joined
21:05 leifmetcalf joined
21:05 augur joined
21:07 augur joined
21:07 ystael joined
21:08 AntonF joined
21:08 badmann left
21:09 <AntonF> Hello everyone. I have quite a silly question: what is best up to date minimal vim plugin for Haskell? Say, reasonable indentation is all I want. Thanks in advance.
21:11 snowalpaca joined
21:12 kadoban joined
21:12 umib0zu left
21:12 seagreen joined
21:13 <clmg> Gurkenglas: I'm new to lenses. I feel like what I'm trying to do shouldn't be that complicated
21:13 <clmg> When I traverse the tree I'm looking for a node with a branch of a specific name. If the branch has that name, destroy its brother and replace the parent with the child.
21:13 <clmg> http://lpaste.net/354592
21:13 <clmg> That's the code I wrote to do it
21:14 <Cale> AntonF: set expandtab, set smarttab, set autoindent
21:14 <clmg> However, when I call that method on my tree it /erases the entire tree/
21:14 <clmg> why????????
21:14 <clmg> why why why
21:14 <clmg> I've been working on this for so long
21:14 EvilMachine joined
21:14 <Sonolin> yea I don't think I even have any hs related vim plugins :)
21:14 <Sonolin> although a smart indent one would be nice
21:15 <Sonolin> i.e. something to keep vertical lines/blocks indented at the same level
21:15 <clmg> A Split is either (Split Direction Split Split Nothing) or (Split Nothing Nothing Nothing Window)
21:15 <clmg> That is, it's either has two children or it is a leaf
21:16 <Cale> Sonolin: Yeah, it would be nice if any edit which caused the first non-whitespace character following a layout keyword to move would cause the entire rest of the block to move accordingly
21:16 <Cale> (in any text editor)
21:16 <Cale> That feature would singlehandedly be enough to get me to switch to whatever text editor it was that supported it.
21:17 <geekosaur> structured-haskell-mode, anyone? :p
21:17 <AntonF> Cale: I would also want guard statements to be aligned along ='s
21:17 <* geekosaur> now remembers playing with syntax-directed editors in the 90s
21:18 <geekosaur> inspired by "Alice: The Personal Pascal"
21:18 <Cale> geekosaur: No, that's way too annoying
21:19 <raichoo> AntonF: Not sure if it fits your needs, but it's the one I develop and use at work every day. https://github.com/neovimhaskell/haskell-vim
21:19 cchalmers joined
21:19 <raichoo> It's opinionated though.
21:19 math932 left
21:20 `^_^v joined
21:20 Edith joined
21:20 Sh4rPEYE joined
21:20 <monochrom> structured-haskell-mode is not a vim plugin :)
21:20 <geekosaur> hm, actually that was mid-late 80s
21:21 <AntonF> raichoo: thanks, I will have a look
21:21 shivansh joined
21:22 clmg joined
21:22 shivansh left
21:22 <Sh4rPEYE> Hey! I'm doing some tasks on CW and I stumbled upon this kata called "Functional streams". First they define infinite sequence like this:
21:22 <Sh4rPEYE> data Stream a = S a (Stream a)
21:22 <clmg> Did anyone respond to my lpaste I got dc'd
21:22 <Sh4rPEYE> But then they write:
21:22 <Sh4rPEYE> -- Note: We will define Stream with the equivalent infix operator constructor.
21:22 <Sh4rPEYE> data Stream a = a :> Stream a
21:22 <EvanR> seems legit
21:22 <Sh4rPEYE> What does the last line mean? I guess the dame as the first one, but what is this (:>)?
21:23 <EvanR> its just like S, only infix
21:23 <Sonolin> Cale: I believe Spacemacs had something similar to this I quite liked
21:23 <Sonolin> although its definitely much more than another editor
21:23 <Cale> Yeah, they just renamed S to :> which is then written infix because it's a name made of symbol characters.
21:23 forgottenone joined
21:23 clmg left
21:23 <Sh4rPEYE> Oh, so just and arbitrary name for a function that constructs a Stream, one might say?
21:23 <EvanR> Sh4rPEYE: you know [1,2,3] is sugar for 1:2:3:[], (:) is the infix constructor for lists
21:24 <Gurkenglas> clmg, then why isn't it "data Split = Split { _direction :: Direction, _left :: Split, _right :: Split } | Window { _window :: Window }"?
21:24 MP2E joined
21:24 <mauke> Sh4rPEYE: data Stream a = (:>) a (Stream a)
21:24 <Cale> Sh4rPEYE: yep
21:24 <EvanR> with that (:>) you could write let x = 1 :> 2 :> 3 :> x
21:25 <EvanR> in x
21:25 <Sh4rPEYE> Oh, of course. Thanks! I saw (:>) in Sequences and I was quite take aback when I saw it used here... I somehow though it was that one
21:25 <EvanR> yeah its colliding with Sequence
21:26 aarvar joined
21:27 Maxdamantus joined
21:27 <Sh4rPEYE> EvanR: Just to verify, the headStream would simply look like this then:
21:27 <Sh4rPEYE> headS (x :> xs) = xs
21:27 <Cale> That would be tail
21:27 <Sh4rPEYE> Oh, ofc, pasted the wrong one
21:28 <EvanR> unlike list head, stream head is totally safe!
21:28 <monochrom> And stream last is totally unsafe!
21:29 <EvanR> a stream always has a beginning, by construction
21:29 mrus joined
21:30 <Sh4rPEYE> Yes
21:31 mtesseract joined
21:32 jmcarthur joined
21:33 pera joined
21:33 Swizec joined
21:33 coot joined
21:34 xcmw joined
21:34 nbro joined
21:35 BlueRavenGT joined
21:36 Snircle_ joined
21:37 <dmwit> monochrom: (untotally safe?)
21:38 Ranhir joined
21:39 earldouglas joined
21:39 Micamo joined
21:39 <Gurkenglas> What libraries should I use to write a web IRC client?
21:39 ggVGc joined
21:40 ckubrak joined
21:40 ckubrak joined
21:40 <Gurkenglas> Hmm. Scratch web, unless it's convenient, for I guess locally would be fine too and I don't actually have a server
21:42 <EvanR> https://hackage.haskell.org/package/irc-client
21:42 <Eduard_Munteanu> Gurkenglas, I'd say servant for a REST/WebSockets <-> IRC gateway, and ghcjs/Elm/etc. for the client app
21:43 <jle`> bollu: pong?
21:44 ChaiTRex joined
21:44 pera_ joined
21:44 nakal_ joined
21:45 bhiliyam joined
21:49 oisdk joined
21:49 dpren joined
21:49 Supersonic112 joined
21:54 stef204 joined
21:54 systemfault joined
21:57 <EvanR> ok
21:57 <EvanR> Data.Unique
21:57 Destol joined
21:58 <EvanR> is based on a global IORef containing a counter that starts at 0
21:58 <EvanR> something doesnt seem that unique to me about this
21:59 <EvanR> also if the program runs a long time, the counter just increases forever
21:59 <* geekosaur> thinks this sounds like Data.Unique is just lisp's gensym
22:00 Guest51282 joined
22:02 <EvanR> so then i looked at Data.Unique.Really
22:02 <EvanR> which is based on Data.Unique, but then does a evaluate then a makeStableName on the unique value.
22:03 hiratara joined
22:03 <EvanR> is it really guaranteed that the stable names wont compare equal for "different" values of the unique?
22:03 <EvanR> like one unique 0 vs "another"
22:04 NyanPasu joined
22:06 <erisco> newtype X a b = X (a -> (b, X a b)) I sense this fits some known pattern
22:06 richi235 joined
22:06 <EvanR> its a state machine
22:07 forgottenone joined
22:07 <erisco> I am looking for packages that have elaborated on this type
22:07 terrorjack joined
22:07 <EvanR> theres a few by ekmett im sure
22:08 <EvanR> https://hackage.haskell.org/package/machines-0.6.1/docs/Data-Machine-Mealy.html
22:08 oreoluwa joined
22:10 <EvanR> so if a program is utilizing Integer counter as a source of unique IDs, and it just keeps counting up
22:10 <EvanR> and it runs indefinitely
22:10 <EvanR> and you have 1G of ram
22:10 <EvanR> what can you say about the reliability of this program?
22:11 <erisco> lets do some maths to see how quickly you can fill the RAM
22:11 isenmann joined
22:11 <erisco> assuming, say, we increment the integer at 1Ghz
22:12 <MarcelineVQ> EvanR: not to sound too glib but it may say that you need a better way to go about using your uniques if your integer is reaching 1gb
22:12 <EvanR> is an integer the size of 1G even possible
22:12 <geekosaur> even on 32 bit you get over 2GB
22:12 <geekosaur> oh, that size, nm
22:13 <EvanR> size in memory
22:13 <geekosaur> I think you could get an Integer that big, but now I will echo MarcelineVQ :)
22:13 <EvanR> by incrementing?
22:13 strykerkkd joined
22:13 <geekosaur> you seriously need to rethink what you're doing if you're generating them that much
22:13 <erisco> I have a feeling you won't count to 2^(10^9) any time soon
22:14 <geekosaur> because, really, you can't do much better than what it is doing.
22:14 <EvanR> the rate of generating them is not going to be 1GHz or even 1MHz, its a reasonable usage of the generator, but even at 1GHz it seems like a combinatorial physical impossibility
22:14 <geekosaur> most of the alternatives are even larger, and if you're seriously worried about a 1GB size int you can;t even think about the usual UUID / GUOID setup
22:14 Micamo joined
22:14 xcmw joined
22:15 frontendloader joined
22:15 RoyalNightGuard left
22:15 <EvanR> this feels weird
22:15 <erisco> it has 301 million decimal digits, according to Wolfram
22:16 <EvanR> is it on the same level of implausibility as getting a non-unique UUID
22:18 <erisco> for reference, this number is about 10^100000000 and the number of grains of sand on Earth is about 10^24
22:18 <EvanR> heres the use case, in a video game enemies will spawn and get a unique ID. but then they will eventually disappear, after that the IDs might still be lingering somewhere
22:19 <EvanR> so if you reuse them, it could go haywire
22:19 <erisco> and the number of atoms in the universe is 10^80
22:19 <Tuplanolla> You can apply the concept of garbage collection to identifiers too, EvanR.
22:19 <MarcelineVQ> for a video game I would simply keep a set of what's in use
22:20 <Tuplanolla> Go through the live set and see if an identifier is no longer in use anywhere.
22:20 <EvanR> the tables have keys for whats in use, but that doesnt tell you what is holding onto this numbers
22:20 <MarcelineVQ> If you need to track a history of enemies then a unique could matter more, i fact I need to do something related for a side-project I have so this is a useful convo
22:21 <EvanR> Tuplanolla: yes thats how the same issue doesnt come up with pointers
22:21 <EvanR> the object isnt retired until *no one has a reference period*
22:21 <EvanR> but i want to be able to manually delete
22:22 <erisco> okay, but, I think it is clear that if we're alright with using Integer that there just isn't a problem
22:22 <EvanR> yes this tangent is "figure out a better way to use your uniques"
22:23 <erisco> if you add bookkeeping cost to IDs then you limit the number you can issue in real time
22:23 <erisco> other than simplicity, this is one reason you'll see such a system in games
22:24 preyalone joined
22:24 <EvanR> would a 64-bit Int be just as good?
22:24 <EvanR> im having a hard time coming back to programmer mode rather than math mode
22:25 indi_ joined
22:25 {emptyset} joined
22:25 <erisco> well, if you see my napkin math above it is mathematically clear that we don't have enough time to observe a problem
22:25 <Tuplanolla> I've seen a monitoring system written in SDL run out of frame numbers and jam firsthand.
22:25 <EvanR> heh
22:25 <erisco> for 64-bit I am not sure, but you can do the same sort of analysis again
22:25 <erisco> how quickly are you issuing IDs and how long can any ID live?
22:25 <Tuplanolla> (It uses its own `Uint32`.)
22:25 <EvanR> yes 32-bit regularly overflows in reality
22:25 <erisco> the lifetime is relevant wrt the rollover of a 64-bit integer
22:26 <EvanR> well, a max of 1GHz covers anything a PC can ever do
22:26 <EvanR> itll never be that fast
22:26 <geekosaur> erisco, I can see a busy MMORPG server generating uniques often enough to require resetting monthly or so to avoid 64-bit rollover
22:26 <erisco> even with rollover, if your life times are short enough you can guarantee (or have be likely) that IDs will not collide
22:27 mjhoy joined
22:27 <EvanR> the max Int is a little under ten billion billion right
22:27 <erisco> and if you have objects of hugely different life times you can consider separate ID spaces for them
22:27 <geekosaur> Integer should work for one that'll be up for a while, but really I'd want better management at that point --- you have bigger problems than reuse, if stuff is hanging around beyond when it should then you're leaking more than Uniques and your players will be very unhappy
22:27 <Gurkenglas> Physics as we know it do not permit incrementing numbers to exceed 2^400. https://arxiv.org/abs/quant-ph/0110141
22:27 <geekosaur> (and so will the server operator, and so will you when the OOM killer triggers)
22:28 <erisco> so, for example, player characters in your MMORPG, which exist for years, may have a separate ID space from the mobs that live for just a few minutes or hours
22:28 <EvanR> im definitely trying to avoid completely unnecesssary optimizations
22:28 <geekosaur> I can imagine an item taken off a mob member retaining *something* about said member. that said it should clone what it needs rather than keeping the mobber around
22:29 <geekosaur> again, this isn;t just uniques leaking, this is a memory leak that will crash your game eventually
22:29 <EvanR> maybe 128-bit Int then ;)
22:29 <Tuplanolla> My main issue is that it's unsatisfying to an obsessive mind.
22:29 <EvanR> Tuplanolla: heh
22:30 beerdrop joined
22:30 tathougies1 joined
22:31 hiratara joined
22:32 <EvanR> so the answer really is... dont have bugs that involve lingering IDs for things that shouldve been logically deleted
22:32 <erisco> machines are limited
22:32 <EvanR> and then just use the least unused number
22:32 <erisco> limited RAM, time, space
22:32 <Rembane> You cannot have the last digit of pi. :(
22:32 <erisco> so estimate the limitations and plan to be well within those margins
22:32 kylepotts joined
22:33 chichou joined
22:33 <EvanR> well haskell doesnt give you tight guarantees of that
22:33 <EvanR> i have no idea how much memory ill need, my tests indicate i could be using constant 75k of memory while not obviously allocating more and more stuff
22:34 dan_f joined
22:34 <EvanR> but who knows
22:34 <EvanR> an incrementing Integer causes that number to slowly creep up
22:34 <erisco> start with a guess of how many IDs you will issue per game update (worst case)
22:35 <dmwit> geekosaur: You can see a busy MMORPG issuing trillions of IDs per second?
22:35 <erisco> then guess how long the game has to be running continuously
22:35 <dmwit> > 2^64/31/24/60/60
22:35 <EvanR> much less than 1 since it would only happen if you spawn or remove objects
22:35 <lambdabot> 6.887225236600041e12
22:35 <erisco> then see what size of integer you need so that you won't run out of IDs
22:36 <dmwit> You're gonna need 1000 servers doing nothing but issuing IDs and managing to do that in only a few cycles per ID.
22:36 <EvanR> this is an arcade game for a bar that is 100 years old, so theres no telling how long it will continue standing
22:36 <erisco> there are games you can leave running for months or a year or more and they actually do overflow
22:37 <EvanR> yeah i consider those shit
22:37 <erisco> some funny things you can see on YouTube ;)
22:37 chichou_ joined
22:37 <EvanR> oh, the power is probably going to go out and reset it from time to time...
22:37 <erisco> such as Peach baking a cake has to cook it for just the right amount of time
22:37 <erisco> which is either about 30 seconds or some many months plus 30 seconds :P
22:39 <erisco> but if you think ahead you can set the bar to be absurd, such as requiring a hundred years or more
22:40 <EvanR> > 2**64 / 10**9 / (86400 * 365)
22:40 <lambdabot> 584.942417355072
22:40 <EvanR> 584 years
22:40 <EvanR> > 2**63 / 10**9 / (86400 * 365)
22:40 <lambdabot> 292.471208677536
22:40 <EvanR> uhg
22:42 jship joined
22:43 orbifx joined
22:43 <erisco> another overflow is in Hearthstone where there is an ability to double HP, so it exponentially grows
22:44 <erisco> therefore in not many steps (though in context of the game it is absurd to make happen) you can overflow the HP
22:44 zenware joined
22:44 <erisco> and HP less than zero kills :P
22:45 <erisco> but that's doubling and with IDs we're only incrementing
22:45 bhiliyam joined
22:46 <EvanR> process ids seem to just go up until you reboot
22:46 <EvanR> i wonder
22:46 <Tuplanolla> They're recycled every now and then.
22:46 <dolio> In Final Fantasy Mystic Quest, you can kill the final boss by curing him, because of an overflow.
22:46 splanch joined
22:47 <dolio> Only one of the characters is able to do it, though.
22:49 <EvanR> i want to make a fake "kill screen" which simulates the sort of problems old arcade games had with this, but having it affect normal game play would be embarassing!
22:50 <Tuplanolla> Back then you could reprogram the game with just the controller, the way it should be.
22:50 <EvanR> that would be cool too but i havent figured out a proper language for that
22:51 <Tuplanolla> I guess you'd need a virtual machine without a memory protection model.
22:52 <hpc> Tuplanolla: that's easy, just make it in flash
22:54 codesoup joined
22:55 Tuplanolla left
22:55 diegonolan joined
22:55 <diegonolan> @pl \a b -> a * b - 3 * b
22:55 <lambdabot> (`ap` (3 *)) . ((-) .) . (*)
22:55 Tuplanolla joined
23:03 iAmerikan joined
23:09 markus1189 joined
23:10 hamishmack joined
23:10 joe9 joined
23:10 markus1199 joined
23:11 <joe9> I want to get the interval between 2 UTCTime's. I see diffUTCTime :: UTCTime -> UTCTime -> NominalDiffTime . But, I cannot figure out how to get the seconds from the NominalDiffTime. Can anyone please help?
23:12 <joe9> > :t realToFrac (100 :: NominalDiffTime) :: Integer
23:12 <lambdabot> <hint>:1:1: error: parse error on input ‘:’
23:12 <joe9> http://codepad.org/qkOGdvlx
23:13 <joe9> there is a diffTimeToPicoseconds but nothing from NominalDiffTime
23:13 theDon_ joined
23:14 shwouchk joined
23:16 forgottenone joined
23:17 texasmynsted joined
23:17 <joe9> got it , round . realToFrac
23:22 geekosaur joined
23:23 atomi joined
23:24 cchalmers joined
23:26 takle joined
23:31 julianleviston joined
23:31 kylepotts joined
23:33 meba joined
23:38 Gurkenglas joined
23:40 mjhoy joined
23:41 justanotheruser joined
23:43 fermi_ joined
23:43 nakal joined
23:44 linelevel joined
23:44 jao joined
23:44 takle joined
23:46 bhiliyam joined
23:49 xiinotulp joined
23:49 splanch joined
23:50 <monochrom> If your program can't fit in constant space, then the next best thing is log-space and it isn't all that bad.
23:50 cpennington joined
23:52 <monochrom> For example if it has taken no less than 10 days for your unique IDs to need n bits, then it will take 10 more days to grow that need to n+1 bits.
23:54 tathougies joined
23:55 <monochrom> And then 20 more days before you need n+2 bits. In general going from n bits to 2n bits takes exponential time.
23:56 <monochrom> Pretty sweet deal if you asked me, short of outright free lunch.
23:57 pinkythepig joined
23:58 MrRicecake joined
23:58 takle joined