Available formats: content-negotiated html turtle (see SIOC for the vocabulary)
Back to channel and daily index: content-negotiated html turtle
These logs are provided as an experiment in indexing discussions using IRCHub.py, Irc2RDF.hs, and SIOC.
| 00:00:30 | <u_quark> | yes memoization :$ |
| 00:00:44 | <u_quark> | damn you spell checker |
| 00:00:55 | <Saizan> | http://www.haskell.org/haskellwiki/Memoization#Memoising_CAFS <- something like this |
| 00:02:06 | <u_quark> | yes Saizan! tnx |
| 00:11:56 | <hatds> | what would you call 'equality' between things that are mutable? |
| 00:12:09 | <hatds> | i.e., for things that support a function a -> a -> IO Bool |
| 00:16:27 | <aavogt> | @type liftM2 (==) `on` readIORef |
| 00:16:29 | <lambdabot> | Not in scope: `readIORef' |
| 00:16:32 | <mmorrow> | pumpkin: TH-generated fully unrolled fft's for powers of 2 up to 64: http://moonpatio.com/repos/ffts_upto_64.hs |
| 00:16:40 | <pumpkin> | mmorrow: I saw, that looks wonderful |
| 00:16:51 | <aavogt> | @type liftM2 (==) `on` (undefined :: a -> IO a) |
| 00:16:52 | <lambdabot> | forall a1. (Eq a1) => a1 -> a1 -> IO Bool |
| 00:17:02 | <mmorrow> | pumpkin: pure-fft take 4.2 seconds on 10,000 size-64 vectors, and that code takes 0.8 seconds :) |
| 00:17:09 | <pumpkin> | wow, how does fftw compare? |
| 00:17:18 | <pumpkin> | we have a binding to it already I think |
| 00:17:21 | <mmorrow> | i'm not sure, haven't tested thatr yet |
| 00:17:33 | <mmorrow> | but i haven't even started using efficient data reps yet either :) |
| 00:17:35 | <pumpkin> | nice |
| 00:17:45 | <pumpkin> | mmorrow: you going to work into making a real library out of this? |
| 00:18:03 | <mmorrow> | i changed my mind, i think lightning-fast fft's could be /generated/ in haskell |
| 00:18:12 | <mmorrow> | pumpkin: i think so yes |
| 00:18:12 | <pumpkin> | I can't think of any fft uses who decide the size of their fft on the fly, so TH-generated FFTs is actually a good idea |
| 00:18:49 | <mmorrow> | pumpkin: here's the Vector type i think i'm gonna use http://moonpatio.com/fastcgi/hpaste.fcgi/view?id=2597 |
| 00:19:13 | <pumpkin> | that's awesome |
| 00:19:20 | <mmorrow> | pumpkin: i'll stick all the code in a repo shortly so it's accessible |
| 00:19:21 | <pumpkin> | does GHC start throwing up on bigger ones than that? |
| 00:19:44 | <mmorrow> | not sure yet, but i bet we could get at least Vec1024's |
| 00:19:57 | <pumpkin> | someone really needs to work on putting SSE support into the codegen |
| 00:20:01 | <pumpkin> | ACTION whistles |
| 00:20:14 | <mmorrow> | (the nice thing is is that there's no static data sitting around, those Vec types are just used in generated code's pattern matches |
| 00:20:28 | <pumpkin> | yeah |
| 00:20:50 | <mmorrow> | compiling http://moonpatio.com/repos/ffts_upto_64.hs takes about 4 seconds i'd say |
| 00:23:38 | <pumpkin> | not too bad |
| 00:23:56 | <pumpkin> | I wonder how big a statically unrolled 1024 fft would be (in terms of code size) |
| 00:25:06 | <pumpkin> | mmorrow: any idea of how much space your fft 64 funcion uses? compared to fft 32? |
| 00:26:45 | <mmorrow> | you mean at runtime wrt allocation? |
| 00:26:54 | <pumpkin> | I mean the generated code size |
| 00:27:04 | <mmorrow> | oh, asm? |
| 00:27:24 | <mmorrow> | 67254 ffts_upto_64.s |
| 00:27:28 | <mmorrow> | [m@monire src]$ wc -l ffts_upto_64.s |
| 00:27:37 | <pumpkin> | ah, not too bad |
| 00:27:41 | <mmorrow> | (that's for all of them <64) |
| 00:28:05 | <mmorrow> | yeah, considering it's the same few hundred lines repeated hundreds of times :) |
| 00:28:36 | <mmorrow> | (the asm looks pretty good actually, i think it could look really good with those types with everything unpacked into the constructor) |
| 00:29:07 | <mmorrow> | (e.g., for Vec64, it has 126 Double#s unpacked into its closure) |
| 00:29:22 | <mmorrow> | so it's essentially an unboxed array that you can pattern match on |
| 00:29:34 | <mmorrow> | (instead of index into with ints) |
| 00:44:44 | <kyevan_> | Hmm. Does anyone know if OS X has a quick way to type λ? >_< |
| 00:44:52 | <kyevan_> | (slightly-offtopic) |
| 00:46:00 | <mriou> | what would be the easiest to convert an Integer to a string (byte by byte -> char)? |
| 00:46:04 | <Striki> | +OK OfRzI0ip62G.YBuDA.ZkGn/0v9k8Y/JQZS70M9n0C1wRxmx/W24n1/45pu2.SGJjw.C2e2q/6lRVG/9mzpq.AyBWj.F6h700YI/8V0rZOmT0 |
| 00:46:09 | <Striki> | +OK SGsS/.Pkanp/ |
| 00:46:17 | <bd_> | Striki: what? |
| 00:46:35 | <Striki> | +OK RlX9Q/sYORE1kYWPq1ige/B0tq.eJ1T6s8U1Hyjpz1DCFBd.DdiRc/Md3Da0 |
| 00:46:36 | <dino-> | > show 42 |
| 00:46:37 | <lambdabot> | "42" |
| 00:46:41 | <dino-> | mriou: ^ |
| 00:47:04 | <mriou> | dino I'm looking for byte by byte conversion |
| 00:47:22 | <mriou> | like 80 would be 'P' |
| 00:47:22 | <dino-> | mriou: If you want something fancier, I tend to go with printf. Say, leading zeroes, etc.. |
| 00:47:53 | <dino-> | > Data.Char.ord 'P' |
| 00:47:54 | <lambdabot> | 80 |
| 00:48:25 | <mriou> | dino yep but then I'm missing how to slice an integer into its successive bytes |
| 00:48:45 | <mriou> | like 2018155139523098493 |
| 00:49:04 | <bd_> | mriou: data.bits is one option. There's probably a more efficient way. |
| 00:50:10 | <mriou> | bd_ yeah I couldn't find better which is why I was asking |
| 00:50:22 | <mriou> | but I guess I'll have to do that |
| 00:50:41 | <bd_> | data.binary might work. Or you could try decomposing the GHC.Num.J# constructor in the implementation. |
| 00:51:35 | <pumpkin> | bd_: I wouldn't do it that way |
| 00:51:57 | <pumpkin> | mriou: so you want a base-2^8 representation of the integer? |
| 00:52:20 | <mriou> | pumpkin: yep |
| 00:53:15 | <pumpkin> | mriou: might be best to just use an unfoldr'd divMod or quotRem for now, using the J# constructor would be really easy (if you don't mind ByteArray# reading) but it's likely to change soon |
| 00:53:28 | <mriou> | I was hoping something like: splitInteger:: Integer -> Word8 |
| 00:53:35 | <pumpkin> | [Word8] ? |
| 00:53:43 | <mriou> | huh yeah |
| 00:55:05 | <mriou> | didn't know about divMod, that might make it slightly better |
| 00:58:13 | <shapr> | What did Striki say? |
| 01:04:00 | <shapr> | I'm trying to cabal install bamboo, but I get "base-4.0.0.0 was excluded because of the top level dependency base -any" |
| 01:04:41 | <dcoutts> | shapr: it's not printing all the info |
| 01:05:11 | <dcoutts> | shapr: what it doesn't say about the dependency "base -any" is that it's a restriction on it being installed |
| 01:05:29 | <dcoutts> | ie, it must pick an installed version of base, not one that's available from hackage |
| 01:05:51 | <dcoutts> | shapr: and you're presumably using ghc-6.8.x which has base 3 and not 4, but you're trying to install a package that uses base 4 |
| 01:05:58 | <shapr> | dcoutts: http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5673#a5673 ? |
| 01:06:12 | <dcoutts> | shapr: cabal can see that there's base 4 on hackage, but it's trying to pick an installed one |
| 01:06:16 | <dcoutts> | hence the conflict |
| 01:06:25 | <shapr> | huh |
| 01:06:35 | <skorpan> | yeah, huh? |
| 01:06:53 | <skorpan> | geez, bamboo had a *lot* of dependencies.. |
| 01:07:00 | <shapr> | dcoutts: thanks |
| 01:07:09 | <dcoutts> | shapr: did that make ant sense? |
| 01:07:16 | <Eiler> | does haskell have anything (package) that can evaluate haskell code at runtime.. besides hs-plugins? |
| 01:07:17 | <shapr> | Yes, actually it did. |
| 01:08:03 | <gwern> | Eiler: ghc api. the best maintained wrapper over it is probably hint |
| 01:09:29 | <Eiler> | cool |
| 01:12:14 | <Eiler> | got another question also. I want to make a program that works like: write a couple of functions, let the user write in functionnames in console where they should be called and print out the value. Say we got factorial:: Integer -> Integer, the user should be able to write: factorial 5, and the program should print out 120. Would this be hard to do? |
| 01:13:08 | <shapr> | dcoutts: That's exactly it, it seems I installed and built cabal et al for 6.8.2 |
| 01:13:13 | <shapr> | foozle |
| 01:14:08 | <Cale> | Eiler: It's not entirely trivial if you want to evaluate arbitrary Haskell expressions, but it's also not too hard. |
| 01:14:24 | <Cale> | Eiler: Have a look at the documentation for hint on Hackage. |
| 01:14:42 | <rwanderley> | hi, I want to try out web programming in haskell. I saw 2 alternatives, happstack and cgi. Do you guys recommend any of this two? |
| 01:15:04 | <pumpkin> | does anyone remember a book that isn't TAPL called something like "type systems for functional languages?" |
| 01:15:16 | <pumpkin> | someone mentioned it in here a few days ago but I can't find it in the logs |
| 01:15:31 | <Eiler> | Cale: yeah, looking at the hint documentation now |
| 01:16:00 | <Eiler> | Cale: well it dont really have to evaluate whole expression, just a functioncall at a time |
| 01:17:27 | <Cale> | Eiler: Well, if you want to do something more static, you might write a parser for the syntax of the input, and have something like a table of possibilities. |
| 01:18:22 | <Eiler> | eww the haskell logo has changed |
| 01:18:53 | <pumpkin> | lol, the one before was eww-worthy |
| 01:19:43 | <Eiler> | Cale: ye well the syntax should just be: functionname arg1 arg2 ... |
| 01:20:19 | <Saizan> | if you've a DAG, how'd you find all the possible paths excluding those that are subpaths of others? |
| 01:22:46 | <QtPlaty[HireMe]> | Saizan: I would take it in to steps. |
| 01:22:51 | <Cale> | Saizan: Start by picking a vertex with no incoming arcs, then find all the maximal paths which start there and. |
| 01:22:53 | <Cale> | er |
| 01:23:03 | <Cale> | and end when there are no outgoing arcs |
| 01:23:15 | <QtPlaty[HireMe]> | I would find all possable paths and then eleminate the subpaths. |
| 01:24:26 | <Cale> | QtPlaty[HireMe]: You know that all the maximal paths start at a vertex with no incoming arcs though, since if there was an incoming arc, you could add the vertex it came from to your path. |
| 01:24:43 | <Cale> | (and it certainly isn't already in your path, because that would lead to a cycle) |
| 01:24:47 | <QtPlaty[HireMe]> | Cale: True so you can eleminate that step. |
| 01:26:03 | <Saizan> | if you've many sources the maximal paths will probably share many subpaths too, maybe this can be done with some dynamic programming approach, starting from the sinks |
| 01:26:11 | <Cale> | and a maximal path can't end at a vertex which has an outgoing arc, since if it does, then you could add the vertex which that arc leads to and extend your path (and again, it can't already be in your path, since the graph is acyclic) |
| 01:26:22 | <Saizan> | where source = no incoming arc, sink = no outgoing arc |
| 01:28:06 | <Cale> | Well, hmm... |
| 01:28:25 | <Cale> | If you know that your DAG has some special structure, then you can perhaps make use of that. |
| 01:28:58 | <Cale> | Like, if you know that every path goes through one particular vertex, you can split up the problem through that vertex and take a Cartesian product. |
| 01:29:41 | <Cale> | But I'm not sure how much that really helps |
| 01:30:08 | <Saizan> | actually, it's not really a DAG, i've something like uncurried functions returning many results, so they connect N vertexes to M others at once |
| 01:34:58 | <shapr> | C# makes me feel pretty stupid. Haskell makes me feel smart. |
| 01:35:36 | <SamB> | C# makes me feel like |
| 01:35:42 | <SamB> | ... like I need a bigger hard drive |
| 01:35:47 | <shapr> | At least part of that is that there's a whole lot of stupid pre-baked into the Microsoft stuff. Sometimes when I just can't solve the problem, I later discover it's because the library I got from Microsoft is broken. |
| 01:36:23 | <SamB> | of course, lots of things do that these days ;-) |
| 01:36:58 | <shapr> | SamB: Yeah, Windows XP seizes and dies every week at least. I've had two Linux kernel panics since 1999, and one of them was because I was hot swapping IDE drives (Linux, and motherboards, don't support that). |
| 01:38:12 | <shapr> | I like Haskell :-) |
| 01:39:04 | <SamB> | hmm, I've been getting a lot of kernel panics lately, but most of them from bad boot options when trying to boot qemu ;-) |
| 01:52:25 | <TomMD> | I have lots of panics about kernels too... "!@#$! Did I just delete the only kernel I've gotten to work on this hardware?" |
| 01:54:07 | <dino-> | TomMD: heh. I include /boot in the nightly backups |
| 01:55:41 | <TomMD> | dino-: You've probably heard that some people keep a repository (e.g. darcs or git) of their critical directories. |
| 01:55:46 | <dino-> | SamB, shapr: Any chance of working in F# at these jobs? Would that even make a difference? |
| 01:56:53 | <dino-> | TomMD: Yes, I have heard that. Source control: It's not just for breakfast or source anymore. |
| 01:57:54 | <dino-> | I say that being nearly completely ignorant of F# other than something about it being MLish |
| 01:59:00 | <A1kmm> | Has anyone else been having problems with programs using the parallel GC crashing with ghc HEAD (for some programs)? |
| 02:11:34 | <SamB> | dino-: I never said I'd actually written anything in C# |
| 02:16:56 | <pumpkin> | QtPlaty[HireMe]: have you thought of putting [ForHire] instead of [HireMe] ? |
| 02:17:06 | <pumpkin> | imperatives may scare people |
| 02:17:49 | <dino-> | pumpkin[YouKnowYouWantMe] |
| 02:18:21 | <dino-> | @src ($!) |
| 02:18:21 | <lambdabot> | f $! x = x `seq` f x |
| 02:19:22 | <pumpkin> | :) |
| 02:19:43 | <pumpkin> | pumpkin[poorSoGiveHimLotsOfMoneyWithoutAskingForAnythingInReturn] |
| 02:20:18 | <ray> | ray[Bum] |
| 02:21:13 | <dino-> | So wait, when do you use seq? The evaluating first argument and discarding is confusing me. |
| 02:21:15 | <A1kmm> | Andrew[SighItOnlyCrashesWhenYouDontUse-debug] |
| 02:21:33 | <ray> | it evaluates whatever x is |
| 02:21:41 | <ray> | so when you use x somewhere else, it's evaluated |
| 02:21:42 | <pumpkin> | A1kmm: and I suppose running it in gdb doesn't give much useful information? |
| 02:21:51 | <pumpkin> | A1kmm: or does it crash in the RTS? |
| 02:22:04 | <A1kmm> | I haven't managed to get it to crash in debug mode. |
| 02:22:13 | <pumpkin> | I mean using the non-debug RTS |
| 02:22:21 | <A1kmm> | and the stack-trace is different every time otherwise. I suspect some sort of race condition. |
| 02:22:27 | <pumpkin> | ah :/ |
| 02:22:43 | <A1kmm> | It also only happens only when parallel GC is turned on. |
| 02:22:57 | <ray> | f x would normally start evaluating f, and only evaluate x when it needs to, if ever |
| 02:23:16 | <ray> | x `seq` f x evaluates x beforehand |
| 02:23:49 | <ray> | remember all that referential transparency junk, x is always the same x |
| 02:23:51 | <dino-> | Ok, but what about x `seq` y (where y has nothing to do with x)? |
| 02:24:05 | <ray> | basically, that's bottom if x is bottom, else it's y |
| 02:24:38 | <A1kmm> | pumpkin: Actually without debug the result is sometimes reasonable: #0 0x000000000067262c in schedule (initialCapability=<value optimized out>, task=0x994370) at rts/Schedule.c:672 |
| 02:25:02 | <pumpkin> | but it isn't always there? |
| 02:25:28 | <A1kmm> | 672 return (waiting_for_gc || |
| 02:25:30 | <A1kmm> | 673 cap->returning_tasks_hd != NULL || |
| 02:25:37 | <A1kmm> | (gdb) print cap |
| 02:25:39 | <A1kmm> | $2 = (Capability *) 0x0 |
| 02:25:43 | <pumpkin> | what kind of a crash? |
| 02:25:44 | <pumpkin> | oh |
| 02:25:46 | <A1kmm> | It seems to be consistent with this version of ghc. |
| 02:25:47 | <pumpkin> | so segfault? |
| 02:25:53 | <dino-> | ray: Thank you |
| 02:25:56 | <A1kmm> | Yeah, null deref it looks like. |
| 02:26:05 | <pumpkin> | so task isn't null, but cap is? |
| 02:26:25 | <pumpkin> | cause both seem to get dereferenced |
| 02:26:51 | <pumpkin> | A1kmm: how big is your failure case? can you reduce it enough to make it happen in a few lines maybe? |
| 02:27:51 | <pumpkin> | A1kmm: also, you said it doesn't happen in the debug RTS, but the function you point at is only present in the threaded RTS, so maybe you need a threaded debug RTS? |
| 02:27:59 | <A1kmm> | I tried earlier without success, but it looks different with the current HEAD vs one a few weeks ago, so maybe I should try a simple program. Although I earlier tried to work out which part of my Haskell code triggered it without much sucess. |
| 02:28:24 | <A1kmm> | pumpkin: Well, the debug RTS was using 800% CPU at one point, so I'm pretty sure it is threaded. |
| 02:28:38 | <pumpkin> | lol |
| 02:28:55 | <pumpkin> | how many capabilities did you give it? I found that if I gave mine too many it would max out my CPU and do almost nothing |
| 02:28:56 | <A1kmm> | Where 800% CPU means 100% of 8 CPUs (there are 24 in that system). |
| 02:29:04 | <pumpkin> | ah, wow |
| 02:29:54 | <A1kmm> | and it is computing a 10,000 element long list using computeAllMIs madata x = map (processMI madata) x `using` parListChunk 500 rnf |
| 02:31:37 | <idnar> | man, wikipedia |
| 02:31:40 | <idnar> | "One well-known (and perhaps the simplest) fixed point combinator in the untyped lambda calculus is called the Y combinator. It was discovered by Haskell B. Curry" |
| 02:31:48 | <pumpkin> | lol |
| 02:31:56 | <idnar> | that makes it sound like he was out for an afternoon stroll in the woods, and tripped over the Y combinator |
| 02:32:11 | <SamB> | idnar: sure! it almost ate him |
| 02:32:19 | <SamB> | @go alligator eggs |
| 02:32:24 | <lambdabot> | http://worrydream.com/AlligatorEggs/ |
| 02:32:24 | <lambdabot> | Title: Alligator Eggs! |
| 02:32:26 | <pumpkin> | he found the y combinator in someone's botom |
| 02:32:51 | <aavogt> | Is Y the same as fix? |
| 02:34:04 | <SamB> | no, Y isn't allowed in Haskell |
| 02:36:02 | <aavogt> | SamB: so the wikipedia article is wrong? |
| 02:36:24 | <aavogt> | @type fix f = f (fix f) |
| 02:36:26 | <lambdabot> | parse error on input `=' |
| 02:36:29 | <pumpkin> | it's the same idea, and you can also encode it with a Mu type can't you? |
| 02:36:34 | <aavogt> | @type let fix f = f (fix f) in fix |
| 02:36:36 | <lambdabot> | forall t. (t -> t) -> t |
| 02:36:54 | <pumpkin> | aavogt: that'll overflow quickly |
| 02:37:35 | <aavogt> | @src fix |
| 02:37:35 | <lambdabot> | fix f = let x = f x in x |
| 02:38:33 | <pumpkin> | @src cycle |
| 02:38:34 | <lambdabot> | cycle [] = undefined |
| 02:38:34 | <lambdabot> | cycle xs = xs' where xs' = xs ++ xs' |
| 02:39:36 | <TheColonial> | how do you get lambdabot to show you the source of, say, an instance of Applicative ? |
| 02:39:49 | <SamB> | TheColonial: you can't |
| 02:39:57 | <TheColonial> | SamB: thanks :) |
| 02:39:57 | <pumpkin> | @src [] (<*>) |
| 02:39:58 | <lambdabot> | (<*>) = ap |
| 02:39:59 | <SamB> | the list is more-or-less hard-coded |
| 02:40:07 | <pumpkin> | but yeah, a few of them are hardcoded in |
| 02:40:26 | <pumpkin> | @src [] pure |
| 02:40:27 | <lambdabot> | pure = return |
| 02:40:50 | <pumpkin> | they don't always match the real implementations though |
| 02:41:07 | <pumpkin> | sort is an example of that |
| 02:41:18 | <pumpkin> | mmorrow: still around? |
| 02:41:20 | <TheColonial> | pumpkin: cool thanks :) |
| 02:41:53 | <JusticeFries> | lambdabot functions as an interpreter? |
| 02:41:59 | <pumpkin> | > text "yes I do" |
| 02:42:01 | <lambdabot> | yes I do |
| 02:42:14 | <JusticeFries> | that's awesome. |
| 02:42:15 | <aavogt> | @type text |
| 02:42:17 | <lambdabot> | String -> Doc |
| 02:42:23 | <aavogt> | @index text |
| 02:42:23 | <lambdabot> | Graphics.HGL.Draw.Text, Graphics.HGL.Draw, Graphics.HGL.Core, Graphics.HGL, Graphics.SOE, Language.Haskell.TH.PprLib, Text.Html, Text.PrettyPrint.HughesPJ, Text.PrettyPrint |
| 02:43:44 | <ray> | fix is the "real" Y, not that stupid abnormal-order Y people love so much :) |
| 02:56:40 | <mmorrow> | pumpkin: http://moonpatio.com/repos/hsfft/ |
| 02:56:51 | <pumpkin> | mmorrow: awesome :) |
| 02:56:56 | <pumpkin> | mmorrow: know much about bytecode in ghci? |
| 02:57:13 | <pumpkin> | lol: http://moonpatio.com/repos/hsfft/README |
| 02:57:24 | <mmorrow> | pumpkin: just redid the the generation |
| 02:57:28 | <mmorrow> | pumpkin: heh |
| 02:57:56 | <mmorrow> | pumpkin: literally created that repo 30 seconds ago :) |
| 02:58:18 | <mmorrow> | pumpkin: so compiling <=128 take about 16 seconds on my machine |
| 02:58:25 | <pumpkin> | ah, not too bad |
| 02:58:32 | <mmorrow> | and i ^C'ed out of 256<= after 40+ seconds |
| 02:58:41 | <pumpkin> | lol |
| 02:58:45 | <mmorrow> | :( |
| 02:59:03 | <pumpkin> | it's compile time code generation, I wouldn't expect it to be fast |
| 02:59:10 | <ray> | i need a new computer :( |
| 02:59:19 | <pumpkin> | although maybe not that slow? |
| 02:59:20 | <pumpkin> | not sure |
| 02:59:21 | <mmorrow> | (also one nice thing is that for bigger vectors, you can just merge the results of ffts of smaller unrolled vectors recorsively) |
| 02:59:41 | <ray> | the worst part of needing a new computer is that i actually have one in the mail |
| 02:59:44 | <pumpkin> | yeah, and then you start running into the fact that ghc doesn't like large chunks of code |
| 02:59:48 | <mmorrow> | pumpkin: oh, i'm writing the generated code to a file first |
| 02:59:52 | <pumpkin> | ah I see |
| 03:00:08 | <mmorrow> | <=512 is 65,000 lines :/ |
| 03:00:10 | <ray> | an agonizing two days of being so close to compiling things |
| 03:00:14 | <pumpkin> | ack |
| 03:00:42 | <mmorrow> | so i guess now it's time to add controllable-with-parameters unrolling |
| 03:01:13 | <mmorrow> | oh, and also the get it using that Vec type or something better than lists.. |
| 03:01:36 | <pumpkin> | is it already all strict? |
| 03:03:17 | <mmorrow> | pumpkin: for the most part, but there's the pointers in the lists to Complex's, which have pointers to two Doubles.. |
| 03:03:25 | <pumpkin> | ah |
| 03:03:32 | <bnijk> | ok somebody explain to me the beauty of STMs |
| 03:03:41 | <mmorrow> | so that Vec is aimed at getting rid of that |
| 03:03:45 | <pumpkin> | ah |
| 03:03:55 | <pumpkin> | bnijk: plural? |
| 03:03:59 | <bnijk> | STM |
| 03:04:00 | <pumpkin> | software transactional memory? |
| 03:04:02 | <pumpkin> | ah |
| 03:04:10 | <mmorrow> | i looked with vacuum, a Vec64 has literally 128 machine Doubles sitting in its closure |
| 03:04:21 | <pumpkin> | nice |
| 03:04:23 | <pumpkin> | :P |
| 03:04:41 | <pumpkin> | bnijk: composability is the main thing that gets people excited, I think |
| 03:04:53 | <bnijk> | composability? |
| 03:05:03 | <jmcarthur> | bnijk: you can compose smaller transactions into bigger transactions without risking deadlock |
| 03:05:13 | <mmorrow> | the really nice thing about Vec too is that you can bind every single elem to a var in a single pattern match, and let ghc's code-gen compute the most optimal asm code to move it around |
| 03:05:22 | <pumpkin> | bnijk: with standard sync constructs, you need to be aware of the order in which various components acquire locks, or you rick deadlock |
| 03:05:26 | <bnijk> | you mean multiple smaller ones into one big one? |
| 03:05:31 | <pumpkin> | you can't treat things as black boxes |
| 03:05:46 | <pumpkin> | mmorrow: yeah |
| 03:05:49 | <mmorrow> | rather than have to index into the vec length(vec) times to get at everything, and do this indexing at the haskell-level |
| 03:06:06 | <pumpkin> | sounds cool |
| 03:06:20 | <bnijk> | acquire locks on the same portion of state you mean, right |
| 03:06:20 | <bnijk> | ? |
| 03:06:24 | <mmorrow> | this is why i think that it's gonna be really fast |
| 03:07:01 | <bnijk> | multithreading scares me a little |
| 03:07:09 | <bnijk> | i am trying to overcome that fear! |
| 03:07:37 | <pumpkin> | ACTION tests an enormous unpacked closure |
| 03:07:52 | <pumpkin> | bnijk: yeah, sort of |
| 03:08:07 | <dino-> | I thought SPJ's chapter in _Beautiful Code_ on STM was useful in explaining the problem with conventional threading models. |
| 03:08:20 | <dino-> | There was a draft of the chapter in PDF: http://www.google.com/url?sa=t&source=web&ct=res&cd=8&url=http%3A%2F%2Fwww.ece.iastate.edu%2F~pjscott%2Fbeautiful.pdf&ei=TNEtSr3-JIeytweG0vmJDA&rct=j&q=beautiful+concurrency&usg=AFQjCNGbHWwws-LjWnbb7aG042dpwm6trQ |
| 03:08:27 | <dino-> | ugh, what a URL |
| 03:08:35 | <bnijk> | dickensurl.com |
| 03:08:58 | <bnijk> | http://dickensurl.com/b511/Liberty_equality_fraternity_or_death_the_last_much_the_easiest_to_bestow_O_Guillotine |
| 03:10:30 | <pumpkin> | mmorrow: wow, ghc slows down so much when you have big code |
| 03:10:38 | <pumpkin> | mmorrow: I'm starting to think it's quadratic in the size of your code or something |
| 03:11:03 | <mmorrow> | pumpkin: yeah, i wonder what the main reason is? |
| 03:11:06 | <pumpkin> | my 1024 unboxed doubles data with a one-line main function is using 700 MB |
| 03:11:09 | <wli> | Pump out some charts and graphs? Regression? |
| 03:11:39 | <mmorrow> | wli: good idea |
| 03:11:46 | <bnijk> | when does the type of a function not have to be explicitly clarified |
| 03:11:58 | <bnijk> | and don't say "when the compiler can infer it" |
| 03:12:14 | <pumpkin> | wow, this is ridiculous |
| 03:12:18 | <dino-> | bnijk: The chapter was called "Beautiful Concurrency" if that URL is a problem |
| 03:12:22 | <pumpkin> | over a gig of RAM now |
| 03:12:26 | <pumpkin> | the file has 1027 lines |
| 03:12:27 | <bnijk> | oh that was for me :O |
| 03:12:29 | <mmorrow> | :( |
| 03:13:02 | <wli> | ACTION is not entirely sure how to do rational regression, but I'd try rational functions of degree type (3, 2) (i.e. a cubic polynomial in the numerator and a quadratic polynomial in the denominator) if such turns out to be feasible. |
| 03:13:56 | <pumpkin> | why would you expect it to be a rational function? |
| 03:14:26 | <pumpkin> | alright, I guess no 1024-unboxed double data for me |
| 03:14:40 | <pumpkin> | oh, it finally got around to linking |
| 03:14:44 | <aavogt> | bnijk: see the MonomorphismRestriction, and also defaulting in haskell '98 |
| 03:14:55 | <wli> | Mostly it's that rational functions are "highly expressive" as opposed to thinking it's a rational function a priori. If there were some a priori expectation of the form of the curve then I'd use that. |
| 03:15:03 | <pumpkin> | ah |
| 03:15:09 | <aavogt> | for when you might have to put annotations |
| 03:15:18 | <aavogt> | @where onlinereport |
| 03:15:19 | <lambdabot> | I know nothing about onlinereport. |
| 03:15:25 | <aavogt> | @where report |
| 03:15:26 | <lambdabot> | http://www.haskell.org/onlinereport/ |
| 03:15:39 | <pumpkin> | mmorrow: finally finished after using 1.1 gigs of RAM and several minutes :) |
| 03:16:12 | <aavogt> | bnijk: but most of the time, you don't have to annotate any types |
| 03:16:44 | <bnijk> | why aren't cpus getting faster |
| 03:17:06 | <bnijk> | and when did 90% of programming become religion |
| 03:17:15 | <pumpkin> | bnijk: it's cheaper to make many lower-power cores than to make one superfast one |
| 03:17:19 | <wli> | Bandwidth in terms of instruction-level parallelism vs. latency. |
| 03:17:33 | <pumpkin> | bnijk: depends what community you ask, about the second questions |
| 03:17:35 | <pumpkin> | -s |
| 03:18:00 | <wli> | There's also, of course, actual parallelism going on. |
| 03:18:07 | <bnijk> | well, which community is right |
| 03:18:20 | <pumpkin> | bnijk: generally the really evangelical ones I'd say are wrong |
| 03:18:22 | <bnijk> | it's haskell right ;) |
| 03:18:40 | <pumpkin> | bnijk: I don't think there's a single best language, but many of us are working to make haskell better :) |
| 03:19:21 | <lament> | pumpkin: what about Javascript? |
| 03:19:31 | <pumpkin> | bnijk: I think you'll find that most people in #haskell are not particularly religious about the language, and tend to be programming language enthusiasts (admiring qualities of many different languages) |
| 03:19:48 | <bnijk> | do you guys know brainfuck |
| 03:19:51 | <pumpkin> | yeah :) |
| 03:19:56 | <bnijk> | of course |
| 03:19:58 | <pumpkin> | I wrote a few things in it |
| 03:20:06 | <pumpkin> | for a class project a while back |
| 03:20:12 | <gwern> | we can probably formalize the no-single-best-language idea, too. I'm sure some combination of rice's theorem or no free lunch theorems would do it. or better yet, some compression theorem - there's no language which optimally encodes all possible programs we might want to write |
| 03:20:34 | <pumpkin> | lament: I don't think it's a bad language |
| 03:20:35 | <bnijk> | yeah gwern |
| 03:20:58 | <pumpkin> | lament: I think c++ for example is an ugly language, as is LaTeX, but they both have a purpose if suitably constrained |
| 03:21:09 | <pumpkin> | :P |
| 03:21:12 | <bnijk> | what is c++ suitable for |
| 03:21:14 | <gwern> | since compressing all possible programs would violate the pigeonhole principle |
| 03:21:19 | <bnijk> | i think i'd take c or java over it |
| 03:21:20 | <gwern> | bnijk: working with c++... |
| 03:21:29 | <bnijk> | that's sort of |
| 03:21:31 | <bnijk> | tautological |
| 03:21:41 | <gwern> | bnijk: not really |
| 03:21:44 | <pumpkin> | bnijk: in c you often end up reimplementing a lot of c++'s basic object system for larger programs |
| 03:21:52 | <pumpkin> | bnijk: might as well use c++, and avoid all the ugly stuff :) |
| 03:22:01 | <gwern> | what I know of tex is pretty ugly to write in, but on the other hand, it renders pretty nice stuff |
| 03:22:06 | <pumpkin> | exactly |
| 03:22:14 | <bnijk> | isn't that what they say about lisp |
| 03:22:23 | <bnijk> | most c programs contain half of a lisp implementation |
| 03:22:27 | <inimino> | gwern: I'm not sure optimal compression is the ideal programming language quality metric... |
| 03:22:43 | <inimino> | greenspun |
| 03:22:43 | <pumpkin> | that'd give you an awfully CISCish language :P |
| 03:23:40 | <ray> | most lisp programs contain half of a c++ implementation |
| 03:23:51 | <ray> | and that's not a compliment to either language :) |
| 03:24:12 | <bnijk> | i like the higher order stuff in haskell the most |
| 03:24:16 | <bnijk> | from what i know |
| 03:24:27 | <bnijk> | saves time |
| 03:24:40 | <ray> | most haskell programs contain half of an implementation of themselves, and the other half too |
| 03:24:54 | <lament> | inimino: it probably is, though |
| 03:25:09 | <gwern> | inimino: nah, I think it's fine. a language should make all the programs we want to write short, at the expense of making all the programs we don't want to write either impossible or lengthy. |
| 03:26:10 | <Berengal> | gwern: They're not exactly direct opposites |
| 03:26:12 | <bnijk> | isn't the namespace of functions in haskell really equivalent to the namespace of programs for an OS |
| 03:26:15 | <gwern> | ideally, a language would have all the programs we want to write be single identifiers :) 'oh you want to do a counting sort on stdin? that's just 538221' |
| 03:26:52 | <ray> | godel |
| 03:26:54 | <jmcarthur> | gwern: well, not really. with such a large number of identifiers, surely they must be indexed in some logical way so you can find them |
| 03:27:01 | <inimino> | lament: it could be, but it's by no means a given :) |
| 03:27:01 | <jmcarthur> | which implies that you're just programming :P |
| 03:27:01 | <gwern> | then we could focus our efforts on deciding which program does what we really want - we'd discuss 'sufficiently smart hoogles' |
| 03:27:12 | <hatds> | it feels like if read/write operations on mutable structures were separated you wouldn't have to worry so much about the order of effects |
| 03:27:19 | <bnijk> | isn't programming just another level deeper into telling a computer what to do ;) |
| 03:27:24 | <lament> | abstraction is exactly making a program shorter by taking advantage of patterns in it -- i.e. compression |
| 03:27:25 | <gwern> | 'with a sufficiently smart hoogle, we could construct a decision tree to narrow down which ones we want' |
| 03:27:27 | <hatds> | anyone else ever have that idea? |
| 03:27:34 | <jmcarthur> | bnijk: most haskellers might disagree with that ;) |
| 03:27:43 | <bnijk> | how so |
| 03:28:18 | <pumpkin> | we tend to think of haskell as being rather divorced from the underlying computing model |
| 03:28:32 | <gwern> | bnijk: well, you can write logical proofs in coq or something, and then the coq can compile it into haskell, which can be compild into machine code. I don't see how on earh a logic proof is 'telling a computer what to do' |
| 03:28:36 | <lament> | bnijk: programming has nothing to do with a computer |
| 03:28:53 | <bnijk> | ACTION frowns |
| 03:29:17 | <gwern> | bnijk: you'll like the djikstra quote 'computer science has as much to do with computers as astronomy with telescopes' |
| 03:29:25 | <lament> | bnijk: you have a problem and you describe the solution formally. The side benefit of having described it formally is that a computer can now run it. |
| 03:29:41 | <bnijk> | is that not an instruction |
| 03:30:14 | <gwern> | look at a prolog program. it describes the properties of a satisfactory solution, but nothing whatsoever about how one could take the constraints and satisfy them |
| 03:30:37 | <lament> | everything is an instruction if you want to look at the world that way. |
| 03:30:50 | <lament> | but that's not the preferred way when dealing with Haskell. |
| 03:31:46 | <bnijk> | what is it then |
| 03:31:55 | <bnijk> | putting everything into a mathematical function |
| 03:32:00 | <bnijk> | doesn't that still constitute an instruction |
| 03:32:23 | <bnijk> | that's how it's interpreted, that's how you conceive of it if you consider its speed and its actual actions as a program |
| 03:32:27 | <inimino> | everything in IO is an instruction |
| 03:32:29 | <inimino> | you can't run a program without telling the computer to run it |
| 03:32:41 | <bnijk> | yes |
| 03:33:08 | <lament> | bnijk: sure, all programs are instructions for the computer to do something |
| 03:33:18 | <lament> | bnijk: but that's not the only possible way of looking at programs |
| 03:33:32 | <gwern> | ACTION thinks bnijk is not arguing here but expounding dogmatic definitions here |
| 03:33:35 | <jmcarthur> | "declarative" can be a vague word, sometimes |
| 03:33:54 | <lament> | as a rule of thumb, if it's hard to debug, it's declarative :) |
| 03:34:02 | <jmcarthur> | perhaps because it is more superficial than we stuck-up Haskell programmers care to think, perhaps not |
| 03:34:19 | <jmcarthur> | regardless, it is at least beneficial to trick yourself into believing it is different, as it does change you style a bit |
| 03:34:24 | <jmcarthur> | *your |
| 03:35:10 | <sclv> | hmmm... does jgoerzen ever hang out on irc? |
| 03:35:11 | <jmcarthur> | lament: hard to debug? that crazy talk. truly declarative programs have no bugs! |
| 03:35:23 | <sclv> | ACTION thinks no |
| 03:35:26 | <gwern> | sclv: sometimes, as cosmic_mercury or something like that |
| 03:35:58 | <lament> | bnijk: as an extremely declarative example, consider a program where you design and work with an electric circuit. |
| 03:36:04 | <jmcarthur> | ACTION goes elsewhere on the internet to spread disinformation |
| 03:36:12 | <lament> | bnijk: ultimately you use this circuit to use some problem you have |
| 03:36:33 | <sclv> | i mildly want to bug him about hdbc-odbc and safe vs. unsafe foreign calls, but only mildly at the moment. |
| 03:36:55 | <lament> | bnijk: of course, in some sense, the circuit you design is converted into intsructions to the computer to do stuff, but that's certainl an odd way of looking at it. You're working with the circuit, not with the computer. |
| 03:37:48 | <bnijk> | i'm telling the computer how to work with the circuit |
| 03:37:56 | <inimino> | lament: but would you call a circuit a program? |
| 03:38:01 | <inimino> | I'd call that a model |
| 03:38:06 | <hatds> | if that's the case then I'll take that computer off your hands that you don't need |
| 03:38:34 | <sclv> | programs can be evaluated by people as well as computers |
| 03:39:03 | <jmcarthur> | inimino: i'd say that could be a difference between imperative and declarative styles. i would be more inclined to call a declarative concept a model than a set of instructions |
| 03:39:16 | <lament> | bnijk: no, whoever wrote the circuit designer program did that |
| 03:39:21 | <lament> | bnijk: you just build the circuit |
| 03:39:36 | <bnijk> | that would be a model |
| 03:39:36 | <bnijk> | then |
| 03:40:01 | <lament> | for you it's much more natural to think of the circuit as a circuit as opposed to an extremely high-level language that somehow gets converted to machine code |
| 03:40:03 | <jmcarthur> | bnijk: do you mean "as opposed to a program"? |
| 03:40:08 | <bnijk> | yes |
| 03:40:10 | <sclv> | oblig xkcd link (sorry haters): http://xkcd.com/505/ |
| 03:40:25 | <bnijk> | i do hate xkcd |
| 03:40:30 | <jmcarthur> | bnijk: consider a DSL for describing circuits then, embedded in a language like haskell |
| 03:40:34 | <bnijk> | man |
| 03:40:35 | <jmcarthur> | is it still not programming? |
| 03:40:41 | <lament> | bnijk: now s/circuit/haskell program, s/circuit designer/GHC, and consider the implications |
| 03:40:51 | <BMeph_> | preflex: seen CosmicRay |
| 03:40:52 | <preflex> | CosmicRay was last seen on #haskell 4 days, 6 hours, 49 minutes and 9 seconds ago, saying: mauke: another reason 6.10.3 sucks? sigh |
| 03:41:13 | <bnijk> | does describing circuit designers? |
| 03:41:21 | <bnijk> | uhhh |
| 03:41:23 | <bnijk> | oops |
| 03:41:50 | <bnijk> | are we talking about what you build in the circuit modelling program |
| 03:41:53 | <bnijk> | or the program itself |
| 03:42:19 | <lament> | what you build in it |
| 03:42:21 | <lament> | the circuit |
| 03:42:33 | <lament> | that's your declarative program |
| 03:42:44 | <jmcarthur> | bnijk: take a look at this syntax, which is eerily similar to circuits http://www.haskell.org/arrows/syntax.html |
| 03:42:59 | <jmcarthur> | you can actually write real programs with circuits |
| 03:43:02 | <inimino> | XKCD rocks :D |
| 03:43:47 | <jmcarthur> | that syntax only makes it more apparent, but you actually can approach a LOT of programming domains in a similar way |
| 03:43:49 | <Hunner> | The previous one was much cooler imho |
| 03:45:07 | <sclv> | ACTION idly notices that haskell-beginners often has quite deep discussions while -cafe still gets lots of beginner questions... |
| 03:45:32 | <lament> | compare with kernelnewbies :) |
| 03:45:49 | <jmcarthur> | i think we shouldn't have #haskell-beginners. beginners don't know to go there, or when their questions are advanced enough to take into #haskell |
| 03:45:51 | <sclv> | lament: same thing happens there? |
| 03:46:05 | <lament> | sclv: kernelnewbies is/was a community of mostly kernel wizards |
| 03:46:32 | <sclv> | i think we just need to push haskell-beginners more in the main haskell pages |
| 03:46:34 | <jmcarthur> | #haskell-in-depth is probably a bad idea as well, in my opinion :\ |
| 03:46:48 | <lament> | does any discussion ever happen in #haskell-in-depth? |
| 03:46:53 | <jmcarthur> | very occasionally |
| 03:46:57 | <jmcarthur> | i don't go any more |
| 03:47:29 | <sclv> | haskell-in-depth is pretty good on when you want some discussion on subtleties of the threaded runtime or some funny typechecker you're working on not to get drowned in noise. |
| 03:47:59 | <byorgey_> | what, there's a #haskell-beginners channel? |
| 03:48:08 | <sclv> | it would be really nice if more of the -cafe questions that belonged on the beginners list actually made it there. |
| 03:49:08 | <byorgey> | oh, no, there isn't, false alarm =) |
| 03:49:27 | <byorgey> | win move up |
| 03:49:35 | <byorgey> | whoops |
| 03:52:03 | <bnijk> | wow http://www.panda3d.org/showss.php?shot=ssg-flight/flight06 |
| 03:52:11 | <bnijk> | those are among the best graphics i've ever seen |
| 03:54:02 | <idnar> | byorgey: lose move down! |
| 03:54:36 | <byorgey> | idnar: you've got the idea! |
| 04:01:36 | <sclv> | ACTION is disappointed that the Alloy paper didn't benchmark against compos |
| 04:02:51 | <sclv> | compos is a limited approach, i'll grant, but its so insanely simple compared to almost anything else. |
| 04:14:07 | <eck> | i have a style/stm question: does this look correct and idiomatic, or is there a preferred way of doing this? http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5675 |
| 04:17:06 | <TomMD> | eck: The only exceptions I know of that are thrown from STM contexts are rather serious and don't mean you should redo your action. |
| 04:17:27 | <eck> | i have an orElse that fails in joinStm |
| 04:18:08 | <eck> | joinStm ct m x n = do joinAction `orElse` (fail "") where joinAction = ... |
| 04:18:10 | <TomMD> | orElse should just result in an STM retry, not an exception. |
| 04:18:20 | <TomMD> | oh, fail... that is a different story |
| 04:18:20 | <eck> | ok |
| 04:18:22 | <TomMD> | why fail? |
| 04:18:40 | <eck> | i'm trying to figure out how to signal that i need i/o to be done (to get the current time) |
| 04:18:45 | <TomMD> | you can 'retry'... unless you are worried about retrying so often that the time grows stale. |
| 04:19:07 | <TomMD> | I handled this once before... let me look at some old code (which might not be handled intelligently) |
| 04:19:12 | <eck> | cool |
| 04:21:43 | <TomMD> | eck: sorry, a design change looks to have eliminated the issue a while ago (I had this issue in control-event). |
| 04:22:08 | <sjanssen> | TomMD: I though fail "" == retry in STM? |
| 04:22:28 | <TomMD> | Does it? That makes the catch all the less worth while in my eyes. |
| 04:22:56 | <eck> | my code is untested :-/ |
| 04:22:57 | <sjanssen> | TomMD: ah, it does seem to throw an exception |
| 04:22:58 | <TomMD> | I just use 'retry' and generally try to forget 'fail' exists except for when I'm using ErrorT or the like. |
| 04:23:02 | <eck> | just wondering what the correct way to do this is |
| 04:23:09 | <sjanssen> | I think I'd prefer fail to be retry, though |
| 04:23:30 | <sjanssen> | eg. do Just x <- readTVar v -- be nice if this retried when it got Nothing |
| 04:23:46 | <TomMD> | eck: Unless you have some sort of high assurance concern with this clock time I'd just trust the atomic action will happen reasonably quickly and eliminate the catch and handler/ |
| 04:24:11 | <eck> | ok |
| 04:25:00 | <eck> | just thought of another thing i could do... i could spawn a thread that updates a TVar with the current time every second (which is really the granularity i'm concerned with), and then read from that TVar in the STM action |
| 04:25:53 | <eck> | that also makes the stm function composable |
| 04:27:44 | <TomMD> | You could - that is exactly what control-engine does! |
| 04:27:58 | <TomMD> | Well, actually that is what haskell-DHT does, which uses control-engine. |
| 04:28:27 | <TomMD> | It works well for me, but Control-Engine has very low contention for the TVar |
| 04:42:38 | <Habitue> | Hey can anyone help me with an issue with digitToInt? |
| 04:43:02 | <pumpkin> | we don't know until you ask the question :) |
| 04:43:57 | <Habitue> | ok, I have a line like: putStrLn $ show $ toEnum (digitToInt selNum - 1) :: SomeEnumType |
| 04:44:36 | <Habitue> | and I'd like to avoid a ton of exception catching if selnum isn't a char from 0 - 9 |
| 04:44:59 | <jimmyjazz14> | what type can I use to store list of different types like an array (or a vector in C++) |
| 04:45:02 | <Habitue> | are there versions of toEnum and digitToInt that return Maybe's instead? |
| 04:45:07 | <pumpkin> | filter out anything outside of 0-9 beforehand? |
| 04:45:52 | <Habitue> | that's simple enough, I'll try that |
| 04:45:56 | <Habitue> | thanks :) |
| 04:46:23 | <jimmyjazz14> | I basically need a list like [1,2,3,[3,4,5],6,7,8] |
| 04:46:46 | <pumpkin> | @type (\x -> guard (x >= '0' && x <= '9') >> pure (digitToInt x)) |
| 04:46:48 | <lambdabot> | forall (m :: * -> *). (MonadPlus m, Applicative m) => Char -> m Int |
| 04:46:53 | <pumpkin> | :P |
| 04:47:02 | <malouin> | jimmyjazz14: that list doesn't have different types. |
| 04:47:02 | <pumpkin> | @type (\x -> guard (x >= '0' && x <= '9') >> Just (digitToInt x)) |
| 04:47:04 | <lambdabot> | Char -> Maybe Int |
| 04:47:47 | <malouin> | Is it possible to have x :: ((->) r)? |
| 04:48:09 | <jimmyjazz14> | @type [1,2,3,[3,4,5],6,7,8] |
| 04:48:10 | <lambdabot> | forall t. (Num [t], Num t) => [[t]] |
| 04:48:24 | <jimmyjazz14> | hmm right |
| 04:49:11 | <jimmyjazz14> | not sure of this error I get from ghci when I try: let a = [1,2,3,[3,4,5],6,7,8] |
| 04:49:28 | <jimmyjazz14> | No instance for (Num [t]) arising from the literal `8' |
| 04:49:43 | <dmwit> | Lists are homogeneous. |
| 04:49:57 | <dmwit> | You can't mix values of different types. |
| 04:51:01 | <jimmyjazz14> | dmwit: is there a data structure in haskell that will allow me to (other than tuples)? |
| 04:51:37 | <dmwit> | Not really. |
| 04:51:45 | <dmwit> | It's kind of the whole point of Haskell. =P |
| 04:52:05 | <jimmyjazz14> | hmm, right, perhaps I am just looking at the problem wrong |
| 04:52:09 | <malouin> | jimmyjazz14: what about a tree? |
| 04:52:32 | <jimmyjazz14> | a tree was my next thought |
| 04:52:32 | <pumpkin> | you can store heterogeneous things in lists, but you need an existential wrapper, and it helps if you know something "common" about the elements |
| 04:52:39 | <pumpkin> | but a tree looks more suitable for your problem |
| 04:53:11 | <malouin> | something like data mytree = num Int | intlist [Int] |
| 04:53:43 | <jimmyjazz14> | yeah I think a tree will work better thinking about it now |
| 04:53:54 | <pumpkin> | malouin: no it isn't possible to have that, as far as I know |
| 04:54:08 | <pumpkin> | malouin: x :: ((->) r), that is |
| 04:54:30 | <pumpkin> | you can write instances for it, but you'd essentially be defining x as a type function in your example |
| 04:54:41 | <pumpkin> | which is possible in other ways |
| 04:54:59 | <pumpkin> | I may be wrong though :) |
| 04:55:23 | <malouin> | pumpkin: ok, I didn't think it made sense to have x :: ((->) r), but I thought I'd check. |
| 04:56:07 | <Yrogirg> | Hello. I have a program that takes a lot of time to run. I want to make it possible to interrupt the program by keypress so the data already processed can be stored and the progam can resume to the computation later. How can I implement this keyboard interruption? |
| 04:56:25 | <byorgey> | malouin: ((->) r) has kind * -> *. Only things with kind * may classify values. |
| 04:57:03 | <malouin> | kind, ok. |
| 04:57:21 | <byorgey> | kinds are types for types. |
| 04:57:29 | <dmwit> | Yrogirg: Sounds like the perfect use for threading. |
| 04:57:37 | <malouin> | ok, yhat is what I figured. |
| 04:59:47 | <malouin> | @type (\x -> x x) |
| 04:59:48 | <lambdabot> | Occurs check: cannot construct the infinite type: t = t -> t1 |
| 04:59:48 | <lambdabot> | Probable cause: `x' is applied to too many arguments |
| 04:59:48 | <lambdabot> | In the expression: x x |
| 05:02:57 | <roconnor> | @type (\x -> out x x) |
| 05:02:58 | <lambdabot> | Occurs check: cannot construct the infinite type: f = (->) (Mu f) |
| 05:02:58 | <lambdabot> | Probable cause: `out' is applied to too many arguments |
| 05:02:58 | <lambdabot> | In the expression: out x x |
| 05:03:44 | <malouin> | what is out? |
| 05:03:47 | <roconnor> | @type (\x -> In (out x x)) |
| 05:03:49 | <lambdabot> | Occurs check: cannot construct the infinite type: t = Mu ((->) t) |
| 05:03:49 | <lambdabot> | Expected type: t |
| 05:03:49 | <lambdabot> | Inferred type: Mu ((->) t) |
| 05:03:53 | <roconnor> | @src Mu |
| 05:03:53 | <lambdabot> | newtype Mu f = In { out :: f (Mu f) } |
| 05:04:19 | <roconnor> | oh right, Mu probably isn't enough to do this |
| 05:04:29 | <dmwit> | http://r6.ca/blog/20060919T084800Z.html |
| 05:04:33 | <dmwit> | roconnor: ^^ |
| 05:04:48 | <roconnor> | thanks I was looking for that |
| 05:05:22 | <byorgey> | hehe |
| 05:06:24 | <roconnor> | @type \f -> (\x -> f ((out x) x)) (In (\x -> f ((out x) x))) |
| 05:06:26 | <lambdabot> | Occurs check: cannot construct the infinite type: t = Mu ((->) t) |
| 05:06:26 | <lambdabot> | Expected type: t |
| 05:06:26 | <lambdabot> | Inferred type: Mu ((->) t) |
| 05:07:03 | <dmwit> | hmph |
| 05:07:18 | <roconnor> | @type \f -> (\x -> f ((out x) x)) (In (\x -> f ((out x) x))) :: (a -> a) -> a |
| 05:07:19 | <lambdabot> | Occurs check: cannot construct the infinite type: t = Mu ((->) t) |
| 05:07:19 | <lambdabot> | Expected type: t |
| 05:07:19 | <lambdabot> | Inferred type: Mu ((->) t) |
| 05:07:30 | <roconnor> | @type (\f -> (\x -> f ((out x) x)) (In (\x -> f ((out x) x)))) :: (a -> a) -> a |
| 05:07:31 | <lambdabot> | Occurs check: cannot construct the infinite type: t = Mu ((->) t) |
| 05:07:32 | <lambdabot> | Expected type: t |
| 05:07:32 | <lambdabot> | Inferred type: Mu ((->) t) |
| 05:07:36 | <roconnor> | humm |
| 05:08:11 | <roconnor> | my my and lambdabot's My are different |
| 05:08:18 | <roconnor> | er |
| 05:08:25 | <roconnor> | my Mu and lambdabot's MU are different |
| 05:08:28 | <roconnor> | @src Mu |
| 05:08:28 | <lambdabot> | newtype Mu f = In { out :: f (Mu f) } |
| 05:08:32 | <dmwit> | roconnor: Mu is defined differently from that page, too. |
| 05:08:42 | <roconnor> | dmwit: that is my page :) |
| 05:08:47 | <dmwit> | ...oh =P |
| 05:08:52 | <dmwit> | quite |
| 05:09:05 | <dmwit> | ACTION feels silly for pointing at the page now |
| 05:09:15 | <roconnor> | dmwit: I was trying to find it. |
| 05:09:20 | <pumpkin> | ACTION moos |
| 05:09:21 | <idnar> | haha |
| 05:09:25 | <byorgey> | ACTION is amused |
| 05:09:33 | <pumpkin> | aMused? |
| 05:09:38 | <byorgey> | hah! |
| 05:09:41 | <byorgey> | pumpkin++ |
| 05:09:45 | <dmwit> | roconnor: That is the first sign of excellent website design. =) |
| 05:09:54 | <roconnor> | The problem seems to be that we need f x to be (x -> a) |
| 05:10:11 | <roconnor> | but that is soft of like (Flip (->) a) |
| 05:10:19 | <roconnor> | rather than ((->) a) |
| 05:10:20 | <SamB_XP_> | roconnor: shouldn't that be r7 ? |
| 05:10:34 | <roconnor> | SamB_XP_: Russell is my name |
| 05:10:40 | <SamB_XP_> | oh |
| 05:10:50 | <SamB_XP_> | true |
| 05:11:05 | <roconnor> | SamB_XP_: r7 was an understandable remark |
| 05:11:24 | <idnar> | shouldn't that be r5l? |
| 05:11:27 | <malouin> | r5l was too many characters. |
| 05:11:39 | <pumpkin> | yeah, r6 is already a pain to type |
| 05:11:39 | <byorgey> | ACTION is very confused |
| 05:11:45 | <pumpkin> | too many characters |
| 05:11:53 | <SamB_XP_> | byorgey: arguing about his domain name |
| 05:11:55 | <idnar> | and I suppose r was already taken? |
| 05:12:03 | <roconnor> | @ask Cale can we have more type level combinators in addtion to Mu like Flip, Compose, Const, and, Join? |
| 05:12:03 | <lambdabot> | Consider it noted. |
| 05:12:06 | <idnar> | or should that be 7? |
| 05:12:22 | <byorgey> | SamB_XP_: I got that part, but that's about as far as I got |
| 05:12:22 | <roconnor> | idnar: you cannot have 1 or 2 letter domain names in canada |
| 05:12:25 | <SamB_XP_> | idnar: I don't think bare numbers are legal |
| 05:12:45 | <pumpkin> | roconnor: so r6 isn't allowed? |
| 05:12:52 | <SamB_XP_> | byorgey: well, I was figuring "there are seven letters after the r in roconnor" |
| 05:12:52 | <roconnor> | pumpkin: 6 isn't a letter |
| 05:12:56 | <roconnor> | pumpkin: apparently |
| 05:12:56 | <pumpkin> | oh I see |
| 05:13:01 | <byorgey> | ohhhhh |
| 05:13:03 | <roconnor> | as I found out |
| 05:13:15 | <byorgey> | ACTION should go to sleep |
| 05:13:21 | <pumpkin> | .com doesn't allow one-letter domains either, except for a couple |
| 05:13:32 | <SamB_XP_> | pumpkin: what "couple"? |
| 05:13:42 | <dmwit> | wtf.com |
| 05:13:49 | <pumpkin> | x.com belongs to paypal, and another one that I can't remember belongs to toyota iirc |
| 05:14:04 | <TomMD> | SamB_XP_: ∀.com |
| 05:14:09 | <roconnor> | :) |
| 05:14:23 | <SamB_XP_> | TomMD: rectangle.com ... okay! |
| 05:14:24 | <idnar> | xn--b9g.com? |
| 05:14:33 | <pumpkin> | and q.com |
| 05:14:38 | <pumpkin> | I don't think .com allows IDN yet? |
| 05:15:04 | <TomMD> | SamB_XP_: You need better unicode support or fonts. |
| 05:15:05 | <SamB_XP_> | oh, forall.com it was |
| 05:15:11 | <SamB_XP_> | TomMD: I guess! |
| 05:15:11 | <TomMD> | Indeed! |
| 05:15:28 | <malouin> | gotta get ∀∃.ae |
| 05:15:31 | <SamB_XP_> | if they add IDN support, will C-- finally be allowed? |
| 05:15:44 | <SamB_XP_> | malouin: wouldn't it be better with a real ae character? |
| 05:15:59 | <malouin> | yeah but that is the arab emirates tld that allows IDN |
| 05:16:19 | <malouin> | and IIRC anyone to register |
| 05:16:29 | <malouin> | ACTION has an.alo.gy |
| 05:17:16 | <idnar> | malouin: what about æ.ae? |
| 05:17:30 | <malouin> | :) |
| 05:21:18 | <malouin> | so ((->) r) is a type, but no value can have that type because it is of the * kind |
| 05:21:37 | <malouin> | s/is/is not/ |
| 05:21:48 | <idnar> | it's a type constructor, and it has kind * -> * |
| 05:22:06 | <malouin> | err... s/is of/is not of/ |
| 05:22:36 | <malouin> | ACTION is trying to wrap the head around instance Functor ((->) r) |
| 05:24:04 | <roconnor> | @src fmap (->) |
| 05:24:04 | <lambdabot> | Source not found. Just try something else. |
| 05:24:10 | <roconnor> | @src fmap ((->) a) |
| 05:24:10 | <lambdabot> | Source not found. Just what do you think you're doing Dave? |
| 05:24:30 | <SamB_XP_> | @src fmap Reader |
| 05:24:31 | <lambdabot> | Source not found. You type like i drive. |
| 05:24:50 | <roconnor> | malouin: (r ->) is a useful functor / applicative functor |
| 05:24:57 | <roconnor> | and kinda useful monad |
| 05:25:01 | <SamB_XP_> | @src Reader fmap |
| 05:25:02 | <lambdabot> | Source not found. This mission is too important for me to allow you to jeopardize it. |
| 05:25:06 | <SamB_XP_> | @src fmap |
| 05:25:07 | <lambdabot> | Source not found. |
| 05:27:23 | <malouin> | I can't find it either. |
| 05:27:39 | <roconnor> | malouin: anyhow, fmap = (.) |
| 05:28:12 | <Baughn> | malouin: Which makes perfect sense if you think of a (possibly infinite) mape from all input values to all output values |
| 05:28:31 | <Baughn> | malouin: Er. If you think of a function as a map from input to output values. |
| 05:29:11 | <roconnor> | think of the function (r -> a) as an indexed set of a's (indexed by r) and you want to map (a -> b) |
| 05:29:35 | <roconnor> | so you just look up a, and then apply your f :: a -> b to what you looked up |
| 05:29:49 | <rob_> | hi everyone. I feel ashamed to ask, but I read on the Internet about totally unsafe printing functions, like printf, that don't need to be called inside the IO monad. I don't have time to learn how to use a debugger right now, so can you tell me where to find those ? |
| 05:29:50 | <malouin> | Learn You a Haskell's way of explaining it makes sense to me. |
| 05:30:07 | <roconnor> | fmap f indexedSet index = f (indexSet index) |
| 05:30:15 | <roconnor> | malouin: oh, that's good. |
| 05:30:20 | <SamB_XP_> | > f . [x,y,z] |
| 05:30:21 | <lambdabot> | Couldn't match expected type `a -> b' against inferred type `[a1]' |
| 05:30:34 | <malouin> | It goes through |
| 05:30:38 | <malouin> | fmap :: (a -> b) -> f a -> f b |
| 05:30:40 | <SamB_XP_> | huh, that's not calaskell anymore? |
| 05:30:46 | <Baughn> | rob_: Not printf. See Debug.Trace |
| 05:30:47 | <malouin> | fmap :: (a -> b) -> ((->) r a) -> ((->) r b) |
| 05:30:56 | <malouin> | fmap :: (a -> b) -> (r -> a) -> (r -> b) |
| 05:31:03 | <SamB_XP_> | rob_: the debugger is lousy anyway, if you ask me |
| 05:31:11 | <roconnor> | @djinn (a -> b) -> ((->) r a) -> ((->) r b) |
| 05:31:11 | <lambdabot> | Cannot parse command |
| 05:31:21 | <roconnor> | @djinn (a -> b) -> (r -> a) -> (r -> b) |
| 05:31:21 | <lambdabot> | f a b c = a (b c) |
| 05:31:30 | <malouin> | It seems reasonable composition makes sense for that signature. |
| 05:31:53 | <roconnor> | malouin: its the only reasonable thing that has that signature |
| 05:32:06 | <rob_> | yeah that's why I just want to call show on some of my variables without having to throw in some IO stuff or invoking error |
| 05:32:27 | <SamB_XP_> | of course, the debugger is quite young -- it is convievable that it might get better |
| 05:32:50 | <SamB_XP_> | but then again it is so ... so *temporal* |
| 05:33:59 | <Baughn> | Would you prefer an eccleistical debugger? |
| 05:34:53 | <SamB_XP_> | I ... don't get it |
| 05:35:06 | <SamB_XP_> | that was a *serious* criticism of the debugger! |
| 05:35:40 | <Baughn> | SamB_XP_: "Temporal" has multiple meanings. I picked the least convenient one. |
| 05:35:46 | <Baughn> | Or the most convenient one, as it may be. |
| 05:35:54 | <malouin> | roconnor: so it is possible to prove that fmap must be (.) for ((->) a)? |
| 05:36:58 | <Baughn> | malouin: Prove? I don't know that you'd want to. |
| 05:37:24 | <SamB_XP_> | malouin: try it and see! |
| 05:37:27 | <Baughn> | THe fmap implementations are picked for usefulness, not generally for correctness - yes, they must obey some laws, but that's easy. |
| 05:37:28 | <mornfall> | Quickie... is it better to use -- foo or -- | foo style comments for bits that are not exported from a module? |
| 05:37:40 | <malouin> | don't want to do it, just wondering what disiderata you have to adopt to prove it or whether the Functor class and the type signature are enough. |
| 05:37:47 | <SamB_XP_> | Baughn: but sometimes one wonders if there is a choice |
| 05:38:33 | <malouin> | and the reason I ask is that I have a sense that it is possible to prove in this case. |
| 05:38:37 | <malouin> | but I could be wrong. |
| 05:39:22 | <jmcarthur> | @djinn (a -> b) -> (c -> a) -> (c -> b) |
| 05:39:23 | <lambdabot> | f a b c = a (b c) |
| 05:39:36 | <jmcarthur> | @pl f a b c = a (b c) |
| 05:39:37 | <lambdabot> | f = (.) |
| 05:39:41 | <malouin> | what is djinn? |
| 05:39:51 | <jmcarthur> | not a proof of course |
| 05:40:02 | <jmcarthur> | djinn takes a type and creates a function |
| 05:40:12 | <jmcarthur> | for a limited subset of possible types |
| 05:40:39 | <jmcarthur> | @djinn (a -> b) -> a -> b |
| 05:40:40 | <lambdabot> | f a = a |
| 05:40:49 | <jmcarthur> | @djinn a -> b -> a |
| 05:40:49 | <lambdabot> | f a _ = a |
| 05:40:53 | <jmcarthur> | etc. |
| 05:41:20 | <malouin> | interesting |
| 05:42:22 | <malouin> | @free fmap :: (a -> b) -> (c -> a) -> (c -> b) |
| 05:42:23 | <lambdabot> | g . k = p . f => f . q = f1 . h => g . fmap k q = fmap p f1 . h |
| 05:42:40 | <malouin> | that seems rather cryptic. |
| 05:48:39 | <hatds> | > tail . reverse . tails $ reverse [1..5] |
| 05:48:40 | <lambdabot> | [[1],[2,1],[3,2,1],[4,3,2,1],[5,4,3,2,1]] |
| 05:48:42 | <hatds> | bleh |
| 05:49:05 | <hatds> | any better ideas? |
| 05:49:44 | <dolio> | > scanl1 (:) [] [1..5] |
| 05:49:45 | <lambdabot> | Occurs check: cannot construct the infinite type: a = [a] |
| 05:49:57 | <dolio> | > scanl1 (flip (:)) [] [1..5] |
| 05:49:58 | <lambdabot> | Occurs check: cannot construct the infinite type: a = [a] |
| 05:50:02 | <dolio> | > scanl (flip (:)) [] [1..5] |
| 05:50:03 | <lambdabot> | [[],[1],[2,1],[3,2,1],[4,3,2,1],[5,4,3,2,1]] |
| 05:50:11 | <dolio> | Boom. |
| 05:50:13 | <hatds> | there we go :) |
| 05:56:21 | <solrize_> | hey is there an idiomatic way to take an infinite [IO Bool] stream and chop it at the first false value? |
| 05:56:39 | <solrize_> | like, something with foldM_ perhaps |
| 05:56:41 | <sclv> | hoogle untilM |
| 05:56:45 | <sclv> | ?hoogle untilM |
| 05:56:46 | <lambdabot> | No results found |
| 05:56:49 | <sclv> | ?hoogle whileM |
| 05:56:50 | <lambdabot> | No results found |
| 05:57:07 | <sclv> | i'd write untilM |
| 05:57:47 | <mbuf> | newbie here; how do I install Haskell dependencies on Fedora if build-depends in .cabal says: curl, hslogger, base, test-framework, hxt? |
| 05:57:59 | <solrize_> | sclv ok, i'm just surprised it's not in some library |
| 05:58:05 | <solrize_> | websearch found one right away |
| 05:58:09 | <solrize_> | http://porg.es/blog/simple-socket-programming-with-haskell |
| 05:58:53 | <hatds> | funny, I was just writing a whileM |
| 05:59:02 | <pumpkin> | can't you just sequence it and use until? |
| 05:59:13 | <solrize_> | :t until |
| 05:59:14 | <lambdabot> | forall a. (a -> Bool) -> (a -> a) -> a -> a |
| 05:59:18 | <sclv> | sequence isn't lazy i think? |
| 05:59:20 | <hatds> | no |
| 05:59:22 | <pumpkin> | ah |
| 05:59:27 | <hatds> | sequence constructs the whole list |
| 05:59:34 | <pumpkin> | that's annoying |
| 05:59:35 | <hatds> | (once it is demanded) |
| 05:59:40 | <hatds> | it'd be unsafe otherwise |
| 05:59:52 | <hatds> | yea, [IO a]'s are often more useful than IO [a] |
| 06:00:12 | <solrize_> | > until (> 100) (**2) 1.5 |
| 06:00:13 | <lambdabot> | 656.8408355712891 |
| 06:00:21 | <solrize_> | @where until |
| 06:00:21 | <lambdabot> | I know nothing about until. |
| 06:00:29 | <solrize_> | @hoogle until |
| 06:00:29 | <lambdabot> | Prelude until :: (a -> Bool) -> (a -> a) -> a -> a |
| 06:00:34 | <sclv> | @src until |
| 06:00:34 | <lambdabot> | until p f x | p x = x |
| 06:00:34 | <lambdabot> | | otherwise = until p f (f x) |
| 06:00:37 | <solrize_> | hmm i didn't know about that |
| 06:01:01 | <solrize_> | :t fix |
| 06:01:02 | <lambdabot> | forall a. (a -> a) -> a |
| 06:03:25 | <hatds> | there really should be a library of list-like functions generalizing find, takeWhile, dropWhile, etc. for working with [IO a]'s and functions (a -> IO Bool) that short circuit properly |
| 06:04:29 | <tibbe> | I need a mutable array where I can store functions as elements, what should I use? |
| 06:05:00 | <Berengal> | tibbe: IOArray or STArray, probably |
| 06:05:15 | <tibbe> | Berengal: ok, thanks |
| 06:05:41 | <pumpkin> | mmorrow: |
| 06:05:42 | <pumpkin> | foreign import ccall unsafe "getAllocations" getAllocations :: IO Int64 |
| 06:05:42 | <pumpkin> | -- defined in ghc/rts/Stats.c |
| 06:07:00 | <mmorrow> | pumpkin: oh nice |
| 06:08:09 | <m3ga> | @atomically |
| 06:08:09 | <lambdabot> | Unknown command, try @list |
| 06:08:25 | <m3ga> | :t atomically |
| 06:08:27 | <lambdabot> | Not in scope: `atomically' |
| 06:09:47 | <sclv> | ?hoogle atomically |
| 06:09:47 | <lambdabot> | Control.Exception NestedAtomically :: Exception |
| 06:11:11 | <m3ga> | found it : http://hackage.haskell.org/packages/archive/base/latest/doc/html/GHC-Conc.html#v:atomically |
| 06:11:35 | <tibbe> | ACTION wonders why the library documentation never ranks highly on google |
| 06:15:37 | <thoughtpolice> | yay: https://gist.github.com/7c21be754f21dd159ca6 |
| 06:15:41 | <thoughtpolice> | ghc annotations are neat :) |
| 06:16:11 | <pumpkin> | thoughtpolice: ? |
| 06:16:59 | <pumpkin> | as in BSP's plugins? |
| 06:17:41 | <pumpkin> | or is this separate? |
| 06:18:03 | <thoughtpolice> | pumpkin: using annotations for my own compiler |
| 06:18:29 | <pumpkin> | ACTION is still confused :o |
| 06:18:38 | <pumpkin> | not that that's a rare thing |
| 06:19:31 | <tibbe> | what do I have to import to access the I# constructor? |
| 06:19:54 | <pumpkin> | GHC.Int is one of them |
| 06:20:05 | <pumpkin> | it's actually in a bunch of places I think |
| 06:20:26 | <pumpkin> | GHC.Types I think actually |
| 06:21:01 | <pumpkin> | zomg I found it |
| 06:21:01 | <pumpkin> | data [] a = [] | a : [a] |
| 06:21:05 | <pumpkin> | it's hidden in GHC.Types |
| 06:21:10 | <pumpkin> | not even covered by haddock |
| 06:21:57 | <pumpkin> | wow, we have three edwardks now |
| 06:31:30 | <Berengal> | View patterns are nice |
| 06:31:53 | <Berengal> | But they tend to move computations to the lhs... |
| 07:03:05 | <tibbe> | is there an efficient way to copy the values of one STArray into another? |
| 07:04:16 | <pumpkin> | I don't think so |
| 07:05:24 | <pumpkin> | lol, in the comment: -- No Ix context for STArray. They are stupid, |
| 07:05:49 | <Berengal> | Which comment? |
| 07:05:57 | <pumpkin> | for STArray |
| 07:06:44 | <Berengal> | Ix contexts are stupid now? |
| 07:07:18 | <pumpkin> | -- No Ix context for STArray. They are stupid, |
| 07:07:18 | <pumpkin> | -- and force an Ix context on the equality instance. |
| 07:07:26 | <pumpkin> | -- Just pointer equality on mutable arrays: |
| 07:07:26 | <pumpkin> | instance Eq (STArray s i e) where |
| 07:07:26 | <pumpkin> | STArray _ _ _ arr1# == STArray _ _ _ arr2# = |
| 07:07:26 | <pumpkin> | sameMutableArray# arr1# arr2# |
| 07:08:13 | <dolio> | Contexts on data declarations are stupid. |
| 07:08:38 | <Berengal> | Oh, yes, like that |
| 07:08:47 | <Berengal> | Indeed, data declarations have no need for contexts |
| 07:12:52 | <tibbe> | ACTION finds the default Haskell arrays complicated |
| 07:13:26 | <pumpkin> | me too |
| 07:13:29 | <pumpkin> | uvector ftw :P |
| 07:15:52 | <tibbe> | unfortunately I need a mutable array |
| 07:16:04 | <tibbe> | in fact I need a vector<T> |
| 07:16:07 | <pumpkin> | MUArr |
| 07:16:12 | <pumpkin> | hmm |
| 07:16:17 | <pumpkin> | oh, not unboxed |
| 07:16:21 | <tibbe> | i.e. dynamic resize |
| 07:16:25 | <pumpkin> | oh |
| 07:16:36 | <tibbe> | I need Int indexes and function values |
| 07:16:40 | <tibbe> | (i.e. callbacks) |
| 07:16:41 | <pumpkin> | build a simple wrapper around Array# ? |
| 07:16:52 | <tibbe> | pumpkin: it's all but simple ;) |
| 07:16:54 | <tibbe> | I tried though |
| 07:17:01 | <tibbe> | around MutableArray# |
| 07:17:02 | <Berengal> | Are there no arrayCopy functions anywhere? |
| 07:17:08 | <tibbe> | couldn't find one |
| 07:17:10 | <pumpkin> | Berengal: I was looking for one |
| 07:17:11 | <tibbe> | I'm sure there are |
| 07:17:19 | <pumpkin> | I typically just FFI to memcpy |
| 07:17:23 | <pumpkin> | but that'll only work for unboxed stuff |
| 07:17:26 | <Berengal> | If not, that's a pretty big hole in the array api... |
| 07:17:51 | <dolio> | It should work for boxed arrays, too, I think. |
| 07:18:05 | <dolio> | You're just memcpying pointers instead of unboxed values. |
| 07:18:43 | <pumpkin> | ah |
| 07:19:05 | <dolio> | At least, I assume it'd work. I don't know if anything special happens when you read/write MutableArray#s. |
| 07:20:19 | <tibbe> | mm, thaw/freeze should copy so perhaps I can find a reference there |
| 07:20:50 | <tibbe> | it kinda sucks to work with STRefs if multiple readSTRef to the same ref can't be optimized away |
| 07:20:51 | <Berengal> | thaw/freeze copies, but it doesn't resize... |
| 07:20:55 | <tibbe> | it really hurs composability |
| 07:21:13 | <tibbe> | Berengal: I can allocate a new one if I can figure out how to copy the old one |
| 07:22:10 | <dolio> | Well, worst case you can write your own copying loop. That's what I did in uvector-algorithms before I convinced dons to add some memcpy stuff to uvector. |
| 07:22:57 | <tibbe> | I'm looking at http://www.haskell.org/ghc/docs/latest/html/libraries/array/src/Data-Array-Base.html#freeze and STUArray is memcpy but normal arrays are a naive loop |
| 07:23:25 | <dolio> | Huh, maybe it's not safe to use memcpy on the pointer arrays, then. |
| 07:23:27 | <Berengal> | Maybe something like 'mapM_ insert $ toList oldArray' will be fused, or something? |
| 07:23:34 | <Berengal> | Wouldn't bet on it though... |
| 07:24:00 | <tibbe> | me neither |
| 07:24:08 | <tibbe> | I haven't seen any RULES for it |
| 07:25:22 | <dolio> | Wait, freezeSTArray isn't in this module. |
| 07:27:25 | <dolio> | freezeSTArray is still a loop, though. |
| 07:27:47 | <tibbe> | http://www.haskell.org/ghc/docs/latest/html/libraries/base/src/GHC-Arr.html#thawSTArray |
| 07:27:51 | <tibbe> | that looks better |
| 07:27:52 | <dolio> | Oh, I think I know why you can't memcpy the MutableArray#s. |
| 07:28:04 | <dolio> | Whenever you write to them, you need to set the dirty bit. |
| 07:28:11 | <dolio> | Which memcpy obviously wouldn't. |
| 07:28:13 | <tibbe> | hmm |
| 07:28:14 | <tibbe> | right |
| 07:28:20 | <tibbe> | but does every write do that? |
| 07:28:31 | <dolio> | I think so. |
| 07:28:33 | <tibbe> | isn't that a bit inefficient if you want to copy in a loop? |
| 07:28:47 | <dolio> | Yes. |
| 07:29:05 | <dolio> | Well, setting the bit isn't inefficient, probably. |
| 07:29:22 | <dolio> | Having the garbage collector scan all the pointers in the array is. |
| 07:29:47 | <dolio> | For however many times the collector runs during your copying. |
| 07:30:06 | <mmorrow> | tibbe: you can get I# with GHC.Exts |
| 07:30:12 | <tibbe> | mmorrow: thanks ;) |
| 07:30:13 | <mmorrow> | GHC.Exts(Int(I#)) |
| 07:30:22 | <Berengal> | Why would you need to set the dirty bit when copying? |
| 07:30:31 | <tibbe> | looks like I have to go with MutableArray# instead of STArray to get at the goodies |
| 07:30:31 | <pumpkin> | mmorrow: onoes, getAllocations never gives me anything :( |
| 07:30:34 | <Berengal> | I'd think you'd only have to if the source was dirty... |
| 07:30:56 | <tibbe> | time to go to work |
| 07:30:58 | <tibbe> | ttyl |
| 07:31:03 | <mmorrow> | pumpkin: oh noes |
| 07:31:08 | <mmorrow> | pumpkin: what do you mean? |
| 07:31:19 | <pumpkin> | well the difference of two calls is always 0 in my tests |
| 07:31:26 | <pumpkin> | but I should see if the return value is 0 too |
| 07:31:55 | <pumpkin> | yeah, it is |
| 07:31:55 | <pumpkin> | hmm |
| 07:32:03 | <pumpkin> | I wonder what's wrong |
| 07:32:11 | <mmorrow> | err, i don't understand, so the retval of the C function is always 0? |
| 07:32:15 | <pumpkin> | yup |
| 07:33:06 | <pumpkin> | oh it isn't |
| 07:33:14 | <mmorrow> | does peeking total_allocated give you nonzero? |
| 07:33:15 | <pumpkin> | I just hadn't done anything when I first called it |
| 07:33:20 | <mmorrow> | ah |
| 07:33:21 | <pumpkin> | but the difference is still always 0 |
| 07:33:33 | <pumpkin> | I wonder whether gmp is really using our allocators :o |
| 07:33:37 | <pumpkin> | I guess it has to |
| 07:33:38 | <mmorrow> | i'm getting values by peeking total_allocated |
| 07:33:40 | <dolio> | Berengal: I don't really grok the whole dirty bit for arrays thing, myself. |
| 07:34:07 | <mmorrow> | pumpkin: ohh, did you pass the ghc alloc functions to gmp_set_alloc_functions (or whatever)? |
| 07:34:29 | <mmorrow> | pumpkin: or maybe those functions allocate somewhere where total_allocated doesn't record |
| 07:34:34 | <pumpkin> | this is still using 6.10.3 |
| 07:34:38 | <pumpkin> | with primops etc. |
| 07:34:44 | <mmorrow> | ACTION tries |
| 07:35:16 | <dolio> | Berengal: Somehow GHC only has to crawl arrays of pointers to see what's live if you've modified the array. I guess it remembers from past crawls if you don't modify it. |
| 07:36:23 | <dolio> | So if you're copying, it needs to crawl to establish what's live based on the new array, I guess. |
| 07:36:33 | <dolio> | Although if you were smart, you could just copy that information from the old array. |
| 07:36:45 | <dolio> | Assuming I'm correctly understanding how it all works. |
| 07:37:25 | <pumpkin> | ACTION is trying to come up with a really cool benchmarking suite |
| 07:37:30 | <pumpkin> | for integers |
| 07:38:25 | <pumpkin> | maybe I'm overengineering it, but it's fun |
| 07:41:02 | <mmorrow> | pumpkin: it changes, but a lot of the time the diff'll be zero |
| 07:41:15 | <pumpkin> | hmm, but I'm doing really big integer operations between the calls |
| 07:41:37 | <pumpkin> | ACTION tries even bigger ones |
| 07:41:47 | <mmorrow> | pumpkin: http://moonpatio.com/fastcgi/hpaste.fcgi/view?id=2614#a2614 |
| 07:42:06 | <mmorrow> | yeah, you have to build huger things than you first think too |
| 07:42:09 | <pumpkin> | 401225798736931 |
| 07:42:09 | <pumpkin> | [(5.012781,0),(5.074234,0),(5.106006,0),(5.439548,0)] |
| 07:42:18 | <pumpkin> | I'm raising that number to the power of 500000 |
| 07:42:32 | <mmorrow> | on mine it was only changing every 100 samples or so.. |
| 07:42:33 | <pumpkin> | the first is the number of seconds elapsed for each try |
| 07:42:44 | <pumpkin> | the second is the difference in calls to getAllocations |
| 07:42:56 | <mmorrow> | and each loop i was doing (100000^n), n `in` [100..4242] |
| 07:43:23 | <pumpkin> | mine is a much bigger number, but I'm only doing it once |
| 07:43:24 | <pumpkin> | hmm |
| 07:43:29 | <mmorrow> | (i'm peeking total_allocated directly, but don't see why that would change anything) |
| 07:43:42 | <mmorrow> | pumpkin: oh, you have to do it hundreds of times |
| 07:44:20 | <pumpkin> | oh, maybe it only updates the allocations counter after a GC? |
| 07:44:26 | <pumpkin> | that would be odd though |
| 07:44:28 | <mmorrow> | all my diffs are roughly 65026 too .. |
| 07:44:39 | <mmorrow> | so i guess that's the granularity of this counter |
| 07:44:59 | <mmorrow> | , 2 ^ 16 - 1 |
| 07:45:01 | <lunabot> | 65535 |
| 07:45:24 | <pumpkin> | there is definitely allocation going on here |
| 07:45:42 | <pumpkin> | I'm raising 631603098302601^5000000 |
| 07:45:46 | <mmorrow> | it looks like you need to allocate > 65535 bytes |
| 07:45:50 | <pumpkin> | the program is using 165 megabytes |
| 07:45:55 | <pumpkin> | from that computation alone |
| 07:46:02 | <pumpkin> | let's see if it shows me any allocations now! :P |
| 07:46:03 | <mmorrow> | maybe it only ticks it every 100 or so spins? |
| 07:46:10 | <pumpkin> | maybe that's it |
| 07:46:29 | <mmorrow> | (literally my test prog was only show a nonzero diff every 100 or so spins) |
| 07:46:40 | <pumpkin> | how do I get it to spin idle? |
| 07:46:42 | <mmorrow> | so once every 100 or so allocations |
| 07:46:56 | <mmorrow> | you have to allocate each spin |
| 07:47:04 | <pumpkin> | hm |
| 07:47:09 | <pumpkin> | I guess I could allocate something tiny |
| 07:47:14 | <pumpkin> | newByteArray# 1 |
| 07:47:19 | <pumpkin> | :P |
| 07:47:23 | <mmorrow> | 42 `seq` ... |
| 07:47:31 | <pumpkin> | that's enough? |
| 07:47:40 | <mmorrow> | that'll allocate (i think) |
| 07:47:49 | <mmorrow> | length [0..4095] `seq` ... |
| 07:47:53 | <mmorrow> | will definitely allocate |
| 07:48:11 | <pumpkin> | but I don't want to allocate more than I need to, or it'll add a big constant to my measurements |
| 07:48:18 | <pumpkin> | I guess I can measure how much that adds and subtract it |
| 07:48:26 | <pumpkin> | assuming it's constant |
| 07:51:16 | <pumpkin> | dammit |
| 07:54:06 | <binarycodes> | hey all |
| 07:54:08 | <mmorrow> | pumpkin: hmm, it looks like tot_allocs doesn't get updated very sanely, i'd use the block/mblock counts |
| 07:54:22 | <mmorrow> | MemStats {blocks = 131, mblocks = 1, totalloc = 0} |
| 07:54:22 | <mmorrow> | MemStats {blocks = 16007, mblocks = 68, totalloc = 0} |
| 07:54:29 | <pumpkin> | I wonder how ghci's works consistently |
| 07:54:35 | <pumpkin> | or maybe it doesn't |
| 07:54:39 | <pumpkin> | and everyone just ignores that number |
| 07:54:50 | <mmorrow> | pumpkin: that's wired in to the interpreter or something like that i think |
| 07:54:58 | <mmorrow> | i don't think it's from here |
| 07:55:09 | <pumpkin> | it is, that's where I found the function |
| 07:55:21 | <mmorrow> | hmm |
| 07:55:29 | <binarycodes> | i have a function factor num = x: num `div` x , where num `mod` x == 0. now how do i specify that x is to be drawn from a list of primes, till the clause num `mod` x is true ? |
| 07:55:38 | <mmorrow> | pumpkin: if you just use the block/megablock count you can sidestep this whole issue :) |
| 07:55:55 | <pumpkin> | fair enough |
| 07:56:06 | <binarycodes> | i have a function that generates the list of primes, just cant figure out how to make that factor function draw x from there |
| 07:56:34 | <pumpkin> | mmorrow: so a megablock is the result of an OS malloc, and a block is some subunit of that? |
| 07:57:53 | <mmorrow> | pumpkin: there're both used with haskell alloc |
| 07:57:56 | <mmorrow> | *they're |
| 07:58:10 | <mmorrow> | a megablock is 1MB and a block is 4K |
| 07:58:21 | <pumpkin> | zomg, I'm still getting a difference of 0!!!!11 |
| 07:58:28 | <pumpkin> | ACTION tries throwing more allocation in between |
| 07:59:09 | <pumpkin> | ACTION @#!$!#&$ |
| 07:59:39 | <binarycodes> | any help on the above, or atleast what i should be looking for? |
| 08:00:03 | <doserj> | binarycodes: head . filter (\x -> n`mod`x==0) |
| 08:00:43 | <binarycodes> | doserj, ah compose. right. thanks |
| 08:00:53 | <pumpkin> | mmorrow: alright, no more cursing and swearing, time for bed instead... still haven't been able to get a meaningful difference between values |
| 08:04:01 | <mmorrow> | pumpkin: oh, it does reset those counters on a gc, and it looks like it only updates them after a gc as well |
| 08:04:26 | <pumpkin> | ACTION sobs |
| 08:05:33 | <prince_arioch> | haskell, a demon of great power from the lower levels of the demonic abyss |
| 08:05:37 | <prince_arioch> | we must be cautious |
| 08:05:42 | <pumpkin> | indeed! |
| 08:05:53 | <pumpkin> | do not let the GC get in the way of your measurements |
| 08:06:07 | <mmorrow> | pumpkin: check out the output of this one http://moonpatio.com/fastcgi/hpaste.fcgi/view?id=2614#a2615 |
| 08:06:22 | <pumpkin> | grr at the observer effect |
| 08:07:04 | <mmorrow> | (the fact that we're making a ccall also might be having some effect of something or other too) |
| 08:07:16 | <pumpkin> | bah :) |
| 08:07:17 | <mmorrow> | err, well i'm just peeking, so i guess not |
| 08:07:42 | <pumpkin> | maybe there's a special case in ghc saying "if he peeks at this address, fuck with him" |
| 08:08:54 | <pumpkin> | anyway, tomorrow will bring new inspiration on how to do this right |
| 08:09:05 | <prince_arioch> | hm |
| 08:09:11 | <prince_arioch> | I love myself |
| 08:09:27 | <pumpkin> | prince_arioch: glad to hear it |
| 08:09:28 | <mmorrow> | that'd be sweet if there was a way to monitor mem access that was lighter weigth than a signal |
| 08:09:43 | <pumpkin> | I wonder how that interactive profiler is doing it |
| 08:09:48 | <pumpkin> | the one that person is working on |
| 08:09:59 | <pumpkin> | ACTION is so abstract |
| 08:10:11 | <prince_arioch> | I have this task: there are 6000 movies on a unix box |
| 08:10:35 | <prince_arioch> | each is /home/dir/movieX/wmv/movieID |
| 08:10:49 | <prince_arioch> | and some movies has 2 or 3 mvoieID folders |
| 08:11:02 | <prince_arioch> | my task is to delete all but the newest if there are multiple |
| 08:11:08 | <prince_arioch> | how do in haskell? |
| 08:11:27 | <mmorrow> | System.Directory and System.FilePath would be two you'd need |
| 08:11:35 | <mmorrow> | @hoogle getModificationTime |
| 08:11:36 | <lambdabot> | System.Directory getModificationTime :: FilePath -> IO ClockTime |
| 08:12:06 | <mmorrow> | (you'll probably need to rename all the functions from System.Directory in your module to avoid going insane) |
| 08:12:22 | <prince_arioch> | er |
| 08:12:22 | <prince_arioch> | ? |
| 08:12:23 | <mmorrow> | getTheContentsOfTheDirectoryPassedAndReturnThem |
| 08:12:34 | <mmorrow> | (they're painfully long) |
| 08:12:37 | <prince_arioch> | im already batty |
| 08:12:41 | <mmorrow> | ls = getTheContentsOfTheDirectoryPassedAndReturnThem |
| 08:12:44 | <mmorrow> | wee |
| 08:13:02 | <mmorrow> | @hoogle getCurrentDirectory |
| 08:13:03 | <lambdabot> | System.Directory getCurrentDirectory :: IO FilePath |
| 08:13:03 | <prince_arioch> | I love girls who are curvey, and michael moorcock novels, and I like netbsd |
| 08:13:06 | <mmorrow> | pwd = .. |
| 08:13:26 | <prince_arioch> | so haskell is well able to do files and directoies |
| 08:14:26 | <pumpkin> | it's a general-purpose language, I should hope it knows how to do files |
| 08:14:28 | <prince_arioch> | Im just totally fascinated |
| 08:14:37 | <pumpkin> | unless you have different notions of "do" ;) |
| 08:14:40 | <prince_arioch> | even tho sysadmin I know scoff at me and say I should learn python |
| 08:15:06 | <pumpkin> | prince_arioch: haskell is a fascinating language :) but if you stare too much you'll get drawn in and will never escape |
| 08:15:09 | <pumpkin> | get away while you still can! |
| 08:15:30 | <prince_arioch> | I feel lame because I tried learning common lisp 4 times |
| 08:15:34 | <prince_arioch> | and got frustrated |
| 08:15:48 | <prince_arioch> | I really only know a bit of tcl and bash |
| 08:17:47 | <dever> | sysadmin scoff at everyone |
| 08:18:03 | <pumpkin> | :) |
| 08:18:10 | <dever> | sysadmin make the baby dever cry |
| 08:18:29 | <pumpkin> | maybe I should make my benchmarking stuff available as a library when I'm done with it |
| 08:18:54 | <pumpkin> | it's slightly different from other approaches I've seen |
| 08:19:05 | <pumpkin> | closer to quickcheck |
| 08:21:18 | <dever> | ACTION must learn how to do *proper* testing in haskell |
| 08:21:47 | <hatds> | "but if you stare too much you'll get drawn in and will never escape" god isn't that the truth |
| 08:22:17 | <pumpkin> | it's a total timesink |
| 08:22:31 | <PeakerWork> | hmm.. I need a binary-search over data that's in IO. Is there any existing "monadic binary search"? |
| 08:22:34 | <pumpkin> | I just can't stop reading about it, experimenting with it, learning more, and branching out into the kind of theory that other haskellers enjoy |
| 08:22:51 | <pumpkin> | PeakerWork: how do you mean? |
| 08:23:03 | <hatds> | like binary tree or like find? |
| 08:23:22 | <PeakerWork> | (Ix a, Ord b) => b -> (a, a) -> (a -> IO b) -> a |
| 08:23:36 | <pumpkin> | hmm |
| 08:23:39 | <PeakerWork> | Something like this -- that binary searches using the given (a -> IO b), in the range (a, a) |
| 08:23:51 | <hatds> | here, I just wrote such a thing I think |
| 08:23:51 | <pumpkin> | ah I see |
| 08:23:56 | <PeakerWork> | s/IO/Monad m => m |
| 08:24:08 | <PeakerWork> | (Monad m, Ix a, Ord b) => b -> (a, a) -> (a -> m b) -> m a |
| 08:24:11 | <hatds> | scanfind1 :: [a] -> (a -> IO Bool) -> IO (Maybe a) |
| 08:24:13 | <hatds> | scanfind1 [] f = return Nothing |
| 08:24:15 | <hatds> | scanfind1 (a:as) f = do |
| 08:24:16 | <hatds> | boolean <- f a |
| 08:24:18 | <hatds> | if (boolean == True) |
| 08:24:19 | <hatds> | then return $ Just a |
| 08:24:21 | <hatds> | else scanfind1 as f |
| 08:24:31 | <hatds> | maybe should have hpasted that :) |
| 08:25:03 | <pumpkin> | not quite binary :) |
| 08:25:18 | <hatds> | oh didn't see that |
| 08:25:44 | <hatds> | also I apparently wrote boolean == True (covers face) |
| 08:25:58 | <PeakerWork> | hatds: I don't have a list, I have a range |
| 08:26:12 | <PeakerWork> | I guess I'll just write that binary search |
| 08:26:23 | <hatds> | there really should be a better way to get these functions |
| 08:26:34 | <hatds> | but you can fake it with unsafePerformIO/interleaveIO |
| 08:27:28 | <PeakerWork> | where is there binary search for pure stuff? |
| 08:27:33 | <PeakerWork> | @hoogle bisect |
| 08:27:33 | <lambdabot> | No results found |
| 08:27:36 | <PeakerWork> | @hoogle binary |
| 08:27:36 | <lambdabot> | package binary |
| 08:27:36 | <lambdabot> | package binary-search |
| 08:27:36 | <lambdabot> | package binary-strict |
| 08:27:40 | <PeakerWork> | aha |
| 08:27:50 | <yitz> | PeakerWork: a and b are also instances of some numeric class? |
| 08:28:32 | <hcube> | hi! i've a problem. Id like to compose two functions(f1 and f2), but it dont know how to do it. f1 :: c -> d f2 :: a -> b -> c the required result: (f1 . f2) :: a-> b -> d |
| 08:29:08 | <PeakerWork> | yitz: I have a set of files that can be viewed as one huge array of lines. a is an index into those lines (probably something that represents (Filename, LineNumber) |
| 08:29:17 | <PeakerWork> | yitz: b is basically an integer, yeah |
| 08:29:25 | <yitz> | @djinn (c->d)->(a->b->c)->a->b->d |
| 08:29:25 | <lambdabot> | f a b c d = a (b c d) |
| 08:29:35 | <Botje> | @pl f1 (f2 a b) |
| 08:29:36 | <lambdabot> | f1 (f2 a b) |
| 08:29:42 | <Botje> | @pl \a b -> f1 (f2 a b) |
| 08:29:43 | <lambdabot> | (f1 .) . f2 |
| 08:29:51 | <Botje> | hcube: there's your answer |
| 08:30:00 | <hcube> | thank you :) |
| 08:30:09 | <doserj> | @type (.).(.) |
| 08:30:11 | <lambdabot> | forall a b c a1. (b -> c) -> (a -> a1 -> b) -> a -> a1 -> c |
| 08:30:20 | <cadZzz> | waaat the fuk |
| 08:30:37 | <cadZzz> | what's (f1 .) even mean/ |
| 08:30:46 | <hatds> | left section of (.) |
| 08:30:48 | <hatds> | :) |
| 08:30:50 | <opqdonut> | it's a section with the . operator |
| 08:30:50 | <doserj> | but i usually define f .: g = (f .) . g |
| 08:31:10 | <pumpkin> | is .. a valid operator? probably not, eh |
| 08:31:43 | <hatds> | I just go with pointed syntax when it comes to this |
| 08:31:46 | <opqdonut> | > (+1) Prelude.. (*2) $ 3 |
| 08:31:47 | <lambdabot> | 7 |
| 08:31:51 | <opqdonut> | pumpkin: ^ |
| 08:32:01 | <opqdonut> | > let (..) = (+) in 1 .. 2 |
| 08:32:02 | <lambdabot> | <no location info>: parse error on input `..' |
| 08:32:05 | <pumpkin> | that's different :) |
| 08:32:13 | <opqdonut> | yeah it isn't a valid operator |
| 08:32:16 | <yitz> | @type (..) |
| 08:32:17 | <lambdabot> | parse error on input `..' |
| 08:32:18 | <pumpkin> | > let (...) = (+) in 1 ... 3 |
| 08:32:20 | <lambdabot> | 4 |
| 08:32:29 | <yitz> | pumpkin: it's a reserved op |
| 08:32:35 | <pumpkin> | for the list thing, I guess |
| 08:32:40 | <yitz> | yeah |
| 08:32:41 | <Alpounet> | yeah |
| 08:33:51 | <cadZzz> | @type (f .) |
| 08:33:53 | <lambdabot> | forall b c a. (Show b, SimpleReflect.FromExpr c) => (a -> b) -> a -> c |
| 08:34:01 | <yitz> | PeakerWork: and the a's are monotonic under the test function, I suppose |
| 08:34:41 | <pumpkin> | > let (...) f g = (f .) . (. g) in (("moo" ++) ... (++ "baa")) (++ "oi") "hohoho" |
| 08:34:43 | <lambdabot> | "moohohohobaaoi" |
| 08:34:52 | <pumpkin> | :P |
| 08:35:31 | <cadZzz> | that is not entirely wholesome. |
| 08:36:11 | <pumpkin> | wHOlesome? |
| 08:36:43 | <yakov> | hello |
| 08:37:08 | <PeakerWork> | yitz: what does monotonic mean? |
| 08:37:08 | <yitz> | PeakerWork: Ix is a pain in the neck. Maybe just use some numeric type there also? |
| 08:37:25 | <hatds> | I always use Ints instead of Ix |
| 08:37:26 | <yitz> | PeakerWork: increasing or decreasing |
| 08:38:10 | <PeakerWork> | yitz: yeah, I'm looking at the binary-search package, their type is nicer |
| 08:38:23 | <PeakerWork> | yitz: Just use (Integral a) and (a->Bool) rather than an Ord b |
| 08:38:29 | <cadZzz> | *either non-decreasing or non-increasing |
| 08:38:46 | <yitz> | cadZzz: right, that's better |
| 08:38:56 | <PeakerWork> | (Monad m, Integral a) => (a, a) -> (a -> m Bool) -> m a |
| 08:39:13 | <cadZzz> | hehe I should be sleep |
| 08:39:22 | <cadZzz> | night all |
| 08:39:28 | <yitz> | PeakerWork: are you sure you don't want a -> m Ordering? |
| 08:39:41 | <yakov> | i've converted socket to fd in order to set O_NONBLOCK to do non-blocking accept and accept refused to work on such a socket after (can't perform accept on socket in status ConvertedToHandle) do we have ability to set O_NONBLOCK for sockets? |
| 08:40:28 | <PeakerWork> | yitz: For binary search, you don't really need Ordering, you can have a "least one satisfying a condition" |
| 08:40:35 | <PeakerWork> | yitz: which is simpler and just as powerful, I think |
| 08:41:41 | <yitz> | PeakerWork: ah, ok |
| 08:42:10 | <MyCatVerbs> | yakov: use forkIO, accept in a seperate thread to the rest of the program. |
| 08:42:32 | <PeakerWork> | yitz: Making an Integral instance for (FileName, LineNumber) might be a little bit of a pain, though |
| 08:43:09 | <PeakerWork> | All-encompassing classes like Num are a pain to instantiate, even if nice to use. |
| 08:43:28 | <MyCatVerbs> | yakov: (Other than that, I'm not sure, the RTS deals with blocking-ness of IO inside itself. Best not to mess with it. But using forkIO to have (accept) run in a seperate Haskell thread works Just Fine, No Worries. ^_^) |
| 08:43:55 | <yitz> | PeakerWork: well you could define just the ops you need for binary search |
| 08:44:02 | <yakov> | MyCatVerbs, well, it's dirty workaround for api flow as for me (i know about the trick).. I need to poll for connections and in case there's no connections to something |
| 08:44:22 | <PeakerWork> | yitz: type-unsafe, though |
| 08:44:24 | <Lemmih> | ?ask dons Didn't you once have some benchmarking tools for Haskell implementations? |
| 08:44:25 | <lambdabot> | Consider it noted. |
| 08:44:42 | <yakov> | MyCatVerbs, the only question with this approach is how to kill thread gracefuly when it's blocked on foreign accept?! |
| 08:45:01 | <yakov> | seems like no sane way! |
| 08:45:15 | <yakov> | because of missing non-blocking call.. :-( |
| 08:45:15 | <yitz> | PeakerWork: if you need it to be general, roll your own type class. Or an ADT that wraps up the functions you need. |
| 08:46:09 | <yitz> | yakov: what's wrong with just killing it? |
| 08:46:13 | <MyCatVerbs> | yakov: do { mv <- newEmptyMVar; forkIO (forever $ do { (h,_,_) <- accept sock; putMVar mv h; }; {- rest of program goes here. -} ) |
| 08:46:24 | <PeakerWork> | yitz: I'm basically copying the binary-search code, and replacing it with monadic binary search |
| 08:46:33 | <MyCatVerbs> | yakov: and then you can poll the MVar mv. |
| 08:46:57 | <yakov> | yitz, killing is NOT portable and wrong by design |
| 08:46:59 | <yitz> | PeakerWork: bin search itself is pretty trivial, that |
| 08:47:03 | <yitz> | 's not your issue |
| 08:47:21 | <yitz> | yakov: not portable? |
| 08:47:35 | <MyCatVerbs> | yakov: Control.Concurrent.killThread works just fine, whether the thread being blown to smithereens is blocking in accept or not. |
| 08:47:44 | <yakov> | MyCatVerbs, yeah, but in case if there is NO connection accept will block for a long time and there's no way to know about it AFAIU |
| 08:48:14 | <yakov> | MyCatVerbs, really? i though that throwTo works only when I get out of foreign call after all |
| 08:48:15 | <PeakerWork> | yitz: http://hackage.haskell.org/packages/archive/binary-search/0.0/doc/html/src/Numeric-Search-Bounded.html |
| 08:48:25 | <PeakerWork> | yitz: simple, not trivial |
| 08:48:34 | <MyCatVerbs> | yakov: No. Sure, there's no way to time out on accept *in that thread*. But you can have more than one thread running! |
| 08:48:35 | <PeakerWork> | yitz: easy to make "off-by-one" bugs |
| 08:48:56 | <yitz> | PeakerWork: eh, after you've written them a few times you get used to it. |
| 08:49:31 | <PeakerWork> | yitz: I've written it a few times, but I'd still rather slightly adapt an existing one :-) |
| 08:49:54 | <yitz> | PeakerWork: most of the one-off issues actually are legitimate alternatives - you have to decide what you want your search to do when it gets close |
| 08:50:28 | <MyCatVerbs> | yakov: Network.accept is not implemented by just a bare call to C's accept(2). Internally it has to be implemented in a non-blocking manner, because otherwise it would block the rest of the RTS (when you're not using the threaded RTS, anyway). |
| 08:51:17 | <yakov> | well, yeah, i've checked it implementation but did not payed enough attention to investigate it's non-blockines.. thx for tip! |
| 08:51:25 | <yakov> | i need to dig this deeper |
| 08:55:35 | <cjs> | > let expr = return () :: IO () in expr `Control.Exception.Base.catch` const (return ()) |
| 08:55:37 | <lambdabot> | Not in scope: `Control.Exception.Base.catch' |
| 08:55:58 | <cjs> | > let expr = return () :: IO () in expr `Control.Exception.catch` const (return ()) |
| 08:55:59 | <lambdabot> | Not in scope: `Control.Exception.catch' |
| 08:56:15 | <cizra> | @src last |
| 08:56:15 | <lambdabot> | last [x] = x |
| 08:56:16 | <lambdabot> | last (_:xs) = last xs |
| 08:56:16 | <lambdabot> | last [] = undefined |
| 08:56:38 | <cizra> | ACTION pats lambdabot |
| 08:57:02 | <cjs> | Bah. But anyway, I get "Ambiguous type variable `e' in the constraint: Exception e..." Any nice way of getting around that in the above code, except by extrating the 'return ()' to a separate function and adding a type signature to it? |
| 08:58:35 | <sjanssen_> | cjs: I think the point of catch's new type is that it isn't typically valid to ignore all exceptions |
| 08:59:30 | <PeakerWork> | pretty ugly that fail takes a string.. |
| 08:59:36 | <PeakerWork> | @src MaybeT fail |
| 08:59:36 | <lambdabot> | Source not found. Just what do you think you're doing Dave? |
| 08:59:57 | <PeakerWork> | @src MonadError |
| 08:59:58 | <lambdabot> | class (Monad m) => MonadError e m | m -> e where |
| 08:59:58 | <lambdabot> | throwError :: e -> m a |
| 08:59:58 | <lambdabot> | catchError :: m a -> (e -> m a) -> m a |
| 09:00:36 | <PeakerWork> | I wonder if it makes sense to have a Monad m => MonadError () (MaybeT m) instance |
| 09:01:05 | <PeakerWork> | because such an instance does not seem to exist, and could work |
| 09:01:57 | <deeflex> | hey I get a stack overflow with my newbie code. http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5671#a5677 . Can someone please help out? |
| 09:02:13 | <sjanssen> | ACTION searches for foldl |
| 09:03:02 | <BONUS> | PeakerWork: pretty cool idea |
| 09:03:38 | <Botje> | deeflex: add a ! to every parameter of the loop definition |
| 09:03:47 | <Botje> | loop !fi !di !vi !ei !i | .... |
| 09:05:05 | <prince_arioch> | good night nobel haskellers |
| 09:06:11 | <PeakerWork> | BONUS: then I wouldn't have to use fail "" |
| 09:06:19 | <PeakerWork> | throwError () is nicer :-) |
| 09:06:54 | <deeflex> | Botje, ok let me try. |
| 09:08:46 | <quicksilver> | PeakerWork: well it overlaps. |
| 09:08:55 | <quicksilver> | PeakerWork: that's the general problem with instance schemes like that. |
| 09:08:57 | <PeakerWork> | quicksilver: with what? |
| 09:09:08 | <quicksilver> | PeakerWork: with a (possible) lifted MonadError instance |
| 09:09:11 | <quicksilver> | if "m" already had one. |
| 09:09:42 | <PeakerWork> | quicksilver: that's true of any instance of MonadError on a transformer, perhaps even of any type-class on a transformer? |
| 09:10:09 | <deeflex> | Botje, That didn't work. Syntax error in declaration (unexpected `!') . Do I need to import something? |
| 09:11:09 | <mux> | deeflex: add {-# LANGUAGE BangPatterbs #-} at the first line |
| 09:11:16 | <mux> | woops, make that BangPatterns :-) |
| 09:11:57 | <deeflex> | mux, heh ok...hold on |
| 09:11:58 | <quicksilver> | PeakerWork: yes, it is. |
| 09:12:07 | <quicksilver> | PeakerWork: it's the problem of instance schemes on transformers. |
| 09:12:34 | <quicksilver> | PeakerWork: the "suggested" fix is to newtype your *actual* stack, and then write the instance on that. |
| 09:12:34 | <mux> | deeflex: alternatively, you could have compiled with -XBangPatterns |
| 09:12:50 | <quicksilver> | ...would be nice if there was a way to reduce the boilerplate on that. |
| 09:13:55 | <deeflex> | mux, that line..is that GHC specific? Im running hugs and that's not working. |
| 09:14:21 | <psygnisfive> | deeflex: you need to running kisses along side to make it work properly |
| 09:14:23 | <sjanssen> | deeflex: Hugs doesn't support bang patterns |
| 09:14:37 | <deeflex> | OK |
| 09:14:55 | <sjanssen> | deeflex: by the way, I don't think anybody seriously uses Hugs any more |
| 09:17:05 | <deeflex> | sjanssen, well ...there must be a solution to my problem, not involving switching to ghc. =) |
| 09:17:40 | <quicksilver> | deeflex: bangpatterns are just syntactic sugar |
| 09:17:43 | <quicksilver> | you can use seq instead |
| 09:18:01 | <quicksilver> | loop !a !b !c = (....) is rewritten as |
| 09:18:11 | <quicksilver> | loop a b c = a `seq` b `seq` c `seq` (....) |
| 09:18:58 | <sjanssen> | deeflex: http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5671#a5678 |
| 09:19:07 | <sjanssen> | ie. do as quicksilver says :) |
| 09:19:18 | <quicksilver> | good advice. |
| 09:19:36 | <sjanssen> | deeflex: if this doesn't fix the issue, you probably have an infinite loop somewhere |
| 09:20:18 | <deeflex> | sjanssen, ok...let me try your (and quicksilver's ) solution |
| 09:21:22 | <PeakerWork> | quicksilver: hmm. What about not having lifted instances? |
| 09:21:26 | <PeakerWork> | quicksilver: (Except explicit ones) |
| 09:22:59 | <quicksilver> | PeakerWork: well, then you'd miss out on the MonadState instance of MaybeT (StateT (...)) |
| 09:23:02 | <quicksilver> | ACTION shrugs |
| 09:23:05 | <deeflex> | sjanssen, nope didn't work :) |
| 09:23:14 | <quicksilver> | obviously you could take a decision to only have instances for the top-level constructor. |
| 09:24:49 | <PeakerWork> | quicksilver: I don't want that instance |
| 09:25:12 | <PeakerWork> | quicksilver: I want explicit lifting for the state, because otherwise it has no name. I like giving my state a name |
| 09:25:32 | <quicksilver> | fair enough. |
| 09:25:41 | <quicksilver> | I also haev misgivings about MonadState |
| 09:25:51 | <quicksilver> | but it would be nicer if there was easier ways to *write* the instances. |
| 09:26:14 | <quicksilver> | you're obviously going to want, in some way, a special version of get/put/modify for your custom newtype. |
| 09:26:20 | <quicksilver> | it would be nice if it was simple to write those. |
| 09:26:59 | <PeakerWork> | quicksilver: I'd be ok with get/put/modify hard-coded for StateT, and just have liftMyStatename $ get .. |
| 09:27:32 | <sjanssen> | deeflex: I see you're using minimumBy, that has a space leak with long lists |
| 09:29:28 | <dhun> | lambda.org is gay website, don't want to hurt anybodies feelings, neither gay ones nor functional programmers, but still I smile about it, "a programmer could not but be gay such a functional company ", freely adapted from Daffodils by William Wordsworth |
| 09:31:44 | <deeflex> | sjanssen, oh ok. Anyway I don't quite understand, even if I for example call neighbor with an empty list, I get a stack overflow. |
| 09:32:05 | <ski> | (PeakerWork : .. i'd like something like that, as well) |
| 09:33:19 | <ski> | (i.e. being able to associate names with the layers of a monad transformer stack, and then use the names to refer to which layer an operation should be run in) |
| 09:33:42 | <PeakerWork> | ski: I do it manually by newtype'ing a stack and writing boiler-plate lifters |
| 09:33:52 | <PeakerWork> | liftBlah = lift . lift ; liftBleh = lift . lift . lift |
| 09:34:46 | <ski> | PeakerWork : yes, except some of the operations aren't as simple to lift as just a few `lift' calls chained |
| 09:35:45 | <ski> | e.g. |
| 09:35:46 | <ski> | @type catchError |
| 09:35:47 | <lambdabot> | forall (m :: * -> *) a e. (MonadError e m) => m a -> (e -> m a) -> m a |
| 09:38:33 | <quicksilver> | antyhing with a callback. |
| 09:40:20 | <ski> | *nod* |
| 09:42:46 | <ski> | ideally we'd like a solution that allows to write down once how to lift `MonadFoo'-operations over each `BarT' monad transformer, like currently with the instances, but which also allows one to pick and choose which layer one wants certain operations to execute in (e.g. if one has several `StateT' layers) |
| 09:43:47 | <quicksilver> | ski: yes. I want a "instance recipe" |
| 09:43:52 | <quicksilver> | ski: that I can apply |
| 09:43:57 | <quicksilver> | ski: a little bit like an ML functor |
| 09:44:05 | <quicksilver> | in the sense that I give it parameters and it generates code. |
| 09:44:41 | <ski> | hm .. maybe it's similar to ML functors in some way i don't see clearly |
| 09:45:16 | <ski> | ACTION was before thinking of some kind of type system extension which lets you label the layers in the type, and use those labels in operations to specify which layer is wanted |
| 10:03:18 | <PeakerWork> | ski: You can use (lift . lift $ catchError ..) if you're only using monadic operations of the inner monads, right? |
| 10:03:53 | <PeakerWork> | ski: is it possible for catchError buried deep inside to be used to perform exception handling with actions of outer monads? |
| 10:05:34 | <ski> | PeakerWork : how do you mean ? |
| 10:09:34 | <PeakerWork> | ski: what's the problem with a lifted catchError? That the "m a" in your catch handler is limited to the inner monads, right? |
| 10:11:21 | <quicksilver> | inner or outer depending which way out your mental model is |
| 10:11:23 | <quicksilver> | but, yes. |
| 10:11:53 | <PeakerWork> | heh |
| 10:12:56 | <ski> | PeakerWork : look e.g. at the `MonadError' instance at <http://haskell.org/ghc/docs/latest/html/libraries/mtl/src/Control-Monad-State-Lazy.html#(line208)> |
| 10:12:58 | <PeakerWork> | So if I have (StateT s (MaybeT m)) -- is it equivalent to MaybeT (StateT s m) in terms of failure handling? |
| 10:13:20 | <ski> | `throwError' there is defined by using `lift', like you suggested |
| 10:13:34 | <ski> | but `catchError' there can't be implemented that way |
| 10:13:54 | <ski> | you need to know implementation details about `StateT' to define it |
| 10:14:05 | <ski> | that's not something which you want to do in your own code |
| 10:14:06 | <PeakerWork> | ah, so each monad has to be specifically aware of catchError to implement it, it cannot be implemented in the general case? |
| 10:14:32 | <PeakerWork> | maybe StateT could implement some more generic operation? Perhaps that alternate monad transformer implementation that avoids the O(N*N) instance problem? |
| 10:15:19 | <ski> | at least in the way the monad classes are implemented right now, you need (at most) one instance for each combination of a monad transformer and a monad class providing certain operations |
| 10:15:34 | <ski> | (and i'm not sure how one could avoid this) |
| 10:15:41 | <PeakerWork> | ski: does the catchError implementation of StateT make the ordering of StateT and the error monad not meaningful? e.g: Making the (StateT s (ErrorT e m)) and ErrorT e (StateT s m) equivalent? |
| 10:16:14 | <PeakerWork> | ski: Someone told me a little while ago that there's an implementation of monad transformers that avoids the N^2 instance problem by defining a method more general or more powerful than "lift" |
| 10:16:22 | <ski> | there might be some more general operation .. like `lift', but also allowing handling callbacks in some way, that could be used, yes |
| 10:16:33 | <ski> | but i don't know which operation that would be |
| 10:17:41 | <ski> | no, that `instance MonadError e m => MonadError e (StateT s m)' doesn't by itself make `StateT s (ErrorT e m)' and `ErrorT e (StateT s m' equivalent |
| 10:18:26 | <ski> | all it does is allow you to use the `MonadError' operations (`throwError',`catchError') on `StateT s m', assuming you can already use them on `m' |
| 10:19:13 | <ski> | you could already do the same as `throwError' on `StateT s m' before by doing `lift . throwError', which is not very hard/problematic |
| 10:19:14 | <Cale> | PeakerWork: istr it was a package on hackage |
| 10:19:14 | <lambdabot> | Cale: You have 1 new message. '/msg lambdabot @messages' to read it. |
| 10:19:21 | <PeakerWork> | Cale: yeah |
| 10:19:41 | <ski> | what is problematic is having to know about internal implementation details to "lift" `catchError' in a similar way |
| 10:19:50 | <Cale> | http://hackage.haskell.org/packages/archive/mmtl/0.1/doc/html/Control-Monad-Trans.html |
| 10:19:54 | <Cale> | tmap :: (Monad m, Monad n) => (forall a. m a -> n a) -> (forall b. n b -> m b) -> t m c -> t n c |
| 10:20:40 | <ski> | that instance therefore allows one to use `catchError' directly on `StateT s m' monads .. but you can't select which layer of the transformer stack you want the `MonadError' operations to apply to |
| 10:21:26 | <ski> | ACTION wouldn't have `(forall b. n b -> m b)' there in the type of `tmap' |
| 10:21:45 | <ski> | (yes, i know it's probably required for some instance .. but it's more restrictive) |
| 10:21:48 | <Cale> | ski: It appears needed for Cont |
| 10:22:12 | <Cale> | Many other instances seem to ignore it... |
| 10:22:16 | <ski> | so `Cont' should use an `tExpMap' (or whatever it is to be called) |
| 10:22:44 | <ski> | often it is not possible to do both a `forall a. m a -> n a' and a `forall b. n b -> m b' for certain `m',`n' |
| 10:22:59 | <ski> | it should not be required, unless it is needed |
| 10:24:57 | <ski> | (an endo-functor over the category of haskell-monads should just have the `forall a. m a -> n a' direction, as argument) |
| 10:25:01 | <PeakerWork> | why does tmap need a two-way conversion, and not just one-way to convert the transformed monad? |
| 10:25:11 | <Cale> | PeakerWork: for Cont |
| 10:25:16 | <PeakerWork> | ah |
| 10:25:33 | <Cale> | (and monads of that sort, I suppose) |
| 10:25:33 | <PeakerWork> | I thought ski asked about the forall there |
| 10:26:05 | <ski> | nono .. i commented about both having `m -> n' and `n -> m' natural transformations |
| 10:26:21 | <ski> | (should maybe actually be monad morphisms ..) |
| 10:58:23 | <mamalujo> | hi! So, Id like to try haskell platform tar on my deban. I presume I should remove debian packages of libs and tools included in the platform first? |
| 11:01:50 | <dever> | quit |
| 11:05:33 | <Tarrant> | So I'm playing with some basic IO stuff. I have a function along the lines of 'contents <- getContents; hPutStr handle contents' I call said function in GHCi and ^D doesn't work to send the eof. Does eof just not work in ghci or am I doing something wrong? |
| 11:05:59 | <cizra> | Perhaps you're on Windwoes? |
| 11:06:18 | <Tarrant> | cizra: Nope definitely a Unix (FreeBSD) box. |
| 11:06:35 | <Tarrant> | I should also mention said code works great when run using 'runhaskell' |
| 11:06:41 | <cizra> | Tarrant: Are you really sure? Perhaps it's just a cleverly disguised wolf in a lamb skin... |
| 11:06:50 | <cizra> | Tarrant: Oh, please don't listen to me |
| 11:09:00 | <quicksilver> | Tarrant: in ghci, stdin of your process is just stdin of ghci |
| 11:09:14 | <quicksilver> | Tarrant: if you managed to send EOF it would be EOF for ghci, not EOF for your program |
| 11:09:20 | <quicksilver> | that wouldn't be good, so it's blocked. |
| 11:11:10 | <Tarrant> | Makes sense. |
| 11:13:45 | <quicksilver> | of course, it would be nice if there was a clever way to make it work. |
| 11:14:14 | <Tarrant> | quicksilver: Wouldn't life just be great :) |
| 11:23:31 | <lilac> | quicksilver: there is a clever way to make it work, but it'd require ghci to do smarter terminal handling stuff |
| 11:24:24 | <quicksilver> | lilac: does ghci do its own terminal handling? or delegate it to the readline flavour in use? |
| 11:24:31 | <quicksilver> | lilac: presumably the key is to allocate a fresh pty? |
| 11:25:05 | <lilac> | i don't know what ghci does if it's using readline; my ghci is more broken than that :) |
| 11:25:15 | <lilac> | ACTION has no line editing at all |
| 11:25:58 | <lilac> | but readline should restore the terminal to a sensible state while a command is running, so i think that's a red herring |
| 11:27:03 | <lilac> | in any case, i was thinking that if ghci insists on switching the terminal into raw mode, it should simulate cooked mode for things run within it |
| 11:27:36 | <lilac> | (that is, translate the EOF key into an actual EOF when running code) |
| 11:27:53 | <lilac> | allocating a new pty sounds good too; either way I guess it means hacking the IO implementation a bit |
| 11:35:14 | <PeakerWork> | @src filterM |
| 11:35:14 | <lambdabot> | Source not found. Maybe you made a typo? |
| 11:36:45 | <PeakerWork> | how do I find out what modules are exposed by an installed package? |
| 11:40:57 | <PeakerWork> | tar tvzf ~/.cabal/packages/*/<package-name>/<version>/* I guess |
| 11:41:21 | <dcoutts> | PeakerWork: cabal info thepkgname |
| 11:41:46 | <PeakerWork> | ah, thanks |
| 11:41:47 | <dcoutts> | lists the modules and more useful info |
| 11:42:47 | <PeakerWork> | if cabal-install re-exposed some ghc-pkg stuff (unregister, find-module, list) it could allow users to know just a single interface, no? |
| 12:10:18 | <hatds> | what's the idiomatic way of writing a list to a file so that it is easy to append values to the list later? |
| 12:13:22 | <hatds> | is there a middle ground between writing each element of the list to a line (makes reading less nice) and just 'show'ing the list (makes appending less nice)? |
| 12:13:50 | <FliPPeh> | Man, the tutorials did not lie |
| 12:14:10 | <FliPPeh> | Once you manage to surpress type errors, you'll be surprised too see how often a code works on the first try |
| 12:14:34 | <cizra> | FliPPeh: amen, brohter |
| 12:14:40 | <mmorrow> | hatds: write a `show'ed list to each line |
| 12:14:50 | <kig> | and still does the wrong thing when unit-tested ;D |
| 12:14:51 | <hatds> | then concat? |
| 12:14:53 | <hatds> | I see |
| 12:14:55 | <mmorrow> | they don't even need to be the same size |
| 12:14:57 | <mmorrow> | yeah |
| 12:15:01 | <FliPPeh> | I mean |
| 12:15:06 | <mmorrow> | concatMap read . lines |
| 12:15:09 | <FliPPeh> | I just learned catching exceptions |
| 12:15:19 | <FliPPeh> | And it runs flawlessy here |
| 12:18:42 | <FliPPeh> | Anyone would like to look at my short code and tell me, if that's good coding style, and if I'm thinking Haskell correctly? |
| 12:19:07 | <EvilTerran> | hatds, using, say, "mapM_ (hPrint fh)" to write them out one line at a time could be inverted with something fairly simple like "mapM readIO . lines =<< hGetContents fh" |
| 12:19:34 | <FliPPeh> | http://moonpatio.com/fastcgi/hpaste.fcgi/view?id=2620#a2620 |
| 12:19:37 | <FliPPeh> | Good so far? |
| 12:20:46 | <EvilTerran> | FliPPeh, if you line up the first character of "case" with the first character of "handle <-", you won't need that semicolon |
| 12:21:13 | <EvilTerran> | similarly for the bit with isAvailable further down |
| 12:21:20 | <FliPPeh> | Okay, thanks :) |
| 12:21:24 | <FliPPeh> | I wondered why I had to put that |
| 12:22:00 | <EvilTerran> | FliPPeh, if you indent a line more than the first line in a do block, it's considered to be a continuation of the previous line |
| 12:22:10 | <EvilTerran> | iirc |
| 12:22:38 | <EvilTerran> | FliPPeh, also, you could probably write handleInput neater with guards |
| 12:22:39 | <ski> | FliPPeh : in `handleInput', use pattern-matching instead of if head s == ':' |
| 12:22:54 | <EvilTerran> | and that |
| 12:22:59 | <FliPPeh> | Thanks, didn't think about that! |
| 12:23:09 | <ski> | and use a `case' instead of if head (words s) == "PING" and if length (words s) > 1 |
| 12:23:45 | <ski> | (well, a guard might work instead) |
| 12:24:40 | <gwern> | huh. I just realized that my conviction that GNU Hurd development was being pushed forwards by a bunch of Turkish hackers, actually comes from a dream the other day |
| 12:24:41 | <lambdabot> | gwern: You have 2 new messages. '/msg lambdabot @messages' to read them. |
| 12:24:44 | <gwern> | I hate when that happens |
| 12:25:30 | <ski> | (.. happened often ?) |
| 12:25:39 | <gwern> | ski: distressingly so |
| 12:25:41 | <EvilTerran> | FliPPeh, actually (considering ski's comment), i'd write something like: case words s of ... "PING":ws -> ...; _ -> return () |
| 12:25:57 | <FliPPeh> | I just used guars |
| 12:25:59 | <FliPPeh> | guards |
| 12:26:01 | <FliPPeh> | Erm |
| 12:26:03 | <FliPPeh> | Pattern Matching |
| 12:26:13 | <gwern> | it's something of a problem; I'll dream I did something, or I'll learn something in a dream, and then I won't forget it in real life |
| 12:26:13 | <FliPPeh> | handleInput h (':':rest) = return () |
| 12:26:13 | <FliPPeh> | handleInput h s = if head (words s) == "PING" |
| 12:26:15 | <FliPPeh> | :) |
| 12:26:22 | <gwern> | @messages |
| 12:26:22 | <lambdabot> | kowey said 4h 2m 34s ago: gitit: Server error: UnknownError: mergeContents requires 'git' or 'merge', and neither was found in the path -- happens if I'm editing something, and somebody updates the |
| 12:26:22 | <lambdabot> | page before I hit save |
| 12:26:22 | <lambdabot> | kowey said 4h 2m 12s ago: I've also uploaded gitit-with-help which I believe has John's RST-help stuff |
| 12:26:23 | <marco_g> | gwern: Many Hurd hackers live in Germany, the USA and France in reality :-) |
| 12:26:30 | <EvilTerran> | actually, "PING":pinger:_ -> ... |
| 12:26:38 | <marco_g> | ACTION wonders why gwern dreams about Hurd developers... |
| 12:26:41 | <EvilTerran> | would work nicely |
| 12:26:45 | <ski> | FliPPeh : that's not a guard .. |
| 12:26:48 | <FliPPeh> | As I said |
| 12:26:51 | <FliPPeh> | [14:25:21] <FliPPeh> Erm |
| 12:26:51 | <FliPPeh> | [14:25:24] <FliPPeh> Pattern Matching |
| 12:27:08 | <gwern> | marco_g: dunno either. it just was in my dream! dreams aren't known for making sense |
| 12:27:09 | <ski> | it's using `if'-`then'-`else' |
| 12:27:25 | <ski> | using guards would be like |
| 12:27:30 | <FliPPeh> | EvilTerran, I'm getting the input as a single string, so it won't come as ["PING" ":894372894"] but as "PING :89456465" |
| 12:27:30 | <ski> | handleInput h (':':rest) = return () |
| 12:27:34 | <ski> | handleInput h s |
| 12:27:40 | <ski> | | head (words s) == "PING" = ... |
| 12:27:47 | <ski> | | ... |
| 12:27:52 | <marco_g> | gwern: Were they singing the free software song? |
| 12:27:54 | <EvilTerran> | FliPPeh, say: case words s of ... "PING":pinger:_ -> sendLine h $ "PONG " ++ pinger; _ -> return () |
| 12:27:55 | <gwern> | @tell kowey yeah, that's what happens with edit conflicts. gitit first trys to use git's merge functionality, then falls back to generic unix util merge. guess neither was in wiki.darcs.net's $PATH... |
| 12:27:56 | <lambdabot> | Consider it noted. |
| 12:28:07 | <FliPPeh> | Oh, didn't think about PM in case expressions |
| 12:28:09 | <EvilTerran> | FliPPeh, that's why it's "case words s of", not just "case s of" :) |
| 12:28:16 | <gwern> | marco_g: no, I have the vague impression that I was reading about the turks in some mailin list |
| 12:29:28 | <FliPPeh> | Man |
| 12:29:31 | <FliPPeh> | I love pattern matching |
| 12:29:31 | <FliPPeh> | case words s of |
| 12:29:32 | <FliPPeh> | "PING":pingString:_ -> sendLine h $ "PONG " ++ pingString |
| 12:29:37 | <FliPPeh> | :) |
| 12:29:41 | <FliPPeh> | Thanks EvilTerran |
| 12:29:52 | <EvilTerran> | pattern matching is _awesome_. every language should have it. :) |
| 12:29:58 | <FliPPeh> | Again killed off 4 lines of unneccessary error checking |
| 12:30:48 | <EvilTerran> | so, what do you have now? |
| 12:31:21 | <FliPPeh> | http://moonpatio.com/fastcgi/hpaste.fcgi/view?id=2621#a2621 |
| 12:31:22 | <FliPPeh> | This |
| 12:31:53 | <FliPPeh> | I now don't even have to check if the input is long enough to actually do head (tail s) and not worry about exceptioning |
| 12:32:10 | <ski> | (FliPPeh : maybe next time annotate the existing paste ?) |
| 12:32:22 | <FliPPeh> | okay |
| 12:33:52 | <FliPPeh> | handleInput h (':':rest) = case words rest of |
| 12:33:52 | <FliPPeh> | (nick:'!':user:'@':host):command:params -> return () |
| 12:33:57 | <FliPPeh> | That did ACTUALLY COMPILE? |
| 12:34:18 | <FliPPeh> | Just a fun thing I wanted to try out |
| 12:34:18 | <EvilTerran> | i doubt it meant what you wanted, though |
| 12:34:27 | <FliPPeh> | I'll test that |
| 12:34:33 | <PeakerWork> | to break out of a forM_, is it customary to callCC? |
| 12:34:33 | <EvilTerran> | nick, user :: Char; host :: String |
| 12:35:04 | <FliPPeh> | Yep |
| 12:35:06 | <FliPPeh> | It made it a char |
| 12:35:10 | <FliPPeh> | Too bad :) |
| 12:35:15 | <EvilTerran> | PeakerWork, i've used EitherT for that |
| 12:35:23 | <EvilTerran> | (not mtl's broken ErrorT, mind) |
| 12:35:32 | <PeakerWork> | EvilTerran: how si mtl's ErrorT broken, which one isn't? |
| 12:35:51 | <PeakerWork> | EvilTerran: and how do you "catch" the error, or do you just runErrorT and ignore it? |
| 12:35:55 | <EvilTerran> | the Error class constraint is trouble |
| 12:35:57 | <dhun> | how can I say that a type should be bound to two classes like :: Show a,Eq a => ? |
| 12:36:14 | <PeakerWork> | dhun: () around the constraints |
| 12:36:22 | <PeakerWork> | dhun: (Show a, Eq a) => a -> Bool |
| 12:36:27 | <dhun> | ok |
| 12:36:44 | <ski> | @src Error |
| 12:36:45 | <lambdabot> | class Error a where |
| 12:36:45 | <lambdabot> | noMsg :: a |
| 12:36:45 | <lambdabot> | strMsg :: String -> a |
| 12:36:57 | <EvilTerran> | PeakerWork, i'd <- runEitherT and then pattern-match the result |
| 12:36:59 | <ski> | PeakerWork : presumably that it insists on having those two methods implemented for any exception type ? |
| 12:37:09 | <EvilTerran> | ski, exactly |
| 12:37:23 | <ski> | ACTION has been irked by that several times |
| 12:37:32 | <EvilTerran> | PeakerWork, if you're breaking out because you've got an error, ErrorT would be fine. i was thinking for the more general use of short-circuiting out when it's not actually an error |
| 12:39:26 | <ski> | (also the fact that the `Monad (Either e)' instance is destroyed by adding a `Error e' constraint ..) |
| 12:39:37 | <PeakerWork> | EvilTerran: I guess ErrorT is more specifically suited to "breaking" loops than ContT which can do anything at all |
| 12:39:46 | <PeakerWork> | EvilTerran: hey, even MaybeT |
| 12:40:09 | <EvilTerran> | FliPPeh, for the purposes of splitting up a nick!user@host, i'd suggest using 'break' |
| 12:40:09 | <dhun> | so I got my first polymorphic type, the funny thing about Haskell is that I can generalize things, of which I believed that even special cases were to hard to implement |
| 12:40:18 | <FliPPeh> | okay |
| 12:40:22 | <EvilTerran> | PeakerWork, sure, MaybeT works if you don't want to pass a value out when you're done |
| 12:40:32 | <EvilTerran> | > break (=='!') "nick!user@host" |
| 12:40:33 | <lambdabot> | ("nick","!user@host") |
| 12:40:40 | <PeakerWork> | EvilTerran: ErrorT is a bad name, should have been EitherT |
| 12:40:43 | <EvilTerran> | > break (=='!') "no excalamation marks" |
| 12:40:44 | <lambdabot> | ("no excalamation marks","") |
| 12:40:50 | <ski> | ACTION hasn't really an idea for when `ErrorT' would be appropriate .. maybe in some open-ended exception-type situation |
| 12:41:17 | <EvilTerran> | PeakerWork, well, it's the right name for the instance, considering the Error e => constraint |
| 12:41:34 | <fasta> | EvilTerran: what's wrong with ErrorT? |
| 12:41:36 | <EvilTerran> | PeakerWork, but i'd rather have an instance without the constraint, and call it EitherT. |
| 12:41:37 | <PeakerWork> | ski: consider having no IO exceptions at all, but instead having the type of stuff that can break be ErrorT IOError IO a ? |
| 12:41:46 | <EvilTerran> | fasta, ski has explained above |
| 12:42:06 | <PeakerWork> | EvilTerran: yeah, what does the constraint help with? |
| 12:42:20 | <EvilTerran> | PeakerWork, "fail" :/ |
| 12:42:20 | <PeakerWork> | EvilTerran: can have more functions with more restrictions, if one wants |
| 12:42:38 | <PeakerWork> | EvilTerran: the incorrectness of the monad class design manifests itself everywhere, eh? |
| 12:42:42 | <EvilTerran> | ?src Either fail |
| 12:42:42 | <lambdabot> | fail msg = Left (strMsg msg) |
| 12:42:55 | <EvilTerran> | >:[ |
| 12:43:25 | <ski> | @src Either mzero |
| 12:43:26 | <lambdabot> | mzero = Left noMsg |
| 12:43:59 | <EvilTerran> | ^ the problem is the Error constraint in the Either instance, really; i can always define my own newtype EitherT, but it'd be extra clunky to have my own type isomorphic to just Either |
| 12:44:50 | <ski> | ACTION defined `Exn' and `ExnT' just to get around this |
| 12:54:41 | <akamaus> | can someone help with building curl binding on windows? Cabal says it couldn't find curl library but I have dev version of curl installed in cygwin |
| 12:55:26 | <FliPPeh> | > join ["a", "b"] ',' |
| 12:55:27 | <lambdabot> | Couldn't match expected type `GHC.Types.Char -> t' |
| 12:55:29 | <FliPPeh> | Mhh |
| 12:55:38 | <FliPPeh> | > interpserse ["a", "b"] ',' |
| 12:55:39 | <lambdabot> | Not in scope: `interpserse' |
| 12:55:44 | <FliPPeh> | > intersperse ["a", "b"] ',' |
| 12:55:45 | <lambdabot> | Couldn't match expected type `[[[GHC.Types.Char]]]' |
| 12:55:52 | <FliPPeh> | > intersperse ',' ["a", "b"] |
| 12:55:53 | <lambdabot> | Couldn't match expected type `GHC.Types.Char' |
| 12:55:55 | <FliPPeh> | :( |
| 12:55:56 | <quicksilver> | why does LB give these stupid error messsages ? |
| 12:56:08 | <quicksilver> | is it because it has GHC.Types in scope? |
| 12:56:12 | <quicksilver> | if so, can we remove it? |
| 12:56:20 | <quicksilver> | :t intersperse |
| 12:56:21 | <lambdabot> | forall a. a -> [a] -> [a] |
| 12:56:29 | <quicksilver> | FliPPeh: the type tells you what you need to know |
| 12:56:37 | <quicksilver> | > intersperse ',' "ab" |
| 12:56:38 | <lambdabot> | "a,b" |
| 12:56:52 | <PeakerWork> | > intersperse "," ["a", "b"] |
| 12:56:53 | <lambdabot> | ["a",",","b"] |
| 12:56:54 | <FliPPeh> | Well, Got a list of strings here |
| 12:57:11 | <PeakerWork> | @type (concat.) . intersperse |
| 12:57:12 | <lambdabot> | forall a. [a] -> [[a]] -> [a] |
| 12:57:13 | <FliPPeh> | Want to join them from ["aaa","bbbb"] to aaa,bbb |
| 12:57:19 | <jix_> | > concat $ intersperse "," ["a", "b"] |
| 12:57:20 | <lambdabot> | "a,b" |
| 12:57:23 | <PeakerWork> | forecasted you :-) |
| 12:57:29 | <FliPPeh> | :) |
| 12:57:44 | <PeakerWork> | > concat . intersperse "," $ ["hello", "world"] |
| 12:57:45 | <lambdabot> | "hello,world" |
| 12:57:47 | <ClaudiusMaximus> | @src intercalate |
| 12:57:47 | <lambdabot> | intercalate xs xss = concat (intersperse xs xss) |
| 12:58:01 | <PeakerWork> | @. pl src intercalate |
| 12:58:02 | <lambdabot> | (line 1, column 1): |
| 12:58:02 | <lambdabot> | unexpected end of input |
| 12:58:02 | <lambdabot> | expecting white space, "()", natural, identifier, lambda abstraction or expression |
| 12:58:12 | <PeakerWork> | @pl intercalate xs xss = concat (intersperse xs xss) |
| 12:58:12 | <lambdabot> | intercalate = (join .) . intersperse |
| 12:58:48 | <quicksilver> | FliPPeh: "well I got a list of strings here" -- the answer is : So in that case, use that type with a = String, see? |
| 12:58:51 | <quicksilver> | ;) |
| 12:59:01 | <FliPPeh> | > concat . intersperse "," $ ["hello"] |
| 12:59:01 | <lambdabot> | "hello" |
| 13:00:08 | <FliPPeh> | :type concat |
| 13:00:13 | <FliPPeh> | :t concat |
| 13:00:14 | <lambdabot> | forall a. [[a]] -> [a] |
| 13:00:28 | <FliPPeh> | > concat [1,3,4,3,2,4,4] |
| 13:00:29 | <lambdabot> | No instance for (GHC.Num.Num [a]) |
| 13:00:29 | <lambdabot> | arising from the literal `1' at <inter... |
| 13:00:40 | <FliPPeh> | > show (concat [1,3,4,3,2,4,4]) |
| 13:00:42 | <lambdabot> | No instance for (GHC.Num.Num [a]) |
| 13:00:42 | <lambdabot> | arising from the literal `1' at <inter... |
| 13:00:54 | <FliPPeh> | > concat ['s','o'] |
| 13:00:55 | <lambdabot> | Couldn't match expected type `[a]' |
| 13:00:55 | <ski> | > concat [[0,1,2,3],[4,5,6],[7,8],[9],[]] |
| 13:00:56 | <lambdabot> | [0,1,2,3,4,5,6,7,8,9] |
| 13:00:57 | <FliPPeh> | ;S |
| 13:00:59 | <FliPPeh> | Oh.. |
| 13:01:05 | <FliPPeh> | Stupid me |
| 13:01:07 | <RayNbow> | FliPPeh, intercalate = concat . intersperse |
| 13:01:08 | <FliPPeh> | double list |
| 13:01:18 | <ski> | > concat ["a","quick","brown","fox"] |
| 13:01:20 | <lambdabot> | "aquickbrownfox" |
| 13:01:37 | <RayNbow> | > unwords ["a","quick","brown","fox"] |
| 13:01:39 | <lambdabot> | "a quick brown fox" |
| 13:02:03 | <RayNbow> | > intercalate "--" ["a","quick","brown","fox"] |
| 13:02:04 | <lambdabot> | "a--quick--brown--fox" |
| 13:02:06 | <FliPPeh> | > intercalate ',' ["testing", "furiously"] |
| 13:02:07 | <lambdabot> | Couldn't match expected type `[a]' |
| 13:02:10 | <RayNbow> | ah wait |
| 13:02:15 | <jthing> | > words "a quick brown fox" |
| 13:02:16 | <lambdabot> | ["a","quick","brown","fox"] |
| 13:02:30 | <FliPPeh> | > intercalate "," ["testing", "furiously"] |
| 13:02:31 | <lambdabot> | "testing,furiously" |
| 13:02:40 | <bryan1> | > reverse ["a","quick","brown","fox"] |
| 13:02:42 | <lambdabot> | ["fox","brown","quick","a"] |
| 13:02:59 | <ski> | @free concat |
| 13:03:01 | <lambdabot> | $map f . concat = concat . $map ($map f) |
| 13:03:24 | <FliPPeh> | Sooo |
| 13:03:44 | <jthing> | > reverse "ablewasiwhenisawelba" |
| 13:03:45 | <lambdabot> | "ablewasinehwisawelba" |
| 13:03:59 | <FliPPeh> | I just managed to write my own IRC Bot without using that tutorial. This marks the start of my active Haskelling phase |
| 13:04:14 | <FliPPeh> | :) |
| 13:04:25 | <FliPPeh> | Fetish of mine, I have to write one in every language I try |
| 13:05:02 | <EvilTerran> | > let cs = map toLower . filter isAlpha $ "Doc, note I dissent - a fast never prevents a fatness. I diet on cod!" in cs == reverse cs |
| 13:05:04 | <lambdabot> | True |
| 13:05:04 | <jthing> | well I'll warn orhers of your IRC's |
| 13:13:01 | <TFHosting> | http://tfhosting.servehttp.com/services.php <<--- Need a SeedBox? |
| 13:14:41 | <EvilTerran> | Lemmih, beaten to the punch? |
| 13:14:51 | <Lemmih> | Yeah :( |
| 13:14:57 | <EvilTerran> | (or the kick, in this case :P) |
| 13:15:17 | <Lemmih> | ACTION will go kick an orphan instead. |
| 13:15:58 | <edwardk> | ACTION waves hello. |
| 13:17:51 | <Saizan> | hi |
| 13:23:03 | <byorgey_> | > intercalate "," ["a", "b"] |
| 13:23:04 | <lambdabot> | "a,b" |
| 13:23:31 | <byorgey_> | hey edwardk |
| 13:24:54 | <edwardk> | I'm finally able to get back to writing Haskell and my brain is a blank slate ;) |
| 13:25:32 | <SamB_XP_> | edwardk: isn't that the ideal state ? |
| 13:25:50 | <SamB_XP_> | well, I mean, it's better than having it full of bad OO methodologies, right? |
| 13:25:54 | <edwardk> | alas the ideal and the useful rarely coincide ;) |
| 13:27:22 | <SamB_XP> | ACTION wonders what -e is |
| 13:28:10 | <byorgey> | E is for Execute! |
| 13:28:16 | <FliPPeh> | If I want to keep a state and update it sometimes, I will need a Monad, right? |
| 13:28:39 | <edwardk> | in general yes |
| 13:28:44 | <byorgey> | FliPPeh: you don't NEED a monad, you can just pass the state around as an extra parameter to all your functions |
| 13:28:52 | <byorgey> | but the State monad will automate that for you. |
| 13:28:52 | <FliPPeh> | Like I am doing now |
| 13:28:58 | <edwardk> | you can get away without it but the monad is the most convenient method |
| 13:29:00 | <FliPPeh> | autoJoinChannels :: Handle -> IO () |
| 13:29:08 | <FliPPeh> | Always passing a handle |
| 13:29:27 | <edwardk> | then you might consider working in StateT Handle IO |
| 13:29:39 | <edwardk> | or making a bigger environment if you commonly use other things |
| 13:29:53 | <FliPPeh> | I won't keep the handle alone in there |
| 13:30:08 | <FliPPeh> | I want to pass around current nickname and channel details |
| 13:30:10 | <edwardk> | the usual idiom is StateT MyState IO ... |
| 13:30:26 | <edwardk> | and in MyState you have fields for your nickname, channels, etc. |
| 13:30:34 | <byorgey> | data MyState = MyState { nick :: String, channel :: Foo, handle :: Handle } |
| 13:32:02 | <SamB_XP> | byorgey: it looks like it actually means "ban exception", possibly ... |
| 13:32:27 | <byorgey> | oh. |
| 13:32:33 | <edwardk> | One thing I love about this community is that I'm rarely the only person thinking about something (unless it involves too many uses of the co- prefix) http://www-ps.informatik.uni-kiel.de/~sebf/data/pub/icfp09.pdf provides a nice way to handle some sharing issues i've been having in an EDSL for bayes using gibbs sampling |
| 13:32:53 | <SamB_XP> | well, except -e would be "no ban exception" |
| 13:33:11 | <byorgey> | "ban exception excepted"? |
| 13:33:50 | <dhun> | I am trying to parse my own tokens with Parsec I try to use the "token" function, it takes a function of time (tok -> SourcePos) but I don't know how to implement it? |
| 13:33:56 | <byorgey> | edwardk: yeah, that lazy monadic sharing stuff is neat =) |
| 13:33:59 | <SamB_XP> | well, +e is supposed to be "ban exception" |
| 13:34:05 | <dhun> | type |
| 13:34:46 | <edwardk> | byorgey: i had basically worked out something nigh identical from reading another paper of kiselyov and shan the one on the statistical EDSL in ocaml using delimited continuations |
| 13:34:55 | <edwardk> | but they packaged it with a better type than I had |
| 13:35:16 | <ski> | @type Text.ParserCombinators.Parsec.Prim.token |
| 13:35:17 | <lambdabot> | forall tok a st. (tok -> String) -> (tok -> Text.ParserCombinators.Parsec.Pos.SourcePos) -> (tok -> Maybe a) -> Text.ParserCombinators.Parsec.Prim.GenParser tok st a |
| 13:35:49 | <edwardk> | i've been trying to avoid dipping down into monads, sticking to applicatives where possible lately because i can play tricky games with stable names to recover sharing info |
| 13:36:15 | <ski> | dhun : probably you should create a `MyToken' type which contains information about the source position of the token as well as what token it is |
| 13:36:40 | <edwardk> | note their share :: m a -> m (m a) operator (which is roughly a duplicate/cojoin) doesn't require m to be a monad per se. |
| 13:37:23 | <edwardk> | i should go through and take their share laws and see how they map onto Alternative |
| 13:37:34 | <Botje> | phew |
| 13:37:39 | <Botje> | just finished my written haskell exam |
| 13:40:34 | <ray> | written haskell?! |
| 13:40:40 | <ray> | like on paper!? |
| 13:41:01 | <dhun> | ski I do pos<-getPosition; |
| 13:41:01 | <dhun> | token show |
| 13:41:01 | <dhun> | (\x -> pos) |
| 13:42:58 | <Botje> | ray: yeah |
| 13:43:17 | <edwardk> | i never got to take an exam on haskell =/ |
| 13:43:19 | <boegel> | ray: I think we had something like that too, many years ago |
| 13:43:32 | <boegel> | ray: hell, I even had a Java exam on paper (partly) |
| 13:43:47 | <boegel> | Botje: how was it? |
| 13:44:15 | <fasta> | Let met guess: parsers + folds + a simple inductive proof? |
| 13:44:42 | <Botje> | good |
| 13:44:59 | <Botje> | had to rewrite my erlang solution because i missed the final condition in the question |
| 13:45:33 | <aCiD2> | Hey all, I'm trying out cabal for the first time, but when I run `cabal update` I get the error: "cabal: user error (Codec.Compression.Zlib: premature end of compressed stream)" |
| 13:45:53 | <aCiD2> | I'm behind a proxy, so it might be that (though it's correctly set in http_proxy), so I'm not sure what else could be the problem |
| 13:46:44 | <Axman6> | dcoutts: you around? |
| 13:46:46 | <fasta> | aCiD2: it depends a lot on the actual proxy. |
| 13:47:06 | <dcoutts> | @arr! |
| 13:47:06 | <lambdabot> | Ahoy mateys |
| 13:47:13 | <dcoutts> | Axman6: arr? |
| 13:47:29 | <Axman6> | thought you might be able to help aCiD2 |
| 13:47:42 | <Beelsebob> | how does one ask cabal to build multiple/a specific target from your cabal file? |
| 13:47:47 | <dcoutts> | aCiD2: that'll almost certainly be due to a truncated or otherwise borked download |
| 13:47:53 | <dino-> | @type Control.Arrow.arr |
| 13:47:54 | <lambdabot> | forall b c (a :: * -> * -> *). (Arrow a) => (b -> c) -> a b c |
| 13:48:01 | <Beelsebob> | i.e. I have both a library and an executable specified in the same cabal file |
| 13:48:05 | <Beelsebob> | atm, it only builds the library |
| 13:48:14 | <Beelsebob> | how do I get it to build the executable too |
| 13:48:31 | <dcoutts> | Beelsebob: it builds everything by default unless you set any of them to be not buildable |
| 13:48:40 | <aCiD2> | dcoutts: ok, but how do I fix that :) |
| 13:48:42 | <aCiD2> | fasta: how so? |
| 13:48:48 | <dcoutts> | aCiD2: take a look at the ~/.cabal/packages/$server/00-index.tar.gz |
| 13:48:52 | <aCiD2> | ok |
| 13:48:56 | <Beelsebob> | oh hmm, it built the other after a clean |
| 13:48:56 | <dcoutts> | aCiD2: does it look like a short download? |
| 13:48:57 | <Beelsebob> | how odd |
| 13:48:59 | <dino-> | Beelsebob: It's not building both? |
| 13:49:02 | <dino-> | ah, nm |
| 13:49:06 | <deeflex> | how do I read from stdin? |
| 13:49:22 | <Axman6> | hGetcontents |
| 13:49:28 | <aCiD2> | Yea, unexpected EOF |
| 13:49:28 | <Axman6> | Contents* |
| 13:49:29 | <fasta> | aCiD2: proxies generally suck |
| 13:49:54 | <aCiD2> | dcoutts: it is indeed too short, removing it and trying again results in the same problem |
| 13:50:00 | <dino-> | Or just getContents |
| 13:50:02 | <aCiD2> | maybe I should use a ssh tunnel and update through that? |
| 13:50:11 | <pastorn> | deeflex: if you just want to do a program that reads from stdin and prints stuff to stdout, check out 'interact' |
| 13:50:34 | <dcoutts> | aCiD2: ok, when you run update with -v3 and see the http conversation, does it report anything odd? What version of the HTTP lib did you build the cabal program against? |
| 13:50:58 | <aCiD2> | lol, it works fine if I use -v3 |
| 13:50:59 | <aCiD2> | weird |
| 13:51:05 | <deeflex> | pastorn, no I don't want to print to stdout. |
| 13:51:30 | <Axman6> | dcoutts: hGetContents |
| 13:51:35 | <Axman6> | uh, deeflex |
| 13:51:36 | <Axman6> | even |
| 13:51:38 | <dcoutts> | aCiD2: that is indeed weird, it doesn't do anything different, just dump the headers sent in each direction |
| 13:51:40 | <fasta> | aCiD2: I am also behind a proxy and other than my http_proxy variable I don't have to do anything specific. Did you try again? |
| 13:52:03 | <aCiD2> | yea, it now seems trying for the 5th time is breaking again (as is cabal install hledger) |
| 13:52:07 | <Axman6> | deeflex: there's getLine |
| 13:52:13 | <dino-> | Axman6: Is there a benefit, if you specifically want stdin, to NOT using getContents? |
| 13:52:17 | <fasta> | aCiD2: time to contact your network administrator. |
| 13:52:37 | <dcoutts> | aCiD2: can you get the 00-index.tar.gz file using wget? |
| 13:52:40 | <Axman6> | dino-: only if you forgot getContents existed, like i did ;) |
| 13:52:44 | <aCiD2> | I highly doubt this is a problem with the proxy (as I have never seen any problems in over 2 years) and this runs over the whole of the university... |
| 13:52:49 | <dcoutts> | aCiD2: I mean can wget work with your proxy but cabal cannot? |
| 13:52:57 | <deeflex> | Axman6, mhm interesting. I'll look into it |
| 13:53:06 | <Axman6> | :t getContents |
| 13:53:07 | <lambdabot> | IO String |
| 13:53:07 | <quicksilver> | dino-: getContents has broken interleaved IO semantics which mask errors and can't recover from them. Not using it avoids that problem. |
| 13:53:26 | <Axman6> | quicksilver: alternative is...? |
| 13:53:32 | <aCiD2> | dcoutts: yep |
| 13:53:34 | <dcoutts> | aCiD2: in which case we should look at the -v3 debug log and compare it to the wget one. What version of the HTTP lib are you using? |
| 13:53:35 | <aCiD2> | wget is fine |
| 13:53:43 | <aCiD2> | How can I check that? |
| 13:53:46 | <quicksilver> | Axman6: not using it. |
| 13:53:51 | <dcoutts> | aCiD2: ghc-pkg list HTTP |
| 13:53:51 | <quicksilver> | Axman6: getLine, for example. |
| 13:53:56 | <quicksilver> | Axman6: or hGetBuf. |
| 13:54:00 | <Axman6> | quicksilver: that's what i wanted to know |
| 13:54:14 | <aCiD2> | that just shows ghc 6.10.3 |
| 13:54:15 | <quicksilver> | or strict bytestring's version of getcontents |
| 13:54:23 | <quicksilver> | which is fine if you're happy to read it all at once |
| 13:54:26 | <dcoutts> | aCiD2: where did you get the cabal program from? |
| 13:54:40 | <dino-> | Ya, I was thinking of that too, that if your task gets serious enough, you end up knocking on ByteString's door. |
| 13:54:42 | <aCiD2> | I run Arch Linux, so I installed cabal from the community repository |
| 13:55:01 | <dcoutts> | aCiD2: ok, and what version of HTTP do they use? |
| 13:55:42 | <dcoutts> | aCiD2: it might be worth building your own version with a known HTTP lib version and reproducing the problem with that, so we know the real version. |
| 13:55:59 | <aCiD2> | they depend on ">=4000" from the package source |
| 13:56:33 | <dcoutts> | aCiD2: I'm afraid we need to know the exact version, perhaps try building it from source |
| 13:57:02 | <dcoutts> | aCiD2: there are several 4000.x versions and there were some important fixes for proxies |
| 13:57:24 | <aCiD2> | I just installed 4000.0.6 |
| 13:57:36 | <aCiD2> | should I update to 4000.0.7? |
| 13:58:00 | <dcoutts> | aCiD2: doesn't matter, so long as you've rebuilt the cabal-install package from source using one version or the other |
| 13:58:14 | <dcoutts> | so that we know the exact version we're testing |
| 13:58:17 | <aCiD2> | ok, I'll upgrade HTTP and build cabal-install from source now |
| 13:58:22 | <dcoutts> | great |
| 14:04:15 | <aCiD2> | dcoutts: Well, I'm pretty sure everything is up-to-date, but the same error happens |
| 14:04:40 | <dino-> | You know, I still have cabal-install 0.6.0 manually installed. I wonder if I should have it cabal-install itselup up to 0.6.2 |
| 14:04:41 | <aCiD2> | It's odd, because if I keep re-running `cabal update` one of them does happen (and I can't see the problem from -v3) |
| 14:04:53 | <dino-> | ..itself up.. |
| 14:05:15 | <dcoutts> | aCiD2: and the symptom, when it fails, is that the download is 0-size right? |
| 14:05:44 | <dcoutts> | ac: could you file a ticket with the cabal update -v3 log of a failing case. |
| 14:05:49 | <dcoutts> | oops |
| 14:05:51 | <aCiD2> | No, not size, but incomplete |
| 14:05:51 | <dcoutts> | aCiD2: ^^ |
| 14:05:52 | <aCiD2> | Sure |
| 14:06:04 | <dcoutts> | http://hackage.haskell.org/trac/hackage/ |
| 14:06:07 | <Saizan> | dcoutts: yes, you can simply run "cabal install Cabal cabal-install" so that it upgrades Cabal too |
| 14:06:24 | <Saizan> | ops |
| 14:06:27 | <Saizan> | dino-: ^^^ |
| 14:06:30 | <dcoutts> | ;-) |
| 14:06:57 | <dcoutts> | aCiD2: mention the HTTP version, and what would make it really useful is a log of wget getting the same file for comparison. |
| 14:07:19 | <dcoutts> | aCiD2: do you know how to run wget so that we can see all the headers sent and received? |
| 14:07:27 | <dino-> | @type (^^^) |
| 14:07:27 | <lambdabot> | Not in scope: `^^^' |
| 14:07:28 | <aCiD2> | No, but I'm sure it's in the man page :) |
| 14:07:36 | <dcoutts> | aye :-) |
| 14:07:48 | <ray> | :t (&&&) |
| 14:07:50 | <lambdabot> | forall (a :: * -> * -> *) b c c'. (Arrow a) => a b c -> a b c' -> a b (c, c') |
| 14:07:51 | <ray> | close enough |
| 14:08:14 | <edwardk> | i am amused that the fischer, kiselyov and shan paper basically used the Codensity (Reader t) encoding encoding of State t. =) |
| 14:08:32 | <ray> | > (fst &&& snd) (1,2) |
| 14:08:33 | <edwardk> | er s/encoding encoding/encoding/ |
| 14:08:35 | <lambdabot> | (1,2) |
| 14:14:26 | <aCiD2> | dcoutts: is --verbose -S for wget what you need (verbose + http headers)? |
| 14:15:10 | <dcoutts> | aCiD2: we want to see what HTTP headers wgets sends, and what the proxy/server sends back. |
| 14:15:22 | <aCiD2> | Yea, -S seems to give that |
| 14:15:25 | <dcoutts> | what HTTP headers the proxy/server sends back. |
| 14:15:33 | <dcoutts> | we don't care so much about the data |
| 14:17:38 | <aCiD2> | dcoutts: is http://hackage.haskell.org/trac/hackage/ticket/562 ok? |
| 14:19:25 | <dcoutts> | aCiD2: just to confirm, the first is it failing? the second working? |
| 14:19:30 | <aCiD2> | yep |
| 14:20:27 | <aCiD2> | The only difference I can see is that the working one has "Proxy-Connection: Close" and the failing one has "Connection: close" |
| 14:20:38 | <aCiD2> | wget always uses the former, and never fails (at least over 10 runs) |
| 14:20:55 | <defun> | HI. I am trying to install some cabal pkgs (i.e. plugins, haskell-src) and they fail because cabal can't install happy. I tried installing happy directly with cabal install happy; and I get this http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5683#a5683 any ideas? |
| 14:20:58 | <dcoutts> | aCiD2: and the first returns X-Cache: MISS |
| 14:21:26 | <aCiD2> | Yea, I don't understand why it seems to query the cache twice though |
| 14:21:39 | <aCiD2> | It hits first, then misses |
| 14:22:10 | <dcoutts> | aCiD2: perhaps one proxy is talking to another |
| 14:22:20 | <dcoutts> | defun: looks like some packages are borked |
| 14:22:41 | <defun> | dcoutts: borked? what's that mean? |
| 14:22:42 | <aCiD2> | I'll try changing my proxy to exactly wwwcache3 - wwwcache is a sort of round-robin server, I believe |
| 14:23:12 | <aCiD2> | and loe and behold, it now always works |
| 14:24:03 | <defun> | dcoutts: is there a way to fix a borked package? How do I know which ones are borked? |
| 14:24:18 | <codebliss> | What else do you need to do other than "cabal install foo"? |
| 14:24:28 | <codebliss> | I should have mtl, but there's still a compiler error |
| 14:24:42 | <codebliss> | Simply compiling http://haskell.org/haskellwiki/Roll_your_own_IRC_bot |
| 14:25:05 | <byorgey> | codebliss: what's the error? |
| 14:25:48 | <FliPPeh> | Can anyone help me enhance my code to use a state monad? I've tried it a all, but I just can't get it done :( |
| 14:26:17 | <dcoutts> | defun: do you by any chance have more than one version of the unix package installed? eg globally and per-user? |
| 14:26:19 | <byorgey> | FliPPeh: I can probably give you some hints if you paste the code somewhere |
| 14:26:26 | <codebliss> | GHCI: unknown package: mtl-1.1.0.0 |
| 14:26:26 | <codebliss> | GHC: ghc-6.8.2: unknown package: mtl-1.1.0.0 (dependency of parsec-3.0.0) |
| 14:26:34 | <FliPPeh> | I'm commenting it right now, hold on a second! |
| 14:27:13 | <dcoutts> | aCiD2: could you update the ticket with that, and can you confirm that you were using HTTP-4000.7 (and you're sure you were then testing using the rebuilt one, not the system one) |
| 14:27:34 | <dcoutts> | aCiD2: I've added a note about the differences |
| 14:27:42 | <defun> | dcoutts: no idea. Not sure how to check. Should i use ghc-pkg? Trying it now... |
| 14:27:44 | <aCiD2> | Ok |
| 14:27:52 | <byorgey> | codebliss: can you paste the output of 'ghc-pkg list'? I suspect the problem may be with local vs global package installation |
| 14:28:15 | <dcoutts> | codebliss: also, ghc-pkg check will report that mtl is missing but that other packages still depend on it |
| 14:28:30 | <dcoutts> | codebliss: this happens when packages get unregistered but other things still need them |
| 14:28:48 | <aCiD2> | In a slightly more unrelated question: where do packages get installed to? I had some installed in /usr/local/lib, but I've since removed them |
| 14:28:48 | <FliPPeh> | byorgey: http://moonpatio.com/fastcgi/hpaste.fcgi/view?id=2624#a2624 |
| 14:28:59 | <codebliss> | http://pastebin.com/m290a631a |
| 14:29:37 | <Baughn> | aCiD2: With cabal-install? ~/.cabal, usually. |
| 14:29:45 | <aCiD2> | ah, ok |
| 14:29:45 | <Baughn> | aCiD2: THough the registry is in ~/.ghc |
| 14:29:45 | <aCiD2> | thanks |
| 14:29:48 | <byorgey> | FliPPeh: so, what fields do you want to be part of your state? |
| 14:30:17 | <Baughn> | aCiD2: You can tell it to install globally using --global, in which case you should also set a root-cmd in .cabal/config |
| 14:30:26 | <FliPPeh> | Nickname, Fullname, the Handle of course, Channellist, Server IP and Port |
| 14:30:27 | <dcoutts> | codebliss: so you've installed mtl-1.1.0.2 but unregistered mtl-1.1.0.0 |
| 14:30:30 | <Baughn> | ACTION thinks that ought to default to sudo |
| 14:30:36 | <dcoutts> | codebliss: but other packages still need that mtl-1.1.0.0 |
| 14:30:48 | <dcoutts> | codebliss: run "ghc-pkg check" it'll tell you which |
| 14:30:51 | <codebliss> | How would I register said package? =D |
| 14:30:54 | <codebliss> | kk |
| 14:30:54 | <FliPPeh> | that's how far I got myself, I also created the StateT Monads, but it kept failing on my exception codes |
| 14:30:58 | <defun> | dcoutts: I have 2 pkgs. one in /usr/local/lib/ghc-6.10.1/./package.conf and one unix in /export/home/zivkovic/.ghc/i386-solaris2-6.10.1/package.conf both contain unix-2.3.1.0 here is a copy of the output: http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5684#a5684 |
| 14:30:58 | <FliPPeh> | So I gave up |
| 14:31:09 | <Baughn> | codebliss: Best option, if possible, is to reinstall the mtl-dependent packages |
| 14:31:24 | <codebliss> | http://pastebin.com/m44bee47f |
| 14:31:31 | <codebliss> | --reinstall? |
| 14:31:32 | <dcoutts> | defun: so the user one is shadowing the global one and that's causing the linker errors |
| 14:31:37 | <Baughn> | Yes |
| 14:31:38 | <dcoutts> | defun: remove the per-user one |
| 14:31:52 | <dcoutts> | defun: because they're not exporting the same ABI |
| 14:31:59 | <byorgey> | FliPPeh: a couple points: (1) if you switch to using types like StateT MyState IO a, you will need to wrap any IO actions in a call to 'liftIO' |
| 14:32:06 | <defun> | dcoutts: how? edit the file? |
| 14:32:19 | <Baughn> | codebliss: Well, the downside of reinstalling mtl-1.1.0.0 would be that you may get type errors in programs that use both, for example, network and parsec |
| 14:32:34 | <Baughn> | codebliss: But only in interfaces that use mtl types |
| 14:32:34 | <FliPPeh> | liftOP putStrLn "Like that?" |
| 14:32:50 | <codebliss> | I doubt I personally will use mtl in my code for a while now |
| 14:32:54 | <byorgey> | FliPPeh: more like liftIO $ putStrLn "Like this" |
| 14:33:03 | <FliPPeh> | Okay |
| 14:33:04 | <Baughn> | codebliss: Considering that you've got gtk2hs in there I'd say reinstall mtl and deal with it if it happens. :) |
| 14:33:05 | <dcoutts> | defun: no, use ghc-pkg unregister --user thepkgname-x.y |
| 14:33:18 | <defun> | thanks! |
| 14:33:22 | <codebliss> | Alright, thanks mate. |
| 14:33:27 | <Baughn> | It defaults to --user, doesn't it? |
| 14:33:34 | <byorgey> | FliPPeh: 'gets fieldname' is useful for extracting one particular component of a state record |
| 14:34:00 | <byorgey> | FliPPeh: updating one component of the state is a bit annoying, but I suggest making separate functions to do this, like: |
| 14:34:17 | <FliPPeh> | updateNick |
| 14:34:22 | <Baughn> | @type runState |
| 14:34:23 | <lambdabot> | forall s a. State s a -> s -> (a, s) |
| 14:34:36 | <codebliss> | Baughn: ghc-pkg check now yields nothing, thank you =D |
| 14:34:56 | <byorgey> | setNick :: StateT MyState IO () ; setNick n = do s <- get; put (s { nick = n }) |
| 14:35:05 | <Baughn> | > runState (put =<< (+1) <$> get) 2 |
| 14:35:07 | <lambdabot> | ((),3) |
| 14:35:27 | <Baughn> | > runState (replicateM 3 (put =<< (+1) <$> get)) 2 |
| 14:35:29 | <lambdabot> | ([(),(),()],5) |
| 14:35:45 | <byorgey> | FliPPeh: I'm not sure exactly what you mean when you say that it was "failing on your exception codes" |
| 14:36:12 | <FliPPeh> | Had to do with IO vs new Monad |
| 14:38:04 | <defun> | I masked the pkg and now I get a new error... :( http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5685#a5685 |
| 14:38:57 | <FliPPeh> | hmmm |
| 14:39:46 | <Saizan> | defun: some problem but with another package |
| 14:40:06 | <defun> | Saizan: you mean 'same problem'? |
| 14:40:19 | <FliPPeh> | How can I manually create an empty, invalid IO State? |
| 14:40:21 | <Saizan> | defun: yes, sorry |
| 14:40:45 | <Saizan> | FliPPeh: what's your main problem? |
| 14:41:03 | <Saizan> | FliPPeh: that you can't pass something using StateT s IO to catch? |
| 14:41:06 | <defun> | Saizan: perhaps I should unregister the global unix pkg and use the usr unix pkg? |
| 14:41:08 | <FliPPeh> | I'll have to add the Handle to my Botstate |
| 14:41:16 | <FliPPeh> | And in order to create the StateT |
| 14:41:19 | <FliPPeh> | .. |
| 14:41:23 | <Saizan> | defun: no, the opposite |
| 14:41:31 | <FliPPeh> | main = runStateT sample (BotState ...) |
| 14:41:38 | <FliPPeh> | I have to initialize it first |
| 14:41:47 | <FliPPeh> | But I cannot initialize a handle |
| 14:41:49 | <defun> | I just did the opposite. i.e. unregistered unix user pkg... |
| 14:42:23 | <Saizan> | FliPPeh: i'd open the connection before running the action, or you can use "error "handle not set yet"" for the Handle field |
| 14:42:31 | <defun> | Saizan: Is it possible that both unix pkgs are messed up? |
| 14:42:45 | <FliPPeh> | I'll try connecting before state |
| 14:43:00 | <Saizan> | defun: it might be, can you paste the output of ghc-pkg list? |
| 14:43:11 | <defun> | sure. |
| 14:43:42 | <Saizan> | it's more likely you've two versions of process |
| 14:43:49 | <defun> | Saizan: http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5686#a5686 |
| 14:44:08 | <defun> | you'll see that unix usr has been unregistered before the error. |
| 14:44:45 | <Saizan> | defun: i'd unregister process-1.0.1.1 too |
| 14:45:11 | <defun> | Saizan: ok. 1 sec. |
| 14:45:13 | <kig> | is there a ready-made function for stripping duplicates from a list? |
| 14:45:19 | <SamB> | kig: nub |
| 14:45:30 | <Saizan> | defun: it probably dependend on the old unix |
| 14:45:36 | <SamB> | it apparantly means "essance" |
| 14:45:39 | <Saizan> | defun: s/old/user/ |
| 14:45:43 | <SamB> | er. "essence" |
| 14:46:02 | <kig> | SamB: perfect, thanks |
| 14:46:41 | <defun> | Saizan: it's saying that unregistering process would break the haskell98 pkg... should i use --force to override? |
| 14:46:51 | <codebliss> | kig: Check out (http://www.haskell.org/ghc/docs/latest/html/libraries/base/Data-List.html), you use those funcs a lot |
| 14:48:32 | <defun> | ok, i'll use --force. |
| 14:49:18 | <Saizan> | defun: unregister the user haskell98 too :) |
| 14:50:13 | <Saizan> | defun: did you use "cabal upgrade" perhaps? it's been a while since i've seen this kind of packages breakage |
| 14:50:53 | <defun> | Saizan: now Happy installed! Yay! Thanks! No, I used cabal install. What does cabal upgrade do? upgrade a pkg or upgrade cabal itself? |
| 14:51:27 | <ray> | it tells you what packages to upgrade |
| 14:51:39 | <Saizan> | defun: upgrades a package and its dependencies |
| 14:51:55 | <Saizan> | defun: i do not recommend using it |
| 14:52:03 | <defun> | i see. thanks. |
| 14:53:33 | <FliPPeh> | Maaan |
| 14:53:33 | <defun> | Saizan: what do i do if I need to re-register those pkgs in the future? |
| 14:53:41 | <FliPPeh> | Main.hs:40:27: |
| 14:53:41 | <FliPPeh> | Couldn't match expected type `()' |
| 14:53:41 | <FliPPeh> | against inferred type `((), BotState)' |
| 14:53:49 | <FliPPeh> | runStateT run (BotState server port nick name channels h) |
| 14:53:49 | <FliPPeh> | run :: Bot () |
| 14:53:50 | <FliPPeh> | What? |
| 14:54:48 | <byorgey> | @type runStateT |
| 14:54:49 | <lambdabot> | forall s (m :: * -> *) a. StateT s m a -> s -> m (a, s) |
| 14:55:00 | <byorgey> | @type execStateT |
| 14:55:01 | <lambdabot> | forall s (m :: * -> *) a. (Monad m) => StateT s m a -> s -> m s |
| 14:55:09 | <byorgey> | @type evalStateT |
| 14:55:10 | <lambdabot> | forall s (m :: * -> *) a. (Monad m) => StateT s m a -> s -> m a |
| 14:55:16 | <byorgey> | perhaps you want one of those instead? |
| 14:55:25 | <byorgey> | runStateT gives you back a pair of the result and the final state |
| 14:56:16 | <PeakerWork> | why are run/exec not in MonadState for consistency, btw? |
| 14:56:26 | <PeakerWork> | oh, I see why |
| 14:57:49 | <quicksilver> | you can only run when StateT is outermost. |
| 14:58:06 | <PeakerWork> | and you don't want the result in a monad if its just State |
| 14:59:28 | <defun> | I am trying to install haskell-src, but cabal can't find happy. I *just* installed it. Here is the output: http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5688#a5688 |
| 14:59:38 | <PeakerWork> | I understand how ContT (StateT s ...) behaves. How does StateT s (ContT ...) behave differently? |
| 14:59:39 | <Saizan> | defun: you shouldn't install the same version of a package in both the global and user database (this should be fixed for ghc-6.12), but otherwise you can just cabal install them |
| 14:59:52 | <Saizan> | defun: do you have happy on your $PATH ? |
| 15:00:28 | <defun> | I don't even know where happy is... I just assume it's in the .cabal directory. Anyway I could find out? |
| 15:00:40 | <Saizan> | ~/.cabal/bin by default |
| 15:00:51 | <defun> | I see. |
| 15:00:53 | <defun> | 1 sec. |
| 15:00:58 | <mapreduce> | "the happy path" |
| 15:01:20 | <edwardk> | PeakerWork: think of the StateT s (ContT ...) -- as its expansion to: s -> ((a, s) -> m r) -> m r -- then it should be more obvious |
| 15:01:33 | <quicksilver> | PeakerWork: the different is whether, when you do "weird control flow", do you take your state with you? |
| 15:01:47 | <quicksilver> | PeakerWork: or do you "reset" the state to that which applies to the new control flow location. |
| 15:02:10 | <PeakerWork> | edwardk, quicksilver: Thanks! |
| 15:02:15 | <PeakerWork> | quicksilver: but what exactly do you reset to? |
| 15:02:27 | <edwardk> | unfortunately both of those are valid interpretations of what to do with the state, so you wind up having conflicting semantics for dealing with cps'd state |
| 15:04:09 | <edwardk> | quicksilver: erm, isn't it instance MonadState s m => MonadState s (ContT m) that has the issue? |
| 15:04:27 | <quicksilver> | is this an "issue" |
| 15:04:30 | <edwardk> | StateT m doesn't care what m is or how it affects control flow, merely that it is a monad. |
| 15:04:35 | <quicksilver> | isn't it just what they things mean? |
| 15:04:48 | <quicksilver> | compare ErrorT StateT and StateT ErrorT |
| 15:04:55 | <quicksilver> | in one case you still have a final state, in case of error |
| 15:05:04 | <defun> | Saizan: added ~/.cabal/bin to my path. Still says happy not found... |
| 15:05:05 | <quicksilver> | in the other case, you don't have a final state, you only have an error. |
| 15:05:14 | <quicksilver> | ErrorT is a very simple case of ConT |
| 15:05:21 | <defun> | Saizan: so should they be installed in usr or global? |
| 15:05:22 | <quicksilver> | (where the only thing you can do is jump to the end) |
| 15:05:23 | <edwardk> | quicksilver: well what i mean by issue is that you have the ensuing religious war as to whether you get 'commit' or 'rollback' =) |
| 15:05:47 | <dcoutts> | defun: if it's in your path, ie you can run $ happy, then cabal will find it |
| 15:06:39 | <defun> | 1 sec. it looks like it's not in my path after all... I hate bash... |
| 15:07:35 | <hatds> | what's the proper way to open, say, a 40 MB .txt file and read the contents to a haskell value? |
| 15:07:37 | <edwardk> | personally i've always thought it made the most sense to just define ContT (State s ...) with the opposite behavior of StateT s Cont ..., but mmorrow convinced me that its useful to offer both |
| 15:07:49 | <koeien> | hatds: what "value"? a String or ByteString? |
| 15:07:53 | <quicksilver> | hatds: if you have 40M of memory spare, then a strict bytestring is quite a good way. |
| 15:08:07 | <hatds> | value in the sense of Read a |
| 15:08:12 | <koeien> | hatds: or a very long integer for example |
| 15:08:25 | <defun> | dcoutts: ok it is now. and haskell-src is installing... thnx. |
| 15:08:32 | <quicksilver> | Ouch. You really don't want to call "read" on a 40M string |
| 15:08:37 | <quicksilver> | read is not built for performance ;) |
| 15:08:42 | <koeien> | read is slow |
| 15:08:43 | <hatds> | yea, so what should I do |
| 15:08:43 | <defun> | YES! It worked! |
| 15:09:13 | <skorpan> | is hs-plugins deprecated or something? |
| 15:09:31 | <koeien> | hatds: do you know the type you want to read ? |
| 15:09:34 | <skorpan> | the homepage hasn't been updated in more than three years |
| 15:09:53 | <defun> | thanks! now everything works as expected. :-D |
| 15:09:58 | <hatds> | koeien: yes |
| 15:10:24 | <Twinside> | hi, I would like to add an instance to MArray STUArray (or IOUArray, I don't car which one) for one of my simple type, is there a documented way somewhere? |
| 15:10:35 | <koeien> | hatds: you can try to `read' it, but i doubt it'll be fast |
| 15:10:48 | <Saizan> | skorpan: it's still used by, e.g. turbinado |
| 15:10:55 | <hatds> | even just reading the file to a String is ridiculous, ghc is paging like crazy |
| 15:10:59 | <hatds> | I don't know why |
| 15:11:32 | <fasta> | Haskell is not C, that's why. |
| 15:12:01 | <fasta> | Or the compiler is not smart enough to make something run as if it were written in C. |
| 15:12:02 | <hatds> | yea, but a String is how many times bigger than a .txt? |
| 15:12:22 | <Saizan> | 10x? |
| 15:12:52 | <Saizan> | maybe more |
| 15:12:55 | <fasta> | 16 bytes/char, or something like that? I never had to care about those details, but maybe in some time. |
| 15:13:13 | <hatds> | task manager says ghc is holding onto 1.6 GB |
| 15:13:30 | <fasta> | hatds: that's just the maximum memory usage. |
| 15:13:36 | <vegai> | I suppose it could be just 16bits+list overhead |
| 15:13:42 | <vegai> | 16bits/char |
| 15:13:43 | <Lemmih> | String is 20bytes per character on 32bit machines. Then comes the 3x GC overhead. |
| 15:13:53 | <vegai> | whoa, vhy? |
| 15:14:02 | <vegai> | pardon my surprising german accent |
| 15:14:19 | <fasta> | hatds: GHC doesn't return memory to the OS. |
| 15:14:25 | <hatds> | why isn't it like 4 bytes for the Char, and a few more bytes for the Box and Cons? |
| 15:14:34 | <quicksilver> | it is. |
| 15:14:40 | <fasta> | hatds: the argument is that especially on 64 bit systems, the virtual memory system handles it. |
| 15:14:47 | <Lemmih> | hatds: It is. |
| 15:14:52 | <quicksilver> | 4 bytes for the char, 4 bytes for the indirection, 4 bytes for the cons cell, 4 bytes for the cons cell indirection |
| 15:15:03 | <quicksilver> | and 4 bytes for the tail pointer |
| 15:15:08 | <vegai> | ah |
| 15:15:11 | <quicksilver> | == 20 bytes per char, if I got that right. |
| 15:15:21 | <fasta> | hatds: the real reason is that nobody cares enough for that particular issue. |
| 15:15:32 | <quicksilver> | hatds: that's why we have bytestring |
| 15:15:38 | <vegai> | why 4 bytes for the char? |
| 15:15:42 | <hatds> | teach me how to love bytestring then |
| 15:15:44 | <quicksilver> | hatds: which is why all the initial answers to your question mentioned bytestring |
| 15:15:52 | <quicksilver> | vegai: uniform representation. |
| 15:15:56 | <quicksilver> | vegai: everything is 4 bytes |
| 15:16:01 | <quicksilver> | that's how polymorphism works. |
| 15:16:08 | <hatds> | can bytestring be used to serialize and unserialize haskell values? |
| 15:16:10 | <Axman6> | hatds: uses arrays of unboced chars i think |
| 15:16:12 | <quicksilver> | yes. |
| 15:16:13 | <Saizan> | well, also because Char is an unicode codepoint |
| 15:16:14 | <koeien> | yes. |
| 15:16:24 | <vegai> | quicksilver: ok |
| 15:16:26 | <quicksilver> | Saizan: sure, but Word8 is 4 bytes as well. |
| 15:16:33 | <Lemmih> | fasta: It's not that we don't care. It's not technically possible for it to be smaller with the same representation. |
| 15:16:33 | <quicksilver> | Saizan: ...and Char is 8 bytes on a 64 bit machine. |
| 15:16:43 | <Axman6> | unboxed* |
| 15:17:14 | <Axman6> | hatds: i've never used them, but bytestrings are supposed to be very fast, and very efficient |
| 15:17:20 | <koeien> | they are |
| 15:17:28 | <koeien> | you can get close to C performance |
| 15:17:32 | <jmcarthur_work> | very fast |
| 15:17:34 | <fasta> | Lemmih: I am sorry, I don't understand why that is the case. We are talking about returning memory to the OS, right? |
| 15:17:45 | <jmcarthur_work> | a bit of a pain to mess with namespacing though |
| 15:17:52 | <dino-> | Just to throw this out, the data parts of happstack do some of this too, deserialize data on disk back into your type(s) in mem. But structuring around that storage may not fit your needs. |
| 15:17:54 | <Saizan> | hatds: see the binary package for serialization with bytestring |
| 15:18:11 | <jmcarthur_work> | i wish the default String type was ByteString and that we also just had ListString or something instead |
| 15:18:18 | <vegai> | is there a technical reason why String and Bytestring don't both implement a typeclass? |
| 15:18:23 | <koeien> | or polymorphic string literals ;) |
| 15:18:25 | <Lemmih> | fasta: Oh sorry, I through you were referring to the String issue. My bad. |
| 15:18:25 | <vegai> | jmcarthur_work: exactly :) |
| 15:18:41 | <jmcarthur_work> | :t fromString |
| 15:18:42 | <lambdabot> | Not in scope: `fromString' |
| 15:18:46 | <jmcarthur_work> | eh, i don't remember it |
| 15:18:52 | <vegai> | factor's sequence protocol is so nice... |
| 15:19:11 | <jmcarthur_work> | with the overloaded strings extension you can make string literals convert to a type other than String |
| 15:19:29 | <jmcarthur_work> | like Num |
| 15:20:16 | <jmcarthur_work> | class IsString a where fromString :: String -> a |
| 15:20:20 | <jmcarthur_work> | that's the class |
| 15:20:43 | <doserj> | vegai: for one thing, in Haskell'98 String, can't implement any typeclass... |
| 15:20:55 | <jmcarthur_work> | http://www.haskell.org/ghc/docs/latest/html/users_guide/type-class-extensions.html#overloaded-strings |
| 15:21:44 | <quicksilver> | jmcarthur_work: I don't. |
| 15:21:51 | <quicksilver> | if ByteString was the default string type then |
| 15:22:07 | <quicksilver> | foldr, unfoldr, map, filter, foldl', concat .... woudln't work on it |
| 15:22:16 | <quicksilver> | that's not the language I want to use. |
| 15:22:22 | <jmcarthur_work> | toList? |
| 15:22:30 | <jmcarthur_work> | unpack, whatever |
| 15:22:36 | <quicksilver> | right. So I have to add "toList" to every single operation |
| 15:22:42 | <quicksilver> | and I end up back at [Char] |
| 15:22:47 | <quicksilver> | I'd rather start with [Char], please ;0 |
| 15:22:48 | <jmcarthur_work> | not every single operation, just the ones that are list-like |
| 15:22:54 | <quicksilver> | and use ByteString when I choose to. |
| 15:22:56 | <quicksilver> | which is seldom. |
| 15:23:32 | <jmcarthur_work> | :t concat |
| 15:23:33 | <lambdabot> | forall a. [[a]] -> [a] |
| 15:24:08 | <jmcarthur_work> | would work fine on [ByteString] if it was the properly overloaded version of concat |
| 15:24:21 | <jmcarthur_work> | i still get your point |
| 15:24:32 | <quicksilver> | ByteString isn't a monad, either ;) |
| 15:24:50 | <jmcarthur_work> | i tend to use strings as lists rather infrequently |
| 15:24:51 | <quicksilver> | I don't think overloading is a good solution for this. |
| 15:25:33 | <doserj> | what would that overloaded type for concat be? |
| 15:25:34 | <jmcarthur_work> | and anyway, having String be ByteString by default doesn't mean we can't have prelude functions that don't work on [Char] or return IO [Char] or whatever |
| 15:25:47 | <jmcarthur_work> | it just means String is a different type |
| 15:26:05 | <quicksilver> | that is, of course, true. |
| 15:26:05 | <jmcarthur_work> | :t Data.Foldable.concat |
| 15:26:07 | <lambdabot> | forall (t :: * -> *) a. (Data.Foldable.Foldable t) => t [a] -> [a] |
| 15:26:10 | <jmcarthur_work> | err |
| 15:26:20 | <jmcarthur_work> | :t Data.Foldable.fold |
| 15:26:21 | <lambdabot> | forall (t :: * -> *) m. (Data.Foldable.Foldable t, Monoid m) => t m -> m |
| 15:26:23 | <quicksilver> | that generalises in the wrong direction ;) |
| 15:26:27 | <quicksilver> | yeah, that's the one you want. |
| 15:26:45 | <doserj> | ah |
| 15:27:24 | <quicksilver> | in fact that's more generalised that jmcarthur_work was specifically after |
| 15:27:29 | <jmcarthur_work> | :t fold |
| 15:27:31 | <lambdabot> | Not in scope: `fold' |
| 15:27:34 | <quicksilver> | he was after the particular case where t = [] |
| 15:27:41 | <quicksilver> | but, it is obviously good enough ;) |
| 15:28:41 | <jmcarthur_work> | @hoogle Monoid m => [m] -> m |
| 15:28:42 | <lambdabot> | Data.Monoid mconcat :: Monoid a => [a] -> a |
| 15:28:42 | <lambdabot> | Prelude head :: [a] -> a |
| 15:28:42 | <lambdabot> | Prelude last :: [a] -> a |
| 15:28:47 | <jmcarthur_work> | mconcat! |
| 15:29:56 | <jmcarthur_work> | does hoogle even care about type classes? |
| 15:30:17 | <quicksilver> | I think the latest version might do? |
| 15:30:21 | <quicksilver> | I'm not sure the one in LB does. |
| 15:33:34 | <alinp> | Hi |
| 15:33:51 | <alinp> | can anyone please tell me, why/when I'll need infinite lists in haskell ? |
| 15:34:15 | <Vq^> | alinp: you don't _need_ them |
| 15:34:17 | <alinp> | Some infinite term explained link will help |
| 15:36:06 | <Vq^> | ACTION can't think of a problem that can't be solved without infinite lists |
| 15:36:38 | <jmcarthur_work> | i tend to consider lists as a control structure rather than a data structure |
| 15:36:44 | <PhilRod> | but they're often a nice way of framing a problem |
| 15:36:46 | <jmcarthur_work> | and an infinite list is basically an infinite loop |
| 15:36:48 | <alinp> | Vq^: sorry, but I can't understand your statement :) |
| 15:36:55 | <jmcarthur_work> | but you can break out of that loop, of course |
| 15:37:02 | <jmcarthur_work> | and even go back into it later |
| 15:37:04 | <PhilRod> | ACTION used them all the time for project euler |
| 15:38:24 | <ClaudiusMaximus> | > let converge (x:y:xs) = if x == y then x else converge (y:xs) in converge . iterate (\x -> x + 1/x) $ (1::Double) |
| 15:38:30 | <lambdabot> | mueval-core: Prelude.read: no parse |
| 15:38:30 | <lambdabot> | mueval: ExitFailure 1 |
| 15:38:43 | <Vq^> | alinp: you don't need infinite lists, but sometimes they simplify your code in a nice way |
| 15:38:55 | <alinp> | I see |
| 15:39:00 | <PhilRod> | alinp: somewhere I used them a lot (for euler) was for looping over the primes, say |
| 15:39:01 | <jmcarthur_work> | typically the alternative to an infinite list is explicit recursion |
| 15:39:25 | <alinp> | yes, I know, primes is the best example for infinite lists |
| 15:40:09 | <jmcarthur_work> | > head . filter (\x -> x `mod` 2000 == 0) $ [2001..] |
| 15:40:11 | <lambdabot> | 4000 |
| 15:40:13 | <alinp> | I asked this about infinite list, because one friend of mine, asked me "and how infinite lists can help me ? " |
| 15:40:13 | <mxc> | hi, getting a strange error regarding overlapping instances.. I defined my own instance Monad Data.Either and am getting this error: Matching instances: |
| 15:40:14 | <mxc> | instance (Control.Monad.Error.Class.Error e) => Monad (Either e) |
| 15:40:14 | <mxc> | -- Defined in Control.Monad.Error |
| 15:40:14 | <mxc> | |
| 15:40:19 | <jmcarthur_work> | ^^ would require some recursion otherwise |
| 15:40:22 | <alinp> | and I didn't know what to answer to thaty |
| 15:40:25 | <alinp> | *that |
| 15:40:30 | <mxc> | is there anyway to hide the instance from Control.Monad.Error? |
| 15:40:34 | <jmcarthur_work> | or math, i guess |
| 15:40:45 | <jmcarthur_work> | but there are other things which wouldn't simplify with arithmetic |
| 15:40:45 | <Vq^> | zip [0..] is a nice idiom that uses an infinite list |
| 15:41:01 | <jmcarthur_work> | > zip "Hello, world!" [0..] |
| 15:41:02 | <lambdabot> | [('H',0),('e',1),('l',2),('l',3),('o',4),(',',5),(' ',6),('w',7),('o',8),('... |
| 15:41:13 | <Axman6> | alinp: one simple example would be f xs = zip [0..] xs, which would give you an index for each element in a list |
| 15:41:28 | <doserj> | mxc: only by not importing Control.Monad.Error |
| 15:41:49 | <mxc> | doserj - thats the strange thing, I dont import it anywhere |
| 15:42:03 | <doserj> | mxc: you do, indirectly, probably |
| 15:42:10 | <mxc> | !find . -name "*.hs" | xargs grep -i Monad.Error give nothing.. |
| 15:42:13 | <jmcarthur_work> | this is a problem with type classes. they are global |
| 15:42:24 | <mxc> | doserj - you must be right |
| 15:43:23 | <Vq^> | alinp: it's often more troublesome to add a limit than to have something infinite |
| 15:44:51 | <dhun> | how can I remove the element x from the list y |
| 15:45:22 | <jmcarthur_work> | filter (/= x) y |
| 15:45:32 | <jmcarthur_work> | something like that? |
| 15:45:40 | <dhun> | yes |
| 15:45:41 | <EvilTerran> | > delete 'a' "abracadabra" |
| 15:45:43 | <lambdabot> | "bracadabra" |
| 15:45:49 | <jmcarthur_work> | that works too :P |
| 15:45:54 | <jmcarthur_work> | but will only delete one |
| 15:45:59 | <jmcarthur_work> | which may be what you want |
| 15:46:01 | <dhun> | thats ok |
| 15:46:03 | <EvilTerran> | ^ delete takes only the first copy, so would be more efficient if you know there's no duplicates |
| 15:46:18 | <EvilTerran> | > filter (/='a') "abracadabra" -- while filter, naturally, takes all of them |
| 15:46:19 | <lambdabot> | "brcdbr" |
| 15:46:23 | <dhun> | I got no duplictes |
| 15:47:39 | <mxc> | thanks guys |
| 15:47:41 | <dhun> | : Not in scope: `delete' |
| 15:47:51 | <EvilTerran> | dhun, it's in Data.List |
| 15:48:16 | <EvilTerran> | "import Data.List (delete)" at the top of the module (or after the "module ... where", if you've got one) |
| 15:48:46 | <PeakerWork> | @index delete |
| 15:48:47 | <lambdabot> | Data.HashTable, Data.IntMap, Data.IntSet, Data.List, Data.Map, Data.Set |
| 15:49:15 | <dhun> | hehe but I can not compare data constructors for equality, so I can't do that |
| 15:49:35 | <jmcarthur_work> | oh this is a list of functions? |
| 15:49:52 | <dhun> | a list of data consturctors |
| 15:50:03 | <jmcarthur_work> | those are essentially functions |
| 15:50:06 | <dhun> | data A= A Int | B int |
| 15:50:10 | <dhun> | [A,B] |
| 15:50:18 | <quicksilver> | you don't want to do that, IMO. |
| 15:50:25 | <jmcarthur_work> | A :: Int -> A and B :: Int -> A |
| 15:50:34 | <quicksilver> | you want to do |
| 15:50:40 | <jmcarthur_work> | dhun, if you really need that, perhaps you should have a Map or something |
| 15:50:46 | <jmcarthur_work> | instead of a list |
| 15:50:58 | <quicksilver> | data A = A Int | B Int; data A_Con = AC_A | AC_B deriving (Eq) |
| 15:51:08 | <jmcarthur_work> | what he said |
| 15:51:09 | <quicksilver> | then put [AC_A,AC_B] in the list, where you can compare them. |
| 15:51:26 | <quicksilver> | i.e. have a simple "enum-like" type which mirrors your constructor structure. |
| 15:51:27 | <jmcarthur_work> | and a function construct :: A_Con -> Int -> A |
| 15:51:32 | <Saizan> | or data A = Con Kind Int; data Kind = A | B |
| 15:51:39 | <quicksilver> | yup. |
| 15:51:46 | <quicksilver> | if it really is Int in all cases |
| 15:51:50 | <quicksilver> | oh, obviously it is |
| 15:51:57 | <dhun> | I think I will just have two list, the lists are fixed at compile time anyway |
| 15:51:57 | <quicksilver> | or you wouldn't be able to put them in a list |
| 15:52:00 | <jmcarthur_work> | yeah, the list worked |
| 15:52:02 | <quicksilver> | so yes, I'm with Saizan. |
| 15:52:11 | <quicksilver> | data A = Con Kind Int; |
| 15:53:33 | <EvilTerran> | or just "data A = A | B", and use (A,Int) |
| 15:53:52 | <EvilTerran> | although that's a bit quick-and-dirty-er |
| 15:53:54 | <dhun> | interesting |
| 15:55:12 | <doserj> | data A = Con Kind Int gives you the Con_A constructor essentially for free, though. (A,) doesn't work unfortunately.. |
| 15:55:29 | <quicksilver> | you just spell it (,) A |
| 15:55:35 | <quicksilver> | maybe that's uglier than Con A |
| 15:55:38 | <quicksilver> | but it's not very different. |
| 15:55:41 | <doserj> | true |
| 15:55:49 | <Saizan> | if you hate the overhead you could derive Data and use its reflection features, but that's probably not the best route for a beginner |
| 15:56:02 | <quicksilver> | the advantage of (A,Int) is you get fst and snd for free |
| 15:56:05 | <quicksilver> | I suppose. |
| 15:56:18 | <dhun> | haskell has got reflection? |
| 15:56:24 | <EvilTerran> | quicksilver, and all the Arrow functions for pairs |
| 15:56:29 | <jmcarthur_work> | dhun, what kind of reflection? |
| 15:56:45 | <jmcarthur_work> | oh Data |
| 15:56:48 | <dhun> | the one Saizan mentioned? |
| 15:56:51 | <FliPPeh> | "do h <- gets handleS" How would I write that without using DO notation? |
| 15:56:53 | <Saizan> | dhun: you can reify constructors and types using Typeable/Data |
| 15:57:11 | <EvilTerran> | FliPPeh, depends on what you're doing with h |
| 15:57:16 | <quicksilver> | dhun: no, and yes. |
| 15:57:22 | <FliPPeh> | Mhh.. |
| 15:57:24 | <quicksilver> | haskell doesn't have reflection, technically. |
| 15:57:25 | <FliPPeh> | I want to use it. |
| 15:57:32 | <Saizan> | FliPPeh: gets handleS >>= \h -> ... |
| 15:57:46 | <EvilTerran> | where "..." is where you're using it |
| 15:57:47 | <quicksilver> | but there are metaprogamming facilities which enable you to accomplish much the same thing |
| 15:58:10 | <quicksilver> | "deriving Typeable" is relatively lightweight metaprogramming, "deriving Data" is much more complex. |
| 15:58:17 | <quicksilver> | and TH is even more powerful. |
| 15:58:30 | <quicksilver> | All these things happen at compile-time whereas "Reflection" normally happens at runtime. |
| 15:58:34 | <jmcarthur_work> | i don't think macros count as reflection |
| 15:58:39 | <Saizan> | does the "lots of boilerplate written by the compiler" qualifies as metaprogramming? |
| 15:58:46 | <quicksilver> | obviously that makes reflection inferior. |
| 15:59:02 | <jmcarthur_work> | Saizan, i'd say it does, just not reflection |
| 15:59:04 | <EvilTerran> | quicksilver, well, there's a fair bit of runtime shennanigans involved in SYB, isn't there? |
| 15:59:10 | <quicksilver> | jmcarthur_work: they are different but can be used to solve the same problem. |
| 15:59:26 | <FliPPeh> | I want to use it there: http://moonpatio.com/fastcgi/hpaste.fcgi/view?id=2627#a2627 |
| 15:59:34 | <quicksilver> | jmcarthur_work: (some of the same problems, I mean) |
| 15:59:55 | <dhun> | my parser finally understands this |
| 15:59:55 | <dhun> | # 1 |
| 15:59:55 | <dhun> | #* 2 |
| 15:59:55 | <dhun> | #;; 3 ''dd'' |
| 15:59:55 | <dhun> | #** 4 |
| 15:59:55 | <dhun> | # 5 |
| 16:00:06 | <dhun> | very happy |
| 16:00:07 | <EvilTerran> | FliPPeh, i'd stick with do-notation there |
| 16:00:07 | <jmcarthur_work> | @undo do h <- gets handleS; doSomething h |
| 16:00:08 | <lambdabot> | gets handleS >>= \ h -> doSomething h |
| 16:00:11 | <quicksilver> | EvilTerran: Hmm. Well, yes and no. |
| 16:00:22 | <jmcarthur_work> | @@ @pl @undo do h <- gets handleS; doSomething h |
| 16:00:22 | <lambdabot> | doSomething =<< gets handleS |
| 16:00:23 | <quicksilver> | EvilTerran: there is a *compile-time* process which arranges for lots of stuff to be reified as values |
| 16:00:28 | <quicksilver> | EvilTerran: which can be inspected at runtime. |
| 16:00:31 | <Axman6> | @. pl undo do h <- gets handleS; doSomething h |
| 16:00:31 | <lambdabot> | doSomething =<< gets handleS |
| 16:00:32 | <FliPPeh> | Keeps telling me the last statement must be an expression |
| 16:00:32 | <EvilTerran> | gotcha |
| 16:00:53 | <doserj> | FliPPeh: indentation error. align the "case" with the h |
| 16:01:00 | <EvilTerran> | FliPPeh, 'case' has to be lined up with the first line in the do block, not the do itself |
| 16:01:20 | <FliPPeh> | Ohh-- |
| 16:01:27 | <EvilTerran> | {-not here-}do {-but here!-}h <- gets handleS |
| 16:01:29 | <FliPPeh> | Stupid me, forgot that when adding that |
| 16:01:44 | <FliPPeh> | The "return ()" at the end is right, right? |
| 16:01:59 | <EvilTerran> | yeah, looks fine |
| 16:02:10 | <FliPPeh> | :) |
| 16:02:12 | <FliPPeh> | Thank you! |
| 16:02:31 | <EvilTerran> | assuming handlePrivmsg and autoJoinChannels are both :: ... -> IO (), anyway |
| 16:02:52 | <Saizan> | Bot () |
| 16:02:53 | <Saizan> | rather |
| 16:02:57 | <FliPPeh> | Bot () |
| 16:02:58 | <FliPPeh> | yep |
| 16:02:58 | <EvilTerran> | er, yes |
| 16:03:26 | <EvilTerran> | ACTION is used to the monad being IO when monads and handles occur together <.< >.> |
| 16:05:43 | <FliPPeh> | I hate errors that should not pop up |
| 16:05:49 | <FliPPeh> | Main.hs:81:160: parse error on input `->' |
| 16:06:03 | <FliPPeh> | Line 81 = " "376" -> autoJoinChannels " |
| 16:07:20 | <Twey> | FliPPeh: Looks like an indentation error. |
| 16:07:26 | <FliPPeh> | I think |
| 16:07:28 | <FliPPeh> | Just can't find it |
| 16:07:36 | <Twey> | Been mixing tabs and spaces? |
| 16:08:05 | <FliPPeh> | I configured my editor to only use spaces |
| 16:08:57 | <FliPPeh> | O |
| 16:08:58 | <FliPPeh> | Ohh |
| 16:09:00 | <FliPPeh> | haha |
| 16:09:17 | <EvilTerran> | FliPPeh, ? |
| 16:09:27 | <FliPPeh> | "376" -> autoJoinChannels _ -> return () |
| 16:09:31 | <FliPPeh> | Dead line on the end of it |
| 16:09:39 | <FliPPeh> | Must have tapped "DEL" one too often |
| 16:09:48 | <FliPPeh> | Was outside of the viewpoint :) |
| 16:09:54 | <EvilTerran> | dead line? |
| 16:10:04 | <FliPPeh> | It belongs under that line |
| 16:10:07 | <FliPPeh> | Not right behind it |
| 16:10:25 | <EvilTerran> | ah |
| 16:11:19 | <EvilTerran> | FliPPeh, incidentally, you could fold those two nested cases into case words rest of sender:"PRIVMSG":para -> ...; _:"376":_ -> ...; _ -> return () |
| 16:15:22 | <Eiler> | how do i make a table with a string representing a function? |
| 16:15:56 | <EvilTerran> | that depends entirely on what you mean by "table" and "representing" |
| 16:16:07 | <quicksilver> | and possibly "function" |
| 16:16:12 | <quicksilver> | oh language, how you fail us. |
| 16:16:48 | <Eiler> | "sqrt" -> sqrt |
| 16:17:25 | <EvilTerran> | ... that'll be manually, then |
| 16:17:45 | <EvilTerran> | names given to haskell values have no meaning at runtime |
| 16:17:55 | <Eiler> | what does "->" represent in words then? |
| 16:18:13 | <EvilTerran> | α-renaming is kinda useful to keep working |
| 16:18:38 | <Zao> | function taking _ "giving" _? |
| 16:18:42 | <EvilTerran> | Eiler, er, that looks like some kind of introspection, or runtime evaluation of haskell code, or something of that nature |
| 16:18:58 | <doserj> | Eiler: do you want sth. like Data.Map.fromList [("sqrt",sqrt),...], or sth like eval::String -> (...)? |
| 16:19:16 | <Zao> | EvilTerran: Map String f , where f is a nice and cuddly monomorphic function type? |
| 16:19:34 | <EvilTerran> | ACTION pokes Zao's tab key a second time |
| 16:19:59 | <FliPPeh> | EvilTerran: http://moonpatio.com/fastcgi/hpaste.fcgi/view?id=2629#a2629 is this what good haskell should look like? :) |
| 16:20:06 | <dhun> | why does this definition work: notFollowedBy p = try (do{ c <- p; unexpected (show [c]) } |
| 16:20:06 | <dhun> | <|> return () |
| 16:20:06 | <dhun> | ) |
| 16:20:07 | <Zao> | EvilTerran: Alternatively, I could type out more than one character before I complete, but that'd be work :) |
| 16:20:12 | <Zao> | EvilTerran: IRC needs more DWIMC. |
| 16:20:24 | <Eiler> | doserj: yes that might be it. now i have like: functionpointer fn = case fn of \n "factorial" -> factorial \n "sqrt" -> sqrt \n _ -> id |
| 16:20:31 | <dhun> | to me it look that return () is alway executed |
| 16:20:34 | <Eiler> | and it is runtime evaluation im going to do |
| 16:20:37 | <Zao> | EvilTerran: Will the functions always be a -> b ? |
| 16:20:44 | <Zao> | Dammit... Eiler :P |
| 16:20:57 | <Zao> | With the same a and b for everything? |
| 16:21:18 | <Eiler> | not sure but i think so |
| 16:21:20 | <EvilTerran> | FliPPeh, looks pretty good, yeah |
| 16:21:43 | <EvilTerran> | FliPPeh, i think forever may be written for you in Control.Monad |
| 16:22:07 | <EvilTerran> | not that "import Control.Monad (forever)" is substantially shorter than "forever m = m >> forever m" |
| 16:22:16 | <Eiler> | what is eval::String? |
| 16:22:35 | <FliPPeh> | :) |
| 16:22:36 | <doserj> | Eiler: sth that doesn't exist in Haskell |
| 16:22:37 | <FliPPeh> | Thanks |
| 16:22:48 | <Saizan> | it does exist |
| 16:22:50 | <Eiler> | sth = something? |
| 16:22:59 | <Saizan> | look at the hind package |
| 16:23:02 | <Saizan> | *hint |
| 16:23:15 | <EvilTerran> | FliPPeh, and you could write "connect s = connectTo s . PortNumber . fromIntegral", but it's a matter of personal taste whether that or yours is preferrable |
| 16:23:31 | <FliPPeh> | And now just by giving a function the type of Bot, I can use the gets and put methods to get any value from the BotState data? |
| 16:24:15 | <ClaudiusMaximus> | EvilTerran: i thought PortNumber had a Num instance, which was preferrable to using the PortNumber constructor, for endianness reasons |
| 16:24:17 | <FliPPeh> | I somehow like parantheses |
| 16:25:00 | <EvilTerran> | ClaudiusMaximus, i forget, i was just giving something with the same semantics as what was in the paste |
| 16:25:00 | <Saizan> | ?hoogle PortNumber |
| 16:25:00 | <lambdabot> | No results found |
| 16:26:06 | <jmcarthur_work> | afaik, PortNumber is an instance Num |
| 16:26:59 | <quicksilver> | ClaudiusMaximus: that's right. |
| 16:27:09 | <quicksilver> | ClaudiusMaximus: and by calling fromIntegral explicitly, EvilTerran is using the Num instance. |
| 16:27:25 | <quicksilver> | (PortNumber 42) is the same as (PortNumber . fromIntegral $ 42) |
| 16:27:42 | <quicksilver> | ACTION thinks that through for a moment |
| 16:27:46 | <quicksilver> | hang on that's rubbish |
| 16:27:53 | <quicksilver> | this is the constructor you're not supposed to use, isn't it? |
| 16:27:59 | <quicksilver> | and it's a bug that it's exported. |
| 16:28:10 | <Saizan> | no |
| 16:28:15 | <Saizan> | PortNumber is fine |
| 16:28:16 | <lilac> | if so, i have some code to fix... |
| 16:28:21 | <Saizan> | it's a constructor of PortID |
| 16:28:33 | <haonan> | could someone help me out with a question ? http://www.nabble.com/help-with-a-question-td23946402.html |
| 16:28:34 | <Saizan> | the constructor of the type PortNumber shouldn't be used, instead |
| 16:28:34 | <jmcarthur_work> | not a bug, but just fromIntegral should work, shouldn't it? |
| 16:28:53 | <quicksilver> | Saizan: Ah, thanks. |
| 16:29:01 | <Saizan> | PortID is not an instance of Num either |
| 16:29:06 | <quicksilver> | Saizan: I knew there was one constructor you're not supposed to use ;) |
| 16:29:09 | <jmcarthur_work> | ah! |
| 16:29:17 | <quicksilver> | type + constructor with same name |
| 16:29:21 | <quicksilver> | (but not being the same type) |
| 16:30:55 | <lilac> | haonan: i think your solution to (1) is wrong |
| 16:31:15 | <haonan> | wrong? |
| 16:31:29 | <Axman6> | i do too |
| 16:31:32 | <lilac> | haonan: well, for a start, what's as and at? :) |
| 16:31:43 | <Axman6> | considering as and at aren't defined anywhere |
| 16:32:18 | <Axman6> | haonan: also, just for convention's sake, you might consider using xss@(x:xs) and yss@(y:ys) |
| 16:32:21 | <lilac> | haonan: also, with the as and at corrected to be xs and xt, this appears to only work if the two lists are in the same order |
| 16:32:43 | <lilac> | haonan: are you aware of the 'elem' function? |
| 16:32:52 | <lilac> | > 4 `elem` [1,2,3,4,5] |
| 16:32:54 | <lambdabot> | True |
| 16:32:56 | <haonan> | axman6: noted |
| 16:32:59 | <lilac> | > 10 `elem` [1,2,3,4,5] |
| 16:33:00 | <haonan> | nope i'm not |
| 16:33:01 | <lambdabot> | False |
| 16:33:06 | <lilac> | you might find it useful. |
| 16:33:35 | <haonan> | ah alright |
| 16:33:49 | <Axman6> | hmm, i'm confused what should happen if say 1 is in both lists, and is in one list more than once |
| 16:34:15 | <haonan> | question 1 ?? |
| 16:34:21 | <Axman6> | yes |
| 16:34:52 | <Badger> | :t elem |
| 16:34:53 | <lambdabot> | forall a. (Eq a) => a -> [a] -> Bool |
| 16:34:57 | <haonan> | i haven't gt a single clue. i only got on to haskell yesterday and i'm not particularly strong in programming |
| 16:35:13 | <Axman6> | haonan: yeah i'm struggling with it too ;) |
| 16:35:44 | <lilac> | haonan: ok. your answer for question 1 is close, but not quite right |
| 16:36:05 | <haonan> | lilac: yup i figured out that one with some help here. thanks |
| 16:36:15 | <haonan> | now need major help with question 2 haha |
| 16:36:53 | <Axman6> | > let interset xs ys = filter (`elem` ys) xs in linterset [1,2,3] [1..10] |
| 16:36:54 | <lambdabot> | Not in scope: `linterset' |
| 16:36:59 | <Axman6> | > let interset xs ys = filter (`elem` ys) xs in interset [1,2,3] [1..10] |
| 16:37:00 | <lambdabot> | [1,2,3] |
| 16:37:04 | <Axman6> | > let interset xs ys = filter (`elem` ys) xs in interset [1,2,3] [2..10] |
| 16:37:05 | <lambdabot> | [2,3] |
| 16:37:06 | <lilac> | > let intersect [] ys = []; intersect xs [] = xs; intersect xs@(x:xt) ys@(y:yt) = if x == y then x:intersect xt yt else intersect xt ys in intersect [1,2,3] [3,2,1] |
| 16:37:07 | <lambdabot> | [3] |
| 16:37:19 | <lilac> | haonan: when the question says 'set', what does it mean? |
| 16:37:25 | <Saizan> | haonan: have you been exposed to list comprehensions? |
| 16:37:40 | <Axman6> | > let interset xs ys = filter (`elem` ys) xs in interset [1,2,3] [] |
| 16:37:41 | <lambdabot> | [] |
| 16:37:55 | <haonan> | A = { x, y , z} ? |
| 16:38:28 | <Axman6> | haonan: we're helping you with question 1 because it's more fundamental to your learning. imo, questions 2 is just annoying |
| 16:38:37 | <lilac> | haonan: by 'set' do you just mean a list, or do you mean a list with no duplicates, or do you mean a sorted list with no duplicates, or do you mean something else? |
| 16:38:40 | <haonan> | mm ok |
| 16:38:47 | <haonan> | just a list |
| 16:39:15 | <lilac> | what should 'intersect [1,1,1] [1,1]' return? |
| 16:39:29 | <haonan> | hold on |
| 16:39:57 | <Axman6> | > let interset xs ys = filter (`elem` ys) xs in interset [1,1,1] [1,1] |
| 16:39:58 | <lambdabot> | [1,1,1] |
| 16:40:07 | <Axman6> | > let interset xs ys = filter (`elem` ys) xs in interset [1,1] [1,1,1] |
| 16:40:08 | <lambdabot> | [1,1] |
| 16:40:25 | <Axman6> | associativity fail :( |
| 16:40:52 | <haonan> | it shld return [1,1] |
| 16:40:55 | <Saizan> | that's commutativity |
| 16:41:19 | <Axman6> | ah, yeah |
| 16:41:28 | <lilac> | > let intersect xs ys = concat [[y | y <- ys, y == x] | x <- xs] in intersect [1,1,1] [1,1] |
| 16:41:29 | <lambdabot> | [1,1,1,1,1,1] |
| 16:41:35 | <lilac> | > let intersect xs ys = concat [[y | y <- ys, y == x] | x <- xs] in intersect [1,1] [1,1,1] |
| 16:41:36 | <lambdabot> | [1,1,1,1,1,1] |
| 16:41:55 | <lilac> | haonan: what about 'intersect [1,1] [1,1,1]'? |
| 16:42:23 | <haonan> | same |
| 16:42:28 | <haonan> | [1,1] |
| 16:43:09 | <Axman6> | Saizan: what's aqssociativity again? (should really know this by now, i've learnt it enough times) |
| 16:43:42 | <lilac> | Axman6: associativity means x * (y * z) == (x * y) * z |
| 16:43:52 | <Axman6> | ah yes, right |
| 16:44:49 | <paolino> | what is needed on windows to run a gtk2hs application ? |
| 16:45:12 | <haonan> | hmm |
| 16:46:18 | <haonan> | i think i'll come back again tml for help. it's past midnight here and i'm too sleepy to do this |
| 16:46:39 | <haonan> | thanks guys |
| 16:47:23 | <Axman6> | night |
| 16:49:10 | <andrewsw> | I have two noob IO questions, 1) when doing `readFile somefile >>= putStr` what really goes on in the background? |
| 16:49:28 | <andrewsw> | does it just stream the whole file through or are there readLine's going on in there somehow? |
| 16:50:08 | <jmcarthur_work> | @src readFile |
| 16:50:09 | <lambdabot> | readFile name = openFile name ReadMode >>= hGetContents |
| 16:50:19 | <jmcarthur_work> | @src hGetContents |
| 16:50:20 | <lambdabot> | Source not found. Where did you learn to type? |
| 16:50:26 | <jmcarthur_work> | grr |
| 16:50:47 | <jmcarthur_work> | well, if you look at the source you will see some unsafeInterleaveIO and stuff |
| 16:50:49 | <andrewsw> | heh... |
| 16:50:57 | <andrewsw> | whoosh |
| 16:51:04 | <vegai> | andrewsw: try reading a 100GB file :P |
| 16:51:06 | <jmcarthur_work> | :t unsafeInterleaveIO |
| 16:51:07 | <lambdabot> | Not in scope: `unsafeInterleaveIO' |
| 16:51:14 | <jmcarthur_work> | :t System.IO.Unsafe.unsafeInterleaveIO |
| 16:51:15 | <lambdabot> | forall a. IO a -> IO a |
| 16:51:16 | <lilac> | andrewsw: what really happens is that readFile returns you a magic list |
| 16:51:32 | <andrewsw> | okay, I see. |
| 16:51:35 | <andrewsw> | more or less. |
| 16:51:39 | <lilac> | andrewsw: when you try to look at later elements of that list, more of the file is read in and cached |
| 16:51:49 | <dcoutts> | paolino: just the gtk dll files |
| 16:51:51 | <jmcarthur_work> | unsafeInterleaveIO basically means take an IO action and give me a value that, when evaluated in pure code, executes the action |
| 16:51:53 | <jmcarthur_work> | lazy IO |
| 16:52:16 | <lilac> | andrewsw: thus it's important that you operate on the list in such a way that you don't keep references to earlier bits |
| 16:52:29 | <dcoutts> | paolino: are you trying to distribute a gtk2hs program for systems that don't have ghc or gtk installed? |
| 16:52:34 | <lilac> | (otherwise you will end up with the whole file in memory as a [Char], and that can be pretty bug) |
| 16:52:42 | <lilac> | *big |
| 16:52:45 | <dcoutts> | paolino: for a demo of that, see http://haskell.org/~duncan/gtk2hs/LSystemSetup.exe |
| 16:52:48 | <andrewsw> | lilac: got it thanks |
| 16:53:03 | <andrewsw> | now 2) I want to filter that stream, and I'm having small troubles with it |
| 16:53:18 | <alinp> | Hi |
| 16:53:38 | <lilac> | andrewsw: what sort of troubles? |
| 16:53:42 | <andrewsw> | I'm thinking I need to readFile someFile >>= someFunction :: String -> IO() |
| 16:54:19 | <alinp> | I'm not a mathematical person, what book can be recomanded ? |
| 16:54:28 | <alinp> | ofc, Haskell book |
| 16:54:42 | <Axman6> | real world haskell? |
| 16:54:52 | <alinp> | Axman6: yes, been there |
| 16:54:53 | <lilac> | andrewsw: minor point, :: has really low precedence, that should be readFile someFile >>= (someFunction :: String -> IO ()) |
| 16:54:53 | <Axman6> | or learn you a haskell maybe? |
| 16:54:57 | <alinp> | somethingelse ? |
| 16:54:58 | <MyCatVerbs> | alinp: the two favourite ones are RWH and LYAH. |
| 16:54:58 | <paolino> | dcoutts: thanks , but I don't have a windows running machine |
| 16:55:01 | <MyCatVerbs> | @where lyah |
| 16:55:01 | <lambdabot> | www.learnyouahaskell.com |
| 16:55:11 | <lilac> | andrewsw: but yes, that's essentially right |
| 16:55:42 | <alinp> | the reason why I'm asking that is because there are a lot of cathegory theory concepts |
| 16:55:50 | <alinp> | Functors, Monoids, Monads .. etc |
| 16:55:52 | <andrewsw> | lilac: yeah, just trying to describe what I'm doing. Basically, I want to drop some of the lines that come through using, I assume filter (predicate) <input from readFile here> |
| 16:55:57 | <paolino> | dcoutts: I was asking just to know for casual users if it is a pain or not |
| 16:56:00 | <alinp> | and it seems that they are explained in a mathematical way |
| 16:56:02 | <lilac> | alinp: for those, the typeclassopedia is pretty good |
| 16:56:04 | <alinp> | which I can't handle |
| 16:56:14 | <lilac> | @where typeclassopedia |
| 16:56:14 | <lambdabot> | I know nothing about typeclassopedia. |
| 16:56:17 | <lilac> | @where typeclassopaedia |
| 16:56:18 | <lambdabot> | I know nothing about typeclassopaedia. |
| 16:56:39 | <lilac> | andrewsw: do you know about the 'lines' and 'unlines' functions? |
| 16:56:56 | <lilac> | > lines "hello world\nline 2\ngoodbye" |
| 16:56:57 | <lambdabot> | ["hello world","line 2","goodbye"] |
| 16:57:00 | <alinp> | ok, I'll give them a try |
| 16:57:04 | <alinp> | thanks guys |
| 16:57:30 | <MyCatVerbs> | http://www.haskell.org/haskellwiki/The_Monad.Reader <- Issue 13 includes the Typeclassopedia. |
| 16:57:44 | <andrewsw> | lilac: yeah, I'm doing some version of: |
| 16:57:48 | <alinp> | MyCatVerbs: RWH = ? and LYAH = ? |
| 16:57:59 | <alinp> | ah, LYAH = Learn Yourself .. |
| 16:58:04 | <lilac> | alinp: Real World Haskell, Learn You A Haskell (For Great Good) |
| 16:58:05 | <alinp> | but RWH ? |
| 16:58:08 | <alinp> | ah, ok |
| 16:58:22 | <andrewsw> | lilac: removeTarget target = putStr =<< (\x -> filter (contains target) (lines x)) |
| 16:58:28 | <MyCatVerbs> | alinp: RWH is "Real World Haskell", LYAH is "Learn You A Haskell (For Great Good)". Neither have any chunky bacon in them, IIRC. |
| 16:58:30 | <andrewsw> | lilac: but having little success with various permutations |
| 16:58:59 | <alinp> | MyCatVerbs: ok, thanks but I don't really like RWH |
| 16:59:11 | <alinp> | why is that ? because it's not what I want |
| 16:59:19 | <paolino> | dcoutts: with wine the program doesn't show well :), but it was very easy |
| 16:59:23 | <alinp> | it's too real .. if I may say so |
| 16:59:35 | <alinp> | LYAH I think is better |
| 17:00:07 | <MyCatVerbs> | alinp: Hrmn, thank you for the anecdote. |
| 17:00:38 | <alinp> | :) |
| 17:00:54 | <alinp> | sorry, I didn't wanted to sound like this |
| 17:01:40 | <alinp> | but the thing is that I don't consider RWH to be too good organised |
| 17:01:53 | <alinp> | it gives me different concepts without knowing them |
| 17:02:25 | <lilac> | andrewsw: ok, well that particular formulation won't work because the RHS is a function, so it'll be in the wrong monad |
| 17:02:29 | <alinp> | I need to read few more chapters in order to get any idea about 1st chapter concepts |
| 17:02:42 | <MyCatVerbs> | Hrmn. |
| 17:02:52 | <MyCatVerbs> | alinp: don't apologise, feedback is useful. :) |
| 17:03:13 | <lilac> | andrewsw: you don't want to combine two things in the IO monad here, so you don't need (>>=) |
| 17:03:16 | <andrewsw> | oh yeah, duh, I think... |
| 17:03:24 | <andrewsw> | lilac: on the function part |
| 17:03:26 | <alinp> | In fact RWH is pretty ok ... pretty practical, but I can't follow it |
| 17:03:46 | <alinp> | like I said, few concepts are introduced too soon, without knowing what they mean |
| 17:03:51 | <andrewsw> | lilac: I really want to take the output of the removeTarget function and just print it |
| 17:03:54 | <Axman6> | yeah, i do think that RWH needs another revision |
| 17:04:17 | <alinp> | I don't know if is ok, but Monads are a very important concept in haskell |
| 17:04:17 | <andrewsw> | lilac: but the input to that function is an IO String and I'm a lost noob |
| 17:04:24 | <alinp> | if not maybe the most |
| 17:04:42 | <alinp> | and should be very well explained, at least in that RWH |
| 17:04:56 | <lilac> | andrewsw: you want removeTarget to be the someFunction you mentioned above |
| 17:05:03 | <lilac> | andrewsw: so it's :: String -> IO () |
| 17:05:13 | <andrewsw> | lilac: yes |
| 17:05:20 | <lilac> | andrewsw: that is, its argument is just a String, not an IO String |
| 17:05:25 | <alinp> | haskellwiki is pretty good, but some times too much mathematics for me |
| 17:05:28 | <andrewsw> | lilac: right, I follow |
| 17:05:54 | <alinp> | and I'm starting too feel sorry that I wasn't paying atention to mathematics in highschool/university |
| 17:06:15 | <andrewsw> | lilac: hence I'm doing: readFile someFile >>= removeTarget (and I"ve hard coded the target despite my previous post) |
| 17:07:02 | <alinp> | anyone knows when "Coming soon" of Monads and rest of concepts from LYAH will be ? |
| 17:07:10 | <lilac> | andrewsw: ok, so you'll have something like 'removeTarget fileContents = putStr (something)' |
| 17:07:15 | <Botje> | alinp: ask BONUS |
| 17:07:22 | <lilac> | @seen BONUS |
| 17:07:22 | <Botje> | but i'm guessing he's smack in the middle of exams atm |
| 17:07:23 | <lambdabot> | BONUS is in #haskell. I last heard BONUS speak 8h 4m 20s ago. |
| 17:08:17 | <alinp> | I think all current computer science world needs a practical explanation of monads & co. |
| 17:08:22 | <andrewsw> | lilac: I think I got it! |
| 17:08:29 | <lilac> | andrewsw: great! |
| 17:08:46 | <andrewsw> | lilac: removeTarget = putStr . unlines . filter (contains "TARGET") . lines |
| 17:08:59 | <andrewsw> | lilac: at least it compiles, that's sufficient right? heh |
| 17:09:03 | <lilac> | andrewsw: right. and bonus marks for points-free style :) |
| 17:09:27 | <andrewsw> | lilac: that's the part that was getting me... where does the '>>=" put stuff |
| 17:09:51 | <andrewsw> | lilac: so I was thinking along the lines of points-free and ended up down the lambda hole somehow |
| 17:10:10 | <lilac> | andrewsw: that's the key thing about monads; the RHS of >>= is just an arbitrary function that returns something in the monad |
| 17:11:33 | <andrewsw> | lilac: yeah, I see now. Thanks for helping me through that. big light starting to glow there |
| 17:11:50 | <FliPPeh> | Just out of couriosity, why do I have to use liftIO inside of StateT? |
| 17:11:52 | <FliPPeh> | :) |
| 17:11:52 | <lilac> | andrewsw: incidentally, it's considered good style to separate the 'pure' parts of your code from the 'monadic' parts, as in... |
| 17:11:59 | <FliPPeh> | curiousity? |
| 17:12:02 | <FliPPeh> | Bad word |
| 17:12:04 | <FliPPeh> | I hate it. |
| 17:12:17 | <byorgey> | curiosity, only one u and one o =) |
| 17:12:27 | <FliPPeh> | :D |
| 17:12:34 | <FliPPeh> | Saved. |
| 17:12:45 | <lilac> | andrewsw: readFile "foo" >>= putStr . removeTarget "TARGET" where removeTarget target = unlines . filter (not . contains target) . lines |
| 17:13:02 | <byorgey> | FliPPeh: it's because the types would not match otherwise. You can't sequence a StateT s IO action with an IO action because they have not the same type. |
| 17:13:14 | <FliPPeh> | :t liftIO |
| 17:13:15 | <lambdabot> | forall a (m :: * -> *). (MonadIO m) => IO a -> m a |
| 17:13:19 | <byorgey> | FliPPeh: liftIO is for 'lifting' IO actions into StateT s IO actions which don't modify the state. |
| 17:13:23 | <lilac> | andrewsw: here, removeTarget :: String -> String -> String (no IO involved) |
| 17:13:40 | <andrewsw> | lilac: yeah, i wondered about that a bit. and nice catch that my function didn't do what it said... heh |
| 17:13:42 | <byorgey> | well, as you can see, it's actually more general than that, it works for any monad which is an instance of MonadIO |
| 17:13:46 | <FliPPeh> | Okay, thanks :) |
| 17:13:49 | <byorgey> | but StateT s IO is such a monad |
| 17:14:01 | <FliPPeh> | So it's just a bridge? |
| 17:14:25 | <lilac> | andrewsw: incidentally, do you know about 'do' notation? |
| 17:14:36 | <hatds> | why isn't there a hGetLine for lazy ByteStrings? |
| 17:15:00 | <andrewsw> | lilac: a little bit. I use it when I see something that is clearly imperative like: |
| 17:15:01 | <byorgey> | FliPPeh: more like a box. If you're going to ship your cat somewhere you have to put it in a box first, since cats are not stackable |
| 17:15:15 | <FliPPeh> | If you train them right.. |
| 17:15:21 | <FliPPeh> | You might aswell stack them :) |
| 17:15:27 | <byorgey> | well, the analogy breaks down I guess =) |
| 17:15:59 | <andrewsw> | lilac: updateFile line = do print "updating file |
| 17:16:00 | <FliPPeh> | http://www.craftycrafty.tv/stackablecats_shop.jpg |
| 17:16:05 | <FliPPeh> | See, stackable |
| 17:16:18 | <byorgey> | hahaha |
| 17:16:24 | <andrewsw> | lilac: appendFile someFile line |
| 17:16:35 | <andrewsw> | lilac: or something like that |
| 17:17:21 | <byorgey> | FliPPeh: but anyway, yes, liftIO is just for translating from the IO-world to the m-world where m is essentially any monad built by stacking transformers on top of IO |
| 17:17:36 | <lilac> | andrewsw: right. your case might read more clearly as: do { contents <- readFile "foo"; putStr (removeTarget "TARGET" contents) } |
| 17:17:50 | <FliPPeh> | ;) |
| 17:17:54 | <FliPPeh> | Okayyy |
| 17:18:06 | <lilac> | andrewsw: however, if you're a fan of point-free form, you'll probably like the >>= version more... |
| 17:18:06 | <FliPPeh> | I'm making great progress in Haskell |
| 17:18:08 | <FliPPeh> | [19:16:44] <@FliP^2eH> !uptime |
| 17:18:08 | <FliPPeh> | [19:16:44] <+LambdaZero> I've been running for 8m 4s. |
| 17:18:09 | <FliPPeh> | Worky! |
| 17:18:19 | <byorgey> | =D |
| 17:18:39 | <andrewsw> | lilac: I'm not necessarily a fan of points-free but for some idioms it just seems right to me |
| 17:18:53 | <andrewsw> | lilac: this filtering of a file is jsut the sort of thing that fits it, in my opinion |
| 17:19:12 | <lilac> | andrewsw: well, i'm with you on that. sometimes it's helpful to think of the process, sometimes it's helpful to think of the data |
| 17:19:13 | <FliPPeh> | > getClockTime |
| 17:19:14 | <lambdabot> | Not in scope: `getClockTime' |
| 17:19:16 | <FliPPeh> | ;O |
| 17:19:24 | <andrewsw> | lilac: if only because it *looks* like it's filtering something through a funnel |
| 17:19:31 | <FliPPeh> | > :m System.Time |
| 17:19:32 | <lambdabot> | <no location info>: parse error on input `:' |
| 17:19:34 | <FliPPeh> | :d |
| 17:20:01 | <FalconNL> | Does anyone know if 480.000 Array lookups are supposed to take about a second? It seems kind of long to me. |
| 17:20:13 | <lilac> | FalconNL: certainly sounds like a long time |
| 17:20:56 | <FalconNL> | http://codepad.org/qe1ieCLt |
| 17:21:14 | <FliPPeh> | Hey, new Fedora is out |
| 17:21:16 | <FalconNL> | I can't see what's supposed to be taking this long |
| 17:21:20 | <FliPPeh> | Sticking to Arch Linux, tho |
| 17:21:26 | <FliPPeh> | I wonder if there are many linuxers here? |
| 17:21:28 | <andrewsw> | lilac: all this just to write a simple todo after seeing http://www.reddit.com/r/programming/comments/8nv63/ask_proggit_how_do_you_todo/ |
| 17:21:46 | <thoughtpolice> | FliPPeh: plenty :) |
| 17:21:48 | <andrewsw> | lilac: great excuse to learn some haskell |
| 17:21:54 | <andrewsw> | lilac: anyways, thanks a ton |
| 17:22:13 | <MyCatVerbs> | andrewsw: to learn a Haskell. |
| 17:22:22 | <MyCatVerbs> | andrewsw: (for great good!) |
| 17:22:27 | <andrewsw> | MyCatVerbs: my bad, I knew that ;-P |
| 17:22:32 | <Badger> | @where lyah |
| 17:22:33 | <lambdabot> | www.learnyouahaskell.com |
| 17:22:41 | <FliPPeh> | Learn You A Haskell is great :( |
| 17:22:42 | <FliPPeh> | :) |
| 17:22:50 | <FliPPeh> | Should add monads |
| 17:23:04 | <Badger> | ACTION looks slyly at BONUS |
| 17:25:08 | <lilac> | FalconNL: interpreted in ghci, it takes 12s on my fast machine and 40s on my slow machine to read 500000 entries from a 1000000 entry array |
| 17:25:32 | <lilac> | andrewsw: no problem |
| 17:25:42 | <FliPPeh> | I wonder how stable my Bot is |
| 17:26:00 | <FliPPeh> | My previous ones in the first days all died because of string parsing failures |
| 17:26:50 | <FalconNL> | lilac: hm. I don't suppose you know another list-like data type with fast random access? I tried Vector, but the type inference seems to hate it. |
| 17:28:35 | <paolino> | dcoutts: do I need a local windows machine to make an installer like LSystem ? |
| 17:29:25 | <MyCatVerbs> | FalconNL: there's Data.Sequence. |
| 17:29:58 | <lilac> | i don't understand reddit. isn't there supposed to be a link on which people are commenting? |
| 17:30:17 | <FalconNL> | MyCatVerbs: sadly, the elements are non-unique |
| 17:30:22 | <jmcarthur_work> | lilac, you can also do a self link which is solely for comment threads |
| 17:30:22 | <ray> | sometimes they're "self" posts |
| 17:30:28 | <ray> | and there's no link, just a title |
| 17:30:38 | <andrewsw> | it's just an "ask proggit" thing |
| 17:30:44 | <ray> | it can get a bit stupid though |
| 17:31:05 | <ray> | well it's not that there's no link exactly, but the link is to the reddit post itself |
| 17:32:07 | <lilac> | so it's like taking the fixed point of commenting? |
| 17:32:28 | <ray> | it's the fixed point of something |
| 17:33:24 | <dcoutts> | paolino: you might be able to run InnoSetup under Wine |
| 17:33:27 | <lilac> | FalconNL: well, array should be the go-to type for that sort of thing. |
| 17:33:55 | <FalconNL> | lilac: That was my thought too, but I assumed it would be faster in ghci |
| 17:33:56 | <malouin> | So who releases the haskell report? Is there a haskell standards body, or something like the perl foundation for haskell, or is it individuals? |
| 17:34:14 | <ray> | is it considered bad form to use Data.Set for the implicit sorting? |
| 17:34:23 | <ray> | i'm thinking yes (but doing it anyway) |
| 17:34:26 | <mauke> | ray: no |
| 17:34:44 | <ray> | i'd figure the implicit uniqueness is ok though |
| 17:36:22 | <lilac> | FalconNL: compiled with -O9 using GHC 6.8.2 it takes 3.5 seconds here :-/ |
| 17:37:05 | <mauke> | -O9? stop making up options |
| 17:37:05 | <lilac> | ray: the Ord constraint and element ordering is all explicit in the Set contract, so I think it's fine |
| 17:37:34 | <burp> | lol |
| 17:37:48 | <lilac> | mauke: what's with the attitude? -O9 is fully documented |
| 17:37:59 | <mauke> | oh, is that new in 6.8? |
| 17:38:10 | <lilac> | mauke: -O<n> Set optimization level <n> |
| 17:38:19 | <ray> | it's not like i'm doing a sort with toList . fromList or anything silly like that |
| 17:38:20 | <FalconNL> | lilac: the sample I posted on codepad runs in 0-15 ms when compiled with O2 on GHC 6.10.2 |
| 17:38:34 | <lilac> | mauke: looks like 9 is equivalent to 2, but i don't see that's a problem... |
| 17:39:11 | <hatds> | can one convert between ByteStrings and Lazy.ByteStrings? |
| 17:39:18 | <mauke> | lilac: where does it say 9 is equivalent to 2? |
| 17:39:23 | <thoughtpolice> | hatds: convert I believe |
| 17:39:41 | <lilac> | mauke: it doesn't. but it says various things are implied by -O2 |
| 17:39:45 | <thoughtpolice> | hatds: ah no wait |
| 17:39:48 | <thoughtpolice> | hatds: http://hackage.haskell.org/packages/archive/bytestring/0.9.1.4/doc/html/Data-ByteString-Lazy.html#v:fromChunks |
| 17:39:51 | <thoughtpolice> | ^^ that's what you want |
| 17:40:17 | <mauke> | lilac: I think 6.8 did make -O<n> for n > 2 equivalent to -O2, but in older GHCs it was worse than -O1 |
| 17:40:25 | <thoughtpolice> | hatds: essentially a lazy bytestring is just a set of strict bytestrings, hence toChunks/fromChunks for conversion |
| 17:40:28 | <mauke> | but not quite -O0 |
| 17:41:05 | <lilac> | mauke: well, i appreciate the history lesson :) |
| 17:59:02 | <FliPPeh> | If I want to parse very simple configuration files with key/value pairs like NAME="Santa", is parsec suitable? |
| 17:59:14 | <FliPPeh> | I want a result like ("NAME", "Santa") |
| 17:59:17 | <FliPPeh> | Tuple |
| 17:59:40 | <Lemmih> | Yes. |
| 17:59:59 | <Lemmih> | You could also do it without parsec. |
| 18:00:13 | <FliPPeh> | I fear of those whitespace interferences |
| 18:01:47 | <Saizan> | do you allow " in values or not? |
| 18:01:56 | <FliPPeh> | I won't |
| 18:02:02 | <FliPPeh> | Not right now |
| 18:02:02 | <MyCatVerbs> | map (second tail . span (/='=')) . lines $ "NAME=Santa\nNOSE=red\nMOOD=jovial\n" |
| 18:02:08 | <MyCatVerbs> | > map (second tail . span (/='=')) . lines $ "NAME=Santa\nNOSE=red\nMOOD=jovial\n" |
| 18:02:09 | <lambdabot> | [("NAME","Santa"),("NOSE","red"),("MOOD","jovial")] |
| 18:02:32 | <FliPPeh> | > map (second tail . span (/='=')) . lines $ "NAME=Santa\nNOSE=red\nMOOD= jovial\n" |
| 18:02:37 | <FliPPeh> | > map (second tail . span (/='=')) . lines $ "NAME=Santa\nNOSE=red\nMOOD= jovial\n" |
| 18:02:38 | <lambdabot> | [("NAME","Santa"),("NOSE","red"),("MOOD"," jovial")] |
| 18:02:40 | <FliPPeh> | Bad spaces |
| 18:02:46 | <MyCatVerbs> | Heehee. :3 |
| 18:03:34 | <FliPPeh> | Some time later I will consider adding "" for strings and quoteless for numbers |
| 18:03:41 | <FliPPeh> | But I don't see much use for this right now |
| 18:03:50 | <FliPPeh> | As only I use it and I know how to not-break it :) |
| 18:04:21 | <Saizan> | it's also easy to trim spaces |
| 18:04:27 | <FliPPeh> | Thought so |
| 18:09:29 | <FliPPeh> | @src second |
| 18:09:30 | <lambdabot> | Source not found. You untyped fool! |
| 18:09:48 | <FliPPeh> | > map (tail . span (/='=')) . lines $ "NAME=Santa\nNOSE=red\nMOOD= jovial\n" |
| 18:09:49 | <lambdabot> | Couldn't match expected type `[a]' |
| 18:09:54 | <FliPPeh> | > map (second tail . span (/='=')) . lines $ "NAME=Santa\nNOSE=red\nMOOD= jovial\n" |
| 18:09:55 | <lambdabot> | [("NAME","Santa"),("NOSE","red"),("MOOD"," jovial")] |
| 18:09:56 | <FliPPeh> | :S |
| 18:09:59 | <FliPPeh> | second = ? |
| 18:10:01 | <FliPPeh> | :t second |
| 18:10:02 | <lambdabot> | forall (a :: * -> * -> *) b c d. (Arrow a) => a b c -> a (d, b) (d, c) |
| 18:31:37 | <FliPPeh> | > Just (takeWhile (/= '!') str) where str = "Test!String" |
| 18:31:38 | <lambdabot> | <no location info>: parse error on input `where' |
| 18:32:05 | <FliPPeh> | > let str = "Test!String" in Just (takeWhile (/= '!') str) |
| 18:32:06 | <lambdabot> | Just "Test" |
| 18:32:12 | <FliPPeh> | Why does it work here? |
| 18:32:16 | <FliPPeh> | But no in my code? |
| 18:32:47 | <MyCatVerbs> | FliPPeh: Can't tell you without seeing the code in question. hpaste? |
| 18:32:51 | <FliPPeh> | Wait |
| 18:32:52 | <FliPPeh> | Trying to cpoy |
| 18:33:01 | <FliPPeh> | getUserDetails u = if '!' `elem` u |
| 18:33:01 | <FliPPeh> | then (Just (takeWhile (/= '!') u), Just "dbg", Nothing) |
| 18:33:01 | <FliPPeh> | else (Nothing, Nothing, u) |
| 18:33:04 | <FliPPeh> | There we go |
| 18:33:11 | <FliPPeh> | getUserDetails :: String -> (Maybe String, Maybe String, String) |
| 18:33:15 | <mauke> | don't use tabs in the middle of lines :-( |
| 18:33:29 | <MyCatVerbs> | @where hpaste |
| 18:33:30 | <lambdabot> | http://hpaste.org/ |
| 18:33:38 | <MyCatVerbs> | For the love of hpaste, please use hpaste. |
| 18:33:45 | <FliPPeh> | I will |
| 18:33:46 | <mauke> | FliPPeh: Nothing :/: String |
| 18:33:58 | <FliPPeh> | Oh wow |
| 18:34:00 | <FliPPeh> | I'm stupid |
| 18:34:14 | <FliPPeh> | Looking for the right error in the wrong place |
| 18:34:16 | <FliPPeh> | Thanks |
| 18:35:09 | <FliPPeh> | > let str = "Test!String@teeeeheee" in Just (takeWhile (/= '!') . (dropWhile (/= '@')) str) |
| 18:35:11 | <lambdabot> | Couldn't match expected type `a -> [GHC.Types.Char]' |
| 18:35:26 | <FliPPeh> | > let str = "Test!String@teeeeheee" in Just takeWhile (/= '!') . dropWhile (/= '@') str) |
| 18:35:27 | <lambdabot> | <no location info>: parse error on input `)' |
| 18:35:32 | <FliPPeh> | > let str = "Test!String@teeeeheee" in Just takeWhile (/= '!') . dropWhile (/= '@') str |
| 18:35:34 | <lambdabot> | Couldn't match expected type `(GHC.Types.Char -> GHC.Bool.Bool) |
| 18:35:36 | <FliPPeh> | Meh |
| 18:35:37 | <FliPPeh> | ghci time |
| 18:39:04 | <jeffersonheard_h> | well, today is apparently weird bug day |
| 18:47:23 | <Taejo> | anybody know what C function System.Process.runProcess uses? I'm trying to get it to run 'vim' |
| 18:48:14 | <Lemmih> | The exec family, I think. |
| 18:48:47 | <quicksilver> | fork and exec, under *nix, I believe |
| 18:48:53 | <quicksilver> | something else under windows |
| 18:49:23 | <Taejo> | quicksilver: I don't care hugely about Windows atm, tho I think it uses CreateProcess there |
| 18:49:24 | <Badger> | ACTION gives everyone a monkfish |
| 18:50:08 | <Badger> | (disregard that, I etc. etc.) |
| 18:50:27 | <quicksilver> | it's OK. An unsolicited monkfish is never unwelcome. |
| 18:51:48 | <Badger> | heh. |
| 18:52:09 | <Badger> | never leave autospeaking scripts on |
| 18:52:21 | <Lemmih> | What's a monkfish? Is it similar to getting a hummer? |
| 18:52:59 | <Badger> | Slightly cheaper. |
| 18:53:11 | <quicksilver> | Not. It's just a fish. Unless there is some double entendre that has passed me by. |
| 18:53:24 | <MyCatVerbs> | No, it's a tasty animal with firm, juicy flesh. |
| 18:53:38 | <MyCatVerbs> | It's commonly used as a scampi substitute, but it's good stuff in its own right too. |
| 18:54:16 | <guenni_> | hi, does cabal that ships with ghc 6.10.3 have problems with finding c libs? |
| 18:54:29 | <dcoutts> | guenni: nope |
| 18:55:14 | <dcoutts> | guenni: that doesn't mean it can do magic :-) |
| 18:55:25 | <guenni_> | rather strange dcoutts , I tried to reinstall stuff when switching from 6.10.2 |
| 18:55:45 | <guenni_> | dcoutts: hdbc driver for isntance |
| 18:55:55 | <dcoutts> | eg if you've got C libs that are not on the normal linker path then you'd have to tell Cabal about that |
| 18:56:41 | <guenni_> | I can't figure out what I could have changed in my systems config, |
| 18:56:59 | <dino-> | Taejo: What's it doing? I was able to run vim with import System.Process ... runCommand "vim" >>= waitForProcess |
| 18:57:23 | <dino-> | But HSH runIO "vim", not so much |
| 18:57:53 | <guenni_> | dcoutts: just to be on the safe side, how do I do that on xp, ie tell cabal where the libs are? |
| 18:58:35 | <dcoutts> | guenni: --extra-include-dirs --extra-lib-dirs |
| 18:58:37 | <guenni_> | dcoutts: I noticed that gcc seems to be missing in 6.10.3 |
| 18:58:48 | <guenni_> | dcoutts: thx |
| 18:58:59 | <dcoutts> | guenni_: it's there in the default windows installer |
| 18:59:17 | <Taejo> | dino-: "Vim: Error reading input, exiting... Vim: Finished." |
| 18:59:25 | <dcoutts> | guenni_: check in the dir where it's installed, it'll be there. It's used every time for assembling and linking. |
| 19:00:08 | <guenni_> | dcoutts: yep, you're right, false alarm, sry |
| 19:01:43 | <Taejo> | dino-: it looks like System.Cmd.rawSystem is what I need |
| 19:23:18 | <jmcarthur_work> | wow this code to convert CamelCase to underscore_separated took me entirely too long to write |
| 19:23:34 | <mauke> | spoj.pl? |
| 19:25:03 | <jmcarthur_work> | wow i never heard of spoj.pl |
| 19:25:11 | <mauke> | http://www.spoj.pl/problems/JAVAC/ |
| 19:26:22 | <jmcarthur_work> | i actually went the other direction than that |
| 19:26:34 | <jmcarthur_work> | this would have been easier! |
| 19:27:03 | <Cale> | > intercalate "_" . map (map toLower) . groupBy (\x y -> isUpper x && isLower y) $ "CamelCase" |
| 19:27:05 | <lambdabot> | "camel_case" |
| 19:27:23 | <Cale> | hmm, maybe not the best way |
| 19:27:24 | <jmcarthur_work> | > intercalate "_" . map (map toLower) . groupBy (\x y -> isUpper x && isLower y) $ "CamelXXCase" |
| 19:27:26 | <lambdabot> | "camel_x_x_case" |
| 19:27:35 | <jmcarthur_work> | mine handled that too |
| 19:27:39 | <jmcarthur_work> | camel_xx_case |
| 19:27:46 | <mauke> | that's wrong |
| 19:27:47 | <Cale> | Perhaps groupBy (\x y -> isLower y) $ "CamelCase" |
| 19:28:09 | <Taejo> | a version of getEnv that returned IO (Maybe String) would be very nice |
| 19:28:22 | <Taejo> | but since it's not there... time to learn how to catch exceptions |
| 19:28:31 | <Cale> | > intercalate "_" . map (map toLower) . groupBy (\x y -> isLower y) $ "camelCase" |
| 19:28:33 | <lambdabot> | "camel_case" |
| 19:29:03 | <mauke> | getenv def var = getEnv var `catch` (const $ return def) |
| 19:29:30 | <Cale> | Since, for example... |
| 19:29:34 | <Cale> | > groupBy (\x y -> isUpper x && isLower y) $ "camelCase" |
| 19:29:36 | <lambdabot> | ["c","a","m","e","l","Case"] |
| 19:29:39 | <Cale> | which is wrong |
| 19:29:51 | <Cale> | > groupBy (\x y -> isLower y) $ "camelCase" |
| 19:29:53 | <lambdabot> | ["camel","Case"] |
| 19:30:20 | <mauke> | s/([A-Z])/_\l$1/g |
| 19:30:25 | <thoughtpolice> | dcoutts: ping |
| 19:30:26 | <olsner> | cool abuse of groupBy |
| 19:30:37 | <Cale> | I don't consider it an abuse :) |
| 19:30:38 | <mauke> | groupBy is meant to be abused |
| 19:30:49 | <dcoutts> | thoughtpolice: pong |
| 19:30:53 | <jmcarthur_work> | still doesn't handle camelXXCase properly |
| 19:31:03 | <Cale> | jmcarthur_work: It doesn't? |
| 19:31:04 | <mauke> | jmcarthur_work: your definition of "proper" is wrong! |
| 19:31:15 | <Cale> | > groupBy (\x y -> isLower y) $ "camelXXCase" |
| 19:31:16 | <lambdabot> | ["camel","X","X","Case"] |
| 19:31:16 | <jmcarthur_work> | camelURLCase |
| 19:31:22 | <Cale> | Seems right to me. |
| 19:31:23 | <olsner> | I wouldn't want to rely on groupBy using the head of the group to compare with |
| 19:31:28 | <jmcarthur_work> | camel_u_r_l_case? |
| 19:31:29 | <Cale> | olsner: I would. |
| 19:31:37 | <mauke> | jmcarthur_work: yes |
| 19:31:42 | <jmcarthur_work> | yuck! |
| 19:31:44 | <mauke> | that just shows why camelCase sucks |
| 19:31:56 | <jmcarthur_work> | why? |
| 19:32:14 | <dcoutts> | Cale: so you want it to compare each element to the first in the group, or to compare runs, ie each to the previous in the group? |
| 19:32:31 | <Cale> | dcoutts: I think we should have both, but the existing groupBy should be the first. |
| 19:32:33 | <olsner> | seems to me that there should be an implicit demand for the condition to have pretty much the same properties as (==) |
| 19:32:54 | <Cale> | dcoutts: There should also be a groupByAdj which compares pairs of adjacent elements |
| 19:33:01 | <dcoutts> | Cale: I remember bumping into this issue when implementing the streamable groupby |
| 19:33:02 | <jmcarthur_work> | olsner, you mean commutative? lists are ordered. i think we should be able to rely on ordering |
| 19:33:18 | <olsner> | using the head of the group or using the adjacent element should be an undefined implementation detail of group, I think |
| 19:33:20 | <Cale> | dcoutts: I think both of them are useful |
| 19:33:35 | <Cale> | I really hate what's been done to nubBy recently. |
| 19:33:35 | <dcoutts> | Cale: and the nub/nubBy issues is similar right? |
| 19:33:38 | <Cale> | yeah |
| 19:33:45 | <jmcarthur_work> | mauke, why does this mean camel case sucks? |
| 19:33:48 | <Cale> | We should be able to rely on its behaviour |
| 19:33:53 | <mauke> | because it can't represent underscore_URL_separated identifiers |
| 19:33:55 | <dcoutts> | Cale: wasn't that fixing things so nub = nubBy (==) |
| 19:33:58 | <jmcarthur_work> | yes it can |
| 19:34:01 | <olsner> | jmcarthur_work: actually, I would also expect it to work the same if it groups backwards |
| 19:34:05 | <jmcarthur_work> | underscoreURLSeparated |
| 19:34:08 | <jmcarthur_work> | it's unambiguous |
| 19:34:12 | <Cale> | dcoutts: But in the process, they broke nubBy |
| 19:34:20 | <mauke> | jmcarthur_work: underscore_u_r_l_separated |
| 19:34:21 | <dcoutts> | Cale: perhaps it should be the other way around, but we must have nub = nubBy (==) |
| 19:34:28 | <Cale> | yes, we should :) |
| 19:34:30 | <jmcarthur_work> | mauke, your mental algorithm is wrong |
| 19:34:32 | <ray> | underscoreUrlSeparated |
| 19:34:36 | <ray> | and then you lose case information |
| 19:34:48 | <Cale> | It wasn't nubBy's fault, it was the implementation of nub, as far as I can tell. |
| 19:34:51 | <jmcarthur_work> | i managed to get my converter to work right...\ |
| 19:34:56 | <Cale> | nubBy in 6.8.3 was correct. |
| 19:35:01 | <mauke> | jmcarthur_work: well, how do you turn underscore_u_r_l_separated into camel case? |
| 19:35:16 | <ray> | _ separated things can have case information, but can't have _s |
| 19:35:19 | <dcoutts> | Cale: send in some QC tests to specify the behaviour. I remember being somewhat disappointed that the list lib functions are not that well specified. Eg the generic ones do not always match the specialised ones. |
| 19:35:45 | <Cale> | dcoutts: Okay, but on the mailing list, I gave a mathematical definition of the behaviour I want them to have. |
| 19:35:46 | <jmcarthur_work> | mauke, oh i see what you mean now. but when would you ever write something like that in underscore notation anyway? |
| 19:35:47 | <Zao> | Some camel standards encourage camelUrlCase. |
| 19:35:55 | <dcoutts> | Cale: eg when doing the stream versions I noticed that genericTake is not the same as take, or perhaps it was drop. |
| 19:36:09 | <Zao> | As a capital letter unambigiously maps to a _ then, it's all fine. |
| 19:36:51 | <mauke> | jmcarthur_work: struct spork_c_style { ... }; |
| 19:37:00 | <Cale> | dcoutts: An easy way to check if you have it right for nubBy is the implementation of primes |
| 19:37:06 | <jmcarthur_work> | sporkCStyle still seems okay to me though |
| 19:37:21 | <mauke> | visually clashy, but you're right, I suppose |
| 19:37:30 | <Cale> | nubBy (\x y -> y `mod` x == 0) [2..] should be the list of primes |
| 19:37:54 | <mauke> | let's see if I have x_x_x_x identifiers anywhere |
| 19:38:12 | <FliPPeh> | Using StateT, is there a way to get all of my state data, or do I have to "gets" each of them as single? |
| 19:38:44 | <mauke> | FliPPeh: lol wut |
| 19:38:52 | <FliPPeh> | wat wat |
| 19:38:57 | <jmcarthur_work> | FliPPeh, what do you mean? if you have a record as your state then get should return the entire thing anyway |
| 19:39:15 | <mauke> | FliPPeh: 'get', but even if you only had 'gets', it's just 'gets id' |
| 19:39:16 | <FliPPeh> | okay! |
| 19:39:59 | <dirk_> | me for example |
| 19:40:51 | <mauke> | move_x_y_origin |
| 19:42:50 | <jmcarthur_work> | mauke, arguably, the x and y there aren't necessary anyway |
| 19:43:12 | <jmcarthur_work> | could be replaced with 2d or something |
| 19:43:34 | <jmcarthur_work> | and even so, moveXYOrigin is still readable |
| 19:43:43 | <jmcarthur_work> | move_xy_origin would mean the same thing to me |
| 19:44:25 | <jmcarthur_work> | anyway, i'm tired of meaningless syntactical debate, and I accept that there are other valid opinions ;) |
| 19:44:49 | <dirk_> | is there serialization in Haskell? |
| 19:45:03 | <jmcarthur_work> | > show [1,2,3,] |
| 19:45:04 | <lambdabot> | <no location info>: parse error on input `]' |
| 19:45:08 | <jmcarthur_work> | > show [1,2,3] |
| 19:45:10 | <lambdabot> | "[1,2,3]" |
| 19:45:11 | <jmcarthur_work> | my bad |
| 19:46:52 | <dino-> | I had a job a few years ago where they decided to start imposing coding style guidelines on the entire 300 person engineering division. A huge argument raged for a couple of weeks about whether or not to outlaw // style comments and force /* */ only. |
| 19:47:22 | <Cale> | jmcarthur_work: I think that to convert between camelCase and underscores in a pretty way, human intervention is sometimes required. |
| 19:47:41 | <dino-> | > read "[1,2,3]" |
| 19:47:42 | <lambdabot> | * Exception: Prelude.read: no parse |
| 19:47:48 | <jmcarthur_work> | certainly to convert from underscores to camelCase |
| 19:47:53 | <dino-> | > read "[1,2,3]" :: [Int] |
| 19:47:54 | <Cale> | > read "[1,2,3]" :: [Integer] |
| 19:47:55 | <lambdabot> | [1,2,3] |
| 19:47:56 | <lambdabot> | [1,2,3] |
| 19:48:05 | <jmcarthur_work> | since mauke has already show that the former is strictly more expressive |
| 19:48:07 | <jmcarthur_work> | *shown |
| 19:48:27 | <Cale> | (and more typing ;) |
| 19:48:31 | <jmcarthur_work> | i think camelCase to underscore can be automated well enough though |
| 19:48:38 | <jmcarthur_work> | heck, i just did it |
| 19:48:50 | <ray> | aw heck |
| 19:49:01 | <jmcarthur_work> | darn it all to heck |
| 19:49:10 | <_Jordan_> | Is State both a type constructor (like Maybe) and a data constructor (like Just)? |
| 19:49:15 | <ray> | > read "fromList [1,2,3]" :: Set Integer |
| 19:49:16 | <lambdabot> | Not in scope: type constructor or class `Set' |
| 19:49:19 | <dino-> | I feel like the real struggle isn't camel/underscore, it's getting people to write good identifiers |
| 19:49:25 | <ray> | g;fjd;lsj;lfs |
| 19:49:25 | <Cale> | _Jordan_: yes |
| 19:49:37 | <jmcarthur_work> | ray, that is unfortunate |
| 19:49:39 | <ray> | that's a nice-looking read instance anyway |
| 19:50:00 | <_Jordan_> | Cale: Thanks. So what is "runState" then? |
| 19:50:02 | <Cale> | _Jordan_: There are two things called State in Control.Monad.State, one at the type level, and one at the value level. They're in different namespaces, so it doesn't hurt that they're named the same thing. |
| 19:50:02 | <jmcarthur_work> | dino-, agreed |
| 19:50:16 | <jmcarthur_work> | :t runState |
| 19:50:17 | <lambdabot> | forall s a. State s a -> s -> (a, s) |
| 19:50:21 | <Cale> | _Jordan_: runState is what you use to run a State monad computation with a given initial state. |
| 19:50:22 | <jmcarthur_work> | that's runState :) |
| 19:50:50 | <jmcarthur_work> | _Jordan_, if you are looking at the source for State, then runState is defined by using record syntax as a shortcut |
| 19:51:04 | <Cale> | Given a computation, and an initial state, it results in a pair consisting of the result and final state. |
| 19:51:19 | <_Jordan_> | alright, thanks |
| 19:51:27 | <_Jordan_> | Yeah, I was wondering why it was defined with record syntax |
| 19:51:31 | <ray> | the use of record syntax for defining runStuff certainly confused me for a while |
| 19:51:32 | <dino-> | Also, some of our conventions in the big H are excellent. Like *M and *_ as in mapM_ |
| 19:51:38 | <jmcarthur_work> | yeah, that's just a handy shortcut |
| 19:51:51 | <Cale> | _Jordan_: Simply because we're using a representation for State monad computations which allows that. |
| 19:51:55 | <jmcarthur_work> | and unsafe* |
| 19:52:03 | <ray> | then i converted it in my head to non-record-syntax, and it made sense |
| 19:52:22 | <Cale> | _Jordan_: (basically, we define a State monad computation internally to be the function which will result when you apply runState to it) |
| 19:52:41 | <Cale> | _Jordan_: If we were using a different implementation of the State monad, runState might be more complicated. |
| 19:52:56 | <_Jordan_> | ah, I see |
| 19:53:18 | <Baughn> | _Jordan_: (However, that's pretty much the most natural definition, and it's hard to think of alternatives) |
| 19:53:22 | <jmcarthur_work> | some of the CPS transformer libraries might have more complicated state monads |
| 19:53:25 | <dino-> | yes, unsafe* hm: partialHead = head |
| 19:53:56 | <jmcarthur_work> | dino-, i agree with you (maybe not on the actual prefix, but that there should be one) |
| 19:54:08 | <jmcarthur_work> | but many functions are partial |
| 19:54:12 | <Cale> | It's possible to define the State monad in a sort of dual way, using a GADT to represent the operations explicitly. |
| 19:54:50 | <Taejo> | has the web hoogle stopped including hackage packages in its results? |
| 19:54:56 | <Taejo> | @hoogle hmm |
| 19:54:56 | <lambdabot> | package hmm |
| 19:54:56 | <Cale> | (But GADTs are new to Haskell) |
| 19:55:03 | <jmcarthur_work> | Taejo, try hayoo? |
| 19:55:35 | <Cale> | Did anyone else go and implement that Hammurabi game after the blog post yesterday? :) |
| 19:55:48 | <Taejo> | jmcarthur_work: I don't mean indexing the *contents* of the package. I meant <lambdabot> package hmm |
| 19:55:59 | <jmcarthur_work> | ah |
| 19:56:23 | <Taejo> | Cale: I found BASIC code, but I don't think the basic package supports multiple statements per line |
| 19:56:30 | <edwardk> | hammurabi? |
| 19:56:40 | <Cale> | Taejo: I implemented the game in Haskell. |
| 19:56:45 | <jmcarthur_work> | the number guessing one? |
| 19:56:47 | <Cale> | http://playtechs.blogspot.com/2009/06/messing-with-haskell.html |
| 19:57:06 | <Cale> | It's not a number guessing game -- this guy mentioned the number guessing game though. |
| 19:57:10 | <jmcarthur_work> | yeah, i did it too, but it wasn't impressively shorter... only about 40% shorter. i was sure i could do better |
| 19:57:14 | <jmcarthur_work> | ah |
| 19:57:20 | <jmcarthur_work> | i forget it now |
| 19:57:48 | <jmcarthur_work> | well, i could have done better, but it would have been obfuscation |
| 19:58:02 | <jmcarthur_work> | i think a lot of other haskellers think i am a fan of obfuscation already |
| 19:58:10 | <Cale> | http://www.apollowebworks.com/russell/samples/hamurabi.html -- here's an implementation of the game he wanted to implement in Haskell. |
| 19:58:14 | <Taejo> | it's only a few hundred lines of basic, but I think it has quite high semantics-to-syntax ratio |
| 19:58:38 | <Cale> | Yeah, my Haskell implementation was still ~200 lines. |
| 19:59:13 | <harlekin> | In the pdf's version of Programming with Arrows there are no pictures but the captions suggest there should be some. Is it available in some other format containing the figures? |
| 19:59:18 | <Cale> | But I still feel unhappy about a bit of it. The I/O still isn't as separate as it could be |
| 20:00:00 | <Hunner> | Why do I get `read' is not a (visible) method of class `Read' |
| 20:00:12 | <Hunner> | when trying to define my own read for a data type? |
| 20:00:18 | <opqdonut> | because it aint |
| 20:00:25 | <opqdonut> | @info Read |
| 20:00:25 | <lambdabot> | Read |
| 20:00:25 | <jmcarthur_work> | Cale, ryan ingram always pushes his monadprompt stuff for separating IO from a stack, which seems to especially come up in games. i haven't tried it yet though |
| 20:00:30 | <opqdonut> | @src Read |
| 20:00:30 | <lambdabot> | class Read a where |
| 20:00:30 | <lambdabot> | readsPrec :: Int -> ReadS a |
| 20:00:30 | <lambdabot> | readList :: ReadS [a] |
| 20:00:30 | <lambdabot> | readPrec :: ReadPrec a |
| 20:00:30 | <lambdabot> | readListPrec :: ReadPrec [a] |
| 20:00:31 | <Gracenotes> | ..wha |
| 20:00:33 | <Cale> | http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5692#a5692 -- here's what I threw together, anyway :) |
| 20:00:45 | <Gracenotes> | oh, yes. "read" is a utility |
| 20:00:48 | <Cale> | jmcarthur_work: Yeah, the MonadPrompt way would be cool. I could have done that. |
| 20:00:51 | <Gracenotes> | @src read |
| 20:00:51 | <opqdonut> | Hunner: read is defined on top of readS |
| 20:00:51 | <lambdabot> | read s = either error id (readEither s) |
| 20:01:00 | <Gracenotes> | @src readEither |
| 20:01:01 | <lambdabot> | Source not found. You type like i drive. |
| 20:01:04 | <Gracenotes> | pssh. |
| 20:01:16 | <deech_> | Hi all, I am having some difficulty processing XML with the HXT library. I have an XML document with an "Items" root node that contains many "Item" node. I would like process each of these in turn and collect the results into a list. Is there a map-like function in HXT? |
| 20:01:27 | <Cale> | jmcarthur_work: I was actually just thinking about fixing up MonadPrompt to have decent Haddock documentation, and then implementing the MTL monads and maybe LogicT in terms of it. |
| 20:01:35 | <deech_> | The closest I could find was processChildren and I can't figure out how it works. |
| 20:01:51 | <jmcarthur_work> | woah mtl in terms of prompt? i didn't even think about that |
| 20:02:18 | <Cale> | The next step after that would be to benchmark it. |
| 20:02:25 | <jeffersonheard_h> | so.... would there be anyone out there interested in helping with the ongoing development of either Hieroglyph or Buster |
| 20:02:32 | <Gracenotes> | hm. it does seem to be defined in terms of readPrec, though ... and in terms of readPrec_to_S... |
| 20:02:40 | <Hunner> | okay, I'm not sure what to do with Read if I can't tell it how to read my string... |
| 20:02:41 | <Gracenotes> | gawsh, the Haskell Read system is complicated |
| 20:02:54 | <opqdonut> | Greit is |
| 20:03:04 | <Cale> | I might expect a little bit of a hit in performance for the extra abstraction it affords, but internally, MonadPrompt uses a continuation passing style which I can imagine compiling to fairly efficient code, so I don't know. |
| 20:03:17 | <opqdonut> | Hunner: http://haskell.org/ghc/docs/latest/html/libraries/base/Text-Read.html#t%3ARead <- read it up |
| 20:03:22 | <Hunner> | Thanks |
| 20:03:25 | <jmcarthur_work> | yeah that would be interesting to find out |
| 20:03:38 | <opqdonut> | Hunner: "Minimal complete definition: readsPrec" is the most important part |
| 20:04:01 | <opqdonut> | Hunner: you can basically ignore the Int parameter to readsPrec for simple stuff |
| 20:04:11 | <jmcarthur_work> | wouldn't there be a lot of GADT going on to implement mtl in terms of prompt though? i can't imagine that would be free of overhead |
| 20:04:13 | <jeffersonheard_h> | oh, and I've got a question about cabal: do you put stuff you need to be compiled and linked in, but not exposed in "extra source modules" |
| 20:04:26 | <jeffersonheard_h> | source files, whatever |
| 20:04:30 | <Cale> | jmcarthur_work: Well, there would be one GADT for each set of operations. |
| 20:04:33 | <Baughn> | jeffersonheard_h: Yes |
| 20:04:47 | <jeffersonheard_h> | Baughn, thanks |
| 20:04:59 | <jmcarthur_work> | prompt essentially requires an interpreter |
| 20:05:29 | <Cale> | jmcarthur_work: Yeah, representing operations as data is the part I thought might be expensive. |
| 20:05:45 | <Cale> | The nice thing about it is that you can have multiple intepreters for the same computations then. |
| 20:06:01 | <jmcarthur_work> | yeah |
| 20:06:08 | <jmcarthur_work> | would be awesome |
| 20:06:28 | <Cale> | And in fact, that's how the lifter from Prompt to PromptT works :) |
| 20:06:45 | <Taejo> | was base-4 the first split up one? or base-3? |
| 20:06:58 | <Taejo> | and what's a reasonable version range of container to depend on? |
| 20:07:00 | <Cale> | (just run the computations with an interpreter that reapplies the prompt for PromptT to each primitive :) |
| 20:07:39 | <Cale> | Taejo: I believe it started with 3 |
| 20:08:21 | <Cale> | Taejo: I'm not sure... there really ought to be a wiki page somewhere with a big table of the version numbers of packages that come with various GHCs... |
| 20:08:25 | <jmcarthur_work> | Cale, do you think the MonadPrompt approach to MTL would basically replace the need for the MTL type classes, like MonadState, etc.? |
| 20:08:26 | <Cale> | (but I don't think there is :) |
| 20:08:45 | <jmcarthur_work> | since you can interpret the ops differently "on the outside" |
| 20:08:59 | <Taejo> | Cale: indeed. I guess I'll just guess, until somebody tells me my program doesn't compile somewhere |
| 20:09:11 | <Cale> | jmcarthur_work: Sort of, though you still will want a way to combine sets of operations and a corresponding way to combine interpreters for those. |
| 20:09:42 | <jmcarthur_work> | yeah |
| 20:09:46 | <jmcarthur_work> | it's just different |
| 20:10:15 | <Cale> | I think I'll hack up a bit right now and see how it goes. |
| 20:10:20 | <jmcarthur_work> | sweet |
| 20:11:30 | <Baughn> | @type (>>=) |
| 20:11:31 | <lambdabot> | forall (m :: * -> *) a b. (Monad m) => m a -> (a -> m b) -> m b |
| 20:11:48 | <jmcarthur_work> | =<< > >>= |
| 20:12:03 | <Yokisho> | @type mapM_ |
| 20:12:04 | <lambdabot> | forall a (m :: * -> *) b. (Monad m) => (a -> m b) -> [a] -> m () |
| 20:12:29 | <sneep> | Hi everyone, I'm experiencing a (probably really simple) problem... I was trying to write a function in Haskell that gets two arguments and tests if the first arg equals the first element of the second argument (which is a list) |
| 20:12:34 | <Taejo> | why does containers-0.1.0.1 not satisfy container >=0.1 && <0.3 |
| 20:12:43 | <sneep> | My code (along with the error message I get) is here: http://pastebin.com/d619cfbd4 |
| 20:13:19 | <Cale> | sneep: The problem is that you use == which isn't defined for any type a |
| 20:13:30 | <Cale> | sneep: Only for types a which are instances of the class Eq |
| 20:13:46 | <Cale> | sneep: So you want firsteq :: Eq a => a -> [a] -> Bool |
| 20:14:19 | <Cale> | sneep: Another way to discover this is to comment out your type signature and ask hugs for what it infers |
| 20:14:22 | <Cale> | :t firsteq |
| 20:14:24 | <lambdabot> | Not in scope: `firsteq' |
| 20:14:34 | <sneep> | Thanks, works now :D |
| 20:14:48 | <Taejo> | d'oh, "container" /= "containers" |
| 20:15:37 | <Yokisho> | ehms, functions overloaded? |
| 20:16:04 | <opqdonut> | Yokisho: ? |
| 20:16:19 | <sinelaw> | "Microsoft SQL Server 2008 and the Data Platform: Your Data, Any Place, Any Time" |
| 20:16:23 | <FliPPeh> | Say I have a number, from 1 - 31, say it's a month, how would I append a zero in front of it, if it's below 10? 01, 02, 04, 10, ... |
| 20:16:25 | <sinelaw> | heh, truly. |
| 20:16:33 | <sinelaw> | YOUR data, any place, any time :) |
| 20:16:35 | <dino-> | sneep: I might also replace some of your bindings with _ |
| 20:16:46 | <Yokisho> | opqdonut, http://pastebin.com/d619cfbd4 |
| 20:16:52 | <sneep> | Is _ in Haskell like _ in Prolog? |
| 20:17:03 | <sneep> | (Anonymous variable) |
| 20:17:06 | <Yokisho> | there are functions overloaded :S |
| 20:17:11 | <sneep> | (Matches everything) |
| 20:17:18 | <Cale> | sneep: _ is a pattern which matches anything and binds no variable |
| 20:17:26 | <sneep> | If that thing about overloading was directed at me, I had the two functions in different files before... Forgot to rename them before submitting |
| 20:17:30 | <sneep> | Ah, okay |
| 20:17:37 | <sneep> | In Prolog it's the same :P |
| 20:17:57 | <opqdonut> | Yokisho: the type of firsteq needs to be "Eq a => a -> [a] -> Bool" |
| 20:18:00 | <dino-> | I don't know Prolog. Does it have pattern matching? |
| 20:18:03 | <opqdonut> | Yokisho: like Calse said |
| 20:18:06 | <opqdonut> | dino-: yes |
| 20:18:34 | <Yokisho> | ahms, oops, sorry |
| 20:18:35 | <omer> | its a programmers chat right? |
| 20:19:09 | <Cale> | 。。。 |
| 20:19:28 | <Cale> | What is with these people who show up for 10 seconds and leave? :) |
| 20:19:42 | <FliPPeh> | Dunno |
| 20:19:55 | <FliPPeh> | So how do I smartly prepend numbers under 10 with one zero? |
| 20:20:39 | <tromp> | > 0: show 6 |
| 20:20:40 | <lambdabot> | No instance for (GHC.Num.Num GHC.Types.Char) |
| 20:20:40 | <lambdabot> | arising from the literal `0... |
| 20:20:45 | <tromp> | > '0': show 6 |
| 20:20:46 | <lambdabot> | "06" |
| 20:21:04 | <opqdonut> | there's printf for haskell but it isn't type safe |
| 20:21:10 | <dino-> | tromp: Oh that's clever. I would have reached immediately for printf, yeah |
| 20:21:18 | <Cale> | > printf "%2d" 6 |
| 20:21:20 | <lambdabot> | Add a type signature |
| 20:21:22 | <Cale> | > printf "%2d" 6 :: String |
| 20:21:24 | <lambdabot> | " 6" |
| 20:21:28 | <Cale> | > printf "%02d" 6 :: String |
| 20:21:29 | <lambdabot> | "06" |
| 20:21:46 | <pastorn> | > printf "%02d" 12 :: String |
| 20:21:47 | <lambdabot> | "12" |
| 20:21:51 | <pastorn> | cool :) |
| 20:22:01 | <Cale> | printf is pure evil though ;) |
| 20:22:11 | <dino-> | We have that new TotalPrintf |
| 20:22:11 | <pastorn> | Cale: howcome? |
| 20:22:22 | <dino-> | from Oleg |
| 20:22:24 | <Yokisho> | under 10 pastorn :P |
| 20:22:35 | <byorgey> | dino-: tromp's code doesn't work for things over 9 though. |
| 20:22:51 | <Cale> | pastorn: It doesn't check until runtime that the arbitrarily many arguments you've given it are the right types. |
| 20:22:53 | <pastorn> | Yokisho: i just wanted to test that it didn' prepend the '0' if the number was > 10 :p |
| 20:23:04 | <dino-> | byorgey: yes, but it's clever for that small set of numbers! |
| 20:23:11 | <Cale> | pastorn: (by design, it couldn't possibly do so) |
| 20:23:11 | <byorgey> | true =) |
| 20:23:27 | <Cale> | Also, the format strings are arcane and convoluted. |
| 20:23:29 | <pastorn> | Cale: how do you give a function an arbitrary amount of arguments? |
| 20:23:45 | <Cale> | pastorn: By having its type be in a typeclass which includes function types as an instance. |
| 20:24:10 | <pastorn> | so THAT'S how you do that |
| 20:24:21 | <dino-> | ah, here it is: http://article.gmane.org/gmane.comp.lang.haskell.general/17251 |
| 20:24:27 | <Cale> | http://www.haskell.org/ghc/docs/latest/html/libraries/base/Text-Printf.html |
| 20:24:28 | <dino-> | TotalPrintF |
| 20:24:39 | <Cale> | You can see how the trick works there |
| 20:24:41 | <mauke> | Text.Printf is actually completely H98 :-) |
| 20:24:45 | <pastorn> | i had been thinking about doing a weird type class some weeks ago, but i had a deadline and din't bother to put my brain through that |
| 20:24:48 | <Cale> | class PrintfType t |
| 20:24:55 | <Cale> | IsChar c => PrintfType ([] c) |
| 20:24:55 | <Cale> | PrintfType (IO a) |
| 20:24:55 | <Cale> | (PrintfArg a, PrintfType r) => PrintfType (a -> r) |
| 20:24:56 | <Taejo> | I just installed a package with the wrong name, how do I remove it (or rename it)? |
| 20:25:05 | <jmcarthur_work> | Cale, well, it could do so with a dependently typed language of course, just not in haskell |
| 20:25:10 | <jmcarthur_work> | type check, that is |
| 20:25:14 | <mauke> | (the format strings are extremely convenient if you already know printf) |
| 20:25:25 | <byorgey> | Taejo: ghc-pkg unregister ? |
| 20:25:38 | <Cale> | jmcarthur_work: Not without changing the meaning of the thing. |
| 20:25:56 | <jmcarthur_work> | what do you mean changing the meaning? |
| 20:26:07 | <Cale> | jmcarthur_work: The thing about printf is that by design, the format string is a value given at runtime. |
| 20:26:27 | <Cale> | jmcarthur_work: So there's no way to statically check that it's correct. |
| 20:26:31 | <Cale> | (in general) |
| 20:26:48 | <jmcarthur_work> | still could be checked in many cases. would just require horrible proofs |
| 20:26:58 | <FliPPeh> | preZero i |
| 20:26:58 | <FliPPeh> | | i > 9 = show i |
| 20:26:58 | <FliPPeh> | | otherwise = '0': (show i) |
| 20:26:59 | <FliPPeh> | :) |
| 20:27:13 | <Cale> | preZero (-1) |
| 20:27:20 | <FliPPeh> | Bam |
| 20:27:23 | <FliPPeh> | You just broke my program |
| 20:27:27 | <FliPPeh> | I hope you're happy :( |
| 20:27:42 | <Yokisho> | @type SqlValue |
| 20:27:43 | <lambdabot> | Not in scope: data constructor `SqlValue' |
| 20:28:02 | <byorgey> | | i < 0 = error "I HOPE YOU'RE HAPPY CALE" |
| 20:28:07 | <Cale> | haha |
| 20:30:12 | <olsner> | @paste |
| 20:30:12 | <lambdabot> | Haskell pastebin: http://hpaste.org/new |
| 20:30:18 | <Baughn> | conal: Is the Monoid instance for events diagonalizing mappend? |
| 20:35:41 | <pedro-kun> | hi there |
| 20:36:10 | <pedro-kun> | how can i make haskell programs properly display accented characters? |
| 20:36:22 | <mauke> | define "properly" |
| 20:36:31 | <mauke> | also, what's your environment? |
| 20:36:38 | <pedro-kun> | the way it is now, i just get squares |
| 20:36:45 | <pedro-kun> | define environment, please :) |
| 20:36:48 | <jmcarthur_work> | Baughn, it merges the event streams by time |
| 20:36:53 | <mauke> | where do you get squares? |
| 20:37:10 | <Baughn> | jmcarthur_work: Yes, I got that |
| 20:37:17 | <pedro-kun> | mauke: i do something like putStrLn "lalalala" |
| 20:37:20 | <pedro-kun> | oops |
| 20:37:24 | <pedro-kun> | "laáááá" |
| 20:37:35 | <pedro-kun> | and I get "la" followed by 4 rectangles |
| 20:37:40 | <mauke> | yes |
| 20:37:45 | <Baughn> | jmcarthur_work: I'm wondering why, when I stick a trace-show on the event being joined in joinE (which calls mappend), I get them in diagonal order. Well, it makes sense though. |
| 20:37:47 | <jmcarthur_work> | ah, i assumed that "diagonalizing" meant that it was more of a lifted mappend |
| 20:37:52 | <mauke> | pedro-kun: where do you get them? |
| 20:38:39 | <pedro-kun> | sorry, i don't understand... what do you mean by where? console output? |
| 20:38:56 | <mauke> | pedro-kun: using my psychic debugging skills, you're seeing them in a terminal emulator that expects UTF-8 |
| 20:38:56 | <Baughn> | jmcarthur_work: Nope, I'm debugging joinE. It likes giving me bottoms instead of a maxBound when the event ends, which /ought/ to be a simple fix.. well, once I understand it anyhow. |
| 20:39:14 | <Baughn> | jmcarthur_work: Had to detour for some days to fix a ghc bug first. (Well, wound up working around it..) |
| 20:39:14 | <pedro-kun> | hmm, probably mauke |
| 20:40:05 | <mauke> | pedro-kun: putStrLn is actually broken; it just truncates characters at 8 bits and then treats them as raw bytes |
| 20:40:13 | <Baughn> | jmcarthur_work: I _will_ get reactive working, so I can learn to use reactive, so I can write my map editor, so I can play a game! *burning eyes* |
| 20:40:36 | <mauke> | which is fine for ASCII and happens to work for Latin-1, but isn't going to work for UTF-8 |
| 20:40:39 | <jmcarthur_work> | Baughn, heh. i've been playing with reactive-style frp implementations for a while. it is tricky! |
| 20:40:50 | <pedro-kun> | so, what do you recommend? :) |
| 20:41:12 | <mauke> | http://hackage.haskell.org/packages/archive/utf8-string/0.3.5/doc/html/System-IO-UTF8.html |
| 20:41:24 | <pedro-kun> | hmm |
| 20:41:27 | <pedro-kun> | i'll go see :) |
| 20:41:29 | <pedro-kun> | thanks |
| 20:42:59 | <mauke> | the other places you could have seen squares: linux system console (no GUI), printing to a file and looking at it in some text editor, sending html to a browser from a web application, or using some GUI toolkit to draw your own text |
| 20:43:25 | <pedro-kun> | oh, right |
| 20:43:36 | <pedro-kun> | thanks for that, next time i'll know what to answer |
| 20:43:41 | <mauke> | :-) |
| 20:44:14 | <pedro-kun> | so, besides using utf8-string, i could just format the source code using latin1 and it would work too, right? |
| 20:44:27 | <mauke> | no |
| 20:44:41 | <pedro-kun> | why wouldn't it? |
| 20:44:58 | <mauke> | why would it? |
| 20:45:05 | <Taejo> | how do I tell Cabal I want a README file to be included in the cabal sdist? |
| 20:45:07 | <mauke> | haskell strings are unicode |
| 20:45:30 | <mauke> | your source representation of strings has to be turned into actual data; this is done by the compiler |
| 20:45:31 | <Saizan_> | Taejo: extra-source-files |
| 20:45:42 | <mauke> | ghc understands utf-8, so that part worked fine |
| 20:46:04 | <mauke> | using latin-1 will either cause a decoding error or give the same result |
| 20:46:33 | <mauke> | the problem is in the IO libraries, which don't properly encode the unicode strings before writing them out |
| 20:47:15 | <pedro-kun> | oh, i see |
| 20:47:26 | <pedro-kun> | i tried utf8-string now and it seems to work :) |
| 20:47:28 | <pedro-kun> | thanks |
| 20:48:42 | <pedro-kun> | i'm kinda new in haskell so i tend to have these strange doubts :p |
| 20:48:48 | <pedro-kun> | *new to haskell |
| 20:49:37 | <pedro-kun> | is there any way to have utf8-string's functions "replace" the standard ones? |
| 20:49:55 | <pedro-kun> | or do i have to use them in a qualified form everytime? |
| 20:50:04 | <pedro-kun> | (sorry if i'm making no sense at all) |
| 20:50:15 | <FliPPeh> | I can't find any way to remove certain items from a list :S |
| 20:50:19 | <Saizan_> | you can hide the standard ones |
| 20:50:23 | <FliPPeh> | I think I'm stupid |
| 20:50:27 | <Baughn> | ACTION wishes there was a way to automatically add Show restrictions to type annotations |
| 20:50:29 | <pedro-kun> | Saizan_: how do i do that? |
| 20:50:40 | <pedro-kun> | import the prelude hiding them? |
| 20:50:45 | <Saizan_> | yes |
| 20:51:05 | <ClaudiusMaximus> | :t delete |
| 20:51:06 | <lambdabot> | forall a. (Eq a) => a -> [a] -> [a] |
| 20:51:54 | <pedro-kun> | Saizan_: thanks, it worked |
| 20:51:56 | <pedro-kun> | :) |
| 20:51:56 | <Nereid_> | FliPPeh: filter? |
| 20:52:32 | <FliPPeh> | Filter works, too :) |
| 20:52:51 | <Nereid_> | I guess delete x is the same as filter (/=x) |
| 20:53:05 | <ClaudiusMaximus> | > delete 3 [1,1,2,2,3,3,4,4,5,5] |
| 20:53:06 | <lambdabot> | [1,1,2,2,3,4,4,5,5] |
| 20:53:12 | <Nereid_> | nope |
| 20:53:15 | <Nereid_> | only removes the first one |
| 20:53:28 | <Nereid_> | filter (/=3) [1,1,2,2,3,3,4,4,5,5] |
| 20:53:30 | <Nereid_> | > filter (/=3) [1,1,2,2,3,3,4,4,5,5] |
| 20:53:31 | <lambdabot> | [1,1,2,2,4,4,5,5] |
| 20:54:00 | <Nereid_> | depends on which behaviour you want I guess |
| 20:55:09 | <ClaudiusMaximus> | > deleteBy ((1==) . fst) [(1,"a"),(1,"b")] |
| 20:55:10 | <lambdabot> | Couldn't match expected type `(a, b) -> GHC.Bool.Bool' |
| 20:55:38 | <Cale> | hmmmm |
| 20:55:42 | <ClaudiusMaximus> | :t deleteBy |
| 20:55:43 | <lambdabot> | forall a. (a -> a -> Bool) -> a -> [a] -> [a] |
| 20:55:49 | <Cale> | I wonder if the lack of a RecPromptT is a fundamental limitation. |
| 20:56:01 | <Yokisho> | :i Int |
| 20:56:11 | <ClaudiusMaximus> | > deleteBy (comparing fst) (1,undefined) [(1,"a"),(1,"b")] |
| 20:56:12 | <lambdabot> | Couldn't match expected type `GHC.Bool.Bool' |
| 20:56:15 | <Yokisho> | O_o |
| 20:56:19 | <ClaudiusMaximus> | doh |
| 20:56:31 | <mauke> | > deleteBy ((==) `on` fst) (1,undefined) [(1,"a"),(1,"b")] |
| 20:56:32 | <lambdabot> | [(1,"b")] |
| 20:56:49 | <Taejo> | how do I put quotes into a Cabal Description file? 'quoted text' gets turned into monospace |
| 20:56:58 | <mauke> | \' |
| 20:57:07 | <Taejo> | thank |
| 20:57:13 | <Taejo> | *thanks, mauke |
| 20:57:35 | <mauke> | (it's haddock markup) |
| 20:57:57 | <Taejo> | ok |
| 20:59:35 | <Nereid_> | :t comparing |
| 20:59:36 | <lambdabot> | forall b a. (Ord a) => (b -> a) -> b -> b -> Ordering |
| 20:59:41 | <Nereid_> | lol |
| 21:00:29 | <malouin> | @source Plus |
| 21:00:29 | <lambdabot> | Plus not available |
| 21:00:55 | <malouin> | @source Eq |
| 21:00:55 | <lambdabot> | Eq not available |
| 21:00:59 | <Cale> | @src Eq |
| 21:01:00 | <lambdabot> | class Eq a where |
| 21:01:00 | <lambdabot> | (==), (/=) :: a -> a -> Bool |
| 21:01:09 | <malouin> | thanks Cale |
| 21:01:11 | <Cale> | @source Prelude |
| 21:01:11 | <lambdabot> | http://darcs.haskell.org/packages/base/Prelude.hs |
| 21:01:15 | <malouin> | @src Plus |
| 21:01:15 | <lambdabot> | Source not found. My pet ferret can type better than you! |
| 21:01:32 | <Cale> | What's Plus? |
| 21:01:42 | <malouin> | that's what I'm trying to figure out. It's a class. |
| 21:01:44 | <malouin> | that's all I know. |
| 21:01:52 | <malouin> | ran into it in some Formlets code |
| 21:02:11 | <jeff_s_> | @src otherwise |
| 21:02:12 | <lambdabot> | otherwise = True |
| 21:02:18 | <jeff_s_> | oh, heh |
| 21:02:19 | <byorgey> | maybe it's for doing type-level addition? |
| 21:02:21 | <Nereid_> | there's no Plus in hoogle |
| 21:02:21 | <byorgey> | malouin: link? |
| 21:02:32 | <malouin> | http://chrisdone.com/blog/html/2008-12-14-haskell-formlets-composable-web-form-construction-and-validation.html |
| 21:02:51 | <malouin> | label :: (X.HTML xml, Monad m, Plus xml) => String -> Form xml m a -> Form Html m a |
| 21:03:42 | <Nereid_> | I'm guessing you should replace Plus with Monoid |
| 21:03:49 | <malouin> | yay, it's HaXmL |
| 21:04:04 | <Nereid_> | the source doesn't mention Plus, but it does show Monoid in that context |
| 21:04:08 | <malouin> | or maybe I spoke to soon |
| 21:04:40 | <Cale> | I think it's from the XML library |
| 21:04:52 | <Nereid_> | malouin: if you look at the source, you will see |
| 21:05:00 | <Nereid_> | label :: (X.HTML xml, Monad m,Monoid xml) => String -> Form xml m a -> Form Html m a |
| 21:05:03 | <Cale> | xhtml rather |
| 21:05:34 | <Cale> | hmm |
| 21:05:49 | <malouin> | ok, s/Plus/Monoid/ seems to do what I want. |
| 21:06:00 | <malouin> | Nereid_: what source particularly? |
| 21:06:21 | <Cale> | Ah, there's a link to it |
| 21:06:24 | <Cale> | http://chrisdone.com/blog/haskell/Main.hs |
| 21:06:26 | <byorgey> | I can't seem to find Plus in xhtml, or any other xml library for that matter |
| 21:06:38 | <Cale> | byorgey: Yeah, I didn't find it either. |
| 21:06:59 | <malouin> | Nereid_: Nereid the polychaete ;) |
| 21:07:03 | <byorgey> | oh, that file you linked to uses Monoid |
| 21:07:06 | <malouin> | err ?;) |
| 21:07:09 | <Cale> | yeah |
| 21:07:12 | <byorgey> | that must be what it is |
| 21:07:26 | <byorgey> | ah, Nereid_ was right all along =) |
| 21:07:47 | <malouin> | ok, thank you all. |
| 21:07:53 | <Nereid_> | :-) |
| 21:08:21 | <malouin> | unary ++ needs to be distributive ( Nereid_ , byorgey , Cale )++ |
| 21:08:40 | <Cale> | @karma ) |
| 21:08:40 | <lambdabot> | ) has a karma of 3 |
| 21:08:50 | <malouin> | ha |
| 21:09:53 | <Nereid_> | :) |
| 21:10:00 | <roconnor> | @karma ] |
| 21:10:01 | <lambdabot> | ] has a karma of 0 |
| 21:10:03 | <lunabot> | luna: parse error on input `of' |
| 21:10:08 | <Nereid_> | lol |
| 21:10:15 | <roconnor> | > [ 7 ]++ [ 8 ] |
| 21:10:16 | <lambdabot> | [7,8] |
| 21:10:19 | <roconnor> | @karma ] |
| 21:10:19 | <lambdabot> | ] has a karma of 1 |
| 21:10:20 | <lunabot> | luna: parse error on input `of' |
| 21:10:22 | <Nereid_> | :-) |
| 21:10:28 | <malouin> | > map (++ "++") [" Nereid_", " Cale", " byorgey"] |
| 21:10:29 | <lambdabot> | [" Nereid_++"," Cale++"," byorgey++"] |
| 21:10:45 | <Nereid_> | I don't think that works |
| 21:10:56 | <Nereid_> | maybe want "++ " instead of "++" |
| 21:10:57 | <malouin> | lambdabot doesn't read its own output for karma? |
| 21:11:00 | <Cale> | Yeah, lambdabot doesn't parse its own output |
| 21:11:01 | <ray> | you need to make some other bot say it |
| 21:11:11 | <Nereid_> | how does lunabot work? :) |
| 21:11:12 | <roconnor> | , map (++ "++") [" Nereid_", " Cale", " byorgey"] |
| 21:11:13 | <lunabot> | [" Nereid_++"," Cale++"," byorgey++"] |
| 21:11:24 | <pumpkin> | @karma Cale |
| 21:11:25 | <lambdabot> | Cale has a karma of 16 |
| 21:11:27 | <pumpkin> | oh my |
| 21:11:34 | <Nereid_> | ah |
| 21:11:35 | <skorpan> | @karma skorpan |
| 21:11:36 | <lambdabot> | You have a karma of 1 |
| 21:11:38 | <skorpan> | skorpan++ |
| 21:11:39 | <skorpan> | @karma skorpan |
| 21:11:39 | <lambdabot> | You have a karma of 1 |
| 21:11:41 | <Nereid_> | lol |
| 21:11:43 | <pumpkin> | @karma |
| 21:11:43 | <skorpan> | fuuuuuuuu... |
| 21:11:43 | <lambdabot> | You have a karma of 6 |
| 21:11:47 | <Nereid_> | @karma |
| 21:11:47 | <lambdabot> | You have a karma of 0 |
| 21:11:52 | <Nereid_> | indeed, so |
| 21:12:00 | <Nereid_> | , map (++ "++ ") [" Nereid_", " Cale", " byorgey"] |
| 21:12:01 | <lunabot> | [" Nereid_++ "," Cale++ "," byorgey++ "] |
| 21:12:06 | <Cale> | I think the karma information has gotten reset a couple of times. |
| 21:12:08 | <ray> | shouldn't it subtract one from you if you increment yourself? |
| 21:12:09 | <Nereid_> | @karma |
| 21:12:10 | <lambdabot> | You have a karma of 1 |
| 21:12:13 | <Nereid_> | lol |
| 21:12:13 | <Cale> | @karma |
| 21:12:14 | <lambdabot> | You have a karma of 17 |
| 21:12:23 | <Nereid_> | so yeah you need the space after ++ |
| 21:12:25 | <skorpan> | hey let's make a deal i give you karma, you give me karma |
| 21:12:31 | <Lemmih> | , map (++ "++ ") (repeat " Lemmih") |
| 21:12:32 | <lunabot> | [" Lemmih++ "," Lemmih++ "," Lemmih++ "," Lemmih++ "," Lemmih++ "," Lemmi... |
| 21:12:34 | <Cale> | @karma dons |
| 21:12:34 | <lambdabot> | dons has a karma of 9 |
| 21:12:37 | <Cale> | heh |
| 21:12:44 | <pumpkin> | zomg Lemmih is a karmawhore |
| 21:12:45 | <Cale> | Definitely has been reset |
| 21:12:46 | <Lemmih> | ?karma |
| 21:12:47 | <lambdabot> | You have a karma of 12 |
| 21:12:47 | <FliPPeh> | How can I return some value out of the Maybe monad? I've got Just "String" and I want just.. the string! |
| 21:12:54 | <FliPPeh> | Any pre-made function? |
| 21:12:54 | <Lemmih> | Kewl. |
| 21:12:57 | <skorpan> | FliPPeh: pattern matching |
| 21:13:00 | <skorpan> | FliPPeh: fromJust |
| 21:13:01 | <pumpkin> | FliPPeh: fromMaybe/fromJust |
| 21:13:04 | <byorgey> | FliPPeh: maybe, fromMaybe, fromJust |
| 21:13:04 | <Cale> | FliPPeh: case |
| 21:13:11 | <pumpkin> | FliPPeh: or the maybe function |
| 21:13:14 | <malouin> | Lemmih: thanks for your response to my email the other day. |
| 21:13:14 | <ray> | do what cale says |
| 21:13:15 | <Nereid_> | depends on whether you care about the Nothing or not |
| 21:13:17 | <skorpan> | maybe doesn't really give you the value though |
| 21:13:20 | <Cale> | case foo of Nothing -> ... ; Just x -> ... |
| 21:13:49 | <skorpan> | hm |
| 21:13:59 | <skorpan> | maybe "lol" id (Just "hey") |
| 21:14:01 | <skorpan> | > maybe "lol" id (Just "hey") |
| 21:14:02 | <lambdabot> | "hey" |
| 21:14:05 | <FliPPeh> | Caseis no option |
| 21:14:06 | <malouin> | Lemmih: I decided not to use berkeleydb because I had many concurrent processes accessing the database and I wasn't sure how it was going to work. |
| 21:14:12 | <FliPPeh> | Case is no option |
| 21:14:12 | <Nereid_> | > fromMaybe "lol" (Just "hey") |
| 21:14:13 | <lambdabot> | "hey" |
| 21:14:13 | <Cale> | FliPPeh: Why not? |
| 21:14:17 | <Nereid_> | > fromMaybe "lol" Nothing |
| 21:14:17 | <FliPPeh> | It has to be inline |
| 21:14:19 | <lambdabot> | "lol" |
| 21:14:25 | <Cale> | FliPPeh: case is an expression form :) |
| 21:14:31 | <skorpan> | FliPPeh: as Cale showed you, "case" can be "inline" |
| 21:14:36 | <FliPPeh> | sendLine $ "NOTICE " ++ fromJust (getNick (getUserDetails from)) |
| 21:14:38 | <Lemmih> | malouin: Right, that might make things "interesting". |
| 21:14:44 | <Nereid_> | > case (Just "hey") of Nothing -> "lol"; Just x -> x |
| 21:14:45 | <lambdabot> | "hey" |
| 21:15:11 | <malouin> | Lemmih: So I implemented a key/value pair schema on top of hdbc/sqlite, as ugly as that is :) |
| 21:15:12 | <skorpan> | maybe is one of those "two-way monads" that i read about, but what monad was the other one? |
| 21:15:18 | <jeff_s_> | ACTION sees a semicolon and collapses |
| 21:15:18 | <Cale> | FliPPeh: Your bot will die if getNick ever returns Nothing |
| 21:15:20 | <Nereid_> | skorpan: Either |
| 21:15:24 | <ray> | maybe isn't really two way |
| 21:15:28 | <Baughn> | conal: So I managed to trigger another GHC bug, apparently. |
| 21:15:32 | <ClaudiusMaximus> | > case (lookup "foo" [("foo, "bar")]) of Just x -> x |
| 21:15:32 | <lambdabot> | <no location info>: |
| 21:15:33 | <lambdabot> | lexical error in string/character literal at end o... |
| 21:15:34 | <skorpan> | ray: why not? |
| 21:15:42 | <ray> | nothing |
| 21:15:44 | <Cale> | > fromJust Nothing |
| 21:15:46 | <lambdabot> | * Exception: Maybe.fromJust: Nothing |
| 21:15:46 | <FliPPeh> | Meh |
| 21:15:50 | <FliPPeh> | Okay okay |
| 21:15:54 | <FliPPeh> | Inline case :) |
| 21:16:00 | <ClaudiusMaximus> | oops |
| 21:16:04 | <Cale> | Or you could use fromMaybe |
| 21:16:04 | <skorpan> | ray: what about it? |
| 21:16:05 | <Cale> | or maybe |
| 21:16:10 | <dschoepe> | Is there a reason HasTrie from memo-trie lacks a Char instance, or has it just been overlooked? |
| 21:16:17 | <Nereid_> | FliPPeh: case getNick (getUserDetails from) of Nothing -> return (); Just x -> sendLine $ "NOTICE " ++ x |
| 21:16:21 | <sjanssen> | dschoepe: overlooked, probably |
| 21:16:21 | <skorpan> | ray: what i mean by two-way is that you can actually "get out of it", without unsafe stuff |
| 21:16:31 | <FliPPeh> | "PING":what:_ -> sendLine $ "NOTICE " ++ case (getNick (getUserDetails from)) of Nothing -> "null"; Just x -> x ++ " :\SOHPING " ++ what ++ "\SOH" |
| 21:16:33 | <Nereid_> | then it will do nothing if you get Nothing |
| 21:16:35 | <Baughn> | conal: But for what I've figured out so far: merge (in PrimReactive.hs) seems to have trouble when *both* events are not going to happen, which is why joinE ends up throwing an exception instead of capping the generated Event. Comments? |
| 21:16:45 | <ray> | and you can't get anything from Nothing |
| 21:16:47 | <skorpan> | hm, i think i'm talking out of my ass |
| 21:16:51 | <ray> | except bottom |
| 21:16:55 | <Nereid_> | or |
| 21:16:56 | <Nereid_> | better |
| 21:16:59 | <dschoepe> | sjanssen: Okay, thanks. |
| 21:17:00 | <Cale> | FliPPeh: You probably don't want to sendLine unless it is Just x |
| 21:17:33 | <Nereid_> | maybe (return ()) (\x -> sendLine $ "NOTICE " ++ x) (getNick (getUserDetails from)) |
| 21:17:36 | <Nereid_> | I dunno |
| 21:17:48 | <Cale> | yeah |
| 21:18:28 | <Cale> | case getNick (getUserDetails from) of |
| 21:18:31 | <Cale> | Nothing -> return () |
| 21:19:20 | <Cale> | Just x -> sendLine . concat $ ["NOTICE ", x, " :\SOHPING ", what, "\SOH"] |
| 21:19:29 | <pumpkin> | @quote BONUS If we think of a list as a monster, here's what's what. |
| 21:19:30 | <lambdabot> | No quotes for this person. There are some things that I just don't know. |
| 21:19:37 | <pumpkin> | @remember BONUS If we think of a list as a monster, here's what's what. |
| 21:19:37 | <lambdabot> | I will remember. |
| 21:20:17 | <Cale> | That is the best diagram ever. |
| 21:20:47 | <Cale> | http://learnyouahaskell.com/listmonster.png |
| 21:20:57 | <pumpkin> | I love it |
| 21:21:11 | <pumpkin> | @quote monster |
| 21:21:12 | <lambdabot> | dcoutts says: (:[]) looks like a monster |
| 21:21:17 | <ClaudiusMaximus> | transparency fail :( |
| 21:21:29 | <Cale> | transparency? |
| 21:21:43 | <ClaudiusMaximus> | yes. my default browser background is not white |
| 21:21:46 | <Cale> | ah |
| 21:21:54 | <pumpkin> | zomg why not |
| 21:22:47 | <Cale> | Yeah, given that it's a png, it could have made better use of the alpha channel |
| 21:23:13 | <pumpkin> | I bet he did it on purpose to prevent people from reusing his graphics on sites with ugly backgrounds! |
| 21:23:31 | <Cale> | It looks like it would if it was converted from a gif |
| 21:24:10 | <Berengal> | Mmm, lists... |
| 21:24:41 | <Nereid_> | I eat list monsters for breakfast |
| 21:24:55 | <Berengal> | list monsters eat lists for breakfast |
| 21:25:06 | <Berengal> | I wonder what lists eat for breakfast... |
| 21:25:11 | <Botje> | .. other lists! |
| 21:25:24 | <Botje> | and i still want a poster-sized version of that drawing |
| 21:25:26 | <Nereid_> | I guess a list of type [a] would eat things of type a for breakfast |
| 21:25:30 | <skorpan> | yeah, the mouth is located at the head of the list, which consumes other lists |
| 21:25:31 | <Botje> | .. or maybe just a tshirt |
| 21:25:39 | <Botje> | a tshirt would be awesome. |
| 21:26:05 | <Berengal> | Hmm, yeah, a t-shirt would be fine too |
| 21:26:12 | <skorpan> | a cat would be fine too... |
| 21:26:47 | <pumpkin> | ceiling cat? |
| 21:27:08 | <Berengal> | ACTION just wrote a chat server thingamajig in 45 minutes |
| 21:27:13 | <ceilingcat> | ACTION iz watchin u |
| 21:27:35 | <Berengal> | STM is good stuff |
| 21:27:45 | <Botje> | too much STM will kill you |
| 21:27:51 | <Botje> | but so will too little STM |
| 21:27:53 | <Botje> | BE WARNED! |
| 21:28:21 | <Berengal> | I coudn't find a modifyTVar function though. Granted, it's only two lines, but still... |
| 21:29:07 | <FliPPeh> | > case "123test123:D" of ('1':'2':'3':x:'1':'2':3':x) -> x |
| 21:29:09 | <lambdabot> | <no location info>: |
| 21:29:09 | <lambdabot> | lexical error in string/character literal at chara... |
| 21:29:20 | <FliPPeh> | > case "123test123:D" of ("123":x) -> x |
| 21:29:21 | <lambdabot> | Couldn't match expected type `GHC.Types.Char' |
| 21:29:24 | <FliPPeh> | :( |
| 21:29:29 | <Botje> | yeah. |
| 21:29:31 | <FliPPeh> | > case "123test123:D" of "123":x -> x |
| 21:29:32 | <lambdabot> | Couldn't match expected type `GHC.Types.Char' |
| 21:29:48 | <FliPPeh> | Looks like I have to do real splitting |
| 21:29:59 | <Nereid_> | FliPPeh: I don't think "123":x does what you think it does |
| 21:30:02 | <Berengal> | Or use view patterns |
| 21:30:32 | <Nereid_> | > case "123test123:D" of '1':'2':'3':x -> x |
| 21:30:33 | <lambdabot> | "test123:D" |
| 21:30:34 | <pumpkin> | > case "123test123:D" of '1':'2':'3':x -> x |
| 21:30:36 | <lambdabot> | "test123:D" |
| 21:30:36 | <sjanssen> | Berengal: writeTVar v . f =<< readTVar v -- is two lines? :) |
| 21:30:40 | <pumpkin> | I fail |
| 21:30:43 | <ray> | : is not ++ |
| 21:30:50 | <FliPPeh> | I know |
| 21:30:56 | <Berengal> | sjanssen: Type signature too :P |
| 21:30:56 | <FliPPeh> | I'm just hoping :) |
| 21:31:15 | <Nereid_> | and this won't work either: |
| 21:31:16 | <ray> | and ++ isn't a constructor. EVERYONE LOSES |
| 21:31:20 | <Nereid_> | > case "123test123:D" of "123"++x -> x |
| 21:31:21 | <lambdabot> | <no location info>: Parse error in pattern |
| 21:31:31 | <ray> | LAMBDAS FALL EVERYONE DIES |
| 21:32:05 | <Nereid_> | since ++ isn't a constructor |
| 21:32:45 | <Berengal> | case "123test123:D" of (prefixMatch "123" -> Just x) -> x |
| 21:33:04 | <Berengal> | prefixMatchBy _ (x:xs) [] = Nothing |
| 21:33:04 | <Berengal> | prefixMatchBy _ [] ys = Just ys |
| 21:33:04 | <Berengal> | prefixMatchBy (≡ ) (x:xs) (y:ys) | x ≡ y = prefixMatchBy (≡ ) xs ys |
| 21:33:04 | <Berengal> | | otherwise = Nothing |
| 21:33:27 | <FliPPeh> | > case "|test 123|" of '|':text:'|' |
| 21:33:27 | <lambdabot> | <no location info>: parse error (possibly incorrect indentation) |
| 21:33:28 | <Berengal> | prefixMatch = prefixMatchBy (==) |
| 21:33:35 | <FliPPeh> | > case "|test 123|" of '|':text:'|':"" |
| 21:33:36 | <lambdabot> | <no location info>: parse error (possibly incorrect indentation) |
| 21:33:47 | <FliPPeh> | Meh |
| 21:34:03 | <Nereid_> | you forgot the -> etc |
| 21:34:12 | <Nereid_> | anyway text would have to be a Char in that case |
| 21:34:13 | <Berengal> | Wouldn't help |
| 21:34:24 | <FliPPeh> | Okay |
| 21:34:25 | <magthe> | is there some way to hide a standard instance definition... I'd like to redefine `instance Pretty a => Pretty [a]`? |
| 21:34:27 | <FliPPeh> | Need real splitting then |
| 21:34:30 | <Nereid_> | yeah |
| 21:34:40 | <mauke> | magthe: no |
| 21:35:36 | <magthe> | mauke: oki, so my only option is to wrap the list in a custom datatype, e.g. `data MyPrettyList a = MyPrettyList [a]` and then define the Pretty instance on that? |
| 21:35:49 | <Nereid_> | FliPPeh: if you want anything much more complicated then a parser is good |
| 21:35:52 | <Nereid_> | have a look at the irc package too |
| 21:35:56 | <FliPPeh> | Not complicated |
| 21:35:58 | <mauke> | magthe: yeah (also s/data/newtype/) |
| 21:36:13 | <ville> | Half the ##C++ population is here, eh? |
| 21:36:19 | <magthe> | mauke: ah, ok... a bit more typing then, but not too bad :) |
| 21:36:21 | <magthe> | thanks |
| 21:37:14 | <Peaker> | ville: I wouldn't expect that |
| 21:37:22 | <guenni> | how can I get [a, b, c, d, e, .... , aa, ab, ac, ad] again? |
| 21:37:37 | <Peaker> | would there be a lot of overlap between C++ and Haskell crowds? |
| 21:37:56 | <Raevel> | i would hope not :-P |
| 21:37:57 | <Nereid_> | guenni: maybe [a..ad] is what you're looking for? |
| 21:38:00 | <ville> | Peaker: surprisingly lot it seems. |
| 21:40:13 | <conal> | Baughn: "conal: Is the Monoid instance for events diagonalizing mappend?" it's more like set union, if you think of events as sets of time/value pairs. or with E a = T -> [a], then it's the usual function monoid. |
| 21:41:16 | <Baughn> | conal: I'm just thinking of the order in which they get evaluated. Sure looks like diagonalization.. well, never mind. |
| 21:41:23 | <Baughn> | conal: As you can see, I hit another GHC bug. ^^; |
| 21:41:35 | <conal> | Baughn: yeah. |
| 21:42:12 | <conal> | Baughn: by diagonalization, do you mean \ x -> f x x (join on functions)? |
| 21:42:38 | <conal> | Baughn: and are you asking about evaluation or meaning? |
| 21:42:59 | <Baughn> | conal: Evaluation. |
| 21:42:59 | <conal> | (operational or denotational) |
| 21:42:59 | <Baughn> | conal: Actually, it's blatantly obvious, and I believe you state it outright in your paper. :P |
| 21:43:05 | <Baughn> | So there's no need to worry about that. |
| 21:43:30 | <Baughn> | That is, what joinE needs to do to merge infinite events correctlyt |
| 21:43:44 | <conal> | yep |
| 21:43:49 | <Peaker> | does ghci have a short line limit? |
| 21:44:02 | <conal> | Baughn: potentially, an infinite stream of infinite streams. |
| 21:44:10 | <conal> | merged into temporal order |
| 21:44:57 | <jmcarthur_work> | ACTION finds the procrastinating-variable package dangerously interesting |
| 21:44:59 | <Baughn> | conal: Right. And if you make a 2d array from the occurences, and look at the merge order, you get diagonalization. Well, in the simplest case at least. |
| 21:45:21 | <conal> | Baughn: i don't think so. |
| 21:45:37 | <conal> | Baughn: diagonalization discards most values, right? |
| 21:46:24 | <Baughn> | conal: Hm. "Diagonalization" may not be the right term. When I checked, it appears to not mean the same as what I meant.. |
| 21:46:59 | <jmcarthur_work> | well, you might see a pattern which your mind might interpret as diagonal on one end and flat on the other |
| 21:47:12 | <Baughn> | conal: What I meant was the occurences in the merged event, if you map them back to the original 2D occurence grid, will be in a diagonal-ish order |
| 21:47:17 | <jmcarthur_work> | if you were to, say, see when things evaluate |
| 21:47:19 | <Peaker> | ville: 55 nicks in both ##c++ and #haskell |
| 21:47:26 | <Baughn> | conal: I don't think we're actually disagreeing here, so I'm going to get back to debugging ghc. :P |
| 21:47:52 | <conal> | Baughn: good luck, and thanks. |
| 21:51:18 | <ville> | Peaker: heh, ok. |
| 21:52:46 | <Peaker> | ville: Had to struggle with ghci to get that, apparently there's some really short line length limit |
| 21:55:34 | <deeflex> | Learnin IO now. I want to write a function which reads from stdin and returns like IO [a]. I'm so confused with this :) |
| 21:55:53 | <mauke> | what's the problem? |
| 21:55:59 | <BONUS> | what does it return |
| 21:56:11 | <Cale> | IO [a]? You want it to be polymorphic? |
| 21:56:16 | <BONUS> | i.e. what do you want it to do |
| 21:58:08 | <FliPPeh> | Hey, C knows global compiler set values such as __FILE__ and __DATE__ |
| 21:58:12 | <FliPPeh> | Can Haskell do that, too? GHC? |
| 21:58:48 | <deeflex> | ye I have defined a data type, say A. I want to read from stdin, for each line: create an instance of that data type and then return the list of all instances. |
| 21:59:07 | <Peaker> | FliPPeh: You can run cpp on a Haskell program too :-) |
| 21:59:14 | <BONUS> | how many lines do you want to read? |
| 21:59:21 | <FliPPeh> | Any easy way? :) |
| 21:59:39 | <luqui> | cpp myfile.hs ? |
| 22:00:14 | <Peaker> | deeflex: You should separate the side-effecting part from the pure processing part. You want to read the entire file (effect), divide it into lines (pure), apply a constructor on each line (pure), right? |
| 22:00:58 | <pumpkin> | {-# LANGUAGE CPP #-} at the top |
| 22:01:18 | <Peaker> | deeflex: do { contents <- hGetContents stdin ; ... apply pure functions to contents here ... ; return (whatever you want here) } |
| 22:01:19 | <luqui> | deeflex, write function makeA :: String -> A, then map makeA (lines fileContents) |
| 22:01:46 | <Peaker> | deeflex: try to separate your program into the computational part, and the part that interacts with files/world |
| 22:03:18 | <deeflex> | BONUS: until EOF. |
| 22:03:55 | <BONUS> | yeah then do what the guys said |
| 22:04:42 | <deeflex> | Ok is this even correct? http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5695#a5695 I don't have a haskell environment so I cant test anything now :). But main should call another function which reads from stdin and creates type A. |
| 22:04:58 | <deeflex> | Peaker: oh ok I see |
| 22:06:43 | <Peaker> | deeflex: if readStuff takes "stdin" as an arg, then its not an IO value, its a function. Only functions have args |
| 22:06:47 | <Berengal> | deeflex: For small and easy programs, take a look at 'interact'. It takes a function of type String -> String and gives it the contents of stdin as input, and prints the output to stdout |
| 22:07:03 | <Peaker> | deeflex: so readStuff must be Handle -> IO something |
| 22:08:14 | <deeflex> | Peaker: ok |
| 22:08:31 | <Peaker> | deeflex: you don't need to do isEOF stuff, you have hGetContents :: Handle -> IO String |
| 22:08:41 | <Peaker> | deeflex: gives you the whole file as a string, inside an IO action |
| 22:09:19 | <deeflex> | Peaker: ok, this is my first attempt so.. =) |
| 22:10:20 | <thoughtpolice> | dcoutts: sorry, ping again |
| 22:10:40 | <thoughtpolice> | dcoutts: I'm running the latest HEAD cabal/cabal-install, and ghc-pkg dump is failing, but not if I provide the '-v2' flag to it |
| 22:10:50 | <thoughtpolice> | dcoutts: this happens on every package pretty much |
| 22:11:11 | <Peaker> | deeflex: you can define, for example: hReadLines :: Handle -> IO [String] ; hReadLines handle = do { contents <- hGetContents handle ; return (lines contents) } |
| 22:11:49 | <Peaker> | deeflex: note that instead of: do { x <- act ; return (f x) } you can use: fmap f act. So you can alternatively use: hReadLines handle = fmap lines hGetContents |
| 22:12:04 | <Peaker> | hReadLines handle = fmap lines (hGetContents handle) -- that was |
| 22:12:26 | <Nereid_> | or liftM instead of fmap |
| 22:12:56 | <Nereid_> | which seems more intuitive to me |
| 22:13:04 | <Peaker> | Nereid_: its just a different name? |
| 22:13:10 | <Peaker> | Nereid_: how is a name "more intuitive"? :) |
| 22:13:23 | <pumpkin> | <$> is even nicer I think |
| 22:13:42 | <Peaker> | pumpkin: and then you need to import stuff :-( |
| 22:14:07 | <pumpkin> | I think it should be in prelude :) |
| 22:14:28 | <Peaker> | I am wondering whether to create a Scripting module that imports everything from all over the place |
| 22:14:36 | <Peaker> | (e.g a bit like lambdabot's import list) |
| 22:14:38 | <Nereid_> | likewise for liftM, but my point is that liftM is monads, and fmap is for functors |
| 22:14:50 | <Gracenotes> | just doesn't call fmap (.), plox. |
| 22:14:54 | <Peaker> | Nereid_: liftM=fmap for well-behaved monads |
| 22:14:59 | <pumpkin> | so, just because people call it the IO monad doesn't mean it's only a monad |
| 22:15:10 | <Nereid_> | sure |
| 22:15:15 | <Nereid_> | but that's how I tend to think of it |
| 22:15:16 | <Berengal> | I almost always import Control.Applicative anyway... |
| 22:15:16 | <Peaker> | Nereid_: so they are just aliases |
| 22:15:21 | <Gracenotes> | all monads are functors, anyweh.. |
| 22:15:22 | <dcoutts> | thoughtpolice: how peculiar |
| 22:15:23 | <pumpkin> | it's the IO functor just as much as it's the IO monad |
| 22:15:30 | <Nereid_> | and liftM works for all monads, not just IO |
| 22:15:35 | <pumpkin> | so does fmap |
| 22:15:38 | <Peaker> | Berengal: I always import qualified or with (). Don't hurt your code readers :( |
| 22:15:39 | <Nereid_> | fine |
| 22:15:40 | <Nereid_> | :-) |
| 22:15:41 | <pumpkin> | and I like to use the most general function when I can :) |
| 22:15:45 | <dcoutts> | thoughtpolice: does ghc-pkg fail normally when you run it directly? |
| 22:15:52 | <Gracenotes> | <$> isn't so bad.... raly. |
| 22:15:59 | <Berengal> | Peaker: I have none :( |
| 22:15:59 | <sjanssen> | pumpkin: modulo Haskell '98 sucking |
| 22:16:02 | <luqui> | pumpkin, (or rather, what ought to be the more general function) |
| 22:16:03 | <Peaker> | Nereid_: Using fmap makes your code more general, sometimes |
| 22:16:03 | <dcoutts> | thoughtpolice: or only when Cabal calls it |
| 22:16:07 | <pumpkin> | sjanssen: true :) |
| 22:16:11 | <Nereid_> | I'm new to haskell anyway |
| 22:16:13 | <Peaker> | Berengal: maybe that's why! :) |
| 22:16:18 | <Berengal> | Anyway, fmap is specialized, so might in some cases be more efficient than liftM |
| 22:16:46 | <Botje> | ACTION always uses liftM in monad context. |
| 22:16:52 | <Botje> | fmap just seems .. wrong :) |
| 22:16:56 | <pumpkin> | what's a monad context? |
| 22:17:08 | <jmcarthur_work> | i only use liftM if it prevent another type constraint |
| 22:17:08 | <Apocalisp> | as opposed to Functor |
| 22:17:24 | <Botje> | in a do block |
| 22:17:26 | <jmcarthur_work> | Monad *should* imply Functor anyway, but since it doesn't... |
| 22:17:30 | <Botje> | or when i'm just working with monads |
| 22:17:31 | <luqui> | i always grumble and flip a coin |
| 22:17:40 | <deeflex> | Peaker: ok thanks a lot. I'll give it I try tomorrow, it's late and I don't have a hugs env. here. |
| 22:17:47 | <Apocalisp> | I like (.) |
| 22:17:51 | <Peaker> | deeflex: install ghci, not hugs, if you can |
| 22:17:59 | <Peaker> | (.) should be Control.Category's, probably |
| 22:18:21 | <luqui> | :t fmap `fmap` fmap |
| 22:18:22 | <jmcarthur_work> | yeah i have come to agree with (.) being part of Category |
| 22:18:22 | <lambdabot> | forall (f :: * -> *) a b (f1 :: * -> *). (Functor f, Functor f1) => (a -> b) -> f (f1 a) -> f (f1 b) |
| 22:18:29 | <luqui> | :t (.).(.) |
| 22:18:30 | <lambdabot> | forall a b c a1. (b -> c) -> (a -> a1 -> b) -> a -> a1 -> c |
| 22:18:33 | <Apocalisp> | > (* 2) . [1,2,3] |
| 22:18:34 | <lambdabot> | Couldn't match expected type `a -> b' against inferred type `[a1]' |
| 22:18:37 | <Berengal> | fmap /= Control.Category.(.) |
| 22:18:37 | <luqui> | oh no more Caleprelude? |
| 22:19:13 | <Cale> | That's been gone a long time, since the GHC API or hint is bad at hiding. |
| 22:19:14 | <jmcarthur_work> | yeah i kind of miss Caleskell |
| 22:19:18 | <Peaker> | fmap and Control.Category.(.) seem to be strongly related |
| 22:19:28 | <Cale> | Weird. 'xset r off' here makes X think that the Enter key is held down or something |
| 22:19:45 | <Cale> | I had to switch to a terminal... |
| 22:20:37 | <Vulpyne> | :r |
| 22:20:38 | <quicksilver> | Cale: Why does it give bogus error messages in volving GHC.Types now? |
| 22:20:44 | <quicksilver> | Cale: can it be fixed? |
| 22:20:57 | <Cale> | hmm? |
| 22:20:58 | <quicksilver> | > take "hi" "there" |
| 22:20:59 | <lambdabot> | Couldn't match expected type `GHC.Types.Int' |
| 22:21:03 | <deeflex> | Peaker: OK. Btw in hReadLines it should be Handle -> IO [someType] (instead of [String], right? And from main I should write do { return hReadLines }. will that write to stdout? |
| 22:21:18 | <quicksilver> | Int, sure. Prelude.Int, sure. GHC.Types.Int? no thanks. |
| 22:21:19 | <Cale> | quicksilver: Isn't that a correct error message? |
| 22:21:22 | <Cale> | Oh. |
| 22:21:28 | <pumpkin> | yeah, that started recently |
| 22:21:46 | <quicksilver> | it's distracting noise and confuses learners |
| 22:21:57 | <aluink> | anyone got any ideas on this? http://aluink.pastebin.com/m38beb3de |
| 22:22:04 | <FliPPeh> | > let para = ":test" in (case para of (':':clean) -> clean; clean -> clean) |
| 22:22:06 | <lambdabot> | "test" |
| 22:22:09 | <FliPPeh> | > let para = "test" in (case para of (':':clean) -> clean; clean -> clean) |
| 22:22:10 | <lambdabot> | "test" |
| 22:22:25 | <aluink> | i can't find a nice solution for trhsx |
| 22:22:40 | <Cale> | I have no idea. |
| 22:22:51 | <Zao> | deeflex: return just wraps a value in a monad. |
| 22:23:02 | <Cale> | Perhaps it started when I upgraded it to 6.10.3 |
| 22:23:16 | <Zao> | deeflex: In the case of (return foo) it yields an action that when executed yields foo. |
| 22:23:27 | <Zao> | deeflex: It doesn't print anything, unless that's an side effect. |
| 22:23:38 | <jmcarthur_work> | :t (<=<) |
| 22:23:40 | <lambdabot> | forall b (m :: * -> *) c a. (Monad m) => (b -> m c) -> (a -> m b) -> a -> m c |
| 22:23:41 | <Zao> | deeflex: hPutStr or print tends to be IO functions suitable. |
| 22:23:42 | <Berengal> | return never has any side effects |
| 22:23:42 | <deeflex> | Zao: ok so I putStr then? |
| 22:23:46 | <Berengal> | Well, shouldn't |
| 22:23:52 | <Zao> | Berengal: Muahaha. |
| 22:24:00 | <Nereid_> | FliPPeh: |
| 22:24:04 | <Gracenotes> | @src (>=>) |
| 22:24:04 | <lambdabot> | Source not found. My mind is going. I can feel it. |
| 22:24:07 | <Nereid_> | > let para = ":test" in stripPrefix ":" para |
| 22:24:09 | <lambdabot> | Just "test" |
| 22:24:22 | <Nereid_> | ok, not quite what I was looking for |
| 22:24:25 | <FliPPeh> | Nereid: I'm gonna use that inline |
| 22:24:28 | <FliPPeh> | So case is faster |
| 22:24:36 | <Peaker> | deeflex: hReadLines :: Handle -> IO [String] -- why someType? it reads lines, specifically. whatever main returns does not go anywhere |
| 22:24:38 | <FliPPeh> | "NICK" -> handleNickChange sender (case para of (':':clean) -> clean; clean -> clean) |
| 22:24:46 | <Cale> | (f <=< g) x = do v <- g x; f v |
| 22:24:52 | <Zao> | @type ("lol", return "lol") |
| 22:24:54 | <lambdabot> | forall (m :: * -> *). (Monad m) => ([Char], m [Char]) |
| 22:25:11 | <Cale> | return is a left and right identity for <=< |
| 22:25:15 | <Cale> | and <=< is associative |
| 22:25:27 | <Cale> | That's another way to say the monad laws :) |
| 22:25:29 | <luqui> | FliPPeh, is speed really a key concern in this code? |
| 22:25:39 | <FliPPeh> | Noo, faster to write for me |
| 22:25:41 | <jmcarthur_work> | (<=<) is the closest way to relate fmap to Control.Category.(.) that i can think of |
| 22:25:44 | <Berengal> | Cale: The better way, imho |
| 22:26:08 | <luqui> | FliPPeh, oh... faster than a library func |
| 22:26:18 | <luqui> | > stripPrefix ":" "foo" |
| 22:26:19 | <lambdabot> | Nothing |
| 22:26:32 | <FliPPeh> | Library func using Maybe |
| 22:26:37 | <FliPPeh> | Wich I'll have to strip, too |
| 22:26:41 | <Cale> | Berengal: yes |
| 22:26:43 | <Nereid_> | > let para = ":test" in fromMaybe para $ stripPrefix ":" para |
| 22:26:44 | <lambdabot> | "test" |
| 22:26:47 | <Nereid_> | > let para = "test" in fromMaybe para $ stripPrefix ":" para |
| 22:26:48 | <lambdabot> | "test" |
| 22:26:52 | <Berengal> | FliPPeh: view patterns |
| 22:26:56 | <Nereid_> | less writing than the case version |
| 22:27:08 | <luqui> | > let strip x = fromMaybe x $ stripPrefix ":" x in strip "foo" |
| 22:27:10 | <lambdabot> | "foo" |
| 22:27:15 | <Cale> | Berengal: I sometimes wonder if it wouldn't be better for Monad to be defined in terms of (<=<) and return |
| 22:27:35 | <algal> | newbie question. I'm trying to convert an integer to list of its digits. "integerDigits n = map Char.digitToInt (show n)" performs better than my own efforts, but then it doesn't have a sensible type signature. |
| 22:27:44 | <Cale> | That might be a little awkward in writing some instances though. |
| 22:27:48 | <FliPPeh> | @src fromMaybe |
| 22:27:48 | <lambdabot> | fromMaybe d x = case x of {Nothing -> d;Just v -> v} |
| 22:27:48 | <Berengal> | Cale: Maybe. It wouldn't be worse, at least |
| 22:27:51 | <algal> | is there a way to fix it up so it goes Integral -> [Int] ? |
| 22:27:59 | <FliPPeh> | @module fromMaybe |
| 22:27:59 | <lambdabot> | Unknown command, try @list |
| 22:28:02 | <algal> | Or else fixup my arithmetic version so it performs well? |
| 22:28:02 | <FliPPeh> | @list |
| 22:28:03 | <lambdabot> | http://code.haskell.org/lambdabot/COMMANDS |
| 22:28:11 | <luqui> | > let strip = ap fromMaybe . stripPrefix in (strip ":" ":foo", strip ":" "foo") |
| 22:28:12 | <lambdabot> | ("foo","foo") |
| 22:28:17 | <Nereid_> | algal: use (fromIntegral . Char.digitToInt) instead of Char.digitToInt perhaps |
| 22:28:20 | <Berengal> | We could put (<=<) in the class and use defaults... |
| 22:28:34 | <Nereid_> | ? |
| 22:28:54 | <deeflex> | Peaker: Ok nvm. That's where the mapping comes in...map a function to the result of hReadLines and then return [someType]. right? |
| 22:28:55 | <Nereid_> | :t digitToInt |
| 22:28:56 | <lambdabot> | Char -> Int |
| 22:29:03 | <Cale> | > reverse . map (`mod` 10) . takeWhile (/= 0) . iterate (`div` 10) $ 12345 |
| 22:29:05 | <lambdabot> | [1,2,3,4,5] |
| 22:29:15 | <Cale> | Does that not perform well? |
| 22:29:51 | <algal> | Cale: hmm.. that's more compressed than my arithmeti version. not sure if it's doing the same thing.. |
| 22:30:00 | <Cale> | (How incredibly large are the numbers you're doing this with that you need to care about the performance of it?) |
| 22:30:06 | <algal> | the character-manipulating version beat the elegant version. |
| 22:30:26 | <Cale> | I suppose you can save some work by using divMod instead |
| 22:30:26 | <algal> | Cale: I'm working thru the project euler problems in Haskell & other langs, so I end up handling big integers and needing performance. |
| 22:30:38 | <luqui> | plus, it's more natural to have the least significant digit up front |
| 22:30:54 | <Berengal> | > reverse $ unfoldr (\n -> let (rest, digit) = divMod n 10 in if n == 0 then Nothing else Just (digit, rest)) 12345 |
| 22:30:55 | <lambdabot> | [1,2,3,4,5] |
| 22:31:04 | <Peaker> | deeflex: yeah, but such mapping happens outside of hReadLines and does not affect its type |
| 22:31:04 | <luqui> | algal, it's still log time wrt the size of the number.. you shouldn't hit a barrier |
| 22:31:05 | <Cale> | Yeah, if you can stand to have the digits in the opposite order, not reversing would be better. |
| 22:31:28 | <algal> | mine was: |
| 22:31:40 | <deeflex> | Peaker: YE ok thanks. |
| 22:31:40 | <algal> | intToDigits = reverse . intToDigitsReversed |
| 22:31:40 | <algal> | intToDigitsReversed n | (n == digit) = [digit] |
| 22:31:40 | <algal> | | otherwise = digit : intToDigitsReversed rest |
| 22:31:40 | <algal> | where (rest, digit) = quotRem n 10 |
| 22:31:57 | <algal> | I can't quite tell if that's the same as yours.. My haskell-fu is not strong enough yet. |
| 22:32:12 | <Berengal> | Looks very similar to mine |
| 22:32:13 | <luqui> | algal, it's almost the same. you do divMod, cale does div and mod. |
| 22:32:33 | <Peaker> | deeflex: main = do { lines <- hGetLines stdin ; let result = map whatever lines ; print result } -- note the get-input(effect), input -> compute -> output, print-output(effect) |
| 22:32:33 | <FliPPeh> | > let para = [":test"] in fromMaybe para $ stripPrefix ":" head para |
| 22:32:34 | <lambdabot> | Couldn't match expected type `[GHC.Types.Char]' |
| 22:32:36 | <luqui> | hopefully the rest will fuse (?) |
| 22:32:40 | <FliPPeh> | > let para = [":test"] in fromMaybe para $ stripPrefix ":" (head para) |
| 22:32:41 | <lambdabot> | Couldn't match expected type `[GHC.Types.Char]' |
| 22:33:01 | <Peaker> | deeflex: whatever would convert each line from String to whatever you want |
| 22:33:39 | <algal> | luqui: so you think the divMod version should be comparable to the Char-based version? |
| 22:33:47 | <Peaker> | deeflex: of course, as Haskell mojo goes up, you end up writing that as: main = print =<< map whatever . lines <$> getContents |
| 22:34:07 | <luqui> | algal, what do you mean the char-based version? |
| 22:34:33 | <Berengal> | Peaker: main = iteract $ unlines . map whatever . lines |
| 22:34:34 | <Peaker> | deeflex: You can see it as sort of a "pipeline". getContents starts the pipeline, gives it to lines, then to map whatever, eventually to print |
| 22:34:44 | <luqui> | algal, although yes, show on Integer should be pretty fast. |
| 22:34:46 | <algal> | luqui: digitToInt is in Char. My (blurry) understand is that it's doing a non-mathematical character manipulation. |
| 22:35:01 | <Peaker> | Berengal: needs even more mojo :-) |
| 22:35:11 | <ClaudiusMaximus> | @src show Integer |
| 22:35:11 | <lambdabot> | Source not found. I can't hear you -- I'm using the scrambler. |
| 22:35:24 | <luqui> | algal, oh. i'm not sure. i'd use cale's, because it's purdy |
| 22:35:26 | <Berengal> | algal: digitToInt is probably just '(-65) . ord' or something similar |
| 22:35:40 | <luqui> | algal, project euler is about algorithms, not raw speed |
| 22:35:59 | <sjanssen> | Peaker: I don't think anybody should write it that way |
| 22:36:08 | <sjanssen> | Peaker: print . map whatever . lines =<< getContents |
| 22:36:08 | <algal> | luqui: I have a terrible weakness for the purdy. But prettiness does not equal speed. Which makes me sad. |
| 22:36:28 | <Cale> | algal: It often does |
| 22:36:34 | <luqui> | algal, but in this case it ought to be comparable, and if you need that extra boost in project euler, you are doing the problems wrong |
| 22:36:51 | <Berengal> | algal: Which problem are you currently working on? Just curious... |
| 22:37:06 | <Peaker> | sjanssen: yeah, there are various better variants of that, just showing PL style in general |
| 22:37:17 | <deeflex> | Peaker: much appreciated. Should be able to finish this now :) |
| 22:37:32 | <algal> | Berengal: this is just prob4. I'm only up to 40-something, but I'm going back and doing everything in c++, Java, python, Cl, and Haskell. |
| 22:38:19 | <algal> | I need to learn c++ & Java for bloody interviews. Haskell for fun. |
| 22:38:26 | <luqui> | deeflex, please use interact... :) |
| 22:39:14 | <algal> | Cale: is there a convention for naming a function which produces a reversed list? Seems like it must happen a lot. |
| 22:39:28 | <deeflex> | luqui: maybe I will..better if I come back tomorrow where I can actually test the code =) |
| 22:39:29 | <Cale> | Not really. |
| 22:39:58 | <algal> | Cale: oh. what about for predicate functions? |
| 22:40:14 | <Cale> | :t null |
| 22:40:16 | <lambdabot> | forall a. [a] -> Bool |
| 22:40:21 | <luqui> | deeflex, you could always do it with a little one on one time with lambdabot |
| 22:40:30 | <Cale> | Normally they're named quite plainly. There are some which start with 'is' |
| 22:40:35 | <Cale> | :t isUpper |
| 22:40:36 | <lambdabot> | Char -> Bool |
| 22:40:44 | <Cale> | :t toUpper |
| 22:40:44 | <algal> | Cale: ok. |
| 22:40:45 | <lambdabot> | Char -> Char |
| 22:41:03 | <Cale> | I might add 'Rev' to the end of a function if it produced a reversed result. |
| 22:41:32 | <luqui> | or, god forbid, Reversed |
| 22:41:40 | <algal> | Cale: yeah, that's what I was thinking. But I always try to follow native idiom |
| 22:42:02 | <luqui> | reversed lists are very uncommon in my experience |
| 22:42:11 | <Berengal> | You're often creating reversed lists when you just start out. At least I remember I did. I don't anymore... |
| 22:42:14 | <luqui> | they delazify an otherwise nice stream program |
| 22:42:17 | <Cale> | http://loadingreadyrun.com/videos/view/440/The-Joystique -- haha |
| 22:42:28 | <algal> | luqui: oh, interesting. |
| 22:42:34 | <luqui> | Berengal, yeah, from the tail recursion fever |
| 22:42:40 | <deeflex> | luqui: i'll pass ;) |
| 22:43:42 | <algal> | Nereid_: btw, fromIntegral didn't solve my puzzle. Maybe this is my excuse to go slow and pretty after all. |
| 22:44:12 | <Cale> | algal: You can add explicit type signatures if you get a type which is too polymorphic |
| 22:44:25 | <Berengal> | algal: What exactly are you doing that is slow? I just tested the naive implementation, and it finished in about a second... |
| 22:44:33 | <Luckytoilet> | > test |
| 22:44:35 | <lambdabot> | Not in scope: `test' |
| 22:44:53 | <Luckytoilet> | > "test" |
| 22:44:55 | <lambdabot> | "test" |
| 22:45:16 | <malouin> | Is the function (\x -> case x of Left _ -> Nothing Right a -> Just a) in a lib somewhere? |
| 22:45:47 | <algal> | Berengal: it came up on prob34. calculate the sum of all numbers which are equal to the sum of the factorial of their digits. |
| 22:45:48 | <Berengal> | malouin: either (const Nothing) Just |
| 22:46:11 | <Berengal> | algal: Ah, I thought you were just on problem 4 |
| 22:46:12 | <algal> | so I did a generate & test going up to 2540160 |
| 22:46:26 | <algal> | I've solved higher in other langs, but now I'm re-doing in haskell |
| 22:46:33 | <malouin> | Berengal: aha! |
| 22:46:34 | <algal> | for some reason I've done 34 in haskell and mathemtiaca. |
| 22:46:39 | <malouin> | thank you! |
| 22:46:39 | <Luckytoilet> | project euler? |
| 22:46:49 | <Nereid_> | yeah |
| 22:46:51 | <algal> | Luckytoilet: project euler = teh awesome |
| 22:47:02 | <Luckytoilet> | 230/248 done =] |
| 22:47:29 | <yairchu> | Luckytoilet: couldn't solve problem 60 yet.. don't tell me though! |
| 22:47:50 | <Luckytoilet> | ok |
| 22:47:53 | <Berengal> | algal: Ah, for problem 34 I think I just did something like 'scanl1 (+) (filter isCurious [1..])' |
| 22:47:54 | <algal> | My question is, where the hell are all these assembly languages programmers on project euler coming from? |
| 22:48:13 | <Cale> | My question is, why is the answer to every Project Euler problem a number? |
| 22:48:20 | <algal> | Berengal: Yes, but isCurious requires pulling out digits! |
| 22:48:21 | <Luckytoilet> | not every |
| 22:48:35 | <Eiler> | why not? |
| 22:48:35 | <Cale> | Pretty much :) |
| 22:48:40 | <Berengal> | algal: Yes, I know. Don't remember exactly how I did it... |
| 22:49:28 | <yairchu> | Cale: numbers are easy to compare? |
| 22:49:45 | <Luckytoilet> | hmm 162 isn't a number |
| 22:52:10 | <yairchu> | algal: digits = map (read . (:[])) . show |
| 22:52:14 | <Berengal> | algal: digits = map digitToInt . show seems fast enough. It just solved problem 34 in much less than a second for me... |
| 22:52:56 | <Berengal> | Well, "solved"... using scanl1 (+) produces an infinite list of only two elements... |
| 22:53:03 | <Berengal> | (In this case) |
| 22:54:27 | <Berengal> | > let digits = map digitToInt . show; isCurious = (==) <*> sum . map (product . enumFromTo 1) . digits in take 2 $ scanl1 (+) (filter isCurious [3..]) |
| 22:54:28 | <lambdabot> | [145,40730] |
| 22:54:38 | <Luckytoilet> | > fact 5 where fact x | x == 0 = 1 | x * fact (x-1) |
| 22:54:40 | <lambdabot> | <no location info>: parse error on input `where' |
| 22:54:58 | <Luckytoilet> | fact 5 where fact x | x == 0 = 1 | otherwise = x * fact (x-1) |
| 22:55:19 | <Luckytoilet> | > fact 5 where fact x | x == 0 = 1 | otherwise = x * fact (x-1) |
| 22:55:21 | <lambdabot> | <no location info>: parse error on input `where' |
| 22:55:26 | <Luckytoilet> | gah how do i use this |
| 22:55:35 | <Berengal> | Lambdabot doesn't do where, I believe... |
| 22:55:38 | <Berengal> | > foo where foo = 5 |
| 22:55:40 | <lambdabot> | <no location info>: parse error on input `where' |
| 22:55:52 | <Luckytoilet> | > foo = 5 in foo |
| 22:55:53 | <lambdabot> | <no location info>: parse error on input `=' |
| 22:56:01 | <Berengal> | > let foo = 5 in foo |
| 22:56:02 | <lambdabot> | 5 |
| 22:56:04 | <Luckytoilet> | > let foo = 5 in foo |
| 22:56:06 | <lambdabot> | 5 |
| 22:56:13 | <Luckytoilet> | ah yum |
| 22:56:20 | <algal> | Berengal: umm. say again. is there a pastepad? |
| 22:57:00 | <Berengal> | > let digits = map digitToInt . show; isCurious = (==) <*> sum . map (product . enumFromTo 1) . digits in take 2 $ scanl1 (+) (filter isCurious [3..]) -- algal, this |
| 22:57:01 | <lambdabot> | [145,40730] |
| 22:57:22 | <Luckytoilet> | let fact x | 0 = 1 | otherwise = x * fact x-1 in fact 5 |
| 22:57:27 | <Luckytoilet> | > let fact x | 0 = 1 | otherwise = x * fact x-1 in fact 5 |
| 22:57:29 | <lambdabot> | No instance for (GHC.Num.Num GHC.Bool.Bool) |
| 22:57:29 | <lambdabot> | arising from the literal `0'... |
| 22:57:44 | <Luckytoilet> | > let fact x | x == 0 = 1 | otherwise = x * fact x-1 in fact 5 |
| 22:57:46 | <lambdabot> | * Exception: stack overflow |
| 22:58:42 | <Berengal> | > let fact x | x == 0 = 1 | otherwise = x * fact (x-1) in fact 5 |
| 22:58:43 | <lambdabot> | 120 |
| 22:59:40 | <zloog> | Anyone know why cabal would tell me I do and don't have a particular dependency met? http://www.moonpatio.com/fastcgi/hpaste.fcgi/view?id=2640#a2640 |
| 23:00:47 | <Nereid_> | let fact x = product [1..x] |
| 23:00:47 | <Berengal> | zloog: I assume it has to do with global vs user package repositories |
| 23:00:53 | <dcoutts> | zloog: use "cabal" or use "runhaskell Setup.lhs". There is no need to use a mixture of both, you'll just confuse yourself. |
| 23:01:35 | <dcoutts> | zloog: there's no need to use both, it just means you have to remember whether you're doing --global or --user installs (since the defaults are reversed between the two) |
| 23:03:16 | <zloog> | Ah thanks, I'll try to see about the user settings |
| 23:04:18 | <zloog> | !! worked. thanks |
| 23:04:47 | <dcoutts> | zloog: remember that you can just run "cabal configure" rather than "runhaskell Setup.lhs configure" |
| 23:05:04 | <dcoutts> | the cabal tool replaces the runhaskell Setup.lhs interface |
| 23:06:01 | <zloog> | dcoutts: Yea, I really need to sit and learn about cabal sometime. It makes sense for this issue though. |
| 23:06:40 | <Saizan_> | though running "cabal configure" make sense only for cabal haddock and sdist, since install will reconfigure (unless you use an undocumented flag) |
| 23:06:43 | <dcoutts> | zloog: fortunately if you're familiar with the "runhaskell Setup.lhs" command line interface then it's easy, since it's exactly the same for the "cabal" tool. |
| 23:07:15 | <dcoutts> | Saizan_: usually that doesn't matter |
| 23:08:23 | <Saizan_> | dcoutts: when you don't pass any option, right? |
| 23:08:33 | <dcoutts> | right |
| 23:09:26 | <dcoutts> | Saizan_: I accept it's not ideal. If you've got any suggestions for distinguishing the "do everything" from just copy+register then I'd be happy to hear them. |
| 23:13:43 | <algal> | is there some kind of visual atlas of the HOFs? I think it would make them easier to learn. |
| 23:13:43 | <dcoutts> | Saizan_: in particular it's tricky in the general case where Setup.hs uses its own build system so we cannot know when it's safe to not reconfigure |
| 23:13:43 | <gwern> | 'Extract interesting commands and add them to a text file. "Interesting" means not matching any regular expression in the file. This allows one to keep a textual database of commands. Never again say "I wish I remembered what arguments to give wibble to make it flibber the gibbet" three months after you looked it up. WARNING: historian truncates ~/.bash_history. ' |
| 23:13:43 | <gwern> | okay, I'm no longer interested in historian |
| 23:13:43 | <gwern> | too bad, because the idea is a sound one. wouldn't it be cool if there was a tool which could look through your shell history and tell you what things you should turn into aliases and functions? |
| 23:13:43 | <Saizan_> | dcoutts: yeah, it's more like a job for the build system, but also an UI problem, if it's acceptable at all for "cabal install" to use the options passed to the last "cabal configure" |
| 23:13:43 | <jix> | i hope unsafePerformIO works as i want ... |
| 23:13:53 | <byorgey> | algal: what would such a visual atlas look like? |
| 23:13:57 | <gwern> | hm. I don't really see what historian buys one; looks like it's just a gussied up grep |
| 23:14:29 | <dcoutts> | Saizan_: we can certainly save the flags we passed to configure, so perhaps if they're unchanged then we just build + install |
| 23:14:52 | <algal> | byorgey: not sure. will tell you next time. |
| 23:14:59 | <byorgey> | =) |
| 23:15:03 | <algal> | thanks for the help, chaps. |
| 23:15:21 | <dcoutts> | Saizan_: so we'd re-plan and compare if the configuration has changed |
| 23:15:43 | <Saizan_> | dcoutts: if you're used to the Setup.hs interface you'd expect to not have to pass the options again to install |
| 23:16:09 | <dcoutts> | Saizan_: right |
| 23:16:39 | <Saizan_> | dcoutts: ah, so you'd reconfigure only with conflicting options? |
| 23:16:51 | <dcoutts> | Saizan_: right |
| 23:17:14 | <dcoutts> | Saizan_: which I guess also works if you install --with-extra-flags |
| 23:17:31 | <idnar> | gwern: I just use zsh with a gigantic history file and histignorealldups so it doesn't grow too quickly |
| 23:18:00 | <gwern> | idnar: the important thing is to factor out repeated patterns |
| 23:18:17 | <idnar> | gwern: well, the thing is, I'm too lazy to create aliases or whatever |
| 23:18:21 | <gwern> | I do the same thing with bash, but it doesn't save one from repetition unless one knows one is repeating something |
| 23:18:22 | <idnar> | gwern: I just use history-incremental-search-backward a lot |
| 23:20:27 | <_Lucretia_> | anyone know anything about wxhaskell? well, the wxc bit |
| 23:21:20 | <Cale> | _Lucretia_: I don't really, but if you ask a question, I can try to help anyway |
| 23:22:06 | <_Lucretia_> | well, i just want to get the c bit built, tried using the wxc source, fails miserably, the wxhaskell version is at least up to date |
| 23:22:21 | <_Lucretia_> | how can i build it without the haskell bit? |
| 23:23:42 | <Cale> | This is on linux? |
| 23:24:27 | <flipflap> | Meh, I've got a StateT using function, which I want to launch in a thread.. how'd I do that? |
| 23:24:39 | <Cale> | flipflap: runStateT first |
| 23:24:43 | <flipflap> | forkIO $ liftIO $ spam to does not wor |
| 23:25:06 | <Cale> | flipflap: Of course not. liftIO turns IO computations into other computations, not the other way around |
| 23:25:07 | <SamB> | flipflap: yes, that only works in Python |
| 23:25:19 | <Cale> | You can liftIO . forkIO $ foo |
| 23:25:26 | <flipflap> | Other way around didn't work, too |
| 23:25:37 | <Nereid_> | don't you mean |
| 23:25:39 | <Cale> | But that results in a StateT (or other) computation |
| 23:25:39 | <Nereid_> | liftIO forkIO foo |
| 23:25:39 | <Nereid_> | ? |
| 23:25:47 | <flipflap> | Thing is, forkIO naturally wants the function to be IO (), but it has to be Bot () |
| 23:25:51 | <Cale> | Nereid_: I'm sure I mean what I said :) |
| 23:25:57 | <flipflap> | Fr the StateT |
| 23:26:04 | <Cale> | flipflap: It cannot be. |
| 23:26:18 | <Nereid_> | hmm |
| 23:26:18 | <Nereid_> | wait |
| 23:26:21 | <flipflap> | So I should just pass the state as a plain value to it? |
| 23:26:22 | <Nereid_> | liftIO (forkIO foo) |
| 23:28:31 | <Nereid_> | no, that's not right |
| 23:28:31 | <Cale> | flipflap: There's no way to thread the state parameter through a computation if it's running in another thread. |
| 23:28:31 | <vininim> | @type liftIO |
| 23:28:31 | <lambdabot> | forall a (m :: * -> *). (MonadIO m) => IO a -> m a |
| 23:28:31 | <Cale> | flipflap: In fact, it doesn't even make sense. |
| 23:28:31 | <vininim> | @type forkIO |
| 23:28:31 | <lambdabot> | Not in scope: `forkIO' |
| 23:28:31 | <Nereid_> | iirc, forkIO :: IO () -> ThreadId |
| 23:28:31 | <vininim> | certainly not |
| 23:28:31 | <flipflap> | So just give it a copy and let it go manually? |
| 23:28:31 | <Nereid_> | I'm going crazy then |
| 23:28:31 | <Nereid_> | IO ThreadId |
| 23:28:31 | <Cale> | flipflap: However, you can take a StateT computation and turn it into an IO computation by running the state layer, and run *that* in another thread. |
| 23:28:31 | <vininim> | oh |
| 23:28:31 | <Cale> | yeah |
| 23:28:31 | <Nereid_> | ACTION is noob :-) |
| 23:28:31 | <flipflap> | Cale, how? |
| 23:28:31 | <Cale> | Something like... |
| 23:28:55 | <Cale> | do s <- get; liftIO . forkIO $ runStateT foo s |
| 23:29:10 | <flipflap> | Where foo is my function? |
| 23:29:21 | <Cale> | Where foo is a StateT s IO computation |
| 23:29:48 | <Cale> | and we're assuming that the whole thing is as well. |
| 23:30:09 | <Cale> | This will fork a new thread, but note that the thread will have no impact on the state of the original thread |
| 23:30:26 | <_Lucretia_> | Cale: yeh |
| 23:30:44 | <Cale> | (How could it anyway? StateT just saves you from passing parameters around by hand) |
| 23:31:16 | <flipflap> | So how would I go running my test function? |
| 23:31:26 | <flipflap> | do s <- get; liftIO . forkIO $ runStateT test s does not work |
| 23:31:39 | <flipflap> | Ah meh wait |
| 23:32:39 | <flipflap> | No, no idea |
| 23:32:42 | <flipflap> | How do I start it? |
| 23:34:31 | <Cale> | hm? |
| 23:34:50 | <Cale> | What are you actually trying to accomplish? |
| 23:35:52 | <flipflap> | Trying to start my function as a thread with it having at least read access to the state |
| 23:36:21 | <flipflap> | I'll just put that off some time, maybe I find a solution not based on threads |
| 23:37:29 | <Cale> | Oh, I see, it needs a >> return () |
| 23:38:53 | <Peaker> | or () <$ |
| 23:42:11 | <aavogt> | Is there a haskell-style shell out there that builds with ghc-6.10? I've come across HaSh, which has not been written yet, and Hashell, which doesn't build, due to some changes in the GHC api. Are there others? |
| 23:42:36 | <idnar> | @type (<$) |
| 23:42:38 | <lambdabot> | forall a (f :: * -> *) b. (Functor f) => a -> f b -> f a |
| 23:43:06 | <SamB> | aavogt: the one you're about to start writing because we say "no"? |
| 23:43:56 | <Berengal> | There's always ghci + convenience functions... |
| 23:44:05 | <idnar> | Hashell sounds like hell |
| 23:44:05 | <idnar> | ;) |
| 23:44:20 | <luqui> | ACTION would like a nice modular extensible ghci for this kind of thing |
| 23:44:25 | <luqui> | i guess that probably possible using the api |
| 23:44:28 | <Berengal> | Except the already existing convenience functions aren't convenient for shell use yet |
| 23:44:56 | <Berengal> | ... and as such can't really be called convenience functions... |
| 23:47:34 | <byorgey> | aavogt: there's HSH, although I haven't used it so I don't know if it's exactly what you're looking for |
| 23:47:47 | <byorgey> | but CosmicRay just released a new version so I imagine it ought to work with 6.10. |
| 23:48:29 | <ray> | inconvenience functions |
| 23:49:59 | <aavogt> | byorgey: from the documentation, HSH looks quite promising |
| 23:52:25 | <aavogt> | thanks for the suggestions everybody |
| 23:54:14 | <hoooopy> | OT: what's a good live linux distro that allows you to burn CDs and is just generally good for diagnostic purposes? |
| 23:54:46 | <Cale> | aavogt: HSH is more useful for writing shell-script-like things with Haskell rather than as an actual interactive shell |
| 23:54:49 | <SamB> | hoooopy: well, generally you'll need two CD drives for that |
| 23:55:20 | <ray> | not really |
| 23:55:54 | <SamB> | okay, maybe I'm still in the stone ages where RAM < CD |
| 23:56:10 | <ray> | even my computer can handle a little ramdisk |
| 23:56:57 | <SamB> | isn't it hard to get Linux to even see the CD drive it was booted from after an El Torito boot? |
| 23:57:42 | <aavogt> | Cale: true, seeing as it doesn't offer any completion, and things need to be prefixed with run |
| 23:57:53 | <ray> | if that's the case, just have grub or whatever do the ramdisk thing (i think it can) |
| 23:58:02 | <dumael> | SamB: yes. the boot kernel is on an emulated floppy disk image though the magic of the BIOS. the kernel still needs the appropiate drivers to access the cd-rom drive and the like. |
| 23:58:21 | <pumpkin> | ACTION is trying to figure out how to write "quickbench" |
| 23:58:30 | <SamB> | isn't it tricky to get the floppy disk emulation to stop? |
| 23:58:34 | <ray> | > text "quickbench" |
| 23:58:36 | <lambdabot> | quickbench |
Back to channel and daily index: content-negotiated html turtle