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:01:24 | <mux> | > let allEq xs = case group xs of (_:_:_) -> False; _ -> True |
| 00:01:25 | <lambdabot> | not an expression: `let allEq xs = case group xs of (_:_:_) -> False; _ -> ... |
| 00:01:34 | <mux> | > let allEq xs = case group xs of (_:_:_) -> False; _ -> True in allEq [1,2] |
| 00:01:36 | <lambdabot> | False |
| 00:01:40 | <mux> | > let allEq xs = case group xs of (_:_:_) -> False; _ -> True in allEq [1,1 |
| 00:01:42 | <lambdabot> | <no location info>: parse error (possibly incorrect indentation) |
| 00:01:44 | <mux> | > let allEq xs = case group xs of (_:_:_) -> False; _ -> True in allEq [1,1] |
| 00:01:46 | <lambdabot> | True |
| 00:01:51 | <mux> | > let allEq xs = case group xs of (_:_:_) -> False; _ -> True in allEq [] |
| 00:01:53 | <lambdabot> | True |
| 00:08:46 | <Gracenotes> | :. |
| 00:31:58 | <MyCatVerbs> | @pl (\x -> if x then '1' else '0') |
| 00:31:58 | <lambdabot> | flip (flip if' '1') '0' |
| 00:32:41 | <MyCatVerbs> | @pl (\x -> case x of { True -> '1'; False -> '0'; } |
| 00:32:42 | <lambdabot> | (line 1, column 18): |
| 00:32:42 | <lambdabot> | unexpected "{" |
| 00:32:42 | <lambdabot> | expecting variable, "(", operator or ")" |
| 00:34:35 | <xian> | @pl (\x -> case x of True -> '1'; False -> '0') |
| 00:34:36 | <lambdabot> | (line 1, column 23): |
| 00:34:36 | <lambdabot> | unexpected ">" |
| 00:34:36 | <lambdabot> | expecting variable, "(", operator or ")" |
| 00:34:58 | <Tsion> | Can someone join lambdabot to #botters, please? :) |
| 00:48:22 | <Qriva> | Could someone explain why the function 'simple x y z = x * (y + z)' is typed: simple :: Integer -> Integer -> Integer -> Integer ? |
| 00:48:44 | <Qriva> | Is it because it takes 3 integer values and produces an integer result? |
| 00:49:26 | <EvilTerran> | Qriva, er, yes |
| 00:49:32 | <IntergalacticOwl> | you'd think so! |
| 00:50:04 | <Qriva> | EvilTerran: is it more complicated than that? or should I quit reading into it? |
| 00:50:06 | <Qriva> | :) |
| 00:50:18 | <EvilTerran> | ?type let simple x y z = x * (y + z) in simple |
| 00:50:19 | <lambdabot> | forall a. (Num a) => a -> a -> a -> a |
| 00:50:33 | <EvilTerran> | it's a bit more complicated than that :) |
| 00:50:45 | <Qriva> | can i do that in ghci EvilTerran ? (the type let simple...) |
| 00:50:50 | <Qriva> | EvilTerran: care to try to explain it to me? |
| 00:51:05 | <EvilTerran> | Qriva, yes, ":type let simple ... in simple" would work |
| 00:51:12 | <EvilTerran> | but i have to go to bed now, unfortunately |
| 00:51:31 | <EvilTerran> | i'm sure there's other helpful people awake in here |
| 00:51:33 | <Qriva> | no worries -- thanks |
| 00:53:03 | <Qriva> | ?type [(2,3), (4,5)] |
| 00:53:04 | <lambdabot> | forall t t1. (Num t, Num t1) => [(t, t1)] |
| 00:54:25 | <Qriva> | ^-What's the proper type of that? [(Integer)]? |
| 00:54:36 | <Qriva> | ^-What's the proper type of that? [(Integer), (Integer)]? |
| 00:55:42 | <Zao> | Depends on context. |
| 00:55:56 | <Zao> | Until now, it's just two possibly different types conforming to Num |
| 00:56:21 | <Qriva> | In the HSoE book he asks that question in an exercise |
| 00:56:29 | <Qriva> | early in the book |
| 00:56:31 | <Zao> | The type to use could be inferred by context or by explicit signatures. |
| 00:56:52 | <Qriva> | Zao: how about ['z', -42]? |
| 00:56:59 | <Qriva> | [Char, Integer]? |
| 00:57:02 | <xian> | No. |
| 00:57:09 | <xian> | It's not an expression. |
| 00:57:22 | <Zao> | Qriva: That would be broken. |
| 00:57:29 | <Qriva> | I noticed -42 when you ask for it's type gives you an answer with an a, not a t |
| 00:57:35 | <idnar> | @type ['z', -42] |
| 00:57:36 | <Qriva> | ?type ['z', -42] |
| 00:57:37 | <lambdabot> | No instance for (Num Char) |
| 00:57:37 | <lambdabot> | arising from a use of syntactic negation at <interactive>:1:6-8 |
| 00:57:37 | <lambdabot> | Possible fix: add an instance declaration for (Num Char) |
| 00:57:38 | <lambdabot> | No instance for (Num Char) |
| 00:57:38 | <lambdabot> | arising from a use of syntactic negation at <interactive>:1:6-8 |
| 00:57:38 | <lambdabot> | Possible fix: add an instance declaration for (Num Char) |
| 00:57:48 | <Zao> | A list needs all elements to be the same type. |
| 00:58:13 | <Qriva> | how about: |
| 00:58:21 | <Qriva> | ?type ('z', 42) |
| 00:58:22 | <lambdabot> | forall t. (Num t) => (Char, t) |
| 00:58:29 | <Qriva> | err -42 |
| 00:58:34 | <Qriva> | ?type ('z', -42) |
| 00:58:35 | <lambdabot> | forall t. (Num t) => (Char, t) |
| 00:59:10 | <Qriva> | what does the t represent? am ambiguous type? |
| 00:59:13 | <Qriva> | an* |
| 00:59:26 | <skorpan> | just a type |
| 00:59:45 | <skorpan> | it's a "type variable", meaning it could be any type |
| 00:59:52 | <skorpan> | in this case, the type also has to instantiate Num |
| 01:00:10 | <Qriva> | why does :type -42 and :type 42 give the result in 'a' and 't' respectively? |
| 01:00:19 | <skorpan> | :t -42 |
| 01:00:20 | <skorpan> | :t 42 |
| 01:00:20 | <lambdabot> | forall a. (Num a) => a |
| 01:00:21 | <lambdabot> | forall t. (Num t) => t |
| 01:00:33 | <skorpan> | i'm not sure, but there's no difference really |
| 01:00:59 | <Qriva> | hmm, okay, ill just move on and quit harding on it for now :) |
| 01:01:00 | <Zao> | Literal vs. expression? |
| 01:01:03 | <Qriva> | harping* |
| 01:01:09 | <idnar> | @type +42 |
| 01:01:11 | <lambdabot> | parse error on input `+' |
| 01:01:13 | <idnar> | aww |
| 01:01:15 | <idnar> | @type 0+42 |
| 01:01:16 | <lambdabot> | forall t. (Num t) => t |
| 01:01:27 | <skorpan> | +42 would have been valid javascript though :P |
| 01:01:28 | <Qriva> | ?type --42 |
| 01:01:29 | <Zao> | Bah, theory disproven. |
| 01:01:30 | <lambdabot> | on the commandline: |
| 01:01:30 | <idnar> | @type 0-42 |
| 01:01:30 | <lambdabot> | Warning: -fno-th is deprecated: use -XNoTemplateHaskell or pragma {-# LANGUAGE NoTemplateHaskell#-} instead |
| 01:01:30 | <lambdabot> | <no location info>: not an expression: `' |
| 01:01:31 | <lambdabot> | forall t. (Num t) => t |
| 01:01:36 | <Zao> | Qriva: -- is a comment |
| 01:01:41 | <Qriva> | lol so it is! |
| 01:01:48 | <Qriva> | ?type -(-42) |
| 01:01:49 | <idnar> | that was a bizarre error, though |
| 01:01:50 | <lambdabot> | forall a. (Num a) => a |
| 01:02:25 | <Qriva> | ?type -(42) |
| 01:02:26 | <skorpan> | :t -(-(-42)) |
| 01:02:26 | <lambdabot> | forall a. (Num a) => a |
| 01:02:27 | <lambdabot> | forall a. (Num a) => a |
| 01:02:30 | <Qriva> | :) |
| 01:02:57 | <Qriva> | how do you define a temporary binding on the bot? |
| 01:03:02 | <skorpan> | "let" |
| 01:03:08 | <skorpan> | > let x = 5 in x + 3 |
| 01:03:09 | <lambdabot> | 8 |
| 01:03:16 | <skorpan> | > let myList = [1,2,3] |
| 01:03:17 | <lambdabot> | not an expression: `let myList = [1,2,3]' |
| 01:03:21 | <skorpan> | okay, so that doesn't work |
| 01:03:24 | <skorpan> | @let myList [1,2,3] |
| 01:03:24 | <lambdabot> | Parse error |
| 01:03:28 | <xian> | > let myList = [1,2,3] in myList |
| 01:03:28 | <skorpan> | @let myList = [1,2,3] |
| 01:03:30 | <lambdabot> | [1,2,3] |
| 01:03:30 | <lambdabot> | Defined. |
| 01:03:34 | <skorpan> | > head myList |
| 01:03:35 | <lambdabot> | 1 |
| 01:03:38 | <Qriva> | cool, thank you |
| 01:04:15 | <Zao> | Note that lambdabot also accepts private messages. |
| 01:04:25 | <Qriva> | I have to say I was completely flabbergasted at learning Haskell -- seemed beyond my reach, but Cale gave me a good intro the other night and im really getting into it |
| 01:04:31 | <xian> | By the way, how is lambdabot protected against evaluating infinite lists etc.? |
| 01:04:32 | <Qriva> | this is fun stuff to think about |
| 01:04:55 | <skorpan> | Qriva: beware though, programming anything else after having done some haskell will prove painful |
| 01:05:50 | <idnar> | @sum [1..] |
| 01:05:51 | <lambdabot> | Maybe you meant: bug run src |
| 01:05:52 | <idnar> | err |
| 01:05:53 | <idnar> | > sum [1..] |
| 01:06:00 | <lambdabot> | mueval-core: Prelude.read: no parse |
| 01:06:00 | <lambdabot> | mueval: ExitFailure 1 |
| 01:06:06 | <skorpan> | uhh |
| 01:06:12 | <skorpan> | that's not what it usually does, is it? |
| 01:06:15 | <Qriva> | @let x = x + 1 |
| 01:06:15 | <idnar> | well, that wasn't quite the message I was expecting |
| 01:06:17 | <lambdabot> | <local>:5:0: |
| 01:06:18 | <lambdabot> | Multiple declarations of `L.x' |
| 01:06:18 | <lambdabot> | Declared at: <local>:2... |
| 01:06:24 | <skorpan> | > sum [1..] |
| 01:06:29 | <lambdabot> | mueval-core: Prelude.read: no parse |
| 01:06:29 | <lambdabot> | mueval: ExitFailure 1 |
| 01:06:31 | <idnar> | but those expressions get evaluated in a separate process, which is killed after a certain period of time |
| 01:06:41 | <skorpan> | lambdabot is ill |
| 01:06:46 | <Qriva> | ACTION hugs lambdabot |
| 01:07:54 | <Qriva> | Is there a way to tell lambdabot something like: |
| 01:07:59 | <Qriva> | x :: Float |
| 01:08:48 | <skorpan> | what do you mean? |
| 01:09:11 | <cads> | hey, is there any way to turn f::(a, b, c, d ...) -> p into f'::a->b->c->d->...->p ? |
| 01:09:33 | <skorpan> | :t uncurry |
| 01:09:35 | <lambdabot> | forall a b c. (a -> b -> c) -> (a, b) -> c |
| 01:09:38 | <skorpan> | :t curry |
| 01:09:39 | <lambdabot> | forall a b c. ((a, b) -> c) -> a -> b -> c |
| 01:10:19 | <skorpan> | maybe something along the lines of `curry' |
| 01:11:07 | <skorpan> | cads: seeing as tuples of different lengths have different types, you may have to write your own function for it |
| 01:11:16 | <eck> | is there a way to get sprintf functionality out of Text.Printf? |
| 01:11:47 | <kpreid> | eck: if you let the return type be a string then it is sprintf |
| 01:11:53 | <eck> | ah, thanks |
| 01:11:55 | <kpreid> | then printf is sprintf, I mean |
| 01:12:13 | <Qriva> | skorpan: to be honest I don't really know what I mean -- many examples I'm looking at look like: totalArea :: Float totalArea = pi * r1^2 + pi * r2^2 + pi * r3^2 |
| 01:12:21 | <Qriva> | Is that type 'declaration' necessary? |
| 01:12:29 | <skorpan> | Qriva: rarely is it necessary |
| 01:12:59 | <skorpan> | :t fromIntegral 1 |
| 01:13:00 | <lambdabot> | forall b. (Num b) => b |
| 01:13:20 | <skorpan> | :t 1 |
| 01:13:21 | <lambdabot> | forall t. (Num t) => t |
| 01:13:22 | <Qriva> | whoa now we've got a b! a, b, and t |
| 01:13:45 | <cads> | skorpan: "currying is a very important theoretical device because it reduces multiple-argument functions to single-argument functions only (Schoenfinkel, 1924" |
| 01:13:51 | <Qriva> | :t 0 - 1 |
| 01:13:52 | <lambdabot> | forall t. (Num t) => t |
| 01:14:13 | <skorpan> | cads: what are you saying? |
| 01:14:52 | <cads> | well, in haskell it seems like the analogue of multi-arg functions, since functions are all normally curried, is a function that takes a tuple of some rank |
| 01:15:32 | <cads> | but how can we use the curry function to turn a function on a higher rank tuple into a curried form? |
| 01:16:00 | <skorpan> | you can't, afaik, but then again, what do i know |
| 01:17:24 | <skorpan> | afaik, in haskell, you can't have a function which takes a tuple of "any length", and therein lies the issue |
| 01:18:46 | <idnar> | @type curry |
| 01:18:48 | <lambdabot> | forall a b c. ((a, b) -> c) -> a -> b -> c |
| 01:18:54 | <idnar> | @type curry . curry |
| 01:18:55 | <lambdabot> | forall a b b1 c. (((a, b), b1) -> c) -> a -> b -> b1 -> c |
| 01:19:07 | <idnar> | @type curry . curry . curry |
| 01:19:08 | <lambdabot> | forall a b b1 b2 c. ((((a, b), b1), b2) -> c) -> a -> b -> b1 -> b2 -> c |
| 01:19:24 | <skorpan> | idnar: it's just too bad ((a, b), c) isn't the same as (a, b, c) :) |
| 01:19:35 | <idnar> | skorpan: some people think only the first one of those should exist :P |
| 01:19:48 | <idnar> | except I think they usually want (a, (b, (b1, (b2, ())))) |
| 01:20:28 | <skorpan> | idnar: i can understand that, but that's almost the equivalent of heterogeneous lists |
| 01:20:41 | <idnar> | except it's type-level |
| 01:20:46 | <skorpan> | yes |
| 01:22:02 | <cads_> | skorpan: I got disconnected so I missed any replie |
| 01:22:19 | <skorpan> | <skorpan> you can't, afaik, but then again, what do i know |
| 01:22:28 | <cads_> | :t curry . curry . curry |
| 01:22:30 | <lambdabot> | forall a b b1 b2 c. ((((a, b), b1), b2) -> c) -> a -> b -> b1 -> b2 -> c |
| 01:24:09 | <cads_> | skorpan: hehe, I am looking up shoenfinkel '24 to see what he means by that |
| 01:34:56 | <Qriva> | So I'm reading the HSoE book and I'm trying to run the code he provides for a function but I can't get it to run |
| 01:35:12 | <Qriva> | @let listSum [] = 0 |
| 01:35:13 | <lambdabot> | Defined. |
| 01:35:32 | <Qriva> | @let listSum (x:xs) = x + listSum xs |
| 01:35:33 | <lambdabot> | Defined. |
| 01:35:44 | <Qriva> | > listSum [1,2,3] |
| 01:35:45 | <lambdabot> | 6 |
| 01:35:52 | <Qriva> | why doesn't this work in my GHCI? |
| 01:36:20 | <Ralith> | because your GHCI is overriding, not overloading, the previous definition. |
| 01:36:50 | <Qriva> | how do I fix that or get around it? |
| 01:36:56 | <Ralith> | > let listSum (x:xs) = x + listSum xs; listSum [] = 0 |
| 01:36:57 | <lambdabot> | not an expression: `let listSum (x:xs) = x + listSum xs; listSum [] = 0' |
| 01:37:01 | <Ralith> | > let listSum (x:xs) = x + listSum xs; listSum [] = 0 in listSum [1,2,3] |
| 01:37:02 | <xian> | Put the definition in a file and then :load it into your ghci session. |
| 01:37:02 | <lambdabot> | 6 |
| 01:37:11 | <Ralith> | or do what I just demonstrated |
| 01:37:13 | <Ralith> | :P |
| 01:37:38 | <Ralith> | (the '...in listSum [1,2,3]' bit isn't necessary if you're in GHC; the definition will stick.) |
| 01:40:27 | <Qriva> | thanks Ralith, im still newbin it up |
| 01:46:24 | <Qriva> | when im load a .hs file into ghci, does it matter the order the functions inside of it were written? |
| 01:46:46 | <harlekin> | Qriva, no |
| 01:49:50 | <Ralith> | Qriva: yes, it does, I'm pretty sure. |
| 01:50:11 | <Ralith> | you want most specific pattern match first. |
| 01:51:03 | <Ralith> | e.g. if you have foo x = x and foo (y:ys) = y then you'll want to put the latter first or else it'll never get hit (ghc should warn you about this) |
| 01:51:47 | <eck> | i'm pretty impressed by Data.Binary |
| 01:51:47 | <xian> | But harlekin is right that the order in which *functions* are defined is irrelevant. |
| 01:51:53 | <eck> | ACTION spent the better part of the day packing bits |
| 01:52:37 | <Ralith> | xian: okay, fair, but that probably wasn't the question Qriva meant to ask. |
| 02:25:58 | <hackagebot> | either-unwrap 1.0 |
| 02:29:11 | <Qriva> | Ralith: actually I did sort of mean what xian said |
| 02:30:01 | <Qriva> | Ralith: although i am curious about the whole :load'ing process in general in ghci |
| 02:32:14 | <Axman6> | @hackage either-unwrap |
| 02:32:14 | <lambdabot> | http://hackage.haskell.org/cgi-bin/hackage-scripts/package/either-unwrap |
| 02:37:05 | <aavogt> | so that library writer is aware of the function either? |
| 02:37:47 | <aavogt> | does eitherM === either? |
| 02:38:06 | <aavogt> | with slightly different parameter order |
| 02:38:17 | <Axman6> | :t either |
| 02:38:18 | <lambdabot> | forall a c b. (a -> c) -> (b -> c) -> Either a b -> c |
| 02:38:29 | <Axman6> | yeah, that's all eitherM is |
| 02:39:50 | <aavogt> | hmm, and the type isn't that much more specific that it will reduce the number of required annotations |
| 02:40:48 | <jasondew> | anyone feel like looking at some haskell code and pointing me in the right direction to speed it up? i've done profiling, looking at core, etc, etc |
| 02:41:09 | <idnar> | what's the type of eitherM? |
| 02:41:19 | <aavogt> | eitherM :: Monad m => Either a b -> (a -> m c) -> (b -> m c) -> m c |
| 02:41:43 | <idnar> | huh |
| 02:42:50 | <aavogt> | I like the parameter order on the regular either better |
| 02:42:53 | <idnar> | yeah, that's just weird |
| 02:43:03 | <idnar> | there's no particular point in the Monad annotation |
| 02:43:15 | <idnar> | which in turn makes the naming convention weird |
| 02:44:41 | <aavogt> | @type \x -> either ?f ?g =<< x |
| 02:44:43 | <lambdabot> | forall a b (m :: * -> *) b1. (?f::a -> m b1, ?g::b -> m b1, Monad m) => m (Either a b) -> m b1 |
| 02:45:12 | <aavogt> | @type either (?f =<<) (?g =<<) |
| 02:45:14 | <lambdabot> | forall a (m :: * -> *) b a1. (?f::a -> m b, Monad m, ?g::a1 -> m b) => Either (m a) (m a1) -> m b |
| 02:45:48 | <aavogt> | @type on either (=<<) |
| 02:45:50 | <lambdabot> | forall a (m :: * -> *) b. (Monad m) => (a -> m b) -> (a -> m b) -> Either (m a) (m a) -> m b |
| 02:46:12 | <Qriva> | my 'friend' is telling me he thinks Haskell is 'kind of a toy' |
| 02:46:16 | <Qriva> | what do you even say to something like that? |
| 02:46:53 | <Gracenotes> | :> |
| 02:47:06 | <inimino> | "that's nice"? |
| 02:47:09 | <inimino> | nothing? |
| 02:47:19 | <idnar> | Qriva: well, it's a toy that's used to write financial software for banks :P |
| 02:47:40 | <inimino> | ACTION would probably smile and move on ;-) |
| 02:47:50 | <Qriva> | i feel bad for him -- he's so set on the idea that all he needs to do is go through a compsci program, learn Java and some C, and that's it |
| 02:48:00 | <Qriva> | im trying to open him up to the idea that there's more out there |
| 02:48:05 | <inimino> | Qriva: why is he studying CS? |
| 02:48:09 | <shapr> | Yeah, really. |
| 02:48:20 | <p_l> | Qriva: He probably will fail C with that kind of mindset |
| 02:48:26 | <Qriva> | he's like a lot of CS majors -- no other clue what to do |
| 02:48:31 | <Qriva> | and thinks it will make him money |
| 02:48:39 | <shapr> | Can't argue with that. |
| 02:48:40 | <inimino> | based on your description so far, it's probably for the money |
| 02:48:42 | <inimino> | yeah |
| 02:48:47 | <inimino> | no point in trying to help the guy then |
| 02:48:54 | <p_l> | Qriva: Java isn't helping. I'm surprised Java people can write any C without failing... oh |
| 02:49:05 | <inimino> | if we's in it for the money, let him learn Java and make what money he can |
| 02:49:13 | <inimino> | s/we's/he's/ |
| 02:49:33 | <Qriva> | he has an interest in computers, but once i get onto ANY sort of theoretical discussion with him about i dont know, functional programming, persistence, blah blah |
| 02:49:39 | <p_l> | inimino: if he wants money, he should learn COBOL |
| 02:49:43 | <Qriva> | he just shrugs like he doesn't care |
| 02:49:52 | <inimino> | in my opinion people who learn programming for that reason rarely get good at it, and then only by accident |
| 02:50:27 | <Qriva> | he's just not passionate about it, which is really sad, i dont know |
| 02:50:40 | <inimino> | my advice would be to treat him as you would any other professional in a field that is not your own |
| 02:50:42 | <Qriva> | i cant save 'em all, but i thought id give it a try |
| 02:51:07 | <aavogt> | @faq can Haskell save souls? |
| 02:51:07 | <lambdabot> | The answer is: Yes! Haskell can do that. |
| 02:51:11 | <Qriva> | lol |
| 03:04:31 | <Gracenotes> | hallelujah |
| 03:04:34 | <Gracenotes> | .. |
| 03:05:33 | <athos> | hm |
| 03:05:38 | <athos> | it's already 5am |
| 03:14:05 | <alexsuraci> | In Control.Concurrent.Chan, what if I write to a channel before something tries to read from it? Does the value get lost? |
| 03:14:35 | <alexsuraci> | I'm thinking no but it would explain the trouble I'm having |
| 03:16:09 | <hydo> | slow day... |
| 03:16:26 | <hydo> | sorry, alexsuraci, I don't know. |
| 03:16:34 | <luqui> | alexsuraci, it gets queued up |
| 03:16:35 | <lambdabot> | luqui: You have 1 new message. '/msg lambdabot @messages' to read it. |
| 03:16:57 | <Gracenotes> | alexsuraci: how soon before? |
| 03:17:01 | <alexsuraci> | luqui: that's what I thought |
| 03:17:07 | <alexsuraci> | Gracenotes: can't be certain |
| 03:19:16 | <alexsuraci> | well, I'm getting a "thread blocked indefinitely" and it seems to be happening when it's reading from a channel, even after I write to it |
| 03:19:33 | <alexsuraci> | maybe I'm writing to two different channels accidentally, hmm |
| 03:20:37 | <alexsuraci> | it can't be that the channel's simply empty though, readChan would wait in that case |
| 03:20:50 | <alexsuraci> | so something deeply sinister must be going on |
| 03:23:51 | <Gracenotes> | D: |
| 03:24:51 | <Gracenotes> | well, don't underestimate stdout. The source for Chan is simple-ish, so you could make your own module plus debugging... concurrency bugs are so annoying :/ |
| 03:25:12 | <alexsuraci> | yeah I've made extensive use of Debug.Trace :P |
| 03:25:15 | <bos> | "thread blocked indefinitely" usually means a bug in your code. |
| 03:25:32 | <alexsuraci> | yeah, figured that much, I'm just not sure what causes it specifically |
| 03:28:37 | <bos> | alexsuraci: it means that your thread has the only reference to the Chan (or the MVars it's constructed with) |
| 03:29:01 | <bos> | alexsuraci: since no other thread has a reference to it, when you try to read from the Chan, it's not possible for the thread ever to wake |
| 03:31:20 | <alexsuraci> | ah, thanks |
| 03:31:24 | <Gracenotes> | as I said a few days ago, Chan needs to borrow some functionality from the MVars used to implement it. tryTake and tryPut, would be useful :/ |
| 03:32:27 | <Gracenotes> | if that's possible |
| 03:32:36 | <alexsuraci> | bos: to be clear, by "your thread" you mean the thread trying to read from it, right? |
| 03:32:48 | <bos> | right |
| 03:33:20 | <alexsuraci> | alright, thanks |
| 03:34:35 | <alexsuraci> | in other news, if anyone's in the Fort Wayne, IN area help me find my cat :( https://post.craigslist.org/manage/1197573122/ysf8v |
| 03:34:43 | <alexsuraci> | http://fortwayne.craigslist.org/laf/1197573122.html rather |
| 03:37:04 | <centrinia> | Is there a way to set the channel's queue size? |
| 03:38:52 | <mmorrow> | Gracenotes: this is the replacement for Chan i use now http://moonpatio.com/repos/vacuum-gl/System/Vacuum/OpenGL/Q.hs |
| 03:39:06 | <mmorrow> | (ever since i was told that |
| 03:39:10 | <Gracenotes> | I have seen :) |
| 03:39:20 | <mmorrow> | forkIO (takeChan ch >> return ()) |
| 03:39:23 | <mmorrow> | isEmptyChan ch |
| 03:39:25 | <mmorrow> | blocks |
| 03:39:28 | <Gracenotes> | do you have Haddocks of it? |
| 03:39:35 | <mmorrow> | Gracenotes: no, but i should |
| 03:39:41 | <Gracenotes> | preferably fried? |
| 03:39:47 | <mmorrow> | weee |
| 03:41:46 | <mmorrow> | centrinia: by channel you mean Chan? (and if so, what would be the desired behavior when the queue is full and a thread tries to add an elem to the Chan? (to block i assume?)) |
| 03:42:16 | <centrinia> | Maybe the queue size can be set only once? |
| 03:42:25 | <alexsuraci> | is there a more detailed spec sheet on the concurrency implementations I could read up on? |
| 03:43:08 | <Gracenotes> | hm. I wish there was a built-in thing for return () :: Monad m => m (). No idea what it would be called though. |
| 03:43:41 | <kpreid> | Gracenotes: void; |
| 03:43:44 | <kpreid> | ? |
| 03:43:45 | <centrinia> | Gracenotes, It would be called return () :p |
| 03:43:46 | <mmorrow> | alexsuraci: i peeked at this the other day and it looks like a good intro http://research.microsoft.com/en-us/um/people/simonpj/papers/parallel/AFP08-notes.pdf |
| 03:43:52 | <Gracenotes> | kpreid: oooh. I like. |
| 03:43:58 | <centrinia> | :t return () |
| 03:43:59 | <lambdabot> | forall (m :: * -> *). (Monad m) => m () |
| 03:44:10 | <Gracenotes> | centrinia: well. You know how it is with multiparameter functions and having to use parentheses. |
| 03:44:17 | <alexsuraci> | mmorrow: thanks |
| 03:44:19 | <centrinia> | @let void = return () |
| 03:44:21 | <lambdabot> | Defined. |
| 03:44:26 | <centrinia> | > void |
| 03:44:27 | <lambdabot> | No instance for (GHC.Show.Show (m ())) |
| 03:44:27 | <lambdabot> | arising from a use of `M728820821... |
| 03:45:16 | <bos> | > void :: IO () |
| 03:45:17 | <lambdabot> | <IO ()> |
| 03:50:10 | <mmorrow> | alexsuraci: actually, looking at that paper it looks like there's only a brief section on MVars, and the rest on STM.. so the three different ways of doing concurrent stuff are basically (IORef+atomicModifyIORef, MVar, and STM) (in decreasing order of speed and increasing order of ease-of-implementation) |
| 03:50:35 | <centrinia> | Oh, Chan has a queue size of 1. |
| 03:50:52 | <mmorrow> | centrinia: what do you mean by queue size? |
| 03:51:28 | <centrinia> | The number of elements that can be put in the FIFO. |
| 03:51:41 | <mmorrow> | it's unbounded |
| 03:51:45 | <alexsuraci> | mmorrow: ah, ok |
| 03:52:10 | <centrinia> | Okay. |
| 03:52:41 | <mmorrow> | alexsuraci: i liked this one: http://www.haskell.org/~simonmar/papers/concurrent-data.pdf |
| 04:00:48 | <alexsuraci> | mmorrow: looks nice and brief with plently of code examples. I approve. ;) Thanks. |
| 04:01:01 | <mmorrow> | alexsuraci: np :) |
| 04:10:21 | <halberd> | as I understand it, in type theory an expression can have multiple types--correct? how come in Haskell then we talk about "the" type of an expression? |
| 04:10:44 | <Gracenotes> | you're referring to polymorphism? |
| 04:11:17 | <codebliss> | @src join |
| 04:11:17 | <lambdabot> | join x = x >>= id |
| 04:11:19 | <Gracenotes> | a polymorphic type is still a type. |
| 04:11:25 | <codebliss> | How does that work? I still don't get it |
| 04:11:51 | <NEEDMOAR> | In some type systems, every expression has only one type, halberd. |
| 04:11:53 | <alexsuraci> | codebliss: >>= is equivalent to concatMap with lists |
| 04:11:56 | <codebliss> | Since id :: a -> a, and that part of (>>=) is (a -> m b), that means a has to be m b, and it would be (m b -> m b)? |
| 04:12:14 | <Gracenotes> | yes |
| 04:12:17 | <codebliss> | alexsuraci: I never said anything about lists? |
| 04:12:31 | <alexsuraci> | codebliss: sorry, assumed that's what you meant based on the context |
| 04:12:33 | <Gracenotes> | codebliss: you're right.. |
| 04:12:35 | <halberd> | well Lambda ((x) x) has the type List A -> List A, and also the type Eq A -> Eq A, for example |
| 04:12:40 | <codebliss> | alexsuraci: No problem =) |
| 04:12:59 | <Gracenotes> | halberd: that's a union of types. which is one type. |
| 04:13:07 | <Gracenotes> | er, I mean, intersection |
| 04:13:11 | <codebliss> | OH |
| 04:13:14 | <halberd> | they are 2 different types which can be derived for the expression |
| 04:13:20 | <halberd> | using the rules of type theory |
| 04:13:24 | <codebliss> | so it's m (m b) -> (m b -> m b) -> m b |
| 04:13:26 | <codebliss> | OH |
| 04:13:39 | <codebliss> | Lol sorry, I never looked back at that first a XD |
| 04:13:44 | <NEEDMOAR> | hellige: in which type theory? |
| 04:13:59 | <halberd> | the type of an expression can be interpreted as just a proposition that is true of that expression, so there shouldn't be any limit to the number or kind of types a dependently typed expression might have, should there? |
| 04:14:44 | <halberd> | because any number of propositions might be true of a given expression |
| 04:14:50 | <Gracenotes> | unions and intersections of types are formulated pretty solidly in type theory |
| 04:15:14 | <Gracenotes> | halberd: you might be interested in http://lucacardelli.name/Papers/OnUnderstanding.A4.pdf |
| 04:15:19 | <NEEDMOAR> | halberd: you do not state which type system are you using... |
| 04:15:57 | <halberd> | martin lof's type theory, as presented in the introduction by nordstrom, petersson, and smith |
| 04:16:31 | <Gracenotes> | ..could've said that.. |
| 04:16:33 | <NEEDMOAR> | halberd: well, intuicionistic type theory is not the same as Haskell's types. |
| 04:16:44 | <halberd> | I know that |
| 04:18:37 | <Gracenotes> | halberd: you've come asking here about Martin Lof's theory before, but.. I think LtU might know more? :) or maybe #haskell-in-depth |
| 04:19:23 | <NEEDMOAR> | halberd: you can talk about the type of an expression in Haskell, because the type system (probably) assures that an expression has only one type. |
| 04:19:53 | <NEEDMOAR> | Well, that's more or less. |
| 04:19:57 | <halberd> | ah #haskell-in-depth... didn't realize it existed |
| 04:20:00 | <NEEDMOAR> | You have the most generic type, etc. |
| 04:21:25 | <aavogt> | I'm having difficulties with specifying endomorphisms that work within an existential type |
| 04:22:25 | <mmorrow> | aavogt: unless you package the function within the same box that you put the data when you first box it up, the type system will refuse |
| 04:22:48 | <mmorrow> | (if i'm understanding your situation correctly) |
| 04:25:33 | <mmorrow> | (e.g. data A b = forall a. A (a -> b) a) |
| 04:25:36 | <halberd> | Gracenotes: I'm in the habit of asking #haskell for any computer-science-related question, just because it is full of computer science people |
| 04:25:39 | <halberd> | and math people |
| 04:25:57 | <halberd> | unlike #c or #java or #python |
| 04:26:32 | <halberd> | it's hit or miss though... I'll check out lambda the ultimate |
| 04:26:43 | <copumpkin> | isn't #python really strict? or was that another one |
| 04:27:12 | <halberd> | strict? well I never tried bending the rules in there |
| 04:27:16 | <halberd> | so I don't know |
| 04:27:20 | <mmorrow> | copumpkin: heh, what do you mean strict |
| 04:27:22 | <mmorrow> | ? |
| 04:27:24 | <aavogt> | mmorrow: sort of like that |
| 04:27:35 | <aavogt> | I want to write something like: |
| 04:27:43 | <halberd> | but the people who frequent #python tend not to be as theoretically minded as the #haskell people |
| 04:27:54 | <Gracenotes> | halberd: sure... I understand |
| 04:27:57 | <aavogt> | liftExistential f (Box a) = Box (f a) |
| 04:28:02 | <copumpkin> | oh, I thought I heard someone that you get flamed/kicked for anything remotely off-topic and that it's full of the typical IRC-types who like to correct your question before answering it |
| 04:28:08 | <copumpkin> | but I've never been there myself so I don't know :) |
| 04:28:20 | <mmorrow> | so, (data Box = forall a. Box a) i take it? |
| 04:28:22 | <Gracenotes> | don't mind me :P |
| 04:28:43 | <aavogt> | this Box has some typeclass constraints too |
| 04:28:59 | <aavogt> | but that's basically it |
| 04:29:03 | <mmorrow> | aavogt: ah, ok. in that case you have at least something to work with |
| 04:29:28 | <mmorrow> | aavogt: but in the general case, you'd have to ensure correctness yourself and then just unsafeCoerce |
| 04:29:36 | <mmorrow> | @src fromDynamic |
| 04:29:37 | <lambdabot> | fromDynamic (Dynamic t v) = case unsafeCoerce v of |
| 04:29:37 | <lambdabot> | r | t == typeOf r -> Just r |
| 04:29:37 | <lambdabot> | | otherwise -> Nothing |
| 04:29:47 | <mmorrow> | @src Dynamic |
| 04:29:47 | <lambdabot> | Source not found. Maybe you made a typo? |
| 04:29:53 | <mmorrow> | @src Dyn |
| 04:29:54 | <lambdabot> | Source not found. That's something I cannot allow to happen. |
| 04:30:18 | <aavogt> | this seems close: liftLayout :: (LayoutClass l a, Read (l a), LayoutClass m a, Read (m a)) => (l a -> m a) -> Layout a -> Layout a |
| 04:30:46 | <mmorrow> | what's the def of Layout? |
| 04:31:21 | <aavogt> | but I can't get the (l a) to refer to the (l1 a) that's inside the (Layout a) argument |
| 04:31:39 | <Berengal> | I just had the weirdest dream. I was collecting pokemon-ish creatures in Bowser's castle, fighting of Bernie the dinosaur (or whatever his name), looking for a red and a blue monoid I could mappend with my yellow one and save the universe from Princess Peach... |
| 04:32:11 | <aavogt> | data Layout a where Layout :: forall a l. (LayoutClass l a, Read (l a)) => (l a) -> Layout a |
| 04:32:29 | <Gracenotes> | :ox |
| 04:33:20 | <hydo> | Berengal: Pr. Peach is the villain now adays or is this just in your dream? |
| 04:33:54 | <Berengal> | hydo: She wasn't a villain. She was the villain's secret weapon (against her will) |
| 04:34:12 | <hydo> | aww... poor pixelated thing. |
| 04:34:30 | <mmorrow> | aavogt: hmm |
| 04:38:15 | <aavogt> | I have a feeling that it is possible, but unsafeCoerce will prevent ghc from picking the correct class instances? |
| 04:38:39 | <mmorrow> | aavogt: so you need to forall the `l' there http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5436#a5436 |
| 04:39:01 | <sjanssen> | aavogt: btw, I would prefer not to have unsafeCoerce# in xmonad's source code :) |
| 04:39:03 | <mmorrow> | since you don't know that the `l' your function works on is the same `l' that's in the box |
| 04:39:14 | <sjanssen> | aavogt: what if layout transformers were of type "Layout a -> Layout a"? |
| 04:40:13 | <mmorrow> | aavogt: so in that case, unsafeCoerce would just result in segfault |
| 04:40:42 | <mmorrow> | (but with the alternative liftLayout in that paste you don't need it) |
| 04:44:00 | <mmorrow> | ooh, also this is an option too |
| 04:44:04 | <aavogt> | sjanssen: yeah, I'm after layout transformers to be Endo (Layout a) |
| 04:44:39 | <mmorrow> | liftLayout :: (LayoutClass m a) => (forall l. LayoutClass l a. => l a -> m a) -> Layout a -> Layout a |
| 04:45:53 | <sjanssen> | that seems easy to write, no? |
| 04:47:08 | <aavogt> | mmorrow: any ideas as how to solve the: Inferred type is less polymorphic than expected; Quantified type variable `l' escapes |
| 04:47:30 | <hackagebot> | bindings-common 0.1 |
| 04:47:56 | <aavogt> | from say (liftLayout Mirror) where Mirror has the correct instances |
| 04:52:16 | <mmorrow> | hmm |
| 04:54:23 | <mmorrow> | aavogt: i'd have to see the specific code i think |
| 04:55:01 | <mmorrow> | (like, what's the definition of LayoutClass, and of Mirror, and which version of liftLayout are you using?) |
| 04:55:23 | <aavogt> | http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5437#a5437 |
| 04:55:29 | <mmorrow> | ACTION looks |
| 04:57:15 | <mmorrow> | aavogt: what about Mirror? |
| 04:57:23 | <mmorrow> | (are these all in XMonad?) |
| 04:57:33 | <hackagebot> | bindings-sqlite3 0.0.1 |
| 04:57:48 | <aavogt> | mmorrow: http://hackage.haskell.org/packages/archive/xmonad/0.8.1/doc/html/XMonad-Layout.html#t%3AMirror |
| 04:57:59 | <mmorrow> | ha, perfect |
| 04:58:03 | <mmorrow> | s/ha/ah/ |
| 05:00:33 | <hackagebot> | bindings-libusb 0.0.1 |
| 05:04:49 | <malouin> | how does HDBC relate to hsql? |
| 05:05:19 | <Gracenotes> | Haskell :D |
| 05:06:22 | <Apocalisp> | @bot |
| 05:06:22 | <lunabot> | :) |
| 05:06:31 | <lambdabot> | :) |
| 05:07:25 | <Elly> | haskell relates to everything |
| 05:07:30 | <Elly> | by force if necessary |
| 05:08:40 | <aavogt> | thanks for helping with this mmorrow, I think the latest problem is the that resuling layout type (m) depends on the input (l). But it doesn't really escape afaict :( |
| 05:09:01 | <mmorrow> | yeah, it's the `l' in Mirror that's causing the problem here |
| 05:09:18 | <mmorrow> | you might be able to work around it by making something like: |
| 05:09:24 | <mmorrow> | data ExistMirror a = forall l. (LayoutClass l a, Read (l a)) => ExistMirror (Mirror l a) |
| 05:09:40 | <mmorrow> | and using that, but then you have to hand-define an instance of Read for that |
| 05:10:20 | <mmorrow> | (which i was just trying but am getting errors about "(LayoutClass l a, Read (l a))" not being known, even though it's there in the ExistMirror def |
| 05:10:24 | <mmorrow> | which is annoying |
| 05:10:39 | <mmorrow> | maybe if ExistMirror was a GADT? |
| 05:10:52 | <mmorrow> | anyways, yeah this looks semi-painful :) |
| 05:11:34 | <dmwit> | > 6^6^6 * logBase 10 6 :: CReal |
| 05:11:39 | <lambdabot> | mueval-core: Prelude.read: no parse |
| 05:11:39 | <lambdabot> | mueval: ExitFailure 1 |
| 05:11:45 | <dmwit> | > 6 :: CReal |
| 05:11:46 | <lambdabot> | 6.0 |
| 05:11:54 | <dmwit> | > 6^6^6 :: CReal |
| 05:12:00 | <lambdabot> | mueval-core: Prelude.read: no parse |
| 05:12:00 | <lambdabot> | mueval: ExitFailure 1 |
| 05:12:04 | <dmwit> | okay then |
| 05:14:40 | <aavogt> | > 6^6^6 |
| 05:14:42 | <lambdabot> | 265911977215322677968248940438791859490534220026992430066043278949707355987... |
| 05:14:51 | <aavogt> | > 6^6 |
| 05:14:52 | <lambdabot> | 46656 |
| 05:15:01 | <aavogt> | > 6^6 :: CReal |
| 05:15:02 | <lambdabot> | 46656.0 |
| 05:15:19 | <aavogt> | > length $ show $ 6^6^6 |
| 05:15:20 | <lambdabot> | 36306 |
| 05:15:37 | <hackagebot> | bindings 0.1.1 |
| 05:19:22 | <aavogt> | mmorrow: the layout being modified shows up in the type of every modified layout, but perhaps the best thing to do would be to change them to start off as (Layout a -> Layout a) |
| 05:19:58 | <aavogt> | since this liftLayout has not worked out |
| 05:20:50 | <mmorrow> | possibly, i'm not sure all the moving pieces. what hard here is that you can't modify the types that already exist in xmonad.. |
| 05:21:31 | <mmorrow> | aavogt: but yeah, i'd probably try a different angle of attack |
| 05:22:50 | <mmorrow> | (different from the original i mean, not different than (Layout a -> Layout a), that could work (not sure) :) |
| 05:35:23 | <aavogt> | mmorrow: thanks again, and good night. Hopefully we'll find a better solution to this issue later. |
| 05:38:41 | <mmorrow> | aavogt: good luck |
| 05:49:03 | <jimmyjazz14> | I'm looking for an example of mapping a function over the lines in a file. |
| 05:50:45 | <mmorrow> | main = putStr . unlines . fmap f . lines =<< getContents |
| 05:51:23 | <mmorrow> | better would be |
| 05:51:26 | <mmorrow> | main = putStr . unlines . f . lines =<< getContents |
| 05:51:31 | <mmorrow> | then you could do e.g. |
| 05:51:51 | <mmorrow> | f = zipWith (\n l -> n ++ ":" ++ l) [1..] -- number lines |
| 05:51:53 | <mmorrow> | etc |
| 05:52:19 | <Gracenotes> | :o |
| 05:52:32 | <mmorrow> | f = fmap (show . length) -- number of char on each line |
| 05:53:01 | <mmorrow> | err, show n |
| 05:53:06 | <mmorrow> | f = zipWith (\n l -> show n ++ ":" ++ l) [1..] -- number lines |
| 05:57:01 | <rick_2047> | hi everyone i was just starting out with haskell and was curious about its functional programming paradigim. i heard its very closely related to discrete mathematics. i am interested in maths so can anyone point me to a source which teaches me this language with a mathematical problem approach |
| 05:57:04 | <jimmyjazz14> | ah thanks |
| 05:59:14 | <Twey> | rick_2047: Perhaps ‘The Haskell Road to Logic, Maths, and Programming’ |
| 06:00:15 | <rick_2047> | Twey, sounds interesting lemme just read a review on amazon |
| 06:01:03 | <Twey> | I'm not sure I'd describe Haskell as ‘closely related’ to any branch of mathematics |
| 06:01:18 | <Twey> | It does use a lot of mathematical concepts, but at its heart it is a programming language |
| 06:01:40 | <Twey> | Better to say it borrows from mathematics, perhaps |
| 06:02:27 | <rick_2047> | Twey, dats exactly what i mean but you see haskell is used in a lots of maths project and a friend suggested that i use it in my math experiments |
| 06:03:36 | <Twey> | Don't forget that Mathematic is the world's most powerful computational software. |
| 06:03:39 | <Twey> | Mathematica** |
| 06:15:16 | <sayyestolife> | what's up? |
| 06:17:00 | <dmwit> | ?wn up |
| 06:17:11 | <dmwit> | uh... |
| 06:17:13 | <dmwit> | ?botsnack |
| 06:17:27 | <dmwit> | Don't worry, I've got \bot's back! |
| 06:17:47 | <dmwit> | up (adj): being or moving higher in position or greater in some value |
| 06:19:03 | <dmwit> | sayyestolife: Doing any awesome Haskell hacks? |
| 06:19:28 | <lambdabot> | *** "up" wn "WordNet (r) 2.0" |
| 06:19:28 | <lambdabot> | up |
| 06:19:28 | <lambdabot> | adj 1: being or moving higher in position or greater in some value; |
| 06:19:30 | <lambdabot> | being above a former position or level; "the anchor is |
| 06:19:32 | <lambdabot> | up"; "the sun is up"; "he lay face up"; "he is up by a |
| 06:19:33 | <sayyestolife> | dmwit, no, I'm actually trying to figure out if there is a way to get max integer size in Ada |
| 06:19:34 | <lambdabot> | [28 @more lines] |
| 06:19:36 | <lambdabot> | :) |
| 06:19:40 | <dmwit> | laaaag |
| 06:19:47 | <ski> | @uptime |
| 06:19:48 | <lambdabot> | uptime: 5d 23h 25m 16s, longest uptime: 1m 10d 23h 44m 29s |
| 06:20:13 | <dmwit> | ACTION didn't know anybody used ada any more |
| 06:20:26 | <sayyestolife> | heh, it's for university |
| 06:25:27 | <p_l> | dmwit: it's still used in the same places as always :) |
| 06:25:53 | <dmwit> | so... the military? |
| 06:26:51 | <stepnem> | http://auroraux.blastwave.org/index.php/Main_Page |
| 06:27:38 | <p_l> | dmwit: embedded and critical stuff |
| 06:32:52 | <hydo> | Out of curiosity, does anyone here use netbsd? I'm thinking of using it for an embedded experiment. |
| 08:01:08 | <mreh> | @go yi |
| 08:01:10 | <lambdabot> | http://en.wikipedia.org/wiki/Yi |
| 08:01:10 | <lambdabot> | Title: Yi - Wikipedia, the free encyclopedia |
| 08:01:24 | <mreh> | @go site:haskell.org yi |
| 08:01:26 | <lambdabot> | http://www.haskell.org/haskellwiki/Yi |
| 08:01:26 | <lambdabot> | Title: Yi - HaskellWiki |
| 08:41:48 | <dibblego> | @type \x f -> case x of [] -> []; (h:t) -> f h : t -- is there a combinator for this in the standard library? |
| 08:41:49 | <lambdabot> | forall a. [a] -> (a -> a) -> [a] |
| 08:44:31 | <Gracenotes> | not that I know of... |
| 08:50:02 | <ski> | @let list :: as -> (a -> as -> as) -> ([a] -> as); list nil cons [] = nil; list nil cons (a:as) = cons a as |
| 08:50:03 | <lambdabot> | Couldn't match expected type `as' against inferred type `[a]' |
| 08:50:17 | <ski> | @let list :: as -> (a -> [a] -> as) -> ([a] -> as); list nil cons [] = nil; list nil cons (a:as) = cons a as |
| 08:50:18 | <lambdabot> | Defined. |
| 08:50:35 | <ski> | @type flip $ \f -> list [] ((:) . f) |
| 08:50:37 | <lambdabot> | forall b. [b] -> (b -> b) -> [b] |
| 09:06:12 | <dibblego> | @type \f x -> ((++) . (f <$>)) `uncurry` (splitAt 1 x) |
| 09:06:13 | <lambdabot> | forall a. (a -> a) -> [a] -> [a] |
| 09:06:29 | <dibblego> | >let k = \f x -> ((++) . (f <$>)) `uncurry` (splitAt 1 x) in k "abc" |
| 09:06:33 | <dibblego> | > let k = \f x -> ((++) . (f <$>)) `uncurry` (splitAt 1 x) in k "abc" |
| 09:06:35 | <lambdabot> | Couldn't match expected type `a -> a' |
| 09:06:41 | <dibblego> | > let k = \f x -> ((++) . (f <$>)) `uncurry` (splitAt 1 x) in k toUpper "abc" |
| 09:06:42 | <lambdabot> | "Abc" |
| 09:06:47 | <voker57__> | how to modify one field in 'data' type? |
| 09:07:04 | <ski> | > (\f -> list [] ((:) . f)) toUpper "abc" |
| 09:07:06 | <lambdabot> | "Abc" |
| 09:07:33 | <lars9> | hi, who knows how to uninstall all packages installed by cabal-install? |
| 09:07:42 | <voker57__> | like ???? $ Wtf {a = 2, b =3} = Wtf {a=2, b=4} |
| 09:08:00 | <eivuokko> | lars9, Assuming ghc, use ghc-pkg unregister to remove them from package database and remove the files by hand. |
| 09:08:31 | <ski> | let wtf = Wtf {a = 2, b = 3} in wtf {b = 4} -- voker57__ ? |
| 09:10:50 | <ski> | > let wtf = Node {rootLabel = 2,subForest = []} in wtf {subForest = [Node {rootLabel = 3,subForest = []}]} |
| 09:10:52 | <lambdabot> | Node {rootLabel = 2, subForest = [Node {rootLabel = 3, subForest = []}]} |
| 09:11:50 | <cayennext> | I am trying to implement IO using dialogs and I have some problems with it. Process is a function that takes a request and returns response and program is a function that returns list of requests and have responses passed as argument. Please look at those 13 lines of code: http://pastebin.com/m2f1e06d0. It works well if both functions are pure ((1) in code). But when I added IO to process ((2) in code), it doesn't work. Can someon |
| 09:11:50 | <cayennext> | e help me with this? |
| 09:11:52 | <ski> | let ftw wtf = wtf {subForest = [Node {rootLabel = 3,subForest = []}]} in ftw $ Node {rootLabel = 2,subForest = []} |
| 09:11:55 | <ski> | > let ftw wtf = wtf {subForest = [Node {rootLabel = 3,subForest = []}]} in ftw $ Node {rootLabel = 2,subForest = []} |
| 09:11:57 | <lambdabot> | Node {rootLabel = 2, subForest = [Node {rootLabel = 3, subForest = []}]} |
| 09:16:02 | <ski> | {-# LANGUAGE RecursiveDo #-} |
| 09:16:04 | <ski> | run :: IO (List Request, List Response) |
| 09:16:13 | <ski> | run = mdo responses <- process requests |
| 09:16:23 | <ski> | let requests = program responses |
| 09:16:32 | <ski> | return (requests, responses) |
| 09:16:44 | <ski> | cayennext : tried something like that ? |
| 09:16:59 | <cayennext> | I didn't know about this lang extension |
| 09:17:12 | <cayennext> | thank you |
| 09:17:37 | <ski> | Chapter 7. GHC Language Features 7.3. Syntactic extensions 7.3.6. The recursive do-notation <http://www.haskell.org/ghc/docs/latest/html/users_guide/syntax-extns.html#mdo-notation> |
| 09:18:31 | <voker57__> | ski: thanks |
| 09:19:54 | <ski> | The Hugs 98 User's Guide - Chapter 6. Language extensions supported by Hugs and GHC - 6.1. Syntactic extensions - 6.1.1. Recursive do-notation - <http://cvs.haskell.org/Hugs/pages/users_guide/hugs-ghc.html#RECURSIVE-DO> |
| 09:20:43 | <cayennext> | there's a problem: <<exception: loop>> |
| 09:22:12 | <cayennext> | my code heavily relies on laziness, can it work with unfinished data? |
| 09:23:05 | <ski> | possibly you need to use `~' (more ?) ? |
| 09:23:12 | <cayennext> | from documentation: "The do-notation of Haskell does not allow recursive bindings". That's what I am trying to do in this code. |
| 09:23:25 | <cayennext> | sorrry |
| 09:23:34 | <cayennext> | thought it's about mdo |
| 09:23:55 | <voker57__> | wtf {a=3} works ok, but can i use it as curried function? Like for map |
| 09:24:20 | <ski> | map (\wtf -> wtf {a = 3}) |
| 09:24:57 | <voker57__> | ah, lambdas |
| 09:25:54 | <Beelsebob> | voker57__: usually the first thing I do when I define a record is write a bunch of boilerplate definitions: |
| 09:26:14 | <Beelsebob> | setA w na = w{a=na} |
| 09:26:16 | <Beelsebob> | etc |
| 09:26:37 | <voker57__> | not nice at all... |
| 09:26:48 | <Beelsebob> | no, record syntax in haskell fails |
| 09:27:34 | <ski> | @type let foo Node {rootLabel = r,subForest = f} = (r,f) in foo |
| 09:27:36 | <lambdabot> | forall t. Tree t -> (t, Forest t) |
| 09:27:45 | <ski> | @type let foo t {rootLabel = r,subForest = f} = (t,r,f) in foo |
| 09:27:46 | <lambdabot> | Parse error in pattern |
| 09:28:02 | <ski> | @type let foo (t {rootLabel = r,subForest = f}) = (t,r,f) in foo |
| 09:28:04 | <lambdabot> | Parse error in pattern |
| 09:28:06 | <ski> | mhm |
| 09:28:11 | <mux> | Data.Accessor helps with that |
| 09:48:44 | <cayennext> | fun = do { x <- g; return 1:x }. If g = _|_, can I get head of f where f <- fun? |
| 09:49:58 | <Twey> | cayennext: Yes |
| 09:50:09 | <cayennext> | What extension shoul I use? |
| 09:50:16 | <Twey> | No extension required |
| 09:50:23 | <Twey> | Oh! |
| 09:50:30 | <Twey> | Depends on the monad, though |
| 09:50:35 | <cayennext> | IO |
| 09:50:43 | <Twey> | Yeah, IO is strict, so that won't work |
| 09:50:55 | <Twey> | x can be _|_, but g cannot |
| 09:50:56 | <cayennext> | any extension magic to fix this? |
| 09:51:10 | <Twey> | No — it doesn't make sense to ‘fix’ it |
| 09:51:26 | <Twey> | Imagine if your IO actions weren't performed in the order you told them to be :-P |
| 09:51:35 | <cayennext> | :) |
| 09:53:34 | <Cale> | cayennext: Basically, if you have something like do x <- undefined; return (1:x) it has to evaluate the 'undefined' in order to tell that it isn't supposed to go and print something to screen there. |
| 09:54:47 | <cayennext> | Yes, now I see what I was trying to do, I should try another way. |
| 09:55:47 | <Cale> | You could use unsafeInterleaveIO to cheat though. |
| 09:56:08 | <Cale> | Prelude System.IO.Unsafe> do (y:ys) <- do { x <- unsafeInterleaveIO undefined; return (1:x) }; print y |
| 09:56:08 | <Cale> | 1 |
| 09:56:18 | <mreh> | I'm running the configure script in the ghc 6.10 binary, and I get this |
| 09:56:19 | <mreh> | configure: error: cannot determine current directory |
| 09:56:31 | <Cale> | mreh: What platform? |
| 09:56:32 | <cayennext> | I cannot. Professor said: no unsafe. |
| 09:56:38 | <mreh> | Cale: debian |
| 09:56:47 | <Twey> | Good professor |
| 09:56:49 | <Cale> | x86 or x86_64 ? |
| 09:57:01 | <mreh> | Cale: x86 |
| 09:57:30 | <mreh> | it's GHC6.1.3 |
| 09:57:32 | <mreh> | it's GHC6.10.3 |
| 09:58:00 | <Cale> | mreh: Hmm, I recall getting that error when I accidentally tried to install the x86 package on a 64bit machine. |
| 09:58:21 | <mreh> | Cale: I'm definately not 64bit! |
| 09:58:27 | <mreh> | definitely* |
| 09:58:39 | <Cale> | okay :) |
| 09:58:59 | <mreh> | i've got one machine that has taken 3 hours to install cabal, and one that thinks it's 64 bit!!! |
| 09:59:27 | <dcoutts> | mreh: if it's been stuck for 3 hours then something is very wrong |
| 09:59:34 | <mreh> | dcoutts: its IO bound |
| 09:59:50 | <dcoutts> | linking programs takes at most 30 seconds over slow NFS |
| 10:00:07 | <Cale> | Maybe it's just caused by a similar problem. ISTR the GHC binary package coming with a funky version of pwd which is usually the first thing to fail if there's an incompatibility. |
| 10:01:09 | <mreh> | dcoutts: I have no memory to speak of |
| 10:01:33 | <mreh> | I figured it was writing and reading virtual memory the whole time |
| 10:01:56 | <mreh> | stupid laptop |
| 10:02:10 | <Cale> | mreh: try running ./utils/pwd/pwd forwardslash from the root of the package directory |
| 10:02:16 | <Cale> | mreh: does it work? |
| 10:03:00 | <mreh> | what does that do? |
| 10:03:14 | <Cale> | It should just print the current directory you're in |
| 10:03:18 | <mreh> | it reminds me of people telling you to press ALT-F4 |
| 10:03:26 | <Cale> | (using forwardslashes) |
| 10:03:44 | <Cale> | pwd is a standard unix command, but for whatever reason, the ghc installer includes its own |
| 10:04:15 | <Cale> | and usually if there's a dependency problem, it's the first place in the install to fail |
| 10:04:17 | <mreh> | ./utils/pwd/pwd: error while loading shared libraries: libgmp.so.3: cannot open shared object file: No such file or directory |
| 10:04:19 | <Cale> | aha |
| 10:04:23 | <Cale> | So you have no libgmp |
| 10:04:43 | <mreh> | what on earth is that? |
| 10:04:55 | <Cale> | It's the C library used to implement the Integer type in Haskell. |
| 10:04:55 | <ski> | (cayennext : it's arguable whether `unsafeInterleaveIO' actually is "unsafe", though ..) |
| 10:05:20 | <mreh> | it's completely missing from my installation of GHC?! |
| 10:05:21 | <Cale> | apt-get install libgmp3c2 |
| 10:05:48 | <Twey> | It should be a dependency... |
| 10:05:53 | <Twey> | Oh, wait, you're compiling from source? |
| 10:06:03 | <Cale> | He's installing the generic binary |
| 10:06:20 | <Cale> | It probably should try to discover when that library is missing. |
| 10:06:33 | <Twey> | Yeah |
| 10:06:41 | <Twey> | I thought there were plans for an installer. |
| 10:07:26 | <Cale> | It's probably that someone overlooked that ./utils/pwd/pwd is written in Haskell and linked against libgmp and so if you run it before the test for libgmp the installer will fail without telling the user anything sensible. |
| 10:07:40 | <mreh> | configure: error: C compiler cannot create executables |
| 10:07:47 | <Cale> | Oh, nice. |
| 10:07:55 | <Twey> | >.< |
| 10:08:28 | <mreh> | I think I might try and upgrade my distribution |
| 10:09:08 | <mreh> | What does that even mean?! |
| 10:09:48 | <Cale> | I'm a bit surprised that the C compiler needs to be able to create executables to install the binary ghc... |
| 10:10:00 | <Cale> | It means that your install of GCC is broken though. |
| 10:10:29 | <Cale> | (or that autoconf's script thinks it is, anyway) |
| 10:10:35 | <p_l> | Cale: or that your options cause it to fail - had this with misplaced -mach |
| 10:12:10 | <kynes> | hi, I'm currently using catch from Control.Exception to run functions safely in my application |
| 10:12:21 | <kynes> | is there a way to specify a time limit on a function run / expression ? |
| 10:12:35 | <Cale> | kynes: System.Timeout |
| 10:12:42 | <kynes> | Cale, how can I use that? |
| 10:12:49 | <Cale> | timeout :: Int -> IO a -> IO (Maybe a) |
| 10:12:59 | <Cale> | I believe the parameter is in microseconds |
| 10:13:01 | <mreh> | my ghc wont install :''''( |
| 10:13:09 | <kynes> | Cale, okay thanks |
| 10:13:18 | <Heffalump> | does that work with let loop () = loop () in loop () ? |
| 10:13:22 | <mreh> | Cale: should I tinked with the configure script? |
| 10:13:26 | <mreh> | tinker* |
| 10:13:33 | <kynes> | Cale, if expression times out, what does it give as return value ? |
| 10:13:34 | <Cale> | Heffalump: probably if you apply evaluate to it first |
| 10:13:41 | <Cale> | kynes: Nothing |
| 10:13:52 | <Cale> | kynes: and if not, it gives Just x |
| 10:13:56 | <Heffalump> | most things only interrupt when an allocation happens, and that never allocates and never blackholes |
| 10:14:01 | <Heffalump> | or at least didn't the last time I checked |
| 10:15:00 | <Cale> | Prelude System.Timeout Control.Exception> timeout 1000000 (evaluate (let loop () = loop () in loop ())) |
| 10:15:00 | <Cale> | Nothing |
| 10:15:28 | <Berengal> | Prelude System.Timeout> timeout 10000 (return (loop ())) |
| 10:15:28 | <Berengal> | Just ^CInterrupted. |
| 10:15:47 | <Cale> | Of course, since return is not strict. |
| 10:16:09 | <Berengal> | Indeed, 's what I thought |
| 10:17:37 | <Berengal> | Prelude System.Timeout> timeout 10000 (loop () `seq` return ()) |
| 10:17:37 | <Berengal> | Nothing |
| 10:19:27 | <mreh> | http://moonpatio.com/fastcgi/hpaste.fcgi/view?id=2530#a2530 <--- This is the config.log |
| 10:19:51 | <kynes> | Cale, Berengal, thank you both |
| 10:20:06 | <mreh> | look at the failed program |
| 10:21:48 | <Athas> | How can I do unsigned arithmetic in Haskell? Or just shift Int32's without sign extension? |
| 10:21:56 | <Bacta> | @faggot Can haskell.. |
| 10:21:56 | <lambdabot> | Unknown command, try @list |
| 10:22:36 | <olsner> | Athas: you have Word and Word32 etc that correspond to the Int types but are unsigned |
| 10:22:44 | <Berengal> | > 256 :: Word8 |
| 10:22:45 | <lambdabot> | 0 |
| 10:22:57 | <olsner> | > 255 :: Int8 |
| 10:22:58 | <lambdabot> | -1 |
| 10:23:23 | <Athas> | olsner: nifty, thanks. |
| 10:26:09 | <voker57__> | @hoogle (a -> a -> a) -> (a -> a) |
| 10:26:10 | <lambdabot> | Prelude foldl1 :: (a -> a -> a) -> [a] -> a |
| 10:26:10 | <lambdabot> | Prelude foldr1 :: (a -> a -> a) -> [a] -> a |
| 10:26:10 | <lambdabot> | Data.List foldl1 :: (a -> a -> a) -> [a] -> a |
| 10:26:49 | <kynes> | I run on hugs and it says: Can't find imported module "System.Timeout" |
| 10:27:02 | <kynes> | I'm on Ubuntu, is the default hugs package "minimal" ? |
| 10:27:13 | <kynes> | I can import System.Environment |
| 10:28:06 | <kynes> | is this an extra haskell package ? |
| 10:28:11 | <kynes> | I mean Timeout |
| 10:28:49 | <Cale> | kynes: Oh, it's something that comes with GHC |
| 10:29:24 | <kynes> | Cale, :( I was currently using runhugs |
| 10:30:38 | <Cale> | kynes: One moment while I get you a snippet of code to do a similar thing... |
| 10:30:52 | <Cale> | oh, heh, we can just steal the code probably |
| 10:31:11 | <kynes> | Cale, :) thanks man |
| 10:31:15 | <Cale> | er... hmm |
| 10:31:15 | <mreh> | editline-0.2.1.0 is missing from GHC6.10.3 |
| 10:31:45 | <Cale> | mreh: right, it's gotten rid of the use of editline. I think the package can be obtained from hackage still if you really need it(?) |
| 10:32:18 | <mreh> | Cale: i'm installing the haskell platform with 6.10.3 |
| 10:32:28 | <mreh> | i think it was distributed with .2 |
| 10:33:06 | <mreh> | I only wanted to install the platform to get cabal, but i need cabal to install editline |
| 10:33:10 | <mreh> | :D |
| 10:33:21 | <mreh> | ACTION sighs |
| 10:34:07 | <dcoutts> | mreh: use the configure option to allow building with an unsuported ghc version |
| 10:35:45 | <mreh> | dcoutts: it appears to be undocumented, short of looking in the script, is there something you would guess at? |
| 10:36:30 | <Berengal> | Isn't cabal included in the ghc install? |
| 10:36:36 | <mreh> | no |
| 10:36:41 | <mreh> | the haskell platform |
| 10:37:44 | <dcoutts> | mreh: ./configure --help |
| 10:38:18 | <Cale> | kynes: ah, okay, in Hugs it can't work the same way as it does in GHC, since in GHC, what it does is to start a thread which throws an exception back to the original thread when the timeout is up, and Hugs doesn't support throwTo |
| 10:38:20 | <mreh> | yeah, thanks |
| 10:38:43 | <kynes> | Cale, oh |
| 10:38:52 | <Cale> | kynes: So, I can just get you some code which I wrote a long time ago. The difference is that it doesn't run the timed-out computation in the original thread. |
| 10:39:09 | <Cale> | http://www.haskell.org/haskellwiki/Timing_out_computations |
| 10:39:25 | <Cale> | The first two snippets on that page ought to work, I think... |
| 10:40:01 | <kynes> | Cale, okay I'm taking a look |
| 10:40:45 | <Cale> | Oh, d'oh, hugs has no killThread either. |
| 10:40:52 | <Cale> | Why are you using hugs anyway? |
| 10:42:58 | <kynes> | Undefined variable "threadDelay" for 1st snippet |
| 10:43:01 | <Cale> | Heh, apparently in Hugs, the ThreadId type is a synonym for () |
| 10:43:16 | <Cale> | kynes: I didn't get that... did you remember to import Control.Concurrent? |
| 10:43:39 | <Cale> | But still, the killThread that it absolutely requires isn't there. |
| 10:44:22 | <kynes> | Cale, yes I imported that, just as in the snippet |
| 10:44:32 | <stroan> | "T a -> (a -> T a) -> a" I'm trying to make a monad, where bind ignores any operations after a certain situation holds true, simply passing on the previous state. But obviously, that does not match the requirement for bind in a monad. Is there any way to do this without making each function deal with that functionallity and making bind trivial |
| 10:44:50 | <Cale> | kynes: hugs is a somewhat impoverished environment for writing actual applications. |
| 10:45:01 | <Peaker> | Cale: that code is very similar to unamb's race - except it doesn't handle exceptions/etc |
| 10:45:12 | <Twey> | Hugs is for learning, Yhc is for playing, GHC is for working :-P |
| 10:45:15 | <Peaker> | (compete, that is) |
| 10:45:48 | <Cale> | Peaker: yeah |
| 10:45:54 | <Peaker> | one shouldn't write do { resourceAllocation ; ... ; resourceFreeing } in code -- should always use bracket, or a withResource thing |
| 10:46:24 | <Cale> | Peaker: hm? |
| 10:46:42 | <Peaker> | Cale: resourceFreeing should always be made to happen, even if the code in between throws or such |
| 10:46:56 | <Cale> | Peaker: yyyes... I don't see what you're referring to. |
| 10:47:00 | <kynes> | Cale, I was using hugs to evaluate simple Haskell codes without throwing every code piece to GHC and use the output |
| 10:47:11 | <Cale> | kynes: ghci? |
| 10:47:11 | <kynes> | Cale, it was a quick solution together with Python |
| 10:47:14 | <Peaker> | http://www.haskell.org/haskellwiki/Timing_out_computations -- compete has forkIO's and then killThreads |
| 10:47:21 | <kynes> | Cale, oh sorry, yes :) |
| 10:47:33 | <Saizan_> | stroan: your monad sounds like MaybeT (State s) |
| 10:47:40 | <Peaker> | and timeoutIterate has too |
| 10:47:50 | <Cale> | Peaker: Well, it more or less is the abstraction wrapper. |
| 10:48:09 | <Cale> | Peaker: You have to write the bracket-like-thingy somewhere :) |
| 10:48:34 | <kynes> | Cale, can I use ghci just as I use runhugs ? |
| 10:48:40 | <Peaker> | Cale: it could use a lower-level abstraction wrapper in it -- something like: withThread that scopes the operations afterwards and guarantees the thread is killed |
| 10:48:47 | <Cale> | kynes: There's runghc |
| 10:48:58 | <Cale> | kynes: Which works in more or less the same way :) |
| 10:49:35 | <Cale> | Peaker: I'm not sure it would make it any clearer, but you can try. :) |
| 10:50:28 | <ski> | stroan : define your own combinator which does what you want ? |
| 10:50:37 | <kynes> | Cale, ghci throws more parse errors than hugs.. :/ |
| 10:50:53 | <Cale> | kynes: Can you paste the code on hpaste or something? |
| 10:52:19 | <stroan> | ski: Aye. That's what I have, I'm just trying to wrap it all up into a monad at the moment. |
| 10:52:24 | <Cale> | stroan: Could what you're describing be more or less similar to using a continuation? |
| 10:53:10 | <Cale> | stroan: That is, you wrap the whole thing in a callCC and when you reach the condition you mentioned, you call the continuation that's been passed in? |
| 10:53:38 | <ski> | stroan : maybe you could use an exception or continuation monad to abort the monadic computation when the "certain situation holds true", cutting off the rest of the bind operations ? |
| 10:54:32 | <kynes> | Cale, http://pastebin.com/d39d5e2f6 |
| 10:54:51 | <stroan> | I'll look into these. I'm extremely new to all this. Writting this application to get my head around monads really. |
| 10:54:53 | <kynes> | parse error on input `;' for line 9 |
| 10:55:13 | <Cale> | Yeah, you have a spurious ; at the end of the line there |
| 10:55:15 | <Cale> | delete it |
| 10:55:15 | <kynes> | which runs fine in Hugs |
| 10:55:38 | <Cale> | It shouldn't. |
| 10:55:49 | <Saizan_> | stroan: maybe you can paste your type and your combinator, and we can take a look |
| 10:55:49 | <ski> | stroan : you might try pasting your code (and/or explaining more what you're about) |
| 10:55:52 | <kynes> | Cale, I cannot delete it because it's student code :) they have built their homework around Hugs |
| 10:56:19 | <kynes> | Cale, is there a way to make GHCi more flexible like Hugs ? |
| 10:56:36 | <Cale> | That ; isn't correct Haskell syntax and I have no idea why hugs would accept it |
| 10:56:55 | <stroan> | will do now |
| 10:57:57 | <Cale> | ; is a separator, not a terminator, and is only allowed inside of blocks, which occur in the 'let' portion of a let/in (but not the in), after 'where', 'do' and 'of' for a case |
| 10:58:29 | <kynes> | Cale, you're definitely right |
| 10:58:30 | <ski> | (kynes : btw "Unknown post id, it may have expired or been deleted") |
| 10:58:49 | <kynes> | ski, oh I'll repost |
| 10:58:52 | <kynes> | ski, sorry |
| 10:59:18 | <stroan> | http://moonpatio.com/fastcgi/hpaste.fcgi/view?id=2531 I'm trying to write a parser. |
| 10:59:24 | <kynes> | ski, http://pastebin.com/d67416773 |
| 10:59:41 | <Cale> | stroan: btw, you're indenting if/then/else unconventionally |
| 10:59:59 | <Cale> | stroan: the normal Haskell way is to always line up the 'then' with the 'else' |
| 11:00:00 | <stroan> | what would be standard? |
| 11:00:04 | <Cale> | So it goes |
| 11:00:07 | <Cale> | if foo |
| 11:00:09 | <Cale> | then bar |
| 11:00:12 | <Cale> | else quux |
| 11:00:26 | <Cale> | Or something like |
| 11:00:27 | <stroan> | ah, my every other language ever days coming back to haunt me ;) |
| 11:00:32 | <Cale> | if foo then bar |
| 11:00:37 | <Cale> | else quux |
| 11:00:45 | <stroan> | will change that now |
| 11:01:01 | <Cale> | It makes sense if you think about it :) |
| 11:01:25 | <stroan> | it does yeah |
| 11:01:29 | <stroan> | just habbits |
| 11:01:29 | <Cale> | The 'then' and 'else' are part of the 'if', so should be indented more than it, and are siblings, so should be indented the same. |
| 11:01:56 | <Cale> | I find it works really nicely in bash scripts too :) |
| 11:02:12 | <Cale> | (you can avoid semicolons :) |
| 11:02:37 | <kynes> | ski, have you taken a look ? |
| 11:02:43 | <kynes> | ski, I'll erase it after some time |
| 11:03:45 | <ski> | > let ; in () |
| 11:03:46 | <lambdabot> | () |
| 11:03:51 | <ski> | > let () = () ; in () |
| 11:03:53 | <lambdabot> | () |
| 11:03:58 | <ski> | > let ; () = () in () |
| 11:04:00 | <lambdabot> | () |
| 11:04:15 | <ski> | ACTION raises eyebrow |
| 11:04:19 | <Beelsebob> | > let ; a = 5 in a |
| 11:04:21 | <lambdabot> | 5 |
| 11:05:09 | <Cale> | > (let a = 5 in a;) |
| 11:05:11 | <lambdabot> | <no location info>: parse error on input `;' |
| 11:05:47 | <Cale> | You can have empty declarations in a let, but the semicolon is totally out of place in an 'in' |
| 11:05:50 | <Baughn> | > let ; ; ; a = 5 in a |
| 11:05:52 | <lambdabot> | 5 |
| 11:06:04 | <Baughn> | > let;a=5 in a |
| 11:06:06 | <lambdabot> | 5 |
| 11:06:17 | <Baughn> | > let;a=5in a |
| 11:06:18 | <lambdabot> | 5 |
| 11:06:20 | <Beelsebob> | looks like a good new way of obfuscating haskell |
| 11:06:23 | <ski> | kynes : i think the `;' in the paste there is ok, as long as you have some declaration/signature/definition after the one defining `executeCommands' |
| 11:06:42 | <kynes> | ski, yes there is |
| 11:06:50 | <kynes> | ski, so indeed the code is okay ? |
| 11:07:06 | <kynes> | I mean, is GHCi at fault ? |
| 11:07:12 | <Cale> | ski: I don't think so... |
| 11:07:13 | <ski> | kynes : not in isolation, but as a fragment followed by more top-level items |
| 11:07:31 | <kynes> | ski, yes, it's used like that in the code indeed |
| 11:07:39 | <Cale> | Note on line 8 the semicolon inside the 'in' which is followed by the 'else' |
| 11:07:44 | <Cale> | That is not valid. |
| 11:07:52 | <Baughn> | > let;a=5in;a |
| 11:07:54 | <lambdabot> | <no location info>: parse error on input `;' |
| 11:07:55 | <ski> | oh .. i missed that one |
| 11:08:11 | <kynes> | ski, http://pastebin.com/d2943c94f updated |
| 11:08:47 | <kynes> | Cale, so there is a bug at Hugs ? |
| 11:09:21 | <kynes> | I noticed that GHCi is also stricter about indentation |
| 11:09:22 | <ski> | (that `in' was indented too much, so i was thinking it was another equation inside that `let' ..) |
| 11:09:22 | <dibblego> | @type \f -> zipWith ($) (f : repeat id) |
| 11:09:24 | <lambdabot> | forall b. (b -> b) -> [b] -> [b] |
| 11:09:33 | <dibblego> | > let k = \f -> zipWith ($) (f : repeat id) in k toUpper "abc" |
| 11:09:35 | <lambdabot> | "Abc" |
| 11:09:38 | <dibblego> | zing! |
| 11:09:49 | <ski> | kynes : generally, one does not indent like |
| 11:09:53 | <ski> | let foo = ... |
| 11:09:58 | <ski> | bar x = ... |
| 11:10:04 | <ski> | in ..foo..bar.. |
| 11:10:14 | <kynes> | ski, I didn't mean the indentation is correct in the pasted code |
| 11:10:21 | <kynes> | ski, I meant another code |
| 11:10:33 | <kynes> | ski, but I fixed that one so cannot paste.. hmm |
| 11:10:40 | <Serica> | i wonder why whatever i specify in --host= when building ghc it always defaults to i386-unknown-linux ? |
| 11:10:51 | <Cale> | kynes: Yes, it is a bug for hugs to accept that |
| 11:11:02 | <ski> | (stroan : btw, s/(elem s list)/elem s list/) |
| 11:11:44 | <stroan> | changed. Any idea how to make the monad do what combine does? |
| 11:11:50 | <kynes> | do I have a Timeout solution I can use in Hugs ? |
| 11:12:05 | <kynes> | ski, Cale, Baughn I'm erasing the post |
| 11:12:09 | <kynes> | is it okay ? |
| 11:12:29 | <ski> | (kynes : i already have it in browser, so sure :) |
| 11:12:34 | <Cale> | sure |
| 11:12:35 | <Serica> | umm i decided to ask in #ghc and close the question here |
| 11:12:36 | <kynes> | ski, :) okay |
| 11:13:15 | <kynes> | thank you very much for your help |
| 11:13:42 | <ski> | stroan : it appears like `extract' tries to separate a longest prefix of characters all occuring in a given list |
| 11:14:39 | <ski> | stroan : could you explain more what you're trying to do ? |
| 11:14:59 | <ski> | how and why are you going to use `extract' and `combine' ? |
| 11:15:46 | <stroan> | aye. there is also an extractWhile function that extracts till a non match. So say I want to extract an identifier which matches the pattern of a123df. The first leter must be a member of ['a'..'z'] and the rest of the letters must be of (['a'..'z'] ++ ['0'..'9']) |
| 11:16:45 | <stroan> | so I call extract with the first pattern. then I call extractwhile with the second pattern. but I want such combinations to terminate when the larger pattern can no longer be matched against |
| 11:18:19 | <kynes> | Cale, http://markmail.org/message/earajbrh2muzppn2#query:haskell%20base%20timeout+page:1+mid:mgpwb2rnxgzjuago+state:results |
| 11:18:21 | <ski> | so `Done' means something like "cannot parse further" while `Cont' means something like "partial parse succeeded, can parse further" ? |
| 11:18:51 | <stroan> | yup |
| 11:18:59 | <Cale> | kynes: yes, this is the code which uses throwTo |
| 11:19:05 | <Cale> | kynes: Which I was trying earlier. |
| 11:19:26 | <Cale> | mm... more or less, anyway |
| 11:19:43 | <Cale> | http://www.haskell.org/ghc/docs/latest/html/libraries/base/src/System-Timeout.html#timeout |
| 11:19:47 | <ski> | (stroan : so why is `Done' not called something like `NoParse' or `ParseError' or `Bad', then ?) |
| 11:20:00 | <stroan> | because it's not nesecarilly a bad thing |
| 11:20:55 | <stroan> | like when matching an arbitrarilly large thing. I just want to match till the pattern fails. so if I have "a+b" it will match the a, and give me a done |
| 11:21:00 | <ski> | if i pass the string "1abc45" for parsing with your identifier parser, wouldn't that return a `Done' result ? |
| 11:21:22 | <kynes> | Cale, ERROR "test.hs" - Unknown entity "throwDynTo" imported from module "Control.Exception" |
| 11:21:29 | <kynes> | Cale, as you said |
| 11:21:37 | <stroan> | it would pass a done, after having extracted nothing |
| 11:21:46 | <Cale> | Right, and that's throwTo in the current library, but neither exists in hugs |
| 11:22:03 | <Cale> | kynes: Hugs doesn't even have a concept of a ThreadId, so it's impossible. |
| 11:22:14 | <ski> | stroan : right .. how is that not a parse error (wrt your identifier parser) ? |
| 11:22:42 | <Cale> | (you can start threads, but there are no operations on them -- you can only use MVars to communicate with them, and they are responsible for stopping themselves) |
| 11:22:57 | <ski> | stroan : e.g. do you expect to be able to extract some partial information for a parse, even if not the whole parse succeeded ? |
| 11:23:49 | <stroan> | Because I'm building this of an LL(1) grammar, so I was going to ask it to check several possible patterns at once and only one of them may match, and return a result and whichever one does is the correct one. |
| 11:24:11 | <stroan> | if multiple patterns match then it's also an error |
| 11:24:23 | <stroan> | but that was going to be checked with other logic |
| 11:25:20 | <ski> | mhm |
| 11:26:10 | <ski> | i'm not convinced your `ParserData' is defined correctly |
| 11:26:32 | <stroan> | It's probably not :/ Though this is as close to working as I've gotten the program in a few days :P |
| 11:27:07 | <stroan> | A third, error, state might be required |
| 11:27:27 | <ski> | btw, you're aware there are already parsing combinator libraries which you might use or at least be inspired by ? |
| 11:27:53 | <stroan> | Aye. This is mostly a get to know haskell / get my head around monads project |
| 11:27:59 | <ski> | i'm not sure why the type signature of `extract' should mention all those `[Char]' |
| 11:29:12 | <ski> | it seems some occurances of `[Char]' there stands for the underlying list of tokens to be parsed, while other occurances of it stands for an identifier being currently implemented as a list of characters |
| 11:29:32 | <ski> | what if you had an abstract type of identifiers, `Ident' |
| 11:29:55 | <ski> | hm |
| 11:30:42 | <stroan> | My current plan is just to tokenise / parse in one step. |
| 11:30:52 | <jkramer> | Hello |
| 11:31:16 | <ski> | (i realize i misread before, `extract' only does one step of identifier parsing) |
| 11:31:26 | <stroan> | aye. |
| 11:31:48 | <stroan> | I also have extractWhile, that extracts until done. |
| 11:31:59 | <ski> | so, what would the type be of an operation for parsing a whole identifier, in your parsing combinator framework ? |
| 11:32:15 | <ski> | (i'm just asking for a type signature, not an implementation) |
| 11:32:16 | <jkramer> | I'm trying to install encoding with cabal, but it seems to hang at 43/47 (Data.Encoding.JISX0208). Does anyone know that problem? |
| 11:32:33 | <jkramer> | ghc eats 99% of CPU |
| 11:32:52 | <jkramer> | Or is that module just very hard to compile? |
| 11:33:54 | <stroan> | extractIdentifier :: String -> ParserData |
| 11:34:01 | <stroan> | and that raises some issues :P |
| 11:34:04 | <Saizan_> | jkramer: the latter |
| 11:34:10 | <ski> | `ParserData' requires a type argument |
| 11:34:22 | <stroan> | ParserData (String,String) |
| 11:34:50 | <jkramer> | Saizan_: But +10 minutes eating ~100% CPU on 2x2Ghz? |
| 11:34:51 | <ski> | and what if an identifier had type `Ident' instead of `String' ? |
| 11:35:15 | <ski> | (you may assume `data Ident = MkI String' if that makes you feel better) |
| 11:35:46 | <jkramer> | The other encodings compiled in < 1s |
| 11:36:08 | <maltem> | jkramer, I tried and I'm seeing the same thing. Let's see how long it takes here :) |
| 11:36:09 | <stroan> | so the signature would be String -> ParserData(Ident, String)? |
| 11:36:37 | <ski> | ok |
| 11:37:07 | <jkramer> | maltem: May the faster machine finish first :) |
| 11:37:26 | <Saizan_> | jkramer: well, two processors don't count when you're using only one :) |
| 11:37:32 | <ski> | so the first occurance of `String' is the input from the point to parse an identifier, and the second occurance of `String' is the input from the point after the identifier being parsed, yes ? |
| 11:37:33 | <jkramer> | That's true |
| 11:37:41 | <stroan> | yes |
| 11:37:51 | <jkramer> | It's not even two processors but just two cores :( |
| 11:38:22 | <jkramer> | Has anyone tried turbinator yet? |
| 11:38:23 | <ski> | your `ParserData m' is basically the same as `Either m m' (just other names for the two constructors) |
| 11:38:37 | <ski> | so that makes your type being roughly |
| 11:38:47 | <ski> | String -> Either (Ident, String) (Ident, String) |
| 11:39:49 | <ski> | iiuc, the first case (the `Cont' case) corresponds to an identifier having been parsed, and also there's some part left of the input string to parse on from |
| 11:39:58 | <jkramer> | He, it just finished :) |
| 11:40:17 | <jkramer> | http://en.wikipedia.org/wiki/JIS_X_0208 - sounds like a lot of characters |
| 11:40:18 | <PeakerWork> | Nicer to have (Bool, Ident, String) ? |
| 11:40:27 | <stroan> | Cont if the last parse was successful. Done if the last match failed |
| 11:40:47 | <ski> | what is the "last parse/match" ? |
| 11:40:52 | <ski> | say the input string is |
| 11:41:04 | <ski> | "a123df+1" |
| 11:41:30 | <ski> | say we want to parse an identifier, and then maybe continue parsing some else with the rest of the input |
| 11:42:14 | <stroan> | the last match it would perform inside the identifier parsing section would be the "+", which it would leave in place and return done |
| 11:42:39 | <stroan> | so Done ("a123df","+1") |
| 11:42:56 | <ski> | so is the first string there a valid identifier ? |
| 11:43:03 | <stroan> | yes |
| 11:43:12 | <ski> | what if the string was |
| 11:43:20 | <ski> | "(1+2)" |
| 11:43:30 | <stroan> | Done ("", "(1+2)") |
| 11:43:31 | <ski> | what should the identifier parser return ? |
| 11:43:43 | <ski> | is the empty string a valid identifier ? |
| 11:43:53 | <stroan> | Nope |
| 11:44:06 | <ski> | then the types doesn't match |
| 11:44:15 | <stroan> | You're right |
| 11:44:22 | <stroan> | I need an error type |
| 11:44:39 | <ski> | or at least a "NoParse" alternative |
| 11:44:50 | <ski> | (maybe that amounts to the same thing :) |
| 11:44:56 | <stroan> | :) |
| 11:45:16 | <ski> | maybe it would be easier to think here of a parser of boolean values |
| 11:45:27 | <ski> | the parser would parse strings as |
| 11:45:30 | <ski> | "True" |
| 11:45:32 | <ski> | as well as |
| 11:45:34 | <ski> | "False" |
| 11:45:54 | <ski> | also allowing there to be any amount of extra tokens/characters after those characters |
| 11:45:59 | <ski> | so |
| 11:46:17 | <ski> | parseBoolean :: String -> ParserData (Bool,String) |
| 11:46:19 | <ski> | maybe ? |
| 11:47:00 | <stroan> | I already have a Token datatype, which I was planning on using a step later. But it's pretty clear you're completely right :) |
| 11:47:00 | <ski> | (the point being that the type `Bool' doesn't contain any such dummy values as the empty string above, so one can't make a mistake in that way at least) |
| 11:47:53 | <ski> | also, i'll give a suggestion, which i'm not completely sure if it applies with the kind of parsing you want to do, but anyway |
| 11:48:24 | <ski> | if you feel you're having this `String -> ParserData (Foo,String)' pattern over and over, consider defining |
| 11:48:36 | <maltem> | jkramer, true, that's a really tough package to compile :o (now at 45/47) |
| 11:48:48 | <ski> | newtype Parser a = MkP (String -> ParserData (a,String)) -- or something similar |
| 11:48:53 | <ski> | so that you can then have |
| 11:49:01 | <ski> | parseBoolean :: Parser Bool |
| 11:49:09 | <ski> | parseIdentifier :: Parser Ident |
| 11:49:58 | <ski> | (also, it might be that even though `ParserData' maybe can't be made into a monad, mayhaps `Parser' can be) |
| 11:50:46 | <stroan> | hmmm, thanks for all this. It is seriously a huge help. |
| 11:51:10 | <stroan> | Haskell really makes it very hard to be unclear in your thinking. |
| 11:51:38 | <ski> | anyway, good luck |
| 11:51:42 | <stroan> | thanks :) |
| 11:51:42 | <ski> | ACTION needs to leave |
| 11:58:34 | <Absolute0> | Is it possible to make Map.lookup x map into a higher order function where x is the only argument, without making a helper function with reversed arguments? (let helper x = Map.lookup x setup) ? |
| 11:59:08 | <Cale> | flip |
| 11:59:12 | <Cale> | :t flip |
| 11:59:13 | <lambdabot> | forall a b c. (a -> b -> c) -> b -> a -> c |
| 11:59:26 | <EvilTerran> | (`Map.lookup` map) |
| 11:59:28 | <Cale> | Or just use a lambda :) |
| 11:59:48 | <Absolute0> | Cale: yeah i was using a lambda but it was to long for my example |
| 11:59:48 | <EvilTerran> | or (flip Map.lookup map), or (\x -> Map.lookup x map)... |
| 12:00:49 | <Absolute0> | does flip have to take 3 parameters? |
| 12:01:03 | <Absolute0> | @let foo x y = x |
| 12:01:04 | <lambdabot> | Defined. |
| 12:01:10 | <Absolute0> | > flip foo |
| 12:01:11 | <lambdabot> | Overlapping instances for GHC.Show.Show (b -> a -> a) |
| 12:01:11 | <lambdabot> | arising from a use... |
| 12:01:17 | <Absolute0> | :( |
| 12:01:39 | <Jedai> | Absolute0: What do you mean ? flip like all functions in Haskell only takes one parameter |
| 12:01:45 | <maltem> | Absolute0, that as because functions cannot be printed |
| 12:01:49 | <maltem> | *was |
| 12:03:10 | <Absolute0> | :t flip foo |
| 12:03:11 | <lambdabot> | forall a b. b -> a -> a |
| 12:03:32 | <Absolute0> | what is forall? |
| 12:03:36 | <Absolute0> | :t forall |
| 12:03:37 | <lambdabot> | Not in scope: `forall' |
| 12:03:43 | <Absolute0> | not a function.. |
| 12:03:58 | <Absolute0> | oh its polymorphic? |
| 12:04:03 | <Jedai> | Absolute0: forall is for all, it just means that a and b are type variables |
| 12:04:11 | <Absolute0> | gotcha |
| 12:04:16 | <Jedai> | Absolute0: like in mathematics |
| 12:04:35 | <Absolute0> | haskell has got to be the closest language to mathematics :) |
| 12:04:55 | <Jedai> | Absolute0: actually you can write forall yourself in your type annotation if you enable some extensions |
| 12:05:25 | <Cale> | (It's because those extensions are enabled that the bot prints it) |
| 12:05:34 | <Absolute0> | I was thinking, why can't you achieve what monads achieve by simply writing a bunch of where declarations? |
| 12:05:37 | <Cale> | Specifically, RankNTypes |
| 12:05:39 | <Jedai> | Absolute0: it's usually implicit, but for some advanced type manipulation, making forall explicit is necessary |
| 12:06:04 | <Absolute0> | each new declaration caliing a previous one |
| 12:06:05 | <Cale> | Absolute0: The point of monads is to have general operations which work across a wide class of libraries that have been recognised. |
| 12:06:09 | <Absolute0> | hence having states |
| 12:06:25 | <Cale> | Monads in general have essentially nothing to do with state. |
| 12:06:29 | <Jedai> | Absolute0: I'm not sure where you're coming from ? Monads are nothing magic, they're just an useful abstraction |
| 12:06:58 | <Twey> | Absolute0: The answer is ‘you can’ |
| 12:06:58 | <Absolute0> | according to most tutorials they seem to simplify state manipulation |
| 12:07:02 | <Jedai> | Absolute0: If you're speaking about the State monad, you sure can do it by hand |
| 12:07:03 | <Twey> | Monads don't do anything magic |
| 12:07:06 | <Cale> | (To think that they do is confusing the abstraction with the application :) |
| 12:07:07 | <Twey> | They just make it prettier |
| 12:07:28 | <Absolute0> | Is there any nice simple to read monad tutorial out there? |
| 12:07:29 | <Cale> | Absolute0: Beware, there are many poor monad tutorials. |
| 12:07:40 | <Absolute0> | the majority of them seem to get too academic |
| 12:07:53 | <Absolute0> | or poor as Cale said :) |
| 12:08:03 | <Jedai> | Absolute0: but if you try to do it on a big example you'll soon understand why we use monads |
| 12:08:05 | <Twey> | And therefore I recommend Cale's excellent Monads as Computation: http://haskell.org/haskellwiki/Monads_as_computation |
| 12:08:27 | <Cale> | Yeah, actually in that one I try to explain what the point is of talking about monads at all. |
| 12:08:44 | <Jedai> | Absolute0: and as other said, State monads are only a small part of what you can do with monads |
| 12:09:11 | <Cale> | If all you want is any one monad, there's no point in talking about monads. For example, if all you want is IO, there's no need to recognise that it's a monad. |
| 12:09:27 | <foo-nix> | twanvl, ping. |
| 12:10:08 | <Cale> | It's only when you get reuse out of the general polymorphic operations in Control.Monad and elsewhere that the fact that anything is a monad becomes useful knowledge. |
| 12:10:17 | <Cale> | Like, for example... |
| 12:10:19 | <Cale> | :t mapM |
| 12:10:21 | <lambdabot> | forall a (m :: * -> *) b. (Monad m) => (a -> m b) -> [a] -> m [b] |
| 12:10:24 | <Cale> | :t sequence |
| 12:10:26 | <lambdabot> | forall (m :: * -> *) a. (Monad m) => [m a] -> m [a] |
| 12:10:29 | <Cale> | :t foldM |
| 12:10:31 | <lambdabot> | forall a b (m :: * -> *). (Monad m) => (a -> b -> m a) -> a -> [b] -> m a |
| 12:10:36 | <Cale> | etc, etc. |
| 12:11:19 | <Absolute0> | isn't forall superflous in the above lines? |
| 12:11:21 | <Cale> | Otherwise, you're just talking about specific combinator libraries, and while even that is new for most people, it's not what monads are about. |
| 12:11:27 | <Absolute0> | no type means all types... |
| 12:11:27 | <Jedai> | Absolute0: it is |
| 12:11:28 | <Cale> | yes |
| 12:11:30 | <Absolute0> | ehh |
| 12:11:35 | <Cale> | It's just being very explicit. |
| 12:11:43 | <Jedai> | Absolute0: but it doesn't hurt anything |
| 12:11:47 | <PeakerWork> | didn't know about foldM |
| 12:11:54 | <Absolute0> | Jedai: might confuse some... |
| 12:11:55 | <Absolute0> | :) |
| 12:11:58 | <Absolute0> | like i was |
| 12:12:11 | <Cale> | In Haskell, if you leave type variables unquantified, they're automatically forall'd at the beginning of the type signature |
| 12:12:22 | <Cale> | But if you place the foralls elsewhere, the meaning changes. |
| 12:12:39 | <Jedai> | Absolute0: Actually the explicit notation is rather clearer in my eyes |
| 12:12:59 | <Cale> | For example, foo :: (forall a. a -> a) -> ... means that foo takes a function *required to be polymorphic* as a parameter |
| 12:13:07 | <Absolute0> | superflous is superflous making it unecessary |
| 12:13:12 | <Jedai> | Absolute0: what might be confusing is the coexistence of an implicit and an explicit notation |
| 12:13:42 | <PeakerWork> | Absolute0: Monads abstract computations that can be sequenced to use previous results. They can be used to abstract state, continuations, exceptions, side effects, and many other interesting things |
| 12:14:00 | <Jedai> | Absolute0: it's not like it will tire the bot... |
| 12:14:00 | <Cale> | Absolute0: But yeah, if you like, you can ignore all that part up to the '.' |
| 12:14:26 | <Cale> | It's just making explicit that m is a type constructor and that a, b are types |
| 12:14:33 | <Cale> | (any types, not particular ones) |
| 12:14:40 | <Absolute0> | PeakerWork: regarding the "sequenced" part i mentioned that simple where clauses could do the job. |
| 12:14:41 | <Jedai> | Absolute0: and being consistent (putting forall everywhere rather than only when it needs to be explicit) is not bad either |
| 12:15:04 | <PeakerWork> | Absolute0: what do you mean? |
| 12:15:20 | <Absolute0> | ie: where x = 5 y = x + 2 z = y + 3 |
| 12:15:42 | <PeakerWork> | Absolute0: That's not "sequencing computations" -- that's just creating a graph for evaluation |
| 12:15:54 | <Jedai> | Absolute0: there is no sequencing in your example |
| 12:16:12 | <Cale> | That is more or less the identity monad without recognising that it's the identity monad. |
| 12:16:15 | <PeakerWork> | Absolute0: "sequencing computation" means "apply whatever sequencing operation the specific Monad implements" in order get exceptions, continuations, failure handling, state, etc |
| 12:16:42 | <Absolute0> | i need to do some RTFM'ing |
| 12:16:59 | <Jedai> | Absolute0: Don't listen to Peaker though, "explicit sequencing" is only one aspect of the capacity of monads |
| 12:16:59 | <PeakerWork> | Absolute0: For example, an "exception monad" might implement the sequencing operation to ignore any computation its requested to sequence, if the previous computation has resulted in error |
| 12:17:13 | <Cale> | Though, of course, let is a bit different in its typing rules than do-notation (which translates in terms of lambdas) would be. |
| 12:17:32 | <Cale> | But that's not a big difference. |
| 12:17:49 | <PeakerWork> | Jedai: What other aspects do you have in mind? |
| 12:17:58 | <Jedai> | PeakerWork: I don't much like "the sequencing operation" to design bind (>>=), it's not the only thing that it can do |
| 12:18:35 | <PeakerWork> | Jedai: I think its a legitimate POV on monads, as the "sequencing order" is always allowed to have semantic significance |
| 12:18:41 | <Jedai> | PeakerWork: I don't see how the list monad enter your description exactly, for me it's not a matter of sequencing |
| 12:18:56 | <Jedai> | PeakerWork: and the monads that can commute ? |
| 12:19:01 | <PeakerWork> | Jedai: even the list monad sequences |
| 12:19:07 | <Jedai> | PeakerWork: No |
| 12:19:13 | <Cale> | Jedai: It's a certain kind of sequencing. The order in which selections are made. |
| 12:19:19 | <PeakerWork> | > liftM2 (,) [1,2] [3,4] /= liftM2 (,) [3,4] [1,2] |
| 12:19:20 | <lambdabot> | True |
| 12:19:22 | <EvilTerran> | Jedai, considering it to be the backtracking computation monad, >>= starts to look like sequencing |
| 12:19:29 | <Cale> | It just happens to have nothing to do with the evaluation order. |
| 12:19:38 | <Cale> | (well, essentially nothing) |
| 12:19:41 | <Jedai> | PeakerWork: the list "sequence" in your example, not the monad |
| 12:19:56 | <PeakerWork> | Jedai: some monads don't sequence, but since monads in general are allowed to sequence -- its hard not to see the sequencing as part of the abstraction of monads |
| 12:20:01 | <Cale> | > do x <- [1..3]; y <- [1..x]; return (x,y) |
| 12:20:03 | <lambdabot> | [(1,1),(2,1),(2,2),(3,1),(3,2),(3,3)] |
| 12:20:38 | <Cale> | Pick a number x from 1 up to 3, then pick a number y from 1 up to x, and return the pair (x,y) |
| 12:20:59 | <Jedai> | PeakerWork: That's part of the capacity of monads, I agree, I just don't think it's a very good idea to use "sequence" and "sequencing operation" as a basic vocabulary to describe monads in general |
| 12:21:00 | <Cale> | So it's a kind of sequence of operations, though the evaluation order is drastically different. |
| 12:21:18 | <Absolute0> | Is it common to have type signatures in where clauses? |
| 12:21:28 | <ivanm> | not really |
| 12:21:34 | <Cale> | I think sequencing is to some extent at the heart of what monads abstract over, but you have to be cautious that you really know what is meant by it. |
| 12:21:56 | <Absolute0> | silly monads |
| 12:22:01 | <Jedai> | Absolute0: it is sometimes necessary, especially if the monomorphism restriction is activated, but it's relatively uncommon |
| 12:22:02 | <Absolute0> | confusing everyone |
| 12:22:10 | <Cale> | Using the term around those who are uninitiated is perhaps dangerous. :) |
| 12:22:14 | <EvilTerran> | Cale, as in, sequencing the flow of information, not the evaluation order |
| 12:22:15 | <EvilTerran> | ? |
| 12:22:23 | <Gracenotes> | Absolute0: in some cases you might even need scoped type variables >_> |
| 12:22:27 | <Cale> | EvilTerran: something like that, I suppose. |
| 12:22:30 | <PeakerWork> | Jedai: Monads do Functor(fmapping) + Applicative(sequencing + value combining) + Monad(can use results of previous sequence to choose how to continue sequencing) |
| 12:22:30 | <sohum> | this is very offtopic, but where would I go to ask a CS question? |
| 12:22:43 | <Absolute0> | the author of the haskell book at yale says that monads should've been called "warm and fuzzy things |
| 12:22:45 | <Cale> | EvilTerran: Sequencing in terms of what <=< does |
| 12:22:54 | <EvilTerran> | although the Etats monad has information flowing in both directions <.< >.> |
| 12:23:02 | <Jedai> | Cale: That's what I was saying, not that "sequencing" has nothing to do with monads, just that a little caution around the term when teaching a beginner may be good |
| 12:23:17 | <Gracenotes> | sohum: can't do much if we don't know what the question is... |
| 12:23:17 | <Cale> | That is, a monad has about as much to do with sequencing as the composition of any category does. |
| 12:23:43 | <Cale> | But associativity is the heart of what we expect from sequences |
| 12:23:59 | <Cale> | and composition in categories is associative |
| 12:24:01 | <sohum> | Gracenotes: well, I don't want to ask #haskell, I just wondered if yall knew somewhere where a CS question would be ontopic |
| 12:24:03 | <Jedai> | sohum: you can try here, eventually go to haskell-in-depth |
| 12:24:15 | <Gracenotes> | sohum: CS is extremely general. what. |
| 12:24:22 | <PeakerWork> | Jedai: I think a beginner should learn Functor, then Applicative, then Monad -- and Applicative should already introduce sequencing |
| 12:24:22 | <sohum> | fair enough. |
| 12:24:32 | <Gracenotes> | unfortunately there's not a CS channel on freenode. at least not a busy one. |
| 12:24:44 | <Cale> | Applicative doesn't really have sequencing in the sense that Monad does. |
| 12:25:01 | <Gracenotes> | :/ but... for jeeve's sake, what's the question? |
| 12:25:11 | <sohum> | if there's a graph with exactly 2x nodes, and each node is connected to exactly x other nodes, does there have to exist a clique of size x? |
| 12:25:22 | <Absolute0> | Applicative? |
| 12:25:36 | <Jedai> | Absolute0: another typeclass |
| 12:25:42 | <Absolute0> | does lambdabot provide links? |
| 12:25:43 | <Cale> | Absolute0: Applicative is another abstraction similar to Monad, but weaker in its operations and more general. |
| 12:25:44 | <EvilTerran> | sohum, you could also try #math for a problem like that |
| 12:25:52 | <sohum> | EvilTerran: I could, thankee. |
| 12:25:53 | <Jedai> | Absolute0: yes, I think |
| 12:25:59 | <Absolute0> | whats the syntax? |
| 12:26:00 | <Cale> | (Every monad is an applicative functor, but not every applicative functor is a monad) |
| 12:26:07 | <Cale> | See Control.Applicative |
| 12:26:10 | <Jedai> | > (+3) <$> [1..5] |
| 12:26:10 | <Gracenotes> | sohum: math is a good channel :) sorry for snarky |
| 12:26:11 | <lambdabot> | [4,5,6,7,8] |
| 12:26:22 | <Cale> | that's just fmap... |
| 12:26:42 | <Cale> | > [id, (+2), (*2), (^2), (2^)] <*> [5,6,7] |
| 12:26:44 | <lambdabot> | [5,6,7,7,8,9,10,12,14,25,36,49,32,64,128] |
| 12:26:52 | <Gracenotes> | better to ask than to ask to ask, they say |
| 12:26:53 | <Absolute0> | :t <+> |
| 12:26:55 | <lambdabot> | parse error on input `<+>' |
| 12:27:01 | <Absolute0> | :t (<+>) |
| 12:27:02 | <lambdabot> | Ambiguous occurrence `<+>' |
| 12:27:02 | <lambdabot> | It could refer to either `Control.Arrow.<+>', imported from Control.Arrow at /home/cale/.lambdabot/State/L.hs:4:0-19 |
| 12:27:02 | <lambdabot> | or `Text.PrettyPrint.HughesPJ.<+>', imported from Text.PrettyPrint.HughesPJ at /home/cale/.lambdabot/State/L.hs:54:0-46 |
| 12:27:03 | <Cale> | :t pure |
| 12:27:05 | <lambdabot> | forall a (f :: * -> *). (Applicative f) => a -> f a |
| 12:27:08 | <EvilTerran> | > [f,g,h] <*> [x,y,z] :: [Expr] |
| 12:27:08 | <Cale> | :t (<*>) |
| 12:27:09 | <Jedai> | Absolute0: "f <$> x <*> y" is a simple example, you can have more sophisticated ones |
| 12:27:09 | <lambdabot> | Ambiguous occurrence `x' |
| 12:27:10 | <lambdabot> | It could refer to either `L.x', defined at <local... |
| 12:27:10 | <sohum> | Gracenotes: np ;} |
| 12:27:11 | <lambdabot> | forall (f :: * -> *) a b. (Applicative f) => f (a -> b) -> f a -> f b |
| 12:27:23 | <Cale> | Absolute0: pure and <*> are the basic functions for Applicative |
| 12:27:38 | <Absolute0> | :t Control.Arrow.<+> |
| 12:27:39 | <lambdabot> | parse error on input `Control.Arrow.<+>' |
| 12:27:44 | <Absolute0> | :t Control.Arrow.(<+>) |
| 12:27:45 | <lambdabot> | Couldn't find qualified module. |
| 12:27:48 | <Absolute0> | beh |
| 12:27:55 | <Cale> | Absolute0: everything else is built from those two |
| 12:27:55 | <Gracenotes> | sohum: you're sure it's not P? :P |
| 12:28:04 | <Cale> | <+> is unrelated |
| 12:28:13 | <Jedai> | Absolute0: <+> isn't an operator of Applicative |
| 12:28:16 | <NEEDMOAR> | sohum: btw, an "square" (four points joint by four lines in the standard way) wouldn't be a counterexample? |
| 12:28:16 | <Absolute0> | xmonad uses <+> in the config |
| 12:28:22 | <Absolute0> | i am trying to figure out what it does |
| 12:28:37 | <Jedai> | Absolute0: search in the xmonad doc (look in the index) |
| 12:28:39 | <ivanm> | Absolute0: it's an xmonad operator |
| 12:28:40 | <sohum> | Gracenotes: :P |
| 12:28:41 | <Cale> | I think you'd have to look in the xmonad code for that. |
| 12:28:46 | <ivanm> | it joins together two hooks, IIRC |
| 12:29:13 | <sohum> | NEEDMOAR: no, because the "square" has four cliques of size 2 |
| 12:29:31 | <NEEDMOAR> | sohum: nevermind, stupid me. |
| 12:29:32 | <Absolute0> | it looks funky, very intriguing :) |
| 12:29:33 | <Cale> | http://hackage.haskell.org/packages/archive/xmonad/0.8.1/doc/html/XMonad-ManageHook.html#v%3A<%2B> |
| 12:29:35 | <Cale> | Absolute0: ^^ |
| 12:30:11 | <Cale> | Heh, apparently its implementation is mappend :P |
| 12:30:31 | <Absolute0> | xmonad rocks by the way |
| 12:30:38 | <Cale> | aha, type ManageHook = Query (Endo WindowSet) |
| 12:30:40 | <Absolute0> | hands down the best WM |
| 12:30:48 | <walter_> | >pates |
| 12:30:51 | <walter_> | >paste |
| 12:30:52 | <sohum> | (incidentally, the reason my mind is currently blown is because I read through the Monad chapters in RWH ;}) |
| 12:30:52 | <Cale> | and Query derives its Monoid instance |
| 12:31:02 | <Cale> | So it just composes functions on WindowSets |
| 12:31:19 | <Cale> | er, oops |
| 12:31:23 | <Cale> | newtype Query a = Query (ReaderT Window X a) |
| 12:31:27 | <Cale> | instance Monoid a => Monoid (Query a) where |
| 12:31:27 | <Cale> | mempty = return mempty |
| 12:31:27 | <Cale> | mappend = liftM2 mappend |
| 12:31:36 | <Cale> | so, more or less :) |
| 12:32:30 | <Jedai> | Absolute0: So <+> is related to Monoid, though only the Hook monoid |
| 12:32:31 | <Cale> | So what it does when you <+> two ManageHooks together is it constructs the Query computation which when run will run each, and then compose their results |
| 12:32:48 | <Cale> | (which are required to be WindowSet -> WindowSet functions |
| 12:32:50 | <Cale> | ) |
| 12:32:57 | <Cale> | (wrapped in Endo) |
| 12:32:57 | <Absolute0> | thanks :) |
| 12:33:04 | <Jedai> | Absolute0: I suppose you already know the Monoid typeclass ? If not it's well worth knowing despite its apparent simplicity |
| 12:33:15 | <Absolute0> | I'll pretend to. :) |
| 12:33:26 | <Absolute0> | for the time being. |
| 12:33:28 | <Cale> | Absolute0: It's rather simple to explain... |
| 12:33:56 | <Absolute0> | monoid related to monad? |
| 12:34:10 | <Cale> | distantly |
| 12:34:15 | <Berengal> | @quote endofunctors |
| 12:34:15 | <lambdabot> | wadler says: A monad is a monoid in the category of endofunctors, what's the problem? |
| 12:34:18 | <Jedai> | Absolute0: monoid are just set with a binary operation that is associative and has a neutral element |
| 12:34:39 | <Absolute0> | monoid monad functor, haskell sounds like some sort of new funky religion :) |
| 12:34:48 | <Cale> | If you have a type, and a special operation, say (*) you'd like to identify on that type, which happens to be associative, that is x * (y * z) = (x * y) * z for all x,y,z, and has an identity, say 1 such that 1 * x = x * 1 = x, for all x, then you can make it an instance of the Monoid class |
| 12:34:48 | <Jedai> | Absolute0: for instance (Integer, (+), 0) is a monoid |
| 12:34:56 | <Cale> | With mappend = (*) and mempty = 1 |
| 12:35:00 | <Absolute0> | Jedai: a field... |
| 12:35:04 | <Jedai> | Absolute0: monoid are really basics in maths |
| 12:35:08 | <Absolute0> | in mathematical terms |
| 12:35:17 | <Jedai> | Absolute0: a field is much more complicated, |
| 12:35:56 | <Absolute0> | are there isomorphisms in haskell? :-D |
| 12:35:59 | <Cale> | A field is a group under addition, and a monoid under multiplication satisfying a distributive law, and having inverses for nonzero elements under multiplication |
| 12:36:03 | <Absolute0> | or ways to verify isomorphism? |
| 12:36:09 | <Absolute0> | i guess using map function.. |
| 12:36:11 | <Cale> | A group is a monoid with inverses for all elements. |
| 12:36:24 | <Cale> | (Monoid is a mathematical term) |
| 12:36:41 | <Absolute0> | where can a monoid be useful? |
| 12:36:41 | <walter_> | I got a "parse error" , but dont know why, thanks in advance. http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5443#a5443 |
| 12:36:57 | <Cale> | Absolute0: Monoids are almost everywhere. |
| 12:37:04 | <Absolute0> | ah :) |
| 12:37:12 | <Jedai> | Absolute0: http://blog.sigfpe.com/2009/01/haskell-monoids-and-their-uses.html |
| 12:37:50 | <Berengal> | > sortBy (comparing length `mappend` compare) (words "asd fdsasdf fdsaf fds fdssdf fds") |
| 12:37:51 | <lambdabot> | ["asd","fds","fds","fdsaf","fdssdf","fdsasdf"] |
| 12:38:10 | <Cale> | http://www.reddit.com/r/programming/comments/7cf4r/monoids_in_my_programming_language/c06adnx |
| 12:38:14 | <Cale> | Absolute0: ^^ |
| 12:38:29 | <hackagebot> | bindings-sqlite3 0.0.2 |
| 12:38:33 | <Cale> | there's a post I wrote about one example of what recognising that monoids are everywhere gets you :) |
| 12:38:54 | <Cale> | and, it explains what Berengal just showed |
| 12:39:03 | <olsner> | cgibbard = Cale? |
| 12:39:05 | <Cale> | yes |
| 12:39:06 | <Jedai> | walter_: I think the error may well be in the code before the line 28... |
| 12:39:22 | <Absolute0> | I am writing a simple chess game, don't seem to require any of this fancy stuff to get by... |
| 12:39:26 | <Jedai> | walter_: maybe a ")" or a "]" is lacking |
| 12:39:28 | <Absolute0> | not sure why |
| 12:39:46 | <Absolute0> | http://github.com/ramin32/chessengine/tree/master |
| 12:39:55 | <apfelmus> | Absolute0: Ah, but the stuff is not fancy at all. |
| 12:40:15 | <Cale> | There are a lot of monoids associated with chess. |
| 12:40:15 | <Absolute0> | simple data definitions and functions do everything :) |
| 12:40:25 | <apfelmus> | Rather, in its simplicity lies its power. |
| 12:40:39 | <walter_> | Jedai, dont understand where to add ] more in makeNewsPair :: [Tag] -> [(String, String)] |
| 12:40:56 | <Jedai> | Absolute0: as apfelmus says, this stuff is not "fancy", in fact it's rather recognizing simple structure gives you more leverage to manipulate them |
| 12:41:30 | <Absolute0> | monads are not that simple.. |
| 12:41:37 | <Absolute0> | other things could be |
| 12:41:45 | <Jedai> | Absolute0: and I'm sure you don't _need_ them to do pretty impressive things in Haskell, but when you do know them you'll get more elegant, flexible, shorter... code |
| 12:41:48 | <Absolute0> | ehh i am just ill informed |
| 12:41:53 | <Cale> | The basic part of what a monad is, is actually extremely simple. |
| 12:42:07 | <Jedai> | walter_: I said before this line |
| 12:42:28 | <Cale> | The laws might seem confusing, but there is actually a way to present them which makes them seem really simple indeed. |
| 12:42:47 | <Absolute0> | Maybe in my second week of haskell coding i'll get it. :-P |
| 12:43:00 | <Cale> | It's possible to define a monad as a type constructor M with an operation: |
| 12:43:19 | <Cale> | (<=<) :: (b -> M c) -> (a -> M b) -> (a -> M c) |
| 12:43:22 | <Cale> | and |
| 12:43:24 | <Jedai> | walter_: this line appears perfectly correct, but the parser says there is an indentation error, it's probably because the code that precede this line is incorrectly indented or lacks a closing character |
| 12:43:27 | <Cale> | return :: a -> M a |
| 12:43:51 | <Absolute0> | (x) is a functor, right? |
| 12:43:52 | <Cale> | Before I go on, take a moment to compare those types with |
| 12:44:00 | <Cale> | (.) :: (b -> c) -> (a -> b) -> (a -> c) |
| 12:44:03 | <Cale> | and |
| 12:44:07 | <Cale> | id :: a -> a |
| 12:44:17 | <Jedai> | Absolute0: what's (x) ? do you means [] ? |
| 12:44:22 | <Cale> | So we've basically just stuck some M's in :) |
| 12:44:22 | <Absolute0> | return is just taking a simple value and makes it into a Maybe |
| 12:44:26 | <Cale> | yeah |
| 12:44:38 | <Absolute0> | Jedai: (x -> y ->z) -> some fancy crap |
| 12:44:57 | <Cale> | Now the laws are really easy to state in this form: |
| 12:45:00 | <EvilTerran> | Cale, can you define >>= in terms of >=> and return? do you need join too? |
| 12:45:09 | <Cale> | EvilTerran: yes you can |
| 12:45:15 | <Cale> | return <=< f = f |
| 12:45:19 | <Cale> | f <=< return = f |
| 12:45:33 | <Cale> | (f <=< g) <=< h = f <=< (g <=< h) |
| 12:45:42 | <Cale> | those are the three monad laws |
| 12:46:02 | <Jedai> | Cale: like the composition with return =~= id :) |
| 12:46:04 | <Absolute0> | Cale: so <=< is just some transitive sort of function mapping then |
| 12:46:31 | <Cale> | Absolute0: 'transitive', I'm not sure is the word |
| 12:46:35 | <Cale> | But associative |
| 12:46:41 | <Cale> | and having identity return |
| 12:46:50 | <Cale> | Note that |
| 12:46:54 | <Cale> | id . f = f |
| 12:46:58 | <Cale> | f . id = f |
| 12:46:59 | <Cale> | and that |
| 12:47:03 | <Absolute0> | Cale: can you give an example of <=< in use? |
| 12:47:06 | <Jedai> | Absolute0: (<=<) is an operator that "compose" functions of the form (a -> M b) |
| 12:47:06 | <Cale> | (f . g) . h = f . (g . h) |
| 12:47:47 | <Cale> | and so (.) and id define what's called the identity monad, though we can't make that directly an instance of Monad in Haskell, since we need a type constructor |
| 12:48:01 | <Cale> | (so you have to do some extra wrapping then) |
| 12:48:06 | <walter_> | Jedai, excellent, you are right! thank you |
| 12:48:09 | <EvilTerran> | ?type \f m -> (f <=< const m) () -- Cale, would this be =<< ? |
| 12:48:10 | <lambdabot> | forall b (m :: * -> *) c. (Monad m) => (b -> m c) -> m b -> m c |
| 12:48:10 | <ivanm> | well, the new darcs wiki doesn't seem to like searching... >_> |
| 12:48:15 | <Cale> | EvilTerran: yeah |
| 12:48:37 | <Absolute0> | Cale: let me just read your article |
| 12:48:40 | <Absolute0> | thanks anyways |
| 12:48:57 | <EvilTerran> | ACTION feels uncomfortable about the extraneous () in that, but ok... |
| 12:48:57 | <Cale> | Absolute0: My article gives a more down-to-earth look at the monad laws |
| 12:49:12 | <Cale> | Absolute0: Which deals with how they might be desirable in actual programming. |
| 12:49:39 | <Absolute0> | there's some paper i recently read |
| 12:49:43 | <Absolute0> | by some walders guy? |
| 12:49:47 | <Cale> | Wadler |
| 12:49:47 | <Absolute0> | not bad.. |
| 12:49:51 | <Absolute0> | yeah that guy |
| 12:50:02 | <Heffalump> | Cale: btw, I found some situations where blanket use of . . . $ instead of $ $ $ $ is unnatural: if you're doing the same/similar operation on a bunch of things, some of which are simple values and some of which are applications themselves, it feels quite weird for the $ to keep moving around. |
| 12:50:13 | <Absolute0> | I am thinking of doing my phd in functional programming. |
| 12:50:17 | <Absolute0> | i hope i get it in time.. |
| 12:50:20 | <Absolute0> | :) |
| 12:50:38 | <Absolute0> | are there any undone research that can be done? |
| 12:50:39 | <Cale> | Heffalump: hm? |
| 12:50:48 | <Cale> | Absolute0: I'm sure there is. |
| 12:50:50 | <Beelsebob> | Absolute0: there's *many* bits of FP research to do |
| 12:51:01 | <EvilTerran> | Absolute0, it's a huge field, there's lots of unexplored edges |
| 12:51:06 | <Absolute0> | i like programming languages in general |
| 12:51:12 | <Absolute0> | but haskell is just cool |
| 12:52:19 | <Cale> | Heffalump: I'm not sure I understand what you mean there... |
| 12:52:20 | <Absolute0> | scala and python hype about having functional functions, but haskell had it from the start.. |
| 12:52:20 | <Absolute0> | :) |
| 12:52:55 | <Twey> | ‘Functional functions’? |
| 12:53:01 | <Absolute0> | map, |
| 12:53:08 | <Absolute0> | all any.. |
| 12:53:11 | <Twey> | If you mean first-class functions, they've been around since Lisp |
| 12:53:13 | <ivanm> | higher-order functions? |
| 12:53:15 | <Heffalump> | Cale: I can't find my example now |
| 12:53:25 | <Twey> | Which has been around since the '50s |
| 12:53:26 | <ivanm> | Twey: doesn't "first-class" mean you can pass functions around? |
| 12:53:32 | <Twey> | ivanm: Yes |
| 12:54:00 | <ivanm> | whereas Absolute0 seems to be referring to higher-order functions, which IIRC means you have functions that use functions |
| 12:54:01 | <Absolute0> | Twey: in those languages these functions are second-class |
| 12:54:10 | <ivanm> | (which kinda relies on first-class functions...) |
| 12:54:22 | <Twey> | ivanm: It's the same abstraction |
| 12:54:24 | <Absolute0> | unlike haskell/lisp |
| 12:54:26 | <Cale> | Heffalump: I'll tell you one exception I usually make is that I won't split up the parameters to a zip or zipWith |
| 12:54:31 | <Cale> | Heffalump: well... usually |
| 12:54:43 | <Twey> | First-class functions begets higher-order functions; higher-order functions require first-class functions |
| 12:54:54 | <Twey> | Absolute0: In what languages? Lisps? |
| 12:54:57 | <ivanm> | yes, but they're still different ;-) |
| 12:55:05 | <Heffalump> | that's the thing though, if there are cases where you do want $ $, then you can't make it left associative |
| 12:55:14 | <Absolute0> | Twey: scroll up |
| 12:55:16 | <ivanm> | Twey: I think Absolute0 means scala, python, etc. |
| 12:55:17 | <Cale> | Heffalump: Oh, I still don't do that |
| 12:55:21 | <Twey> | Oh, right |
| 12:55:24 | <Cale> | Heffalump: I just use natural application |
| 12:55:28 | <Twey> | Absolute0: Python functions are first-class, at least |
| 12:55:33 | <hackagebot> | uu-parsinglib 2.0.1 |
| 12:55:33 | <Twey> | I don't know about Scala |
| 12:55:47 | <Heffalump> | that involves too many () for me :-) |
| 12:55:49 | <Cale> | Heffalump: This is specifically in the case that it's last in the chain |
| 12:55:49 | <EvilTerran> | Heffalump / Cale: it'd be nice if you could write "zipWith (...) $ some list expression $ some other list expression", eh =/ |
| 12:56:00 | <Cale> | Right. |
| 12:56:15 | <Cale> | That's actually a case where I'd love left associative $ |
| 12:57:07 | <Cale> | But I just meant that if I have something like, oh, foo . bar $ zip x y, I usually won't push it as far as foo . bar . zip x $ y |
| 12:57:18 | <Twey> | ivanm: Absolute0 simply said ‘map’ |
| 12:57:29 | <Twey> | That could have been referring to the arguments it takes *shrugs* |
| 12:57:35 | <ivanm> | Twey: the message before |
| 12:57:36 | <Cale> | But usually I try to maximise my use of composition to the exclusion of application. |
| 12:57:47 | <ivanm> | <Absolute0> scala and python hype about having functional functions, but haskell had it from the start.. |
| 12:57:55 | <ivanm> | Twey: though hey also mentioned all and any |
| 12:58:15 | <Twey> | Absolute0: You got higher-order functions and not first-class functions from ‘functional functions’? :-P |
| 12:58:58 | <Twey> | Cale: In fact I go the other way |
| 12:59:05 | <Absolute0> | Twey: details.... |
| 12:59:07 | <Twey> | Because it saves a character or two :-P |
| 12:59:14 | <Twey> | Er, ivanm** sorry |
| 12:59:38 | <ivanm> | Twey: I got it from map, all, any ;-) |
| 13:00:59 | <sohum> | ACTION stabs this question |
| 13:01:36 | <sohum> | are there any good resources on clique membership problems, as opposed to clique existence problems? |
| 13:01:39 | <walter_> | how express empty tuple? []? |
| 13:01:54 | <Cale> | walter_: [] is the empty list, () is the empty tuple |
| 13:01:59 | <sohum> | walter_: empty tuple? () |
| 13:02:07 | <walter_> | got, thank you! |
| 13:02:08 | <EvilTerran> | walter_, [] is empty list. () is empty tuple. |
| 13:02:08 | <EvilTerran> | ?type [] |
| 13:02:08 | <EvilTerran> | ?type () |
| 13:02:09 | <lambdabot> | forall a. [a] |
| 13:02:10 | <lambdabot> | () |
| 13:02:24 | <esap> | is there a standard way to compare functors for equality based on their structure? |
| 13:02:32 | <Cale> | sohum: Clique membership? |
| 13:03:10 | <sohum> | Cale: as in, given a graph G, a node N in G, and k, is N a member of a clique of size k or greater |
| 13:03:33 | <Cale> | esap: hmm, find a pair of natural transformations and prove they compose to the identity in either direction? |
| 13:03:44 | <ivanm> | sohum: you want to find cliques in a graph? |
| 13:03:57 | <sohum> | ivanm: no, I know that's NP-complete |
| 13:04:02 | <Cale> | sohum: Oh, okay, so you're looking for an algorithm. |
| 13:04:05 | <ivanm> | so what are you actually wanting? |
| 13:04:16 | <ivanm> | ACTION has clique-finding code for FGL graphs, if you want |
| 13:04:23 | <sohum> | ivanm: I want to find if a given node is a member of a clique (of size >= k) |
| 13:04:37 | <sohum> | Cale: yep |
| 13:04:50 | <ivanm> | sohum: as in in Haskell, or an algorithm to do so? |
| 13:05:15 | <sohum> | ivanm: an algorithm will do, this is really a CS question. |
| 13:05:24 | <ivanm> | ahhhh |
| 13:05:37 | <esap> | cale: that's up-to-iso. Well ok, maybe that's what I need to do. I'm just wondering if that's sufficient for declaring two natural transformations to be composable (that the functors in middle are isomorphic?) |
| 13:05:44 | <ivanm> | sohum: I would just try and build a clique with that node; once you've found k nodes in that clique, stop |
| 13:06:37 | <Cale> | esap: Well, otherwise, equality is, well, they're directly the same functor. I suppose we take it for granted in mathematics that you can decide that. |
| 13:07:07 | <Cale> | esap: I suppose if they're only isomorphic, you need a specified isomorphism. |
| 13:07:48 | <Cale> | esap: In implementing a programming language, I suppose I would just check that the types are equal. |
| 13:08:06 | <sohum> | ivanm: hmmmmm. am I right in thinking that that's O(k^2) for the case where you're checking if it's a member of a clique of size k? |
| 13:08:42 | <ivanm> | sohum: sounds like it off the top of my head |
| 13:08:52 | <esap> | cale: Well the thing is, I tried to represent functors as a simple "map of objects" and "map of arrows", but that representation doesn't allow the equality comparison... |
| 13:09:18 | <Cale> | esap: Well, they're equal if those maps are equal... |
| 13:09:33 | <esap> | cale: Well I don't have equality comparison for the maps :-) |
| 13:09:35 | <uzytkownik> | What is standard indentation of do? |
| 13:09:44 | <Cale> | uzytkownik: something like: |
| 13:09:46 | <Cale> | do foo |
| 13:09:48 | <Cale> | bar |
| 13:09:50 | <Cale> | baz |
| 13:10:23 | <uzytkownik> | Cale: Ok. I was not sure if it was do\n foo or do foo. Thanks |
| 13:10:27 | <Cale> | That is, subsequent lines line up with the first non-whitespace character after the 'do' |
| 13:10:36 | <ivanm> | sohum: then again, the way I've found cliques is to take a node n, find it's neighbours, then recursively try adding a neighbour to the current clique and finding the intersection of its neighbours with the neighbours-so-far |
| 13:10:49 | <ivanm> | uzytkownik: you can do that as well |
| 13:10:52 | <ivanm> | some people do: |
| 13:10:55 | <ivanm> | main = do |
| 13:10:57 | <ivanm> | foo |
| 13:10:58 | <ivanm> | bar |
| 13:11:00 | <ivanm> | baz |
| 13:11:00 | <esap> | Cale: http://www.kotiposti.net/epulkkin/Category.txt |
| 13:12:59 | <Cale> | esap: This sort of thing is kind of tricky, because as you go up, you need more and more ability to test equality. I suppose that if you don't mind the finiteness it imposes on things, you can turn more things into concrete values. |
| 13:13:11 | <uzytkownik> | Should I use IO (Maybe a) or use fail? |
| 13:13:22 | <Cale> | uzytkownik: The first, I think. |
| 13:13:37 | <Cale> | uzytkownik: You should never use fail, but there are ways to throw IO exceptions. |
| 13:13:48 | <esap> | cale: yea, I suppose I must rely on finiteness here |
| 13:14:11 | <Cale> | Use Data.Map instead of functions or something |
| 13:14:21 | <uzytkownik> | Cale: Thanks |
| 13:15:41 | <Cale> | uzytkownik: It's generally more convenient to use Maybe when you have any sort of 'lookup' type of operation, because pattern matching is nice and easy. Catching exceptions is not hard, but it's not quite as pretty. |
| 13:15:44 | <esap> | cale: yea, that will work [it'll not be fast, but works] |
| 13:16:33 | <sohum> | ivanm: gaah, brain. could you rephrase that so I can figure out why it's either a heuristic or exponential time? |
| 13:16:49 | <ivanm> | it's not a heuristic |
| 13:16:55 | <ivanm> | but the way my code found cliques was: |
| 13:17:03 | <CSWookie_> | Blah. I feel dumb, but I can't seem to find the syntax for how to define a funtion in the book I'm reading. |
| 13:17:10 | <ivanm> | take a node n; find it's neighbours ns |
| 13:17:56 | <ivanm> | then recursively, take the first elem of ns, and find the intersection of its neighbours and ns |
| 13:18:14 | <ivanm> | (actually, I did this on tails of n's neighbours, IIRC) |
| 13:18:30 | <ivanm> | sohum: I have code online if that would help you... |
| 13:19:28 | <CSWookie_> | Ah, wait, I think I found it. |
| 13:20:24 | <sohum> | ivanm: aha. so in the worst case scenario that is factorial time |
| 13:20:43 | <ivanm> | something like that, yes |
| 13:20:56 | <sohum> | ok, brain better |
| 13:20:59 | <sohum> | thankee |
| 13:21:02 | <ivanm> | you can always simplify it (?) by finding how many you have so far as possibles, as well |
| 13:26:08 | <sohum> | ahaha |
| 13:26:10 | <sohum> | I have it |
| 13:26:32 | <sohum> | checking whether a node of order n is a member of a clique of size n is just O(n^2) |
| 13:26:49 | <sohum> | if the order > n then it becomes exponential |
| 13:41:43 | <hackagebot> | gtk2hs-cast-glib 0.10.1.1 |
| 13:51:56 | <EvilTerran> | ACTION notes that you don't seem to be able to nest QuasiQuoters |
| 13:52:05 | <EvilTerran> | , [$ty| [$ty| () |] |] |
| 13:52:06 | <lunabot> | luna: parse error on input `|]' |
| 13:53:12 | <EvilTerran> | ACTION also notes that surely (ty [|...|]) would make more sense than [$ty| ... |], seeing as the body is meant to be a haskell expression |
| 13:54:08 | <dcoutts> | EvilTerran: you can effectively nest them, but not lexically |
| 13:54:44 | <dcoutts> | and similarly for splicing |
| 13:54:46 | <hackagebot> | bindings-common 0.1.1 |
| 13:55:59 | <EvilTerran> | dcoutts, "effectively nest"? |
| 13:56:11 | <dcoutts> | EvilTerran: using let |
| 13:56:44 | <dcoutts> | EvilTerran: actually, I should admit I've only done it for splicing, not quoting |
| 13:56:59 | <dcoutts> | it'd need reify I think |
| 13:58:25 | <Whoof> | ACTION pokes Phyx with a large stick. |
| 13:59:15 | <Phyx-> | ACTION uses Arrows on Whoof |
| 13:59:46 | <EvilTerran> | , let theType = [$ty| () |] in [$ty| theType |] |
| 13:59:49 | <lunabot> | luna: Exception when trying to run compile-time code: |
| 14:04:24 | <koeien> | @where showHex |
| 14:04:24 | <lambdabot> | I know nothing about showhex. |
| 14:04:34 | <koeien> | ?index showHex |
| 14:04:35 | <lambdabot> | Numeric |
| 14:09:26 | <CSWookie_> | Is there nice way to say 'multiples of 3' in haskell? |
| 14:09:55 | <CSWookie_> | I'm used to python, and I'm trying to understand the haskell idioms. |
| 14:10:16 | <EvilTerran> | > [0, 3 ..] |
| 14:10:17 | <kpreid> | > [0,3..] |
| 14:10:22 | <lambdabot> | mueval-core: Prelude.read: no parse |
| 14:10:22 | <lambdabot> | mueval: ExitFailure 1 |
| 14:10:22 | <lambdabot> | [0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57,60,63,66,69,72,75,... |
| 14:10:32 | <kpreid> | whoops |
| 14:11:29 | <kpreid> | hm, is that lb's parser's bug? I would think that 3 isn't a module name |
| 14:12:33 | <Phyx-> | lol |
| 14:12:38 | <Phyx-> | which of those failed? |
| 14:12:44 | <kpreid> | mine, I expect |
| 14:12:49 | <kpreid> | > [0, 3 ..] |
| 14:12:50 | <lambdabot> | [0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57,60,63,66,69,72,75,... |
| 14:12:51 | <kpreid> | yes |
| 14:12:53 | <Phyx-> | ah |
| 14:13:14 | <olsner> | @faq can template haskell iterate all identifiers in a module? |
| 14:13:15 | <lambdabot> | The answer is: Yes! Haskell can do that. |
| 14:13:30 | <olsner> | now, for the how :) |
| 14:13:36 | <Phyx-> | @faq can haskell save the world? |
| 14:13:36 | <Twey> | No no |
| 14:13:36 | <lambdabot> | The answer is: Yes! Haskell can do that. |
| 14:13:40 | <Phyx-> | rofl |
| 14:13:41 | <Twey> | You don't even need TH |
| 14:13:47 | <Twey> | Look, it says *Haskell* can do it |
| 14:14:12 | <Twey> | That obviously means '98 :-P |
| 14:14:19 | <Phyx-> | you could use SYB and haskell-src-ext? :P |
| 14:14:19 | <olsner> | hmm, well of course *Haskell* can do it, question is can *I* :) |
| 14:14:30 | <trofi> | @hoogle :: Integer -> [a] -> a |
| 14:14:30 | <lambdabot> | Data.List genericIndex :: Integral a => [b] -> a -> b |
| 14:14:30 | <lambdabot> | Data.List intersperse :: a -> [a] -> [a] |
| 14:14:30 | <lambdabot> | Data.List genericDrop :: Integral i => i -> [a] -> [a] |
| 14:14:50 | <Twey> | olsner: *grin* |
| 14:14:58 | <kpreid> | trofi: genericIndex is the general (!!) equivalent |
| 14:15:22 | <CSWookie_> | Can I say multiples of 3 or 5 in a similar way? |
| 14:15:29 | <CSWookie_> | I'm doing projecteuler. |
| 14:15:55 | <hackagebot> | gtk2hs-cast-glade 0.10.1.1 |
| 14:15:56 | <kpreid> | No... |
| 14:15:58 | <kpreid> | hm |
| 14:16:02 | <kpreid> | @hoogle merge |
| 14:16:02 | <lambdabot> | Distribution.Simple.PackageIndex merge :: Package pkg => PackageIndex pkg -> PackageIndex pkg -> PackageIndex pkg |
| 14:16:02 | <lambdabot> | Text.Parsec.Error mergeError :: ParseError -> ParseError -> ParseError |
| 14:16:02 | <lambdabot> | Text.ParserCombinators.Parsec.Error mergeError :: ParseError -> ParseError -> ParseError |
| 14:16:03 | <Jedai> | CSWookie_: You could just merge the multiples of 3 and the multiples of 5 |
| 14:16:19 | <Jedai> | CSWookie_: write the appropriate merge and it's a snap |
| 14:16:26 | <CSWookie_> | Jedai: That sounds like what I want. |
| 14:16:28 | <byorgey> | or you could just use a list comprehension. |
| 14:16:37 | <kpreid> | yeah. |
| 14:16:42 | <Phyx-> | yeah, and restrict the values to a multiple of 3 and 5 |
| 14:16:51 | <trofi> | kpreid: yeah, i searched exactly that function |
| 14:16:54 | <kpreid> | > [x | x <- [0..], x `mod` 3 == 0, x `mod` 5 == 0] |
| 14:16:55 | <lambdabot> | [0,15,30,45,60,75,90,105,120,135,150,165,180,195,210,225,240,255,270,285,30... |
| 14:17:02 | <kpreid> | er |
| 14:17:06 | <kpreid> | > [x | x <- [0..], x `mod` 3 == 0 || x `mod` 5 == 0] |
| 14:17:07 | <lambdabot> | [0,3,5,6,9,10,12,15,18,20,21,24,25,27,30,33,35,36,39,40,42,45,48,50,51,54,5... |
| 14:17:40 | <Jedai> | kpreid: That works if you're in a hurry but it examines much more numbers |
| 14:18:29 | <Jedai> | (ok, in the case of 3 and 5 not that much more, but imagine you want multiples of much bigger numbers... ^^ ) |
| 14:18:57 | <hackagebot> | gtk2hs-cast-th 0.10.1.0 |
| 14:19:02 | <kpreid> | > let merge xs@(x:xs') ys@(y:ys') | x < y = x : merge xs' ys; | otherwise = y : merge xs ys' in merge [0, 3 ..] [0, 5 ..] |
| 14:19:03 | <lambdabot> | <no location info>: parse error on input `|' |
| 14:19:09 | <kpreid> | > let merge xs@(x:xs') ys@(y:ys') | x < y = x : merge xs' ys | otherwise = y : merge xs ys' in merge [0, 3 ..] [0, 5 ..] |
| 14:19:11 | <lambdabot> | [0,0,3,5,6,9,10,12,15,15,18,20,21,24,25,27,30,30,33,35,36,39,40,42,45,45,48... |
| 14:19:27 | <kpreid> | > let merge xs@(x:xs') ys@(y:ys') | x == y = x : merge xs' ys' | x < y = x : merge xs' ys | otherwise = y : merge xs ys' in merge [0, 3 ..] [0, 5 ..] |
| 14:19:28 | <lambdabot> | [0,3,5,6,9,10,12,15,18,20,21,24,25,27,30,33,35,36,39,40,42,45,48,50,51,54,5... |
| 14:19:31 | <kpreid> | there you go |
| 14:19:43 | <CSWookie_> | Jedai: kpreid: the LC up there will go through all numbers, and return those that are multiples of 3 or 5, yes? |
| 14:19:55 | <Jedai> | CSWookie_: Yes |
| 14:19:57 | <hackagebot> | gtk2hs-cast-gnomevfs 0.10.1.2 |
| 14:19:57 | <hackagebot> | gtk2hs-cast-gtk 0.10.1.2 |
| 14:19:59 | <kpreid> | CSWookie_: all nonnegative integers, yes |
| 14:20:33 | <CSWookie_> | Haskell is hard for me to read. |
| 14:20:52 | <kpreid> | practice |
| 14:20:55 | <CSWookie_> | ACTION looks up merge in his book. |
| 14:20:57 | <hackagebot> | gtk2hs-cast-gtkglext 0.10.1.2 |
| 14:21:09 | <Jedai> | CSWookie_: merge is not a standard function |
| 14:21:11 | <Phyx-> | if the numbers are in sequence anyway, wehy not just generate them based on x*3 and 5*x |
| 14:21:14 | <EvilTerran> | CSWookie_, it can take a bit of getting used to |
| 14:21:38 | <CSWookie_> | Oh. |
| 14:21:43 | <Jedai> | CSWookie_: it usually design a function that takes two sorted list and merge them into a sorted list, the detail may vary |
| 14:21:57 | <kpreid> | my eval above gives a definition of merge |
| 14:21:58 | <hackagebot> | gtk2hs-cast-gtksourceview2 0.10.1.2 |
| 14:22:02 | <Jedai> | CSWookie_: kpreid gave a version appropriate to our use above |
| 14:22:06 | <kpreid> | in particular, one which combines equal items rather than repeating them |
| 14:22:18 | <Jedai> | kpreid: and works on infinte streams |
| 14:22:50 | <kpreid> | Jedai: I would expect any merge function on Haskell lists to work on infinite streams. |
| 14:23:01 | <kpreid> | Now, mine fails on *finite* lists, but that's just for brevity. |
| 14:23:08 | <Jedai> | kpreid: I meant and only works on infinite streams |
| 14:23:24 | <CSWookie_> | I'm used to much longer variable names. |
| 14:23:49 | <uzytkownik> | I have a parametrized function - by parametr k. In a where close I need to cast on this type (compiler have no way to determin - but that's a different story). Is it possible to indicate that a in where statement is the same a as in function declaration or I have to use less direct method (I know how but it requires 'empty' statement such as head (y:(snd z)) to indicate type of z). |
| 14:23:50 | <Jedai> | CSWookie_: well in our case there is not much point to them |
| 14:24:27 | <CSWookie_> | Jedai: Why? |
| 14:24:52 | <kpreid> | CSWookie_: One can construct a general principle: variable names' length is proportional to the nearness of their uses |
| 14:24:59 | <Jedai> | CSWookie_: merge is the traditional merge, a more precise name is hard to give, and the (x:xs) (y:ys) are traditional for general lists |
| 14:25:18 | <kpreid> | Since Haskell code is so short otherwise, we use short names... |
| 14:25:25 | <CSWookie_> | What? |
| 14:25:35 | <CSWookie_> | Your general principle doesn't make sense to me. |
| 14:25:52 | <CSWookie_> | Jedai: What does the @ mean? |
| 14:25:54 | <kpreid> | Like in C, you almost always use 'i' for a simple array index. |
| 14:25:56 | <kpreid> | Because it's part of the loop and nothing larger. |
| 14:26:04 | <Jedai> | CSWookie_: you could write (head:tail) but it wouldn't give more detail |
| 14:26:29 | <Jedai> | CSWookie_: the @ is a "as-pattern" |
| 14:26:52 | <Axman6> | i prefer x:xs to had:tail because there's a visual que that x is smaller than xs (which is most cases it will be) |
| 14:27:03 | <Axman6> | head* |
| 14:27:21 | <Axman6> | head:tail seems to imply to me that they are equal lengths |
| 14:27:23 | <Jedai> | CSWookie_: xs'@(x:xs) match xs' with the whole list, x with the head of the list and xs with the tail |
| 14:27:30 | <Axman6> | i'm probably alone here though... |
| 14:28:04 | <Axman6> | CSWookie_: xss@(x:xs) defines xss to be the whole list, x to be the head of the list, and xs to be the tail |
| 14:28:15 | <Jedai> | CSWookie_: in general, it allows you to keep a name for the whole parameter while breaking it into finer parts at the same time |
| 14:28:31 | <olsner> | turns out, reify barfs with a compile error when given a nonexistant identifier (rather than indicating whether or not it was defined) |
| 14:28:40 | <CSWookie_> | I'm sorry if I'm thick about things. I've got to go to church, now. I'll be back later, maybe in quiter. |
| 14:29:15 | <Jedai> | CSWookie_: You're not thick, Haskell isn't a particularly easy language to learn |
| 14:29:30 | <Jedai> | CSWookie_: especially if it's your first functional language |
| 14:29:37 | <Axman6> | it's handy for a lot of other things, like data Vec = V Double Double Double; f :: Vec -> Double; f v@(V x y z) = x + 2y* mag v |
| 14:29:44 | <Twey> | Oh, CSWookie_, hello |
| 14:29:56 | <nA1828KcFz9q> | type theory resources? |
| 14:30:06 | <paolino> | hi, anyone can explain the different behaviors here http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5444#a5444 , please? |
| 14:32:36 | <kpreid> | paolino: in the second one, your ErrorT adds an independent error mechanism which has no relation to the one in IO. And your catchError applies to that one rather than IO. |
| 14:32:40 | <EvilTerran> | ?hoogle catchError |
| 14:32:41 | <lambdabot> | Control.Monad.Error.Class catchError :: MonadError e m => m a -> (e -> m a) -> m a |
| 14:32:45 | <Axman6> | nA1828KcFz9q: i don't think those words form a question |
| 14:33:18 | <kpreid> | paolino: you'll have to "lift" the catchError into IO to make it do the same as the first (but note that it's a 2-arg function so you can't just apply lift) |
| 14:33:19 | <EvilTerran> | ?instances-importing Control.Monad.Error MonadError |
| 14:33:21 | <lambdabot> | IOError IO, e (Either e), e (ErrorT e m), e (RWST r w s m), e (ReaderT r m), e (StateT s m), e (WriterT w m) |
| 14:34:21 | <EvilTerran> | ACTION concurs with kpreid - that'll be the instance MonadError IOError IO, and the instance MonadError e (ErrorT e m) |
| 14:34:46 | <kpreid> | (where e = String and m = IO) |
| 14:34:57 | <paolino> | it makes sense |
| 14:35:49 | <nA1828KcFz9q> | Axman6: Which papers or pages are the standard resources referred to when one is beginning to study algebraic type theory? |
| 14:36:03 | <EvilTerran> | unfortunately, there's an ambiguty in chosing an instance for MonadError for (ErrorT e m) where m is already a MonadError instance |
| 14:36:22 | <Axman6> | that is a certainly a questions. i wish i could help you now :) |
| 14:36:28 | <paolino> | is lifting catchError the way to go from the IOException to a common layer with logic errors ? |
| 14:36:32 | <Axman6> | ACTION doesn't know anything (formally) about type theory |
| 14:36:33 | <EvilTerran> | and, while it does make more sense to go for the instance based around the ErrorT, it does result in this kinda behaviour |
| 14:37:53 | <paolino> | if I'm able to lift it, in the end |
| 14:38:28 | <EvilTerran> | nA1828KcFz9q, Ben Pierce's Types and Programming Languages is an excellent introductory text |
| 14:38:37 | <EvilTerran> | ?go TaPL pierce |
| 14:38:38 | <lambdabot> | http://www.cis.upenn.edu/~bcpierce/tapl/ |
| 14:38:38 | <lambdabot> | Title: Types and Programming Languages |
| 14:39:19 | <EvilTerran> | i don't recall how much detail it goes into wrt algebraic types, but it covers basic type theory nicely |
| 14:40:28 | <uzytkownik> | ?hoogle listToMaybe |
| 14:40:29 | <lambdabot> | Data.Maybe listToMaybe :: [a] -> Maybe a |
| 14:40:37 | <voker57__> | can i make a list which has different types, but all of one typeclass? |
| 14:40:55 | <voker57__> | like type Objects = (Object a) => [a] |
| 14:41:23 | <EvilTerran> | voker57__, not in haskell98; there's usually other ways of achieving the same thing, though |
| 14:41:48 | <Axman6> | hmm, i can see it being possible using partially applied functions... maybe |
| 14:41:49 | <voker57__> | EvilTerran: like? |
| 14:42:33 | <EvilTerran> | voker57__, well, it depends on what you want to do with the list |
| 14:42:53 | <paolino> | kpreid: I don't know how to lift catchError :-/ |
| 14:43:04 | <EvilTerran> | for instance, rather than having a [forall a. Show a => a], you could achieve pretty much the same result with just a [String] |
| 14:44:42 | <kpreid> | voker57__: you can get the effect using an existential-type wrapper (which is not h98 as EvilTerran said) -- but yes, you should first consider whether there's a better way to do it |
| 14:48:10 | <jbjohns> | hi all. How does the dynamic linking work in Haskell? I want to create a Haskell CMS and I want users to be able to add modules to the running system like one can with e.g. Joomla! . |
| 14:51:26 | <harlekin> | jbjohns, check out http://hackage.haskell.org/cgi-bin/hackage-scripts/package/plugins. |
| 14:52:06 | <Jedai> | jbjohns: look at happstack too, it may be a good basis |
| 14:53:30 | <paolino> | kpreid: to move errors between layers I have to tag results from IO and case-match them in the ErrorT layer ? |
| 14:53:50 | <alexsuraci> | Is there a way to dump the raw data of a string? e.g. raw "ABC" => "\x41\x42\x43" (or something more natural) |
| 14:54:03 | <alexsuraci> | "raw data" may be the wrong term |
| 14:54:11 | <kpreid> | paolino: it's up to you how you translate the errors |
| 14:54:23 | <kpreid> | > map fromEnum "ABC" |
| 14:54:24 | <harlekin> | @ty ord |
| 14:54:26 | <lambdabot> | [65,66,67] |
| 14:54:26 | <lambdabot> | Char -> Int |
| 14:54:35 | <harlekin> | alexsuraci, map ord "ABC" |
| 14:54:46 | <alexsuraci> | harlekin: thanks, that seems like it'd do it |
| 14:55:00 | <harlekin> | alexsuraci, kpreid's suggestion is more general, though. I'd prefer that. |
| 14:55:11 | <Axman6> | > ord maxBound |
| 14:55:12 | <lambdabot> | 1114111 |
| 14:55:49 | <Axman6> | > foldl' (\x n -> n * 1114111 + x) "ABC" |
| 14:55:50 | <lambdabot> | No instance for (GHC.Num.Num [GHC.Types.Char]) |
| 14:55:51 | <lambdabot> | arising from the literal ... |
| 14:55:59 | <Axman6> | > foldl' (\x n -> x * 1114111 + n) "ABC" |
| 14:56:00 | <lambdabot> | No instance for (GHC.Num.Num [GHC.Types.Char]) |
| 14:56:00 | <lambdabot> | arising from the literal ... |
| 14:56:12 | <Axman6> | > foldl' (\x n -> x * 1114111 + n) 0 "ABC" |
| 14:56:13 | <lambdabot> | No instance for (GHC.Num.Num GHC.Types.Char) |
| 14:56:13 | <lambdabot> | arising from the literal `1... |
| 14:56:32 | <Axman6> | > foldl' (\x n -> n * 1114111 + ord x) 0 "ABC" |
| 14:56:33 | <lambdabot> | Couldn't match expected type `GHC.Types.Char' |
| 14:56:48 | <Axman6> | :t foldl' (\x n -> n * 1114111 + ord x) 0 |
| 14:56:48 | <Jedai> | > foldl' (\x n -> x * 1114111 + ord n) 0 "ABC" |
| 14:56:50 | <lambdabot> | 80680889352258 |
| 14:56:50 | <lambdabot> | Couldn't match expected type `Char' against inferred type `Int' |
| 14:56:50 | <lambdabot> | In the expression: n * 1114111 + ord x |
| 14:56:50 | <lambdabot> | In the first argument of `foldl'', namely |
| 14:57:00 | <Axman6> | thaks Jedai |
| 14:57:12 | <Axman6> | i never can remember how to use folds |
| 14:57:25 | <paolino> | kpreid: I want to write a function IO a -> ErrorT String IO a, where the possible IOExceptions are found in Lefts values , I suppose |
| 14:57:27 | <Jedai> | Axman6: you're welcome... so base 1114111 ? |
| 14:57:37 | <Axman6> | yup |
| 14:57:51 | <Axman6> | or, base Haskell Char |
| 14:59:08 | <paolino> | :i ErrorT |
| 14:59:16 | <paolino> | @src ErrorT |
| 14:59:17 | <lambdabot> | newtype ErrorT e m a = ErrorT { runErrorT :: m (Either e a) } |
| 14:59:52 | <marcot> | Is there a getDirectoryContentsRecursive function somewhere? |
| 14:59:52 | <marcot> | Like unix find. |
| 14:59:52 | <lambdabot> | marcot: You have 1 new message. '/msg lambdabot @messages' to read it. |
| 15:00:32 | <EvilTerran> | marcot, there may be something on hackage |
| 15:00:42 | <jbjohns> | harlekin: thanks |
| 15:00:48 | <jbjohns> | l |
| 15:03:45 | <Phyx-> | @info -> |
| 15:03:45 | <lambdabot> | Parse error at "->" (column 1) |
| 15:03:48 | <paolino> | :t \f -> ErrorT ((Right <$> f) `catch` (return . Left . show)) |
| 15:03:54 | <Phyx-> | @info ~> |
| 15:03:54 | <lambdabot> | (~>) |
| 15:04:01 | <Phyx-> | helpful |
| 15:04:09 | <harlekin> | :D |
| 15:04:42 | <Phyx-> | @info (~>) |
| 15:04:42 | <lambdabot> | (~>) |
| 15:04:59 | <Phyx-> | @type (~>) |
| 15:05:00 | <lambdabot> | Not in scope: `~>' |
| 15:05:02 | <paolino> | info is not offensive at least :| |
| 15:05:17 | <Phyx-> | lol |
| 15:05:20 | <EvilTerran> | Phyx-, there's no @info command, it's typo-corrected to @undo |
| 15:05:20 | <EvilTerran> | @info do x <- 1; return (x,x) |
| 15:05:20 | <lambdabot> | 1 >>= \ x -> return (x, x) |
| 15:05:36 | <Phyx-> | EvilTerran: which explains alot |
| 15:05:37 | <Phyx-> | lol |
| 15:05:51 | <EvilTerran> | ^ see, @undo :) |
| 15:06:20 | <Phyx-> | > folder (+) 0 [] |
| 15:06:22 | <lambdabot> | Not in scope: `folder' |
| 15:06:42 | <Phyx-> | oops, right, only commands are typo corrected |
| 15:08:59 | <Phyx-> | @king StateT |
| 15:08:59 | <lambdabot> | Maybe you meant: kind ping |
| 15:09:09 | <Phyx-> | @king\d StateT |
| 15:09:10 | <lambdabot> | * -> (* -> *) -> * -> * |
| 15:09:20 | <Phyx-> | lol |
| 15:09:41 | <Phyx-> | that was actually unintentional |
| 15:09:44 | <jbjohns> | @src (>>>) |
| 15:09:44 | <lambdabot> | Source not found. Where did you learn to type? |
| 15:09:51 | <Phyx-> | hahaha |
| 15:10:07 | <Phyx-> | @index (>>>) |
| 15:10:07 | <lambdabot> | Control.Arrow |
| 15:10:17 | <Phyx-> | @src Control.Arrow |
| 15:10:17 | <lambdabot> | Source not found. Where did you learn to type? |
| 15:10:23 | <paolino> | src is offensive |
| 15:10:28 | <Jedai> | @source Control.Arrow |
| 15:10:29 | <lambdabot> | http://darcs.haskell.org/packages/base/Control/Arrow.hs |
| 15:10:39 | <Jedai> | @source Control.Arrows |
| 15:10:40 | <lambdabot> | Control.Arrows not available |
| 15:10:49 | <Jedai> | @source isn't though :) |
| 15:10:49 | <lambdabot> | isn't though :) not available |
| 15:10:52 | <Phyx-> | why both src and source? |
| 15:11:08 | <Jedai> | Phyx-: they don't do the same thing |
| 15:11:17 | <Phyx-> | is src for it's local definitions? |
| 15:11:34 | <EvilTerran> | @src prints source code to the channel; @source provides a link to the source file |
| 15:11:49 | <EvilTerran> | @src foldr |
| 15:11:49 | <lambdabot> | foldr f z [] = z |
| 15:11:49 | <lambdabot> | foldr f z (x:xs) = f x (foldr f z xs) |
| 15:11:50 | <Jedai> | Phyx-: @src gives the source code for a function (when it knows it, so never... ;) and @source gives a link to the source file of a module |
| 15:12:01 | <Phyx-> | @src (+) |
| 15:12:02 | <lambdabot> | Source not found. I am sorry. |
| 15:12:05 | <jbjohns> | I think it's actually in Category |
| 15:12:11 | <EvilTerran> | @source Prelude |
| 15:12:11 | <lambdabot> | http://darcs.haskell.org/packages/base/Prelude.hs |
| 15:12:11 | <Phyx-> | Jedai: so... @src is useless? |
| 15:12:14 | <Jedai> | @src Int (+) |
| 15:12:14 | <lambdabot> | Source not found. BOB says: You seem to have forgotten your passwd, enter another! |
| 15:13:05 | <Jedai> | Phyx-: no, as EvilTerran has shown, @src works for Prelude functions and some others, but it won't work very often otherwise |
| 15:13:16 | <Jedai> | @src Maybe fmap |
| 15:13:16 | <lambdabot> | fmap _ Nothing = Nothing |
| 15:13:16 | <lambdabot> | fmap f (Just a) = Just (f a) |
| 15:13:21 | <Phyx-> | @hoogle (>>>) --info |
| 15:13:21 | <lambdabot> | Control.Arrow (>>>) :: Arrow a => a b c -> a c d -> a b d |
| 15:13:21 | <lambdabot> | |
| 15:13:21 | <lambdabot> | From package base, version 3.0.1.0 |
| 15:13:58 | <Phyx-> | Jedai: ok, then not useless, just not so useful :) |
| 15:14:12 | <Jedai> | Phyx-: nice to show a basic function to a beginner |
| 15:14:54 | <Phyx-> | :) |
| 15:15:10 | <Jedai> | Phyx-: by the way, @src (+) don't work because (+) is a class method, @src Int (+) should work but I'm guessing it don't because it's defined somewhere in the entrail of GHC |
| 15:15:27 | <Jedai> | @src Complex (+) |
| 15:15:27 | <lambdabot> | Source not found. Are you on drugs? |
| 15:15:32 | <Phyx-> | hahahah |
| 15:15:41 | <Phyx-> | rofl |
| 15:15:59 | <Jedai> | @src (++) |
| 15:15:59 | <lambdabot> | [] ++ ys = ys |
| 15:15:59 | <lambdabot> | (x:xs) ++ ys = x : (xs ++ ys) |
| 15:15:59 | <lambdabot> | -- OR |
| 15:15:59 | <lambdabot> | xs ++ ys = foldr (:) ys xs |
| 15:16:22 | <Phyx-> | @src return |
| 15:16:22 | <lambdabot> | Source not found. I can't hear you -- I'm using the scrambler. |
| 15:16:34 | <Jedai> | @src Maybe return |
| 15:16:34 | <lambdabot> | return = Just |
| 15:16:39 | <Phyx-> | ah |
| 15:16:40 | <Phyx-> | right |
| 15:17:27 | <Phyx-> | i was actually expecting it to print out the definition in the class, on the first one |
| 15:17:36 | <EvilTerran> | marcot, would http://hackage.haskell.org/cgi-bin/hackage-scripts/package/directory-tree suit your purposes? |
| 15:17:44 | <Taejo> | which Regex library is the fastest? (my regexes are large but fairly simple) |
| 15:17:52 | <Berengal> | @src Monad |
| 15:17:53 | <lambdabot> | class Monad m where |
| 15:17:53 | <lambdabot> | (>>=) :: forall a b. m a -> (a -> m b) -> m b |
| 15:17:53 | <lambdabot> | (>>) :: forall a b. m a -> m b -> m b |
| 15:17:54 | <lambdabot> | return :: a -> m a |
| 15:17:56 | <lambdabot> | fail :: String -> m a |
| 15:17:58 | <marcot> | EvilTerran: I was looking at Unixutils, let me see this option. |
| 15:18:03 | <Jedai> | Phyx-: Nope, @src is pretty stupid... and offensive ! |
| 15:18:22 | <Phyx-> | hehehe |
| 15:18:34 | <kpreid> | ACTION also wishes @src wouldn't print insults |
| 15:18:43 | <jbjohns> | I was just trying to figure out an example from Niel Bartlett's blog |
| 15:18:56 | <Jedai> | Taejo: regex-pcre is pretty fast from what I know, if you ever write a benchmark don't forget to post the results ! |
| 15:19:10 | <jbjohns> | > test1 a = a * a |
| 15:19:11 | <lambdabot> | <no location info>: parse error on input `=' |
| 15:19:20 | <jbjohns> | > let test1 a = a * a |
| 15:19:21 | <lambdabot> | not an expression: `let test1 a = a * a' |
| 15:19:31 | <marcot> | EvilTerran: Unixutils seems to be simpler. |
| 15:19:44 | <jbjohns> | no way to define functions with lambda bot then? |
| 15:19:49 | <Phyx-> | @let test1 a = a * a |
| 15:19:50 | <lambdabot> | Defined. |
| 15:19:53 | <jbjohns> | ah |
| 15:19:57 | <Phyx-> | > test1 6 |
| 15:19:59 | <lambdabot> | 36 |
| 15:20:04 | <Taejo> | Jedai: I was just thinking, if all else fails, I'll just use something that isn't PCRE. I prefer high-factor linear time to heavily optimized exponential |
| 15:20:18 | <Jedai> | jbjohns: but usually we use "> let ... in ..." |
| 15:20:29 | <EvilTerran> | but note all the @let definitions disappear if anyone does an @undef |
| 15:20:45 | <jbjohns> | He gave the example: summaries = deep (hasName "cd") >>> (getAttrValue "artist") &&& (getAttrValue "title") >>> (arr . uncurry) itemSummary |
| 15:20:50 | <Jedai> | @undef |
| 15:20:55 | <Phyx-> | @undef test1 |
| 15:21:07 | <Phyx-> | odd |
| 15:21:12 | <Phyx-> | > test1 7 |
| 15:21:13 | <lambdabot> | Not in scope: `test1' |
| 15:21:15 | <Phyx-> | ah |
| 15:21:37 | <Phyx-> | > join (+) 6 |
| 15:21:38 | <lambdabot> | 12 |
| 15:22:51 | <Jedai> | Taejo: you still have posix, IIRC they're linear time, no ? |
| 15:22:55 | <jbjohns> | As I read that, deep must be returning a list of xml nodes, but the rest of it seems to work with only one element |
| 15:23:06 | <mxc> | regarding atomicModifyIORef, the docs say that it is unsafe for multiple IORefs, does that mean that if you are trying to modify multiple IORefs in a single call its unsafe or if you have multiple IORefs in distinct parts of the code, anywhere, its unsafe? |
| 15:23:16 | <EvilTerran> | Phyx-, as i said, @undef doesn't take a parameter, it undefines everything |
| 15:23:26 | <Taejo> | Jedai: well, posix, tdfa and dfa seem to be the options |
| 15:23:40 | <Phyx-> | EvilTerran: that needs some updating |
| 15:23:59 | <jbjohns> | @let itemSummary a t = t ++ " performed by " ++ a |
| 15:24:01 | <lambdabot> | Defined. |
| 15:24:12 | <Jedai> | jbjohns: what's the definition of deep |
| 15:24:21 | <jbjohns> | deep scan of an XML tree |
| 15:24:30 | <eivuokko> | mxc, it means it's not possible to have atomic guarantee when trying to change multipe iorefs from one location, in presence of other threads/finalisers. |
| 15:24:35 | <Jedai> | jbjohns: right but what's its type |
| 15:25:04 | <mxc> | eivuokko : thanks. thats what I thought, but just wanted to double check |
| 15:25:09 | <jbjohns> | @let getAttrValue k ((k',v):'t) = if k == k' then v else getAttrValue k 't |
| 15:25:09 | <lambdabot> | Parse error in pattern: HsVarQuote (UnQual (HsIdent "t")) |
| 15:25:22 | <jbjohns> | @let getAttrValue k ((k',v):t') = if k == k' then v else getAttrValue k t' |
| 15:25:23 | <lambdabot> | Defined. |
| 15:25:40 | <jbjohns> | getAttrValue "artist" [("artist", "me")] |
| 15:25:46 | <jbjohns> | > getAttrValue "artist" [("artist", "me")] |
| 15:25:47 | <lambdabot> | "me" |
| 15:26:00 | <Berengal> | > curry id 5 6 |
| 15:26:02 | <lambdabot> | (5,6) |
| 15:26:04 | <Jedai> | @type lookup |
| 15:26:05 | <lambdabot> | forall a b. (Eq a) => a -> [(a, b)] -> Maybe b |
| 15:26:19 | <EvilTerran> | @src lookup |
| 15:26:20 | <lambdabot> | lookup _key [] = Nothing |
| 15:26:20 | <lambdabot> | lookup key ((x,y):xys) | key == x = Just y |
| 15:26:20 | <lambdabot> | | otherwise = lookup key xys |
| 15:26:59 | <jbjohns> | > (getAttrValue "artist") &&& (getAttrValue "title") >>> (arr . uncurry) itemSummary $ [("artist", "Puddle of mud"), ("title", "She hates me")] |
| 15:27:00 | <lambdabot> | "She hates me performed by Puddle of mud" |
| 15:27:32 | <jbjohns> | so I was trying to figure out how deep is able to get this part to iterate over all the nodes. It seems to operator only on a single entry |
| 15:27:47 | <jbjohns> | > :t (getAttrValue "artist") &&& (getAttrValue "title") >>> (arr . uncurry) itemSummary |
| 15:27:48 | <lambdabot> | <no location info>: parse error on input `:' |
| 15:27:59 | <jbjohns> | @type (getAttrValue "artist") &&& (getAttrValue "title") >>> (arr . uncurry) itemSummary |
| 15:28:00 | <lambdabot> | [([Char], [Char])] -> [Char] |
| 15:28:01 | <Jedai> | @type (>>>) |
| 15:28:02 | <lambdabot> | forall (cat :: * -> * -> *) a b c. (Control.Category.Category cat) => cat a b -> cat b c -> cat a c |
| 15:28:47 | <jbjohns> | @type deep |
| 15:28:48 | <lambdabot> | Not in scope: `deep' |
| 15:29:14 | <Jedai> | jbjohns: Your inquiry is pointless without the type of deep, the arrow in which we're operating or a link to the article/paper |
| 15:29:54 | <jbjohns> | it's from HXL |
| 15:30:05 | <jbjohns> | HXT even |
| 15:30:24 | <jbjohns> | the XML library that uses arrows |
| 15:30:53 | <jbjohns> | deep :: XmlFilter -> XmlFilter |
| 15:31:17 | <jbjohns> | type XmlFilter = XmlTree -> [XmlTree] |
| 15:35:34 | <lars9> | hey, i've learning haskell, i have a problem to solve but dunno how to design the code, may i get some help here? |
| 15:35:52 | <Zao> | Quite possibly. |
| 15:35:54 | <eivuokko> | Very likely. |
| 15:36:25 | <burp> | ?faq can haskell solve the problem? |
| 15:36:25 | <lambdabot> | The answer is: Yes! Haskell can do that. |
| 15:36:31 | <lars9> | the problem is: given a list l, print out all sublist of length n, and the number of their appearence |
| 15:39:19 | <Phyx-> | > quickCheck \x->x==x |
| 15:39:20 | <lambdabot> | <no location info>: parse error on input `\' |
| 15:39:34 | <Phyx-> | > quickCheck (\x->id x = x) |
| 15:39:36 | <lambdabot> | <no location info>: parse error on input `=' |
| 15:39:41 | <Phyx-> | > quickCheck (\x->id x == x) |
| 15:39:42 | <lambdabot> | Not in scope: `quickCheck' |
| 15:40:02 | <Jedai> | jbjohns: From what I see, deep is an operation from the class ArrowTree |
| 15:40:29 | <EvilTerran> | @check \x -> id x == x |
| 15:40:30 | <lambdabot> | "OK, passed 500 tests." |
| 15:40:42 | <Phyx-> | ah |
| 15:40:46 | <EvilTerran> | @check \x y -> x == y -- but beware of defaulting |
| 15:40:47 | <lambdabot> | "OK, passed 500 tests." |
| 15:40:47 | <jbjohns> | ah, yep, I see it |
| 15:41:04 | <Phyx-> | @check \x join pure x == x |
| 15:41:04 | <lambdabot> | Parse error at "==" (column 16) |
| 15:41:13 | <Phyx-> | @check \x-> join pure x == x |
| 15:41:14 | <lambdabot> | "OK, passed 500 tests." |
| 15:41:29 | <Jedai> | jbjohns: anyway, arrows are a very powerful abstraction, (>>>) on this case isn't working on simple functions, trying to approximate it with composition won't work |
| 15:41:34 | <Phyx-> | how does that work anyway, i don't see how join pure becomes the identity |
| 15:41:35 | <lars9> | for example, give 1231234, all sublists of length 3 are: 123, 231, 312, 234, which appears 2, 1, 1, 1 times, respectively |
| 15:41:55 | <voker57__> | lars9: something like [inits ts | ts <- tails xs] |
| 15:42:04 | <voker57__> | where xs is the list |
| 15:42:43 | <Phyx-> | @type join pure |
| 15:42:44 | <lambdabot> | forall a. a -> a |
| 15:42:47 | <Phyx-> | @type join |
| 15:42:48 | <lambdabot> | forall (m :: * -> *) a. (Monad m) => m (m a) -> m a |
| 15:42:58 | <voker57__> | > let xs = [1..10] |
| 15:42:59 | <lambdabot> | not an expression: `let xs = [1..10]' |
| 15:43:06 | <EvilTerran> | ?type join pure |
| 15:43:07 | <lambdabot> | forall a. a -> a |
| 15:43:16 | <voker57__> | > let xs = [1..10] in [inits ts | ts <- tails xs] |
| 15:43:17 | <lambdabot> | [[[],[1],[1,2],[1,2,3],[1,2,3,4],[1,2,3,4,5],[1,2,3,4,5,6],[1,2,3,4,5,6,7],... |
| 15:43:28 | <jbjohns> | Jedai: I agree, but the thing I did above was using the same operators. I tried passing a list of those nodes but I didn't see how to make it traverse. (>>>) also doesn't seem to be a type class method so I didn't see how it's overloaded unless (.) itself is overloaded |
| 15:43:39 | <Taejo> | > break (== 2) [2, 2, 3, 4] |
| 15:43:42 | <lambdabot> | ([],[2,2,3,4]) |
| 15:43:48 | <Phyx-> | EvilTerran: I thought the result of join was always a monad |
| 15:43:50 | <Taejo> | > break (=/ 2) [2, 2, 3, 4] |
| 15:43:52 | <lambdabot> | Not in scope: `=/' |
| 15:43:59 | <Taejo> | > span (== 2) [2, 2, 3, 4] |
| 15:44:01 | <lambdabot> | ([2,2],[3,4]) |
| 15:44:01 | <byorgey> | Phyx-: that's using the ((->) a) monad |
| 15:44:16 | <Taejo> | anyone have a good mnemonic for which is which of break and span? |
| 15:44:21 | <Jedai> | > M.fromList (take 3 . tails $ [1, 2, 3, 1, 2, 3, 4]) |
| 15:44:22 | <lambdabot> | Couldn't match expected type `(k, a)' against inferred type `[a1]' |
| 15:44:32 | <voker57__> | > let xs = [1..5] in [filter (/= []) (inits ts) | ts <- tails xs] |
| 15:44:33 | <byorgey> | pure :: a -> m a, so unifying that with m (m a) means m = (a ->) |
| 15:44:34 | <lambdabot> | [[[1],[1,2],[1,2,3],[1,2,3,4],[1,2,3,4,5]],[[2],[2,3],[2,3,4],[2,3,4,5]],[[... |
| 15:44:34 | <Jedai> | > S.fromList (take 3 . tails $ [1, 2, 3, 1, 2, 3, 4]) |
| 15:44:35 | <lambdabot> | fromList [[1,2,3,1,2,3,4],[2,3,1,2,3,4],[3,1,2,3,4]] |
| 15:45:02 | <voker57__> | > let xs = [1..3] in [filter (/= []) (inits ts) | ts <- tails xs] |
| 15:45:04 | <lambdabot> | [[[1],[1,2],[1,2,3]],[[2],[2,3]],[[3]],[]] |
| 15:45:06 | <EvilTerran> | Phyx-, both the join and the pure are in the (e->) monad |
| 15:45:13 | <Jedai> | > M.fromList (map take 3 . tails $ [1, 2, 3, 1, 2, 3, 4]) |
| 15:45:14 | <lambdabot> | Couldn't match expected type `b -> c' |
| 15:45:20 | <voker57__> | > let xs = [1..3] in filter (/=[]) [filter (/= []) (inits ts) | ts <- tails xs] |
| 15:45:21 | <Jedai> | > M.fromList (map (take 3) . tails $ [1, 2, 3, 1, 2, 3, 4]) |
| 15:45:22 | <lambdabot> | [[[1],[1,2],[1,2,3]],[[2],[2,3]],[[3]]] |
| 15:45:23 | <lambdabot> | Couldn't match expected type `(k, a)' against inferred type `[a1]' |
| 15:45:29 | <EvilTerran> | Phyx-, in which join f x = f x x, and pure = const |
| 15:45:30 | <Jedai> | > S.fromList (map (take 3) . tails $ [1, 2, 3, 1, 2, 3, 4]) |
| 15:45:31 | <lambdabot> | fromList [[],[1,2,3],[2,3,1],[2,3,4],[3,1,2],[3,4],[4]] |
| 15:45:35 | <voker57__> | that's it, i guess |
| 15:45:35 | <lars9> | in other languages, that problem requires a 'map', but how to do in haskell |
| 15:45:41 | <Phyx-> | EvilTerran, byorgey hm, ok, guess i'll go take a look at that monad |
| 15:45:47 | <Jedai> | lars9: with a MAp |
| 15:46:15 | <voker57__> | with map, you map! |
| 15:46:24 | <Jedai> | > M.fromListWith (+) . map (flip (,) 1) . map (take 3) . tails $ [1, 2, 3, 1, 2, 3, 4] |
| 15:46:26 | <lambdabot> | fromList [([],1),([1,2,3],2),([2,3,1],1),([2,3,4],1),([3,1,2],1),([3,4],1),... |
| 15:46:56 | <Jedai> | lars9: there, it's almost good, you just have to delete those pesky too small sublists |
| 15:47:09 | <EvilTerran> | Phyx-, Reader is just (->) with a newtype wrapper |
| 15:47:23 | <voker57__> | i solved this already |
| 15:47:58 | <voker57__> | why IntMap? |
| 15:48:12 | <Jedai> | voker57__: I didn't see it ? |
| 15:48:24 | <Phyx-> | EvilTerran: ah ok, cool |
| 15:48:39 | <voker57__> | Jedai: let xs = [1..3] in filter (/=[]) [filter (/= []) (inits ts) | ts <- tails xs] |
| 15:48:46 | <Jedai> | voker57__: I don't think you're resolving the problem lars9 asked |
| 15:49:02 | <skorpan> | would it be appropriate to call something with the type "s -> Bool" a predicate? |
| 15:49:05 | <EvilTerran> | voker57__, it'd be better to write (not.null) rather than (/= []) |
| 15:49:06 | <Jedai> | voker57__: he wanted all sublists of length n (3 in his example) |
| 15:49:12 | <voker57__> | ah, length n |
| 15:49:19 | <EvilTerran> | ?type not.null |
| 15:49:19 | <EvilTerran> | ?type (/= []) |
| 15:49:20 | <lambdabot> | forall a. [a] -> Bool |
| 15:49:21 | <lambdabot> | forall a. (Eq a) => [a] -> Bool |
| 15:49:27 | <voker57__> | well another filter :) |
| 15:49:31 | <EvilTerran> | skorpan, entirely appropriate, imo |
| 15:49:32 | <Jedai> | @src (>>>) |
| 15:49:33 | <lambdabot> | Source not found. My brain just exploded |
| 15:49:34 | <Phyx-> | ahhh ok |
| 15:49:36 | <skorpan> | EvilTerran: okay, thanks |
| 15:49:40 | <Phyx-> | makes sense now |
| 15:49:44 | <Jedai> | @source Control.Arrow |
| 15:49:44 | <lambdabot> | http://darcs.haskell.org/packages/base/Control/Arrow.hs |
| 15:50:08 | <voker57__> | Jedai: let xs = [1..3] in filter (((==) 3) . length) [filter (not.null) (inits ts) | ts <- tails xs] |
| 15:50:15 | <voker57__> | > let xs = [1..3] in filter (((==) 3) . length) [filter (not.null) (inits ts) | ts <- tails xs] |
| 15:50:17 | <lambdabot> | [[[1],[1,2],[1,2,3]]] |
| 15:51:06 | <Jedai> | @source Control.Category |
| 15:51:06 | <lambdabot> | Control.Category not available |
| 15:52:18 | <Jedai> | jbjohns: but (.) is overloaded (in Control.Category, where (>>>) is defined) |
| 15:52:37 | <voker57__> | > let xs = [1..5]; n=3 in filter (not.null) [filter (((==) 3) . length) (inits ts) | ts <- tails xs] |
| 15:52:39 | <lambdabot> | [[[1,2,3]],[[2,3,4]],[[3,4,5]]] |
| 15:53:08 | <Jedai> | voker57__: not elegant (and you have too much []) |
| 15:53:25 | <voker57__> | > let xs = [1..5]; n=3 in foldl (++) [] $ filter (not.null) [filter (((==) 3) . length) (inits ts) | ts <- tails xs] |
| 15:53:27 | <lambdabot> | [[1,2,3],[2,3,4],[3,4,5]] |
| 15:54:03 | <voker57__> | yep... the requirement on length allows to make it easier |
| 15:54:04 | <Jedai> | > M.fromListWith (+) . map (flip (,) 1) . foldr (.) id (replicate 2 inits) . map (take 3) . tails $ [1, 2, 3, 1, 2, 3, 4] |
| 15:54:05 | <lambdabot> | Occurs check: cannot construct the infinite type: a = [a] |
| 15:54:26 | <Jedai> | > M.fromListWith (+) . map (flip (,) 1) . foldr (.) id (replicate 2 init) . map (take 3) . tails $ [1, 2, 3, 1, 2, 3, 4] |
| 15:54:28 | <lambdabot> | fromList [([1,2,3],2),([2,3,1],1),([2,3,4],1),([3,1,2],1),([3,4],1)] |
| 15:54:36 | <Jedai> | ok, so : |
| 15:54:41 | <Taejo> | what is the language pragma for no monorphism restriction? |
| 15:54:52 | <jbjohns> | jedai: yea, I was looking to see if that was overriden to do some iteration anywhere, but the definition for deep you found doesn't seem to iterate. Definition: deep f = f `orElse` (getChildren >>> deep f) |
| 15:55:02 | <wli> | {-# LANGUAGE NoMonomorphismRestriction #-} |
| 15:55:40 | <Jedai> | let countSub n = M.fromListWith (+) . map (flip (,) 1) . foldr (.) id (replicate (n-1) init) . map (take n) . tails in countSub 3 [1, 2, 3, 1, 2, 3, 4] |
| 15:55:46 | <Jedai> | > let countSub n = M.fromListWith (+) . map (flip (,) 1) . foldr (.) id (replicate (n-1) init) . map (take n) . tails in countSub 3 [1, 2, 3, 1, 2, 3, 4] |
| 15:55:47 | <lambdabot> | fromList [([1,2,3],2),([2,3,1],1),([2,3,4],1),([3,1,2],1),([3,4],1)] |
| 15:56:14 | <Jedai> | > let countSub n = M.fromListWith (+) . map (flip (,) 1) . foldr (.) id (replicate n init) . map (take n) . tails in countSub 3 [1, 2, 3, 1, 2, 3, 4] |
| 15:56:15 | <lambdabot> | fromList [([1,2,3],2),([2,3,1],1),([2,3,4],1),([3,1,2],1)] |
| 15:56:49 | <Jedai> | lars9: There, you have it, works perfectly and not too inneficient |
| 15:57:07 | <voker57__> | > let n = 3; xs = [1..5] in filter (((==) n) . length) $ map (take n) (tails xs) |
| 15:57:09 | <lambdabot> | [[1,2,3],[2,3,4],[3,4,5]] |
| 15:57:10 | <lars9> | Jedai: thanks, let me learn it |
| 15:57:14 | <Taejo> | wli: thanks, must have been misspelling it |
| 15:57:15 | <voker57__> | another one :) |
| 15:57:15 | <lars9> | Jedai: first |
| 15:57:28 | <lars9> | voker57__: great, thanks too |
| 15:58:06 | <voker57__> | Jedai: so why do use Map? |
| 15:58:23 | <Jedai> | voker57__: ((==) n) can be written (n ==), it's a little bit better IMHO |
| 15:58:56 | <Jedai> | voker57__: to count the number of occurence of each sublist, it was my understanding that this was what was asked |
| 15:59:08 | <voker57__> | oh. |
| 15:59:20 | <lars9> | Jedai: yeah, count the number of occurence |
| 15:59:24 | <voker57__> | ACTION needs to learn to read |
| 15:59:45 | <Jedai> | <lars9> the problem is: given a list l, print out all sublist of length n, and the number of their appearence |
| 16:00:01 | <voker57__> | i though it was about a total number of sublists |
| 16:00:21 | <lars9> | that would be length - n + 1, :D |
| 16:01:02 | <Jedai> | voker57__: also your proposition is less efficient than my own, probably two times slower |
| 16:02:07 | <lars9> | Jedai: is there staright forward way to do the count thing? like count the number of each char in a string |
| 16:02:50 | <Jedai> | lars9: the idiom is "M.fromListWith (+) . map (flip (,) 1)" |
| 16:03:03 | <EvilTerran> | lars9, length . filter (==c) would be the usual method |
| 16:03:14 | <EvilTerran> | (for each char) |
| 16:03:32 | <EvilTerran> | or map (head &&& length) . group . sort |
| 16:03:42 | <EvilTerran> | to get a [(Char,Int)] with a list of counts |
| 16:03:43 | <lars9> | EvilTerran: then we need to 'unique' the string first? |
| 16:03:58 | <Phyx-> | nub |
| 16:04:00 | <EvilTerran> | > map (head &&& length) . group . sort $ "abracadabra" |
| 16:04:02 | <lambdabot> | [('a',5),('b',2),('c',1),('d',1),('r',2)] |
| 16:04:25 | <Jedai> | Phyx-: Please don't say nub to the beginner, it's too damn slow ! |
| 16:04:36 | <Phyx-> | rofl |
| 16:04:53 | <Phyx-> | it's because he is a beginner i said it |
| 16:04:56 | <lars9> | EvilTerran: abracadabra is common in textbook, did you just think it out? :D |
| 16:05:05 | <EvilTerran> | nub is O(n^2); map head . sort is O(n*log n) |
| 16:05:05 | <Phyx-> | @type group |
| 16:05:07 | <lambdabot> | forall a. (Eq a) => [a] -> [[a]] |
| 16:05:10 | <Jedai> | EvilTerran: What do you think is faster ? The Map trick or this one (theoretically it has the same complexity) |
| 16:05:31 | <Heffalump> | hi augustss |
| 16:05:55 | <augustss> | hi |
| 16:05:57 | <Phyx-> | @index group |
| 16:05:57 | <lambdabot> | Data.List |
| 16:06:05 | <EvilTerran> | lars9, i just use it as a placeholder for demo'ing various string manipulations |
| 16:06:13 | <EvilTerran> | lars9, it has various useful properties for that sort of thing |
| 16:06:17 | <Phyx-> | hmm interestig function |
| 16:06:22 | <EvilTerran> | (like five 'a's) |
| 16:08:13 | <lars9> | what about the usual way of implementing key-value data structure in haskell? |
| 16:08:26 | <EvilTerran> | Jedai, no idea; i figure they're probably close enough that you should use whichever you find clearest |
| 16:08:29 | <EvilTerran> | lars9, that'd be Data.Map |
| 16:09:12 | <lars9> | EvilTerran: let me check Data.Map, maybe it's better in doing the counting job |
| 16:09:27 | <lars9> | EvilTerran: more straight forward i mean |
| 16:09:28 | <Jedai> | lars9: That's what I used in my method |
| 16:09:56 | <lars9> | Jedai: the 'M' is Data.Map? |
| 16:10:04 | <Jedai> | @type M.fromListWith |
| 16:10:05 | <lambdabot> | forall a k. (Ord k) => (a -> a -> a) -> [(k, a)] -> M.Map k a |
| 16:10:11 | <lars9> | Jedai: sorry i didnt figure it out |
| 16:10:42 | <Jedai> | lars9: it's a shortcut in lambdabot (Data.Map is imported qualified as M) |
| 16:10:54 | <EvilTerran> | lars9, lambdabot basically has "import qualified Data.Map as M" |
| 16:11:06 | <lars9> | Jedai: i see, smart bot |
| 16:13:05 | <stepnem> | and what is the comma in (flip (,) 1)? |
| 16:13:26 | <Jedai> | stepnem: I could rewrite that as (\x -> (x,1)) |
| 16:13:41 | <stepnem> | ah, I see, :) |
| 16:13:49 | <Jedai> | stepnem: It could be clearer (depending on your addictiong to pointfree style) |
| 16:14:10 | <byorgey> | @type (,) |
| 16:14:11 | <lambdabot> | forall a b. a -> b -> (a, b) |
| 16:14:16 | <byorgey> | > (,) 2 3 |
| 16:14:17 | <lambdabot> | (2,3) |
| 16:14:22 | <stepnem> | heh |
| 16:14:42 | <lars9> | i know the Map thing now. How to do this counting job onlinely?: read symbols from a list one by one, and print the number of occurence of the read symbol. |
| 16:15:31 | <Jedai> | lars9: I'm not sure what you mean, you want to print the number of occurence "until now" ? |
| 16:15:33 | <byorgey> | you can do that with a Map too. just keep a Map around and update it each time you read a symbol |
| 16:16:02 | <lars9> | read 'a', print 1, read 'b', print 1, read 'a', print 2, read 'c', print 1 |
| 16:16:23 | <lars9> | read '\n', exit |
| 16:17:48 | <kpreid> | lars9: if you like functionalness, start with 'main = interact yourFunc' where yourFunc :: String -> String |
| 16:18:19 | <Jedai> | lars9: Yep, do that with a Map, you can even be pretty efficient by using an insertLookupWithKey (in order to read and modify the value simultaneously) |
| 16:18:51 | <lars9> | Jedai: but how to loop in main? |
| 16:19:21 | <Jedai> | lars9: Try using kpreid method (interact) |
| 16:20:00 | <lars9> | Jedai: kpreid : thanks, let me check 'interact' first |
| 16:20:15 | <Jedai> | lars9: it's pretty easy to loop anyway, you can just call main in main (or do the same with another function if you want a smaller loop) |
| 16:21:14 | <lars9> | i see, recursion for loop |
| 16:21:53 | <lars9> | got to go now, thanks guys, bye:) |
| 16:22:03 | <Jedai> | lars9: You can also write your own loops |
| 16:28:01 | <RayNbow> | ah, apfelmus has a nice quit msg :) |
| 16:34:01 | <Taejo> | how do I run an external process in Haskell? |
| 16:36:40 | <int-e> | something in the process library should do the trick. http://hackage.haskell.org/cgi-bin/hackage-scripts/package/process -- System.Cmd is a simple interface that simply runs commands while System.Process is more complicated but allows you to capture stdin, stdout and stderr as well. |
| 16:44:18 | <burp> | argl, I hate "where" indention |
| 16:46:38 | <Cale> | burp: what about it? |
| 16:46:52 | <Cale> | burp: You have roughly two options |
| 16:46:56 | <Cale> | foo = bar |
| 16:47:05 | <Cale> | where bar = quux |
| 16:47:10 | <Cale> | foo = bar |
| 16:47:12 | <Cale> | where |
| 16:47:16 | <Cale> | bar = quux |
| 16:48:08 | <dolio> | No, no. In that second one, you should line bar up with where. :) |
| 16:48:17 | <Cale> | In either case, the subsequent lines should align to the column containing the first non-whitespace character after the 'where' |
| 16:48:20 | <burp> | really? |
| 16:48:26 | <Cale> | I wouldn't. |
| 16:49:20 | <Cale> | (but obviously the rule is a little more general than this) |
| 16:49:54 | <Cale> | The important thing is that the contents of the 'where' is indented more than the function/value definition itself. |
| 16:51:15 | <burp> | ok |
| 16:51:27 | <kpreid> | there's also foo = bar where |
| 16:51:27 | <kpreid> | ... |
| 16:51:42 | <Cale> | I find that a bit annoying, myself :) |
| 16:51:56 | <burp> | @pretty looooooooooong t = A*cos(omega*t) + B*sin(omega*t) + h where { A = 4.8-5*h; B = 1/2; h = 12.8/14; omega = 2*pi/12 } |
| 16:51:56 | <lambdabot> | looooooooooong t = A * cos (omega * t) + B * sin (omega * t) + h |
| 16:51:56 | <lambdabot> | where A = 4.8 - 5 * h |
| 16:51:56 | <lambdabot> | B = 1 / 2 |
| 16:51:56 | <lambdabot> | h = 12.8 / 14 |
| 16:51:56 | <lambdabot> | omega = 2 * pi / 12 |
| 16:51:57 | <Cale> | Unless the contents of the where will all fit onto that one line |
| 16:52:34 | <Cale> | burp: Note that the 'where' is part of the function definition itself, and *not* the expression on the right hand side of the = |
| 16:53:03 | <Cale> | This actually matters conceptually, as 'where' will scope over multiple guards. |
| 16:53:18 | <Cale> | foo x | y < 0 = ... |
| 16:53:23 | <Cale> | | y == 0 = ... |
| 16:53:28 | <Cale> | | y > 0 = ... |
| 16:53:33 | <Cale> | where y = x^2 + x + 1 |
| 16:54:56 | <burp> | http://paste.railsbox.eu/show/1IOFKrp52ZBMHgMHhPyr/ <- why is this indention wrong then? |
| 16:55:23 | <burp> | oh.. capitals |
| 16:55:33 | <Cale> | (heh, of course, thinking would reveal there that only one of my guards will ever succeed :) |
| 16:55:49 | <Cale> | oh, yes |
| 16:55:58 | <Cale> | A and B look like data constructors |
| 16:56:03 | <burp> | with correcty syntax highlighting the problem is directly visible :> |
| 16:56:09 | <Cale> | indeed :) |
| 17:00:44 | <int-e> | Calling a local binding in a function 'h' 'h' may lead to confusion. |
| 17:01:55 | <burp> | uh, thats true |
| 17:05:33 | <Taejo> | what is the Bool argument to executeFile? |
| 17:06:48 | <Taejo> | ah, never mind, looks like I should be using System.Process |
| 17:06:59 | <alexsuraci> | woo, just implemented python's struct.unpack in haskell |
| 17:07:16 | <int-e> | Taejo: yes you should. but it tells executeFile whether to search the PATH or not. |
| 17:07:31 | <Taejo> | int-e: thanks |
| 17:09:30 | <stepnem> | are there some more accessible resources on arrows (>>>,&&& etc.)? |
| 17:10:27 | <stepnem> | I see there's plenty of stuff on monads, on haskell.org, but what about arrows (other than the paper(s))...? |
| 17:11:03 | <Taejo> | stepnem: the distinction between "papers" and "not papers" is artificial :) |
| 17:11:22 | <Taejo> | but I agree that the arrows paper is not a great tutorial |
| 17:11:44 | <stepnem> | Taejo: well, whatever, *accessible* is my point here, :) |
| 17:12:02 | <Saizan> | the papers are quite accessible |
| 17:12:08 | <stepnem> | and more tutorial-like, yeah |
| 17:12:46 | <stepnem> | hm... maybe I should try the papers then -- honestly, I haven't so far, heh |
| 17:13:03 | <PeakerWork> | stepnem: I think you should start with Category, its much simpler |
| 17:13:30 | <Saizan> | arrows are not so widely used, so you don't have many compelling examples to work with |
| 17:13:34 | <PeakerWork> | stepnem: Arrows are not a very interesting class, due to a design mistake in there.. |
| 17:14:40 | <arjanb> | what design mistake? |
| 17:14:44 | <Taejo> | Saizan: I don't use arrows much, but I use the arrow combinators a fair bit with plain old (->) arrows |
| 17:14:59 | <Taejo> | first, second, (&&&), (***) are all pretty handy |
| 17:15:10 | <stepnem> | hm, I have to say that 'map (head &&& length) . group . sort $ "abracadabra"' *is* quite interesting and compelling for me, :) |
| 17:15:36 | <Saizan> | Taejo: yeah, but that's more like having Data.Tuple than anything else |
| 17:16:00 | <Taejo> | Saizan: yes, indeed. but it seems that's what stepnem is interested in |
| 17:16:19 | <Saizan> | i mean, if you're only using one instance ever you don't even need to learn about the abstraction |
| 17:16:25 | <Taejo> | indeed |
| 17:16:27 | <Saizan> | just learn about what each combinator does |
| 17:16:38 | <Taejo> | so, stepnem, don't bother learning the abstraction right now |
| 17:17:42 | <Taejo> | stepnem: the (&&&) combinator has type (a -> b) -> (a -> c) -> (a -> (b, c)) (restricting to the ordinary -> arrow) |
| 17:17:49 | <stepnem> | Taejo: but what should I look at then? only from the source it isn't very ovious to me what's going on there |
| 17:17:55 | <stepnem> | obvious* |
| 17:18:09 | <Taejo> | yes, because of the unneeded abstraction |
| 17:18:46 | <Taejo> | without the abstraction, (&&&) f g x = (f x, g x) |
| 17:19:02 | <Taejo> | and (***) f g (x, y) = (f x, g y) |
| 17:19:07 | <Saizan> | the instance for (->) should have that definition, or similar |
| 17:19:14 | <stepnem> | ah... right, :) |
| 17:19:15 | <Taejo> | true |
| 17:19:25 | <Taejo> | @src (&&&) (->) |
| 17:19:26 | <lambdabot> | Source not found. That's something I cannot allow to happen. |
| 17:19:32 | <Taejo> | @src &&& -> |
| 17:19:33 | <lambdabot> | Source not found. My pet ferret can type better than you! |
| 17:19:42 | <Taejo> | @src (->) (&&&) |
| 17:19:43 | <lambdabot> | Source not found. My mind is going. I can feel it. |
| 17:19:49 | <Taejo> | never mind, then |
| 17:22:53 | <PeakerWork> | how can Ocaml beat Haskell's conciseness in: http://gmarceau.qc.ca/blog/2009/05/speed-size-and-dependability-of.html ? |
| 17:23:40 | <Taejo> | @where (</>) |
| 17:23:41 | <lambdabot> | I know nothing about (</>). |
| 17:26:10 | <Taejo> | is it impossible to use readFile and appendFile on the same file in a program, even if I know that the one finishes before the other starts? |
| 17:29:19 | <Athas> | I just had my first real use of the Maybe monad in code. |
| 17:29:22 | <Athas> | Man, that is really handy. |
| 17:29:45 | <Athas> | I have a definition that now looks like: s' = s { finger = finger s >>= return . (+1) } |
| 17:29:55 | <Athas> | That would have been much more ugly if written explicitly. Thank you, Data.Maybe! |
| 17:30:12 | <CSWookie_> | ACTION goes back to look at that merge thing again. |
| 17:33:37 | <Jedai> | Taejo: No, it's not impossible at all |
| 17:34:01 | <int-e> | Taejo: It's not impossible, but the only way to close the file reliably after readFile is to consume all data that readFile returned. consume :: String -> IO (); consume = foldr (const id) (return ()), say. |
| 17:34:41 | <Jedai> | Athas: s' = s { finger = fmap (+1) (finger s) } |
| 17:35:08 | <Jedai> | Athas: Maybe is an instance of Functor too, and in your case that's all you need |
| 17:35:16 | <Athas> | Oh yes, that is better. Thank you. |
| 17:37:40 | <PhDP> | Somebody know what Don is using in this vidéo; http://www.youtube.com/watch?v=2Lqzygxvus0... emacs ? Vim ? (I really don't know much about this kind of thing, but it seems powerful) |
| 17:38:16 | <Samy> | Probably vim. |
| 17:38:26 | <Samy> | ACTION didn't look at the video |
| 17:38:54 | <profmakx> | its vim |
| 17:38:59 | <profmakx> | as you can see in the top bar |
| 17:39:01 | <Jedai> | PhDP: I couldn't say, the url is malformed for me |
| 17:39:40 | <profmakx> | some day i will try stuff out for my phd in haskell... |
| 17:39:50 | <PhDP> | http://archhaskell.wordpress.com/2009/03/24/chart-a-library-for-generating-2d-charts-and-plots/ |
| 17:39:52 | <Taejo> | int-e: my seq was in the wrong place. thanks for the help |
| 17:41:55 | <jbjohns> | do haskell structures have any kind of syntax like Erlang does? |
| 17:42:16 | <skorpan> | what do you mean? |
| 17:42:28 | <jbjohns> | like for example, the UTCTime structure has a field for every element of time, day, month, etc. |
| 17:42:49 | <jbjohns> | in erlang you could take one of those and do like: UTCTime#variable{hour = 2} |
| 17:42:57 | <jbjohns> | and get a copy of the variable but with the time set to 2 |
| 17:43:02 | <jbjohns> | er, with the hour set to 2 |
| 17:43:36 | <Jedai> | PhDP: Yeah, it vim but he doesn't do anything impressive with it (by emacs or vim standard anyway), the demo is nice thanks to the library, ghci and xmonad |
| 17:43:51 | <jbjohns> | it's nice when you just want to change a part of the "structure" but not all of it |
| 17:44:17 | <Jedai> | jbjohns: In haskell they're called records |
| 17:44:22 | <PhDP> | Well then I'm just easily impressed, for now I'm writting my code with basic text editor. |
| 17:44:39 | <jbjohns> | Erlang as well. I just knew they were made with the data keyword so I didn't know what Haskell called them |
| 17:44:45 | <Jedai> | jbjohns: and you have this kind of syntax too |
| 17:44:51 | <jbjohns> | wonderful |
| 17:45:16 | <Jedai> | data Stuff = { foo :: Int, bar :: Maybe Bool } |
| 17:45:36 | <Jedai> | test = { foo = 5, bar = Nothing } |
| 17:45:53 | <Jedai> | test2 = test { bar = Just True } |
| 17:46:07 | <Jedai> | data Stuff = Stuff { foo :: Int, bar :: Maybe Bool } |
| 17:46:20 | <jbjohns> | ah, that works? I didn't even know what try |
| 17:46:24 | <Jedai> | test = Stuff 5 Nothing |
| 17:46:42 | <jbjohns> | I read through Real World Haskell in the records part but I didn't see it |
| 17:46:43 | <Jedai> | jbjohns: sorry, my first version lacked the constructor |
| 17:47:24 | <Jedai> | test = Stuff {foo = 5, bar = Nothing} |
| 17:47:41 | <Jedai> | jbjohns: so test2 is test with bar modified |
| 17:48:03 | <Jedai> | jbjohns: "foo test" gets the value in the foo field |
| 17:48:53 | <Jedai> | jbjohns: This isn't perfect though, especially when you want to modify a value deep inside a record in a record in a record |
| 17:49:58 | <Jedai> | jbjohns: if you find yourself doing things like that look up the data-accessor package, it's pretty nice |
| 17:50:52 | <Jedai> | jbjohns: http://hackage.haskell.org/cgi-bin/hackage-scripts/package/data-accessor |
| 17:51:06 | <fracture> | (got booted; so missed if anyone answered that) |
| 17:51:58 | <jbjohns> | thanks, I just tried it out on my stuff, looks good |
| 17:52:14 | <jbjohns> | now I can go change a bunch of my code from when I didn't know you could do this |
| 17:52:33 | <Jedai> | jbjohns: How did you do it before ? |
| 17:53:00 | <jbjohns> | I have a function like: withDays f dt = UTCTime { day = f dt.day, month = dt.month, year = .... |
| 17:53:45 | <Jedai> | jbjohns: dt.month is written month dt in Haskell though |
| 17:53:52 | <fracture> | so in case that didn't go through: is there a way to make user defined data constructors that take a variable number of arguments (like [] does)? |
| 17:53:54 | <jbjohns> | I used Haskell before Erlang so it never occurred to me to even look for something like this |
| 17:54:03 | <fracture> | (or maybe [] doesn't...) |
| 17:54:05 | <jbjohns> | Jedai: Yea, must be that then |
| 17:54:45 | <fracture> | actually (after playing around), I guess I don't understand what the tutorials mean when they say [] is like a data constructor |
| 17:54:45 | <Jedai> | fracture: [1,2,3] is special syntax, it's syntax sugar for 1:2:3:[] |
| 17:55:04 | <fracture> | ohh now I get it... [] is a type constructor |
| 17:55:05 | <Jedai> | fracture: [] is not a data constructor, (:) is |
| 17:55:09 | <fracture> | got it |
| 17:55:11 | <fracture> | thanks |
| 17:55:16 | <Jedai> | fracture: right, [] is a type constructor |
| 17:55:18 | <idnar> | Jedai: [] is the data constructor for the empty list |
| 17:55:39 | <Jedai> | idnar: True, but it hasn't any arguments in this case |
| 17:55:45 | <idnar> | yeah |
| 17:55:47 | <idnar> | @src [] |
| 17:55:48 | <lambdabot> | data [] a = [] | a : [a] |
| 17:56:05 | <idnar> | (that's not a "real" definition, but if there were one, that would be it) |
| 17:56:14 | <fracture> | ah |
| 17:56:56 | <Jedai> | fracture: Note that you can use operator as data constructor for your datatypes, as long as they start by : |
| 17:57:08 | <fracture> | ah |
| 17:57:37 | <Jedai> | @src Complex |
| 17:57:37 | <lambdabot> | data (RealFloat a) => Complex a = !a :+ !a |
| 18:00:34 | <Jedai> | jbjohns: with data-accessor, you can rewrite that "day ^: f $ dt" |
| 18:01:10 | <jbjohns> | ah, that's some kind of composition? |
| 18:01:40 | <PeakerWork> | Jedai: [] is both a type-constructor and a data-constructor (as evident in its appearing on the LHS and RHS of that data declaration) |
| 18:02:14 | <Jedai> | PeakerWork: Yep, I forgot the empty list at first |
| 18:02:16 | <PeakerWork> | oh, didn't read the whole thing, you acknowledged that |
| 18:02:19 | <PeakerWork> | sorry |
| 18:02:37 | <AllNight^> | how can I get ghc to show me what the current directory is? I know I can change it with :cd |
| 18:03:00 | <AllNight^> | ACTION just got haskell-mode working :D |
| 18:03:22 | <Jedai> | jbjohns: Yes, in this case it's not particularly interesting, but with longer field name and especially with nested records it makes all the difference in the world |
| 18:03:50 | <jbjohns> | it looks neat with this as well |
| 18:04:03 | <Jedai> | jbjohns: "state ^: date ^: day ^: (+1) $ gameState" |
| 18:04:16 | <jbjohns> | but yea, I can imagine that really helping a lot for nested structures |
| 18:04:30 | <PeakerWork> | Jedai: probably nicer to use a composed accessor, in the same sense a (.) chain is nicer than ($) |
| 18:05:15 | <PeakerWork> | and accessor composition could be done with (Control.Category..) (You might need to declare your own instance) so you could have: (state . date . day) ^: (+1) $ gameState |
| 18:05:33 | <Jedai> | PeakerWork: True, something like "state <: date <: day ^: (+1) $ gameState" |
| 18:05:52 | <PeakerWork> | except <: is silly because accessors should be Control.Category.Category :) |
| 18:06:03 | <PeakerWork> | and one can use (.) or (<<<) |
| 18:06:21 | <PeakerWork> | (much less operator names to remember!) |
| 18:06:22 | <Jedai> | PeakerWork: I guess so, but I don't think the instance is defined by default |
| 18:08:27 | <Taejo> | I'm trying to open an external editor from Haskell -- 'runProcess "vim" [fn] Nothing Nothing Nothing Nothing Nothing' seems to me to be the right thing, but vim complains "Vim: Error reading input, exiting..." |
| 18:08:51 | <EvilTerran> | Taejo, you may need to provide a handle for it to read as stdin |
| 18:09:11 | <Taejo> | EvilTerran: "Handle to use for stdin (Nothing => use existing stdin)" |
| 18:09:36 | <EvilTerran> | oh right, i was thinking Nothing meant that stdin would start closed. |
| 18:10:53 | <PeakerWork> | @hoogle runProcess |
| 18:10:53 | <lambdabot> | System.Process runProcess :: FilePath -> [String] -> Maybe FilePath -> Maybe [(String, String)] -> Maybe Handle -> Maybe Handle -> Maybe Handle -> IO ProcessHandle |
| 18:11:02 | <EvilTerran> | AllNight^, :!pwd, perhaps? |
| 18:11:25 | <AllNight^> | yes that does it - thanks EvilTerran :) |
| 18:11:37 | <PeakerWork> | Maybe [Handle] would probably be nicer (stdin,stdout,stderr are just a convention, you may have more) |
| 18:12:34 | <PeakerWork> | @hoogle runProcess --info |
| 18:12:34 | <lambdabot> | System.Process runProcess :: FilePath -> [String] -> Maybe FilePath -> Maybe [(String, String)] -> Maybe Handle -> Maybe Handle -> Maybe Handle -> IO ProcessHandle |
| 18:12:34 | <lambdabot> | |
| 18:12:34 | <lambdabot> | Runs a raw command, optionally specifying Handles from which to take the stdin, stdout and stderr channels for the new process (otherwise these handles are inherited from the current process). |
| 18:12:53 | <PeakerWork> | Taejo: is your "existing stdin" ok? |
| 18:13:09 | <PeakerWork> | what's the 2nd FilePath? |
| 18:13:23 | <EvilTerran> | ACTION didn't know @hoogle could do that! :o |
| 18:13:28 | <Taejo> | PeakerWork: I'm running the program from a terminal; the 2nd FilePath is the cwd |
| 18:13:44 | <EvilTerran> | PeakerWork, i think it's the name of the process image as it sees it itself |
| 18:13:53 | <EvilTerran> | ... or that. |
| 18:14:08 | <PeakerWork> | I guess that would be the 2nd arg's (!!0) |
| 18:18:37 | <frwmanners> | join haskell-in-depth |
| 18:18:38 | <lambdabot> | frwmanners: You have 1 new message. '/msg lambdabot @messages' to read it. |
| 18:21:00 | <frwmanners> | Baughn: I seem to have got your message 7 days late |
| 18:21:03 | <Athas> | What's the easiest way to read a file as a list of Word32's? |
| 18:21:46 | <PeakerWork> | @hoogle FileHandle -> ByteString |
| 18:21:46 | <lambdabot> | Did you mean: Handle -> ByteString /count=20 |
| 18:21:46 | <lambdabot> | Data.ByteString unfoldr :: (a -> Maybe (Word8, a)) -> a -> ByteString |
| 18:21:46 | <lambdabot> | Data.ByteString.Lazy unfoldr :: (a -> Maybe (Word8, a)) -> a -> ByteString |
| 18:21:56 | <PeakerWork> | @hoogle FileHandle -> IO ByteString |
| 18:21:57 | <lambdabot> | Did you mean: Handle -> IO ByteString /count=20 |
| 18:21:57 | <lambdabot> | Data.ByteString unfoldr :: (a -> Maybe (Word8, a)) -> a -> ByteString |
| 18:21:57 | <lambdabot> | Data.ByteString.Lazy unfoldr :: (a -> Maybe (Word8, a)) -> a -> ByteString |
| 18:22:22 | <frwmanners> | Baughn: re filterE |
| 18:23:04 | <alexsuraci> | I'm getting this error when trying to build haskelldb-hsql: http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5449#a5449 |
| 18:23:12 | <alexsuraci> | related: http://hackage.haskell.org/packages/archive/haskelldb-hsql/0.10/logs/failure/ghc-6.10 |
| 18:23:38 | <alexsuraci> | Is there any known fix for that? |
| 18:23:42 | <PeakerWork> | hoogle/hayoo really kind of suck on this search |
| 18:23:44 | <Jedai> | @hoogle Handle -> IO ByteString |
| 18:23:44 | <lambdabot> | Data.ByteString hGetContents :: Handle -> IO ByteString |
| 18:23:44 | <lambdabot> | Data.ByteString hGetLine :: Handle -> IO ByteString |
| 18:23:45 | <lambdabot> | Data.ByteString.Char8 hGetContents :: Handle -> IO ByteString |
| 18:24:10 | <Jedai> | PeakerWork: as suggested, Handle instead of FileHandle works better |
| 18:24:15 | <PeakerWork> | oh |
| 18:24:18 | <PeakerWork> | whoops |
| 18:24:32 | <Jedai> | Athas: using binary is probably the easiest way |
| 18:24:33 | <PeakerWork> | Athas: you can combine this with Data.Binary.Get |
| 18:25:10 | <Athas> | Yes, I tried using Data.Binary myself, but I think my attempt just consed up a huge list, without ever passing beyond the first four bytes in the file. |
| 18:25:28 | <PeakerWork> | Athas: How did you use it? |
| 18:25:34 | <Athas> | Additionally, Data.Binary seems hardcoded to use lazy bytestrings. |
| 18:26:12 | <gwern> | Athas: indeed |
| 18:26:15 | <Athas> | I can't remember. A recursive parser using getWord32be. |
| 18:26:18 | <gwern> | and binary-strict is a hack |
| 18:26:33 | <PeakerWork> | hmm.. ByteString should have been a class? :P |
| 18:26:45 | <Athas> | Is there a clean way to force the evaluation of the parser before my file handle is closed, in that case? |
| 18:27:04 | <gwern> | 'Performance This was the real unknown. Performance on the prototype looked |
| 18:27:05 | <gwern> | good, but we did not know how it would scale. Other systems implemented in |
| 18:27:05 | <gwern> | Haskell, like Darcs (Roundy, 2005), have shown that performance can be an issue |
| 18:27:05 | <gwern> | in real-world workloads. |
| 18:27:08 | <Athas> | Perhaps I should just use Data.Binary.decodeFile? |
| 18:27:19 | <gwern> | auugh. I knew darcs would become a cited example of bad haskell performance -_- |
| 18:27:25 | <PeakerWork> | Athas: the doc says it just uses ByteString's readFile? |
| 18:27:52 | <PeakerWork> | gwern: is that a horrible thing? |
| 18:28:05 | <gwern> | PeakerWork: yes, it prevents people from swallowing our koolaid |
| 18:28:24 | <PeakerWork> | I don't know how much of darcs' bad performance was attributed to Haskell and how much to the logic, though |
| 18:28:36 | <frwmanners> | Baughn: looking at the new code, it's redundant |
| 18:29:07 | <Baughn> | frwmanners: How's that? |
| 18:29:47 | <frwmanners> | Baughn: So, the problem was Max (AddBounds t) as time in FutureG |
| 18:30:02 | <Baughn> | frwmanners: Er. Hang on, what? |
| 18:30:04 | <Baughn> | What new code? |
| 18:30:04 | <gwern> | ' A surprising weakness was executable size, |
| 18:30:08 | <gwern> | with our executables coming in at 5 megabytes each. With several executables per |
| 18:30:11 | <gwern> | release, and several prototype releases running simultaneously, fpf turned out to |
| 18:30:14 | <gwern> | be unexpectedly disk hungry. |
| 18:30:33 | <frwmanners> | Baughn: reactive-0.11 |
| 18:30:37 | <gwern> | ' A combination of make (Feldman, 1979) and Perl (Wall & Schwartz, 1990) scripts |
| 18:30:40 | <gwern> | complete the build system infrastructure, including a program-level regression test |
| 18:30:41 | <frwmanners> | I think (???) |
| 18:30:43 | <gwern> | suite. Relatively mainstream tools were selected here to simplify maintenance. |
| 18:30:43 | <Baughn> | frwmanners: So that should be the unamb code.. |
| 18:30:45 | <gwern> | -_- |
| 18:30:54 | <Baughn> | frwmanners: Um, I don't think I've got any code in reactive-0.11.. |
| 18:31:14 | <frwmanners> | frwmanners: Sorry, you asked me to elaborate on something I said a week ago |
| 18:31:20 | <Baughn> | frwmanners: What I've been working on is unamb and TVal.hs. The latter is part of reactive, granted, but it isn't done yet.. |
| 18:31:21 | <frwmanners> | ^^^ Baughn |
| 18:31:23 | <Baughn> | Oh |
| 18:31:31 | <Baughn> | I'd completely forgotten about that |
| 18:31:49 | <frwmanners> | Baughn: I only remembered because the lambdabot just told me |
| 18:32:01 | <frwmanners> | Baughn: sorry for time / confusion |
| 18:33:02 | <gwern> | ' The points-free approach, while |
| 18:33:04 | <Baughn> | It rolled out of my log, unfortunately. :/ |
| 18:33:06 | <gwern> | elegant, can make code unreadable, especially if it is written by quantitative analysts |
| 18:33:09 | <gwern> | moonlighting as functional programmers. |
| 18:33:26 | <Tsion> | Hello, could someone with admin on lambdabot make it join #botters please? |
| 18:33:32 | <gwern> | @remember SimonFrankau The points-free approach, while elegant, can make code unreadable, especially if it is written by quantitative analysts moonlighting as functional programmers. |
| 18:33:32 | <lambdabot> | It is forever etched in my memory. |
| 18:33:43 | <Athas> | http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5450#a5450 <- Why doesn't that work? |
| 18:34:00 | <Athas> | It just conses infinitely. |
| 18:34:33 | <Baughn> | frwmanners: But am I mistaken to think that implementing reactive for io-driven events will require the use of unsafePerformIO to grab the current time for the Ord instance of Improving? |
| 18:35:02 | <PeakerWork> | does Lazy Bytestring's file functions do unsafeInterleaveIO? |
| 18:35:03 | <Baughn> | frwmanners: Eg. when merging two Events |
| 18:35:47 | <Taejo> | @pl (\x -> not $ (x `inDB` db) || ("#" isPrefixOf x)) |
| 18:35:48 | <lambdabot> | not . liftM2 (||) (`inDB` db) isPrefixOf |
| 18:36:09 | <Baughn> | frwmanners: "Event a's first occurence is at 1.5 seconds. Event b's first occurence is unknown, but will get timestamped when it happens. We can wait until either (a) it happens, or (b) its clock says 1.5 seconds too, in which case a is first |
| 18:36:37 | <Baughn> | ...oh god, the horror |
| 18:36:48 | <frwmanners> | Baughn: I'd agree with that, but I'm now confused |
| 18:36:55 | <Taejo> | hang on, that's not right |
| 18:36:57 | <int-e> | Athas: what are you expecting it to do? and what are you reading? |
| 18:37:02 | <Taejo> | @pl (\x -> not $ (x `inDB` db) || (['#'] isPrefixOf x)) |
| 18:37:03 | <lambdabot> | not . liftM2 (||) (`inDB` db) isPrefixOf |
| 18:37:05 | <Taejo> | ack |
| 18:37:13 | <Taejo> | @pl (\x -> not $ (x `inDB` db) || ("#" `isPrefixOf` x)) |
| 18:37:15 | <lambdabot> | not . liftM2 (||) (`inDB` db) ("#" `isPrefixOf`) |
| 18:37:34 | <gwern> | ' The preferred solution would be developers more ex- |
| 18:37:37 | <gwern> | perienced in Haskell, but the combined Haskell and financial knowledge is rather |
| 18:37:40 | <gwern> | rare, and it seems that even a relatively inexperienced Haskell programmer can be |
| 18:37:43 | <PeakerWork> | Athas: do you want lazy I/O? Do you mind if the entire file is read immediately? |
| 18:37:43 | <gwern> | more productive than an experienced C++ programmer in domains such as ours. |
| 18:37:59 | <gwern> | ' Should in-process operation be required in the |
| 18:38:03 | <gwern> | future, a com interface can be integrated (Finne et al., 1999). |
| 18:38:04 | <gwern> | the fools! the poor fools! |
| 18:38:10 | <duaneb> | goddamn |
| 18:38:12 | <duaneb> | I hate parsing |
| 18:38:15 | <Athas> | int-e: I would expect it to read a list of Word32s from a file (sequentially, I suppose). And no, I have no strictness requirements. |
| 18:38:32 | <PeakerWork> | duaneb: why not use a Haskell DSL then? |
| 18:38:32 | <duaneb> | Only networking and database theory is a more evil field of computer science |
| 18:38:42 | <duaneb> | PeakerWork: because I need to parse :P |
| 18:38:49 | <PeakerWork> | duaneb: what needs parsing? :( |
| 18:38:50 | <Wraithan> | Ok, I am writing a client for todoist, their API returns JSON objects and I can get the JSON object into a object I could potentially use but I have no clue a to how I would get the data I need from it: http://www.moonpatio.com/fastcgi/hpaste.fcgi/view?id=2532 |
| 18:39:03 | <duaneb> | PeakerWork: s expressions |
| 18:39:06 | <Baughn> | frwmanners: You're not the only one. I'll need to break referential transparency to implement this. |
| 18:39:06 | <duaneb> | homework :/ |
| 18:39:31 | <Taejo> | what characters do I need to escape to make a string into a regex that matches itself? |
| 18:39:32 | <Wraithan> | I would like to grab the api_token value (along with others) but it seems like a rather complicated object to reach in and just grab that data |
| 18:39:42 | <Baughn> | frwmanners: Hopefully in a safe manner, exporting a referentially transparent /interface/, but.. oh my, I see why reactive has provoked RTS bugs |
| 18:40:00 | <frwmanners> | Baughn: I'm happy to think of the eventual goal (futures) as a fairly reasonable extension of the language's semantics |
| 18:40:15 | <int-e> | Athas: well, the list instance reads a word from the file, treats it as the length of the returned list, and then reads that many words. and decodeFile is strict so it won't return any data before the whole list is read. |
| 18:40:25 | <gwern> | Wraithan: wouldn't it be something like 'api_token $ r'? |
| 18:40:32 | <frwmanners> | Baughn: but I agree, that makes implementing it using current methods sort of unpleasant |
| 18:40:44 | <gwern> | Wraithan: since each field of a record has a getter function defined of the smae name |
| 18:41:21 | <Wraithan> | gwern: ok, so how would I access those getter fuctions? |
| 18:42:26 | <gwern> | Wraithan: or, looking at http://hackage.haskell.org/packages/archive/json/0.4.3/doc/html/Text-JSON-Types.html#v%3AfromJSObject |
| 18:42:31 | <gwern> | why not use get_field ? |
| 18:43:00 | <gwern> | offhand, it looks like 'get_field r "api_token"' might work? |
| 18:43:03 | <frwmanners> | Baughn: fyi, my original concern was that AddBounds (Improving t) hides all information when we don't know whether the occurrence is finite or not |
| 18:43:30 | <frwmanners> | Baughn: Improving (AddBounds t) is better; but as I say, this has already been done |
| 18:44:58 | <Taejo> | how do I delete a file from a Haskell program? |
| 18:45:07 | <mauke> | @hoogle removeFile |
| 18:45:07 | <lambdabot> | System.Directory removeFile :: FilePath -> IO () |
| 18:45:15 | <gwern> | Taejo: too vague; say more |
| 18:45:15 | <Taejo> | thanks, mauke |
| 18:46:01 | <Taejo> | the web version of hoogle finds no results for removeFile (I already guessed that name) |
| 18:47:19 | <int-e> | Athas: http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5450#a5452 may work better for you |
| 18:47:44 | <int-e> | Athas: where 'all' should be 'allWords' |
| 18:48:08 | <Athas> | int-e: thanks, I will try it out. |
| 18:48:26 | <int-e> | Athas: and 't' too. (darn. I should test the code after renaming an identifier twice) |
| 18:50:12 | <cads_> | the set C of infinite sequences of binary digits is searcheable. That means that in finite time, we can either return an element of it that satisfies a certain predicate, or say that the element does not exist in C. |
| 18:50:24 | <cads_> | this is a pretty shocking statement to me |
| 18:50:30 | <Wraithan> | Is there any way to strip that left and right crap off so I don't have to worry about both sides of the case returning the same value? just want to simplify things so I can get to actually trying to figure out how to do this, rather than running into typing issues because one side of a case returns something different (when I am just using it to strip left/right) |
| 18:50:32 | <cads_> | are you guys familiar with this result? |
| 18:51:05 | <int-e> | cads_: the point is that the predicate must be computable. |
| 18:51:14 | <cads_> | Exhaustible Sets in Higher-Type Computation: http://arxiv.org/abs/0808.0441 |
| 18:51:31 | <Twey> | cads_: Of course it's true |
| 18:51:50 | <int-e> | http://www.cs.bham.ac.uk/~mhe/papers/seemingly-impossible.html |
| 18:52:15 | <Twey> | Up to any given element, the set is finite |
| 18:52:41 | <PeakerWork> | cads_: you're searching a finite element of it -- if you sort the infinite sequences by length, its enough to get to a higher-lengthed one than the one you search? |
| 18:52:51 | <cads_> | int-e: I was wondering how a function of infinite rank could be used as our predicate and still preserve searcheability |
| 18:53:06 | <hackagebot> | MonadCatchIO-mtl 0.2.0.0 |
| 18:54:00 | <yitz> | hackagebot? |
| 18:54:18 | <yitz> | that's nice. |
| 18:54:27 | <mauke> | not nice enough |
| 18:54:36 | <yitz> | mauke? |
| 18:54:39 | <mauke> | it should use CTCP ACTIONs to announce stuff |
| 18:54:47 | <cads_> | so, Twey, I can't use this to create a representation of the binary number equal to the square root of two, for example? |
| 18:55:31 | <Twey> | Of course — that's irrational and is itself infinite |
| 18:55:56 | <cads_> | but it's a computable real |
| 18:56:20 | <cads_> | that is, there are reals that can't even be defined by a finite computational rule |
| 18:57:17 | <Wraithan> | @hoogle JSValue -> JSObject |
| 18:57:17 | <lambdabot> | Warning: Unknown type JSValue |
| 18:57:18 | <lambdabot> | Unsafe.Coerce unsafeCoerce :: a -> b |
| 18:57:18 | <lambdabot> | Prelude ($) :: (a -> b) -> a -> b |
| 18:58:06 | <Wraithan> | @hoogle Text.JSON.JSValue -> Text.JSON.JSObject |
| 18:58:06 | <lambdabot> | Parse error: |
| 18:58:07 | <lambdabot> | --count=20 "Text.JSON.JSValue -> Text.JSON.JSObject" |
| 18:58:07 | <lambdabot> | ^ |
| 18:58:13 | <Wraithan> | bleh |
| 18:58:22 | <crem> | listAvg x = ( fromIntegral $ sum x ) / ( fromIntegral $ length x ) -- why do I need the second pair of parentheses? |
| 18:58:27 | <cads_> | hmm, I think I'll implement the algorithm in the paper and see what it gives me to play with |
| 18:58:48 | <Jedai> | @hoogle JSValue -> JSObject +json |
| 18:58:48 | <lambdabot> | Could not find file: |
| 18:58:48 | <lambdabot> | json |
| 18:58:48 | <lambdabot> | Searched: |
| 18:58:56 | <int-e> | Wraithan: pattern match on the JSObject constructor? |
| 18:59:05 | <EvilTerran> | crem, because / is tighter binding than $ |
| 18:59:10 | <Wraithan> | int-e: huh? |
| 18:59:15 | <crem> | EvilTerran, thanks. |
| 18:59:34 | <Wraithan> | @hoogle String -> JSObject |
| 18:59:35 | <lambdabot> | Warning: Unknown type JSObject |
| 18:59:35 | <lambdabot> | Prelude error :: String -> a |
| 18:59:35 | <lambdabot> | Debug.Trace trace :: String -> a -> a |
| 18:59:35 | <Jedai> | Wraithan: http://www.haskell.org/hoogle/?hoogle=JSValue+-%3E+JSObject+%2Bjson |
| 18:59:36 | <yitz> | @info (/) |
| 18:59:36 | <lambdabot> | (/) |
| 18:59:57 | <int-e> | Wraithan: case jsvalue of JSObject jsobject -> jsobject; _ -> error "not an object" |
| 18:59:58 | <yitz> | urgh, no fixity info. |
| 19:00:20 | <EvilTerran> | @recall @info |
| 19:00:20 | <lambdabot> | Unknown command, try @list |
| 19:00:21 | <cads_> | aaack |
| 19:00:26 | <EvilTerran> | @quote @info |
| 19:00:26 | <lambdabot> | @info says: typo-corrects to @undo. it isn't a real command. |
| 19:00:33 | <cads_> | the predicate must be total |
| 19:01:14 | <cads_> | ACTION had really wanted to believe the stronger version he'd imagined |
| 19:02:08 | <Jedai> | cads_: Well if it takes infinite time to return, it sure won't find the searched element in finite time... |
| 19:02:48 | <Baughn> | cads_: Well, I dare say an incomputable predicate won't be very useful on a computer.. |
| 19:03:00 | <Baughn> | Or anywhere in this universe, really |
| 19:03:05 | <Heffalump> | oh, hi kowey |
| 19:03:10 | <Heffalump> | I was just trying to email you, one-handed |
| 19:03:23 | <Heffalump> | The Darcs wiki used to have links like |
| 19:03:23 | <Heffalump> | http://wiki.darcs.net/index.html/Foo |
| 19:03:23 | <Heffalump> | and |
| 19:03:23 | <Heffalump> | http://wiki.darcs.net/DarcsWiki/Foo |
| 19:03:23 | <Heffalump> | (a) the front page of http://darcs.net points to these old URLs |
| 19:03:25 | <cads_> | Baughn: hyper-turings? :D |
| 19:03:28 | <Baughn> | ACTION wonders why join isn't part of the Monad class |
| 19:03:35 | <Jedai> | cads_: What was your stronger version like ? I can't really imagine |
| 19:03:42 | <Heffalump> | (b) we should probably use Apache redirect rules to deal with other links we don't know about |
| 19:03:42 | <Baughn> | cads_: Aren't incomputables beyond even them |
| 19:03:45 | <gwern> | @src join |
| 19:03:45 | <lambdabot> | join x = x >>= id |
| 19:04:01 | <Baughn> | cads_: No matter. Current physical law says the universe is turing-computable. |
| 19:04:03 | <gwern> | Baughn: if it can be defined using just the existing monadic typeclass, why add it? |
| 19:04:08 | <cads_> | :) |
| 19:04:12 | <kowey> | Heffalump: oh, yes |
| 19:04:13 | <EvilTerran> | Baughn, for the same reason Functor isn't a superclass of Monad? |
| 19:04:18 | <Heffalump> | sorry, wrong channel! |
| 19:04:21 | <Heffalump> | ACTION --> #darcs |
| 19:04:30 | <Baughn> | gwern: Because you can also define >>= in terms of join and fmap, and it's often easier to do it that way around |
| 19:04:37 | <EvilTerran> | gwern, but in some circumstances, it'd be nice to be able to define a monad in terms of fmap/join/return instead of >>=/return |
| 19:04:38 | <cads_> | I think the point of hyper-turings is to compute with complete real numbers or higher cardinalities |
| 19:04:53 | <Jedai> | gwern: to have specialized version (and we could have default definition for >>= in function of join and vice-versa |
| 19:05:08 | <Baughn> | gwern: Plenty of libraries first define join, then go on to implement >>= in terms of join, then have of course join in terms of >>=... |
| 19:05:19 | <Baughn> | That's not including reactive, which has >>= in terms of join and join in terms of >>= |
| 19:05:43 | <Baughn> | In that case it's the /same/ join. Knot-tying for the win? ^^; |
| 19:05:53 | <EvilTerran> | O.o |
| 19:06:05 | <ray> | join join fmap fmap fmap fmap join |
| 19:06:21 | <EvilTerran> | ?type join join fmap fmap fmap fmap join |
| 19:06:22 | <lambdabot> | Occurs check: cannot construct the infinite type: |
| 19:06:22 | <lambdabot> | t = t -> t -> t1 -> t2 -> t3 -> t4 -> t5 |
| 19:06:22 | <lambdabot> | Probable cause: `join' is applied to too few arguments |
| 19:06:32 | <Baughn> | Anyway, statements like " e >>= f = joinE (fmap f e)" are very common in monad instances.. |
| 19:06:33 | <EvilTerran> | ... actually, i think it's applied to too many. :P |
| 19:06:36 | <cads_> | Jedai: I thought we were somehow able to quantify over the binary numbers that have computable expressions in terms of partial fractions or something like that |
| 19:06:49 | <ray> | yeah, i'm just beatboxing |
| 19:07:07 | <ray> | :k Join |
| 19:07:08 | <lambdabot> | Not in scope: type constructor or class `Join' |
| 19:08:26 | <cads_> | that set would be compact in C |
| 19:09:06 | <duaneb> | could someone help me with my s-expr parser? |
| 19:09:06 | <duaneb> | http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5453#a5453 |
| 19:09:07 | <cads_> | or {0, 1}^|N| |
| 19:09:11 | <duaneb> | specifically parseCons |
| 19:09:16 | <duaneb> | There are two type errors |
| 19:09:17 | <opqdonut> | cads_: which set? |
| 19:09:26 | <duaneb> | at lines 42 and 47 |
| 19:09:32 | <duaneb> | and I can't figure it out :/ |
| 19:09:44 | <cads_> | the set of binary numbers generated by algorithms of finite length |
| 19:09:53 | <opqdonut> | ah |
| 19:10:30 | <opqdonut> | how would it be compact in {0,1}^N |
| 19:10:49 | <duaneb> | well |
| 19:10:54 | <duaneb> | I've figured out the problem |
| 19:10:58 | <duaneb> | I just don't know why it exists |
| 19:12:08 | <Baughn> | conal: I think I've figured out how to fix makeEvent. You had, of course, covered it in the paper, but you know about information which man was not meant to know? This is some of it. |
| 19:12:13 | <Baughn> | ACTION quietly goes insane |
| 19:12:19 | <duaneb> | anyone? :| |
| 19:12:19 | <cads_> | opqdonut: I think you could write a sequence of generated numbers approaching any incomputable number, as their generator algorithms tended towards infinite length |
| 19:12:41 | <EvilTerran> | duaneb, i think, around line 42, you need "case endMaybe of Just _ -> return Null; Nothing -> parseLispType ..." |
| 19:12:46 | <Baughn> | duaneb: Ah, add the type errors as a revision please |
| 19:12:51 | <cads_> | but that actually seems like it could be disastrously bad intuition on by part :) |
| 19:12:53 | <Jedai> | duaneb: are you aware that they're a tutorial that show you step by step how to write a parser (with Parsec) and interpreter for Lisp in Haskell ? |
| 19:13:03 | <Jedai> | *there is |
| 19:13:04 | <duaneb> | Jedai: yea, I don't like their parsing :P |
| 19:13:06 | <EvilTerran> | duaneb, and similarly around 47, i suspect |
| 19:13:17 | <Jedai> | duaneb: Oh, ok... :D |
| 19:13:21 | <opqdonut> | cads_: hmm, what was the criterion for sequentially compact <=> compact |
| 19:13:27 | <opqdonut> | cads_: was it hausdorff or T3? |
| 19:13:37 | <duaneb> | EvilTerran: isn't that what I wrotE? |
| 19:13:40 | <duaneb> | wrote* |
| 19:14:11 | <EvilTerran> | duaneb, i mean, the second branch is already a monadic action, so shouldn't be wrapped in a "return" |
| 19:14:16 | <cads_> | opqdonut: well for example the rational numbers are compact in the reals, even though they're countable. This is because between any two reals there's still a rational |
| 19:14:27 | <EvilTerran> | duaneb, so you should float the "return" wrapping the case to inside it |
| 19:14:46 | <duaneb> | EvilTerran: ok, but why? |
| 19:14:51 | <EvilTerran> | (and only to the Just/Null branch) |
| 19:15:05 | <EvilTerran> | duaneb, the type of >>= |
| 19:15:07 | <EvilTerran> | ?type (>>=) |
| 19:15:09 | <lambdabot> | forall (m :: * -> *) a b. (Monad m) => m a -> (a -> m b) -> m b |
| 19:15:20 | <EvilTerran> | the RHS has to result in a monadic value |
| 19:15:25 | <opqdonut> | cads_: my point was, there are sequentially compact (=> each sequence has a limit) spaces that are not compact (=> each open cover has a finite subcover) |
| 19:15:48 | <EvilTerran> | duaneb, in parseLispType >>= (\t -> Cons t parseCons'), you're not doing that |
| 19:16:46 | <EvilTerran> | duaneb, and, re-writing that to, say "liftM (`Cons` parseCons) parseLispType", that's also a monadic action |
| 19:16:47 | <duaneb> | ah, nm |
| 19:16:48 | <duaneb> | figured out |
| 19:16:51 | <EvilTerran> | duaneb, so you don't need to wrap it in return |
| 19:17:06 | <duaneb> | EvilTerran: no, the problem was I was passing Cons a monad |
| 19:17:10 | <duaneb> | instead of what was in the monad |
| 19:17:21 | <duaneb> | (parseCons' instead of what was in parseCons') |
| 19:17:39 | <EvilTerran> | uh |
| 19:17:42 | <Jedai> | duaneb: The objective of return is to lift an ordinary value into the monad, here the second branch of the case isn't an ordinary value but monadic (it's also different from the type of the first branch of the case which is an obvious error) |
| 19:17:45 | <cads_> | opqdonut: hmm, sec while I open my analysis book :) |
| 19:17:50 | <EvilTerran> | duaneb, parseLispType >>= (\t -> Cons t parseCons') still isn't going to work |
| 19:17:57 | <EvilTerran> | even if you deal with parseCons' |
| 19:18:19 | <opqdonut> | cads_: in metric spaces sequential compactness is the same as compactness, but not generally in topological spaces |
| 19:18:30 | <opqdonut> | cads_: however, there was a simple criterion for when they are the same |
| 19:18:52 | <EvilTerran> | because (>>=) :: Parser a -> (a -> Parser b) -> Parser b, and (Cons ...) does not fit "Parser b" |
| 19:19:05 | <duaneb> | ah. |
| 19:19:20 | <EvilTerran> | ?type liftM |
| 19:19:21 | <duaneb> | I still don't get why putting the return inside each of the cases would help.... |
| 19:19:21 | <lambdabot> | forall a1 r (m :: * -> *). (Monad m) => (a1 -> r) -> m a1 -> m r |
| 19:19:37 | <duaneb> | the `case` type SHOULD be LispType |
| 19:19:53 | <Jedai> | duaneb: it won't be sufficient, but at least both branch of the case will have the same type |
| 19:19:55 | <EvilTerran> | duaneb, you're doing monadic stuff in one branch of the case |
| 19:20:10 | <EvilTerran> | duaneb, and "return (...)" has no monadic side-effects |
| 19:20:22 | <duaneb> | ahh, never mind |
| 19:20:26 | <duaneb> | I figured it out |
| 19:20:59 | <Jedai> | duaneb: the second branch should be something like do { lt <- parseLispType; c' <- parseCons'; return (Cons lt c') } |
| 19:21:22 | <cads_> | opqdonut: bleh, I can't make {0,1}^|N| into a metric space |
| 19:22:09 | <cads_> | wait yes i can |
| 19:25:19 | <cads_> | p(a, b) = sum (a_k + b_k)/2^k. a, b in {0,1}^|N| |
| 19:26:02 | <conal> | Baughn: glad to hear you're making progress. there's a lot packed into that paper. easy to miss things. |
| 19:26:11 | <_JFT_> | Is there some prescribed way to mix State and ST monads? Or is that a general don't? I have a specific application where I need to hold a few tables of "record" which are actually references. There are cyclical references. |
| 19:26:46 | <_JFT_> | So I was thinking of using an State monad for the topology containing the various tables and entry points |
| 19:27:03 | <_JFT_> | in these tables are record containing STRef |
| 19:28:19 | <Baughn> | conal: This time I'm carefully writing tests as I find problems, and coupling them to cabal test. I estimate the probability of this breaking in a future GHC update at 80-something percent. |
| 19:28:36 | <int-e> | _JFT_: StateT state (ST s) should work fine as a monad. Or you could store the state in an STRef. |
| 19:29:18 | <_JFT_> | int-e: I wanted to avoid stocking that state in an STRef since I want need to stack many maniupulation and wanted to avoid manually threading that state |
| 19:29:49 | <Jedai> | _JFT_: Then StateT state (ST s) should be perfect, no ? |
| 19:30:06 | <int-e> | _JFT_: or, meet in the middle, ReaderT (STRef s state) (ST s) |
| 19:30:14 | <_JFT_> | int-e: interesting... |
| 19:30:33 | <duaneb> | ok |
| 19:30:38 | <duaneb> | I got my sexpr working |
| 19:30:39 | <duaneb> | but |
| 19:30:40 | <_JFT_> | int-e: thanks for the ReaderT (STRef s state) (ST s) very clever! |
| 19:30:47 | <_JFT_> | int-e: I am going to try that route :) |
| 19:30:55 | <duaneb> | if there's trailing text, my parser ignores it |
| 19:31:06 | <conal> | Baughn: thanks a bunch for the tests! please include them in your next darcs patch. when unamb gets solid and efficient, i predict people will come up with lots of cool uses. |
| 19:31:15 | <mauke> | <* eof |
| 19:31:20 | <Jedai> | duaneb: put eof at the end of your parser |
| 19:33:12 | <duaneb> | Jedai: yea, just figured that out :P |
| 19:33:19 | <_JFT_> | int-e: the part that was bugging me is how do I eval a combination of State and ST if 2 or more field of my state are ST s... |
| 19:33:43 | <_JFT_> | int-e: using the ReaderT approach i.e. should bypass that issue |
| 19:34:17 | <hackagebot> | uu-parsinglib 2.1.0 |
| 19:37:18 | <int-e> | hackagebot should sat 'new package:' or something like that in addition to the package name. |
| 19:38:09 | <mauke> | hackagebot should /nick hackage and announce things in the format /me upload: uu-parsinglib 2.1.0 |
| 19:47:26 | <bakesz> | hi guys!is there some way to look into a function,which is made by another function?(sorry for my english).thanks for help |
| 19:48:07 | <Twey> | Template Haskell says yes. |
| 19:48:33 | <ray> | templatehaskellsayswhat? |
| 19:49:00 | <IRZ> | hi |
| 19:49:04 | <IRZ> | can u have two foreign keys for one table (each with multiple columns) pointing to the same table. |
| 19:49:44 | <Heffalump> | IRZ: Haskell isn't a database |
| 19:50:17 | <Botje> | bakesz: "look into a function" ? |
| 19:50:57 | <IRZ> | i cant find an answer to my question, so i thought i would ask here |
| 19:51:01 | <IRZ> | wha tis haskel exactly ? |
| 19:51:08 | <IRZ> | alot of people in thsi room |
| 19:51:09 | <Heffalump> | it's a programming language |
| 19:51:15 | <IRZ> | i guessed that |
| 19:51:25 | <IRZ> | but umm whats it predominantly used for |
| 19:51:32 | <Heffalump> | there's URLs in the topic you can use to find out about it |
| 19:51:49 | <tux_rocker> | http://en.wikipedia.org/wiki/Haskell ? |
| 19:51:57 | <IRZ> | was looking for a one sentece answer |
| 19:51:59 | <IRZ> | i dotn really care |
| 19:52:07 | <IRZ> | thx tho |
| 19:52:34 | <tux_rocker> | does anyone know a way to serialize a System.Random.StdGen? |
| 19:52:42 | <kynes> | hi, I have a question about Test.QuickCheck |
| 19:52:49 | <Heffalump> | tux_rocker: it's just a pair of Integers, isn't it? |
| 19:52:49 | <tux_rocker> | there's Read and Show instances but they're asymmetric |
| 19:52:55 | <Heffalump> | that sucks |
| 19:53:12 | <tux_rocker> | Heffalump: it is, but you can't build a StdGen straight from the pair of integers |
| 19:53:30 | <tux_rocker> | kynes: alright, go ahead |
| 19:53:30 | <Heffalump> | I think asymmetric Read/Show is a bug. |
| 19:53:46 | <kynes> | it generates objects having random values to check a property, the question is, can I get these temporary objects ? I mean I want to report them |
| 19:54:12 | <tux_rocker> | kynes: you could use Debug.Trace in the code of your tests |
| 19:54:13 | <kynes> | tux_rocker, is there a way to see the object during the check ? |
| 19:54:24 | <kynes> | tux_rocker, can you give an example usage ? |
| 19:54:37 | <kynes> | tux_rocker, thank you btw |
| 19:54:42 | <Heffalump> | I think QuickCheck 2 might have hooks to help with this |
| 19:55:51 | <bakesz> | Botje: i mean like this: let sum_nums w=if w==0 then 0 else (\f x -> (f (x-1)) +x ) sum_nums w |
| 19:55:52 | <tux_rocker> | Heffalump: I see no hooks on a quic first glance |
| 19:56:14 | <Heffalump> | fair enough |
| 19:56:18 | <bakesz> | it generates function to every input argument,and i would like to see it |
| 19:56:44 | <Botje> | you can't print functions |
| 19:57:24 | <bakesz> | that's sad. |
| 19:57:28 | <Botje> | bakesz: you could put a trace inside that anonymous lambda, though |
| 19:57:47 | <Botje> | import Debug.Trace |
| 19:57:48 | <tux_rocker> | kynes: import Debug.Trace\nprop x y = trace ("x = " ++ show x ++ ", y = " ++ show y) $ x == y || x /= y\nmain = quickCheck prop |
| 19:58:00 | <tux_rocker> | kynes: replace \n by newline |
| 19:58:24 | <Botje> | let sum_nums w = if w == 0 then 0 else (\f x -> trace (show x) $ f (x-1) + x) sum_nums w |
| 19:58:35 | <kynes> | tux_rocker, thanks! |
| 19:58:38 | <Botje> | of course that fragment is pretty contrived |
| 19:58:58 | <Botje> | why bother with the lambda if you're going to apply it sitrectly after ... |
| 19:59:15 | <Botje> | let sum_nums w = if w == 0 then 0 else sum_nums (x-1) + x |
| 19:59:23 | <Botje> | err |
| 19:59:28 | <Botje> | let sum_nums w = if w == 0 then 0 else sum_nums (w-1) + w |
| 19:59:52 | <Botje> | and then you might use pattern matching |
| 20:00:39 | <Twey> | let sum_nums 0 = 0; sum_nums w = sum_nums (w - 1) + w |
| 20:01:35 | <bakesz> | sorry,what does "contrived" mean,because my dictionary doesn't find it |
| 20:01:47 | <Botje> | really really awkward and un-haskelly |
| 20:01:58 | <Botje> | not code any sensible person would write |
| 20:02:42 | <bakesz> | thank you |
| 20:02:47 | <Wraithan> | @type Text.JSON.decode |
| 20:02:47 | <Tsion> | arg |
| 20:02:48 | <lambdabot> | Couldn't find qualified module. |
| 20:02:56 | <dolio> | In general it means made-up and unrealistic. |
| 20:03:01 | <Tsion> | 14:02:29 <@Tsion> @run 1 + 1 |
| 20:03:01 | <Tsion> | 14:02:31 <lambdabot`> L.hs:3:29: Module `Control.Arrow' does not export `pure'L.hs:3:29: Module `... |
| 20:03:07 | <Tsion> | my lambdabot won't work :/ |
| 20:03:10 | <tux_rocker> | correction of myself: read/show for StdGen are not asymmetric |
| 20:03:19 | <Wraithan> | Bleh, anyway, it returns a Result a, how I do I get the value from the result/ |
| 20:03:22 | <tux_rocker> | my program needed a type signature somewhere to work correctly |
| 20:03:49 | <luqui> | i'd like some help on the design of a library |
| 20:04:25 | <luqui> | i'm writing a proof tactics library, where a tactic takes a theorem and attempts to find a proof |
| 20:04:27 | <trofi> | Tsion: try remove hiding (pure) from L.hs |
| 20:04:33 | <Tsion> | trofi: It's not there |
| 20:04:37 | <luqui> | er, takes a statement and ... |
| 20:04:43 | <trofi> | Tsion: ~/.lambdabot/L.hs |
| 20:05:05 | <luqui> | but i would like the code that decides how to find the proof to be overloaded in some respect |
| 20:05:07 | <Tsion> | trofi: Whoa, thanks |
| 20:05:20 | <Tsion> | I was changing it in the source and recompiling |
| 20:05:21 | <luqui> | i.e. allowed to do I/O, or talk to an external context, etc. (not committing to any particular one) |
| 20:05:44 | <luqui> | but i don't want it to be able to return an invalid proof, so the "primitive constructors" are restricted |
| 20:05:45 | <luqui> | any ideas? |
| 20:05:50 | <luqui> | does that make sense? |
| 20:06:00 | <_JFT_> | int-e: can I bug you for one more question? I am trying to eval my ReaderT ST monad stack... |
| 20:06:07 | <Wraithan> | decode :: JSON a => String -> Result a -- How do I get the value of a? I am doing really bad at this haskell stuff so far lol |
| 20:06:20 | <PeakerWork> | luqui: hey.. Is this for an interactive theorem prover? |
| 20:06:33 | <PeakerWork> | luqui: or do you want to let your language's programs partially prove stuff? |
| 20:06:41 | <PeakerWork> | luqui: (and allow automated proof for the rest) |
| 20:06:45 | <maltem> | findProof :: (Monad m) => Tactic m a -> m (Proof a) -- ? |
| 20:06:46 | <int-e> | _JFT_: yes |
| 20:06:47 | <luqui> | PeakerWork, possibly-interactive. i.e. interactivity is one of the ways to instantiate it |
| 20:07:09 | <PeakerWork> | I don't think findProof can/should be in a polymorphic monad |
| 20:07:31 | <_JFT_> | int-e: thanks I could paste the code if you can get a look at it please |
| 20:07:33 | <maltem> | Fair enough |
| 20:07:57 | <luqui> | PeakerWork, well I'd like some way to communicate the proof context to the user from within the library |
| 20:08:05 | <luqui> | yeah, partiality is acceptable |
| 20:08:17 | <PeakerWork> | luqui: proof :: Theorem -> ErrorT ProofFailure IO Proof -- where Proof is represented in a form that is always valid? |
| 20:08:26 | <luqui> | I don't want IO in the type |
| 20:08:29 | <PeakerWork> | luqui: I guess it might be proving some *other* theorem, heh |
| 20:08:36 | <luqui> | right, that too |
| 20:08:46 | <_JFT_> | int-e: http://moonpatio.com/fastcgi/hpaste.fcgi/view?id=2533#a2533 |
| 20:08:53 | <PeakerWork> | luqui: so you do want the Monad to be polymorphic, as per maltem's suggestion? |
| 20:08:56 | <luqui> | so the primitive combinators only allow proofs of what you're actually trying to prove |
| 20:09:24 | <luqui> | PeakerWork, I think so... |
| 20:09:27 | <PeakerWork> | luqui: Sounds impossible in Haskell (that the type will guarantee that the result proof is of that theorem), but maybe I'm wrong |
| 20:09:30 | <luqui> | maltem, what is this a? |
| 20:09:41 | <luqui> | PeakerWork, should be possible using some variant of certificate |
| 20:09:46 | <luqui> | i just can't figure out that variant |
| 20:09:50 | <PeakerWork> | luqui: what's that? |
| 20:09:51 | <_JFT_> | int-e: I understand the problem is with my "s" state thread variable |
| 20:10:04 | <luqui> | restricting the constructors you expose only to allow valid proofs |
| 20:10:18 | <_JFT_> | int-e: but I have no idea how to fix it ( I guess I have to quantify it? forall s. etc?) |
| 20:10:19 | <maltem> | luqui, no idea, I thought you may want to put something resultish in there |
| 20:10:27 | <PeakerWork> | luqui: but they don't only have to be valid proofs, they also have to be proofs of some other argument |
| 20:10:33 | <luqui> | like, modusPonens :: Proof -> Proof -> Maybe Proof |
| 20:10:55 | <PeakerWork> | luqui: (of some theorem |
| 20:11:23 | <_JFT_> | int-e: I added missing part at the top http://moonpatio.com/fastcgi/hpaste.fcgi/view?id=2533#a2534 |
| 20:11:33 | <luqui> | PeakerWork, well, yeah, that's the challenge. Thus exposing the type as a plain function isn't an option |
| 20:11:49 | <luqui> | i.e. Term -> Proof is no good, because that's allowed to return proofs that are not proofs of that term |
| 20:11:57 | <luqui> | so instead it's got to be an abstract type Tactic |
| 20:12:04 | <luqui> | whose structure I cannot figure out... |
| 20:12:58 | <luqui> | like, basic tactic combinators are easy. the problem is shoving that monad/whatever in there |
| 20:13:06 | <PeakerWork> | luqui: the caller can always validate the proof :-) |
| 20:13:10 | <luqui> | so that it can make decisions based on the context |
| 20:13:19 | <luqui> | PeakerWork, don't want them to have too |
| 20:13:21 | <luqui> | *to |
| 20:14:06 | <luqui> | i have a hunch that if it's guaranteed *locally* correct, then it will be easy to verify |
| 20:14:07 | <int-e> | _JFT_: give a type signature: evalTopology :: (forall s . Topology s v f a) -> a |
| 20:14:08 | <luqui> | formally |
| 20:14:46 | <_JFT_> | int-e: thank you VERY much :) I haven't played much with ST and constantly get into problem with the "s" :( |
| 20:15:30 | <int-e> | _JFT_: (requires Rank2Types or RankNTypes) The error message basically means that 'runST' wants to fix the type of 's' itself, but can't, because it's already fixed by the (inferred) type signature of evalTopology. |
| 20:16:35 | <PeakerWork> | luqui: can you show for example, some basic tactic combinators? |
| 20:16:56 | <_JFT_> | int-e: I read your explanation "loud and clear" but the original message wasn't as clear ;) I'll read it back with you interpretation! Thanks again! |
| 20:18:25 | <luqui> | PeakerWork, intro (\h -> assumption h) -- proves eg. A -> A |
| 20:18:51 | <luqui> | but i'd like to be able to: intro (\h -> interactive) |
| 20:19:16 | <luqui> | er, mentioning h in interactive so that it can add it to the context |
| 20:20:31 | <_lilian_> | ouvindo ( Francesco Napoli - Balla Balla.mp3 ) .: kikøscript :. http://kikoscript.blogspot.com |
| 20:20:51 | <luqui> | my intended usage may be flawed, too... |
| 20:35:37 | <bnijk> | http://shootout.alioth.debian.org/u32q/benchmark.php?test=all&lang=ghc&lang2=gnat&box=1 <-- ???? |
| 20:35:46 | <bnijk> | what's with the memory use |
| 20:48:38 | <mux> | rah |
| 20:48:39 | <mux> | atsui! |
| 20:49:09 | <Twey> | Atsusugi :( |
| 20:49:55 | <shapr> | AKIRA! |
| 20:50:03 | <mxc> | nihon kara dete! |
| 20:50:15 | <mxc> | nihon no natsu ga taihen dane! |
| 20:50:31 | <Jedai> | bnijk: ? What's the problem ? Except the Mandelbrot bench, the factor compared to ADA are quite normal and even for the mandelbrot, the memory usage isn't that far fetched |
| 20:50:40 | <shapr> | Jag har ingen aning vad du säger! |
| 20:51:01 | <xian> | shapr: I have no idea what you say? |
| 20:51:02 | <shapr> | Minä haluan hampurilainen! |
| 20:51:23 | <shapr> | xian: Yup, you got the Swedish correct, now can you translate the Finnish? |
| 20:52:19 | <Chile`> | is there a common method of doing substring replaces in haskell? there doesn't seem to be a standard one, unless I'm just missing it in the docs |
| 20:52:21 | <xian> | shapr: Wow, Swedish is really similar to German :) As to the Finnish, I happen to know that minä means ``I'', so I guess it's also something along "I have no idea" |
| 20:52:54 | <RayNbow> | mxc: why use romaji? :p |
| 20:52:58 | <shapr> | xian: Actually I said "I want a hamburger." |
| 20:53:13 | <shapr> | xian: joda, svensk är mycket lika som tysk. |
| 20:53:31 | <shapr> | xian: Talar du tysk? |
| 20:53:36 | <RayNbow> | @users |
| 20:53:37 | <lambdabot> | Maximum users seen in #haskell: 658, currently: 601 (91.3%), active: 19 (3.2%) |
| 20:54:01 | <xian> | shapr: Yeah, that's my native language. |
| 20:54:26 | <shapr> | kul :-) |
| 20:54:42 | <shapr> | My native language is Southern. I'm from Alabama. |
| 20:54:57 | <mxc> | raynbow - does IRC support unicode? |
| 20:55:06 | <mxc> | テスト |
| 20:55:17 | <mxc> | 試験 |
| 20:55:24 | <mxc> | well, i see that, not sure if anyone else does |
| 20:55:30 | <shapr> | I see it. |
| 20:55:58 | <xian> | shapr: Ah, I see. It's interesting to know that there are Swedish speakers in AL. |
| 20:56:05 | <Jedai> | Chile`: not really |
| 20:56:10 | <shapr> | xian: I learned Swedish at the same time my German/French fiancee was learning it, she learned Swedish very quickly. |
| 20:56:28 | <shapr> | xian: Well, I'm in Boston these days, but I'm sure there must be at least one or two Swedish speakers in AL. |
| 20:56:43 | <shapr> | xian: Are you in Boston? Want to hang out? |
| 20:56:53 | <Jedai> | Chile`: it's not too hard to cook one for your specific need most of the time though |
| 20:57:08 | <RayNbow> | mxc: as long as two persons use the same appropiate encoding, they can use unicode over IRC |
| 20:57:25 | <shapr> | Sadly, IRC dös not specify an encoding. |
| 20:57:33 | <shapr> | So most channels choose one. |
| 20:57:36 | <Chile`> | Jedai: no, it's not difficult at all, but every time I rewrite something that fundamental i cringe a little bit :) |
| 20:57:40 | <Jedai> | mxc: I see it (assuming you see the same as me) |
| 20:57:45 | <shapr> | Er, most channels that aren't ASCII. |
| 20:57:52 | <mxc> | for some reason, i imagined that the irc servers would mangle it |
| 20:58:07 | <xian> | shapr: I'd love to, but for now it seems as if I'm stuck in Germany. |
| 20:58:13 | <shapr> | Well, you should come visit! |
| 20:58:13 | <mxc> | although, i guess if its UTF-8, there aren't any \0's in leading bytes |
| 20:58:34 | <Jedai> | Chile`: I agree that it's annoying, maybe someone should just put a module with some traditional variants on hackage |
| 20:58:57 | <shapr> | Jedai: Good idea! Go for it! |
| 20:59:11 | <Jedai> | shapr: I just may :) |
| 20:59:13 | <wli> | ACTION would love to be stuck in Germany |
| 20:59:36 | <RayNbow> | ACTION wouldn't :p |
| 21:00:17 | <RayNbow> | (but that's because I haven't practiced German in a long while) |
| 21:02:24 | <monochrom> | IRC is neutral to "does it support unicode or not". Two humans conversing with each other decide what the bytes mean. |
| 21:03:33 | <monochrom> | My stand is I insist on UTF-8 and you can bite me. |
| 21:06:09 | <RayNbow> | ACTION recently had a small UTF8 problem :p |
| 21:08:40 | <RayNbow> | (when I replaced xmonad with xmonad-darcs... xmobar was no longer displaying text correctly... replacing System.IO.UTF8.hPutStrLn with hPutStrLn in my config fixed it :p) |
| 21:23:42 | <Chile`> | kind of a best practices question.. is monadic parsing actually used in practice, or would basically everyone use Happy or such? |
| 21:23:58 | <augustss> | I wouldn't |
| 21:24:04 | <augustss> | use happy |
| 21:24:04 | <Heffalump> | I think most people use parser combinators |
| 21:27:07 | <mmorrow> | Chile`: mostly happy's used for language parsers and parser combinators for smaller stuff |
| 21:27:08 | <luqui> | though people seem to be moving toward applicative style |
| 21:27:23 | <skorpan> | is it okay to call constructors functions if the context makes it clear that they are indeed constructors? |
| 21:27:57 | <luqui> | skorpan, do you mean "is it okay to call functions constructors if ..." ? |
| 21:28:09 | <skorpan> | no, i meant what i said :) |
| 21:28:13 | <luqui> | constructors *are* functions |
| 21:28:16 | <PeakerWork> | luqui: can an Applicative parser be optimized in ways that a monadic parser can't? |
| 21:28:23 | <luqui> | PeakerWork, yeah |
| 21:28:24 | <skorpan> | yes, i know |
| 21:28:35 | <skorpan> | i'm just not sure whether it's a generally accepted fact |
| 21:28:42 | <PeakerWork> | luqui: I thought the fact applicatives were parameterized over functions destroyed that |
| 21:29:26 | <Chile`> | mmorrow: makes sense, I'll stick to that |
| 21:29:43 | <luqui> | PeakerWork, i'm no expert, but I think there are some optimizations possible |
| 21:29:48 | <luqui> | not *all* the context-free ones, though |
| 21:31:03 | <mmorrow> | Chile`: (and you usually use a monad along with happy, although you don't necessarily have to) |
| 21:31:07 | <peanuts> | i have a beginner question about my implementation of quicksort for list of lists, maybe someone could give me a pointer |
| 21:31:21 | <peanuts> | i'm getting a non-exhaustive pattern error |
| 21:31:29 | <luqui> | peanuts, paste |
| 21:31:34 | <luqui> | if you please |
| 21:31:56 | <Chile`> | mmorrow: alright. I haven't looked at happy at all past knowing of it's existence. |
| 21:31:56 | <peanuts> | sortLists :: Ord a => [[a]] -> [[a]] |
| 21:31:56 | <peanuts> | 8 sortLists [[]] = [[]] -- pattern matching instead of "null" |
| 21:31:56 | <peanuts> | 9 sortLists (x:xs) = sortLists shorterOnes ++(x:sortLists longerOnes) |
| 21:31:56 | <peanuts> | 10 where |
| 21:31:56 | <peanuts> | 11 shorterOnes = [y | y <- xs, length y < length x ] |
| 21:31:56 | <peanuts> | 12 longerOnes = [y | y <- xs, length y >= length x] |
| 21:32:07 | <BONUS> | [[]] is not an empty list :) |
| 21:32:24 | <BONUS> | it's a lsit that has one element (an empty list) |
| 21:32:25 | <duaneb> | ok |
| 21:32:30 | <duaneb> | how can I compare functions? |
| 21:32:35 | <Twey> | duaneb: You can't |
| 21:32:36 | <duaneb> | e.g. (not == not) |
| 21:32:38 | <duaneb> | :( |
| 21:32:39 | <Twey> | It doesn't make sense |
| 21:32:43 | <PeakerWork> | peanuts: why is a sort of lists different from a sort of values? |
| 21:32:44 | <duaneb> | yes it does |
| 21:32:50 | <duaneb> | you can compare variables |
| 21:32:51 | <luqui> | duaneb, (not in general. there are classes of function types that you can compare) |
| 21:32:56 | <duaneb> | "variables" |
| 21:32:59 | <PeakerWork> | Maybe if functions were total, you could compare them? |
| 21:33:02 | <duaneb> | and functions can be data |
| 21:33:20 | <Twey> | duaneb: If you have two functions that do the same thing in different ways, are they equal? |
| 21:33:26 | <peanuts> | oh I didn't realize that I could drop the inner empty list |
| 21:33:29 | <BONUS> | > sortBy (compare `on` length) [[1,2,3],[1],[1,2,3,4,5]] |
| 21:33:30 | <PeakerWork> | duaneb: but should (1+) == (+1) return True or False? |
| 21:33:31 | <lambdabot> | [[1],[1,2,3],[1,2,3,4,5]] |
| 21:33:33 | <peanuts> | I thought it would be a type error |
| 21:33:36 | <luqui> | PeakerWork, not always. you can compare functions with compact, overt domain |
| 21:33:38 | <Twey> | They may have different complexities |
| 21:33:50 | <Chile`> | luqui: applicative parsing referring to http://book.realworldhaskell.org/read/using-parsec.html#id652517 this sort of thing? |
| 21:33:50 | <duaneb> | peaker: well, are they the same function? |
| 21:33:51 | <duaneb> | probably not. |
| 21:34:03 | <duaneb> | it depends on how ghc compiles them |
| 21:34:04 | <PeakerWork> | duaneb: they have the same domain, range, and mapping between them |
| 21:34:05 | <luqui> | duaneb, we say two functions are the same if they do the same thing to every argument |
| 21:34:11 | <PeakerWork> | duaneb: but they might have different operational semantics |
| 21:34:15 | <duaneb> | well, yea |
| 21:34:20 | <duaneb> | just compare the pointers! |
| 21:34:26 | <PeakerWork> | duaneb: should (==) between functions compare just denotational semantics or also operational semantics? |
| 21:34:30 | <luqui> | duaneb, that violates a fundamental premise of haskell |
| 21:34:38 | <duaneb> | no, it really doesn't. |
| 21:34:39 | <peanuts> | thanks for the help! |
| 21:34:43 | <Chile`> | peanuts: what part of OR? |
| 21:34:54 | <luqui> | duaneb, maybe you should come back after you have researched a little |
| 21:35:02 | <PeakerWork> | duaneb: what's the point of comparing functions by pointer to the implementation? |
| 21:35:03 | <duaneb> | luqui: maybe you could help |
| 21:35:09 | <duaneb> | I need to compare two functions |
| 21:35:10 | <peanuts> | Corvallis |
| 21:35:13 | <PeakerWork> | duaneb: what for? |
| 21:35:17 | <Chile`> | peanuts: what part of Corvallis? :) |
| 21:35:19 | <duaneb> | I have a lambda data type |
| 21:35:22 | <duaneb> | for an interpreted language |
| 21:35:26 | <luqui> | duaneb, sure, but don't reply with "no it really doesn't" without knowing what you're saying |
| 21:35:26 | <duaneb> | that has a function in haskell |
| 21:35:28 | <copumpkin> | duaneb: if the input is enumerable and the output has equality, then you can ;) |
| 21:35:33 | <copumpkin> | enumerable in the non |
| 21:35:36 | <BONUS> | also is (head == foldr const undefined) |
| 21:35:36 | <copumpkin> | -Enum sense |
| 21:35:51 | <duaneb> | luqui: I understand what you're saying |
| 21:35:55 | <mmorrow> | , id .==. id |
| 21:35:56 | <peanuts> | Chile |
| 21:35:58 | <lunabot> | True |
| 21:35:58 | <Twey> | Under purity laws, optimisation means that the same name may not refer to the same function |
| 21:35:59 | <mmorrow> | ACTION ducks |
| 21:36:04 | <PeakerWork> | duaneb: (+1) and (1+) do the exact same thing to every input, but they might have different "function pointers", should they not compare equal? Note that the result of (4+4) and 8 may be different "pointers" in the implementation but (==) will still return True |
| 21:36:13 | <copumpkin> | mmorrow: lol, what is that comparing? stablenames? |
| 21:36:15 | <duaneb> | but at the same time, there's nothing stopping haskell from testing for equality between two arbitrary functions |
| 21:36:19 | <Twey> | And two entirely different names may refer to the same function |
| 21:36:23 | <Twey> | You never know |
| 21:36:29 | <peanuts> | Chile`: north west, 10 min from OSU ;) |
| 21:36:31 | <duaneb> | PeakerWork: yes, they should not be the same function! |
| 21:36:33 | <luqui> | duaneb, well, if you're okay with the comparison returning inside IO |
| 21:36:45 | <luqui> | there is a comparison a -> a -> IO Bool, but it is not to be trusted |
| 21:36:49 | <mmorrow> | copumpkin: a .==. b == a `seq` b `seq` I# (reallyUnsafePtrEquality# a b) |
| 21:36:49 | <PeakerWork> | duaneb: under same logic, 4 + 4 /= 8 |
| 21:36:53 | <copumpkin> | lol |
| 21:36:54 | <mmorrow> | copumpkin: ;) |
| 21:37:01 | <duaneb> | also, let f = 5; g = 5; f `funccomp` g should equal False |
| 21:37:03 | <luqui> | depending on details of the garbage collector, concurrency, etc., it might give different answers for the same arguments |
| 21:37:03 | <Twey> | Haskell does not do identity checking — purity means that everything must be checked by value only |
| 21:37:12 | <duaneb> | PeakerWork: No, you're not reading what I'm saying |
| 21:37:16 | <duaneb> | I don't care what the functions do |
| 21:37:21 | <duaneb> | I'm trying to test identit |
| 21:37:23 | <duaneb> | y |
| 21:37:26 | <mmorrow> | copumpkin: err, maybe this one doesn't have the `seq`s, i can't remember |
| 21:37:28 | <PeakerWork> | duaneb: Haskell has no notion of "identity", really |
| 21:37:34 | <duaneb> | well |
| 21:37:37 | <Twey> | duaneb: If you want identity, make your own |
| 21:37:37 | <duaneb> | that's very inconvenient. |
| 21:37:39 | <mmorrow> | , id [] .==. [] |
| 21:37:42 | <lunabot> | False |
| 21:37:42 | <luqui> | duaneb, how about this. haskell doesn't like identity. what are you trying to do, in the larger scheme of things? |
| 21:37:45 | <mmorrow> | no seqs |
| 21:37:56 | <duaneb> | compare two functions |
| 21:37:59 | <Twey> | For example a Data.Unique ID attached to your language object |
| 21:37:59 | <luqui> | duaneb, why? |
| 21:38:01 | <duaneb> | that are stored in a datatype |
| 21:38:09 | <duaneb> | luqui: let's say I'm building a tree |
| 21:38:18 | <duaneb> | a sorted tree |
| 21:38:35 | <duaneb> | of functions |
| 21:38:45 | <duaneb> | how can I sort it if I can't test for equality at the very least? |
| 21:38:49 | <luqui> | duaneb, but you don't care what the sort is, just sorted at all? |
| 21:39:09 | <duaneb> | luqui: look, do you understand what I'm saying? |
| 21:39:25 | <luqui> | duaneb, kind of, but I'm questioning your motivations for putting functions in a sorted tree |
| 21:39:31 | <luqui> | when it's unclear when one function should be less than another... |
| 21:39:33 | <luqui> | what does that mean? |
| 21:39:33 | <duaneb> | luqui: I'm not actually |
| 21:39:44 | <mmorrow> | duaneb: even with ptr equality, you don't get an Ord on functions.. since haskell is garbage collected |
| 21:39:50 | <hatds> | sorted containers are useful because it speeds up lookup. What you want to achieve can be done by insert (Int, func) pairs instead of just functions into your tree |
| 21:40:00 | <mmorrow> | (the Ord would change every GC) |
| 21:40:31 | <luqui> | duaneb, it's hard for newcomers, but haskell actually prevents you, by design, from doing certain things. most languages don't. you buy some nice properties this way, but it does cause you to rethink how you might approach some problems... |
| 21:40:40 | <duaneb> | luqui: well, just compare pointers |
| 21:40:41 | <duaneb> | so |
| 21:40:42 | <luqui> | chances are, if you want to compare functions, you are not doing it "the haskell way" |
| 21:40:44 | <duaneb> | I just can't do this? |
| 21:40:44 | <duaneb> | Ok |
| 21:40:48 | <duaneb> | this is what I'm doing |
| 21:41:33 | <duaneb> | I have a lisp |
| 21:41:35 | <duaneb> | I have two lambdas |
| 21:41:38 | <duaneb> | built-in |
| 21:41:48 | <duaneb> | defined internally as haskell functions |
| 21:41:56 | <luqui> | you're writing a lisp interpreter? |
| 21:42:00 | <duaneb> | I need to implement the scheme function "equal?" |
| 21:42:18 | <duaneb> | part of that entails testing built-in functions for equality |
| 21:42:21 | <PeakerWork> | Does Scheme have eq? and equal? |
| 21:42:23 | <duaneb> | there is NO WAY to do this with haskell? |
| 21:42:26 | <duaneb> | PeakerWork: yes |
| 21:42:37 | <PeakerWork> | duaneb: the "built-in" functions are actually free to be *any type you choose* |
| 21:42:38 | <luqui> | duaneb, there is a way, but scheme is less pure than haskell |
| 21:42:39 | <kpreid> | duaneb: you have to *give* an identity to the builtin functions |
| 21:42:48 | <luqui> | so you'll have to simulate the impurities manually |
| 21:42:51 | <Twey> | duaneb: Like I said: data SchemeType a = SchemeType Id a |
| 21:42:51 | <PeakerWork> | duaneb: they don't have to be Haskell functions |
| 21:42:53 | <luqui> | as kpreid says |
| 21:42:55 | <duaneb> | I am not happy. |
| 21:43:09 | <kpreid> | duaneb: in your table of builtins attach unique ids along with the haskell functions |
| 21:43:18 | <duaneb> | I suppose.... |
| 21:43:24 | <PeakerWork> | duaneb: You're trying to map Scheme functions directly to Haskell functions, despite the semantics of them being very dissimilar |
| 21:43:35 | <gwern> | duaneb: if you're stuck, iirc, there's a Scheme in 21 days or something you could crib from |
| 21:43:37 | <Twey> | Haskell functions are pure. Scheme functions are not. |
| 21:43:39 | <copumpkin> | duaneb: as I said, you can do it if your input is enumerable and the output is an instance of Eq |
| 21:43:53 | <luqui> | copumpkin, that is completely irrelevant to his problem :-) |
| 21:44:07 | <copumpkin> | ACTION puts his tail between his legs and runs away |
| 21:44:11 | <copumpkin> | *stem |
| 21:44:11 | <Twey> | Yeah, that's not nearly the answer in this case. |
| 21:44:16 | <Twey> | Hehehe |
| 21:44:20 | <copumpkin> | I haven't really followed context :P |
| 21:44:22 | <Twey> | Copumpkins have legs? |
| 21:44:26 | <copumpkin> | just keep hearing "OMG function equality" |
| 21:44:27 | <Twey> | They really are different |
| 21:44:44 | <Phyx-> | hmmm http://www.cafepress.com/doitmonad.7154442 |
| 21:44:48 | <mmorrow> | duaneb: imagine if someone implemented vmware in the game of life, ptr equality there would still be ptr equality, but not equality on the ptrs use to implement the life which implements vmware which implements hardware which provides the memory cells which programs running on the hosted os see as ptrs |
| 21:45:12 | <Phyx-> | i wonder how many people would get that if i walk through an airport with it on |
| 21:45:15 | <luqui> | Phyx-, :-) |
| 21:45:29 | <Twey> | ACTION laughs. |
| 21:45:32 | <Twey> | Nice T-shirt, Phyx- |
| 21:45:49 | <duaneb> | mmorrow: well, I understand the problem |
| 21:45:54 | <duaneb> | I just don't understand why that's necessary |
| 21:45:58 | <gwern> | Phyx-: they wouldn't have time to read it |
| 21:46:08 | <Phyx-> | lol, i'm thinking of getting it |
| 21:46:15 | <Phyx-> | or http://www.cafepress.com/classyhaskell.7154232 |
| 21:46:22 | <luqui> | duaneb, when you see f :: Int -> Int in haskell, you already know certain things about f |
| 21:46:28 | <mmorrow> | duaneb: why what's necessary? (no comparison of the ptrs to haskell objects? (because of the gc)) |
| 21:46:36 | <Phyx-> | gwern: well, some are going to be in a 10hour flight with me :) |
| 21:46:39 | <luqui> | for example, it will not do any IO, and if you call it twice with the same argument you'll get the same result. |
| 21:46:46 | <mmorrow> | duaneb: you can use StableName though |
| 21:46:48 | <gwern> | luqui: yeah. like, it could be bottom, it could be using unsafePerformIO, it could... |
| 21:46:51 | <luqui> | if you could willy-nilly compare objects, then it might violate the latter constraint |
| 21:46:58 | <copumpkin> | duaneb: can't you just use a wrapper type for your functions you want to expose in your lisp? data LispFunction = LispFunction String (LispType -> LispType) or something |
| 21:47:02 | <gwern> | actually, we don't get a whole lot of guarantees in real haskell do we -_- |
| 21:47:08 | <luqui> | gwern, I reject your unsafePerformIO and substitute my own |
| 21:47:24 | <gwern> | ACTION sees luqui and raises with an unsafeCoerce# |
| 21:47:26 | <hatds> | lol |
| 21:47:35 | <duaneb> | copumpkin: I have that |
| 21:47:36 | <copumpkin> | ACTION applies StrictAnal |
| 21:47:39 | <copumpkin> | ah |
| 21:47:39 | <Twey> | duaneb: Because what you're saying doesn't make sense in a pure language |
| 21:47:50 | <Twey> | A function is a mapping from one set of values to another |
| 21:47:54 | <duaneb> | data LispType = Lambda (LispType -> LispType) |
| 21:47:58 | <gwern> | ACTION invokes the function 'lub' on copumpkin's StrictAnal |
| 21:48:03 | <copumpkin> | lol |
| 21:48:05 | <PeakerWork> | gwern: if its using unsafePerformIO to break referential transparency, then its buggy -- it cannot under any circumstance do it behind a legitimate interface |
| 21:48:13 | <hatds> | ACTION looks at code using pointer equality. Goes "well there's your problem". |
| 21:48:19 | <duaneb> | Twey: well, it may not make sense, but it's also not prohibited by a pure language |
| 21:48:21 | <Phyx-> | ACTION voilates gwern referential transparency |
| 21:48:23 | <Twey> | In mathematics, it would make sense to say that any functions that could provably yield the same results for all inputs are equal |
| 21:48:34 | <gwern> | ACTION is now impure! damn you Phyx- |
| 21:48:52 | <Twey> | In Haskell, though, that's not necessarily true, since we're running on real hardware and that means that there's computational complexity to consider |
| 21:48:53 | <copumpkin> | we could get a referential transparency violation chain going in here |
| 21:49:00 | <luqui> | Twey, (even unprovably, but that gets yucky) |
| 21:49:03 | <Phyx-> | hahah |
| 21:49:05 | <Twey> | Additionally, that can't be proven anyway |
| 21:49:10 | <Twey> | (by a machine) |
| 21:49:14 | <mreh> | Loading package unix-2.3.2.0 ... <command line>: can't load .so/.DLL for: rt (/usr/lib/librt.so: symbol __librt_multiple_threads, version GLIBC_PRIVATE not defined in file libc.so.6 with link time reference) |
| 21:49:15 | <Phyx-> | ACTION goes to bash.org |
| 21:49:20 | <kpreid> | duaneb: yes it is prohibited. trying to define function identity gives you all sorts of interesting problems with preserving referential transparency, particularly because functions can close over values |
| 21:49:21 | <mreh> | that's exciting |
| 21:49:22 | <hatds> | yea, operational equality and denotational equality would both be somewhat functions to have... if only they weren't so hard to compute! |
| 21:49:32 | <hatds> | *somewhat nice functions |
| 21:49:33 | <mmorrow> | usually in math a function if a function by definition, a priori |
| 21:49:39 | <PeakerWork> | duaneb: That LispType seems kind of useless |
| 21:49:42 | <mmorrow> | because you said it's a function |
| 21:49:43 | <mreh> | i've had so many errors trying to cabal install yi |
| 21:49:44 | <kpreid> | duaneb: it might be possible to define "good enough equality" but it wouldn't be predictable over multiple compiles due to optimization |
| 21:50:00 | <PeakerWork> | duaneb: how do you form an arg for the input of LispType? |
| 21:50:26 | <kpreid> | I assume that was just an example of one of the constructors |
| 21:50:58 | <luqui> | duaneb, anyway, probably looks like this: data LispType = Lambda Unique (LispType -> LispMonad LispType) |
| 21:51:11 | <duaneb> | PeakerWork: well, it's not the only constructor :P |
| 21:51:27 | <luqui> | (LispMonad because lisp functions have more side-effects than just comparing for equality, and you need to get your uniques from somewhere) |
| 21:51:59 | <mmorrow> | i think we're talking about two different things here... so ignoring referential transparency, purity, and letting "anything go", you still can't get Ord on the ptrs to haskell values (you can get Eq though) because of the GC |
| 21:52:13 | <luqui> | PeakerWork, of course, newtype L = L (L -> L) is the scott domain. hard to *do* anything with it :-) |
| 21:52:23 | <luqui> | but it is the foundation of our entire language |
| 21:53:12 | <PeakerWork> | duaneb: I think if you want mutations on values, you can't just attach an Id tag to values and copy the pair around. You have to have some global Map Id LispType |
| 21:53:17 | <hatds> | mmorrow: wait, what? wouldn't GC mess up Eq and Ord equally? |
| 21:53:21 | <PeakerWork> | duaneb: Then you can place all the lisp values in there |
| 21:53:45 | <mmorrow> | hatds: yeah, it destroys any chance for Ord, but you can haz Eq |
| 21:53:47 | <luqui> | PeakerWork, and do manual GC (!) |
| 21:53:50 | <hackagebot> | uuid 1.0.2 |
| 21:53:54 | <luqui> | PeakerWork, probably better to use STRefs |
| 21:53:59 | <hatds> | mmorrow: Eq how? |
| 21:54:05 | <PeakerWork> | luqui: can an STRef be compared for identity? |
| 21:54:11 | <luqui> | PeakerWork, yep |
| 21:54:12 | <mmorrow> | hatds: reallyUnsafePtrEquality# |
| 21:54:17 | <PeakerWork> | luqui: how? |
| 21:54:19 | <hatds> | mmorrow: oh |
| 21:54:23 | <luqui> | @info STRef |
| 21:54:23 | <lambdabot> | STRef |
| 21:54:27 | <luqui> | thanks, lambdabot |
| 21:54:31 | <PeakerWork> | STRef's have an Eq instance? |
| 21:54:42 | <mmorrow> | hatds: which is dependent on what state of evaluation a value happens to be in.. |
| 21:54:58 | <PeakerWork> | oh cool |
| 21:55:06 | <mmorrow> | hatds: (which is why the "unsafe", because it's not referentially transparent) |
| 21:55:45 | <luqui> | duaneb, okay, so using STRef (or IORef if ST scared you) seems like a good bet? |
| 21:56:15 | <mmorrow> | (and the "really" because you have to "really" figure out what's going on to be almost sure it's working like you want it to) |
| 21:57:05 | <PeakerWork> | duaneb: You can have: data LispType = LispValue (IORef Lisp) ; data Lisp = BuiltinFunction (LispType -> LispType) | Atom String | List [LispType] |
| 21:57:55 | <luqui> | PeakerWork, BuiltinFunction (LispType -> IO LispType) ? |
| 21:58:24 | <dmwit> | No, let all the built-in functions be pure! ;-) |
| 21:58:30 | <dmwit> | ?instances-importing Data.STRef Eq |
| 21:58:31 | <lambdabot> | (), (a, b), (a, b, c), (a, b, c, d), (a, b, c, d, e), All, Any, Bool, Char, Double, Dual a, Either a b, First a, Float, Int, Integer, Last a, Maybe a, Ordering, Product a, STRef s a, Sum a, [a] |
| 21:58:40 | <dmwit> | luqui: There you go. |
| 21:58:48 | <dmwit> | luqui: Also, for your future information: |
| 21:58:50 | <PeakerWork> | equal compares identity or eq? |
| 21:58:57 | <PeakerWork> | luqui: Yeah |
| 21:58:58 | <dmwit> | ?info do { x <- foo; return (bar y) } |
| 21:58:58 | <lambdabot> | foo >>= \ x -> return (bar y) |
| 21:59:14 | <luqui> | info = undo? |
| 21:59:23 | <dmwit> | ACTION nods |
| 21:59:27 | <luqui> | how... strange |
| 21:59:32 | <PeakerWork> | I think its accidental |
| 21:59:40 | <copumpkin> | the edit distance is short? |
| 21:59:43 | <dmwit> | right |
| 21:59:47 | <dmwit> | ?botsmuck |
| 21:59:47 | <lambdabot> | :) |
| 21:59:59 | <luqui> | oh lame |
| 22:00:06 | <copumpkin> | ?batstack |
| 22:00:06 | <lambdabot> | :) |
| 22:00:10 | <luqui> | lol |
| 22:00:14 | <PeakerWork> | which of eq/equal are equality and which are identity? |
| 22:00:16 | <PeakerWork> | (in Scheme) |
| 22:00:17 | <PeakerWork> | heh |
| 22:00:22 | <dmwit> | ACTION censors himself |
| 22:00:41 | <sjanssen> | been such a long time since I've used Scheme |
| 22:00:47 | <sjanssen> | I think eq is identity |
| 22:01:16 | <luqui> | there are so many different kinds of equality. *hugs haskell for clearing up the situation* |
| 22:01:32 | <augustss> | equal is equality |
| 22:01:45 | <augustss> | in scheme |
| 22:02:02 | <augustss> | eq is identity, eqv is in between |
| 22:02:08 | <dmwit> | Do any Haskell implementations use unsafe pointer equality as a fast-path for Eq instances? |
| 22:02:20 | <Phyx-> | i tried F# last week... i couldn't make head or tails of it... I was trying to figure out how to make a function signature.. epic fail... |
| 22:02:22 | <augustss> | dmwit: not that I know |
| 22:02:32 | <augustss> | dmwit: it's tricky |
| 22:02:35 | <Trollinator> | what is the $ operator for? after all, f $ x is the same as f `id` x |
| 22:02:59 | <dmwit> | augustss: What, really? |
| 22:03:36 | <Chile`> | Trollinator: just convenient syntax to avoid lots of nested parens |
| 22:03:43 | <luqui> | Trollinator, um... i dunno, readability? |
| 22:03:53 | <dmwit> | augustss: What if we restrict it to derived instances, where we know pointer equality will never steer us wrong? |
| 22:04:31 | <dmwit> | Trollinator: ($) has lower precedence than `id`. |
| 22:04:32 | <Trollinator> | right! i hear $ screaming "I'm the function application operator!" |
| 22:04:42 | <mreh> | I've got a dependancy issue while installing yi, for a package that isn't listed on the hackage dependancy list |
| 22:04:49 | <luqui> | infixr 0 `id` |
| 22:04:52 | <mreh> | unix-2.3.2.0 |
| 22:05:13 | <mreh> | I can't work out which version yi needs, there's some kind of bug in the one I haver |
| 22:05:15 | <mreh> | have* |
| 22:10:16 | <PeakerWork> | luqui: hmm.. trying this approach to Lisp, but how can you create global IORefs for true/false without unsafePerformIO on a newIORef? I guess the entire Lisp thing can be in a ReaderT of an environment with all the necessary builtins, but its not nice |
| 22:11:05 | <PeakerWork> | luqui: (have to return Lisp's true/false inside functions like equal, but they are also inside IORefs. Maybe immutable stuff should have Ids and mutable stuff should be in IORefs |
| 22:11:30 | <luqui> | PeakerWork, yeah i think so |
| 22:11:40 | <luqui> | true/false aren't mutable so they shouldn't be in IORefs |
| 22:11:49 | <copumpkin> | :o |
| 22:11:56 | <luqui> | true := 42 |
| 22:12:14 | <luqui> | > let 1 = 2 in 2+2 |
| 22:12:15 | <lambdabot> | 4 |
| 22:14:17 | <copumpkin> | > let !1 = 2 in 2 + 2 |
| 22:14:18 | <lambdabot> | * Exception: <interactive>:1:153-158: Non-exhaustive patterns in pattern bi... |
| 22:14:25 | <copumpkin> | zomg what will I do |
| 22:20:25 | <telemachus> | do I need to load a special library to have access to ord and chr? |
| 22:20:44 | <sjanssen> | telemachus: import Data.Char |
| 22:20:52 | <telemachus> | that would be it |
| 22:20:53 | <telemachus> | sighs |
| 22:20:57 | <telemachus> | thanks, sjanssen |
| 22:21:23 | <telemachus> | the book I'm using neglected to mention that |
| 22:21:47 | <telemachus> | (and most searches on Google for ord gave tons of hits for Ord) |
| 22:22:32 | <aavogt> | @hoogle chr -- likely better than google for functions |
| 22:22:32 | <lambdabot> | Parse error: |
| 22:22:32 | <lambdabot> | --count=20 "chr -- likely better than google for functions" |
| 22:22:32 | <lambdabot> | ^ |
| 22:22:37 | <aavogt> | @hoogle chr |
| 22:22:38 | <lambdabot> | Data.Char chr :: Int -> Char |
| 22:22:38 | <lambdabot> | Text.PrettyPrint.HughesPJ Chr :: Char -> TextDetails |
| 22:22:38 | <lambdabot> | System.Posix.Internals c_s_ischr :: CMode -> CInt |
| 22:23:47 | <telemachus> | hoogle bookmarked, thanks aavogt |
| 22:24:18 | <sjanssen> | oh jeez, don't tell me we have a shell injection vulneratiblity here |
| 22:24:37 | <sjanssen> | @hoogle chr" ; echo busted |
| 22:24:37 | <lambdabot> | Parse error: |
| 22:24:37 | <lambdabot> | --count=20 "chr" ; echo busted" |
| 22:24:37 | <lambdabot> | ^ |
| 22:25:20 | <centrinia> | @hoogle chr\" ; echo busted |
| 22:25:21 | <lambdabot> | Parse error: |
| 22:25:21 | <lambdabot> | --count=20 "chr\" ; echo busted" |
| 22:25:21 | <lambdabot> | ^ |
| 22:26:06 | <sjanssen> | nope, safe |
| 22:26:09 | <centrinia> | @hoogle ; ls -l |
| 22:26:10 | <lambdabot> | Parse error: |
| 22:26:10 | <lambdabot> | --count=20 "; ls -l" |
| 22:26:10 | <lambdabot> | ^ |
| 22:26:17 | <sjanssen> | the parse error comes from the Hoogle program |
| 22:26:49 | <sjanssen> | we don't go via sh when calling hoogle |
| 22:29:02 | <Phyx-> | @url hoogle |
| 22:29:02 | <lambdabot> | http://haskell.org/hoogle |
| 22:43:07 | <aavogt> | <ghc> My brain just exploded. I can't handle pattern bindings for existential or GADT data constructors. Instead, use a case-expression, or do-notation, to unpack the constructor. |
| 22:54:02 | <PeakerWork> | Why does ghc need to preface that message with "My brain just exploded."? :P |
| 22:54:10 | <PeakerWork> | its funny the first time, but then its annoying for the rest |
| 22:54:48 | <monochrom> | It has a second purpose in addition to being funny. |
| 22:54:50 | <Phyx-> | @src :P |
| 22:54:50 | <lambdabot> | Source not found. Just try something else. |
| 22:54:54 | <Phyx-> | @src (+) |
| 22:54:54 | <lambdabot> | Source not found. Listen, broccoli brains, I don't have time to listen to this trash. |
| 22:55:06 | <Phyx-> | PeakerWork: why does @src try to be funny |
| 22:55:20 | <PeakerWork> | @src is lambdabot, and the above is a ghc error |
| 22:55:20 | <lambdabot> | Source not found. That's something I cannot allow to happen. |
| 22:55:30 | <monochrom> | Let's say you're writing your program but you haven't implemented some planned feature yet, but you leave stub in your code for it. What do you write in the stub? |
| 22:55:44 | <centrinia> | @src -- Please insult me gently with a chainsaw. |
| 22:55:45 | <lambdabot> | Source not found. And you call yourself a Rocket Scientist! |
| 22:55:51 | <aavogt> | it is a trivial change to make my code comply with this arbitrary restriction |
| 22:56:02 | <monochrom> | You probably write like f x = error "I haven't implemented f yet". |
| 22:56:20 | <Phyx-> | PeakerWork: well, i appreciate ghc's attempt at humor though :) |
| 22:56:35 | <monochrom> | So they write "My brain has exploded". It means something is not implemented yet. |
| 22:57:10 | <centrinia> | @let f x = error "I haven't implemented f yet" |
| 22:57:12 | <lambdabot> | Defined. |
| 22:57:15 | <centrinia> | @src f |
| 22:57:16 | <lambdabot> | Source not found. Just try something else. |
| 22:57:24 | <centrinia> | @src L.f |
| 22:57:25 | <lambdabot> | Source not found. Take a stress pill and think things over. |
| 22:57:35 | <centrinia> | That doesn't make sense. |
| 22:57:41 | <monochrom> | src is a static database, and very incomplete. |
| 22:57:52 | <aavogt> | @src src |
| 22:57:53 | <lambdabot> | Source not found. |
| 22:58:06 | <monochrom> | Let's just say what src knows is pretty much hardcoded. |
| 22:58:39 | <monochrom> | It's also somewhat out of touch with reality, too. |
| 22:58:44 | <centrinia> | How do we make the @src database dynamic? |
| 22:58:51 | <wpearson> | @src reality |
| 22:58:52 | <lambdabot> | Source not found. I've seen penguins that can type better than that. |
| 22:59:04 | <centrinia> | @src clue |
| 22:59:05 | <lambdabot> | Source not found. |
| 22:59:07 | <monochrom> | @src length |
| 22:59:07 | <lambdabot> | Source not found. This mission is too important for me to allow you to jeopardize it. |
| 22:59:17 | <monochrom> | @src foldl |
| 22:59:18 | <lambdabot> | foldl f z [] = z |
| 22:59:18 | <lambdabot> | foldl f z (x:xs) = foldl f (f z x) xs |
| 22:59:22 | <aavogt> | @src lambdabot |
| 22:59:22 | <lambdabot> | Source not found. The more you drive -- the dumber you get. |
| 22:59:23 | <centrinia> | @src (>>=) |
| 22:59:24 | <lambdabot> | Source not found. Where did you learn to type? |
| 22:59:32 | <centrinia> | @src sqrt |
| 22:59:33 | <lambdabot> | Source not found. :( |
| 22:59:40 | <monochrom> | For example foldl. It is not what GHC uses. |
| 22:59:56 | <centrinia> | At least @src should have the entire Prelude. :( |
| 23:00:18 | <monochrom> | Did you know that "sqrt" and ">>=" are typeclass methods? |
| 23:00:30 | <centrinia> | Oh. |
| 23:00:39 | <centrinia> | @src sqrt :: Double -> Double |
| 23:00:40 | <lambdabot> | Source not found. Sorry. |
| 23:00:45 | <monochrom> | Did you know that therefore asking for the source code of "sqrt" is ambiguous? Like which instance would you really want? |
| 23:00:47 | <dmwit> | ?src Double sqrt |
| 23:00:47 | <lambdabot> | Source not found. This mission is too important for me to allow you to jeopardize it. |
| 23:00:51 | <dmwit> | ?src [] (>>=) |
| 23:00:52 | <lambdabot> | xs >>= f = concatMap f xs |
| 23:00:58 | <centrinia> | Ah. |
| 23:01:13 | <centrinia> | ?src IO (>>=) |
| 23:01:14 | <lambdabot> | m >>= k = bindIO m k |
| 23:01:20 | <dmwit> | sqrt = sqrtDouble# ;-) |
| 23:01:20 | <centrinia> | ?src bindIO |
| 23:01:21 | <lambdabot> | bindIO (IO m) k = IO ( \ s -> |
| 23:01:21 | <lambdabot> | case m s of (# new_s, a #) -> unIO (k a) new_s) |
| 23:01:35 | <centrinia> | ?src unIO |
| 23:01:36 | <lambdabot> | Source not found. Just what do you think you're doing Dave? |
| 23:01:53 | <aavogt> | @quote not funny |
| 23:01:53 | <lambdabot> | No quotes for this person. Sorry. |
| 23:02:05 | <aavogt> | @quote exploded |
| 23:02:06 | <lambdabot> | tessier says: After the last newbies head exploded trying to read everything on that monad link there was a lot of paperwork. We'd like to avoid doing that again. |
| 23:02:23 | <monochrom> | unIO is the inverse of IO. By IO I mean the data constructor you just saw in "bindIO (IO m) k". |
| 23:03:01 | <monochrom> | The source code probably had "data IO a = IO { unIO :: ... }". And of course src would not know that one. |
| 23:03:22 | <mauke> | @src IO |
| 23:03:23 | <lambdabot> | newtype IO a = IO (State# RealWorld -> (# State# RealWorld, a #)) |
| 23:03:35 | <monochrom> | Yeah I mean newtype. :) |
| 23:04:24 | <monochrom> | You are better off finding GHC library source code elsewhere than asking src. It knows nothing. |
| 23:09:01 | <Botje> | it's from barcelona! |
| 23:09:26 | <dmwit> | oh no! |
| 23:26:34 | <frogman> | Is there a way to test the type of something within a function--like if a function has a return type of either, can I see if the output of another function on the input is one type or another? |
| 23:27:00 | <mauke> | what |
| 23:27:04 | <mauke> | 'either' is not a type |
| 23:27:13 | <frogman> | Either Int String |
| 23:27:26 | <mauke> | case x of Left i -> ...; Right s -> ... |
| 23:27:42 | <frogman> | ok thanks! |
| 23:28:34 | <kpreid> | frogman: those are not different types, they're different values (constructors, you could say) |
| 23:32:54 | <christastrophe> | good evening everyone |
| 23:33:38 | <christastrophe> | i'm having some confusion with a little code snippet |
| 23:34:12 | <christastrophe> | this seems to cause an overflow: foldl' (\(l,s) v -> (l+1,s+v) (0,0) [1..1000000] |
| 23:34:29 | <christastrophe> | but computing each of the sub parts works just fine |
| 23:34:51 | <mauke> | makes sense |
| 23:34:58 | <christastrophe> | what could cause the overflow in the combined version? |
| 23:35:08 | <mauke> | the usual laziness |
| 23:35:08 | <Botje> | christastrophe: foldl' only forces the outer constructor |
| 23:35:14 | <mauke> | forcing a pair doesn't force its contents |
| 23:35:14 | <Botje> | which is (,) |
| 23:35:48 | <christastrophe> | ah I see, so I'm still building up a chain of thunks here |
| 23:35:49 | <Botje> | either use a strict pair or call seq yourself |
| 23:36:00 | <mauke> | (,) $! l+1 $! s+v |
| 23:36:37 | <christastrophe> | ok let me give that a try... |
| 23:40:20 | <christastrophe> | ha. that did work. seems I am not yet 'evaluating' haskell properly in my head |
| 23:54:20 | <hatds> | lazy pairs of numeric types always messed with my head :) |
| 23:55:47 | <christastrophe> | I was reading foldl simmilar to SmallTalks inject, but forgetting the laziness of Haskell |
Back to channel and daily index: content-negotiated html turtle