WELCOME TO MIDNIGHTWIKI: OPEN INFORMATION CONGLOMERATION, CREATION ELATION STATION. Email join*at*midnightwiki*dot*com to get an account and start editing.
Keeping a log of my questions and their answers on #haskell-beginners (freenode)
2016-07-29 08:11:07 +0200 <idonutunderstand> instance Functor ((->) r) where \n fmap = (.) 2016-07-29 08:11:25 +0200 <idonutunderstand> anyone feel like explaining what that means? 2016-07-29 08:12:59 +0200 <idonutunderstand> http://learnyouahaskell.com/functors-applicative-functors-and-monoids 2016-07-29 08:14:03 +0200 <freeside> :t (->) 2016-07-29 08:14:04 +0200 <lambdabot> parse error on input ‘->’ 2016-07-29 08:16:24 +0200 <flounders> idonutunderstand: How familiar are you with functor? 2016-07-29 08:16:58 +0200 <idonutunderstand> a functor is something that can be mapped over? that's the extent of my knowledge 2016-07-29 08:17:21 +0200 <idonutunderstand> like a tree, list, etc.? 2016-07-29 08:17:27 +0200 <freeside> Another instance of Functor that we've been dealing with all along but didn't know was a Functor is (->) r 2016-07-29 08:17:27 +0200 <flounders> :t fmap 2016-07-29 08:17:28 +0200 <lambdabot> Functor f => (a -> b) -> f a -> f b 2016-07-29 08:18:51 +0200 <flounders> Practing with type signatures helps make sense of it. 2016-07-29 08:19:12 +0200 <idonutunderstand> f a means apply the function f to argument a? 2016-07-29 08:19:22 +0200 <flounders> f is not a function here. 2016-07-29 08:19:32 +0200 <flounders> f is a type constructor. 2016-07-29 08:20:08 +0200 <freeside> although type constructors are functions 2016-07-29 08:21:03 +0200 <flounders> Let's look at a concrete type example. 2016-07-29 08:21:10 +0200 <flounders> :t fmap id [1,2,3] 2016-07-29 08:21:11 +0200 <lambdabot> Num b => [b] 2016-07-29 08:21:16 +0200 <flounders> Err. 2016-07-29 08:21:39 +0200 <flounders> :t flip fmap $ [1,2,3] 2016-07-29 08:21:40 +0200 <lambdabot> Num a => (a -> b) -> [b] 2016-07-29 08:21:56 +0200 <flounders> Nevermind. 2016-07-29 08:22:14 +0200 <flounders> Are you familiar with Maybe and Lists? 2016-07-29 08:23:11 +0200 <idonutunderstand> is a list just a sequence of things? 2016-07-29 08:23:26 +0200 <idonutunderstand> I have no idea what Maybe is 2016-07-29 08:23:42 +0200 <flounders> List is kind of that way yeah. 2016-07-29 08:23:57 +0200 <flounders> Alright Maybe is a type that has too data constructors. 2016-07-29 08:24:13 +0200 <idonutunderstand> okay 2016-07-29 08:24:15 +0200 <flounders> It's defined this way: data Maybe a = Just a | Nothing. 2016-07-29 08:24:36 +0200 <flounders> As you learn more about type classes Maybe tends to be the first example referenced. 2016-07-29 08:25:00 +0200 <flounders> In a type signature all we will see is something like Maybe a or Maybe Int. 2016-07-29 08:25:01 +0200 <idonutunderstand> yeah I've heard it referenced before 2016-07-29 08:25:13 +0200 <idonutunderstand> what is Just? 2016-07-29 08:25:44 +0200 <flounders> Just is a data constructor. So if we want to use a Maybe value we would have something like Just 1 or Just 'c' or Nothing. 2016-07-29 08:26:12 +0200 <idonutunderstand> does | mean or?' 2016-07-29 08:26:19 +0200 <flounders> Pretty much. 2016-07-29 08:26:31 +0200 <idonutunderstand> :t Just 1 2016-07-29 08:26:32 +0200 <lambdabot> Num a => Maybe a 2016-07-29 08:26:45 +0200 <idonutunderstand> what did I just do lol 2016-07-29 08:26:57 +0200 <flounders> You just asked what the type signature for that value was. 2016-07-29 08:27:00 +0200 <flounders> Congrats. 2016-07-29 08:27:03 +0200 <idonutunderstand> no pun intended 2016-07-29 08:27:25 +0200 <flounders> Now Maybe has an instance for the Functor typeclass. 2016-07-29 08:27:47 +0200 <chlong> :t Maybe 1 2016-07-29 08:27:48 +0200 <lambdabot> Not in scope: data constructor ‘Maybe’ 2016-07-29 08:27:48 +0200 <lambdabot> Perhaps you meant variable ‘maybe’ (imported from Data.Maybe) 2016-07-29 08:27:53 +0200 <flounders> So when we use fmap on a Maybe value the type signtaure will look like this: fmap :: (a -> b) -> Maybe a -> Maybe b. 2016-07-29 08:29:19 +0200 <idonutunderstand> I still don't understand data Maybe a = Just a | Nothing 2016-07-29 08:29:25 +0200 <idonutunderstand> what's going on there? 2016-07-29 08:29:35 +0200 <flounders> That is just defining a data type. 2016-07-29 08:30:08 +0200 <idonutunderstand> my knowledge would say that Just a | Nothing is a function returning a bool 2016-07-29 08:30:34 +0200 <Axman6> where does it say bool there? 2016-07-29 08:31:08 +0200 <freeside> can i have a go at explaining? i think i may be able to help correct some misconceptions, from first principles. 2016-07-29 08:31:10 +0200 <idonutunderstand> nowhere but if | is like or 2016-07-29 08:31:19 +0200 <Axman6> what that says is: something of type Maybe a (for any a) is either Nothing (with no other data within the constructor) OR Just with an a in it 2016-07-29 08:31:22 +0200 <flounders> freeside: Have a go at it. 2016-07-29 08:31:31 +0200 <freeside> i'm going to talk about basketball hoops and basketballs. 2016-07-29 08:31:32 +0200 <idonutunderstand> or returns a bool in e.g. c++ 2016-07-29 08:31:44 +0200 <freeside> think of a hoop, through which you can toss things. that's a function: it takes input, and produces output. a basketball hoop takes basketballs as input, and produces basketballs as output. so a basketball hoop is an example of an `id` function, of type Basketball -> Basketball. 2016-07-29 08:31:54 +0200 <freeside> the `show` function is a hoop; if you throw an Int through it, a String will come out the other side. got that? 2016-07-29 08:33:00 +0200 <freeside> next big idea: think of a box, in which you can put things. that's a parametric type: the things in the box have a type, but the box also has a type. so, if your box is good at holding lots of ints, you've got a List of Ints, or a [Int]. if your box can only hold either one Int or nothing, you're dealing with the `Maybe Int` type. If there's an Int in the box, with a value of 10, you've got a `Just 10`. If there's nothing in the box, 2016-07-29 08:33:00 +0200 <freeside> you've got a `Nothing`. 2016-07-29 08:33:53 +0200 <freeside> so, you can have a type `Maybe Basketball`, whose possible values are either `Nothing` -- the box is empty -- or `Just Wilson`. 2016-07-29 08:37:38 +0200 <freeside> you can also have a box of basketballs: [Basketball] 2016-07-29 08:38:15 +0200 <idonutunderstand> okay 2016-07-29 08:38:24 +0200 <idonutunderstand> nice 2016-07-29 08:38:27 +0200 <freeside> now, imagine yourself taking something out of a box, tossing it through the hoop, grabbing what comes out, and sticking it back in the same kind of box. 2016-07-29 08:38:46 +0200 <idonutunderstand> okay 2016-07-29 08:38:50 +0200 <freeside> any box that allows you to take things out, toss through hoop, and put things back, is a functor. 2016-07-29 08:39:12 +0200 <idonutunderstand> i.e. it can be mapped over 2016-07-29 08:39:23 +0200 <idonutunderstand> ? 2016-07-29 08:39:40 +0200 <freeside> right. now, because there are different kinds of boxes, you have to define a different fmap function for each one. that's what it means for a type to be an instance of the Functor class. 2016-07-29 08:40:05 +0200 <freeside> now, i should point out that you don't actually put things back into the same box. 2016-07-29 08:40:24 +0200 <freeside> you take a thing out of the box, toss it through the hoop, and put it into the same kind of box on the other side of the hoop. 2016-07-29 08:40:55 +0200 <freeside> if your hoop is a `show`, then you're taking Ints out of your first box, turning them into Strings, and putting the Strings into a box of strings, which is a new box. 2016-07-29 08:41:13 +0200 <idonutunderstand> and that is something to do with non-mutability or something? 2016-07-29 08:41:20 +0200 <freeside> so what does it mean for it to be the same kind of box? if it was a Maybe box on the Int side, it's a Maybe box on the String side. 2016-07-29 08:41:24 +0200 <idonutunderstand> you can't change things? 2016-07-29 08:41:44 +0200 <freeside> yes. you always put things into a new box. you aren't allowed to change what's in a box. 2016-07-29 08:42:24 +0200 <freeside> similarly, the thing that comes out of the hoop is a new thing. 2016-07-29 08:42:46 +0200 <freeside> it's not the old thing that has been overwritten -- that's an idea from imperative programming. 2016-07-29 08:43:33 +0200 <idonutunderstand> roger that 2016-07-29 08:43:34 +0200 <freeside> so, Maybe is an instance of the Functor class, which means if you have a "Just 10", that's an Int in a Maybe box. 2016-07-29 08:43:56 +0200 <freeside> and it's possible to fmap the Just 10. 2016-07-29 08:44:20 +0200 <freeside> if you `fmap show`, the 10 turns into a string "10", and you finish off with a Just "10". 2016-07-29 08:44:36 +0200 <freeside> if you `fmap (*2)`, the 10 turns into an Int 20, and you finish with a Just 20. 2016-07-29 08:44:58 +0200 <freeside> > fmap (*2) (Just 10) 2016-07-29 08:45:00 +0200 <lambdabot> Just 20 2016-07-29 08:45:20 +0200 <freeside> so, that tells us that Maybe is a Functor, because it supports unboxing, hooping, and reboxing. 2016-07-29 08:45:33 +0200 <freeside> for completeness, we should 2016-07-29 08:45:36 +0200 <freeside> > fmap (*2) (Nothing) 2016-07-29 08:45:38 +0200 <lambdabot> Nothing 2016-07-29 08:45:52 +0200 <freeside> if there's nothing in the box, we multiply it *2, and get Nothing back. 2016-07-29 08:46:06 +0200 <freeside> this is exactly the same idea that underlies the NaN value in other languages. 2016-07-29 08:46:19 +0200 <freeside> NaN in other languages is a Maybe Int whose value is Nothing. 2016-07-29 08:46:42 +0200 <freeside> Nan * 2 = Nan 2016-07-29 08:47:32 +0200 <freeside> now, List is also a Functor, because if you have a box containing a dozen Ints, you can fmap (*2) them, and get back another box with a dozen Ints, that are twice the value of the ints in the original box. 2016-07-29 08:47:43 +0200 <freeside> > fmap (*2) [1,2,3] 2016-07-29 08:47:44 +0200 <lambdabot> [2,4,6] 2016-07-29 08:49:27 +0200 <freeside> does all that make sense? you need to understand hoops and boxes before we can go back to what Learn You A Haskell was trying to say about `Functor ((->) r)` 2016-07-29 08:57:17 +0200 <idonutunderstand> more or less yeah! 2016-07-29 08:57:27 +0200 <freeside> now, what happens if you have two basketball hoops, one right beneath the other? you toss a basketball in the top hoop, and the same basketball comes out. then it falls through the lower hoop, and the same basketball comes out. so, that's two id functions in a row. 2016-07-29 08:57:28 +0200 <idonutunderstand> i think my mind needs a rest 2016-07-29 08:57:41 +0200 <freeside> okay, i'm just going to get out the rest of what i have to say, because my battery is about to go flat. 2016-07-29 08:57:47 +0200 <freeside> you can come back and read it later. 2016-07-29 08:57:54 +0200 <idonutunderstand> k :) 2016-07-29 08:58:03 +0200 <freeside> so, here are two hoops, one above the other, hanging free in space. 2016-07-29 08:58:31 +0200 <freeside> well, first, here are a couple of basketballs. 2016-07-29 08:58:32 +0200 <freeside> > data Basketball = Wilson | Spalding deriving Show 2016-07-29 08:58:34 +0200 <lambdabot> <hint>:1:1: parse error on input ‘data’ 2016-07-29 08:58:45 +0200 <freeside> mmm. i don't know how to drive the bot. 2016-07-29 08:58:52 +0200 <freeside> but it works in ghci. 2016-07-29 08:59:03 +0200 <freeside> here's a basketball going through one hoop: 2016-07-29 08:59:15 +0200 <freeside> > id Wilson 2016-07-29 08:59:16 +0200 <lambdabot> Not in scope: data constructor ‘Wilson’ 2016-07-29 08:59:24 +0200 <freeside> here's a basketball going through two hoops: 2016-07-29 08:59:31 +0200 <freeside> > id (id Wilson) 2016-07-29 08:59:32 +0200 <lambdabot> Not in scope: data constructor ‘Wilson’ 2016-07-29 09:00:18 +0200 <freeside> now, let's pretend we want to wire these two hoops together, because in Donald Trump's America nothing is left to chance: 2016-07-29 09:00:21 +0200 <freeside> > (id . id) Wilson 2016-07-29 09:00:23 +0200 <lambdabot> Not in scope: data constructor ‘Wilson’ 2016-07-29 09:00:55 +0200 <freeside> that's function composition. 2016-07-29 09:01:40 +0200 <freeside> now, Learn You A Haskell is trying to explain how ((->) r) can be a Functor instance. 2016-07-29 09:03:01 +0200 <freeside> it previously (i hope) explained how Maybe can be a Functor instance, and how List can be a Functor instance. 2016-07-29 09:04:08 +0200 <freeside> so, when it is talking about ((->) r), it's also talking about a type, in the same way. 2016-07-29 09:04:14 +0200 <freeside> except this type is not a box. this type is a function. 2016-07-29 09:04:37 +0200 <idonutunderstand> woah 2016-07-29 09:05:03 +0200 <idonutunderstand> that makes no sense to me 2016-07-29 09:05:21 +0200 <freeside> okay, that's why i spent so much time setting up this convoluted metaphor. what we have here is a box that doesn't contain basketballs. this is a box that contains hoops. 2016-07-29 09:05:31 +0200 <freeside> and what you're about to do is take a hoop out of the box and throw it through another hoop. 2016-07-29 09:05:48 +0200 <idonutunderstand> AWESOME 2016-07-29 09:06:11 +0200 <freeside> and when you do that, what you get back is equivalent to two hoops wired together, with the (.) operator. 2016-07-29 09:06:20 +0200 <freeside> that's the point they're trying to make. 2016-07-29 09:07:15 +0200 <freeside> that's what it means for a function to also be a functor. it's a box that allows you to take things out and throw them through hoops and put them back in a new type of box. it's just that the things in the box are also hoops. 2016-07-29 09:07:23 +0200 <freeside> and that's what it means for Haskell to have first-class functions. 2016-07-29 09:07:56 +0200 <idonutunderstand> I love this channel 2016-07-29 09:14:36 +0200 <freeside> hm. this hoop metaphor is actually quite productive. a function (of arity 1) takes a thing and produces a thing: `simple :: a -> b`. simplistically, a function of arity 2 takes a thing, and another thing, and produces a thing: `arity2 :: a -> b -> c`. but that's not what's really happening; it's a convenient shorthand, what the buddhists would call Upaya. 2016-07-29 09:15:35 +0200 <freeside> it looks like you're tossing basketball `a` and basketball `b` through the one hoop, in sequence, and the hoop swallows them both and gives you back a basketball `c`. 2016-07-29 09:16:09 +0200 <freeside> but that's not actually true. so let's slow it down on replay. what is REALLY happening is this. when you toss the first basketball `a` through, the hoop emits another hoop. 2016-07-29 09:16:22 +0200 <freeside> then you toss the second basketball `b` through that hoop, and you get back the final basketball `c`. 2016-07-29 09:23:04 +0200 <freeside> now, if you read that chapter again, thinking about hoops and balls and boxes, it should be easier to grasp this time around. 2016-07-29 09:45:16 +0200 <freeside_> A hoop rather simplifies the concept of a function. If you were to watch what happens on super-slo-mo, at the instant something drops into the hoop (execution), tiny manipulators emerge from the rim of the hoop to grasp the incoming object. Then they go quiet. Nothing happens until the game demands an emission from the hoop. Then the manipulators actually get to work. What do they do? Well, it dep 2016-07-29 09:45:17 +0200 <freeside_> ends on the hoop. Every function is different. Every hoop is different. Earlier we talked about fmap, and I said that you grab things out of the box and toss them through a hoop and put them into a new box. Well, it's not really you, the programmer, who does that; it's the fmap function that does it, with its little manipulators. You can think of it as holding the box with one hand, pulling things 2016-07-29 09:45:17 +0200 <freeside_> out with another hand, and shoving them through a hoop held in a third hand. 2016-07-29 09:55:31 +0200 <freeside> now, of course, that's not what's really going on either. when you drop a hoop (a -> b) into the fmap hoop, you get back another hoop, which expects a functor (f a). when you drop a functor into *that* hoop, then it's in a position to start tossing basketballs (a) through the (a -> b) function. 2016-07-29 09:56:18 +0200 <srhb> ... 2016-07-29 09:56:22 +0200 <freeside> but even then it doesn't actually shove things through the hoop; the action only happens on demand, when things are actively being pulled out of it; that's evaluation. 2016-07-29 09:56:27 +0200 <freeside> because lazy evaluation. [19:15] <idonutunderstand> suuuuuuuup [19:16] <idonutunderstand> > Just a | Maybe a [19:16] <lambdabot> <hint>:1:8: parse error on input ‘|’ [19:23] <idonutunderstand> can I think of Maybe a as a box that has an a in it or a Nothing in it? [12:14] == idonutunderstand [ade40c27@gateway/web/freenode/ip.18.104.22.168] has joined #haskell-beginners [12:14] <idonutunderstand> lucky :: (Integral a) => a -> String [12:15] <idonutunderstand> what is the purpose of the (Integral a)? [12:17] <michaelt> It means it works for Int and Integer both [12:17] <nitrix> idonutunderstand: Have you seen type classes yet? [12:17] <michaelt> you can write the more specialized type `lucky :: Int -> String` if you like [12:18] <michaelt> idonutunderstand: also, when you wrote lucky you probably used a literal like `0` or something. If you write `(0 :: Int)` the whole function will get specialized to Int -> String [12:20] <nitrix> idonutunderstand: `a -> String`, the `String` is a type, and `a` is a type variable; it means the function is polymorphic and lets you choose which type you want `a` to be. In your case, the function lucky goes a step further and constraint the types possible that are acceptable for `a` with the constraint `Integral a`, meaning the type chosen must be an instance of the Integral type class. [12:20] <nitrix> idonutunderstand: Word, Integer, Int for example. [12:21] <nitrix> idonutunderstand: You can get a list of the instances of a given type class by typing :info Integral, in GHCi. [12:22] <nitrix> They are also listed in the documentation on hackage. [12:22] <nitrix> idonutunderstand: So far so good? I can give a few concrete examples to clarify. [12:31] <Fernando-Basso> I just saw there is a course on functional programming on coursera. [12:31] <Fernando-Basso> It is in Scala. How much of that is useful in haskell? [12:31] <nitrix> Fernando-Basso: You'll get introduced to functional concepts, sure, but it will be nowhere like Haskell. [12:35] <nitrix> You'll learn basics like recursive functions, lambda, algebraic data types, but the type system in generic is much inferior (especially in regards to purity). [12:35] <nitrix> *in general [12:35] <Fernando-Basso> Okay, I was just curious as I just received a newsletter about that course. [12:36] <nitrix> I don't want to deceive you from learning Scale though, but I'm not an Haskell saleperson either. [12:36] <nitrix> You learn Haskell if you want to learn Haskell :) [12:37] <nitrix> I've stopped trying to convince people. It's better if they come by themselves ;) [12:37] <Fernando-Basso> I want to lear something that makes me think differently than I currently do (sql, php, js, ruby, c and some common lisp). [12:38] <Fernando-Basso> And perhaps use this new way of thinking in the workplace in the (distant) future. [12:38] <nitrix> I watched Chris lambdaconf talk right after you. [12:38] <nitrix> How did you like it? [12:38] <Fernando-Basso> Not very much, actually. [12:39] <nitrix> It seemed like he was more describing his the process that went into his book and the quality of the ecosystem in general. [12:39] <Fernando-Basso> It sounded good up to those 6 minutes, but then it kind didn't give something actionable. [12:39] <nitrix> For... let's say "an outsider", it's not a talk that's pertinent or particuliarly encouraging. [12:40] <nitrix> But it did address very serious concerns. [12:40] <Fernando-Basso> But he was honest and humble about his ideas. [12:40] <Fernando-Basso> But he warned he would not "teach" things. [12:41] <nitrix> Myup :] [12:41] <Fernando-Basso> I have trouble with programming material. Always had. [12:41] <Fernando-Basso> I mean, material for learning how to program. [12:41] <nitrix> Give a look to LYAH in the meantime, I'm sure it'll prompt a lot of discussions. [12:42] <Fernando-Basso> Much of the stuff I see is kind of just restating man pages. [12:43] <nitrix> It's not as good as the haskellbook, but hey, it's fun. [12:43] <nitrix> data Maybe a = Just a | Nothing [12:43] <Fernando-Basso> I am finishing week 1 of cis194. [12:43] <nitrix> > fmap (+1) (Just 5) [12:43] <lambdabot> Just 6 [12:43] <nitrix> > fmap (+1) Nothing [12:43] <lambdabot> Nothing [12:44] <nitrix> I think the first chapters goes quickly into Functors, and I remember, I was like "whhhao, this is actually going to be very useful". [12:45] <nitrix> Especially because PHP uses a dynamic type system and you end up going many checks agaisn't false/0/null all the time. [12:45] <Fernando-Basso> Yep. [12:45] <nitrix> This `Maybe` type in Haskell looked very cool at the time :P [12:46] <Fernando-Basso> I did not get there yet. [12:47] <nitrix> And then I started playing with IOs. [12:47] <nitrix> forever $ getLine >>= putStrLn [12:47] <nitrix> That's an infinite loop that gets a line from the user and echos it back. [12:47] <nitrix> Fascinating stuff :P [12:48] <nitrix> Infinite lists too! [1..] [12:48] <nitrix> And you could take elements from infinite lists, how the hell was that even possible, wouldn't it use all the memory? [12:48] == Motoko11 has changed nick to Moto-chan [12:48] <nitrix> > take 10 [1..] [12:48] <lambdabot> [1,2,3,4,5,6,7,8,9,10] [12:49] <nitrix> Looked very magical indeed :P [12:51] <Fernando-Basso> :) [12:52] <Fernando-Basso> Scala is not pure, it seems. [12:53] <nitrix> And then I put haskell away and a I had a competition with a friend and I had to write the look-and-say sequence A005150 (https://oeis.org/A005150). [12:53] <Fernando-Basso> I prefer haskell because “I admire its purity.” ☺ [12:53] <nitrix> And he wrote... [12:53] <nitrix> @let lookAndSay = read . concatMap (liftM2 (++) (show . length) (take 1)) . group . show [12:53] <lambdabot> Defined. [12:53] <nitrix> > lookAndSay 13112221 [12:54] <lambdabot> *Exception: Prelude.read: no parse [12:54] <nitrix> Whoops. [12:54] <nitrix> > lookAndSay 13112221 :: Integer [12:54] <lambdabot> 1113213211 [12:54] <nitrix> > lookAndSay 1113213211 :: Integer [12:55] <lambdabot> 31131211131221 [12:55] <nitrix> And I was like, what kind of sorcery is that. [12:55] <Fernando-Basso> :) [12:55] <nitrix> His program was just a bunch of small words very generic and powerful, and mine was line, ~300 lines of code in PHP and I was still debugging a bug. [12:56] <Fernando-Basso> But how to get to that result in haskell? It does require math mastery as well as haskell mastery, doesn't it? [12:56] <nitrix> The look-and-say stuff? [12:56] <Fernando-Basso> Yep. [12:56] <Fernando-Basso> And that solution to it. [12:57] <nitrix> Nah it's a sequence that people learn for fun for IQ stuff. [12:57] <nitrix> You simply state the amount of repetition of the number there is, then the number itself. [12:57] <nitrix> 123 would come 111213 (one 1's, one 2's, one 3's). [12:58] <nitrix> 111213 becomes 31121113 (three 1's, one 2's, one 1's, one 3's). [12:58] <Fernando-Basso> ah, I see. [12:58] <Fernando-Basso> But I _bet_, although php is not even near haskell, your 300 lines is not purely php's fault, is it? [12:59] <nitrix> It was just a challenge between him and I because it was something we both thought would be trivial to implement. [12:59] <nitrix> Turns out, PHP doesn't do really well with recursion. [12:59] <Fernando-Basso> And I bet if _I_ tried that in haskell today, I would take many more lines than your friend's version. [12:59] <Fernando-Basso> No, it realy does not. [13:00] <nitrix> When you get to really large numbers, it exploded. I had to change my recursive function to a loop with 3 state variables, and update them carefully with five different iterators and soon the code because very confusing. [13:00] <nitrix> I was juggling plenty of variables, with meaningless names because it was a race... and the weight of the situation eventually became obvious. [13:01] <nitrix> > lookAndSay 6663245777732434346666234232222111134769923493243 :: Integer [13:01] <lambdabot> 36131214154713121413141314461213141213424113141716291213141913121413 [13:01] <Fernando-Basso> I saw that "haskell for C programmers" pdf. It really shows haskell conciseness compared to C. [13:01] <nitrix> Haskell has no troubles with large numbers :P [13:02] <Fernando-Basso> It looks to me that haskell is a "large" language, though. [13:03] <Fernando-Basso> Some languages are smaller (less functions and stuff to learn). [13:03] <nitrix> No, it's actually very minimal. [13:03] <nitrix> https://www.haskell.org/onlinereport/haskell2010/ [13:03] <demize> nitrix: You can do bignums in PHP as well, though you need something like the GMP extension, yeh. [13:03] <nitrix> demize: Then you're playing with the gmp functions I think, it's still not a built-in type :/ [13:04] <demize> Sure. [13:04] <nitrix> Anyway, it's a long time ago, but boy that was fascinating. [13:04] <demize> I mean, the GMP and BC math extensions are both official extensions, part of PHP [13:04] <demize> But they're indeed extensions. [13:05] <nitrix> Fernando-Basso: The link above is the Haskell Report 2010, the equivalent of C standards. It describes the entirety of the language, the language is actually very small. People end up learning libraries and extensions, is what happens. [13:05] <Fernando-Basso> I see. [13:05] <nitrix> Fernando-Basso: https://hackage.haskell.org/package/base [13:06] <nitrix> Fernando-Basso: Even the `base` library, is just that, a library. [13:06] <nitrix> It's what's enough to implement the GHC compiler, so that it's able to compile itself. [13:06] <Fernando-Basso> I am heading home. Se you folks later. [13:06] <Fernando-Basso> nitrix: I'll take a look as soon as I get home. Thanks. [13:53] <idonutunderstand> nitrix: michaelt: have to run [13:53] <idonutunderstand> i will check this later [13:53] <idonutunderstand> thanks
Here's the logging service I'm using:
"If you done had eight careers, your ass is dissatisfied." —Ann
moving back and forth, swaying,
it's amalgamated from the posterior,
can't i remember what it is?
it's something to do with combat,
yes, it's clear now, that this life is a fight.
Yo what if we are computers but we don't realize it? Like we are building AI but we don't realize that it is a reflection of ourselves being built?
A more efficient way to learn math?
Moving quickly over massive amounts of material, just soaking it in, "getting used to it"