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:12:27 | <dibblego> | why do I have Test.QuickCheck at ghci but it is missing if I try to create an executable with ghc? |
| 00:15:32 | <FunctorSal> | are you using ghci-haskeline by chance? |
| 00:15:51 | <FunctorSal> | it confused me by being still linked to an older ghc once :) |
| 00:16:42 | <dibblego> | who? |
| 00:16:57 | <FunctorSal> | you :) |
| 00:17:24 | <dibblego> | I mean who is ghci-haskeline? |
| 00:17:49 | <FunctorSal> | it's a ghci that uses haskeline |
| 00:18:00 | <FunctorSal> | (I think ghc-6.10.3 does this by default now) |
| 00:18:16 | <dibblego> | I'm using ghc 6.10.2 |
| 00:20:43 | <dibblego> | how can I determine if I am using ghci-haskeline? |
| 00:20:50 | <deech> | Hi all, Is there anyway to embed an evaluation into Haddock documentation? |
| 00:21:54 | <dibblego> | actually it's the linking where QuickCheck is missing |
| 00:22:08 | <dibblego> | (.data+0x178): undefined reference to `QuickCheckzm1zi2zi0zi0_TestziQuickCheck_variant_closure' |
| 00:25:56 | <dibblego> | I suppose CABAL would resolve this, but was hoping to avoid that |
| 00:29:56 | <Peaker> | Cale: about removing Eq constraint from Num -- how do you pattern-match against numbers? What's the type of f 0 = 1 ; f n = n*f (n-1) ? Just (Eq a, Num a) => a -> a ? |
| 00:30:59 | <jmcarthur> | i see nothing wrong with that |
| 00:31:15 | <FunctorSal> | isn't that a pseudo-constructor match rather than an equality-guarded match? |
| 00:31:32 | <FunctorSal> | (can you even match on arbitrary Nums?) |
| 00:31:48 | <jmcarthur> | FunctorSal: a number literal is converted implicitly using fromIntegral |
| 00:33:24 | <jak> | > foldl1 (+1) [] |
| 00:33:25 | <lambdabot> | Occurs check: cannot construct the infinite type: a = a -> a |
| 00:33:28 | <jak> | @src foldl |
| 00:33:29 | <lambdabot> | foldl f z [] = z |
| 00:33:29 | <lambdabot> | foldl f z (x:xs) = foldl f (f z x) xs |
| 00:33:35 | <FunctorSal> | jmcarthur: but you'd have to invert formIntegral unless I'm missing something |
| 00:33:46 | <jak> | @src foldr |
| 00:33:46 | <lambdabot> | foldr f z [] = z |
| 00:33:46 | <lambdabot> | foldr f z (x:xs) = f x (foldr f z xs) |
| 00:33:48 | <Cale> | Peaker: Yeah, when you pattern match, you'll need Eq |
| 00:34:39 | <jmcarthur> | :t fromIntegral |
| 00:34:40 | <lambdabot> | forall a b. (Integral a, Num b) => a -> b |
| 00:34:54 | <jmcarthur> | Num also requires Eq, right now |
| 00:34:56 | <Peaker> | pattern-matches against numbers seem to be a special case in Haskell (as (==) . fromInteger is applied) |
| 00:35:15 | <jak> | > (+1) 3 |
| 00:35:16 | <lambdabot> | 4 |
| 00:35:18 | <FunctorSal> | "f @LITERAL = ..." <-> "f x | fromIntegral @LITERAL == x = ..." ? |
| 00:35:20 | <jak> | > 3 (+1) |
| 00:35:20 | <lambdabot> | Add a type signature |
| 00:35:25 | <jmcarthur> | :t fromInteger |
| 00:35:26 | <jak> | > 3 (+1) ::Int |
| 00:35:27 | <lambdabot> | forall a. (Num a) => Integer -> a |
| 00:35:28 | <lambdabot> | No instance for (GHC.Num.Num ((a -> a) -> GHC.Types.Int)) |
| 00:35:28 | <lambdabot> | arising from t... |
| 00:35:36 | <jak> | > (1+) 3 |
| 00:35:37 | <lambdabot> | 4 |
| 00:35:39 | <jmcarthur> | yeah, fromInteger, not fromIntegral, my bad |
| 00:35:45 | <jak> | > 3 (1+) |
| 00:35:46 | <lambdabot> | Add a type signature |
| 00:36:00 | <jak> | > (5-3*) 7 |
| 00:36:02 | <lambdabot> | The operator `GHC.Num.*' [infixl 7] of a section |
| 00:36:02 | <lambdabot> | must have lower prece... |
| 00:36:18 | <jak> | > ((5-3)*) 7 |
| 00:36:19 | <lambdabot> | 14 |
| 00:43:00 | <Cale> | dons: if you're around, you might find the discussion that gwern and I had comparing core between versions of the pidigits code somewhat interesting |
| 00:43:28 | <Cale> | dons: It seems that there are some big differences between how 6.10.2 compiles list comprehensions to 6.10.3 |
| 00:44:59 | <aavogt> | :t ((?f .) .) |
| 00:45:00 | <lambdabot> | forall b c a a1. (?f::b -> c) => (a1 -> a -> b) -> a1 -> a -> c |
| 00:46:24 | <Cale> | :t fmap (fmap f) |
| 00:46:26 | <lambdabot> | forall a b (f :: * -> *) (f1 :: * -> *). (Show a, SimpleReflect.FromExpr b, Functor f, Functor f1) => f1 (f a) -> f1 (f b) |
| 00:46:30 | <Cale> | er |
| 00:46:32 | <Cale> | :t fmap (fmap ?f) |
| 00:46:34 | <lambdabot> | forall a b (f :: * -> *) (f1 :: * -> *). (?f::a -> b, Functor f, Functor f1) => f1 (f a) -> f1 (f b) |
| 00:46:53 | <Cale> | That's how I like to think of it. |
| 00:47:11 | <Cale> | (f .) is the same as fmap f for the (e ->) functor. |
| 00:47:20 | <dibblego> | how can I get cabal to build an executable with the run target? |
| 00:47:23 | <dibblego> | oops build target |
| 00:50:14 | <aavogt> | @pl \x -> (+ map return x) |
| 00:50:15 | <lambdabot> | (+) . map return |
| 00:50:33 | <aavogt> | @pl \x -> (map return x +) |
| 00:50:33 | <lambdabot> | (+) . map return |
| 00:50:51 | <aavogt> | @pl \x y -> (map return x + y) |
| 00:50:52 | <lambdabot> | (+) . map return |
| 00:50:59 | <aavogt> | @pl \x y -> (y+map return x) |
| 00:51:00 | <lambdabot> | (+) . map return |
| 00:51:22 | <aavogt> | shouldn't there be a flip in there somewhere? |
| 00:52:00 | <aavogt> | :t (+) . map return |
| 00:52:01 | <lambdabot> | forall a (m :: * -> *). (Num [m a], Monad m) => [a] -> [m a] -> [m a] |
| 00:52:08 | <aavogt> | :t flip (+) . map return |
| 00:52:10 | <lambdabot> | forall a (m :: * -> *). (Num [m a], Monad m) => [a] -> [m a] -> [m a] |
| 00:52:19 | <dibblego> | @pl \x y -> ((+) y (map return x)) |
| 00:52:20 | <lambdabot> | (+) . map return |
| 00:52:41 | <dibblego> | @pl \x y -> (+) y (map return x) |
| 00:52:42 | <lambdabot> | (+) . map return |
| 00:52:55 | <aavogt> | going by the types, the flip does nothing |
| 00:53:06 | <Gracenotes> | (+) is commutative |
| 00:53:31 | <Gracenotes> | for Int and Integer, at least. Float+Double might have some corner cases |
| 00:53:50 | <aavogt> | :t flip (.) (+) (map return) |
| 00:53:52 | <lambdabot> | Couldn't match expected type `a -> a' against inferred type `[a1]' |
| 00:53:52 | <lambdabot> | In the third argument of `flip', namely `(map return)' |
| 00:53:52 | <lambdabot> | In the expression: flip (.) (+) (map return) |
| 00:53:55 | <Gracenotes> | maybe pl knows this? |
| 00:54:17 | <aavogt> | @pl flip . flip . flip |
| 00:54:18 | <lambdabot> | flip |
| 00:54:43 | <aavogt> | @pl flip (+) |
| 00:54:43 | <lambdabot> | (+) |
| 00:55:06 | <aavogt> | @pl flip (\x y -> (y,x))) |
| 00:55:07 | <lambdabot> | (line 1, column 21): |
| 00:55:07 | <lambdabot> | unexpected ")" |
| 00:55:07 | <lambdabot> | expecting variable, "(", operator or end of input |
| 00:55:11 | <aavogt> | @pl flip (\x y -> (y,x)) |
| 00:55:12 | <lambdabot> | (,) |
| 00:56:10 | <aavogt> | @pl flip ((+) . map return) |
| 00:56:11 | <lambdabot> | (. map return) . (+) |
| 00:56:15 | <Gracenotes> | yes, it seems pl is allowed to flip those |
| 00:56:20 | <Gracenotes> | commutativeOps = ["*", "+", "==", "/=", "max", "min"] |
| 00:56:26 | <Gracenotes> | from the source code. it considers these commutative |
| 00:57:09 | <Gracenotes> | x+y == y+x |
| 00:57:17 | <aavogt> | yeah |
| 00:57:40 | <vininim_> | openFile: resource exhausted (Too many open files) |
| 00:57:40 | <roconnor> | @type infinity |
| 00:57:41 | <lambdabot> | Natural |
| 00:57:42 | <ziman> | @pl flip (+) |
| 00:57:42 | <lambdabot> | (+) |
| 00:57:43 | <vininim_> | baaawwww |
| 00:57:48 | <roconnor> | > 1 + infinity > 1 |
| 00:57:49 | <lambdabot> | True |
| 00:57:55 | <roconnor> | > infinity + 1> 1 |
| 00:57:56 | <lambdabot> | True |
| 00:58:35 | <Gracenotes> | Natural uses lazy comparisons and such |
| 00:58:36 | <jbauman> | > 1 + infinity > infinity |
| 00:58:41 | <lambdabot> | mueval-core: Prelude.read: no parse |
| 00:58:41 | <lambdabot> | mueval: ExitFailure 1 |
| 00:59:00 | <aavogt> | @src infinity |
| 00:59:00 | <lambdabot> | Source not found. You speak an infinite deal of nothing |
| 00:59:01 | <vininim_> | why mapM readFile listOfFiles doesn't garbage collect file handles? |
| 00:59:09 | <Gracenotes> | hm |
| 00:59:09 | <aavogt> | mapM_ |
| 00:59:16 | <Gracenotes> | > genericLength [1..] > (5 :: Natural) |
| 00:59:18 | <lambdabot> | True |
| 00:59:51 | <aavogt> | might be better, but I'd expect the handles to be thrown away in either case |
| 01:00:12 | <aavogt> | plus, mapM_ readfile is quite pointless :) |
| 01:00:44 | <Gracenotes> | vininim_: it should GC the file handles once they're out of scope |
| 01:00:53 | <Gracenotes> | like most other languages |
| 01:00:58 | <Gracenotes> | that GC |
| 01:01:15 | <Gracenotes> | aavogt: oooooh. I see the issue. readFile is lazy. |
| 01:02:08 | <Gracenotes> | http://haskell.org/ghc/docs/latest/html/libraries/base/System-IO.html#v:readFile |
| 01:02:57 | <aavogt> | @type foldl' (\a x -> ?f x =<< a) |
| 01:02:58 | <lambdabot> | forall b (m :: * -> *) b1. (?f::b -> b1 -> m b1, Monad m) => m b1 -> [b] -> m b1 |
| 01:03:23 | <Asdfgh11> | hello , how can i define a data type which can accept Char |
| 01:03:34 | <aavogt> | @type foldl' (>>=) |
| 01:03:36 | <lambdabot> | forall (m :: * -> *) b. (Monad m) => m b -> [b -> m b] -> m b |
| 01:04:06 | <Gracenotes> | too bad there isn't a non-lazy hGetContents |
| 01:04:10 | <Asdfgh11> | i have done that |
| 01:04:56 | <Asdfgh11> | example data K = And Int Int | Char . i need the Char to be without a name |
| 01:05:16 | <aavogt> | Gracenotes: so use a stricter sequence function? |
| 01:05:21 | <Berengal> | Gracenotes: hGetContents >>= return . seq <$> last <*> id |
| 01:05:42 | <Gracenotes> | Berengal: that don't look like a function to me |
| 01:05:51 | <Gracenotes> | >_> |
| 01:06:06 | <Berengal> | Gracenotes: foo handle = hGetContents handle >>= return . seq <$> last <*> id |
| 01:06:13 | <Asdfgh11> | what is that |
| 01:06:29 | <Gracenotes> | Asdfgh11: data types must have a constructor |
| 01:06:43 | <Asdfgh11> | yh b but i have to do it |
| 01:06:50 | <aavogt> | @type fmap (liftA2 seq last id) . hGetContents |
| 01:06:51 | <lambdabot> | Not in scope: `hGetContents' |
| 01:07:00 | <aavogt> | @type fmap (liftA2 seq last id) . const getContents |
| 01:07:01 | <Gracenotes> | but you can have multiple constructors. So: data Foo = Bar Int Int | Baz Char |
| 01:07:01 | <lambdabot> | forall a. a -> IO [Char] |
| 01:07:02 | <Asdfgh11> | exmaple and(and 'a' 'b') |
| 01:07:19 | <Asdfgh11> | and i will put the input as ture wro false |
| 01:07:34 | <roconnor> | @bab nl en geweigerd |
| 01:07:34 | <lambdabot> | Plugin `babel' failed with: Prelude.head: empty list |
| 01:07:41 | <Gracenotes> | eek. |
| 01:08:38 | <Asdfgh11> | i can not use the a constructer for the character |
| 01:08:46 | <Berengal> | Asdfgh11: All values need a constructor, no exceptions |
| 01:09:08 | <Asdfgh11> | what should i do ? |
| 01:09:56 | <Berengal> | Give the constructor a name |
| 01:10:15 | <Asdfgh11> | (And( And 'a' 'b')) |
| 01:10:47 | <Berengal> | Your And constructor takes two ints only... |
| 01:11:14 | <Asdfgh11> | YH |
| 01:11:46 | <Asdfgh11> | its going to be replace by a number given by the user |
| 01:11:47 | <Berengal> | Because that's what you defined it to do |
| 01:12:22 | <Asdfgh11> | i should replace the chars with ints |
| 01:12:37 | <Asdfgh11> | thnak u for heloing |
| 01:12:50 | <Berengal> | What exactly are you trying to do? |
| 01:14:25 | <Asdfgh11> | Add( 'a' 'b') while a=2 and b=3 |
| 01:15:11 | <Berengal> | I assume you meant 'where' there... |
| 01:15:36 | <Asdfgh11> | what does where do |
| 01:15:49 | <Berengal> | > x + y where x = 2; y = 3 |
| 01:15:50 | <lambdabot> | <no location info>: parse error on input `where' |
| 01:16:13 | <Berengal> | lambdabot no do where? :( |
| 01:16:27 | <FunctorSal> | oh dear. I just jumped to the beginning of the "Do we really need FPLs? We can do everything with the imperative languages. " comp.lang.functional thread we had earlier |
| 01:16:41 | <Berengal> | Anyway, where is like let, except it comes after the expressions |
| 01:17:21 | <Cale> | I find it interesting that the naive-looking Haskell pidigits on the shootout is beating the brutally unreadable C version. |
| 01:17:22 | <Berengal> | 'while' generally doesn't make much sense in haskell |
| 01:17:23 | <jeffwheeler> | I went to the UIL state meet (the primary academic competition in Texas), and there was a kid named Tsz Ling Kong from I guess the city of Haskell, Texas (or maybe Haskell high school?) in the Mathematics competition. |
| 01:17:44 | <Asdfgh11> | evaluate (Add(Add('a' 'b') ('c' 'd')) 1 2 3 4 |
| 01:18:14 | <Asdfgh11> | 1 2 3 4 should replace the chars |
| 01:18:43 | <Cale> | FunctorSal: That sounds like a waste of time thread. |
| 01:18:44 | <Berengal> | Asdfgh11: That needs to look like 'evaluate (Add (Add 'a' 'b') (Add 'b' 'c'))) [1,2,3,4]' |
| 01:19:15 | <Berengal> | Or 'evaluate (Add (Add 'a' 'b') (Add 'b' 'c'))) [('a',1),('b',2),('c',3),('d',4)]' |
| 01:19:16 | <FunctorSal> | yes. must... resist... |
| 01:19:50 | <Asdfgh11> | yes |
| 01:19:54 | <Asdfgh11> | sry my mistake |
| 01:20:12 | <Asdfgh11> | what shoudl i do |
| 01:20:19 | <Berengal> | Asdfgh11: I assume the datatype you're looking for is something like 'data Expression = Add Expr Expr | Sub Expr Expr | Var Char | Val Int |...' |
| 01:20:36 | <Berengal> | s/Expr/Expression |
| 01:21:11 | <Berengal> | Then you could have have a function 'evaluate :: Expression -> [(Char, Int)] -> Int' |
| 01:21:49 | <Asdfgh11> | var Char how will it work |
| 01:22:19 | <Berengal> | And pattern match on the expression constructors, like 'evaluate (Add a b) env = evaluate a env + evaluate b env; evaluate (Var c) env = let Just val = lookup c env in val; ...' |
| 01:22:44 | <crutex> | grill $ burgers :: Delicious |
| 01:22:47 | <Berengal> | env is the "environment", or the bindings |
| 01:23:44 | <crutex> | grill $ burgers :: Delicious Food |
| 01:23:56 | <Asdfgh11> | if i created a var c i have to write in the expression var c |
| 01:24:09 | <Berengal> | Asdfgh11: Yes |
| 01:24:36 | <Asdfgh11> | but i cant , that problem |
| 01:24:47 | <crutex> | guys is that proper syntax? |
| 01:24:51 | <Berengal> | So you'd have 'Add (Var 'a') (Var 'b')' |
| 01:25:18 | <Berengal> | Asdfgh11: In that case you need to write a parser or something |
| 01:25:26 | <Asdfgh11> | i should have : Add ('a' 'b') [1 ,2] |
| 01:25:43 | <crutex> | Asdfgh11 are you sure that's proper syntax? |
| 01:25:48 | <Asdfgh11> | i should have : Add (var ' a' var 'b') [1 |
| 01:25:51 | <Asdfgh11> | yes i am |
| 01:25:53 | <crutex> | ... |
| 01:25:55 | <crutex> | i think it's not |
| 01:25:57 | <Berengal> | Asdfgh11: You could do that if you wanted, but then you'd only be able to add variables |
| 01:26:37 | <Asdfgh11> | what do u mean |
| 01:26:41 | <crutex> | that's what i meant |
| 01:26:55 | <Berengal> | Asdfgh11: Actually, you can't have the parenthesis there... |
| 01:27:46 | <crutex> | it's elementary how could you f that up |
| 01:27:53 | <Asdfgh11> | so it cant be done |
| 01:28:08 | <tompledger> | Re Add 'a' 'b': Could you use a class to span both Char and the datatype with Add/Sub/etc? |
| 01:28:20 | <Berengal> | Asdfgh11: ('a' 'b') means "apply the function 'a' to the value 'b'), which can't be done since 'a' isn't a function |
| 01:28:23 | <crutex> | tompledger are you sure that's proper syntax? |
| 01:28:45 | <crutex> | 99% of errors are syntax aerors. |
| 01:29:07 | <Asdfgh11> | what do u mean by spanning |
| 01:29:24 | <crutex> | <span> is like a div but with inline display by default |
| 01:29:28 | <tompledger> | crutex: if Add is a data constructor taking 2 args, then yes |
| 01:29:29 | <crutex> | it's just for partitioning content |
| 01:29:47 | <Berengal> | tompledger: You could have a class Expr e where evaluate :: [...] |
| 01:29:55 | <crutex> | Berengal are you sure that's proper syntax? |
| 01:30:11 | <Berengal> | crutex: I'm sure it's not. |
| 01:30:16 | <crutex> | that's what i thought |
| 01:30:21 | <tompledger> | The [...] is metasyntax ;-) |
| 01:30:29 | <crutex> | i knew it looked strange |
| 01:30:38 | <Berengal> | tompledger is right |
| 01:30:47 | <crutex> | i'm new to this |
| 01:30:58 | <crutex> | forgive if i ask too many questions |
| 01:31:01 | <Asdfgh11> | can you tell me how to write a parser |
| 01:31:14 | <crutex> | ehh maybe in a few years once i learn |
| 01:31:23 | <crutex> | what are you trying to parse |
| 01:31:26 | <crutex> | haskell grammar? |
| 01:31:43 | <Asdfgh11> | i have expression wich i want to be accepted as char also |
| 01:31:59 | <crutex> | hmm |
| 01:32:15 | <crutex> | well what do you mean by "tell you how to write a parser" |
| 01:32:45 | <Asdfgh11> | i want data Exp to accept chars |
| 01:32:57 | <Berengal> | Asdfgh11: A parser takes a string as input. You can't use it directly in source, unless you put a string literal in there... |
| 01:33:32 | <Asdfgh11> | berengal do understand my problem |
| 01:33:47 | <Berengal> | Asdfgh11: Not completely, I'm afraid... |
| 01:33:57 | <gwern> | 'Possibly it should use instead "validating constructors" that return a Maybe type. But note that some minutes have 61 seconds, and given that TimeOfDay might be local civil time (UTC + time zone offset), it can be any minute. So these must be allowed:' |
| 01:34:02 | <gwern> | arrghhh |
| 01:34:03 | <crutex> | gwern are you sure that's proper syntax? |
| 01:34:21 | <gwern> | ACTION hates units. units are insane! a minute has 60 seconds, end of discussion |
| 01:34:30 | <crutex> | well technically not |
| 01:34:30 | <skorpan> | what's wrong with () |
| 01:34:36 | <crutex> | leap seconds |
| 01:34:50 | <crutex> | !google leap seconds |
| 01:34:55 | <Gracenotes> | go! |
| 01:35:01 | <gwern> | crutex: not listening! |
| 01:35:08 | <crutex> | eh ? |
| 01:35:10 | <Gracenotes> | hrm. I might have to use UUIDs to implement "listeners" here. Otherwise I can't remove listeners -- because functions are not Eq |
| 01:35:21 | <roconnor> | bot: A leap second is a positive or negative one-second adjustment to the Coordinated Universal Time (UTC) time scale that keeps it close to mean solar time. |
| 01:35:21 | <Gracenotes> | at least, not in a sane way |
| 01:35:49 | <Gracenotes> | although there must be a better name than listeners. perhaps "hooks" |
| 01:35:54 | <roconnor> | Gracenotes: why use UUIDs |
| 01:36:04 | <roconnor> | just have the listener return the delistening function |
| 01:36:12 | <Berengal> | Gracenotes: Put them in a structure, give them a name. Why UUID? |
| 01:36:15 | <Berengal> | Or use slots... |
| 01:36:19 | <roconnor> | the listener insertion function return the ... |
| 01:36:24 | <roconnor> | you know what I mean |
| 01:36:32 | <Gracenotes> | Berengal: well. a name would be an ID in this case :) |
| 01:36:44 | <Berengal> | roconnor's idea is also sound |
| 01:37:13 | <Gracenotes> | roconnor: well. a delistening function would have to identify the listener somehow |
| 01:37:22 | <Gracenotes> | UUIDs aren't a bad way to do this, eh? |
| 01:38:03 | <roconnor> | Gracenotes: sure, but that doesn't need a universally unique id. Just a locally unique one. |
| 01:38:24 | <Gracenotes> | roconnor: well. yes. perhaps I went too crazy with acronyms |
| 01:38:27 | <roconnor> | there is probably a clever way that needs no ids at all |
| 01:38:31 | <Gracenotes> | just some sort of counter |
| 01:38:38 | <crutex> | are you sure that's proper syntax? |
| 01:38:39 | <Berengal> | How are these listeners stored? |
| 01:39:22 | <Gracenotes> | Berengal: data Listener s = forall a. Listener (MyEvent -> MyMonad s a) |
| 01:39:22 | <vininim_> | http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5242#a5242 |
| 01:39:36 | <crutex> | oh Gracenotes you're such a dullard |
| 01:39:47 | <Gracenotes> | I could easily add an Integer there |
| 01:39:54 | <roconnor> | some sort of IORef ought to work as ID. |
| 01:39:54 | <Gracenotes> | crutex dear, you know I can't help it! |
| 01:39:56 | <vininim_> | previous paste gets a sleeping process with 0 seconds runtime |
| 01:40:04 | <roconnor> | or MVar |
| 01:40:07 | <roconnor> | or whatever |
| 01:40:13 | <Berengal> | Gracenotes: I meant how are they stored after they're hooked in? |
| 01:40:16 | <Gracenotes> | roconnor: and storing it in a [Listener s] |
| 01:40:21 | <crutex> | how would you represent categorical hierarchy in a rdbms |
| 01:40:33 | <Gracenotes> | er, @Berengal |
| 01:41:10 | <Gracenotes> | adding an Integer would provide a way to use delete, which requires Eq, or even better -- a Set -- which requires Ord |
| 01:41:33 | <crutex> | Gracenotes are you by chance a woman |
| 01:41:46 | <Gracenotes> | and when an Event is received the idea is to cycle through 'em all |
| 01:41:59 | <crutex> | that is not meant to sound passive aggressive |
| 01:42:06 | <crutex> | pure inquery |
| 01:42:19 | <Gracenotes> | crutex: isn't all gender by chance? |
| 01:42:35 | <crutex> | at some level everything is by chance |
| 01:42:45 | <crutex> | are you by chance /a woman/ though |
| 01:42:54 | <Gracenotes> | no. |
| 01:42:56 | <Berengal> | Gracenotes: Okay, go ahead, an id couldn't hurt |
| 01:42:57 | <vininim_> | how dare you talk about chance on a pure fuctional language channel? |
| 01:43:22 | <crutex> | Gracenotes are you denying that you are a woman because you are afraid of #haskell thinking less of you |
| 01:43:24 | <Gracenotes> | vininim_: in a nondeterminism monad |
| 01:43:26 | <Berengal> | ACTION still wonders if there could be a functional answer |
| 01:43:30 | <crutex> | you can answer me in PM if you want |
| 01:43:44 | <Gracenotes> | I don't think this is the case |
| 01:43:54 | <crutex> | ok |
| 01:44:40 | <crutex> | sorry didn't mean for that to be awkward |
| 01:44:57 | <crutex> | sooo |
| 01:45:02 | <crutex> | how would you represent categorical hierarchy in a rdbms |
| 01:45:34 | <Gracenotes> | Berengal: it all is very imperative, an IRC bot with a lot of functionality. I think FRP might provide a way to do it nicely, but I don't understand it very well, and I think most people don't |
| 01:46:35 | <Cale> | crutex: I don't understand your question? Is it in any way related to Haskell? |
| 01:46:43 | <crutex> | cale not necessarily |
| 01:46:46 | <crutex> | does it have to be |
| 01:46:52 | <crutex> | to talk here |
| 01:46:53 | <Cale> | crutex: Categorical hierarchy? |
| 01:47:09 | <crutex> | eh yes like a hierarchy of categories is what i meant, not sure if my english was correct |
| 01:47:30 | <Cale> | Well, in this channel when people use the word 'category', they tend to mean something other than the usual English meaning. |
| 01:47:31 | <Berengal> | Gracenotes: If dropping into IO isn't too much a bother, [IORef (Maybe Listener)] ? |
| 01:47:39 | <Cale> | (it has a mathematical definition) |
| 01:47:44 | <crutex> | i see |
| 01:48:11 | <crutex> | i meant a category as ... a category that items could belong to, and if you belong to a category you belong to all the parents of that category |
| 01:48:21 | <Gracenotes> | Berengal: well.. the monad I'm using is a MonadIO. |
| 01:48:24 | <Cale> | yeah |
| 01:48:25 | <Cale> | okay |
| 01:48:34 | <Gracenotes> | Berengal: what's the Maybe for? |
| 01:48:57 | <Gracenotes> | hm.. removing references to Listeners? |
| 01:49:04 | <crutex> | Cale surely a parent child column for each would not be an efficient way, at least the querying would be inefficient? |
| 01:49:22 | <Cale> | Well, relational databases are supposed to make joins of that kind efficient. |
| 01:50:08 | <Cale> | (If they didn't there wouldn't be much point in calling them relational) |
| 01:50:13 | <olivierp> | is there anything that would prevent me from exporting a type constructor from a module? when I list the constructors in the where () clause of the module they're reported not to be in scope. The two constructors are for GADTs, maybe that's related? i can access them from the outside when exporting everything (no where clause) though. |
| 01:50:35 | <crutex> | Cale i'm having a hard time visualizing what the table(s) would look like |
| 01:50:39 | <Berengal> | Gracenotes: Right, so addListener :: Listener -> ListenerList -> IO (ListenerList, IO ()); addListener listener list = do ref <- newIORef (Just listener); let derefListener = writeIORef ref Nothing; return (ref:list, derefListener) |
| 01:51:00 | <crutex> | i'm kind of nub @ it |
| 01:51:30 | <Gracenotes> | hm |
| 01:51:48 | <p_l> | crutex: It's quite easy to model a tree using tables. Define fields: ID and parent, and you can have it done. |
| 01:51:58 | <crutex> | right |
| 01:52:05 | <crutex> | but how would the queries look :X |
| 01:52:36 | <crutex> | if the items are linked to only 1 category |
| 01:53:06 | <crutex> | depending on the level of inheritence that would be a low of work for 1 query wouldn't it |
| 01:53:10 | <crutex> | *lot |
| 01:53:11 | <hatds> | constructors are exported as 'subordinate' names, could that be the problem? |
| 01:53:19 | <p_l> | crutex: for finding all members of given category... SELECT * FROM table WHERE parent = (SELECT id FROM table WHERE name='name'); |
| 01:53:45 | <hatds> | i.e. you aren't accidentally exporting just the typename |
| 01:53:59 | <p_l> | crutex: that however requires a serious RDBMS - I heard MySQL 5.x still fails performance hard with that kind of query |
| 01:54:14 | <crutex> | p_l what if it is say 4 or 5 levels deep |
| 01:54:28 | <Cale> | crutex: So you have a table of categories along with their parent, and then you have a table of items along with the smallest category in which they belong. |
| 01:54:38 | <crutex> | yes cale |
| 01:55:31 | <p_l> | crutex: that was if you know the node whose leafs you wanted, assuming your category was shaped into a tree |
| 01:56:34 | <Cale> | Hmm, it seems that plain SQL isn't really good for taking transitive closures. |
| 01:56:59 | <Cale> | I suppose you could just maintain another table with the transitive closure. |
| 01:57:12 | <Cale> | But that's a bit ugly. |
| 01:59:07 | <p_l> | crutex: you can maintain all links in one table, and various kinds of objects in other tables |
| 01:59:54 | <crutex> | http://i39.tinypic.com/sxmbro.jpg |
| 01:59:56 | <crutex> | here's a pic |
| 02:01:11 | <Cale> | crutex: Right, you need a table which has two columns, parentID and childID, and which expresses not just the direct relationships between categories, but all of them. That is, it'll have an entry with parentID = 2 and childID = 7 |
| 02:01:30 | <crutex> | hehe, seriously |
| 02:01:39 | <crutex> | all possible paths? O_O |
| 02:01:42 | <vininim_> | ok, just completly ignore me |
| 02:01:43 | <Cale> | yeah |
| 02:01:48 | <crutex> | ok |
| 02:01:53 | <crutex> | wasn't sure if there was a pretty way of doing this |
| 02:01:54 | <vininim_> | my example expected the list from standard input heh |
| 02:02:02 | <hatds> | how does the time/allocation report determine the number of entries of a cost center? If you pass a function as a parameter and call it a zillion times at different arguments you won't get more than 1 'entry' ? |
| 02:02:04 | <vininim_> | so of course it was sleeping |
| 02:02:25 | <Cale> | crutex: There are various nonstandard ways of constructing the transitive closure automatically, but plain standard SQL doesn't have one. |
| 02:03:04 | <crutex> | how would it be done then |
| 02:03:28 | <Cale> | It can be constructed somewhat efficiently in stages, where you find all the new relationships you can at each stage, and insert them into the table until there's nothing more to add. |
| 02:04:15 | <crutex> | it seems like this would be a fairly common problem |
| 02:04:16 | <crutex> | is it? |
| 02:04:47 | <crutex> | is mysql/postgre even a good solution for it |
| 02:07:32 | <grncdr> | crutex: I didn't get your whole question but... |
| 02:07:51 | <grncdr> | representing trees in a database is a fairly common problem/practice |
| 02:08:10 | <grncdr> | and a relation database is in fact a terribly inelegant way to store a tree |
| 02:08:14 | <grncdr> | *relational |
| 02:08:59 | <Cale> | It's too bad that there isn't a good way to express the transitive closure in SQL. |
| 02:09:23 | <Cale> | But if you have another language handy which you're manipulating your database with, it's fairly easy to construct. |
| 02:09:27 | <tompledger> | Some SQL engines have it as an extension, don't they? |
| 02:09:32 | <Cale> | tompledger: It seems so. |
| 02:09:34 | <crutex> | cale what do you mean |
| 02:09:38 | <crutex> | this is with postgre and php |
| 02:14:34 | <vininim_> | uh.. I wonder why hmatrix doesn't export joinVert and joinHoriz |
| 02:15:07 | <tompledger> | #type joinVert |
| 02:15:19 | <duaneb> | hi people |
| 02:15:24 | <duaneb> | I'm trying to have an instance of Read |
| 02:15:29 | <duaneb> | and I'm not sure how to go about it |
| 02:15:34 | <Cale> | crutex: Create a new table and start by copying into it the direct tree edges obtained from the other table. Then, insert into the new table (x,x) for each category ID (making it reflexively closed), and then repeatedly insert into it (x,z) where (x,y) and (y,z) are already in it, which is the same as inserting into it an inner join of it with itself where the appropriate columns match |
| 02:15:38 | <duaneb> | I guess |
| 02:15:40 | <vininim_> | joinVert :: Element t => [Matrix t] -> Matrix t |
| 02:15:42 | <duaneb> | there's readsPrec |
| 02:15:48 | <duaneb> | but It's not clear how that works |
| 02:16:00 | <olivierp> | hatds: sorry, didn't notice your reply. both the data types and the constructors are exported, and they have different names |
| 02:16:40 | <hatds> | olivierp: maybe hpaste it if you still have problems |
| 02:16:45 | <crutex> | ok thank you a lot for your awesome input cale |
| 02:17:12 | <olivierp> | hatds: hmm, it seems I only need to export the data types, and the constructors are exported automatically |
| 02:17:46 | <olivierp> | hatds: it works fine if i just remove the constructors from the module where clause |
| 02:17:53 | <hatds> | olivierp: that should only happen with Typename(..) syntax |
| 02:18:09 | <olivierp> | hatds: do you know what the rules for this are? |
| 02:18:18 | <tompledger> | vininim_: thanks, I haven't got the hang of lambdabot yet. Perhaps joinVert is only for use by trusted callers within its module, because its return type doesn't cover the "Oi! Incompatible height/width" situation? |
| 02:18:24 | <duaneb> | ahh, nm |
| 02:18:25 | <duaneb> | I got it |
| 02:18:27 | <hatds> | olivierp: http://www.haskell.org/onlinereport/modules.html |
| 02:18:40 | <hatds> | probably the one place where the gory details of the haskell report are often needed |
| 02:18:42 | <olivierp> | hatds: no i didn't use typename(..), but they're GADTs |
| 02:18:47 | <olivierp> | thanks |
| 02:18:55 | <vininim_> | tompledger: it does |
| 02:19:05 | <vininim_> | joinVert ms = case common cols ms of Nothing -> error "joinVert on matrices with different number of columns" Just c -> reshape c $ join (map flatten ms) |
| 02:19:26 | <tompledger> | Oh, OK |
| 02:19:56 | <BMeph> | Sounds like a snap to do in Q (the DB stuff). :) |
| 02:20:03 | <Cale> | So it'd be like (untested, and I only infrequently use SQL), INSERT INTO cats_tc SELECT tc1.parentID, tc2.childID FROM cats_tc AS tc1 INNER JOIN cats_tc AS tc2 ON tc1.childID=tc2.parentID |
| 02:20:09 | <vininim_> | @type common |
| 02:20:10 | <lambdabot> | Not in scope: `common' |
| 02:20:25 | <Cale> | crutex: ^^ have a look at that and see if it works/makes sense :) |
| 02:20:42 | <crutex> | yes cale i will have to digest it later :} |
| 02:20:44 | <olivierp> | hatds: hmm ok got it. I think i don't actually need the constructors exported, they're only used in a Template Haskell splice that's defined in the same module (but used outside) |
| 02:21:10 | <duaneb> | ahh, never mind |
| 02:21:11 | <duaneb> | got it |
| 02:21:20 | <olivierp> | hatds: i guess TH isn't quite the same as copy/pasting the code at the splice location |
| 02:25:26 | <kniu> | :t (.) (.) |
| 02:25:27 | <lambdabot> | forall b c a a1. (a1 -> b -> c) -> a1 -> (a -> b) -> a -> c |
| 02:25:48 | <crutex> | Thanks again! |
| 02:26:31 | <vininim_> | > foldl1 f [x y z w] |
| 02:26:32 | <lambdabot> | Couldn't match expected type `SimpleReflect.Expr |
| 02:26:39 | <Cale> | It seems really silly that SQL, being based on relational algebra, would not include something such basic things as the transitive or reflexive closure of a relation... |
| 02:26:45 | <vininim_> | > foldl1 f [x y z] |
| 02:26:46 | <lambdabot> | Couldn't match expected type `SimpleReflect.Expr |
| 02:26:56 | <Cale> | -something |
| 02:27:04 | <vininim_> | > foldl1 f [x, y, z] |
| 02:27:06 | <lambdabot> | f (f x y) z |
| 02:27:17 | <vininim_> | heh |
| 02:31:22 | <vininim_> | tompledger: just in case you are interested <|> is joinH and <-> is joinV in hmatrix |
| 02:32:22 | <tompledger> | A rows by any other name... |
| 02:32:32 | <duaneb> | anyone know parsec? |
| 02:32:38 | <duaneb> | I have this thing: liftM (Number . (read::String->Int)) (optional (oneOf "-+") >> many1 digit) |
| 02:32:45 | <duaneb> | where data Number = Number Int |
| 02:32:55 | <kniu> | so I'm trying to install reactive-glut. |
| 02:33:04 | <duaneb> | and yet, (read::String->Number) "-89" leads to Number -89 |
| 02:33:08 | <duaneb> | err, Number 89 |
| 02:33:11 | <kniu> | one of the dependencies depends on two different versions of quickcheck. |
| 02:33:21 | <kniu> | indirectly. |
| 02:33:47 | <Cale> | duaneb: you appear to be discarding the sign |
| 02:33:54 | <kniu> | how do I fix that? |
| 02:34:13 | <Cale> | duaneb: remember that >> discards the result of its left parameter |
| 02:34:15 | <duaneb> | Cale: I do indeed |
| 02:34:32 | <duaneb> | Cale: yea, but doesn't '>>=' pass the result to the next function? |
| 02:34:37 | <Cale> | kniu: Just install the deps one by one. |
| 02:34:38 | <duaneb> | I'm not sure how to manage this.... |
| 02:34:52 | <kniu> | huh |
| 02:34:58 | <Cale> | kniu: But it can be tricky, since the latest version of everything doesn't all work together. |
| 02:35:09 | <Cale> | kniu: The dependencies for reactive are a mess right now. |
| 02:35:11 | <kniu> | well then. |
| 02:36:38 | <Cale> | duaneb: Oh, the other problem is that optional unconditionally discards the result of the parser you apply it to |
| 02:36:47 | <duaneb> | great. |
| 02:36:53 | <Cale> | You can use optionMaybe |
| 02:37:12 | <duaneb> | ACTION thinks this is too complicated |
| 02:37:47 | <duaneb> | whatever, I'll just do it :P |
| 02:37:48 | <Gracenotes> | hm. Is there an MVar with a timer? |
| 02:37:54 | <Cale> | do sign <- optionMaybe (oneOf '+-'); rest <- many1 digit; return (Number (read (fromMaybe '+' sign : rest))) |
| 02:38:03 | <Gracenotes> | well. "timeout", that is |
| 02:38:08 | <Cale> | duaneb: ^^ how about that? |
| 02:38:22 | <duaneb> | that's what I was writing |
| 02:38:23 | <duaneb> | so |
| 02:38:25 | <duaneb> | I agree! |
| 02:38:31 | <Gracenotes> | ( ≖‿≖) |
| 02:38:41 | <duaneb> | Gracenotes++ |
| 02:38:51 | <Gracenotes> | okay, so would it be possible to implement an MVar lookup with a timeout? |
| 02:39:09 | <Gracenotes> | ACTION doesn't see one in the docs |
| 02:39:14 | <Cale> | Gracenotes: Like, try to take the MVar, and if it's empty, block for so long before giving up and returning Nothing? |
| 02:39:24 | <Gracenotes> | yes |
| 02:39:35 | <Cale> | You can do that with an extra thread... |
| 02:39:38 | <Gracenotes> | it is somewhat important here |
| 02:40:35 | <Gracenotes> | Cale: I think I may have threads being created left and right here :) At least Haskell threads a "green" so to say |
| 02:40:37 | <Gracenotes> | are |
| 02:40:52 | <Cale> | Hmm, there's also tryTakeMVar... |
| 02:41:24 | <Gracenotes> | well. that would amount to crude sleeping blocks |
| 02:42:02 | <duaneb> | Cale: works great |
| 02:42:13 | <SamB> | yes, but you could use tryTakeMVar to avoid spawning the thread when you can just take the MVar right off ... |
| 02:42:40 | <Berengal> | Isn't there a timeout :: Int -> IO a -> IO a somewhere? |
| 02:43:13 | <Gracenotes> | SamB: this is very unlikely in my case |
| 02:43:23 | <Cale> | yeah... |
| 02:43:41 | <Cale> | System.Timeout might do it |
| 02:43:48 | <Cale> | timeout :: Int -> IO a -> IO (Maybe a) |
| 02:43:55 | <SamB> | so, why do you want to do that anyway ? |
| 02:44:26 | <Cale> | The Int is in microseconds... |
| 02:45:08 | <Berengal> | Cale: Looks like picoseconds or something to me... |
| 02:45:23 | <Cale> | Multiply by 10^6... |
| 02:45:39 | <Gracenotes> | SamB: an empty MVar is created, a listener is added to a list which only puts in the MVar if a particular event is received, and once the MVar is filled the idea is to remove the listener and yield the event |
| 02:45:45 | <Berengal> | Ah, yes, micro..- |
| 02:46:19 | <Cale> | Gracenotes: So, you should be able to timeout (10^6) (takeMVar v) |
| 02:47:13 | <Gracenotes> | Cale: hm, ingenious! Functional programming for the win. |
| 02:47:19 | <Gracenotes> | except, it is the same as your previous idea |
| 02:47:25 | <Gracenotes> | it creates a new "kill thread" |
| 02:47:28 | <Cale> | yeah |
| 02:47:28 | <Gracenotes> | but at least it is in the stdlib |
| 02:47:37 | <Cale> | http://www.haskell.org/ghc/docs/latest/html/libraries/base/src/System-Timeout.html#timeout |
| 02:47:49 | <Gracenotes> | right |
| 02:47:50 | <hackagebot> | MemoTrie 0.4.5 |
| 02:47:52 | <Cale> | The implementation is careful, but straightforward :) |
| 02:48:36 | <Cale> | The behaviour for negative parameters seems out of place though. |
| 02:48:40 | <Gracenotes> | it does seem limited though. |
| 02:48:50 | <Gracenotes> | particularly with IO. As noted in the docs. |
| 02:49:45 | <Cale> | It does the best that's reasonable for it to do. |
| 02:49:55 | <Gracenotes> | overall, concurrency needs more fine-tuning, more concurrency primitives and concurrent data structures. but this'll do |
| 02:50:00 | <Gracenotes> | :) |
| 02:50:12 | <Cale> | C code doesn't have a notion of async exceptions which could be relied on. |
| 02:50:12 | <dons> | more concurrency primitives? |
| 02:50:12 | <lambdabot> | dons: You have 1 new message. '/msg lambdabot @messages' to read it. |
| 02:50:24 | <dons> | more concurrent data structures? (mutable ones?) |
| 02:50:26 | <Cale> | So FFI calls are always going to be strange... |
| 02:50:43 | <Cale> | Actually, I think the comment in the docs is fairly positive about how well it works. |
| 02:50:48 | <dons> | or you mean things like Chan et al? (concurrent queues) |
| 02:51:42 | <Gracenotes> | by primitives: explicit locks, conditions, etc. Even if they are just wrappers around MVar, a clean interface is good. |
| 02:52:00 | <Cale> | http://picturesforsadchildren.com/index.php?comicID=266 |
| 02:52:05 | <dons> | what kinds of locks and conditions are missing? |
| 02:52:06 | <Gracenotes> | STM and TVar takes care of compare-and-swap-like operations nicely, which does put Haskell ahead of many things |
| 02:52:15 | <Cale> | Gracenotes: locks are worse than MVar... |
| 02:52:27 | <Cale> | Gracenotes: you can just use MVar () |
| 02:52:36 | <Gracenotes> | Cale: yes. But, as I said, a wrapper. |
| 02:52:55 | <Cale> | Does something that simple really need a wrapper? |
| 02:53:00 | <dons> | MVars and TVars will be the primitive thread-aware shared memory abstraction primitives for the next few years. |
| 02:53:29 | <Cale> | Concurrency is important, but it's much less important than pure parallelism, I think. |
| 02:53:30 | <Gracenotes> | Conditions, as in waiting and signalling. |
| 02:53:31 | <dons> | there's fairly regular releases on hackage of things on top, though i'm hard pressed to find uses for some of them |
| 02:53:41 | <Gracenotes> | Chan needs more control over blocking and whatnot. |
| 02:53:52 | <Cale> | Gracenotes: There's an implementation of concurrent ML if you'd like :) |
| 02:53:55 | <jmcarthur> | Cale: and much harder than pure parallelism, too |
| 02:54:09 | <Gracenotes> | there aren't many ways to ensure atomic operations other than using an MVar () |
| 02:54:10 | <jmcarthur> | actually |
| 02:54:14 | <Berengal> | It'd be nice to have a clean message-passing interface |
| 02:54:17 | <Gracenotes> | for instance, you could run into race conditions with Chan functions |
| 02:54:23 | <jmcarthur> | maybe the other way around, with STM :) |
| 02:54:25 | <dons> | Berengal: tried the actors library? |
| 02:54:31 | <dons> | pretty much identical syntactically to erlang. |
| 02:54:42 | <Berengal> | dons: No I haven't. Thanks for the tip |
| 02:54:44 | <dons> | Gracenotes: there's a bounded Chan on hackage. |
| 02:55:02 | <dons> | http://hackage.haskell.org/cgi-bin/hackage-scripts/package/BoundedChan |
| 02:55:06 | <dons> | by a colleague of mine |
| 02:55:14 | <dons> | actors, http://hackage.haskell.org/cgi-bin/hackage-scripts/package/actor |
| 02:55:43 | <Gracenotes> | still, no reason that regular ol' Chan shouldn't be able to support more fine-tuned blocking options. |
| 02:55:44 | <dons> | actors compared w/ erlang, http://gist.github.com/111482 |
| 02:55:53 | <dons> | Gracenotes: what do you want to be able to do? |
| 02:57:13 | <Cale> | dons: Does that come with an Erlang version? |
| 02:58:01 | <Gracenotes> | essentially, act as a queue where you can poll, retrieve an element on top as a (Maybe a), etc. |
| 02:58:07 | <dons> | yeah, on matthew's blog. http://codebetter.com/blogs/matthew.podwysocki/archive/2009/05/12/axum-introduction-and-ping-pong-example.aspx |
| 02:58:29 | <dons> | Gracenotes: sounds like a different library. maybe upload it? |
| 02:58:39 | <Gracenotes> | I think any linked blocking queue should be able to handle it |
| 02:59:18 | <Gracenotes> | also... there's not much support for timeout operations. System.Timeout is neat, although I'm not sure it's the best general-purpose solution :/ |
| 02:59:27 | <dons> | you want to poll, rather than just sleeping until a value arrives (i.e. you want access to the top MVar's tryTake? |
| 03:00:15 | <Gracenotes> | dons: yeah. I'm not sure why there isn't more MVar functionality exposed >_> |
| 03:00:26 | <dons> | no one has needed it? |
| 03:00:32 | <pumpkin> | Gracenotes: write it and expose it! |
| 03:00:40 | <pumpkin> | it can be called Gracenotes' exposé |
| 03:00:43 | <dons> | or: it is trivial to roll your own, so people write that, and upload it. |
| 03:00:49 | <Gracenotes> | pumpkin: but that would be indecent! |
| 03:00:59 | <dons> | yay MVars. the great shared memory sync primitive |
| 03:01:08 | <Cale> | Gracenotes: It's fairly trivial to write a function which races a number of IO actions concurrently and takes the result of the first one to complete as well. |
| 03:01:16 | <Gracenotes> | at least I'm pretty happy with the MVar functionality. |
| 03:01:42 | <Gracenotes> | ACTION wonders if there have been any thread pools implemented, other than with the shootout |
| 03:01:53 | <pumpkin> | I saw something recently on hackage |
| 03:01:56 | <gwern> | Gracenotes: what, like the threadpool package on hackage? |
| 03:02:03 | <Gracenotes> | @hackage threadpool |
| 03:02:03 | <lambdabot> | http://hackage.haskell.org/cgi-bin/hackage-scripts/package/threadpool |
| 03:02:03 | <gwern> | the 1000th package uploaded? |
| 03:02:12 | <dons> | Gracenotes: on hackage. |
| 03:02:15 | <dons> | gwern: months ago |
| 03:02:24 | <Gracenotes> | ;_; |
| 03:02:27 | <gwern> | Gracenotes: incidentally, that feature is just a concatenation - it doesn't actually tell you if it exists |
| 03:02:30 | <Cale> | The cml library also has some very general operations for message protocols. |
| 03:02:36 | <dons> | gwern: 1299 packages. |
| 03:02:43 | <gwern> | the @hackage shortcut I've long felt is nonsense on stilts |
| 03:02:56 | <dons> | commit the change you want to see :) |
| 03:03:00 | <gwern> | dons: yeah, but the discuessions and cabalization of threadpool was months ago as well... |
| 03:03:03 | <sbahra> | "threadPool: Runs other programs in the manner of a thread pool" |
| 03:03:10 | <sbahra> | "Takes a single, optional argument which is the number of threads (the default is three). Give it the commands to run, one per line, through standard input. You may use blank lines to divide the commands into sections. The commands in a section will not be started until all the commands in previous sections are complete. " |
| 03:03:11 | <sbahra> | ... |
| 03:03:24 | <Gracenotes> | hrm |
| 03:03:26 | <gwern> | dons: eh. can lb plugins do http lookups? |
| 03:03:26 | <dons> | dph also has a worker pool at the bototm |
| 03:03:30 | <dons> | sure |
| 03:03:30 | <Gracenotes> | so the thread pool is fixed, too |
| 03:03:33 | <dons> | ?google woot woot |
| 03:03:34 | <lambdabot> | http://www.woot.com/ |
| 03:03:34 | <lambdabot> | Title: Woot : One Day, One Deal (SM) |
| 03:03:34 | <Cale> | http://hackage.haskell.org/packages/archive/cml/0.1.1/doc/html/Control-Concurrent-CML.html |
| 03:03:37 | <Gracenotes> | no cached make-as-you-go thread pools |
| 03:03:40 | <monochrom> | The two commands @hackage and @faq are supposed to teach you basic combinator programming, i.e., the I and K combinators. |
| 03:03:51 | <dons> | Gracenotes: there's a lib for that. dph also has precisely that. |
| 03:04:04 | <pumpkin> | <3 dph |
| 03:04:09 | <gwern> | monochrom: I always saw @faq as a demonstration of 'const' |
| 03:04:24 | <monochrom> | Yes that's K. |
| 03:04:26 | <Gracenotes> | for now, though, I would just be happy if someone made timeout support built into MVars :) |
| 03:04:37 | <Cale> | Gracenotes: why should it be built in? |
| 03:04:45 | <BMeph> | ACTION wonders how tough a Hoogle-like utility for Hackage packages would be... |
| 03:04:52 | <Gracenotes> | why shouldn't it be? I would find it useful. |
| 03:05:03 | <Cale> | Because System.Timeout does it perfectly |
| 03:05:19 | <Gracenotes> | by creating a thread. |
| 03:05:25 | <pumpkin> | a green thread |
| 03:05:25 | <Cale> | Huh? |
| 03:05:33 | <Cale> | Threads are like 24 bytes or something |
| 03:05:34 | <sbahra> | Gracenotes, the package is pretty useless. |
| 03:05:42 | <Cale> | It's not like it's expensive to make one :) |
| 03:05:45 | <Gracenotes> | pumpkin: yes, a green thread, I realize, but one nonetheless |
| 03:05:58 | <Cale> | Gracenotes: Threads are the natural way to do a timeout |
| 03:06:05 | <pumpkin> | a green thread is probably cheaper than any code you could write that simulated it |
| 03:06:06 | <pumpkin> | :P |
| 03:06:07 | <Cale> | Gracenotes: Even if it was built-in, it would use a thread. |
| 03:06:12 | <gwern> | BMeph: what would a hoogle for hackage be besides hoogle itself? |
| 03:06:32 | <jinho> | http://haskell.pastebin.com/m3973d6ff : can someone explain to me what's going on at line 21, specifically with (map renderJValue vs), thanks |
| 03:07:05 | <Cale> | jinho: That applies the function renderJValue to each of the elements of the list vs giving a new list |
| 03:07:36 | <Cale> | actually, that code seems excessive, doesn't it? |
| 03:07:42 | <Cale> | > intercalate ", " [] |
| 03:07:44 | <lambdabot> | "" |
| 03:07:45 | <pumpkin> | :o http://blog.plt-scheme.org/2009/05/typed-scheme-20.html |
| 03:07:48 | <jinho> | Cale: taken from "Real World Haskell" |
| 03:07:56 | <Cale> | jinho: hmm, that's funny then :) |
| 03:07:57 | <jinho> | Cale: maybe it's not so real world |
| 03:07:59 | <Cale> | dons: ! |
| 03:08:00 | <Cale> | hehe |
| 03:08:05 | <Gracenotes> | eh. It'd be nice if something were built straight into Control.Concurrent.MVar. For a concurrent primitive, it seems it should suppose timeouts |
| 03:08:23 | <monochrom> | map renderJValue [x,y,z] = [renderJValue x, renderJValue y, renderJValue z] if it helps. |
| 03:08:23 | <Gracenotes> | *support |
| 03:08:25 | <pumpkin> | Gracenotes: why build in special-case support when you have something more general? |
| 03:08:30 | <Cale> | renderJValue (JArray a) = "[" ++ intercalate ", " (map renderJValue vs) ++ "]" |
| 03:08:35 | <Cale> | would work just as well |
| 03:08:40 | <Gracenotes> | pumpkin: because it's annoying to work with two interfaces at the same time? |
| 03:08:53 | <pumpkin> | it shouldn't be :/ things are supposed to be composable |
| 03:09:19 | <pumpkin> | <=< it! |
| 03:09:22 | <pumpkin> | :P |
| 03:09:24 | <Gracenotes> | >=> |
| 03:09:26 | <Gracenotes> | <=< |
| 03:09:29 | <Cale> | Gracenotes: Consider that System.Timeout works not only with MVars but also with Chans and every other blocking concurrency structure |
| 03:09:46 | <Cale> | (including ones which have not yet been invented) |
| 03:10:06 | <jinho> | Cale: can you tell me what's going on with the renderJValue (JObject o) part? I can't wrap my head around (map renderPair ps) |
| 03:10:07 | <Cale> | As long as it's not making blocking FFI calls, it will work :) |
| 03:10:14 | <codebliss> | ACTION waits for the following to be legal. (:=) = (=) |
| 03:10:29 | <Cale> | jinho: Do you know what map is? |
| 03:10:44 | <Cale> | > map show [1,2,3,4,5] |
| 03:10:46 | <lambdabot> | ["1","2","3","4","5"] |
| 03:10:53 | <jinho> | right |
| 03:11:05 | <Cale> | jinho: So, if ps is a list of pairs |
| 03:11:08 | <jinho> | ok I'm an idiot |
| 03:11:23 | <Cale> | jinho: map renderPairs ps is the list of results of applying renderPair to each of those |
| 03:11:32 | <jinho> | Cale: I didn't realize a JSON object could hold a list of pairs |
| 03:11:36 | <Cale> | ah, okay |
| 03:12:13 | <Gracenotes> | well. I guess I still am a bit suspicious, and I'll see what I can do about Chan not refusing to expose (:O) |
| 03:12:17 | <Cale> | It seems whoever wrote that code for RWH didn't realise that intercalate gives an empty string when given an empty list. |
| 03:12:20 | <mmorrow> | Gracenotes: newtype MVarT a = MVarT (Mvar a); takeMVarT :: Int -> MVarT a -> IO (Maybe a); takeMVarT t (MVarT mv) = timeout t (takeMVar mv) |
| 03:12:21 | <jinho> | Cale: thanks though |
| 03:12:40 | <pumpkin> | Gracenotes: maybe it's a coverup! |
| 03:12:47 | <mmorrow> | Gracenotes: Chans are borked |
| 03:12:50 | <mmorrow> | Gracenotes: do: |
| 03:12:57 | <Cale> | "not refusing to expose"? |
| 03:13:03 | <Gracenotes> | sorry. cut out the "not" |
| 03:13:19 | <pumpkin> | b0rked |
| 03:13:33 | <pumpkin> | b0rk b0rk b0rk |
| 03:13:35 | <Gracenotes> | I have a knack for the worst against-my-original-meaning typos |
| 03:13:36 | <Cale> | mmorrow: Are they? |
| 03:13:57 | <mmorrow> | ghci> ch :: Chan Int <- newChan |
| 03:13:57 | <mmorrow> | ghci> forkIO (readChan ch >> return ()) |
| 03:13:57 | <mmorrow> | ghci> isEmptyChan ch |
| 03:14:01 | <Cale> | http://hackage.haskell.org/packages/archive/cml/0.1.1/doc/html/Control-Concurrent-CML.html -- I'd like someone to try this library and see how it is :) |
| 03:14:03 | <mmorrow> | (it blocks!!) |
| 03:14:15 | <Cale> | Oh, right. That is pretty dumb. |
| 03:14:32 | <pumpkin> | :o |
| 03:14:35 | <mmorrow> | and it's an artifact of the implem... so the only solution is a different one |
| 03:14:41 | <pumpkin> | isEmptyCan can block? |
| 03:14:45 | <pumpkin> | *Chan |
| 03:14:45 | <Cale> | The equivalent written with TChan doesn't do that stupid thing though. |
| 03:14:56 | <Gracenotes> | isEmptyChan is an invitation for race conditions |
| 03:14:58 | <pumpkin> | isn't that just a bug that needs fixing? |
| 03:15:04 | <Cale> | Yes, it's just a bug. |
| 03:15:08 | <mmorrow> | (this is mine: http://moonpatio.com/repos/vacuum-gl/System/Vacuum/OpenGL/Q.hs) |
| 03:15:21 | <pumpkin> | much cooler name |
| 03:15:25 | <mmorrow> | pumpkin: the only way to fix it is a different implmentation though |
| 03:15:27 | <pumpkin> | I want to use a Q |
| 03:15:28 | <Cale> | and an easy workaround is just to use TChan with everything wrapped in atomically :) |
| 03:15:37 | <pumpkin> | your Q feels more rational ;) |
| 03:15:42 | <monochrom> | QChan? |
| 03:15:54 | <mmorrow> | it has a non-blocking getChanContents too! |
| 03:16:03 | <Gracenotes> | Q. Chan: sounds like an awesome name. for a person. |
| 03:16:09 | <pumpkin> | Quentin Chan |
| 03:16:14 | <Gracenotes> | make it so |
| 03:16:15 | <pumpkin> | Quentin Charantino |
| 03:16:22 | <Cale> | You should replace Chan with it... |
| 03:16:23 | <mmorrow> | ACTION was just thinking that |
| 03:16:25 | <monochrom> | "QChan is a channel for requesting the Q community to do magic for you, for example change the user's input so it no longer triggers a bug in your program" |
| 03:16:35 | <mmorrow> | (thinking Quentin Charantino) |
| 03:16:40 | <pumpkin> | :D |
| 03:17:45 | <pumpkin> | Cale: did lambdabot forget quotes recently? |
| 03:17:57 | <Gracenotes> | hm. I suppose I can live with timeouts being inexact. after all, an amount like "10 seconds" is rather arbitrary in the scheme of things |
| 03:17:57 | <Cale> | pumpkin: It is possible? |
| 03:18:04 | <monochrom> | It forgets quotes every year. |
| 03:19:45 | <mmorrow> | Gracenotes: at the second scale Control.timeout should be more than ok |
| 03:19:55 | <mmorrow> | (or threadDelay for that matter) |
| 03:21:23 | <mmorrow> | Cale: i was reading somewhere that STM updates are fundamentally O(n), where n is the size of the structure being updated |
| 03:21:34 | <mmorrow> | (something about transaction logs or something) |
| 03:21:52 | <Cale> | mmorrow: whaaat... that sounds implausible... |
| 03:21:57 | <mmorrow> | or something to the effect that there's an inherent limitation |
| 03:22:06 | <mmorrow> | ACTION looks for quote |
| 03:22:15 | <mmorrow> | i think it was in that new ghc-rts paper |
| 03:22:56 | <monochrom> | If you keep running into contentions yes. |
| 03:23:45 | <QtPlaty[HireMe]> | The "default" keyword is a ghc extention? |
| 03:23:53 | <Cale> | mmorrow: Do you mean that every part of the structure is being updated? |
| 03:23:59 | <Cale> | QtPlaty[HireMe]: no |
| 03:24:07 | <monochrom> | The "default" keyword is in Haskell98. |
| 03:24:40 | <monochrom> | http://www.haskell.org/onlinereport/decls.html#sect4.3.4 |
| 03:25:14 | <roconnor> | @roll 1300000d6 |
| 03:25:14 | <lambdabot> | Consider it noted. |
| 03:25:18 | <roconnor> | damn it |
| 03:25:20 | <roconnor> | I always do that |
| 03:25:26 | <mmorrow> | hmm, not that one. i think i know which one exactly that quotes (or the quote i remembered incorrectly) is from |
| 03:25:32 | <monochrom> | http://www.hck.sk/users/peter/HaskellEx.htm is a very useful page for looking up Haskell98 grammar and where to find details in the Haskell98 report. |
| 03:25:47 | <mmorrow> | Cale: i'm not sure exactly what that remark meant in particular |
| 03:26:24 | <monochrom> | @roll |
| 03:26:25 | <lambdabot> | Plugin `tell' failed with: Prelude.head: empty list |
| 03:26:29 | <Cale> | mmorrow: It certainly takes O(n) time to commit a transaction log which has n entries in it. |
| 03:26:36 | <monochrom> | Oh, roll = tell |
| 03:26:54 | <Cale> | @dice 1300000d6 |
| 03:26:55 | <lambdabot> | 1300000d6 => 4549630 |
| 03:27:00 | <mmorrow> | oh nice. this might be very interesting to anyone that wants to get up to speed with haskell concurrency stuff http://research.microsoft.com/en-us/um/people/simonpj/papers/parallel/AFP08-notes.pdf |
| 03:27:52 | <mmorrow> | Cale: the context was comparing concurrent algo speed/complexity between implems using {IORef+atomicModifyIORef, MVar, STM} |
| 03:28:11 | <mmorrow> | (can anyone think off-hand what paper that is?) |
| 03:28:14 | <pumpkin> | @quote pumpkin |
| 03:28:14 | <lambdabot> | pumpkin says: makes the next internet hit video, 2 natural transformations, 1 functor |
| 03:28:30 | <pumpkin> | oh I guess lambdabot quotes are room-specific? |
| 03:28:58 | <mmorrow> | Cale: found it |
| 03:29:09 | <mmorrow> | www.haskell.org/~simonmar/papers/concurrent-data.pdf |
| 03:31:54 | <gwern> | pumpkin: no, quotes are all from a single file |
| 03:32:01 | <gwern> | which contains no info about origin |
| 03:32:21 | <vininim_> | @src endBy |
| 03:32:21 | <lambdabot> | Source not found. :( |
| 03:32:30 | <pumpkin> | gwern: it's odd, someone did @quote pumpkin four times in a row, in #haskell-blah and got the same quote each time |
| 03:32:39 | <pumpkin> | gwern: did you figure out your list comprehension thing by the way? |
| 03:32:42 | <gwern> | that's randomness for you |
| 03:33:14 | <gwern> | pumpkin: Cale figured that it was conflicting rules resulted in a call to a library map versus an inlined map, but he got different results on 6.10.3 |
| 03:33:16 | <Twey> | ‘Nine... nine... nine... nine... nine... nine... nine... nine...’ |
| 03:34:03 | <Cale> | gwern: The results I got in 6.10.3 were similar enough not to worry about |
| 03:34:17 | <gwern> | @qoute Hobbes |
| 03:34:17 | <lambdabot> | Maybe you meant: quote vote |
| 03:34:19 | <Cale> | gwern: But on 6.10.2 I can imagine those performing differently, do they? |
| 03:34:30 | <gwern> | oh come on, that's obviously closer to quote than vote -_- |
| 03:34:37 | <gwern> | @quote Hobbes |
| 03:34:37 | <lambdabot> | thetallguy says: Using and advocating Haskell is like being Calvin (and Hobbes). To you, it's alive, real, a true delight. To those who know better, it's a stuffed tiger. |
| 03:34:40 | <pumpkin> | are there any things that need figuring out to replace foldr/build fusion with stream fusion in GHC? |
| 03:34:53 | <pumpkin> | or does it just need someone to implement it? |
| 03:35:30 | <Cale> | pumpkin: I thought it was implemented at least in part... |
| 03:35:39 | <pumpkin> | well, as a library |
| 03:35:52 | <pumpkin> | but there was talk of replacing existing fusion with the library |
| 03:37:11 | <mmorrow> | what's the difference? (not rhetorical) |
| 03:37:32 | <pumpkin> | stream fusion helps with many more operations, I think |
| 03:37:42 | <pumpkin> | and seems simpler conceptually, to me at least |
| 03:37:47 | <mmorrow> | is there a description of it somewhere? |
| 03:37:52 | <mmorrow> | @type build |
| 03:37:53 | <lambdabot> | Not in scope: `build' |
| 03:37:55 | <pumpkin> | stream fusion? |
| 03:37:58 | <pumpkin> | or foldr/build? |
| 03:37:59 | <mmorrow> | , build |
| 03:38:00 | <lunabot> | luna: Not in scope: `build' |
| 03:38:03 | <mmorrow> | stream |
| 03:38:12 | <dmwit> | It's buildr. |
| 03:38:21 | <pumpkin> | it is? |
| 03:38:32 | <pumpkin> | mmorrow: http://www.cse.unsw.edu.au/~dons/papers/stream-fusion.pdf |
| 03:38:41 | <pumpkin> | http://hackage.haskell.org/trac/ghc/ticket/915 |
| 03:39:52 | <mmorrow> | , [$ty| build |] |
| 03:39:56 | <lunabot> | forall a . (forall b . (a -> b -> b) -> b -> b) -> [] a |
| 03:40:03 | <pumpkin> | see, that isn't a friendly function signature :P |
| 03:40:10 | <gwern> | (wow, version changed from 6.4.2) |
| 03:40:20 | <pumpkin> | stream fusion is a lot prettier in my opinion :) |
| 03:40:22 | <gwern> | -> [] a |
| 03:40:23 | <gwern> | ? |
| 03:40:28 | <pumpkin> | [a] |
| 03:40:30 | <mmorrow> | pumpkin: oh nice, i've actually looked at this paper when i first started with haskell |
| 03:40:42 | <pumpkin> | it's a cool idea |
| 03:41:07 | <mmorrow> | it should be interesting to go over it again |
| 03:41:22 | <pumpkin> | "To replace GHC's existing list fusion, we'll need to work out how concatMap is optimised, and push the desugaring for list comprehensions into GHC." |
| 03:41:34 | <pumpkin> | so I guess concatMap is the painful one |
| 03:44:06 | <Cale> | pumpkin: I don't think that build is so bad... |
| 03:44:17 | <Cale> | pumpkin: But stream fusion is indeed better. |
| 03:45:02 | <Cale> | It might be even nicer to have some extremely general implementation of fusion as part of the compiler though, I think. |
| 03:45:26 | <mmorrow> | ghc uses either build/foldr or this http://moonpatio.com/fastcgi/hpaste.fcgi/view?id=2260 method to desugar list comps |
| 03:45:27 | <Cale> | (that works across all algebraic types, say) |
| 03:45:36 | <mmorrow> | i don't think it actually uses concatMap |
| 03:45:51 | <pumpkin> | wow |
| 03:45:59 | <mmorrow> | that'd be pretty cool to have *-comprehensions |
| 03:46:05 | <mmorrow> | (where * can be array, vector, whatever) |
| 03:46:08 | <pumpkin> | Cale: I agree |
| 03:49:49 | <mmorrow> | pumpkin: here's that listcomp desugaring code (here done on the TH ast) if you're interested http://moonpatio.com/fastcgi/hpaste.fcgi/view?id=2490#a2490 |
| 03:49:58 | <mmorrow> | this is the "classic" method apparently |
| 03:50:05 | <mmorrow> | (the other being build/foldr) |
| 03:51:07 | <hackagebot> | LslPlus 0.4.1.1 |
| 03:52:30 | <pumpkin> | cool :) |
| 03:52:41 | <mmorrow> | pumpkin: i followed along with http://moonpatio.com/repos/LIBS/Language/ghc/compiler/deSugar/DsListComp.lhs for that algo |
| 03:53:12 | <mmorrow> | i wish darcs.haskell.org sent .l?hs as text/plain |
| 03:53:28 | <pumpkin> | I wish my browser wouldn't download the .gz patches |
| 03:53:39 | <mmorrow> | heh, i actually like that "feature" |
| 03:53:57 | <mmorrow> | err, you mean it doesn't decode them? |
| 03:54:01 | <pumpkin> | yeah |
| 03:54:04 | <mmorrow> | heh |
| 03:54:10 | <pumpkin> | I'd love to see them in the browser without downloading and unpacking them |
| 03:55:51 | <mmorrow> | still have to fill in the case for |
| 03:55:53 | <mmorrow> | , 'LetS |
| 03:55:55 | <lunabot> | Language.Haskell.TH.Syntax.LetS |
| 03:55:59 | <mmorrow> | now that i look at that |
| 03:56:21 | <mmorrow> | (go e (LetS decs : ss) xs = error "don't do LetS") |
| 03:56:23 | <pumpkin> | I wonder what projects people will work on at the hackathon |
| 03:56:27 | <pumpkin> | there are so many things I want to work on |
| 03:57:50 | <pumpkin> | is there a package out there that builds "tied knot" graphs? |
| 03:57:56 | <pumpkin> | that seems like it would be pretty cool |
| 03:58:41 | <ray> | hackathons are filled with boring people who disapprove of crashing drunkenness |
| 03:58:47 | <pumpkin> | :o |
| 03:58:51 | <pumpkin> | so I take it you won't be going to this one? |
| 03:59:27 | <ray> | not unless there's an open bar |
| 04:00:20 | <mmorrow> | ray: just bring a waterbottle |
| 04:00:35 | <ray> | or a flask :) |
| 04:00:55 | <mmorrow> | (i wasn't meaning to put water in the waterbottle ;) |
| 04:01:26 | <ray> | naturally |
| 04:01:32 | <pumpkin> | 151bottle |
| 04:02:54 | <pumpkin> | @seen bsp |
| 04:02:54 | <lambdabot> | I haven't seen bsp. |
| 04:02:56 | <SamB> | ray: what, no alcohol-fueled coders attend hackathons, you say? |
| 04:03:08 | <pumpkin> | does anyone know what his nick on IRC is, or if he just never comes online? |
| 04:03:19 | <shapr> | who? |
| 04:03:34 | <pumpkin> | max bolingbroke |
| 04:03:46 | <gwern> | don't know of him on irc, sry |
| 04:03:47 | <shapr> | I don't know if he shows up on irc. |
| 04:04:00 | <shapr> | Not that I've been online much the past year. |
| 04:05:55 | <pumpkin> | ah :) |
| 04:08:08 | <Gracenotes> | hm. |
| 04:08:13 | <pumpkin> | hm. indeed |
| 04:08:39 | <ray> | philadelpha's not unreachable from here i guess |
| 04:08:56 | <pumpkin> | you should go! |
| 04:08:59 | <ray> | which is good, otherwise it'd be garbage collected |
| 04:09:07 | <pumpkin> | geek. |
| 04:09:16 | <pumpkin> | nerd? |
| 04:09:18 | <pumpkin> | what's the difference |
| 04:09:45 | <ray> | i'm not sure |
| 04:09:52 | <pumpkin> | anyway, one of those |
| 04:09:55 | <Gracenotes> | quizas |
| 04:09:55 | <ray> | i'm not either, just the victim of an unfortunate series of events |
| 04:10:24 | <pumpkin> | Gracenotes: zomg foreign languidge |
| 04:10:53 | <dmwit> | ray: You should definitely come! |
| 04:11:19 | <dmwit> | Also, geek is anyone obsessed with sci-fi or fantasy; nerd is anyone obsessed with technology. You're welcome. |
| 04:11:20 | <ray> | i'll certainly consider it, since it's not tomorrow or anything |
| 04:11:22 | <Gracenotes> | .. |
| 04:11:24 | <Gracenotes> | quiza |
| 04:11:25 | <Gracenotes> | s |
| 04:11:29 | <pumpkin> | Gracenotes will only go if we speak spanish there |
| 04:11:32 | <pumpkin> | dmwit: thanks :) |
| 04:12:10 | <Gracenotes> | dmwit: to the contrary. I think geek is someone obsessed with technology; nerd is obsessed with culture |
| 04:12:25 | <dmwit> | Uh, culture? |
| 04:12:30 | <Gracenotes> | my connotations vs. yours seem reversed >_> |
| 04:12:39 | <lament> | so there's still no way to split a string given a separator? :( |
| 04:12:41 | <Gracenotes> | dmwit: yes. e.g. Star Wars nerd, WoW nerd, etc. |
| 04:12:45 | <pumpkin> | @hackage split |
| 04:12:46 | <lambdabot> | http://hackage.haskell.org/cgi-bin/hackage-scripts/package/split |
| 04:13:02 | <dino-> | lament: Funny you should mention, I was tinkering with something today.. |
| 04:13:06 | <Gracenotes> | vs. programming geek, rocket science geek |
| 04:13:22 | <dmwit> | Well, for what it's worth, the dictionary says a geek is a person with an unusual or odd personality, and a nerd is a student who studies excessively. |
| 04:13:34 | <lament> | ACTION mumbles |
| 04:13:57 | <lament> | pumpkin: :( |
| 04:14:00 | <dino-> | If you have Parsec instanced into Applicative: p target = (,) <$> (manyTill anyChar $ try $ string target) <*> many anyChar |
| 04:14:06 | <pumpkin> | lament: it's a nice package :) |
| 04:14:18 | <pumpkin> | :o |
| 04:14:29 | <lament> | pumpkin: splitting lists is not a package. It's not even a source file. |
| 04:14:33 | <dino-> | You get the (before, after) pair without the target string |
| 04:14:36 | <lament> | It's a couple functions and they should reside in Data.List |
| 04:14:37 | <pumpkin> | lament: ? |
| 04:14:43 | <mmorrow> | lament: i rewrite the it every day probably at least 3 times if that counts :/ |
| 04:14:44 | <pumpkin> | lament: look at the package I linked to |
| 04:14:47 | <mmorrow> | s/the// |
| 04:14:55 | <lament> | pumpkin: that's what i'm saying. |
| 04:15:01 | <lament> | pumpkin: installing a whole package for this is crazy. |
| 04:15:03 | <pumpkin> | lament: there are several different ways of doing it... it's not just a couple of functions |
| 04:15:13 | <Gracenotes> | dmwit: mm. Well those are vague. I tend to view a nerd's obsessions as more popular-culture-y than a geek's. But you can only splice meaning so much... hm. |
| 04:15:17 | <mmorrow> | (actually chunk is what i rewrite every day) |
| 04:15:29 | <pumpkin> | do you keep the separators, discard them, do you split based on conditions or constants, or lengths |
| 04:15:33 | <ray> | splitting combinators! =D |
| 04:15:33 | <pumpkin> | things like that |
| 04:15:36 | <mmorrow> | @let chunk _ [] = []; chunk n xs = let (ys,zs) = splitAt n xs in ys : chunk n zs |
| 04:15:38 | <lambdabot> | Defined. |
| 04:15:40 | <Gracenotes> | they can't really be viewed as opposites. |
| 04:15:42 | <pumpkin> | ray: that's what it is |
| 04:15:46 | <mmorrow> | i can do that in mah sleep now |
| 04:15:50 | <lament> | pumpkin: it's a single function in both Python and C#. |
| 04:15:50 | <Gracenotes> | anyway. </personal connotations> |
| 04:15:58 | <pumpkin> | lament: that isn't as flexible :D |
| 04:16:11 | <pumpkin> | lament: and doesn't work on arbitrary lists |
| 04:16:19 | <mmorrow> | > plit |
| 04:16:20 | <lament> | :\ |
| 04:16:21 | <mmorrow> | > split |
| 04:16:21 | <lambdabot> | Not in scope: `plit' |
| 04:16:23 | <lambdabot> | Overlapping instances for GHC.Show.Show (g -> (g, g)) |
| 04:16:23 | <lambdabot> | arising from a use... |
| 04:16:46 | <dmwit> | > split (0, 0) |
| 04:16:47 | <lambdabot> | No instance for (System.Random.RandomGen (t, t1)) |
| 04:16:47 | <lambdabot> | arising from a use of ... |
| 04:17:03 | <dmwit> | :t mkStdGen |
| 04:17:04 | <lambdabot> | Int -> StdGen |
| 04:17:09 | <dmwit> | > split (mkStdGen 0) |
| 04:17:09 | <mmorrow> | @let splat _ [] = []; splat p xs = case break p xs of ([],zs) = zs; (ys,zs) = ys : splat p zs |
| 04:17:10 | <lambdabot> | (2 40692,40014 2147483398) |
| 04:17:10 | <lambdabot> | Parse error |
| 04:17:13 | <lament> | pumpkin: there's a kind of fine balance between flexibility and usability |
| 04:17:18 | <pumpkin> | lament: split :: Splitter a -> [a] -> [[a]] is nice, I think |
| 04:17:26 | <mmorrow> | @let splat _ [] = []; splat p xs = case break p xs of ([],zs) -> zs; (ys,zs) -> ys : splat p zs |
| 04:17:28 | <lambdabot> | <local>:13:80: |
| 04:17:28 | <lambdabot> | Occurs check: cannot construct the infinite type: a = [a... |
| 04:17:30 | <dmwit> | mmorrow: needs more {} |
| 04:17:47 | <dmwit> | Oh, I guess not. |
| 04:17:55 | <pumpkin> | lament: it's pretty usable :P but if you can decide on a single good meaning (with justification) of split to add to the std lib, maybe they'll add it? |
| 04:18:01 | <mmorrow> | @let splat _ [] = []; splat p xs = case break p xs of ([],zs) -> [zs]; (ys,zs) -> ys : splat p zs |
| 04:18:03 | <lambdabot> | Defined. |
| 04:18:12 | <mmorrow> | can haz cowbell? |
| 04:18:30 | <lament> | > splat "," "hello,world" |
| 04:18:32 | <lambdabot> | Couldn't match expected type `a -> GHC.Bool.Bool' |
| 04:18:38 | <lament> | er |
| 04:18:41 | <ray> | i should write some mahjong combinators |
| 04:18:43 | <dmwit> | mmorrow: I think it needs more drop now. |
| 04:18:46 | <pumpkin> | GHC.Bool.Bool :o |
| 04:18:47 | <mmorrow> | > splat (==',') "hello,world" |
| 04:18:47 | <lament> | > splat ',' "hello,world" |
| 04:18:49 | <lambdabot> | Couldn't match expected type `a -> GHC.Bool.Bool' |
| 04:18:50 | <lambdabot> | ["hello",",world"] |
| 04:18:51 | <pumpkin> | where did that come from? |
| 04:18:53 | <mmorrow> | crapp |
| 04:18:56 | <dmwit> | > splat (==',') "hello,bad,world" |
| 04:18:58 | <lambdabot> | ["hello",",bad,world"] |
| 04:19:11 | <mmorrow> | @let splatter _ [] = []; splatter p xs = case break p xs of ([],zs) -> [zs]; (ys,zs) -> ys : drop 1 (splatter p zs) |
| 04:19:13 | <lambdabot> | Defined. |
| 04:19:20 | <pumpkin> | you need a wrangle in there |
| 04:19:20 | <mmorrow> | > splatter (==',') "hello,world" |
| 04:19:22 | <lambdabot> | ["hello"] |
| 04:19:26 | <mmorrow> | gah! |
| 04:19:30 | <mmorrow> | oh, n/m |
| 04:19:32 | <dmwit> | hehehe |
| 04:19:33 | <mmorrow> | that worked |
| 04:19:38 | <mmorrow> | heh |
| 04:19:51 | <dmwit> | > splatter (==',') "hello,good,world" |
| 04:19:53 | <lambdabot> | ["hello"] |
| 04:19:58 | <dmwit> | fail |
| 04:20:02 | <mmorrow> | the song rawhide plays in my head whenever i write a function named wrangle |
| 04:20:06 | <pumpkin> | ACTION wants to make a new SCM based on darcs |
| 04:20:24 | <mmorrow> | grrr |
| 04:20:30 | <dmwit> | mmorrow: splatter p (drop 1 zs) instead |
| 04:20:39 | <mmorrow> | kill! |
| 04:20:46 | <mmorrow> | im running out of names |
| 04:20:50 | <dmwit> | And change the first branch of the case. |
| 04:20:53 | <dmwit> | To be (zs, []) |
| 04:20:56 | <mmorrow> | yeah, true |
| 04:21:02 | <mmorrow> | guess it's time to pull out wrangle |
| 04:21:08 | <pumpkin> | :D |
| 04:21:16 | <dmwit> | :t splattest |
| 04:21:16 | <lambdabot> | Not in scope: `splattest' |
| 04:21:26 | <pumpkin> | wrangle always works |
| 04:21:32 | <lament> | splat, splatter, splattest! |
| 04:21:42 | <mmorrow> | @let wrangle _ [] = []; wrangle p xs = case break p xs of (ys,[]) -> [ys]; (ys,zs) -> ys : wrangle p (drop 1 zs) |
| 04:21:44 | <lambdabot> | Defined. |
| 04:21:45 | <mmorrow> | wooo |
| 04:21:48 | <pumpkin> | ACTION grins |
| 04:22:01 | <Raynes> | I can't believe I was just stupid enough to type init [1..10000000000] into GHCi. :| |
| 04:22:02 | <lament> | > wrangle (== ',') "what,the , hell" |
| 04:22:04 | <lambdabot> | ["what","the "," hell"] |
| 04:22:10 | <lament> | woo! |
| 04:22:10 | <pumpkin> | Raynes: just ctrl+c it? |
| 04:22:16 | <dmwit> | > wrangle isSpace " " |
| 04:22:17 | <lambdabot> | ["","","","","","","","","","","","","","","","","","",""] |
| 04:22:30 | <mmorrow> | wrangle them isSpaces! |
| 04:22:39 | <mmorrow> | ACTION cues rawhide |
| 04:22:40 | <dmwit> | ...rawhide? |
| 04:22:45 | <Raynes> | pumpkin: By time I noticed my computer was freezing it was too late. |
| 04:22:52 | <pumpkin> | > wrangle even [1..] |
| 04:22:53 | <lambdabot> | [[1],[3],[5],[7],[9],[11],[13],[15],[17],[19],[21],[23],[25],[27],[29],[31]... |
| 04:22:55 | <Raynes> | Pop goes the weesle. |
| 04:22:58 | <dmwit> | Raynes: ^z always works here |
| 04:23:08 | <dmwit> | Raynes: ^zkill %1 is burned into my fingers |
| 04:23:17 | <dmwit> | Which is bad, because it's not always %1. =/ |
| 04:24:04 | <pumpkin> | ray: http://www.haskell.org/haskellwiki/Hac_φ |
| 04:24:46 | <ray> | ghci needs an option to only show a certain number of characters a la lambdabot |
| 04:24:47 | <Gracenotes> | > wrangle even ([1..] >>= \x -> [x, x]) |
| 04:24:49 | <lambdabot> | [[1,1],[],[3,3],[],[5,5],[],[7,7],[],[9,9],[],[11,11],[],[13,13],[],[15,15]... |
| 04:24:55 | <Gracenotes> | o_O |
| 04:24:59 | <pumpkin> | that's useful |
| 04:25:21 | <dmwit> | > wrangle even ([1..] >>= join replicate) |
| 04:25:22 | <lambdabot> | [[1],[],[3,3,3],[],[],[],[5,5,5,5,5],[],[],[],[],[],[7,7,7,7,7,7,7],[],[],[... |
| 04:25:33 | <dmwit> | YES! I've always wanted that! |
| 04:25:46 | <Gracenotes> | ever since I was a little girl! |
| 04:26:14 | <Gracenotes> | er. boy. (as applicable) |
| 04:26:53 | <dino-> | @paste |
| 04:26:53 | <lambdabot> | Haskell pastebin: http://hpaste.org/new |
| 04:27:46 | <dmwit> | Alright... bed and a decent night's rest, or code and never sleep? |
| 04:28:14 | <dino-> | http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5244#a5244 |
| 04:28:38 | <pumpkin> | dmwit: I'd get some sleep |
| 04:28:53 | <dino-> | substAll and splitAll, with applicative parsec. Have I mentioned how excited I am lately with applicative functors? |
| 04:28:59 | <dmwit> | Yeah, that's definitely what I should do. |
| 04:29:12 | <pumpkin> | I love applicative |
| 04:29:14 | <Gracenotes> | dino-: they are very neat |
| 04:29:21 | <Gracenotes> | @where applicativeparsec |
| 04:29:22 | <lambdabot> | http://www.serpentine.com/blog/2008/02/06/the-basics-of-applicative-functors-put-to-practical-work/ and http://book.realworldhaskell.org/read/using-parsec.html#id652399 |
| 04:29:23 | <Gracenotes> | ^ you've read? |
| 04:29:35 | <dino-> | Gracenotes: No, thank you! |
| 04:29:37 | <mxc> | applicative has been getting some love in this channel in the past few days.. |
| 04:29:55 | <mxc> | i wonder if 'learn you a haskell' adding a chapter on it helped |
| 04:29:59 | <pumpkin> | but monoids for parsing also seems cool |
| 04:30:02 | <dino-> | I only read The Paper, wikibook and parts of RWH a-la Applicoparsec |
| 04:30:13 | <pumpkin> | I guess they aren't mutually exclusive :) |
| 04:30:19 | <pumpkin> | and Alternative is just monoid |
| 04:30:22 | <Gracenotes> | righto |
| 04:31:12 | <dino-> | Also, I have a naggy feeling those split* functions should be folds. |
| 04:31:19 | <pumpkin> | folds? |
| 04:31:45 | <pumpkin> | oh in your paste? |
| 04:31:52 | <dino-> | Instead of recursing until Left. yes |
| 04:32:45 | <Gracenotes> | dino-: hm. In general, one would use Parsec with one "parse" call for the whole expression, and everything else composed of smaller Parsers |
| 04:32:49 | <Gracenotes> | a la combinators |
| 04:33:06 | <Gracenotes> | and there are built-in Parsec fold combinators |
| 04:33:10 | <dino-> | Gracenotes: I found the iterativeness of this difficult to do that way. |
| 04:33:17 | <tompledger> | @type unfoldr |
| 04:33:18 | <dino-> | But I could be Doing It Wrong, absolutely |
| 04:33:18 | <lambdabot> | forall b a. (b -> Maybe (a, b)) -> b -> [a] |
| 04:33:34 | <dino-> | ah, parsec fold |
| 04:33:38 | <dino-> | mm, must read |
| 04:42:25 | <roconnor> | @free sortBy |
| 04:42:26 | <lambdabot> | (forall x. g x = h (f x) . f) => $map f . sortBy g = sortBy h . $map f |
| 04:42:35 | <pastorn> | what function does this? |
| 04:42:37 | <dino-> | mm, unfold |
| 04:42:39 | <pastorn> | f "hhhheeello" == ["hhhh","eee","ll","o"] |
| 04:42:44 | <roconnor> | group |
| 04:42:50 | <pastorn> | thanks :) |
| 04:42:54 | <Cale> | > group "mississippi" |
| 04:42:56 | <lambdabot> | ["m","i","ss","i","ss","i","pp","i"] |
| 04:43:07 | <Cale> | > group . sort $ "mississippi" |
| 04:43:09 | <lambdabot> | ["iiii","m","pp","ssss"] |
| 04:43:10 | <pumpkin> | roconnor: what do the $ mean in @free output? |
| 04:43:32 | <pastorn> | is there a more general version of group? |
| 04:43:40 | <pumpkin> | groupBy? |
| 04:43:45 | <pastorn> | one that might also take a function (a -> Eq b) |
| 04:43:51 | <pastorn> | @type groupBy |
| 04:43:52 | <lambdabot> | forall a. (a -> a -> Bool) -> [a] -> [[a]] |
| 04:44:01 | <pastorn> | cool, win |
| 04:44:04 | <roconnor> | pumpkin: $map is the appropriate map for whatever datatype |
| 04:44:07 | <roconnor> | I think |
| 04:44:09 | <pumpkin> | ah |
| 04:44:23 | <pumpkin> | seems like it would need to be list though |
| 04:44:56 | <dmwit> | $map is Prelude.map, to avoid clashes with names you provide in lets. |
| 04:45:03 | <roconnor> | g x y = h (f x) (f y) is probably a more clear hypothesis. |
| 04:45:05 | <pumpkin> | ah :) |
| 04:45:09 | <dmwit> | ?free let map = id in map |
| 04:45:09 | <lambdabot> | Pattern match failure in do expression at /tmp/ghc25834_0/ghc25834_59.hspp:54:20-34 |
| 04:45:18 | <dmwit> | ...or something like that. |
| 04:45:29 | <roconnor> | @free fst |
| 04:45:30 | <lambdabot> | f . fst = fst . $map_Pair f g |
| 04:45:41 | <roconnor> | dmwit: interesting |
| 04:46:18 | <roconnor> | @free Left |
| 04:46:18 | <lambdabot> | Pattern match failure in do expression at /tmp/ghc25834_0/ghc25834_59.hspp:54:20-34 |
| 04:46:24 | <pumpkin> | @free loop |
| 04:46:25 | <lambdabot> | Expected variable or '.' |
| 04:46:33 | <dmwit> | ?free map :: a -> a -> a |
| 04:46:34 | <lambdabot> | f . map x = map (f x) . f |
| 04:46:53 | <dmwit> | There, that shows how you might get a clash. |
| 04:47:08 | <dmwit> | :t sortBy |
| 04:47:10 | <lambdabot> | forall a. (a -> a -> Ordering) -> [a] -> [a] |
| 04:47:19 | <pumpkin> | @free loop :: (a, b) -> (c, b) -> a -> c |
| 04:47:19 | <lambdabot> | h . loop x y = loop ($map_Pair f g x) ($map_Pair h g y) . f |
| 04:47:21 | <dmwit> | ?free map :: (a -> a -> Ordering) -> [a] -> [a] |
| 04:47:22 | <lambdabot> | (forall x. g x = h (f x) . f) => $map f . map g = map h . $map f |
| 04:47:27 | <pumpkin> | fun :) |
| 04:47:56 | <pastorn> | @pl (\c0 c1 -> (xPos c0) == (xPos c1)) |
| 04:47:56 | <lambdabot> | (. xPos) . (==) . xPos |
| 04:48:01 | <pastorn> | nah... |
| 04:48:12 | <dmwit> | (==) `on` xPos |
| 04:48:35 | <dmwit> | Though note that this has a more restrictive type than the lambda you wrote. |
| 04:48:41 | <dmwit> | (very slightly more restrictive) |
| 04:48:57 | <pumpkin> | it'd be nice if it were possible to write on that took typeclasses |
| 04:49:11 | <dmwit> | yeah |
| 04:50:49 | <pastorn> | dmwit: is that the reader monad? |
| 04:50:53 | <pastorn> | @type on |
| 04:50:54 | <lambdabot> | forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c |
| 04:51:00 | <pumpkin> | sort of similar |
| 04:51:09 | <dmwit> | pastorn: No, there's no monad involved, but it does seem Reader-ish. =) |
| 04:51:17 | <pumpkin> | :t liftM2 (==) |
| 04:51:18 | <pastorn> | indeed it does |
| 04:51:18 | <lambdabot> | forall a1 (m :: * -> *). (Eq a1, Monad m) => m a1 -> m a1 -> m Bool |
| 04:51:30 | <pastorn> | gaddamn ((->) a) |
| 04:51:34 | <pumpkin> | I love it :) |
| 04:51:50 | <pumpkin> | could just be the reader applicative I guess |
| 04:52:26 | <pastorn> | ACTION is writing recursive list functions like it's 1998! |
| 04:52:32 | <vininim_> | hGetBufNonBlocking: illegal operation (handle is closed) |
| 04:52:35 | <vininim_> | baaaawwww |
| 04:53:33 | <pumpkin> | http://imgur.com/k27q8.jpg |
| 04:54:37 | <Gracenotes> | er |
| 04:54:47 | <Gracenotes> | subtraction. there is only addition and negation |
| 04:55:19 | <pumpkin> | division. there is only multiplication and multiplicative inversion ? |
| 04:55:29 | <Gracenotes> | I was about to say, yes :o |
| 04:55:44 | <pumpkin> | it's a stupid question :P |
| 04:56:34 | <vininim_> | Is there any alternative to bracket that is ByteString friendly? |
| 04:57:09 | <pumpkin> | in the sense that it'll finalize the underlying buffer of the bytestring? |
| 04:57:46 | <vininim_> | @type ($!) |
| 04:57:48 | <lambdabot> | forall a b. (a -> b) -> a -> b |
| 04:57:59 | <vininim_> | @src ($!) |
| 04:57:59 | <lambdabot> | f $! x = x `seq` f x |
| 04:58:45 | <vininim_> | pumpkin: something like that |
| 05:00:01 | <vininim_> | uh.. it seems unrelated... |
| 05:00:06 | <pumpkin> | ? |
| 05:02:07 | <vininim_> | the problem is Data.ByteString.Lazy.Char8.hGetContents not liking bracket and seq |
| 05:02:35 | <Gracenotes> | hm. it is lazy after all. |
| 05:03:49 | <mmorrow> | vininim_: *GetContents puts the Handle in a "half-closed" state |
| 05:04:19 | <mmorrow> | why are you bracketing? |
| 05:05:21 | <Cale> | You should *never* call hClose on a handle which has already had hGetContents run on it. |
| 05:06:00 | <Cale> | The handle will close automatically at some point after you're done with the string |
| 05:06:36 | <vininim_> | that ``some point'' might lead to resource exhaustion, no? |
| 05:06:41 | <Cale> | yes |
| 05:06:41 | <dmwit> | Yes. |
| 05:06:50 | <dmwit> | If you're worried about it, don't use hGetContents. |
| 05:06:51 | <Cale> | So hGetContents is bad if you're opening many files |
| 05:07:23 | <vininim_> | hm.. what is the recommended way? |
| 05:08:01 | <Cale> | Well, actually you could use the strict bytestring library's version of it, which does completely read the file all at once. |
| 05:08:45 | <Cale> | Or you can read a line or other chunk at a time with the other primitives, and close when you're done |
| 05:08:46 | <mmorrow> | vininim_: or you can just not use hGetContents.. |
| 05:09:15 | <BMeph> | What's "$map_Pair"? Is it like "curry (map . uncurry (***))"? |
| 05:09:24 | <dmwit> | vininim_: Are you actually opening lots of files? |
| 05:09:29 | <dmwit> | (Like, thousands?) |
| 05:10:04 | <dmwit> | $map_Pair f g (x, y) = (f x, g y) |
| 05:10:09 | <vininim_> | yes, 8k |
| 05:10:33 | <dmwit> | Okay, so yeah, you'll want to do your own handle management. |
| 05:10:35 | <dmwit> | :t openFile |
| 05:10:35 | <BMeph> | > curry (map . uncurry (***)) f g (x,y) |
| 05:10:36 | <lambdabot> | Not in scope: `openFile' |
| 05:10:37 | <lambdabot> | Couldn't match expected type `(SimpleReflect.Expr, |
| 05:10:48 | <dmwit> | BMeph: I don't think that type-checks. |
| 05:11:02 | <BMeph> | @type curry (map . uncurry (***)) |
| 05:11:04 | <lambdabot> | forall b c b' c'. (b -> c) -> (b' -> c') -> [(b, b')] -> [(c, c')] |
| 05:11:28 | <dmwit> | BMeph: I think it's just (***) |
| 05:11:37 | <dmwit> | $map_Pair = (***) -- I mean |
| 05:11:41 | <BMeph> | Oh, never mind, the "map" is an analogy. Got it. :) |
| 05:12:02 | <BMeph> | dmwit: Ah, right. Thanks. :) |
| 05:12:41 | <dmwit> | ?hoogle FilePath -> IO Handle |
| 05:12:41 | <lambdabot> | System.IO openBinaryFile :: FilePath -> IOMode -> IO Handle |
| 05:12:41 | <lambdabot> | System.IO openFile :: FilePath -> IOMode -> IO Handle |
| 05:12:41 | <lambdabot> | Distribution.Simple.Utils die :: String -> IO a |
| 05:12:48 | <dmwit> | Oh, so I did get the name right. |
| 05:12:58 | <dmwit> | I guess it makes sense not to import System.IO in \bot, though. |
| 05:15:39 | <walter_> | Could someone give me the haskell paste URL, please? |
| 05:15:45 | <dmwit> | ?hpaste |
| 05:15:45 | <lambdabot> | Haskell pastebin: http://hpaste.org/new |
| 05:16:05 | <walter_> | thanks |
| 05:16:10 | <walter_> | ?hpasete |
| 05:16:10 | <lambdabot> | Haskell pastebin: http://hpaste.org/new |
| 05:16:45 | <elbar> | that looks like cheating ;) |
| 05:18:08 | <walter_> | Why do I get "match(es) are overlapped" http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5245#a5245 |
| 05:18:31 | <dmwit> | isTagText and isTagOpen both match any value. |
| 05:18:43 | <dmwit> | They bind that value to the name isTagText and isTagOpen, respectively. =) |
| 05:19:09 | <dmwit> | (i.e. these do not test whether x is text or open, as you seem to be expecting them to) |
| 05:19:33 | <mmorrow> | vininim_: withFile = flip bracket hClose . flip openFile ReadWriteMode |
| 05:19:39 | <walter_> | dmwit, thank you, then , How can I distict Tag and TagText? |
| 05:20:03 | <mmorrow> | pattern matching |
| 05:20:07 | <jeff_s_> | cast x of x | isTagText x -> |
| 05:20:07 | <jeff_s_> | | isTagOpen x -> |
| 05:20:19 | <jeff_s_> | er, case x of rather |
| 05:20:45 | <dmwit> | walter_: case x of TagOpen tagName attributes -> ...; TagText text -> ... |
| 05:20:59 | <jeff_s_> | nm |
| 05:21:21 | <dmwit> | Guards also work, but it's a good idea to understand how to use patterns. ;-) |
| 05:21:43 | <dmwit> | (jeff_s_'s suggestion would be the guards route; my suggestion would be the patterns route) |
| 05:21:44 | <walter_> | dmwit, your are right. |
| 05:23:34 | <walter_> | I dont really quite understand, thanks. will try both. |
| 05:24:38 | <jeff_s_> | The guards way looks a little sloppy, I'd use pattern matching whenever possible |
| 05:25:11 | <jeff_s_> | but I'm still used to thinking in terms of what looks good in ML. Haskell's been a challenge |
| 05:25:14 | <pastorn> | @src unlines |
| 05:25:14 | <lambdabot> | unlines = concatMap (++ "\n") |
| 05:25:51 | <Gracenotes> | :O |
| 05:25:57 | <Cale> | Haha, from an oldish Onion video: "New CIA intelligence indicates Al-Queda may be linked to Al-Qaida, Al-Qaeada" |
| 05:30:21 | <jeff_s_> | @src lines |
| 05:30:23 | <lambdabot> | Source not found. Are you on drugs? |
| 05:30:28 | <jeff_s_> | haha |
| 05:30:45 | <jeff_s_> | this lambdabot fellow is really smart, clever and resourceful. Oh and reliable |
| 05:30:48 | <jeff_s_> | and dependable |
| 05:31:14 | <Cale> | The source is more reliably linked from the documentation |
| 05:31:36 | <jeff_s_> | ah, then I take back the resourceful part |
| 05:31:57 | <Cale> | for example, from here, http://www.haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v%3Alines you can click the source link, and you'll get http://www.haskell.org/ghc/docs/latest/html/libraries/base/src/Data-List.html#lines |
| 05:32:29 | <Cale> | I think lines was left out for being a little long for @src |
| 05:33:03 | <jeff_s_> | I see |
| 05:48:27 | <jeff_s_> | oh heh, the toplevel isn't very smart about things like cycle [1,2,3] |
| 05:49:26 | <vininim_> | mmorrow: that's bracket point-free =P |
| 05:49:58 | <vininim_> | except that bracket is not only about file input |
| 05:51:27 | <Vq^> | jeff_s_: you're thinking about the memory usage? |
| 05:51:53 | <pumpkin> | shouldn't cycle [1,2,3] run in constant memory? |
| 05:51:56 | <pumpkin> | unless you build something else off it |
| 05:53:11 | <Vq^> | pumpkin: if you assign it to a top-level name and try to evaluate a large chunk of it, it probably takes a lot of memory |
| 05:53:27 | <pumpkin> | why? |
| 05:53:37 | <Vq^> | not sure what jeff_s_ meant by toplevel thought |
| 05:54:58 | <Vq^> | pumpkin: because it gets memoized, and the top-level name has to keep it alive |
| 05:55:16 | <pumpkin> | nope? |
| 05:55:33 | <dmwit> | Vq^: ...so? |
| 05:56:06 | <dmwit> | The memory for memoizing "cycle [1,2,3]" is what, 50 bytes? That's not exactly "a lot". |
| 05:56:11 | <pumpkin> | Vq^: I just wrote a simple program... running in constant space |
| 05:56:28 | <Vq^> | i guess im mistaken then |
| 05:56:31 | <pumpkin> | Vq^: x = cycle [1,2,3] at top level, main = print . length $ x |
| 05:56:43 | <dmwit> | I assume jeff_s_ meant that if you type it into ghci, it loops printing it. |
| 05:57:09 | <dmwit> | Which is true, and I'd be sad if it did anything else. =) |
| 05:57:09 | <Vq^> | or it's some optimization that kicks in for simple programs |
| 05:58:03 | <dmwit> | Optimization? Yes, there's a slight optimization in the source for cycle... |
| 05:58:04 | <dmwit> | ?src cycle |
| 05:58:05 | <lambdabot> | cycle [] = undefined |
| 05:58:05 | <lambdabot> | cycle xs = xs' where xs' = xs ++ xs' |
| 05:58:33 | <dmwit> | That extra name "xs'" is what makes the magic. |
| 06:00:55 | <Vq^> | interesting, i thought x would be stored in pumpkins example, since it shouldn't be recomputed if it's needed again |
| 06:01:03 | <pumpkin> | it is stored |
| 06:01:06 | <pumpkin> | but it's a circular list |
| 06:01:39 | <pumpkin> | now if you did cycle (cycle [1,2,3]) that might be a problem, I think |
| 06:01:43 | <pumpkin> | actually, not even |
| 06:01:56 | <Vq^> | no, that one is the same thing |
| 06:02:10 | <sjanssen> | cycle on an infinite list will leak memory |
| 06:02:25 | <pumpkin> | because the outer call doesn't see the structure of the inner one? |
| 06:03:06 | <dmwit> | sjanssen: I think not this particular infinite list, right? |
| 06:03:19 | <dmwit> | Usually it can leak because we're keeping a reference around to it. |
| 06:03:21 | <Vq^> | i think i get it, it simply doesn't have to construct more data |
| 06:03:25 | <dmwit> | i.e. to the beginning of it. |
| 06:03:36 | <dmwit> | But here that's okay, because the whole damn list is only 50 bytes or so. |
| 06:03:42 | <sjanssen> | dmwit: for any infinite list |
| 06:03:52 | <pumpkin> | yup, definitely problematic :) |
| 06:03:54 | <pumpkin> | I just tried it |
| 06:04:02 | <sjanssen> | pumpkin: yes, the cycle knows nothing about its input |
| 06:05:15 | <dmwit> | Yep, it does seem to be wreaking havoc here. |
| 06:05:33 | <dmwit> | That's odd, and I don't understand it. |
| 06:06:14 | <sjanssen> | dmwit: in "xs' = xs ++ xs'" the end of xs is never reached |
| 06:06:18 | <dmwit> | aah, I do understand it |
| 06:06:25 | <dmwit> | Yeah, that's bad. |
| 06:06:54 | <dmwit> | Well, there's not much you can do about that, I suppose. |
| 06:07:02 | <sjanssen> | right |
| 06:10:26 | <BMeph> | ACTION looks for an interesting article... on Real Anal. Exchange |
| 06:12:51 | <pumpkin> | :o |
| 06:14:49 | <Gracenotes> | BMeph: sorry, it may be too late to use craigslist for that |
| 06:15:49 | <Adamant> | Gracenotes: I was gonna go with a joke about UCSF, but I figured it was borderline bigoted |
| 06:18:12 | <BMeph> | Hmm, rather "Real Analysis Exchange" |
| 06:47:31 | <Baughn> | > (fmap.fmap.fmap |
| 06:47:33 | <lambdabot> | <no location info>: parse error (possibly incorrect indentation) |
| 06:48:34 | <Baughn> | > ((fmap.fmap.fmap) (+) [Just 4,Nothing,Just 5]) 3 |
| 06:48:35 | <lambdabot> | Couldn't match expected type `t -> f (f1 a)' |
| 06:58:58 | <Baughn> | > ((fmap.fmap.fmap) (+3) [Just (+4),Nothing,Just (*5)]) |
| 06:59:00 | <lambdabot> | Overlapping instances for GHC.Show.Show (a -> a) |
| 06:59:00 | <lambdabot> | arising from a use of `... |
| 06:59:18 | <Baughn> | > ((fmap.fmap.fmap) (+3) [Just (+4),Nothing,Just (*5)]) 10 -- Geez, thought it could show those |
| 06:59:19 | <lambdabot> | Couldn't match expected type `t -> f (f1 a)' |
| 06:59:29 | <Baughn> | ACTION groans |
| 06:59:43 | <Baughn> | > ((fmap.fmap.fmap) ($3) [Just (+4),Nothing,Just (*5)]) |
| 06:59:45 | <lambdabot> | No instance for (GHC.Num.Num (a -> b)) |
| 06:59:45 | <lambdabot> | arising from the literal `4' at <... |
| 07:00:25 | <vininim_> | anyone played with attoparsec? |
| 07:03:16 | <Baughn> | > fmap (+2) (+3) 5 |
| 07:03:18 | <lambdabot> | 10 |
| 07:03:39 | <Baughn> | > ((fmap.fmap) (+2) [(+3),(+6)]) 5 |
| 07:03:40 | <lambdabot> | Couldn't match expected type `t -> f a' |
| 07:03:58 | <Baughn> | :t (fmap.fmap) [(+3)] |
| 07:04:00 | <lambdabot> | Couldn't match expected type `a -> b' against inferred type `[a1]' |
| 07:04:00 | <lambdabot> | In the first argument of `(fmap . fmap)', namely `[(+ 3)]' |
| 07:04:00 | <lambdabot> | In the expression: (fmap . fmap) [(+ 3)] |
| 07:04:16 | <pumpkin> | :t (fmap.fmap) (+2) |
| 07:04:17 | <lambdabot> | forall (f :: * -> *) a (f1 :: * -> *). (Functor f, Functor f1, Num a) => f (f1 a) -> f (f1 a) |
| 07:04:43 | <Baughn> | :t (fmap.fmap) (+2) [(+3)] |
| 07:04:44 | <lambdabot> | forall a. (Num a) => [a -> a] |
| 07:04:47 | <pumpkin> | > ((fmap.fmap) (+2) [(+3),(+6)]) <*> [5] |
| 07:04:48 | <lambdabot> | [10,13] |
| 07:04:58 | <Baughn> | :t ((fmap.fmap) (+2) [(+3)]) <*> 6 |
| 07:05:00 | <lambdabot> | forall a. (Num a, Num [a]) => [a] |
| 07:05:03 | <Baughn> | > ((fmap.fmap) (+2) [(+3)]) <*> 6 |
| 07:05:05 | <lambdabot> | No instance for (GHC.Num.Num [a]) |
| 07:05:05 | <lambdabot> | arising from the literal `6' at <inter... |
| 07:05:49 | <Baughn> | Uguuu~ |
| 07:06:10 | <pumpkin> | ? |
| 07:08:24 | <pumpkin> | @pl \x -> map ($x) |
| 07:08:24 | <lambdabot> | map . flip id |
| 07:08:30 | <pumpkin> | @pl \x -> fmap ($x) |
| 07:08:30 | <lambdabot> | fmap . flip id |
| 08:14:31 | <pumpkin> | @type unfoldr |
| 08:14:33 | <lambdabot> | forall b a. (b -> Maybe (a, b)) -> b -> [a] |
| 08:18:01 | <QtPlaty[HireMe]> | Is it correct to say "Function application in haskell is left associative" |
| 08:18:06 | <QtPlaty[HireMe]> | ? |
| 08:21:03 | <fasta> | I am using some functional dependencies, but it appears that type Foo = Double and then depending on Foo gives a different result than directly depending on Double (which does work). Is there some extension which can cause this behaviour? If so, which one? |
| 08:25:34 | <Gracenotes> | QtPlaty[HireMe]: I'd say that. |
| 08:26:17 | <Gracenotes> | in all lambda calculi that I know of |
| 08:26:36 | <Gracenotes> | ...er, and there aren't that many of them, really >_> |
| 08:29:10 | <Gracenotes> | there aren't many other languages where you could say application is associative at all |
| 08:29:36 | <Gracenotes> | hm. |
| 08:33:00 | <Cale> | fasta: That is surprising... |
| 08:33:14 | <Bacta> | @fag can Haskell cure me of my social awkwardness? |
| 08:33:15 | <lambdabot> | The answer is: Yes! Haskell can do that. |
| 08:33:21 | <Bacta> | Awesome! |
| 08:36:10 | <BrokenClockwork> | hey, is there a n-root function in the prelude? :) |
| 08:36:34 | <ziman> | > 27**(1/3) |
| 08:36:35 | <lambdabot> | 3.0 |
| 08:36:53 | <BrokenClockwork> | thanls alot mate |
| 08:36:57 | <ziman> | yw :) |
| 08:42:16 | <fasta> | Cale: I think it was something else. It is solved now, anyway. |
| 08:45:02 | <dancor_> | if i am tracking data length already somewhere else for some binary data, is it still more correct to use (fst <$> newCStringLen x) than (newCString x) |
| 08:59:07 | <fasta> | dancor_: either it is correct or it is not, if you are talking about maintainability and how obviously correct it is, then storing the length and the string in one data structure seems better than to distribute it like you seem to be doing now. |
| 09:05:13 | <dancor_> | fasta: takusen splits it up i guess because postgres accepts the parts in different arguments |
| 09:05:28 | <dancor_> | the postgres c lib |
| 09:05:44 | <mjrosenb> | does rwh cover talking with a database and/or ffi stuff at all? |
| 09:06:18 | <kynky> | thought it did ,but would have to check |
| 09:07:00 | <fasta> | dancor_: and postgres does it that way because the std c lib does it that way. |
| 09:07:25 | <dancor_> | i'm going to go with (fst <$> newCStringLen x). idk if (newCString x) would work. |
| 09:08:04 | <kynky> | ch 7 deals with ffi |
| 09:08:24 | <kynky> | ch21 deals with databases |
| 09:08:46 | <kynky> | ch17 with ffi i mean |
| 09:09:05 | <fasta> | mjrosenb: there are also quite some blog posts on using the FFI. |
| 09:09:26 | <fasta> | mjrosenb: and of course the documentation, which is fairly good. |
| 09:33:28 | <Berengal> | Say you've got a class (Show b) => Foo a b | a -> b, is it possible to constrain b using type families? |
| 09:39:00 | <pumpkin> | Berengal: you mean to replace that fundep with type families? |
| 09:39:53 | <Peaker> | what can type families do that fundeps can't? |
| 09:40:04 | <doserj> | Berengal: in theory, you can do sth. like class (Show b, B a ~ b) => Foo a b where type B a |
| 09:40:14 | <yitz> | Peaker: work well. |
| 09:40:33 | <Peaker> | yitz: ? |
| 09:40:53 | <doserj> | Berengal: but I seem to remember that ghc has some issues with these kind of equality constraints. |
| 09:41:10 | <yitz> | Peaker: it's not clear how the compiler should handle fundeps to make their behavior "unsurprising" to users. |
| 09:41:47 | <Peaker> | yitz: so are they equivalent in power? I thought type families added power |
| 09:43:03 | <yitz> | Peaker: I like the idea of fundeps, but ghc often seems somewhat broken with them. It doesn't seem to be the fault of the ghc team - they seem to be really hard to implement fully. |
| 09:44:03 | <Peaker> | I wonder about the difference in power "in theory" |
| 09:44:07 | <yitz> | Peaker: could be, I don't know, but I haven't run into anything else I need them for in practice. What I said is the reason I like type families. |
| 09:44:45 | <pumpkin> | I've brought this up before, but has anyone thought about "existential typeclass quantification" if that makes sense? |
| 09:44:55 | <pumpkin> | is there a more correct name for that? |
| 09:46:11 | <Peaker> | pumpkin: what do you mean? |
| 09:46:20 | <pumpkin> | well the typical example is generalizing the on function |
| 09:46:26 | <Peaker> | @type on |
| 09:46:27 | <lambdabot> | forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c |
| 09:46:49 | <Peaker> | @type flip on -- nicer |
| 09:46:50 | <lambdabot> | forall b c a. (a -> b) -> (b -> b -> c) -> a -> a -> c |
| 09:46:57 | <pumpkin> | I'm fine with the order :) |
| 09:47:04 | <Peaker> | just as a btw :) |
| 09:47:09 | <pumpkin> | but do you see what I mean? |
| 09:47:12 | <Peaker> | its a double-arg CoFunctor :) |
| 09:47:19 | <Peaker> | nope, not sure -- what is the more general type? |
| 09:47:41 | <Berengal> | For me the main reason to use type families is at the moment readability |
| 09:47:42 | <pumpkin> | well, I can't write it, but it's a typeclass that has a method Class a => a -> b |
| 09:48:09 | <Berengal> | Instead of class Foo a b c d | a -> b c d you get class Foo a where type B a; type C a; type D a |
| 09:48:17 | <yitz> | Peaker: the motivation for the order was things like compare `on` sqrt, which reads nicely in English. Why do you like the oposite order better? |
| 09:48:19 | <pumpkin> | Peaker: so the last two a's in the type of on don't need to be the same... the only important thing is that you have some kind of mapping from each of them to b |
| 09:49:06 | <Peaker> | I'd call it argument2 or bothArgs or something like that |
| 09:49:07 | <pumpkin> | Peaker: and that mapping could be through a typeclass-constrained function |
| 09:49:14 | <Peaker> | sqrt `bothArgs` compare |
| 09:49:47 | <pumpkin> | Peaker: see what I'm saying? |
| 09:50:06 | <Peaker> | pumpkin: ah, I see |
| 09:50:43 | <yitz> | pumpkin: so you want some kind of "uncurried" ***? |
| 09:51:46 | <pumpkin> | something like forallclass C. forall c d. C c, C d => (b -> b -> e) -> (C a => a -> b) -> c -> d -> e |
| 09:51:57 | <pumpkin> | if that makes any sense whatsoever :P |
| 09:52:34 | <Peaker> | pumpkin: trying to find a way to write the type myself, indeed a problem :) |
| 09:53:05 | <yitz> | @type \f g g' x y -> f (g x) (g' y) |
| 09:53:05 | <pumpkin> | it is pretty monstrous :P |
| 09:53:07 | <lambdabot> | forall t t1 t2 t3 t4. (t2 -> t3 -> t4) -> (t -> t2) -> (t1 -> t3) -> t -> t1 -> t4 |
| 09:53:21 | <yitz> | @pl \f g g' x y -> f (g x) (g' y) |
| 09:53:22 | <lambdabot> | ((flip . ((.) .)) .) . (.) |
| 09:53:32 | <pumpkin> | yeah, if you accept that you have two functions, then it's not a problem |
| 09:53:55 | <yitz> | just a little messy |
| 09:53:59 | <pumpkin> | yeah |
| 09:54:49 | <Peaker> | (ia -> ia -> r) -> (? -> ia) -> (ib -> ic -> o) |
| 09:55:19 | <Peaker> | (ia -> ia -> r) -> (forall i. Convertible i ia => i -> ia) -> (ib -> ic -> o) ? |
| 09:55:39 | <Peaker> | class Convertible a b where apply :: a -> b ? |
| 09:55:45 | <yitz> | @type \f g g' -> curry $ uncurry f . (g *** g') |
| 09:55:48 | <lambdabot> | forall a b a1 b1 c. (a1 -> b1 -> c) -> (a -> a1) -> (b -> b1) -> a -> b -> c |
| 09:55:53 | <Peaker> | pumpkin: what about that type? |
| 09:55:54 | <mebbel> | ia -> ia -> fhtagn |
| 09:56:13 | <pumpkin> | Peaker: then you'd need to write a bunch of instances |
| 09:56:21 | <pumpkin> | Peaker: wouldn't you? |
| 09:56:35 | <Berengal> | Where would I find (~)? |
| 09:56:59 | <Peaker> | pumpkin: isn't that inherent? |
| 09:57:14 | <Peaker> | Berengal: I think ~ is a language extension of type families meaning type equality |
| 09:57:19 | <pumpkin> | well, with the forallclass thing I was hoping to exploit existing classes and instances |
| 09:57:41 | <Peaker> | pumpkin: call any random class method to convert? |
| 09:57:42 | <pumpkin> | but I guess if more than one worked, you'd have to choose which one somehow |
| 09:57:44 | <pumpkin> | :P |
| 09:57:49 | <pumpkin> | which would be ugly |
| 09:58:02 | <mebbel> | forget the type; how would you write the function body? |
| 09:58:08 | <pumpkin> | hmm, maybe not such a good idea :) |
| 09:58:10 | <pumpkin> | mebbel: not a clue :P |
| 09:58:25 | <Peaker> | pumpkin: oh, I see what you mean now |
| 09:58:46 | <pumpkin> | probably not a very good idea now that I've gone over it more :) |
| 09:58:47 | <Peaker> | something like: (ia -> ia -> r) -> (forall i. i -> ia) -> (ib -> ic -> o) -- except you want i to just be as polymorphic as necessary and not fully polymorphic |
| 09:59:24 | <Peaker> | so that there should be (forall i. all_restrictions_that_still_catch ib and ic ...) |
| 09:59:31 | <pumpkin> | sort of, yeah :) |
| 09:59:41 | <Peaker> | or maybe (Either ib ic -> ia) :) |
| 10:00:10 | <Peaker> | heh, in the case of wanting to catch just a finite set of types, I guess the best way is just to provide a finite set of functions |
| 10:00:43 | <Peaker> | > (show *** show) (1, 2) |
| 10:00:44 | <lambdabot> | ("1","2") |
| 10:00:49 | <Peaker> | > (show *** show) (1, 'c') |
| 10:00:51 | <lambdabot> | ("1","'c'") |
| 10:01:02 | <Peaker> | @let both = join (***) |
| 10:01:03 | <lambdabot> | Defined. |
| 10:01:08 | <Peaker> | > both show (1, 'c') |
| 10:01:09 | <lambdabot> | No instance for (GHC.Num.Num GHC.Types.Char) |
| 10:01:09 | <lambdabot> | arising from the literal `1... |
| 10:01:10 | <pumpkin> | yeah :/ |
| 10:01:23 | <pumpkin> | what's with lambdabot spitting out low-level types in its errors now? |
| 10:01:36 | <Peaker> | so it may be a little weird to use (show *** show) instead of join (***) show... working around type system weakness |
| 10:02:02 | <Peaker> | @type join (***) |
| 10:02:03 | <lambdabot> | forall (a :: * -> * -> *) b c. (Arrow a) => a b c -> a (b, b) (c, c) |
| 10:02:52 | <pumpkin> | what would have to change to make join (***) as polymorphic as (f *** f) ? the whole monomorphic function application thing? |
| 10:03:15 | <pumpkin> | because even \f -> (f *** f) would be equivalent to join (***) I think? |
| 10:03:20 | <Peaker> | It is equivalent |
| 10:03:42 | <Peaker> | now I understand what dolio (I think it was him) said about let binding and argument binding having different type restriction |
| 10:03:59 | <Peaker> | let show = ... -- show is polymorphically typed whereas \f -> (f *** f) -- f is singly-typed |
| 10:04:07 | <pumpkin> | yup |
| 10:04:23 | <pumpkin> | @let showBoth = (show *** show) |
| 10:04:24 | <lambdabot> | Defined. |
| 10:04:26 | <pumpkin> | :t showBoth |
| 10:04:27 | <lambdabot> | forall b b'. (Show b, Show b') => (b, b') -> (String, String) |
| 10:04:36 | <hackagebot> | fclabels 0.1.2 |
| 10:05:31 | <pumpkin> | I guess that's a pretty fundamental aspect of the language |
| 10:05:44 | <pumpkin> | and changing it would have all sorts of nasty effects |
| 10:05:50 | <Peaker> | pumpkin: if arguments had been polymorphic, then they could not be unified with anything |
| 10:05:53 | <Peaker> | I think |
| 10:06:09 | <Berengal> | class (Show b, B a ~ b) => Foo a where type B a -- doesn't work :( |
| 10:06:18 | <Peaker> | I mean, the type of \x -> (x,x) would not have been a -> (a, a) |
| 10:06:25 | <pumpkin> | yeah :) |
| 10:06:29 | <pumpkin> | it'd be a big mess |
| 10:06:59 | <doserj> | Berengal: class (Show b, B a ~ b) => Foo a b where type B a |
| 10:07:00 | <pumpkin> | I've often wanted that function by the way |
| 10:07:07 | <pumpkin> | should be called duplicate or something |
| 10:07:15 | <pumpkin> | in Control.Arrow, maybe, as an arrow |
| 10:07:18 | <doserj> | Berengal: Foo needs both a and b as parameter |
| 10:07:19 | <pumpkin> | along with both |
| 10:07:29 | <Berengal> | doserj: Yes, but it shouldn't be neccessary to have b as a parameter |
| 10:07:43 | <doserj> | Berengal: if you want to constrain it, it has to |
| 10:07:53 | <pumpkin> | you want some sort of existential b? |
| 10:08:10 | <Peaker> | pumpkin: call it both |
| 10:08:17 | <Peaker> | pumpkin: in consistency with first and second |
| 10:08:20 | <Berengal> | pumpkin: Yes |
| 10:08:27 | <pumpkin> | PeakerWork: I'd want both to be first f >>> second f or something |
| 10:08:47 | <Peaker> | @type \f -> first f >>> second f |
| 10:08:48 | <lambdabot> | forall (cat :: * -> * -> *) b c. (Arrow cat) => cat b c -> cat (b, b) (c, c) |
| 10:08:49 | <pumpkin> | as first and second apply functions to pairs |
| 10:08:56 | <Peaker> | @type \f -> join (***) |
| 10:08:57 | <yitz> | pumpkin: it already exists. it's called join. |
| 10:08:57 | <lambdabot> | forall t (a :: * -> * -> *) b c. (Arrow a) => t -> a b c -> a (b, b) (c, c) |
| 10:08:59 | <Peaker> | oops |
| 10:09:02 | <Peaker> | @type join (***) |
| 10:09:03 | <lambdabot> | forall (a :: * -> * -> *) b c. (Arrow a) => a b c -> a (b, b) (c, c) |
| 10:09:08 | <pumpkin> | yeah, I know :) |
| 10:09:13 | <pumpkin> | I use that all the time, but I think it should be named |
| 10:09:29 | <Peaker> | pumpkin: I mean both = join (***) = first f >>> second f |
| 10:09:34 | <pumpkin> | yeah, I know |
| 10:09:36 | <yitz> | @type join (,) |
| 10:09:38 | <lambdabot> | forall a. a -> (a, a) |
| 10:10:00 | <pumpkin> | I was just going to define it in terms of first and second to be more explicit about the ordering (as the functions in Arrow tend to do) |
| 10:10:06 | <pumpkin> | but yeah, that works too |
| 10:10:09 | <yitz> | of course (,) is just sugar for curry id |
| 10:10:39 | <pumpkin> | :t curry id |
| 10:10:41 | <lambdabot> | forall a b. a -> b -> (a, b) |
| 10:10:58 | <pumpkin> | I've never found myself using curry much |
| 10:11:06 | <pumpkin> | I guess not many functions take pairs |
| 10:11:33 | <pumpkin> | ick, the sun is coming up |
| 10:11:39 | <yitz> | pumpkin: I guess you're not into indian cuisine |
| 10:11:49 | <pumpkin> | I actually make curry a lot :) |
| 10:11:57 | <pumpkin> | I love cooking |
| 10:12:04 | <Peaker> | pumpkin: uncurry is useful though |
| 10:12:10 | <pumpkin> | oh yeah, I use that all the time |
| 10:12:25 | <pumpkin> | especially with the arrow functions |
| 10:15:27 | <pumpkin> | alright, bedtime |
| 10:27:44 | <Fred320> | @src nub |
| 10:27:44 | <lambdabot> | nub = nubBy (==) |
| 10:27:51 | <Fred320> | @src nubBy |
| 10:27:51 | <lambdabot> | nubBy eq [] = [] |
| 10:27:52 | <lambdabot> | nubBy eq (x:xs) = x : nubBy eq (filter (\ y -> not (eq x y)) xs) |
| 10:28:36 | <Fred320> | @pl \ y -> not (eq x y) |
| 10:28:37 | <lambdabot> | not . eq x |
| 10:28:37 | <dev312> | Hi, I have a question that may just indicate my lack of experience. |
| 10:28:53 | <dev312> | If I have a return type of a function, that is wrapped in a monad, how can I get direct access to the data? |
| 10:29:04 | <dev312> | or is that not possible, like private variables in a class in OO languages? |
| 10:29:19 | <mebbel> | dev312: what data? |
| 10:29:20 | <yitz> | hmm... the haskell platform contents page just links to the current hackage page for each package. how do you see at a glance exactly which version of each package is included in a specific HP version? |
| 10:29:34 | <QtPlaty[HireMe]> | dev312: Something liike IO Foo? |
| 10:29:36 | <pumpkin> | dev312: it's not always meaningful, as not all monads "contain" data |
| 10:29:52 | <dev312> | It is of the CGI module... getVars..it returns (MonadCGI m)=> m ( [(String,String)] ) |
| 10:29:56 | <Peaker> | how hard would it be for ghci to allow data declarations? |
| 10:29:59 | <mebbel> | and then you say "the x in M x" and then I say "that's just a type, not data" |
| 10:30:07 | <Zao> | pumpkin: The Id monad? :) |
| 10:30:14 | <mebbel> | and then I tell you how "<-" in a do block is a virtual unwrap |
| 10:30:29 | <Peaker> | dev312: you can access the data directly in a monad, but only in a computation that is itself also in the monad.. |
| 10:30:40 | <dev312> | I see. |
| 10:31:13 | <dev312> | So I would have to create my own monad, then can somehow release the data after combining with this monad? |
| 10:31:18 | <dev312> | Or am I still on the wrong track? |
| 10:31:21 | <Peaker> | dev312: if you have an Monad m =>(m a) which is an "a wrapped in a Monad m", then you can use >>= to access the "a" but your result will be an "m b" |
| 10:31:24 | <dev312> | is the fact that I can never just have a plain list? |
| 10:31:34 | <dev312> | ahh ok |
| 10:31:54 | <Peaker> | dev312: note that its all the same monad type, no mixing of different monads here, just different values of the same monad-type |
| 10:32:06 | <dev312> | ok :( |
| 10:32:07 | <dev312> | gotcha |
| 10:32:09 | <dev312> | makes sense |
| 10:32:55 | <foobaer> | i don't know the CGI monad, but often you start a monad computation with a runFoo function and this function also returns the result of the monad computation unwrapped |
| 10:32:59 | <yitz> | pumpkin: go to sleep, otherwise you'll be sorry later |
| 10:33:08 | <Peaker> | dev312: you can think of a monad as a description of some "special" computation -- you can only access the value, which is namely to "sequence another same-special computation on top of the existing one" |
| 10:33:13 | <pumpkin> | yeah :( |
| 10:33:27 | <pumpkin> | sleep feels like such a waste of time, even though I know it isn't |
| 10:33:45 | <dev312> | PEaker, ok thanks..that makes sense |
| 10:33:56 | <dev312> | I guess it is better for me not to be able to mess with the internals anyway |
| 10:34:32 | <Peaker> | dev312: What do you mean by "mess with the internals"? |
| 10:34:33 | <dev312> | That being said, if the writer of a Monad wanted to provied a convenience function to get data out of a monad, they could |
| 10:34:34 | <dev312> | ? |
| 10:34:44 | <mebbel> | depends on the monad |
| 10:34:45 | <Peaker> | dev312: No, the whole point of the Monad is that there's no escaping it |
| 10:34:55 | <mebbel> | Peaker: I strongly disagree |
| 10:34:56 | <dev312> | Well, flatly, so it is understood what I am saying, I just want the list |
| 10:35:04 | <Peaker> | well, not the whole point, one of the points :-) |
| 10:35:07 | <dev312> | I want to discard the monad and just have the list that it contains |
| 10:35:10 | <mebbel> | I still disagree |
| 10:35:15 | <yottis> | but that's exactly what those run*, exec* and eval* functions do |
| 10:35:22 | <mebbel> | dev312: >>= |
| 10:35:40 | <Peaker> | dev312: First, you should understand that Monad is just a type-class, or a "common interface" that various types provide an implementation for. Each type may provide any extra functions specific to that type in addition to the monad interface |
| 10:35:45 | <yottis> | there's just not anything that works for all monads, but nothing prevents you from creating one for a particular instance |
| 10:35:46 | <foobaer> | Peaker: what about the Maybe monad. there you can escape :) |
| 10:35:50 | <dev312> | hmm ok mebbel |
| 10:35:53 | <dev312> | let me check that out |
| 10:35:53 | <Peaker> | dev312: so some types may provide the Monad interface AND a way to exit the monad, but the Monad interface itself provides no such way |
| 10:35:58 | <Peaker> | foobaer: what if its Nothing? |
| 10:36:10 | <foobaer> | Peaker, well you have to check it of couse |
| 10:36:15 | <doserj> | dev312: I guess "<-" in a do-block is what you want |
| 10:36:24 | <pumpkin> | some monads you can escape from reliably, like ST |
| 10:36:28 | <Peaker> | dev312: If you want to write code that is *general* to all monads, you can't even assume that there's actually a list of values "in" it |
| 10:36:37 | <dcoutts> | yitz: what was the HP question? |
| 10:36:52 | <mebbel> | data W a = W; instance Monad W where return _ = W; W >>= _ = W |
| 10:37:05 | <dev312> | Peaker, I understand |
| 10:37:11 | <dev312> | I understand that not all monads are the same |
| 10:37:16 | <dev312> | and not all monads are "containers" |
| 10:37:17 | <dev312> | etc |
| 10:37:20 | <pumpkin> | class EscapableMonad m where escape :: m a -> a |
| 10:37:24 | <dev312> | Well I do now |
| 10:37:26 | <dev312> | anyway |
| 10:37:42 | <pumpkin> | Comonad |
| 10:39:25 | <Peaker> | dev312: anyway - remember that Monad is just an "interface" that you can program with to get generality of your code -- generality always means you can assume less. In the case of Monads, you can only assume that you can "sequence computations". Once you use a specific type, you can assume much more |
| 10:40:03 | <Peaker> | dev312: Its probably better to first understand Functor, then Applicative, then Monads, because they form natural extensions of each other, and Monads are the most complicated |
| 10:40:23 | <dev312> | ok, well yeah functors I have an understanding of |
| 10:40:29 | <dev312> | and even Monads, to a degree |
| 10:40:36 | <Peaker> | dev312: Well, how do you "exit" a Functor? |
| 10:40:42 | <Peaker> | dev312: how do you extract the value from a Functor? |
| 10:40:44 | <dev312> | What I am probably doing is wrong is simply not being ablt to find the proper convenience functions in this library |
| 10:40:57 | <dev312> | Right, being tested now. |
| 10:41:03 | <dev312> | Ill pass, no pun intended. |
| 10:42:43 | <Peaker> | dev312: I want to help you understand Monad by understanding the class hierarchy above it |
| 10:55:32 | <Berengal> | Success! |
| 10:55:45 | <Berengal> | class (Show (B b)) => Foo b where type B b :: * |
| 10:57:18 | <dev312> | ok Peaker, I have decided to slow down and study Applicative functors. |
| 10:57:37 | <dev312> | Not that this will solve my problem, but I do agree, in principle , it is best to understand fundamentals |
| 11:07:51 | <yitz> | dcoutts: hmm... the haskell platform contents page just links to the current hackage page for each package. how do you see at a glance exactly which version of each package is included in a specific HP version? |
| 11:07:59 | <yitz> | dcoutts: hmm... the haskell platform contents page just links to the current hackage page for each package. how do you see at a glance exactly which version of each package is included in a specific HP version? |
| 11:09:24 | <dcoutts> | http://hackage.haskell.org/platform/2009.2.0/haskell-platform.cabal |
| 11:09:45 | <dcoutts> | yitz: yeah the package list should say, but it's also in the .cabal file for the platform meta-package |
| 11:10:03 | <yitz> | I see. thanks. |
| 11:10:58 | <araujo> | ACTION just released new himerge version1 |
| 11:11:03 | <araujo> | ! |
| 11:13:05 | <yitz> | araujo: link? |
| 11:14:41 | <araujo> | @where himerge |
| 11:14:41 | <lambdabot> | http://www.haskell.org/~luisfaraujo/himerge/ |
| 11:14:45 | <araujo> | err |
| 11:14:51 | <araujo> | www.haskell.org/himerge |
| 11:14:54 | <araujo> | that one |
| 11:15:39 | <yitz> | araujo: nice! |
| 11:16:02 | <araujo> | :D |
| 11:16:07 | <yitz> | araujo: that page makes it look like himerge is only for haskell users |
| 11:16:11 | <mebbel> | @where+ himerge http://www.haskell.org/himerge/ |
| 11:16:12 | <lambdabot> | It is forever etched in my memory. |
| 11:16:29 | <yitz> | araujo: but in reality I'll bet it's userful for all gentoo users |
| 11:16:32 | <yitz> | useful |
| 11:16:34 | <araujo> | yitz, think so? ... why? |
| 11:16:45 | <araujo> | yeah, I know many gentoo users in general using it |
| 11:17:07 | <araujo> | I like when people who don't even know haskell use it :) |
| 11:17:18 | <araujo> | we needm or of those types around |
| 11:17:24 | <araujo> | more* |
| 11:18:12 | <yitz> | araujo: maybe you should just write at the bottom that it is implemented in haskell/gtk2hs, where it says Himerge is Free Software... |
| 11:18:39 | <mebbel> | "Himerge is a graphical user interface (GUI) for the Gentoo portage system written entirely on Haskell using the Gtk2Hs library." <- looks fine to me |
| 11:18:50 | <yitz> | araujo: so you won't scare away any haskephobics :) |
| 11:19:05 | <araujo> | yeah, it is explained in the first paragraph ... it is indeed an important thing to miss |
| 11:19:51 | <araujo> | yitz, my experience (luckily?) has been the opposite ... many of them seem curious about it and at least give it a try |
| 11:19:56 | <yitz> | mebbel: if it were written in C using gtk+, you wouldn't mention that in the first paragraph. possibly not at all on the front page |
| 11:20:05 | <araujo> | when they know what haskell is |
| 11:20:23 | <mebbel> | yitz: yes, I would |
| 11:20:53 | <yitz> | ok, i guess it's a matter of style |
| 11:20:57 | <araujo> | ACTION likes that kind of information at first if possible |
| 11:21:35 | <araujo> | yeah, i guess it is a matter of design and how the developer tries to reach the community |
| 11:22:02 | <araujo> | in my case with himerge, I wanted to show Haskell can indeed be used for daily GUI apps |
| 11:22:12 | <araujo> | so the language is written is very important |
| 11:22:17 | <yitz> | araujo: yeah, that's really great! |
| 11:22:29 | <yitz> | araujo: though I would like it to become unsurprising |
| 11:22:44 | <araujo> | unsurprising? |
| 11:23:00 | <yitz> | araujo: that you really can write a nice gui app easily in haskell |
| 11:23:29 | <Peaker> | Haskell is a fine imperative language too :) |
| 11:23:36 | <araujo> | yitz, yeah, you can! |
| 11:23:48 | <araujo> | Himerge's main purpose is to show that actually |
| 11:24:05 | <yitz> | Peaker: ok, ok, it will be even better once the reactive stuff becomes more mature |
| 11:24:46 | <yitz> | I hope that will be soon |
| 11:25:16 | <Peaker> | yitz: Baughn is helping with unamb now, and I think there aren't many bugs left in there |
| 11:25:23 | <yitz> | great! |
| 11:25:25 | <Peaker> | yitz: someone needs to debug why joinE doesn't work |
| 11:25:27 | <mebbel> | heh |
| 11:25:29 | <Peaker> | I wish I had some time |
| 11:25:51 | <mebbel> | "I think there aren't many bugs left in there" <- famous last words |
| 11:26:23 | <yitz> | mebbel: Fermat once said something along those lines. |
| 11:26:47 | <yitz> | they did get it debugged eventually though. |
| 11:26:56 | <mebbel> | haha |
| 11:27:26 | <mebbel> | imagine writing a program that takes 400 years to debug |
| 11:31:39 | <Axman6> | anyone know who Arnaud Payement is? |
| 11:37:01 | <myst> | ACTION is listening Lacrimosa - I lost my star in Krasnodar [Sehnsucht, 2009] |
| 11:38:08 | <Axman6> | wow, never seen now playing spam in #haskell before |
| 11:38:10 | <cob_jonas> | myst++ after that line the name Arnaud Payement doesn't look so strange |
| 11:38:50 | <myst> | sorry guys it was a test |
| 11:40:17 | <Berengal> | I like it when code just works. I like haskell |
| 11:42:21 | <araujo> | :) |
| 11:43:06 | <Berengal> | I was writing some java at work today, when suddenly a bug attacked. I was actually shocked, because the code compiled just fine |
| 11:43:19 | <HugoDaniel> | hi |
| 11:43:36 | <Berengal> | Hello |
| 11:43:46 | <kynky> | run time error vs compile time error ? |
| 11:43:49 | <Baughn> | yitz: NEar as I can tell,there are no bugs in my last version of unamb |
| 11:44:02 | <Baughn> | yitz: I'm now working on performance, via RTS hacks |
| 11:44:07 | <Berengal> | kynky: Not an "error" as such, just garbage execution |
| 11:44:11 | <cob_jonas> | it's not like that's impossible in haskell either, only much rarer |
| 11:44:20 | <Baughn> | p_l: while true; do mkdir a; cd a; done |
| 11:44:22 | <yitz> | Well, here is Arnaud Payement's thesis (master's?) at Oxford: http://progtools.comlab.ox.ac.uk/projects/jungl/resources/arnaud_msc_thesis.pdf |
| 11:45:03 | <cob_jonas> | Baughn: that's evil |
| 11:45:11 | <yitz> | He acknowledges his advisor Oege de Moor, and Mathieu Verbaere. |
| 11:45:22 | <cob_jonas> | Baughn: if you do it a tricky way you can even get an undeletable directory that way |
| 11:45:32 | <Baughn> | cob_jonas: How's that? |
| 11:45:45 | <cob_jonas> | Baughn: depends on what system you're on |
| 11:45:50 | <cob_jonas> | on DOS it's definitely possible |
| 11:45:52 | <Baughn> | Linux, so no directory hardlinks. |
| 11:46:08 | <Peaker> | Berengal: :) |
| 11:46:21 | <cob_jonas> | Baughn: you can have bind mounts or just plain remount an fs to a longer mount path |
| 11:46:27 | <Peaker> | Berengal: I find that FP Haskell code "Just works" and that imperative Haskell code still has some bugs fly through |
| 11:46:32 | <yitz> | Baughn: glad to hear about the progress. |
| 11:46:46 | <cob_jonas> | I'm not sure if you can do this in linux though |
| 11:47:03 | <Baughn> | yitz: Beyond that, the reactive Monad instance is badly broken, and unfortunately it's used all over the place. |
| 11:47:04 | <cob_jonas> | maybe if you're tricky you could get one you can't delete because you don't have enough memory or something |
| 11:47:06 | <hackagebot> | storable-record 0.0.1 |
| 11:47:09 | <cob_jonas> | but I doubt |
| 11:47:20 | <Baughn> | yitz: That said, fixing unamb fixes quite a lot of its issues. :) |
| 11:47:24 | <yitz> | Baughn: that's pretty fundamental |
| 11:47:26 | <Baughn> | yitz: (Most notably the deadlocks) |
| 11:47:30 | <HugoDaniel> | is there anything similar to assembly in haskell ? |
| 11:47:34 | <Berengal> | Peaker: Yeah, that's my experience as well. |
| 11:47:38 | <cob_jonas> | HugoDaniel: in what way? |
| 11:47:42 | <Baughn> | HugoDaniel: C? |
| 11:47:54 | <yitz> | the Monad instance is in some ways the most important contribution |
| 11:48:02 | <EvilTerran> | HugoDaniel, there's core, being the intermediate language a compiler uses |
| 11:48:10 | <EvilTerran> | HugoDaniel, (but that varies from compiler to compiler) |
| 11:48:19 | <Peaker> | yitz: the Monad instance of what? |
| 11:48:30 | <yitz> | reactive |
| 11:48:42 | <Berengal> | Peaker: But that's still much better than languages where everything is imperative |
| 11:48:43 | <cob_jonas> | also in dos you can have a directory in which you can only put files of short names |
| 11:48:47 | <cob_jonas> | which is a bit funny |
| 11:48:54 | <Peaker> | Berengal: and the imperative part is far more powerful |
| 11:49:20 | <Berengal> | Peaker: The imperative part is like perl on crack |
| 11:50:04 | <HugoDaniel> | hmm |
| 11:50:05 | <yitz> | cob_jonas: ever mount an old dos partition on linux? it's also really weird. |
| 11:50:10 | <FunctorSalad> | hmm... are you not supposed to use stream-fusion/Data.Stream manually? |
| 11:50:14 | <HugoDaniel> | anyone up to coding an "Assembly Monad" in haskell ? |
| 11:50:27 | <Berengal> | HugoDaniel: It's been done |
| 11:50:28 | <yitz> | FunctorSalad: why not? |
| 11:50:32 | <mebbel> | HugoDaniel: what, like harpy? |
| 11:50:33 | <HugoDaniel> | Berengal: where ? |
| 11:50:46 | <cob_jonas> | yitz: I have. I had to to set up the virtual machine with dos. |
| 11:50:53 | <FunctorSalad> | yitz: I tried rewriting the meteor benchmark to use streams directly, and got ~30x slowdown :-( |
| 11:50:58 | <Berengal> | HugoDaniel: http://www.haskell.org/sitewiki/images/1/14/TMR-Issue6.pdf |
| 11:51:00 | <cob_jonas> | but it's not so bad as mounting them from dos |
| 11:51:04 | <FunctorSalad> | yitz: with most of the time lost in concatMap |
| 11:51:25 | <yitz> | FunctorSalad: does sound like you're losing your fusion. |
| 11:51:35 | <cob_jonas> | where depending on what codepage you loaded with mode, you can use different characters in filenames (and the case mapping is different too) so you can have files you can't delete |
| 11:51:38 | <yitz> | FunctorSalad: look over dons' blog about it |
| 11:52:39 | <yitz> | cob_jonas: unmount; format should do the trick |
| 11:53:00 | <cob_jonas> | yitz: sure, but it's easier to just rename them with norton utilities disk editor |
| 11:53:10 | <yitz> | hehe |
| 11:53:14 | <HugoDaniel> | allright, harpy seems like the right tool to use and abuse :D |
| 11:53:19 | <cob_jonas> | or to mount in linux and rename from there |
| 11:53:55 | <FunctorSalad> | yitz: there is a lot of commented out stuff about concatMap, I guess there's still some problem with it? |
| 11:54:11 | <cob_jonas> | or there's some of those fsck utilities (there are like three for dos, each having a slightly different idea about what's valid on fat and what isn't) |
| 11:54:37 | <FunctorSalad> | of course, maybe it's my fault and I blocked the fusion somehow |
| 11:55:16 | <yitz> | cob_jonas: in short: what a mess |
| 11:56:13 | <yitz> | FunctorSalad: don't know. but if you look at the core and experiment, you should be able to figure it out. |
| 11:56:50 | <FunctorSalad> | is there some ghc flag you need to set apart from -O2? |
| 11:57:54 | <Berengal> | @djinn (a -> (b -> c)) -> (a -> b) -> a -> c |
| 11:57:54 | <lambdabot> | f a b c = a c (b c) |
| 11:58:02 | <Berengal> | Hmmm, S |
| 11:58:20 | <Berengal> | I should've gotten that from the type... |
| 11:59:12 | <joeally> | Is anyone familiar to project euler |
| 11:59:29 | <mib_e7tcavos> | hey |
| 11:59:40 | <mib_e7tcavos> | wondering if anyone can help me |
| 11:59:58 | <joeally> | I'll try but i am a noob myself |
| 12:00:01 | <mib_e7tcavos> | gt a slight problem with some code |
| 12:00:28 | <joeally> | okay.. |
| 12:00:47 | <EvilTerran> | mib_e7tcavos, don't ask to ask, just ask; we don't know if we can help you 'til you tell us what the problem is. |
| 12:00:56 | <mib_e7tcavos> | kl |
| 12:01:18 | <mib_e7tcavos> | gt an algebraic type i blieve |
| 12:01:29 | <mib_e7tcavos> | data Film = Film Title Director Year [Fans] |
| 12:02:13 | <mib_e7tcavos> | exampleFilms :: [Film] |
| 12:02:30 | <mib_e7tcavos> | exampleFilms = [(Film "Blade Runner" "Ridley Scott" 1982 ["Garry", "Dave", "Zoe"])] |
| 12:02:43 | <mib_e7tcavos> | so i have a list of films |
| 12:03:02 | <mib_e7tcavos> | now im trying to add a film |
| 12:03:13 | <mib_e7tcavos> | addFilm :: Title -> Director -> Year -> [Film] -> [Film] |
| 12:03:24 | <mib_e7tcavos> | addFilm ti di ye film = film ++ [(Film ti di ye [])] |
| 12:03:33 | <mib_e7tcavos> | ive compiled |
| 12:03:49 | <mib_e7tcavos> | and it tells me it doesnt have a show function |
| 12:03:52 | <mib_e7tcavos> | any ideas? |
| 12:04:06 | <cob_jonas> | what it says |
| 12:04:09 | <mebbel> | yeah, data Film = Film Title Director Year [Fans] deriving (Show) |
| 12:04:41 | <mebbel> | looks like your code is fine, it just doesn't know how to print the results |
| 12:04:53 | <mib_e7tcavos> | oh so i just put deriving show when im declaring |
| 12:04:57 | <Neut> | using a list comprehension, how would I define a function which does this, |
| 12:05:02 | <mebbel> | yes |
| 12:05:12 | <Neut> | matches 1 [1,2,4,2,1,2] ~~ [1,1] |
| 12:05:14 | <mib_e7tcavos> | awesome |
| 12:05:20 | <mib_e7tcavos> | thanks for the help |
| 12:05:44 | <mebbel> | matches k xs = [x | x <- xs, x == k] |
| 12:05:46 | <Axman6> | \y xs -> [ x | x <- xs, x == y] |
| 12:05:54 | <Berengal> | Neut: matches n l = [e | e <- l, n == e] |
| 12:06:28 | <mebbel> | spot the non-idiomatic haskeller :-) |
| 12:06:59 | <yitz> | > let matches k xs = [x | x <- xs, x == k] in matches 1 [1,2,4,2,1,2] |
| 12:07:00 | <lambdabot> | [1,1] |
| 12:07:02 | <Neut> | thanks |
| 12:08:01 | <cob_jonas> | is that just matches m = filter (m ==) |
| 12:08:08 | <Axman6> | yah |
| 12:08:13 | <Berengal> | @type filter <$> (==) |
| 12:08:14 | <lambdabot> | forall a. (Eq a) => a -> [a] -> [a] |
| 12:08:34 | <Berengal> | > let matches = filter <$> (==) in matches 1 [1,2,4,2,1,2] |
| 12:08:34 | <yitz> | @type filter . (==) |
| 12:08:35 | <lambdabot> | [1,1] |
| 12:08:36 | <lambdabot> | forall a. (Eq a) => a -> [a] -> [a] |
| 12:09:13 | <yitz> | @pl matches k xs = [x | x <- xs, x == k] |
| 12:09:14 | <lambdabot> | matches = flip ((:) . ((x | x) <-)) . return . (x ==) |
| 12:09:19 | <yitz> | hehe |
| 12:09:39 | <Axman6> | ha |
| 12:09:59 | <yitz> | where do you file a bug against @pl ? |
| 12:10:01 | <cob_jonas> | let's write it with guard |
| 12:10:09 | <Axman6> | @undo matches k xs = [x | x <- xs, x == k] |
| 12:10:10 | <lambdabot> | matches k xs = concatMap (\ x -> if x == k then [x] else []) xs |
| 12:10:22 | <Axman6> | @. pl undo matches k xs = [x | x <- xs, x == k] |
| 12:10:22 | <zachk> | joeally: yea im on euler, im up to problem 14, none of your haskell programs should reall go over like 60 lines |
| 12:10:23 | <lambdabot> | matches = (=<<) . flip flip [] . (`ap` return) . (if' .) . (==) |
| 12:10:38 | <yitz> | ah, much better |
| 12:10:56 | <zachk> | joeally: though ive been at haskell for a year, ive seen people take 30 lines of my code and drop it down to one line of code, a year latter its one function in Data.List |
| 12:12:24 | <wli> | ACTION is having really bad luck with project euler. |
| 12:12:50 | <Neut> | using comprehensions again, |
| 12:12:55 | <Neut> | how would I define a function wihch |
| 12:13:10 | <yitz> | ACTION had fun for the first 100 or so, then it started getting tedious |
| 12:13:22 | <Neut> | addPairwise [1,7] [8,4,2] ~~ [9,11] |
| 12:13:34 | <wli> | ACTION is just too dumb to solve many of them. |
| 12:13:36 | <yitz> | Neut: try it yourself first |
| 12:13:58 | <Berengal> | ACTION would just zipWith (+) |
| 12:14:04 | <Neut> | yeah I have, but I can't work it out which is why I have jumped on IRC |
| 12:14:10 | <mebbel> | Neut: not possible in H98 |
| 12:14:15 | <mebbel> | that needs an extension |
| 12:14:16 | <Berengal> | mebbel: Sure it is |
| 12:14:20 | <wli> | The few I can solve often have unacceptably slow solutions. |
| 12:14:27 | <mebbel> | Berengal: zip doesn't count |
| 12:14:31 | <Axman6> | > zipWith (+) [1,7] [8,4,2] |
| 12:14:32 | <lambdabot> | [9,11] |
| 12:14:35 | <Berengal> | mebbel: Sure it does |
| 12:14:37 | <yitz> | Neut: what have you tried? |
| 12:14:53 | <burp> | uh, how does zipWith work with unequal sized lists? |
| 12:15:03 | <yitz> | burp: it just quits |
| 12:15:10 | <yitz> | after one runs out |
| 12:15:11 | <Neut> | [m + n | (m,n) <- zip list1 list2] |
| 12:15:12 | <wli> | e.g. the fastest multiplication thing |
| 12:15:12 | <Axman6> | @src zipWith |
| 12:15:12 | <lambdabot> | zipWith f (a:as) (b:bs) = f a b : zipWith f as bs |
| 12:15:13 | <lambdabot> | zipWith _ _ _ = [] |
| 12:15:20 | <burp> | ah I see |
| 12:15:25 | <Berengal> | > let addPairwise xs ys = [r | r <- zipWith (+) xs ys] in addPairwise [1,7] [8,4,2] -- :P |
| 12:15:26 | <lambdabot> | [9,11] |
| 12:15:45 | <yitz> | Neut: that looks good. try it here with lambdabot |
| 12:16:01 | <Axman6> | > [x + y | x <- [1,7] | y <- [8,4,2]] |
| 12:16:03 | <lambdabot> | [9,11] |
| 12:16:06 | <Axman6> | whoot |
| 12:16:12 | <Neut> | >let addPairwise' = [m + n | (m,n) <- zip list1 list2] |
| 12:16:20 | <yitz> | Axman6: that's not H98 though. |
| 12:16:24 | <mebbel> | Berengal: then so does [x | x <- zipWith (+) xs ys] |
| 12:16:24 | <Axman6> | ah |
| 12:16:35 | <yitz> | Neut: you need a space after the > |
| 12:16:41 | <Neut> | kk thanks |
| 12:16:45 | <Neut> | > let addPairwise' = [m + n | (m,n) <- zip list1 list2] |
| 12:16:46 | <Berengal> | mebbel: Huh? |
| 12:16:47 | <lambdabot> | not an expression: `let addPairwise' = [m + n | (m,n) <- zip list1 list2]' |
| 12:17:45 | <yitz> | Neut: put list1 and list2 as parameters after the function name. then put "in ..." at the end to try out your function with an example. |
| 12:17:47 | <cob_jonas> | > let { addPairwise' = [m + n | (m,n) <- zip list1 list2] } in addPairwise' [1,7] [8,4,2] |
| 12:17:47 | <lambdabot> | Not in scope: `list1'Not in scope: `list2' |
| 12:17:56 | <Axman6> | > let addPairwise' list1 list2 = [m + n | (m,n) <- zip list1 list2] in addPairwise' [1,7] [8,4,2] |
| 12:17:57 | <lambdabot> | [9,11] |
| 12:18:06 | <Neut> | ooo works |
| 12:18:08 | <Neut> | thanks |
| 12:18:52 | <Ferdirand> | > let addPairwise = zipWith (+) in addPairwise [1,7] [8,4,2] |
| 12:18:54 | <lambdabot> | [9,11] |
| 12:19:20 | <Neut> | yeah I know there are higher order functions for it, |
| 12:19:26 | <Berengal> | > getZipList $ (+) <$> ZipList [1,7] <*> ZipList [8,4,2] |
| 12:19:27 | <lambdabot> | [9,11] |
| 12:19:28 | <Neut> | just practising list comprehensions |
| 12:21:00 | <mebbel> | Neut: for bonus points, rewrite your list comprehensions using do syntax |
| 12:24:24 | <urquell> | Berengal: What's the <$> and <*> thingies? |
| 12:24:42 | <Axman6> | :t (<$>) |
| 12:24:43 | <lambdabot> | forall a b (f :: * -> *). (Functor f) => (a -> b) -> f a -> f b |
| 12:24:44 | <Axman6> | :t (<*>) |
| 12:24:45 | <lambdabot> | forall (f :: * -> *) a b. (Applicative f) => f (a -> b) -> f a -> f b |
| 12:25:44 | <Axman6> | > (,) <$> [1..5] <*> ['a'..'c'] |
| 12:25:45 | <lambdabot> | [(1,'a'),(1,'b'),(1,'c'),(2,'a'),(2,'b'),(2,'c'),(3,'a'),(3,'b'),(3,'c'),(4... |
| 12:25:50 | <Axman6> | > (,) <$> [1..3] <*> ['a'..'c'] |
| 12:25:51 | <lambdabot> | [(1,'a'),(1,'b'),(1,'c'),(2,'a'),(2,'b'),(2,'c'),(3,'a'),(3,'b'),(3,'c')] |
| 12:26:14 | <Axman6> | :t (,) <$> [1..3] |
| 12:26:15 | <lambdabot> | forall a b. (Num a, Enum a) => [b -> (a, b)] |
| 12:26:49 | <Philonous1> | @type \x -> fmap ($ x) |
| 12:26:51 | <lambdabot> | forall a b (f :: * -> *). (Functor f) => a -> f (a -> b) -> f b |
| 12:27:28 | <Neut> | with the matches function, matches k xs = [x | x <- xs, x==k] |
| 12:27:40 | <Neut> | how would I chnage it so that it only returns unique items from a list |
| 12:27:57 | <Philonous1> | @type fmap.fmap |
| 12:27:58 | <Neut> | ie [1,2,3,2,1,4,5] ~~ [3,4,5] |
| 12:27:59 | <lambdabot> | forall (f :: * -> *) a b (f1 :: * -> *). (Functor f, Functor f1) => (a -> b) -> f (f1 a) -> f (f1 b) |
| 12:29:42 | <cob_jonas> | > M.fromList [(1,5)] |
| 12:29:44 | <lambdabot> | fromList [(1,5)] |
| 12:31:38 | <DrSyzygy> | ?quickcheck (M.toList . M.fromList) xs == xs where _ = xs :: [(Int,Int)] |
| 12:31:39 | <lambdabot> | Unknown command, try @list |
| 12:31:42 | <DrSyzygy> | ?list |
| 12:31:42 | <lambdabot> | http://code.haskell.org/lambdabot/COMMANDS |
| 12:31:55 | <DrSyzygy> | Wasn't there some in-channel quickcheck interface? |
| 12:32:10 | <Axman6> | @check True |
| 12:32:11 | <lambdabot> | "OK, passed 500 tests." |
| 12:32:20 | <DrSyzygy> | ?check (M.toList . M.fromList) xs == xs where _ = xs :: [(Int,Int)] |
| 12:32:20 | <lambdabot> | Parse error at "where" (column 34) |
| 12:32:42 | <DrSyzygy> | ?check \(xs :: [(Int,Int)] -> (M.toList . M.fromList) xs == xs |
| 12:32:42 | <lambdabot> | Unbalanced parentheses |
| 12:32:49 | <cob_jonas> | > let { ie s = map fst (filter ((1 ==) . snd) (M.toList (M.fromListWith (+) (map (flip (,) 1) s)))); } in ie [1,2,3,2,1,4,5] {- M is Data.Map -} |
| 12:32:50 | <lambdabot> | [3,4,5] |
| 12:32:50 | <DrSyzygy> | ?check \(xs :: [(Int,Int)] -> (M.toList . M.fromList) xs == xs) |
| 12:32:50 | <lambdabot> | Parse error at "M.toL..." (column 25) |
| 12:32:57 | <cob_jonas> | => Neut |
| 12:32:57 | <DrSyzygy> | Meh |
| 12:33:12 | <Neut> | yes? |
| 12:33:29 | <RayNbow> | @check \xs :: [(Int,Int)] -> (M.toList . M.fromList) xs == xs |
| 12:33:29 | <lambdabot> | Parse error at "::" (column 5) |
| 12:33:31 | <doserj> | ?check \xs -> (M.toList . M.fromList) xs == (xs::[(Int,Int)]) |
| 12:33:33 | <lambdabot> | "Falsifiable, after 3 tests:\n[(2,-3),(-1,0)]\n" |
| 12:33:40 | <cob_jonas> | Neut: that's the function you wanted, didn't you? |
| 12:33:49 | <cob_jonas> | it gave [3,4,5] from [1,2,3,2,1,4,5] |
| 12:33:50 | <DrSyzygy> | doserj: Thanks. |
| 12:33:56 | <cob_jonas> | or do you also want to keep the order? |
| 12:34:00 | <cob_jonas> | because this one doesn't |
| 12:34:16 | <cob_jonas> | > let { ie s = map fst (filter ((1 ==) . snd) (M.toList (M.fromListWith (+) (map (flip (,) 1) s)))); } in ie [1,5,2,3,2,1,4] |
| 12:34:18 | <lambdabot> | [3,4,5] |
| 12:34:20 | <Neut> | is it possible to do with a simpler list comprehension? |
| 12:34:22 | <DrSyzygy> | ?check \xs -> (sort . M.toList . M.fromList) xs == sort (xs::[(Int,Int)]) |
| 12:34:23 | <lambdabot> | "Falsifiable, after 11 tests:\n[(0,3),(-3,0),(-6,-4),(3,0),(3,6)]\n" |
| 12:34:47 | <cob_jonas> | Neut: it probably is |
| 12:34:50 | <cob_jonas> | dunno |
| 12:35:20 | <doserj> | DrSyzygy: toList.fromList removes duplicate keys |
| 12:35:23 | <cob_jonas> | well this one has a map and filter which you can rewrite to a single list comprehension |
| 12:35:47 | <cob_jonas> | try it if you want to |
| 12:35:48 | <DrSyzygy> | doserj: I expected that but wanted to see QuickCheck confirm it. :-P |
| 12:36:05 | <Neut> | thanks cob_jonas |
| 12:37:13 | <zachk> | sweet, i wrote drop using foldr and zip |
| 12:37:59 | <cob_jonas> | zip? you mean zip with iota? |
| 12:38:19 | <zachk> | > mydrop2 5 [1..10] where mydrop2 n list = foldr (\x y-> if fst x<=n then y else (snd):y) [] $ zip [1..] list |
| 12:38:21 | <lambdabot> | <no location info>: parse error on input `where' |
| 12:39:04 | <zachk> | > let mydrop2 n list = foldr (\x y-> if fst x<=n then y else (snd):y) [] $ zip [1..] list in mydrop2 5 [1..10] |
| 12:39:06 | <lambdabot> | Overlapping instances for GHC.Show.Show ((a, b) -> b) |
| 12:39:06 | <lambdabot> | arising from a use... |
| 12:39:12 | <cob_jonas> | > let { mydrop2 n list = foldr (\x y-> if fst x<=n then y else (snd):y) [] $ zip [1..] list } in mydrop2 5 "policeman" |
| 12:39:13 | <lambdabot> | Overlapping instances for GHC.Show.Show ((a, b) -> b) |
| 12:39:13 | <lambdabot> | arising from a use... |
| 12:39:24 | <zachk> | mydrop2 n list = foldr (\x y-> if fst x<=n then y else (snd x):y) [] $ zip [1..] list |
| 12:39:38 | <zachk> | > mydrop2 n list = foldr (\x y-> if fst x<=n then y else (snd x):y) [] $ zip [1..] list |
| 12:39:40 | <lambdabot> | <no location info>: parse error on input `=' |
| 12:39:45 | <zachk> | i quit it works in ghci |
| 12:39:52 | <cob_jonas> | @type let { mydrop2 n list = foldr (\x y-> if fst x<=n then y else (snd):y) [] $ zip [1..] list } in mydrop2 5 "policeman" |
| 12:39:53 | <lambdabot> | forall a b. [(a, b) -> b] |
| 12:40:17 | <cob_jonas> | maybe you copied it wrong? |
| 12:41:44 | <zachk> | yea i typed it wrong |
| 12:41:52 | <zachk> | did where stop working in lambdabot? |
| 12:42:25 | <cob_jonas> | huh? |
| 12:43:36 | <byorgey> | @where where |
| 12:43:37 | <lambdabot> | ?where where |
| 12:43:47 | <byorgey> | @where hcar |
| 12:43:47 | <lambdabot> | http://www.haskell.org/communities/ |
| 12:43:54 | <byorgey> | looks ok to me |
| 12:44:51 | <zachk> | > let mydrop n list = foldr (\x y-> if fst x<=n then y else (snd x):y) [] $ zip [1..] list in mydrop 5 [1..10] |
| 12:44:54 | <lambdabot> | [6,7,8,9,10] |
| 12:44:58 | <zachk> | there we go :-D |
| 12:51:44 | <Phyx-> | Afternoon, I was wondering how do you check if a value is undefined? |
| 12:51:53 | <cob_jonas> | > SimpleReflect.var$concatMap(["\"","\\",",","> SimpleReflect.var$concatMap([","]!!)[3,0,1,0,0,2,0,1,1,0,2,0,2,0,2,0,3,0,2,0,4,0,4]"]!!)[3,0,1,0,0,2,0,1,1,0,2,0,2,0,2,0,3,0,2,0,4,0,4] |
| 12:51:55 | <lambdabot> | > SimpleReflect.var$concatMap(["\"","\\",",","> SimpleReflect.var$concatMap... |
| 12:51:58 | <cob_jonas> | Phyx-: you don't |
| 12:52:26 | <Phyx-> | there must be someway |
| 12:52:42 | <Botje> | Phyx-: nope. |
| 12:52:54 | <Botje> | why do you need to know if something is undefined? |
| 12:53:17 | <yitz> | Phyx-: you design your code so that it will never be undefined, guaranteed. |
| 12:53:35 | <cob_jonas> | the whole point of bottom is that you don't check for it, right? |
| 12:53:47 | <Botje> | you /can't/ check for it |
| 12:53:51 | <Botje> | not without becoming bottom yourself |
| 12:54:23 | <doserj> | @hoogle isBottom |
| 12:54:24 | <lambdabot> | Test.QuickCheck.Batch isBottom :: a -> Bool |
| 12:55:07 | <Phyx-> | doserj: thanks :) |
| 12:56:08 | <Botje> | O_O |
| 12:56:17 | <doserj> | Phyx-: you should know what you are doing, though, before you use this function |
| 12:56:20 | <Botje> | did the quickcheck guys solve the halting problem? |
| 12:56:38 | <cob_jonas> | Botje: no, it's just an unsafePerformIO without unsafe in it's name |
| 12:56:53 | <Phyx-> | Botje: no, you just evaluate it and catch the exception |
| 12:57:04 | <Phyx-> | i was thinking that aswell, but asked first |
| 12:57:53 | <Phyx-> | doserj: yes, i know what i'm doing :) The only other way i could solve what i'm doing is by using syb and make a generic producer, but using undefined to initialize is much easier |
| 12:58:53 | <yitz> | > isBottom $ fix ("a" ++) |
| 12:58:55 | <lambdabot> | Not in scope: `isBottom' |
| 12:59:22 | <yitz> | > Test.QuickCheck.Batch.isBottom $ fix ("a" ++) |
| 12:59:24 | <lambdabot> | Not in scope: `Test.QuickCheck.Batch.isBottom' |
| 12:59:31 | <yitz> | darn |
| 13:00:00 | <doserj> | yitz: you didn't expect unsafePerformIO to be in scope in lambdabot, did you? |
| 13:00:26 | <Phyx-> | hehehe |
| 13:00:30 | <yitz> | doserj: I didn't expect isBottom to exist at all, if you want to know the truth |
| 13:01:36 | <doserj> | yitz: it is cheating of course. it won't catch last [0..], for example. |
| 13:01:58 | <Phyx-> | which i don't need anyway, i'm also cheating in a sense :) |
| 13:02:10 | <cob_jonas> | will it catch out of memory? or sigint? |
| 13:02:40 | <cob_jonas> | or killThread? |
| 13:02:55 | <Phyx-> | it'll catch anything that throw an exception i beleive |
| 13:02:56 | <yitz> | so it runs the function in a separate thread and looks for an exception? |
| 13:03:15 | <cob_jonas> | yitz: why separate thread? |
| 13:04:54 | <doserj> | yitz: it is basically unsafePerformIO . try . evaluate |
| 13:05:27 | <cob_jonas> | isn't evaluate evil and does something completely different from its name? |
| 13:05:36 | <cob_jonas> | or that doesn't matter at this point? |
| 13:05:43 | <yitz> | ok got it. |
| 13:07:28 | <cob_jonas> | @src Test.QuickCheck.Batch.isBottom |
| 13:07:28 | <lambdabot> | Source not found. Sorry. |
| 13:08:41 | <doserj> | cob_jonas: evaluate is a (almost) just return $! x in the IO Monad |
| 13:10:35 | <doserj> | cob_jonas: 'evaluate x' is an IO action that, when executed, evaluates x |
| 13:10:49 | <amgarching> | hi, why doesnt this work: 1 % 2 % 3 ?? |
| 13:11:14 | <Peaker> | @type (%) |
| 13:11:15 | <lambdabot> | forall a. (Integral a) => a -> a -> Ratio a |
| 13:11:35 | <Peaker> | @type (1%2)%3 |
| 13:11:37 | <lambdabot> | forall t. (Integral t, Integral (Ratio t)) => Ratio (Ratio t) |
| 13:12:08 | <kpreid> | > 1 / 2 / 3 :: Ratio Integer |
| 13:12:09 | <lambdabot> | 1 % 6 |
| 13:12:22 | <Peaker> | hmm -- (Ratio t) is not a type variable, why does @type allow it to be in a class constraint? |
| 13:12:40 | <amgarching> | how do I type, say i * j / k * l / m / n if I want it to be a Ratio? |
| 13:12:41 | <Peaker> | > 1%2%3 |
| 13:12:41 | <Berengal> | Peaker: -XFlexibleContexts? |
| 13:12:42 | <lambdabot> | No instance for (GHC.Real.Integral (GHC.Real.Ratio t)) |
| 13:12:42 | <lambdabot> | arising from a us... |
| 13:12:43 | <kpreid> | amgarching: because % is the "ratio of integers" operation and 1 % 2 is not an integer |
| 13:12:49 | <Peaker> | Berengal: what does that do? |
| 13:13:04 | <kpreid> | amgarching: use / instead |
| 13:13:07 | <Berengal> | Peaker: Allow more than just variables in contexts |
| 13:13:24 | <DrSyzygy> | > i * j / k * l / m / n :: Ratio Exp |
| 13:13:25 | <lambdabot> | Not in scope: type constructor or class `Exp' |
| 13:13:36 | <DrSyzygy> | > 2 * 3 / 4 * 5 / 6 / 7 :: Ratio Int |
| 13:13:38 | <lambdabot> | 5 % 28 |
| 13:13:50 | <kpreid> | > 1 :: Expr |
| 13:13:51 | <lambdabot> | 1 |
| 13:14:00 | <DrSyzygy> | > i * j / k * l / m / n :: Ratio Expr |
| 13:14:02 | <lambdabot> | Couldn't match expected type `GHC.Real.Ratio SimpleReflect.Expr' |
| 13:14:05 | <cob_jonas> | amgarching: if they're all integers, then (i * j * l) % (k * m * n) or just put fromInteger before each and then use * and / |
| 13:14:13 | <kpreid> | > i * j / k * l / m / n :: Expr |
| 13:14:14 | <lambdabot> | i * j / k * l / m / n |
| 13:14:26 | <cob_jonas> | as in (fromIntegral i) * (fromIntegral j) / (fromIntegral k) * ... |
| 13:15:29 | <amgarching> | ok, I got the idea, let me try. Thanks. |
| 13:16:47 | <yitz> | > 2 * 3 % 4 * 5 / 6 / 7 |
| 13:16:49 | <lambdabot> | 5 % 28 |
| 13:17:43 | <yitz> | amgarching: use % for the first division, / for the rest |
| 13:17:57 | <cob_jonas> | yitz: nope |
| 13:18:08 | <yitz> | cob_jonas: counterexample? |
| 13:18:13 | <cob_jonas> | yitz: that only works because number literals are both integers and rationals |
| 13:18:20 | <yitz> | cob_jonas: right |
| 13:18:51 | <cob_jonas> | well I'm not sure what type i and j etc really has in amgarching's question |
| 13:19:11 | <yitz> | the first one makes the type of the expression a Ratio, the rest are division for that type with the literals typed as Ratios |
| 13:19:13 | <cob_jonas> | but if they're all integers than that's not enough, if they're all ratios (including literals) then you don't need that one % neither |
| 13:19:34 | <amgarching> | cob_jonas: i <- [0..n], j <- [0..i], etc |
| 13:19:35 | <yitz> | cob_jonas: that's true, and then you *can't* use %. |
| 13:20:03 | <cob_jonas> | amgarching: same thing, the [0..n] can be lists of ratios |
| 13:20:11 | <cob_jonas> | amgarching: so then you can just use * and / |
| 13:20:49 | <cob_jonas> | amgarching: do { i <- [1..3]; j <- [1..3]; return (i / j) } |
| 13:20:52 | <cob_jonas> | > do { i <- [1..3]; j <- [1..3]; return (i / j) } |
| 13:20:53 | <lambdabot> | [1.0,0.5,0.3333333333333333,2.0,1.0,0.6666666666666666,3.0,1.5,1.0] |
| 13:20:59 | <doserj> | % is just supposed to be used as a (smart) constructor |
| 13:21:02 | <cob_jonas> | > do { i <- [1..3]; j <- [1..3]; return (i / j :: Ratio Integer) } |
| 13:21:04 | <lambdabot> | [1 % 1,1 % 2,1 % 3,2 % 1,1 % 1,2 % 3,3 % 1,3 % 2,1 % 1] |
| 13:21:54 | <yitz> | > [r | r <- [0..3]] :: [Rational] |
| 13:21:56 | <lambdabot> | [0 % 1,1 % 1,2 % 1,3 % 1] |
| 13:22:15 | <FunctorSalad_> | I don't think I get SCCs. I have: foo x = {-# SCC "foo_" #-} go ... where go = ... |
| 13:22:37 | <yitz> | > [r | r <- [0%1..3]] |
| 13:22:40 | <lambdabot> | [0 % 1,1 % 1,2 % 1,3 % 1] |
| 13:22:47 | <FunctorSalad_> | why is the automatic cost center for foo much more costly than my "foo_" ? |
| 13:23:34 | <amgarching> | of what type is r here: [ fromIntegral r | r <- [0..3]] ?? |
| 13:23:42 | <amgarching> | > [ fromIntegral r | r <- [0..3]] ?? |
| 13:23:44 | <lambdabot> | <no location info>: parse error (possibly incorrect indentation) |
| 13:23:54 | <FunctorSalad_> | @type [ fromIntegral r | r <- [0..3]] |
| 13:23:56 | <lambdabot> | forall b. (Num b) => [b] |
| 13:25:55 | <zachk> | haskell is starting to feel like legos :-D |
| 13:26:11 | <xenoblitz> | hi people can I ask a question regarding the following code: http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5276#a5276 |
| 13:26:18 | <DrSyzygy> | zachk: That's good! Then the character of functional programming is reaching you. |
| 13:26:28 | <xenoblitz> | any one can shed some light why simulate latchC works but simulate latchC2 doesn't? |
| 13:27:53 | <zachk> | i would need to draw a schematic :-/ |
| 13:28:06 | <FunctorSalad_> | meh. I covered all the branches of my function with SCCs but the auto top-level SCC of the function still has lots of own time |
| 13:28:09 | <Phyx-> | lol, DrSyzygy untill someone tells you you're supposed to fit that round lego block in that square hole, then they show you how and you're left scratching your head :) |
| 13:28:52 | <zachk> | just take a Round->Square and go from Thuare |
| 13:29:08 | <Phyx-> | lol |
| 13:29:28 | <DrSyzygy> | EXACTLY! |
| 13:29:46 | <amgarching> | so if I have data Monom = Monom Integer Integer Integer, I cannot use (Monom i j k) if any of (i,j,k) is "inferred/promoted" to Rationals? I get some obscure errmsg. |
| 13:30:07 | <DrSyzygy> | amgarching: Because you don't have integers any longer. |
| 13:30:08 | <doserj> | xenoblitz: I would guess latchC2 has a loop? |
| 13:30:21 | <DrSyzygy> | And there is no inherent way to convert a Rational to an Integer, with good reason. |
| 13:30:21 | <xenoblitz> | doserj: both of them actually have a loop |
| 13:30:34 | <fasta> | xenoblitz: post complete code next time |
| 13:30:44 | <xenoblitz> | doserj: just that one has two High inputs while the other has a Low and High |
| 13:30:50 | <xenoblitz> | fasta: it is complete code as far as i know |
| 13:31:03 | <doserj> | xenoblitz: it is missing type Var = String |
| 13:31:06 | <fasta> | xenoblitz: ire.hs:7:12: Not in scope: type constructor or class `Var' |
| 13:31:17 | <xenoblitz> | fasta: ouch yeah sorry let me amend that |
| 13:31:29 | <cob_jonas> | because of && one might have a loop but still terminate |
| 13:32:02 | <xenoblitz> | http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5276#a5277 |
| 13:33:24 | <yitz> | lookUpWire = flip lookup |
| 13:34:12 | <doserj> | ("c", And (Label "a") (Label "f") doesn't loop if a is Low |
| 13:34:48 | <xenoblitz> | doserj: cause and false x is always false? |
| 13:35:01 | <doserj> | yes |
| 13:35:33 | <xenoblitz> | doserj: but how does it reach that conclusion? is this defined somewhere? |
| 13:35:42 | <doserj> | @src && |
| 13:35:43 | <lambdabot> | True && x = x |
| 13:35:43 | <lambdabot> | False && _ = False |
| 13:37:10 | <xenoblitz> | I don't know if I understand correctly... can I view that unknown part as a thunk so False && thunk |
| 13:37:21 | <xenoblitz> | so False? |
| 13:37:43 | <cob_jonas> | > False && undefined |
| 13:37:46 | <lambdabot> | False |
| 13:37:48 | <cob_jonas> | > undefined && False |
| 13:37:49 | <lambdabot> | * Exception: Prelude.undefined |
| 13:37:55 | <Phyx-> | http://en.wikipedia.org/wiki/Short-circuit_evaluation |
| 13:38:29 | <Gracenotes> | similar to short-circuit evaluation, but the mechanisms are entirely different |
| 13:39:19 | <Gracenotes> | not to mention, short-circuit evaluation is more like IO Bool -> IO Bool -> IO Bool. In Haskell, && is pure, Bool -> Bool -> Bool. |
| 13:39:28 | <Gracenotes> | but that's petty |
| 13:40:02 | <Phyx-> | the only difference is that in haskell becauze of lazy evaluation short defining && doesn't need any special operators |
| 13:40:08 | <Phyx-> | but the article mentions that aswell |
| 13:41:54 | <xenoblitz> | thanks guys I keep wondering how I come up against this problems :S |
| 13:43:24 | <jeff_s_> | I think of OR like "elem True list" and AND like "not (elem False list)" |
| 13:44:46 | <xenoblitz> | quickquestion related to what we were discussing:... when we write our own operators are they short-circuited or "normal"? |
| 13:45:48 | <cob_jonas> | xenoblitz: depends on how you write them |
| 13:46:02 | <doserj> | Haskell is lazy, so short-circuited is normal :) unless you explicitely pattern match, nothing is evaluated. |
| 13:46:09 | <Phyx-> | exactly |
| 13:46:30 | <kpreid> | xenoblitz: but the order of cases can determine which argument is examined first, which makes a difference in termination |
| 13:46:42 | <kpreid> | in which argument has to be defined |
| 13:46:48 | <jeff_s_> | I imagine it's easy to rewrite && and || to not short-circuit. |
| 13:46:48 | <kpreid> | > False && undefined |
| 13:46:49 | <lambdabot> | False |
| 13:46:52 | <kpreid> | > undefined && False |
| 13:46:53 | <lambdabot> | * Exception: Prelude.undefined |
| 13:46:56 | <cnwdup> | How would I load (using System.Plugins) a data structure of type Foo s? Is this even possible? I thought I did this but now I have my code rewritten and I get errors about ambiguity of type s. |
| 13:47:12 | <Phyx-> | jeff_s_: yes, just force evaluation before you compare |
| 13:47:41 | <xenoblitz> | oh i c so its a question of pattern matching... if a case exists with a _ you can create short-circuited operators |
| 13:48:02 | <kpreid> | xenoblitz: exactly. well, _ or ~ |
| 13:48:02 | <zachk> | dont use the _ wildcard |
| 13:48:02 | <zachk> | otherwise you wont be able to evaluate it |
| 13:48:11 | <zachk> | whats ~ match to |
| 13:48:13 | <kpreid> | but also a plain variable |
| 13:48:44 | <yottis> | is _ really special or just an idiom? |
| 13:48:47 | <xenoblitz> | in the end its how you pattern match then that defines if an operator or function is short-circuited or not |
| 13:48:53 | <doserj> | > let False && False = False; False && True = False ; True && False = False; True && True = True in False && undefined |
| 13:48:54 | <jeff_s_> | I was just gonna ask the same thing. I don't remember seeing ~ in pattern matches yet. |
| 13:48:54 | <lambdabot> | * Exception: Prelude.undefined |
| 13:48:57 | <kpreid> | if I write "foo False bar = ..." then it doesn't evaluate bar, but does evaluate the first arg and check it |
| 13:49:02 | <kpreid> | yottis: it's special |
| 13:49:08 | <kpreid> | > let foo _ _ = 1 in foo 1 2 |
| 13:49:09 | <lambdabot> | 1 |
| 13:49:14 | <kpreid> | > let foo x x = 1 in foo 1 2 |
| 13:49:15 | <lambdabot> | Conflicting definitions for `x' |
| 13:49:15 | <lambdabot> | In the definition of `foo' |
| 13:49:21 | <kpreid> | > let foo _x _y = 1 in foo 1 2 |
| 13:49:23 | <lambdabot> | 1 |
| 13:49:24 | <yottis> | so foo x y = x is different from foo x _ = x? |
| 13:49:30 | <kpreid> | yottis: no |
| 13:49:48 | <kpreid> | the specialness is just that it doesn't actually bind any variable and can be used many times |
| 13:50:08 | <doserj> | _ is just an identifier that cannot be used on the right hand side |
| 13:50:12 | <kpreid> | it makes no difference if you were to replace every _ in a program with distinct variable names |
| 13:50:14 | <yottis> | is the difference that _ can't be referenced on the right-hand side? |
| 13:50:18 | <yottis> | echo that |
| 13:50:31 | <kpreid> | the other difference is that you can use it multiple times on the left |
| 13:50:46 | <xenoblitz> | amazing stuff I hope i remember hehe |
| 13:50:57 | <jeff_s_> | 4.4 Lazy patterns @ http://www.haskell.org/tutorial/patterns.html |
| 13:51:44 | <xenoblitz> | thanks guys |
| 14:09:33 | <mib_e7tcavos> | hey ive gt a problem |
| 14:09:46 | <mib_e7tcavos> | say i have a list of users |
| 14:09:55 | <mib_e7tcavos> | [user] |
| 14:10:17 | <mib_e7tcavos> | and im trying to find if my user is in a list of users |
| 14:10:30 | <mib_e7tcavos> | so technically |
| 14:10:47 | <mib_e7tcavos> | user == [user] or is part of |
| 14:10:57 | <mib_e7tcavos> | any ideas how to do that |
| 14:11:04 | <cnwdup> | > lookup 2 [1..10] |
| 14:11:05 | <lambdabot> | No instance for (GHC.Enum.Enum (t, b)) |
| 14:11:05 | <lambdabot> | arising from the arithmetic seque... |
| 14:11:11 | <mauke> | > elem 2 [1..10] |
| 14:11:12 | <cnwdup> | > lookup (2::Int) [1..10] |
| 14:11:12 | <lambdabot> | True |
| 14:11:13 | <lambdabot> | No instance for (GHC.Enum.Enum (GHC.Types.Int, b)) |
| 14:11:13 | <lambdabot> | arising from the arit... |
| 14:11:21 | <mauke> | cnwdup: what |
| 14:11:30 | <doserj> | cnwdup: lookup is for association lists |
| 14:11:30 | <cnwdup> | Woups. That was just stupid. (: |
| 14:11:44 | <mib_e7tcavos> | kl |
| 14:13:00 | <Botje> | mib_e7tcavos: there is an "elem" function |
| 14:13:07 | <Botje> | as mauke pointd out |
| 14:13:21 | <mib_e7tcavos> | yeah "looking" it up now |
| 14:13:33 | <Phyx-> | @hoogle elem |
| 14:13:33 | <lambdabot> | Prelude elem :: Eq a => a -> [a] -> Bool |
| 14:13:33 | <lambdabot> | Data.ByteString elem :: Word8 -> ByteString -> Bool |
| 14:13:33 | <lambdabot> | Data.Foldable elem :: (Foldable t, Eq a) => a -> t a -> Bool |
| 14:13:44 | <Phyx-> | @hoogle elem --info |
| 14:13:45 | <lambdabot> | Prelude elem :: Eq a => a -> [a] -> Bool |
| 14:13:45 | <lambdabot> | |
| 14:13:45 | <lambdabot> | elem is the list membership predicate, usually written in infix form, e.g., x `elem` xs. |
| 14:16:40 | <Peaker> | @hoogle unsafePerformIO --info |
| 14:16:40 | <lambdabot> | Foreign unsafePerformIO :: IO a -> a |
| 14:16:41 | <lambdabot> | |
| 14:16:41 | <lambdabot> | This is the "back door" into the IO monad, allowing IO computation to be performed at any time. For this to be safe, the IO computation should be free of side effects and independent of its environmen |
| 14:16:41 | <lambdabot> | t. |
| 14:18:45 | <Peaker> | was --info always there? :P |
| 14:19:02 | <jeff_s_> | @hoogle --help |
| 14:19:03 | <lambdabot> | Go to the website for full help, http://haskell.org/hoogle/ |
| 14:19:04 | <lambdabot> | |
| 14:19:04 | <lambdabot> | Flag reference: |
| 14:19:17 | <ray> | @hoggle safePerformIO |
| 14:19:17 | <lambdabot> | Foreign unsafePerformIO :: IO a -> a |
| 14:19:18 | <lambdabot> | System.IO.Unsafe unsafePerformIO :: IO a -> a |
| 14:19:46 | <Phyx-> | heh, is that an alias? |
| 14:20:08 | <ray> | no, lambdabot has spelling error tolerance |
| 14:20:25 | <Phyx-> | to what extend? |
| 14:20:33 | <Phyx-> | @haggle test |
| 14:20:33 | <lambdabot> | Test.HUnit.Base test :: Testable t => t -> Test |
| 14:20:33 | <lambdabot> | Test.HUnit.Base data Test |
| 14:20:33 | <lambdabot> | Test.QuickCheck class Testable a |
| 14:20:36 | <Phyx-> | hmm |
| 14:20:36 | <jeff_s_> | someone had fun making hoogle |
| 14:20:41 | <Gracenotes> | I think it's Levenshtein distance |
| 14:20:47 | <Gracenotes> | er... lemme see. |
| 14:21:17 | <ray> | but what specific levenshtein distance is the tolerance |
| 14:21:27 | <mauke> | 2 |
| 14:21:34 | <Phyx-> | aha |
| 14:21:41 | <Gracenotes> | :o so I see |
| 14:21:59 | <ray> | so transposing 2 letters uses it up |
| 14:22:14 | <ray> | except in the degenerate case where you transpose 2 letters that are the same |
| 14:22:28 | <Phyx-> | doesn't Hayoo use this? |
| 14:22:45 | <Peaker> | I don't understand the difference between Hoogle and Hayoo |
| 14:22:49 | <ray> | lost my hayoo mail |
| 14:22:54 | <Peaker> | Hayhoo is more comprehensive? |
| 14:23:25 | <ray> | hayoo's newer and possibly fancier |
| 14:23:28 | <boegel> | Hayoo included packages, Hoogle doesn't |
| 14:23:36 | <boegel> | s/included/includes |
| 14:23:46 | <Phyx-> | i find hoogle returns better results |
| 14:23:51 | <cob_jonas> | but you can compile hoogle database for any package, can't you? |
| 14:23:57 | <cob_jonas> | locally |
| 14:24:02 | <boegel> | maybe, yeah |
| 14:24:28 | <Phyx-> | and doesn't hayoo use Textual Type searching and Hoogle 4 Structural Edit distance to do searching? |
| 14:25:17 | <Gracenotes> | mauke: hm. where is the matching in the lambdabot source? |
| 14:25:23 | <Phyx-> | so hayoo alpha normalizes and strength reduced alpha normalizes, then does substring searching |
| 14:25:33 | <mauke> | Gracenotes: dunno |
| 14:25:44 | <Peaker> | Phyx-: What's "structural edit distance"? |
| 14:26:18 | <Phyx-> | Peaker: difference in only structure between the search value and result value |
| 14:26:42 | <Peaker> | as in - ignoring names? |
| 14:27:05 | <Gracenotes> | aha. |
| 14:27:47 | <Phyx-> | Peaker: for instance, if you search for "Maybe Int" the structure it tries to match against is "? ?" |
| 14:27:50 | <Gracenotes> | the edit distance cut-off is < 3 |
| 14:27:57 | <Phyx-> | it's only usefull for the typeseaches i beleive |
| 14:27:58 | <Gracenotes> | so <= 2, as mauke said... |
| 14:28:04 | <cob_jonas> | @hoogle :: Maybe Int |
| 14:28:04 | <lambdabot> | Prelude Nothing :: Maybe a |
| 14:28:05 | <lambdabot> | Data.Maybe Nothing :: Maybe a |
| 14:28:05 | <lambdabot> | Language.Haskell.TH maxPrecedence :: Int |
| 14:28:27 | <Peaker> | Phyx-: I think it would make sense to lose only names of type variables, and not of everything else? |
| 14:28:43 | <Peaker> | Though it could try and substitute everything for a super-class/subclass, etc |
| 14:28:59 | <cob_jonas> | it does that too |
| 14:29:16 | <Phyx-> | Peaker: you have to take into account things like aliases, missing instances, boxing etc |
| 14:29:32 | <cob_jonas> | @hoogle (Monad f) => f (a -> b) -> f a -> f b |
| 14:29:32 | <lambdabot> | Control.Monad ap :: Monad m => m (a -> b) -> m a -> m b |
| 14:29:32 | <lambdabot> | Control.Monad liftM :: Monad m => (a1 -> r) -> m a1 -> m r |
| 14:29:32 | <lambdabot> | Control.Applicative (<*>) :: Applicative f => f (a -> b) -> f a -> f b |
| 14:29:40 | <cob_jonas> | @hoogle (Functor f) => f (a -> b) -> f a -> f b |
| 14:29:40 | <lambdabot> | Prelude fmap :: Functor f => (a -> b) -> f a -> f b |
| 14:29:40 | <lambdabot> | Control.Applicative (<$>) :: Functor f => (a -> b) -> f a -> f b |
| 14:29:40 | <lambdabot> | Control.Monad fmap :: Functor f => (a -> b) -> f a -> f b |
| 14:29:46 | <Phyx-> | so it uses the structure to quickly reduce the set of possibles i beleive and then tries to sort through the best matched ones |
| 14:29:51 | <cob_jonas> | @hoogle (Applicative f) => f (a -> b) -> f a -> f b |
| 14:29:51 | <lambdabot> | Control.Applicative (<*>) :: Applicative f => f (a -> b) -> f a -> f b |
| 14:29:51 | <lambdabot> | Control.Applicative (<**>) :: Applicative f => f a -> f (a -> b) -> f b |
| 14:29:51 | <lambdabot> | Control.Applicative liftA :: Applicative f => (a -> b) -> f a -> f b |
| 14:31:25 | <cnwdup> | @src map |
| 14:31:26 | <lambdabot> | map _ [] = [] |
| 14:31:26 | <lambdabot> | map f (x:xs) = f x : map f xs |
| 14:31:29 | <Gracenotes> | this is rather strange. The "closests" function is used, but I can't find it anywhere |
| 14:31:32 | <Phyx-> | Peaker: that way, for instance searching for Monad m => m a would also find Maybe a, which *might* be what you want, |
| 14:31:32 | <cnwdup> | @type map |
| 14:31:33 | <lambdabot> | forall a b. (a -> b) -> [a] -> [b] |
| 14:31:35 | <Gracenotes> | @hoogle closests |
| 14:31:35 | <lambdabot> | No results found |
| 14:31:38 | <Gracenotes> | :. |
| 14:32:01 | <mux> | :t foldr ((:) . f) [] |
| 14:32:03 | <lambdabot> | forall b a. (Show a, SimpleReflect.FromExpr b) => [a] -> [b] |
| 14:32:05 | <Peaker> | (<**>) = flip (<*>)? or (<**>) = liftA2 (flip ($)) ? |
| 14:32:09 | <mux> | : \f -> t foldr ((:) . f) [] |
| 14:32:14 | <mux> | :t \f -> t foldr ((:) . f) [] |
| 14:32:16 | <lambdabot> | Couldn't match expected type `((a -> b -> b) -> b -> [a] -> b) |
| 14:32:16 | <lambdabot> | -> (a1 -> [b1] -> [b1]) |
| 14:32:16 | <lambdabot> | -> [a2] |
| 14:33:00 | <Phyx-> | Peaker: if you want to know more look at http://community.haskell.org/~ndm/hoogle/ |
| 14:34:13 | <Peaker> | > let (<**>) = liftA2 (flip id) in [10,20] <**> [(+1),(+2)] |
| 14:34:15 | <lambdabot> | [11,12,21,22] |
| 14:34:19 | <Peaker> | > [10,20] <**> [(+1),(+2)] |
| 14:34:21 | <lambdabot> | [11,12,21,22] |
| 14:34:31 | <Peaker> | > let (<**>) = flip (<*>) in [10,20] <**> [(+1),(+2)] |
| 14:34:32 | <lambdabot> | [11,21,12,22] |
| 14:34:39 | <Peaker> | aha |
| 14:34:55 | <Gracenotes> | okay! |
| 14:35:29 | <cob_jonas> | @type <**> |
| 14:35:30 | <lambdabot> | parse error on input `<**>' |
| 14:35:32 | <cob_jonas> | @type (<**>) |
| 14:35:33 | <lambdabot> | forall (f :: * -> *) a b. (Applicative f) => f a -> f (a -> b) -> f b |
| 14:35:58 | <Peaker> | @type flip (<*>) |
| 14:35:59 | <lambdabot> | forall (f :: * -> *) a b. (Applicative f) => f a -> f (a -> b) -> f b |
| 14:36:07 | <Peaker> | the difference is in the way effects are sequenced |
| 14:36:37 | <cob_jonas> | I see |
| 14:36:39 | <Peaker> | flip (<*>) sequences right-to-left, and liftA2 (flip id) sequences left-to-right |
| 14:47:04 | <mgee> | hi, did somebody already worked with QIO? The quantum computer IO monad. |
| 14:47:18 | <mib_e7tcavos> | hey |
| 14:47:45 | <mib_e7tcavos> | anyone know if there is a function for a avergae of a list |
| 14:48:01 | <dmwit> | mib_e7tcavos: No. |
| 14:48:08 | <mib_e7tcavos> | list of int |
| 14:48:13 | <dmwit> | It's easy to write, though. =) |
| 14:48:14 | <cob_jonas> | but there's many ways to write it |
| 14:48:15 | <mib_e7tcavos> | nope ok |
| 14:48:22 | <mib_e7tcavos> | yeah ill give it ago |
| 14:50:01 | <jmcarthur_work> | there is a fast way and a slow way. keep that in mind as you write it :) |
| 14:50:35 | <jmcarthur_work> | (this particular case has been complained about before because the most naive solution isn't the fastest) |
| 14:50:43 | <dmwit> | No, there's a space-efficient way and a space-inefficient way. They're about equally fast. =) |
| 14:50:49 | <Pellwurst> | is there a special symbol to match a whitespace as a regexp? |
| 14:51:02 | <dmwit> | Pellwurst: In PCRE, \s |
| 14:51:14 | <mauke> | [[:space:]] in posix |
| 14:51:15 | <jmcarthur_work> | well, the naive solution can also easily overflow the stack if it's built without optimizations |
| 14:51:22 | <dmwit> | ACTION nods |
| 14:51:28 | <mib_e7tcavos> | average :: [Int] -> Int |
| 14:51:34 | <Pellwurst> | mauke: thx, that should do the job |
| 14:51:41 | <mib_e7tcavos> | average I = sum I / length I |
| 14:51:43 | <mib_e7tcavos> | ? |
| 14:52:06 | <dmwit> | mib_e7tcavos: Seems close. There's a few problems left. |
| 14:52:31 | <dmwit> | mib_e7tcavos: First, variable names have to start with a lower-case letter, to distinguish them from constructor names. |
| 14:52:41 | <mib_e7tcavos> | yeah |
| 14:52:49 | <mib_e7tcavos> | small i lol |
| 14:52:57 | <dmwit> | mib_e7tcavos: Also, length returns an Int, which you can't divide by, so you'll need to convert it: |
| 14:53:00 | <dmwit> | :t fromIntegral |
| 14:53:01 | <lambdabot> | forall a b. (Integral a, Num b) => a -> b |
| 14:53:24 | <mib_e7tcavos> | ah ok |
| 14:53:46 | <doserj> | mib_e7tcavos: what should the average of [1,2] be? |
| 14:53:48 | <dmwit> | As a stylistic note, it's a common idiom in Haskell to call a list of things by a name ending in 's', so xs, ys, zs, is, as, numbers, etc. |
| 14:53:59 | <sammartin> | mib_e7tscos: have you thought about returning a tuple of sum and length as an option? |
| 14:54:05 | <jeff_s_> | average [1,2] = 1 |
| 14:54:22 | <dmwit> | jeff_s_: ewww |
| 14:54:26 | <jeff_s_> | hehe |
| 14:54:27 | <Phyx-> | lol |
| 14:54:32 | <dmwit> | average [1,2] = 3 % 2 |
| 14:55:15 | <cob_jonas> | I thought yyou should fold with a tuple |
| 14:55:30 | <jeff_s_> | I like integer math, 3/2 = 1 has its uses |
| 14:55:34 | <dmwit> | cob_jonas: Yep, but for a beginner, the naive solution is probably fine. |
| 14:55:46 | <dmwit> | Until we have long lists, readable is better than efficient. =) |
| 14:55:47 | <jeff_s_> | actually, how do you do integer divsion in haskell anyway? |
| 14:55:53 | <dmwit> | :t div |
| 14:55:54 | <lambdabot> | forall a. (Integral a) => a -> a -> a |
| 14:56:01 | <jeff_s_> | do you have to truncate the rational number? |
| 14:56:14 | <dmwit> | ...no... |
| 14:56:17 | <mib_e7tcavos> | thanks guys gt it now cheers |
| 14:56:24 | <Absolute0> | Is 'type t = (Int k, Char v) => Data.Map.Map k v' valid? |
| 14:56:28 | <Absolute0> | I am getting an error |
| 14:56:29 | <Ferdirand> | btw, is it possible to automatically fuse two foldls over the same list with a single tuple foldl ? |
| 14:56:32 | <MyCatVerbs> | > [5 `div` 2, 14 `div` 3] |
| 14:56:33 | <lambdabot> | [2,4] |
| 14:56:41 | <Botje> | Absolute0: what is that supposed to do? |
| 14:56:43 | <dmwit> | Absolute0: Int and Char aren't classes. |
| 14:56:52 | <Absolute0> | type t = Data.Map.Map Int Char won't work either |
| 14:56:53 | <jeff_s_> | Ferdirand - ya, start with ([],[]) instead of [] |
| 14:57:01 | <dmwit> | Absolute0: And type names must start with an uppercase letter. |
| 14:57:08 | <Botje> | Absolute0: that's because type names start with an uppercase letter |
| 14:57:10 | <dmwit> | type T = Map Int Char |
| 14:57:12 | <Absolute0> | ah |
| 14:58:30 | <Absolute0> | also importing libraries using the qualified keyword fails in ghci |
| 14:58:38 | <dmwit> | yes |
| 14:58:41 | <Absolute0> | is there any way to override that? |
| 14:59:12 | <dmwit> | Do it in a file? |
| 14:59:27 | <Absolute0> | nevermind. |
| 14:59:47 | <Absolute0> | ghci should behave like a file! |
| 15:00:38 | <dmwit> | I'm going to go ahead and claim that mutual recursion makes your claim false. |
| 15:04:08 | <byorgey> | ghci could behave like a file if you embed it in a (TimeTravelT IO) monad |
| 15:04:50 | <byorgey> | not just mutual recursion, the fact that declarations don't have to be an any particular order in a file is good enough. |
| 15:04:50 | <dmwit> | To be honest, though, I don't see how come it can't behave like a file, now that we have :{ :} |
| 15:05:04 | <byorgey> | be *in any |
| 15:05:22 | <byorgey> | dmwit: are you at school? |
| 15:05:33 | <dmwit> | I'll be in in about an hour or so. |
| 15:05:39 | <Phyx-> | what's :{ :} ? |
| 15:05:47 | <byorgey> | ok, me too |
| 15:05:54 | <dmwit> | Phyx-: :{ starts a multiline ghci command |
| 15:06:00 | <byorgey> | sad devil, happy devil! |
| 15:06:08 | <dmwit> | heh |
| 15:06:11 | <Phyx-> | hmm ok |
| 15:06:28 | <dmwit> | byorgey: I've got a long list of links talking about inter- and intra-city transportation for Hac \phi. |
| 15:06:36 | <byorgey> | sweet! |
| 15:07:05 | <cob_jonas> | let me try to write this average thing the way I wanted now because when mibbit asked I tried to but got an error and then I got called away |
| 15:07:22 | <dmwit> | cob_jonas: Good idea! |
| 15:07:30 | <cob_jonas> | I know I wrote it a few times of course |
| 15:09:25 | <Peaker> | byorgey, dmwit: ghci could suspend disbelief and allow to use yet-inexistent names |
| 15:09:30 | <jeff_s_> | ACTION scrolls up |
| 15:09:36 | <jeff_s_> | thanks MyCatVerbs for the reminder about `div` |
| 15:09:40 | <dmwit> | Peaker: I can't even imagine how many problems that would cause. |
| 15:09:42 | <Peaker> | byorgey, dmwit: It could also re-evaluate dependent stuff when existing names are re-defined |
| 15:09:58 | <dmwit> | Peaker: I make so many typos in ghci it's not even funny. |
| 15:09:59 | <Peaker> | dmwit: or, it could have a special notation to enable that for some name |
| 15:10:01 | <byorgey> | Peaker: maybe. sounds horribly complicated and full of nasty surprises for the user. |
| 15:10:10 | <dmwit> | exactlyl |
| 15:10:13 | <dmwit> | ah |
| 15:10:20 | <dmwit> | Perfect examplel. ;-) |
| 15:10:21 | <Peaker> | dmwit: blah = @bleh bluh |
| 15:10:31 | <byorgey> | dmwit: hehl |
| 15:10:34 | <Peaker> | bluh -- undefined |
| 15:10:39 | <Peaker> | bleh -- OK that it is undefined |
| 15:10:40 | <dino-> | oo, I didn't know about that :{ |
| 15:11:00 | <jeff_s_> | @hoogle blah = bleh bluh |
| 15:11:01 | <lambdabot> | Parse error: |
| 15:11:01 | <lambdabot> | --count=20 "blah = bleh bluh" |
| 15:11:01 | <lambdabot> | ^ |
| 15:11:05 | <Peaker> | when blah is used - only then it will try to type/use it |
| 15:11:27 | <Phyx-> | jeff_s_: ? |
| 15:11:33 | <jeff_s_> | Just being silly. |
| 15:11:39 | <Phyx-> | lol |
| 15:11:49 | <Peaker> | byorgey, dmwit: What problems do you envision with it? |
| 15:12:00 | <Peaker> | I see it *complicating* ghci, but worse isn't better is it? :) |
| 15:13:02 | <dmwit> | Peaker: I propose that you implement it and prove us wrong. ;-) |
| 15:13:11 | <Peaker> | dmwit: I don't know ghc :( |
| 15:13:40 | <cob_jonas> | > let { ave :: [Float] -> Float; ave = snd . foldl' (\(k, a) x -> (k + 1, a + (x - a)/(k + 1))) (0, 0); } in ave [3,2,2] {- throw in a map fromIntegral if it has to work on a list of Ints -} |
| 15:13:41 | <lambdabot> | 2.3333333 |
| 15:13:44 | <byorgey> | Peaker: I don't know of any specific things off the top of my head. it was just a feeling. you may be right. |
| 15:13:46 | <cob_jonas> | there, that way |
| 15:14:06 | <Peaker> | byorgey: CL does essentially that, doesn' tit? |
| 15:14:19 | <byorgey> | Peaker: I've no idea, does it? |
| 15:14:31 | <cob_jonas> | Peaker: so how would that undefined names thingy work? |
| 15:14:33 | <byorgey> | cob_jonas: nice, only one traversal |
| 15:14:38 | <cob_jonas> | what would an undefined name do? |
| 15:15:17 | <Peaker> | cob_jonas: well, I think there could be a customizable configuration whether @ are necessary, and if they are, and you have @ on a name, then it only checks the syntax, and waits for that name to exist before evaluating the expression |
| 15:15:25 | <dmwit> | cob_jonas: That looks like a lot of extra division to me. |
| 15:15:31 | <Phyx-> | that seems overly complicated to me... |
| 15:15:55 | <Peaker> | cob_jonas: unmarked @ names will behave as they do today |
| 15:16:03 | <dmwit> | > let ave = uncurry (/) . foldl' (\(k, a) x -> (k + 1, a + x)) (0, 0) } in ave [3, 2, 2] |
| 15:16:04 | <lambdabot> | <no location info>: parse error on input `}' |
| 15:16:10 | <dmwit> | > let ave = uncurry (/) . foldl' (\(k, a) x -> (k + 1, a + x)) (0, 0) in ave [3, 2, 2] |
| 15:16:11 | <lambdabot> | 0.42857142857142855 |
| 15:16:19 | <dmwit> | Oh, right. |
| 15:16:20 | <cob_jonas> | dmwit: but at least it's more precise in some cases (for arbitary float arguments) than just doing one division |
| 15:16:32 | <byorgey> | dmwit: that's the reciprocal, I think |
| 15:16:33 | <cob_jonas> | for [3,2,2] it doesn't matter of course |
| 15:16:34 | <dmwit> | > let ave = uncurry (/) . foldl' (\(a, k) x -> (a+x, k+1)) (0, 0) in ave [3, 2, 2] |
| 15:16:35 | <lambdabot> | 2.3333333333333335 |
| 15:16:44 | <dmwit> | cob_jonas: Right, that's possibly true. |
| 15:17:17 | <byorgey> | ACTION runs screaming from the dark art of accurate numerics |
| 15:17:19 | <cob_jonas> | Peaker: but would those names be allowed in IO <- binding statements? |
| 15:17:38 | <cob_jonas> | Peaker: I mean, if it's just plain assignments then right, you just print them late |
| 15:18:12 | <Peaker> | cob_jonas: ghci does effect execution and ordinary let bindings.. The former can require entire expression to be well-defined, and the latter can wait |
| 15:19:12 | <Peaker> | Type definitions could work the same - except perhaps if the type is re-defined then all the former uses of it in the shell should either be invalidated, re-evaluated, or remain using the old type, where the new type only shares a name with the old one |
| 15:20:01 | <dmwit> | Peaker: You know, these days you don't have to know GHC to write your own Haskell interpreter. |
| 15:20:13 | <dmwit> | Check out the hint package on Hackage, and wow us with your innovation. =) |
| 15:20:36 | <Peaker> | at the very least I'll have to parse my own syntax? |
| 15:20:43 | <Peaker> | (for the annotations) |
| 15:20:46 | <cob_jonas> | Peaker: so would it work if you entered something like "let { x = @y }" and then "y <- f x" ? |
| 15:21:00 | <Peaker> | cob_jonas: I think that should be fine |
| 15:21:10 | <dmwit> | Yep, you might have to scan for annotations. |
| 15:21:36 | <dmwit> | You could separate annotations from Haskell code in some clever way, though. |
| 15:21:56 | <cob_jonas> | which one does it run first? |
| 15:22:17 | <dmwit> | :t fixIO |
| 15:22:18 | <lambdabot> | Not in scope: `fixIO' |
| 15:22:28 | <dmwit> | ?instances MonadFix |
| 15:22:28 | <lambdabot> | ((->) r), Either e, ErrorT e m, IO, Maybe, RWS r w s, RWST r w s m, Reader r, ReaderT r m, ST s, State s, StateT s m, Writer w, WriterT w m, [] |
| 15:22:28 | <cob_jonas> | yeah, I could never wrap my head around that fixIO thing |
| 15:22:32 | <cob_jonas> | oh well |
| 15:22:44 | <cob_jonas> | anyway, defining types in ghc is sort of easy |
| 15:22:53 | <cob_jonas> | my plugin sort of works for that |
| 15:22:53 | <byorgey> | cob_jonas: hm? what do you mean, which would it run first? |
| 15:23:04 | <mauke> | @hoogle fixIO |
| 15:23:04 | <lambdabot> | System.IO fixIO :: (a -> IO a) -> IO a |
| 15:23:13 | <mauke> | ah, mfix[IO] |
| 15:25:16 | <cob_jonas> | http://erxz.com/pb/17809 allows you to define types inline in ghci |
| 15:25:30 | <Peaker> | > mfix return |
| 15:25:31 | <lambdabot> | No instance for (GHC.Show.Show (m a)) |
| 15:25:31 | <lambdabot> | arising from a use of `M7875774271... |
| 15:25:46 | <Peaker> | > fix id |
| 15:25:51 | <lambdabot> | mueval-core: Prelude.read: no parse |
| 15:25:51 | <lambdabot> | mueval: ExitFailure 1 |
| 15:26:06 | <MyCatVerbs> | Ouch! That loses all current bindings. Not good. :/ |
| 15:26:26 | <Peaker> | @type both |
| 15:26:27 | <lambdabot> | forall (a :: * -> * -> *) b c. (Arrow a) => a b c -> a (b, b) (c, c) |
| 15:26:34 | <Peaker> | MyCatVerbs: that's a binding from earlier? |
| 15:27:50 | <ray> | fix id should be thread killed |
| 15:27:57 | <ray> | why wouldn't it parse? |
| 15:28:32 | <mauke> | I think the parse error refers to the result |
| 15:28:53 | <MyCatVerbs> | Peaker: the inline type definition hack cob_jonas pointed out. |
| 15:29:07 | <ray> | i guess that could be |
| 15:29:15 | <Peaker> | oh |
| 15:29:16 | <MyCatVerbs> | Win: it lets you define data, newtypes and types inline in GHCi. |
| 15:29:35 | <cob_jonas> | MyCatVerbs: yes, but if you have plain let bindings (not IO bindings) you can do them with :decl and then they're reintroduced every time you add a new binding and not lost |
| 15:29:38 | <Peaker> | one after the other, or only the last one survives? |
| 15:29:43 | <MyCatVerbs> | Lose: the only way of implementing that was to build and load a module, which means you suddenly lose all your bindings. |
| 15:30:26 | <cob_jonas> | Peaker: one after the other, if you try to add two of the same name you get an error so use the :undecl command to remove the previous one |
| 15:30:57 | <MyCatVerbs> | cob_jonas: a large portion of the time in GHCi, I am working with IO bindings. Generally I like to put my data sets in files rather than type them into the REPL. |
| 15:31:18 | <Peaker> | MyCatVerbs: put them in an .hs file |
| 15:31:36 | <alexsuraci> | Is there such a thing as a tuple containing one value? |
| 15:31:43 | <dmwit> | No. |
| 15:31:43 | <mauke> | alexsuraci: no |
| 15:31:50 | <cob_jonas> | MyCatVerbs: well, you could bind the IO commands to functions and run those functions as an IO binding, or just use readline to go back and rerun old statements |
| 15:31:53 | <alexsuraci> | alright, thought so |
| 15:31:55 | <alexsuraci> | thanks |
| 15:31:58 | <dmwit> | alexsuraci: There's Identity. |
| 15:32:02 | <dmwit> | > Identity 3 |
| 15:32:03 | <lambdabot> | No instance for (GHC.Show.Show (Control.Monad.Identity.Identity t)) |
| 15:32:03 | <lambdabot> | aris... |
| 15:32:12 | <cob_jonas> | dmwit: yes, but that's not Showable I think |
| 15:32:16 | <cob_jonas> | > Identity 5 |
| 15:32:16 | <lambdabot> | No instance for (GHC.Show.Show (Control.Monad.Identity.Identity t)) |
| 15:32:17 | <lambdabot> | aris... |
| 15:32:40 | <wjt> | there's OneTuple on hackage :D |
| 15:32:41 | <alexsuraci> | well, more from a language implementation standpoint than utility |
| 15:32:44 | <alexsuraci> | haha |
| 15:32:50 | <dmwit> | > runIdentity (Identity 3) |
| 15:32:52 | <lambdabot> | 3 |
| 15:33:36 | <Phyx-> | @cabal info OneTuple |
| 15:33:37 | <lambdabot> | bzzt. |
| 15:33:39 | <Phyx-> | lol |
| 15:33:48 | <dmwit> | eh? |
| 15:33:50 | <dmwit> | ?help cabal |
| 15:33:50 | <lambdabot> | help <command>. Ask for help for <command>. Try 'list' for all commands |
| 15:34:01 | <dmwit> | Okay, so it's auto-correcting to something... |
| 15:34:01 | <ray> | > let show Identity a = "Identity " ++ show a in Identity 3 -- or something |
| 15:34:03 | <lambdabot> | Constructor `Control.Monad.Identity.Identity' should have 1 argument, but h... |
| 15:34:04 | <Phyx-> | @hackage info OneTuple |
| 15:34:05 | <lambdabot> | http://hackage.haskell.org/cgi-bin/hackage-scripts/package/info OneTuple |
| 15:34:11 | <Phyx-> | ... |
| 15:34:19 | <dmwit> | ray: show (Identity a), and it needs to be in an instance block. |
| 15:34:48 | <ray> | yes, (Identity a) |
| 15:35:05 | <bavardage> | o/ |
| 15:35:20 | <dmwit> | ACTION calls on bavardage |
| 15:35:23 | <dmwit> | Yes, dear? |
| 15:37:39 | <cob_jonas> | by the way, let me note that my ghci extension also lets you import modules qualified as |
| 15:37:53 | <cob_jonas> | so you can finally write :import qualified Data.Map as M |
| 15:38:00 | <cob_jonas> | some may find this the most important use |
| 15:39:21 | <cob_jonas> | eg. http://erxz.com/pb/17810 |
| 15:41:59 | <cnwdup> | > let xs = [1::Int, 'c'::Char] :: forall a. Show a => [a] in map show xs |
| 15:42:00 | <lambdabot> | Couldn't match expected type `GHC.Types.Int' |
| 15:42:40 | <cnwdup> | How can I create such a list containing arbitrary values and restricting the usable functions to a few working on any types? |
| 15:44:15 | <mauke> | you can't directly |
| 15:44:21 | <cnwdup> | Ok. |
| 15:44:27 | <integral> | > let xs = [1 :: Int, 'c' :: Char] :: [forall a. Show a => a] in map show xs |
| 15:44:29 | <lambdabot> | Cannot match a monotype with `forall a. (GHC.Show.Show a) => a' |
| 15:44:40 | <mauke> | you can make an existential wrapper and wrap each element individually |
| 15:45:43 | <Gracenotes> | data Showable = forall a. Show a => Showable a |
| 15:46:03 | <Gracenotes> | .. possibly deriving Show. All you can do with it is show, after all... |
| 15:46:14 | <integral> | heh :-) |
| 15:46:58 | <Ferdirand> | jeff_s_: well, I know how to do it by hand. I was wondering if the compiler could do it for me, with a rule or so |
| 15:47:17 | <Ferdirand> | or if there was some subtle hidden catch that would make it incorrect |
| 15:47:53 | <cob_jonas> | or just use a normal algebraic type |
| 15:49:16 | <cob_jonas> | > let { xs = [Left 1, Right 'c']; } in map (either show show) xs |
| 15:49:17 | <lambdabot> | ["1","'c'"] |
| 15:51:10 | <mauke> | > let xs = [show 1, show 'c'] in xs |
| 15:51:12 | <lambdabot> | ["1","'c'"] |
| 15:52:07 | <arcatan> | what would be my options if i wanted to generate png images with haskell? |
| 15:54:46 | <byorgey> | arcatan: what sort of png images? |
| 15:55:03 | <mib_e7tcavos> | hey another noob question here |
| 15:55:16 | <byorgey> | mib_e7tcavos: ask away! |
| 15:55:32 | <Absolute0> | Are list comprehensions lazy when passed as parameters to other functions? |
| 15:55:37 | <mib_e7tcavos> | i need to return top ten films by fans |
| 15:55:59 | <mib_e7tcavos> | all ive gt so far is |
| 15:56:17 | <mib_e7tcavos> | topTenFilms :: [Film] -> [Title] |
| 15:56:28 | <Absolute0> | I am wondering if it is better to insert each element into a map individually or create a list and call fromList function? |
| 15:56:30 | <mib_e7tcavos> | topTenFilms films = [title | Film title director year fans <- films, length fans >= m ] |
| 15:56:38 | <mib_e7tcavos> | im having brain freezer |
| 15:56:54 | <dmwit> | arcatan: Cairo, diagrams, Gtk2Hs, HsMagick, ... |
| 15:57:35 | <tetha> | mib_e7tcavos: couldn't you sort the films by fan-count and take the first 10? |
| 15:57:39 | <dmwit> | Absolute0: Use fromList. |
| 15:57:42 | <mib_e7tcavos> | anyone gt any ideas of what i shud look at |
| 15:57:46 | <byorgey> | mib_e7tcavos: try sorting the films first by number of fans |
| 15:57:49 | <mib_e7tcavos> | yes |
| 15:57:54 | <mib_e7tcavos> | ah yeah |
| 15:57:55 | <Absolute0> | dmwit: just as effecient? |
| 15:57:58 | <mib_e7tcavos> | cheers guys |
| 15:58:01 | <byorgey> | mib_e7tcavos: you can even use sortBy |
| 15:58:14 | <Absolute0> | dmwit: if the list is large creating the list and then sorting it within Data.Map seems silly. |
| 15:58:16 | <dmwit> | Absolute0: Just as, and may in the future be more efficient. |
| 15:58:32 | <dmwit> | Absolute0: I don't understand; why would that be silly? |
| 15:58:38 | <Absolute0> | dmwit: as apposed to individually inserting each one |
| 15:58:50 | <arcatan> | byorgey: dynamically generated png images serverd over HTTP |
| 15:58:54 | <Absolute0> | isn't inserting one quicker than sorting an entire list? |
| 15:59:07 | <dmwit> | Absolute0: Maybe, but inserting them all is not. |
| 15:59:16 | <Absolute0> | ah |
| 15:59:23 | <dmwit> | Absolute0: Also, what is up with your thing against sorting? Data.Map doesn't call sort anywhere. |
| 15:59:42 | <byorgey> | arcatan: yes, but I mean, what will the images be like? how simple/complex? will it involve putting together other images, or just generating simple shapes, or...? |
| 15:59:46 | <Absolute0> | dmwit: how does it achieve log n lookup? |
| 15:59:52 | <Absolute0> | its sorts the map |
| 16:00:09 | <Absolute0> | i think it says so in the docs |
| 16:00:19 | <dmwit> | Absolute0: ...sort of, yes. |
| 16:00:32 | <byorgey> | it uses a balanced tree. |
| 16:00:33 | <arcatan> | byorgey: oh. i will generate the pixel data myself and want to encode it in a png |
| 16:00:34 | <dmwit> | Absolute0: Insertion puts the element "in the right place," so to speak. |
| 16:00:35 | <tetha> | isn't data.map a tree? |
| 16:01:18 | <byorgey> | arcatan: ah. In that case you probably want to use HsMagick, or perhaps Cairo |
| 16:01:22 | <dmwit> | arcatan: Then I suggest Gtk2Hs or HsMagick. |
| 16:01:23 | <Beelsebob> | depends on the implementation tetha |
| 16:01:24 | <SamB> | tetha: sure! |
| 16:01:29 | <Beelsebob> | but in most implementations... yes |
| 16:01:33 | <dmwit> | arcatan: Cairo can be nice, but definitely not if you want pixel-level control. |
| 16:01:42 | <SamB> | well, I mean, you could use some other kind of tree to implement it |
| 16:01:45 | <byorgey> | ok, thanks dmwit, I didn't know that =) |
| 16:01:57 | <SamB> | and if you were insane you could even use an alist |
| 16:02:01 | <arcatan> | dmwit: i do |
| 16:02:03 | <cob_jonas> | Absolute0: if the most efficent method is putting the elements in one by one, then that's what fromList will do, so I think fromList is always the most efficent if you can generate the list in a pure lazy way |
| 16:02:15 | <Absolute0> | dmwit: Inserting a newly generated element into the map is slower than first generating the entire list and calling Map.fromList? |
| 16:02:22 | <SamB> | but nobody would want to use the alist-based Data.Map, would they ? |
| 16:02:27 | <cob_jonas> | the insertion by one might be needed if you can't generate the list lazily, eg. if you're reading the elements from a file one by one |
| 16:02:28 | <Absolute0> | ah alright |
| 16:02:55 | <Absolute0> | i guess i was forgetting that haskell is lazy. |
| 16:02:56 | <Absolute0> | :) |
| 16:03:02 | <dmwit> | Absolute0: It's hard to compare those two operations, because they don't start and end at the same place. |
| 16:03:09 | <tetha> | Absolute0: well, you are venturing into the land of optimizing against a single standard library there |
| 16:03:22 | <dmwit> | Absolute0: Yes, inserting one element is faster than generating a whole new Map, but those are rarely the two options you're comparing. |
| 16:04:06 | <cnwdup> | http://moonpatio.com/fastcgi/hpaste.fcgi/view?id=2491#a2491 Could anyone tell me why this outputs "pluginA: state of wrong type, pluginB: state of wrong type" in ghci? Is this approach right to realize dynamically loaded plugins which can access the other plugin's states? |
| 16:05:36 | <dmwit> | Alright, time to go in to work. yay! =) |
| 16:06:25 | <Absolute0> | :) |
| 16:07:07 | <Absolute0> | So are list comprehensions lazy when inputted to other functions? |
| 16:07:47 | <Absolute0> | ie: map (+) 0 [x | x < [0..99999999999]] |
| 16:08:14 | <mapreduce> | Absolute0: Yes. |
| 16:08:16 | <Absolute0> | ie: fold (+) 0 [x | x < [0..99999999999]] |
| 16:08:28 | <burp> | try it |
| 16:08:31 | <Absolute0> | mapreduce: from #java? :) |
| 16:08:41 | <mapreduce> | > foldl (+) 0 [1..] |
| 16:08:47 | <lambdabot> | mueval-core: Prelude.read: no parse |
| 16:08:47 | <lambdabot> | mueval: ExitFailure 1 |
| 16:08:54 | <mapreduce> | > head [1..] |
| 16:08:57 | <lambdabot> | 1 |
| 16:09:24 | <EvilTerran> | Absolute0, list comprehensions de-sugar to uses of map and filter, so are as lazy as those functions |
| 16:09:52 | <EvilTerran> | @undo [f x | f <- fs, x <- xs, p x] |
| 16:09:52 | <lambdabot> | concatMap (\ f -> concatMap (\ x -> if p x then [f x] else []) xs) fs |
| 16:09:59 | <Absolute0> | mapreduce: foldl (+) 0 [x | x <- [0..99999999999]] |
| 16:10:00 | <byorgey> | and those functions are pretty lazy. Just yesterday I asked map to take out the garbage and it said it 'might get around to it later'. |
| 16:10:12 | <mapreduce> | Absolute0: I am from many programming language channels, not just ##java. |
| 16:10:17 | <EvilTerran> | ok, concatMap and if/then/else. comes to the same thing. |
| 16:10:28 | <Absolute0> | rickyclarkson.. |
| 16:10:42 | <mapreduce> | Yes? |
| 16:13:08 | <Absolute0> | how's scala going? |
| 16:14:12 | <mapreduce> | Not bad, but I'm not getting to use it as much as I was. I follow its development closely. |
| 16:15:08 | <Absolute0> | never got into it, haskell is way cooler :) |
| 16:15:27 | <mapreduce> | Agreed. |
| 16:17:47 | <Absolute0> | Is there any syntax to allow an infinite amount of arguments to a function without using lists? |
| 16:18:18 | <Absolute0> | ie: foo :: a1 -> a2 .. aN-1 -> aN |
| 16:18:27 | <doserj> | that's not infinite |
| 16:18:30 | <pepepto> | hola¡ |
| 16:18:35 | <Absolute0> | i mean undefined |
| 16:18:45 | <jeff_s_> | unbounded? |
| 16:18:49 | <Absolute0> | or that :) |
| 16:18:52 | <cnwdup> | Absolute0, you can use the type system for that like printf does. |
| 16:19:05 | <cnwdup> | quicksilver, ping |
| 16:19:10 | <Absolute0> | ah ok |
| 16:19:12 | <Absolute0> | thanks |
| 16:20:21 | <cob_jonas> | what's wrong with lists? |
| 16:20:39 | <cob_jonas> | there's a reason why we've got an easy syntax for lists |
| 16:20:55 | <jeff_s_> | Text.Printf.printf "%c" |
| 16:21:06 | <jeff_s_> | > Text.Printf.printf "%c" |
| 16:21:08 | <lambdabot> | Add a type signature |
| 16:21:22 | <Absolute0> | cob_jonas: extra bandwidth |
| 16:21:23 | <jeff_s_> | er.... |
| 16:21:24 | <doserj> | there is no easy pattern matching syntax for lists, though |
| 16:21:28 | <cob_jonas> | but printf sucks anyway, because it doesn't handle floating point formats properly |
| 16:21:57 | <cob_jonas> | bandwidth? |
| 16:22:13 | <jeff_s_> | @type Text.Printf.printf |
| 16:22:16 | <lambdabot> | forall r. (PrintfType r) => String -> r |
| 16:22:31 | <Absolute0> | '[' = 8 bytes!!! |
| 16:22:33 | <Absolute0> | :) |
| 16:22:51 | <jeff_s_> | > Text.Printf.printf "%c" "h" |
| 16:22:53 | <lambdabot> | Add a type signature |
| 16:23:03 | <jeff_s_> | oh |
| 16:23:04 | <Peaker> | Absolute0: I think just 4? |
| 16:23:18 | <Absolute0> | Peaker: does haskell use unicode? |
| 16:23:26 | <Peaker> | Absolute0: yeah, at least GHC does |
| 16:23:29 | <cob_jonas> | oh no |
| 16:23:32 | <cob_jonas> | I hate this question |
| 16:23:44 | <Absolute0> | isn't unicode 8 bytes? |
| 16:23:59 | <Twey> | ACTION twitches. |
| 16:24:01 | <jeff_s_> | unicode is like 5 different encoding standards or something like that |
| 16:24:09 | <Absolute0> | utf-8 |
| 16:24:19 | <Twey> | Unicode is a mapping of code points to characters |
| 16:24:24 | <Twey> | Different encodings are different sizes |
| 16:24:26 | <Peaker> | Absolute0: Unicode is an abstract mapping of "code points" to linguistic symbols, and some rules about how to render/go over a sequence of code points |
| 16:24:31 | <Twey> | UTF-8 is variable-size |
| 16:24:32 | <Peaker> | Absolute0: a code point is a number within 32-bit range |
| 16:24:46 | <Twey> | For ASCII characters, it's eight *bits*, hence its name |
| 16:24:56 | <Twey> | For some other characters it can require more |
| 16:24:59 | <Peaker> | Absolute0: but it can be encoded in various ways, one of which is UTF8 which takes 8 *bits* per code-point, if it is simple ASCII. When it isn't, it uses more bytes |
| 16:25:14 | <Twey> | Peaker: :) |
| 16:25:59 | <Absolute0> | see cob_jonas precious bandwidth down the drain just like that, pftt@ |
| 16:26:07 | <Absolute0> | =) |
| 16:26:14 | <Twey> | ACTION laughs. |
| 16:26:17 | <Phyx-> | *twitches* |
| 16:27:03 | <Absolute0> | especially in this economy |
| 16:27:35 | <Phyx-> | hmm... i need to extend my state :P |
| 16:28:13 | <jeff_s_> | I'm looking at the printf source, and I'm thinking that it's a library I don't ever want to use. |
| 16:29:04 | <jeff_s_> | http://oreilly.com/catalog/9780596101213/ btw |
| 16:29:04 | <Phyx-> | lol |
| 16:29:34 | <Phyx-> | now it's time for a game of... Will it typecheck |
| 16:30:07 | <jeff_s_> | lambdabot already convinced me that it won't |
| 16:30:23 | <Phyx-> | lol, i'm talking about my own code :P |
| 16:30:30 | <Phyx-> | i changed my type of my StateT |
| 16:30:36 | <Phyx-> | so now i'm notifying everywhere |
| 16:32:29 | <EvilTerran> | Phyx-, are you familiar with the idea of newtype-wrapping monad transformer stacks? |
| 16:33:18 | <Phyx-> | EvilTerran: i'm changing the get /put calls, which now return a different value |
| 16:33:27 | <Phyx-> | not the type or my functions :P |
| 16:33:37 | <cob_jonas> | or you can try data with named elements and use bracket amend functions |
| 16:33:50 | <EvilTerran> | Phyx-, ah, i see |
| 16:33:53 | <cob_jonas> | then the type changes but your code text needn't |
| 16:34:36 | <Phyx-> | cob_jonas: using records is one way to go, but i don't forsee another change needed |
| 16:35:52 | <Phyx-> | though you never know, so it's not a bad idea... |
| 16:36:00 | <EvilTerran> | Phyx-, what i meant was something like "newtype MyMonad a = MyMonad { unMyMonad :: StateT (Foo, Bar) IO a }; getFoo :: MyMonad Foo; getFoo = MyMonad $ gets fst; putFoo :: Foo -> MyMonad (); putFoo foo = MyMonad . put" ... |
| 16:37:06 | <EvilTerran> | Phyx-, and then you could make it a StateT (Foo, Bar, Baz), and all you'd need to do to fix backwards compatibility would be to update the definitions of (get/put)(Foo/Bar) |
| 16:37:39 | <Phyx-> | EvilTerran: i have something similiar, but i just use a Type synonym atm |
| 16:38:15 | <Phyx-> | i ahve |
| 16:38:17 | <Phyx-> | type ReadB a b c= State (Buchi (a,b),[c]) |
| 16:38:17 | <Phyx-> | type ENGINE a b c d= ReaderT (BuchiPair a b) (ReadB a b d) c |
| 16:38:18 | <cob_jonas> | EvilTerran: of course that only works if you derive Monad and define a run by hand |
| 16:38:35 | <EvilTerran> | cob_jonas, well, yeah, there's a little more boilerplate than i let on :P |
| 16:41:14 | <cob_jonas> | of course that's more useful when you're not just having a state but multiple trickier monad transformers inside |
| 16:42:20 | <EvilTerran> | cob_jonas, although even with just a State monad, the specialised get/set functions keep changes local if you change the state type |
| 16:43:18 | <cob_jonas> | but you can get that if you just define custom indexers and amenders for your tuple type, or let haskell syntax do that for you |
| 16:43:55 | <Phyx-> | ... |
| 16:44:55 | <EvilTerran> | ??? |
| 16:57:18 | <Phyx-> | hrm.. sometimes i think i build too much infrastructure/framework before i actually start on the logic |
| 17:06:57 | <xoclipse> | in my cabal file i have build-depends: haxml, but when i try to configure it tells me "Setup.hs: At least the following dependencies are missing: |
| 17:06:57 | <xoclipse> | HaXml >=1.19.4", (HaXml is installed fine though) |
| 17:07:40 | <koeien> | cabal is case-sensitive |
| 17:08:05 | <xoclipse> | yeah i have it like this: Build-Depends: base, haskell98, |
| 17:08:05 | <xoclipse> | binary >= 0.5, bytestring >= 0.9.1.4, |
| 17:08:05 | <xoclipse> | HaXml >= 1.19.4 |
| 17:08:25 | <koeien> | do you runghc Setup.hs configure ? |
| 17:08:31 | <koeien> | or cabal configure ? |
| 17:08:37 | <koeien> | in the first case, add --user if necessary |
| 17:09:12 | <dcoutts> | or just use cabal |
| 17:09:25 | <dcoutts> | there's really no need to mix use of 'cabal' with 'runghc Setup' |
| 17:09:27 | <koeien> | it's shorter anyway :) |
| 17:09:36 | <xoclipse> | runghc Setup.hs configure doesn't work |
| 17:09:40 | <xoclipse> | i was doing "runhaskell" |
| 17:09:48 | <xoclipse> | same thing w/ cabal configure |
| 17:10:01 | <xoclipse> | if i ghc --make *.hs my source files (that import haxml), it works fine |
| 17:10:09 | <xoclipse> | so i'm sure that HaXml is installed |
| 17:10:14 | <dcoutts> | xoclipse: what does ghc-pkg list HaXml say? |
| 17:14:39 | <xoclipse> | ghc-pkg dump | grep HaXml |
| 17:14:49 | <xoclipse> | import-dirs: /Users/chris/.cabal/lib/HaXml-1.13.3/ghc-6.10.1 |
| 17:14:49 | <xoclipse> | library-dirs: /Users/chris/.cabal/lib/HaXml-1.13.3/ghc-6.10.1 |
| 17:14:49 | <xoclipse> | hs-libraries: HSHaXml-1.13.3 |
| 17:14:49 | <xoclipse> | haddock-interfaces: /Users/chris/.cabal/share/doc/HaXml-1.13.3/html/HaXml.haddock |
| 17:14:49 | <xoclipse> | haddock-html: /Users/chris/.cabal/share/doc/HaXml-1.13.3/html |
| 17:15:01 | <xoclipse> | i changed the cabal script to be HaXml, with no version |
| 17:15:08 | <xoclipse> | but it still fails |
| 17:15:20 | <dcoutts> | xoclipse: next time, it's simpler to use "ghc-pkg list HaXml" |
| 17:15:25 | <xoclipse> | oh okay :) |
| 17:15:51 | <dcoutts> | xoclipse: so you see why you got the error message now |
| 17:16:05 | <xoclipse> | 1.13.3 < 1.19.4? |
| 17:16:26 | <xoclipse> | that ghc-pkg command is helpul, thanks! |
| 17:18:16 | <amgarching> | why is this illegal? instance (Num a) => Num (a, a) where, How would you do complex numbers with tuples? |
| 17:18:41 | <mauke> | I wouldn't use tuples |
| 17:19:17 | <amgarching> | isnt a tuple just another type constructor? |
| 17:19:23 | <mauke> | yes |
| 17:19:46 | <Tigran> | amgarching: But you're making an instance that is too specific |
| 17:19:57 | <Tigran> | amgarching: (a,a) as opposed to (a,b) |
| 17:20:14 | <Tigran> | By making your own data Complex a = Complex a a |
| 17:20:21 | <Tigran> | You're only working with a single type variable |
| 17:20:39 | <Tigran> | Which means you can do the perfectly valid `Num a => Num (Complex a)' |
| 17:25:32 | <shag> | how do i get RTS options compiled into my program? i.e. when using the -N option for controlling the number of threads, i always want my program to use 4 threads |
| 17:25:49 | <shag> | without needing to specify +RTS -N4 all the time |
| 17:26:28 | <monochrom> | I don't think it can. |
| 17:32:04 | <cob_jonas> | sure you can, with http://www.haskell.org/ghc/docs/latest/html/users_guide/ffi-ghc.html#ffi-library |
| 17:32:29 | <cob_jonas> | or just make a simple wrapper program that execs the other program with +RTS -N as arguments |
| 17:33:59 | <cob_jonas> | or you can set the GHCRTS environment variable but that would affect all haskell programs |
| 17:34:18 | <koeien> | including ghc itself... |
| 17:38:41 | <deech_> | Hi all, How do I use an operator like (+) or (-) if it is part of a module that I imported qualified? |
| 17:38:49 | <koeien> | (Prelude.+) |
| 17:39:12 | <Beelsebob> | surprising |
| 17:39:20 | <Beelsebob> | I would have expected it to be Prelude.(+) |
| 17:39:32 | <mauke> | I hate hpaste in a good way |
| 17:39:33 | <monochrom> | IIRC a M.+ b works. |
| 17:39:50 | <deech_> | That worked thanks! |
| 17:40:11 | <Beelsebob> | hmm, I guess in that context (M.+) makes more sense |
| 17:40:19 | <Beelsebob> | parenthesise anything infix and it becomes prefix |
| 17:41:01 | <mib_e7tcavos> | hey can i ask what is wrong with this code |
| 17:41:10 | <mib_e7tcavos> | topTenFilmsa :: [Film] -> [FilmB] |
| 17:41:12 | <Absolute0> | Is it possible to get a range in descending order without calling reverse? |
| 17:41:23 | <mib_e7tcavos> | topTenFilmsa films = [Film title director year sum length fans] |
| 17:41:25 | <mauke> | Absolute0: [a, a-1 .. b] |
| 17:41:50 | <mib_e7tcavos> | can i use sum and length with the statement |
| 17:41:55 | <Absolute0> | thanks |
| 17:42:27 | <mauke> | mib_e7tcavos: you're missing a few parentheses |
| 17:42:31 | <cnwdup> | @ty sum |
| 17:42:33 | <lambdabot> | forall a. (Num a) => [a] -> a |
| 17:42:36 | <cnwdup> | @ty length |
| 17:42:37 | <lambdabot> | forall a. [a] -> Int |
| 17:42:54 | <mauke> | and some other things |
| 17:43:02 | <mib_e7tcavos> | hmm |
| 17:43:07 | <cnwdup> | mib_e7tcavos, you can use length on every list. But you can use sum only on lists which elements are an instances of the Num class. |
| 17:43:21 | <cnwdup> | *instance |
| 17:43:25 | <monochrom> | Haskell is not English. |
| 17:44:34 | <mib_e7tcavos> | but surely length returns a [int] |
| 17:44:44 | <Peaker> | mib_e7tcavos: why? |
| 17:44:44 | <monochrom> | You can't just write "automatic banking machine user" and expect it to be parsible. |
| 17:44:47 | <mib_e7tcavos> | i just used sum to unlist it |
| 17:44:53 | <cnwdup> | mib_e7tcavos, it returns Int not [Int]. |
| 17:44:59 | <mib_e7tcavos> | ahhh |
| 17:45:06 | <monochrom> | Haskell is not German either. You can't just write "automaticbankingmachineuser" and expect it to be parsible. |
| 17:45:24 | <skorpan> | is haskell swedish? |
| 17:45:29 | <monochrom> | I don't know. |
| 17:45:48 | <skorpan> | @faq can haskell parse "automatic banking machine user"? |
| 17:45:48 | <jeff_s_> | Haskell is Esperanto. |
| 17:45:48 | <lambdabot> | The answer is: Yes! Haskell can do that. |
| 17:45:51 | <mib_e7tcavos> | still saying fans paramerters arnt set |
| 17:46:02 | <mauke> | mib_e7tcavos: no, it's not saying that |
| 17:46:09 | <cnwdup> | mib_e7tcavos, then provide the actual code. |
| 17:46:40 | <mib_e7tcavos> | sorry its saying: |
| 17:46:41 | <Philonous> | monochrom: Try capitalising it. Then it might work. |
| 17:46:50 | <mib_e7tcavos> | Undefined variable "fans" |
| 17:46:58 | <monochrom> | Haha |
| 17:47:20 | <cnwdup> | mib_e7tcavos, then you're using the variable fans which is not defined. (; Post the source code in a pastebin, then one can tell you what's wrong. |
| 17:47:21 | <monochrom> | "Undefined variable" is pretty clear. |
| 17:47:52 | <mib_e7tcavos> | ok |
| 17:48:17 | <monochrom> | I don't understand why people don't understand error messages. |
| 17:50:12 | <tetha> | people are lazy and dont want to read |
| 17:50:13 | <Philonous> | No instance for (Read Error) |
| 17:50:19 | <monochrom> | If it says "expected type Char, inferred type Int", then it means exactly that, you have something should be an Int and a Char, you have a self-contradiction. What more do you expect? |
| 17:50:24 | <cob_jonas> | Philonous++ lol |
| 17:50:38 | <monochrom> | Do you expect the computer to tell you how to fix it? |
| 17:50:47 | <koeien> | monochrom: sometimes, yes, but some error messages are obscure |
| 17:50:52 | <mib_e7tcavos> | http://pastebin.ca/1435211 |
| 17:50:57 | <tetha> | I would love to invent a system that tells you how to fix bugs |
| 17:51:08 | <tetha> | I guess then I can just stop studying :) |
| 17:51:08 | <mib_e7tcavos> | trying to return the list of fans as a amount |
| 17:51:13 | <monochrom> | If so, you may as well die now. If the computer can fix it, why do we need you to write programs? What's your point of existence? |
| 17:51:14 | <cob_jonas> | < buubot> cob_jonas: The paste 1435211 has been copied to http://erxz.com/pb/17824 |
| 17:51:15 | <cnwdup> | mib_e7tcavos, where are title director year length and fans defined? |
| 17:51:16 | <c_wraith> | Hmm. I'm getting conflicting instances between convertible-1.0.1 and time-1.1.3 :( |
| 17:52:09 | <cnwdup> | mib_e7tcavos, there are several things wrong with your code as far as I can see. |
| 17:52:24 | <cnwdup> | mib_e7tcavos, you cant to convert a list of Film to a list of FilmB, right? |
| 17:52:37 | <mauke> | nice typo |
| 17:52:50 | <mib_e7tcavos> | ok |
| 17:52:50 | <tetha> | koeien: well, yes, and there are error messages which are misleading due to stacking bugs and arcane errors, but I'd say they are no daily error messages |
| 17:53:51 | <cnwdup> | mib_e7tcavos, if you want to convert a list of Film to a list of FilmB you have to convert every element of the first list to FilmB. map is the function to use for that. |
| 17:54:08 | <mib_e7tcavos> | ok |
| 17:54:09 | <cnwdup> | mib_e7tcavos, map takes a function and a list and applies the function to every element of the list yielding a new list. |
| 17:54:18 | <mib_e7tcavos> | kl |
| 17:54:26 | <cnwdup> | mib_e7tcavos, you can write your function topTenFilmsa using topTenFilmsa films = map toFilmB films. |
| 17:55:03 | <cnwdup> | mib_e7tcavos, toFilmB will look pretty miuch like topTenFilma but title, directory, etc. are used wrong. They are not defined. |
| 17:55:41 | <c_wraith> | Ok... problem solved... explicit dependency on an older version of time. >_> |
| 17:55:45 | <cnwdup> | mib_e7tcavos, However, you can define them as you want if you pattern match Film correctly: toFilmB :: Film -> FilmB, toFilmB (Film title directory year fans) = FilmB title directory year (length fans) |
| 17:56:48 | <mib_e7tcavos> | ok i see what u mean |
| 17:56:58 | <cnwdup> | mib_e7tcavos, another issue with your code: length fans has to be in parantheses since otherwise length and fans would be applied to the data constructor Film. But you want to result of (length fans) to be applied. |
| 18:03:55 | <Baughn> | http://www.pps.jussieu.fr/~jch/software/XinC.html <-- Have a read, fellows |
| 18:08:56 | <ehird> | :t (<*>) |
| 18:08:57 | <lambdabot> | forall (f :: * -> *) a b. (Applicative f) => f (a -> b) -> f a -> f b |
| 18:08:58 | <ehird> | :t (<$>) |
| 18:08:59 | <lambdabot> | forall a b (f :: * -> *). (Functor f) => (a -> b) -> f a -> f b |
| 18:09:16 | <ehird> | hmm |
| 18:09:37 | <ehird> | <$> is used to do things like (pureFunction <$> getLine), isn't it? |
| 18:09:50 | <ehird> | what about (unpureFunction <??> getLine)? |
| 18:09:58 | <Twey> | Is IO a functor? |
| 18:10:11 | <ehird> | (and (unpureFunction <??> getLine <??> aPureThing <??> anotherUnpurething) etc) |
| 18:10:12 | <c_wraith> | ehird: is <*> what you want? |
| 18:10:13 | <Twey> | ehird: >> or >>= |
| 18:10:16 | <cnwdup> | ehird, what's wrong with <*> or ap for that? |
| 18:10:33 | <ehird> | Twey: in (f <foo> x) style, I mean |
| 18:10:40 | <deech_> | Hi all, |
| 18:10:41 | <Beelsebob> | ehird: <*> |
| 18:10:42 | <ehird> | cnwdup: (unpureFunction <*> getLine) :: IO (IO x) |
| 18:10:48 | <ehird> | err, wait |
| 18:10:51 | <ehird> | no |
| 18:11:01 | <ehird> | Beelsebob: how, (a -> IO b) != IO (a -> b) |
| 18:11:04 | <ehird> | 19:08 lambdabot: forall (f :: * -> *) a b. (Applicative f) => f (a -> b) -> f a -> f b |
| 18:11:23 | <Beelsebob> | ehird: well, IO (a -> b) is one form of impure function |
| 18:11:24 | <Twey> | :t print <*> getLine |
| 18:11:26 | <lambdabot> | Couldn't match expected type `a -> b' against inferred type `IO ()' |
| 18:11:26 | <lambdabot> | Probable cause: `print' is applied to too many arguments |
| 18:11:26 | <lambdabot> | In the first argument of `(<*>)', namely `print' |
| 18:11:34 | <Beelsebob> | if you happen to have one of type a -> IO b then you want =<< |
| 18:11:40 | <ehird> | ok |
| 18:11:43 | <deech_> | I am trying to import a CSV file using Text.CSV.ByteString, but it fails if any of the fields have a comma, even if the string containing the comma is enclosed in quotes. |
| 18:11:45 | <Twey> | :t print <$> getLine |
| 18:11:46 | <Beelsebob> | :t print =<< getLine |
| 18:11:46 | <lambdabot> | IO (IO ()) |
| 18:11:47 | <ehird> | what about multiple arguments? |
| 18:11:47 | <lambdabot> | IO () |
| 18:11:55 | <Twey> | So that would be join |
| 18:12:01 | <ehird> | say, (a -> b -> c -> IO d) and a and b are impure, but b is pure |
| 18:12:05 | <Absolute0> | How do I extract the a from Just a? |
| 18:12:22 | <tromp> | easiest by peatternmatch |
| 18:12:24 | <Twey> | join (print <$> getLine) ≡ print =<< getLine |
| 18:12:27 | <monochrom> | Use the do-notation for more arguments. |
| 18:12:34 | <ehird> | monochrom: bleargh |
| 18:12:52 | <Twey> | Absolute0: Pattern match, or fromJust if you're sure it's a Just, or maybe/fromMaybe otherwise |
| 18:12:55 | <tromp> | :t fromJust |
| 18:12:56 | <lambdabot> | forall a. Maybe a -> a |
| 18:13:00 | <tromp> | or that way |
| 18:13:00 | <Beelsebob> | if you don't want to use do notation, use >>= and lambdas ehird |
| 18:13:06 | <Beelsebob> | or... |
| 18:13:13 | <Beelsebob> | stop programming with side effecting stuff ;) |
| 18:13:25 | <Absolute0> | ah, I was trying to use guards direct matching seems like the way to do it.. |
| 18:13:29 | <Twey> | Note that fromJust is unsafe if it could possibly be a Nothing — it will throw an error. |
| 18:13:55 | <FalconNL> | Does anyone know if there's a tutorial on how to work with the AST generated by Language.Haskell.Exts, e.g. getting a list of all top-level functions? |
| 18:13:58 | <Absolute0> | |a == Nothing | a == Just a which is obviously wrong |
| 18:14:06 | <Twey> | Very |
| 18:14:09 | <Absolute0> | :) |
| 18:14:28 | <ehird> | Beelsebob: welp |
| 18:14:31 | <ehird> | main = do [input, output] <- getArgs; image <- loadPngFile input; processImage image; savePngFile output image |
| 18:14:36 | <ehird> | it's just that that's pretty ugly. |
| 18:14:47 | <monochrom> | If you have N arguments you are asking for 2^N combinators. |
| 18:14:57 | <Beelsebob> | ehird: is the image a resource that is read only once? |
| 18:15:13 | <monochrom> | do-notation is pretty pretty. |
| 18:15:16 | <ehird> | Beelsebob: Clarification? |
| 18:15:28 | <Beelsebob> | ehird: does your program ever load the same image file more than once? |
| 18:15:41 | <ehird> | Beelsebob: No. |
| 18:16:05 | <Beelsebob> | ehird: then you can treat loadPngFile as a pure function |
| 18:16:10 | <Beelsebob> | by wrapping it in unsafePerformIO |
| 18:16:13 | <monochrom> | ... |
| 18:16:14 | <ehird> | Beelsebob: ... |
| 18:16:15 | <ray> | !!! |
| 18:16:23 | <Twey> | ACTION twitches. |
| 18:16:26 | <ehird> | (1) No. (2) NO GOD NO. (3) It's a GD function. |
| 18:16:28 | <Zao> | ACTION kicks Beelsebob in the monads. |
| 18:16:38 | <ray> | what's wrong about image <- loadPngFile |
| 18:16:43 | <Beelsebob> | can anyone give me an example where it behaves in a non pure way? |
| 18:16:59 | <ray> | here's what's wrong about it: nothing |
| 18:17:02 | <Twey> | Beelsebob: It does IO? |
| 18:17:09 | <Beelsebob> | Twey: so does unamb |
| 18:17:14 | <Beelsebob> | so do many pure functions |
| 18:17:21 | <Beelsebob> | + for example |
| 18:17:27 | <Twey> | And what do they do if the IO fails? |
| 18:17:33 | <ehird> | ... + does IO? |
| 18:17:35 | <Beelsebob> | return a Maybe |
| 18:17:37 | <ehird> | LOL WAT |
| 18:17:41 | <Beelsebob> | ehird: sure - it calls into the haskell runtime |
| 18:17:45 | <Zao> | Blowing up far from the call site is something you usually need dynamically typed languages for. |
| 18:17:46 | <ehird> | Oh please. |
| 18:17:50 | <Beelsebob> | a great big impreative lump of code |
| 18:17:57 | <ehird> | Implementation details are NOT the same as API details. |
| 18:17:59 | <Twey> | Um. |
| 18:18:05 | <ehird> | You're silly. |
| 18:18:14 | <Beelsebob> | can you give an example where it behaves in an impure way? |
| 18:18:19 | <Twey> | Every function is impure. Let's go back to Clojure! |
| 18:18:26 | <Beelsebob> | when will it return different values for different calls? |
| 18:18:32 | <mauke> | Beelsebob: when the file changes |
| 18:18:35 | <Beelsebob> | remembering that you guarenteed me that you only call it once |
| 18:18:38 | <Beelsebob> | mauke: he only calls it once |
| 18:18:44 | <mauke> | Beelsebob: irrelevant |
| 18:18:46 | <ehird> | This is ridiculous. Utterly ridiculous. |
| 18:18:52 | <mauke> | Beelsebob: we don't have strict evaluation |
| 18:18:56 | <Beelsebob> | mauke: so? |
| 18:19:09 | <mauke> | so the compiler can evaluate stuff as often as it wants |
| 18:19:09 | <ray> | even if you could use unsafePerformIO safely in theory, why would you do it if you can avoid it |
| 18:19:15 | <mauke> | particularly in the presence of inlining |
| 18:19:30 | <Beelsebob> | mauke: which is why you follow the unsafePerformIO rules and mark it no inline ;) |
| 18:19:34 | <Baughn> | Twey: If unamb fails, in particular, it retries the next time you invoke it |
| 18:20:01 | <Baughn> | Twey: For unsafePerformIO in general, it stores the current state of the IO when it catches an exception, and restarts from there |
| 18:20:34 | <ray> | ehird: i don't think that's ugly, incidentally |
| 18:20:49 | <Beelsebob> | if you only load the file once, you can treat it like a resource - just like your program's code... It is to all intents and purposes a pure value |
| 18:21:00 | <ray> | where's the ugly part? |
| 18:21:27 | <ehird> | does anyone know an alternative to the gd package that doesn't stick everything in IO? |
| 18:22:43 | <deech_> | Sorry, my last message was interrupted by a phone call, but I have a CSV file with some text quoted. There are commas within the quotes, but Text.CSV.ByteString parses them as a column break. Is there any way to tell Text.CSV to ignore commas within quotes? |
| 18:23:06 | <Phyx-> | 20:17:22 * Twey twitches. <-- been doing that alot today, maybe you should see a doctor :P |
| 18:23:30 | <Twey> | Haha :-P |
| 18:23:47 | <Baughn> | deech_: The CSV standard has no "quotes". Or variable-sized fields, for that matter. :P |
| 18:23:55 | <Twey> | Baughn: Reading a file is quite clearly IO, IMO. |
| 18:23:56 | <Baughn> | deech_: I imagine you could propose a patch to do that |
| 18:23:58 | <Beelsebob> | ehird: in the mean time, what I'd really do with that program is main = readWrite =<< getArgs where readWrite [in,out] = wrietFile out . processImage =<< readFile in |
| 18:24:10 | <Baughn> | Twey: The question isn't whether it's IO, it's whether it's semantically pure |
| 18:24:11 | <Twey> | CSV is a standard? |
| 18:24:13 | <Beelsebob> | with a pure processImage function |
| 18:24:22 | <Twey> | But it reads a file |
| 18:24:27 | <Twey> | Of course it isn't semantically pure |
| 18:24:30 | <Baughn> | Twey: Which it is, if only done once. Okay, I admit that's questionable, but there you go |
| 18:24:30 | <deech_> | Baughn : I didn't know csv was a standard either. |
| 18:24:34 | <Baughn> | Twey: "IO" is a misnomer |
| 18:24:41 | <Twey> | It's not just an implementation detail — the goal of the function is to perform IO |
| 18:24:56 | <cob_jonas> | wow, em dash |
| 18:25:07 | <cob_jonas> | with spaces |
| 18:25:08 | <ehird> | Beelsebob: I cannot have a pure processImage. All of the gd functions are in IO. |
| 18:25:10 | <Baughn> | Twey: The IO monad doesn't exist to do IO, it exists to handle impure functions that do IO |
| 18:25:21 | <Twey> | cob_jonas: Unspaced em dashes are the devil |
| 18:25:30 | <Baughn> | deech_: Sort of |
| 18:25:33 | <eivuokko> | Baughn, it's also short to type. |
| 18:25:35 | <Beelsebob> | ehird: fix the library then - image processing is entirely pure |
| 18:25:54 | <Baughn> | deech_: Anyway, there are too many possible ways to quote csv data. You could propose a patch adding support for one, but of course only if it's optional. |
| 18:26:05 | <Twey> | Baughn: I would say that was pretty much the definition of impure |
| 18:26:09 | <cob_jonas> | Twey: IMO em dashes are devil, one should use en dashes, but that's because I've grown up in Hungary where en dashes are standard (and in some fonts they look as wide as em dashes) |
| 18:26:13 | <ehird> | Beelsebob: I cannot. |
| 18:26:18 | <Beelsebob> | why not? |
| 18:26:25 | <Twey> | cob_jonas: En dashes have a separate meaning in English |
| 18:26:33 | <Twey> | Several separate meanings, actually |
| 18:26:46 | <Baughn> | Twey: And I would disagree. IO can be pure, if it's idempotent and gives the same thing every time. |
| 18:27:19 | <Beelsebob> | Twey: is a forgien function call to int jam (void) { return 5; } pure? |
| 18:28:08 | <Twey> | Beelsebob: Yes — that function is intrinsically pure |
| 18:28:13 | <Beelsebob> | but it's in IO |
| 18:28:18 | <Beelsebob> | so it can't be, can it? |
| 18:28:29 | <Twey> | Yes — *that's* a case of pure semantics |
| 18:28:38 | <Twey> | And what I would use unsafePerformIO for |
| 18:28:45 | <Beelsebob> | right then, so your argument that any IO function can't be pure is invalid |
| 18:29:03 | <cob_jonas> | do you mean (return 5 :: IO Int) |
| 18:29:07 | <Philonous> | Beelsebob: Bat readFile is neither side effect free nor even referentially transparent |
| 18:29:10 | <Beelsebob> | similarly callMeOnlyOnceLoadResource :: FilePath -> Something can also be pure |
| 18:29:20 | <Beelsebob> | as long as you meet the precondition |
| 18:29:23 | <Beelsebob> | that you call it only once |
| 18:29:37 | <cob_jonas> | lol |
| 18:29:45 | <Beelsebob> | otherwise, no haskell program is pure - after all, the haskell program is a resource that's loaded from disk |
| 18:30:10 | <Beelsebob> | we just have to guarentee that the OS only loads the program once |
| 18:30:36 | <xoclipse> | hey guys, I made a simple AIM/OSCAR client in haskell, it was a cool little project, if anyone wants to check it out: http://chrismoos.com/2009/05/26/haskell-aim-client-a-cool-proof-of-concept/ |
| 18:30:44 | <Philonous> | Beelsebob: Of course the program is impure, that's why main is in IO |
| 18:30:44 | <Baughn> | Beelsebob: You could use a global variable |
| 18:30:58 | <Baughn> | Beelsebob: Start your onlyOnce function with "putMVar global ()" |
| 18:31:04 | <Beelsebob> | Baughn: that would certainly guarentee the only once bit, yes |
| 18:31:08 | <Beelsebob> | sounds like an execellent plan to me |
| 18:32:37 | <Peaker> | xoclipse: haim is a Hebrew name of a guy |
| 18:32:58 | <Cale> | xoclipse: cool |
| 18:33:11 | <Peaker> | xoclipse: why do you use () around IO args? IO (String) instead of IO String? |
| 18:33:54 | <Peaker> | xoclipse: did you write your own Show instances because you don't like the derived ones? |
| 18:33:57 | <xoclipse> | no particular reason |
| 18:34:14 | <xoclipse> | peaker: i just wanted a little more customization |
| 18:34:31 | <xoclipse> | (for the show instances) |
| 18:34:37 | <Peaker> | xoclipse: why did you wrap a Get that you wrote with a runGet -- instead of just exporting Get values? |
| 18:35:04 | <xoclipse> | which file peaker? |
| 18:35:10 | <Peaker> | xoclipse: tlv.hs |
| 18:35:10 | <xoclipse> | you've got a lot of questions :P |
| 18:35:17 | <xoclipse> | btw i've only been using haskell for ~ month |
| 18:35:27 | <jeff_s_> | ACTION senses someone overusing the Socratic method. |
| 18:35:41 | <Peaker> | xoclipse: oh, awesome work ;) |
| 18:35:43 | <xoclipse> | i used runget because i didn't want the function that cals tlv_get to have to run it |
| 18:36:08 | <xoclipse> | i use runPut and runGet a lot |
| 18:36:13 | <xoclipse> | great functions btw, bytestring is awesome |
| 18:36:18 | <Peaker> | xoclipse: the function that calls tlv_get would have to unpack the tuple and do with the continuation byte-string, which is what Get makes more convenient (and possibly more efficient too) |
| 18:36:58 | <xoclipse> | so tlv_get :: BS.ByteString -> Get (TLV, BS.ByteString) is better? |
| 18:37:15 | <Peaker> | xoclipse: for example, if you look at tlv_extract_lblock -- it calls tlv_get and then uses fst/snd on its result, instead of being able to just use: result <- tlv_get ; use rest of input stream here |
| 18:37:24 | <Peaker> | xoclipse: tlv_get :: Get TLV |
| 18:37:42 | <Peaker> | xoclipse: (Get a) already encapsulates the notion of having a bytestring input and extra bytestring output |
| 18:37:51 | <xoclipse> | ohhh okay |
| 18:37:56 | <xoclipse> | yeah that's my misunderstand of it |
| 18:38:03 | <xoclipse> | great that makes my life easier :) |
| 18:38:06 | <Peaker> | xoclipse: :-) |
| 18:38:35 | <xoclipse> | you try out the client? |
| 18:38:37 | <Peaker> | xoclipse: also, if you have: let result = tlv_get stuff and then you use (fst result) and (snd result) its nicer to use: let (result, somethingElse) = tlv_get stuff ... |
| 18:38:44 | <Peaker> | xoclipse: I don't have an AIM account.. |
| 18:38:47 | <cob_jonas> | so type Get = State BS.ByteString |
| 18:38:52 | <xoclipse> | ah okay |
| 18:38:59 | <xoclipse> | peaker: good points |
| 18:39:07 | <xoclipse> | its a learning process :) |
| 18:39:08 | <xoclipse> | that's why i write thigns like this |
| 18:39:13 | <xoclipse> | each time it gets better |
| 18:39:16 | <Peaker> | xoclipse: sure, its the best way to learn, good job :) |
| 18:39:40 | <Peaker> | xoclipse: its already looking decent, and a lot more than decent if you consider that its just 1 month |
| 18:39:54 | <xoclipse> | :) |
| 18:39:58 | <Twey> | Beelsebob: I didn't have an argument that any IO function (one returning and IO a) was impure |
| 18:40:03 | <Twey> | an** |
| 18:40:12 | <Peaker> | cob_jonas: I guess it could be implemented that way, but its not a good semantic model, because you can only move forward/backward and not arbitrarily change the string |
| 18:40:25 | <xoclipse> | i love the recusriveness of the tlv_extract* functions |
| 18:40:27 | <xoclipse> | i had fun with that |
| 18:40:37 | <xoclipse> | incidentally i really like the OSCAR protocol (SNAC, TLV, etc,.) |
| 18:41:31 | <Peaker> | xoclipse: a nice rule of thumb to know is that prefix-calls are always higher-precedence than infix, so you never need () around them. e.g: if (BS.length stuff) == 0 then ([], BS.empty) else do -- can be: if BS.length stuff == 0 then ... |
| 18:41:41 | <Peaker> | @hoogle ByteString -> Bool |
| 18:41:42 | <lambdabot> | Data.ByteString null :: ByteString -> Bool |
| 18:41:42 | <lambdabot> | Data.ByteString.Char8 null :: ByteString -> Bool |
| 18:41:42 | <lambdabot> | Data.ByteString.Lazy null :: ByteString -> Bool |
| 18:41:57 | <Peaker> | xoclipse: BS.null is basically a comparison of length to 0, except it can be more lazy |
| 18:42:23 | <xoclipse> | okay cool |
| 18:43:12 | <xoclipse> | right the parentheses can go |
| 18:43:19 | <xoclipse> | that's my C/C++/Java background :p |
| 18:43:22 | <xoclipse> | stupid parentheses |
| 18:43:46 | <Peaker> | xoclipse: oh cool, I needed an HaXml example, and now I have one :) |
| 18:43:55 | <cnwdup> | @pl (\f -> f `fmap` get) |
| 18:43:56 | <lambdabot> | (`fmap` get) |
| 18:43:58 | <xoclipse> | yeah, i had fun with that |
| 18:44:03 | <xoclipse> | took me a while to grasp HaXml |
| 18:44:17 | <xoclipse> | i probably stared at the screen for like 15 minutes and just thought |
| 18:44:18 | <xoclipse> | haha |
| 18:44:24 | <Peaker> | xoclipse: I think if you use deriving (Show, Read, ..) you get a show that's just as good, and no need for the boilerplate |
| 18:44:34 | <xoclipse> | great, good to know |
| 18:44:47 | <cob_jonas> | I just decided the "xml" library looks better |
| 18:45:08 | <cnwdup> | @pl (\f -> get >>= put . f) |
| 18:45:08 | <lambdabot> | (get >>=) . (put .) |
| 18:45:22 | <Peaker> | xoclipse: a pattern-match of (host:(port:(cookie:xs))) needs no () because : is already right-associative host:port:cookie:xs |
| 18:45:32 | <cnwdup> | @pl (\f -> put . f =<< get) |
| 18:45:32 | <lambdabot> | (get >>=) . (put .) |
| 18:45:37 | <xoclipse> | :) |
| 18:46:35 | <Peaker> | xoclipse: its nicer to have f . g . h . i $ x than: f $ g $ h $ i $ x, too |
| 18:47:09 | <Peaker> | let sig = encode $ BS.unpack $ bytestringDigest $ hmacSha256 (BS.pack $ sessionKey info) (BS.pack hashData) --> let sig = encode . BS.unpack . bytestringDigest . hmacSha256 (BS.pack $ sessionKey info) . BS.pack $ hashData |
| 18:47:34 | <cob_jonas> | I still think usually just parenthesis are better than $ |
| 18:47:56 | <Peaker> | does ByteString.Char8 do utf8 or just (`mod`256)? |
| 18:48:13 | <Peaker> | cob_jonas: its really nice to be able to cut & paste any subset of the "pipe-line" out to its own function |
| 18:48:15 | <jeff_s_> | not utf8 |
| 18:48:31 | <Peaker> | how do you convert String -> ByteString with some unicode encoding? |
| 18:48:50 | <Zao> | Peaker: Data.Text? |
| 18:48:53 | <cob_jonas> | Peaker: the encoding module |
| 18:49:06 | <xoclipse> | okay i'll use the f .g etc,. |
| 18:49:41 | <Peaker> | xoclipse: also, underscore convention isn't very common - the entire library/etc are all in camelCase |
| 18:50:09 | <cob_jonas> | yeah, but undescores are actually more readable |
| 18:50:16 | <cob_jonas> | ACTION ducks |
| 18:50:52 | <xoclipse> | okay |
| 18:51:48 | <xoclipse> | okay, i'm out for now |
| 18:51:52 | <xoclipse> | thanks for the tips, Peaker |
| 18:52:20 | <Peaker> | xoclipse: sure thing |
| 18:52:44 | <Peaker> | cob_jonas: a mishmash is less readable than either convention uniform though, and names less guessable |
| 18:53:17 | <Baughn> | So dromedarCase it is |
| 18:53:21 | <Baughn> | And CamelCase for types |
| 18:53:47 | <cob_jonas> | yeah |
| 18:53:56 | <cob_jonas> | but that's only if you give verbose names like the libraries |
| 18:54:34 | <cob_jonas> | if you use abbrevs like mk_wrd then camelCasing doesn't make it any more mish-mash or predictability |
| 18:54:41 | <cob_jonas> | it's two conventions either way |
| 18:56:13 | <burp> | @pl f x y z = x^2+y^3+z^4 |
| 18:56:13 | <lambdabot> | f = flip flip (^ 4) . (((.) . (+)) .) . (. (^ 3)) . (+) . (^ 2) |
| 18:58:08 | <cob_jonas> | > let { f x y z = x^2+y^3+z^4 } in f x y z |
| 18:58:10 | <lambdabot> | x * x + y * y * y + z * z * (z * z) |
| 19:03:10 | <ehird> | 19:54 cob_jonas: if you use abbrevs like mk_wrd then camelCasing doesn't make it any more mish-mash or predictability |
| 19:03:11 | <ehird> | 19:54 cob_jonas: it's two conventions either way |
| 19:03:13 | <ehird> | so don't do that |
| 19:05:18 | <zong_sharo> | does pattern matching strict or lazy by default? (eg, w/o ! or ~) |
| 19:05:54 | <pumpkin> | > let f (x, y) = 5 in f undefined |
| 19:05:56 | <lambdabot> | * Exception: Prelude.undefined |
| 19:05:59 | <pumpkin> | :) |
| 19:06:09 | <pumpkin> | > let f ~(x, y) = 5 in f undefined |
| 19:06:10 | <lambdabot> | 5 |
| 19:07:02 | <mmorrow> | , let x = undefined in 20 |
| 19:07:05 | <lunabot> | 20 |
| 19:07:11 | <mmorrow> | , let (x,y) = undefined in 20 |
| 19:07:13 | <lunabot> | 20 |
| 19:08:01 | <mmorrow> | let matches are lazy and case matches are strict (patterns in the params of a function == case) (unless you use ~ like pumpkin) |
| 19:08:29 | <Peaker> | mmorrow: is there a difference between let ~(x,y) = and let (x,y) = ? |
| 19:08:42 | <mmorrow> | hmm |
| 19:08:42 | <Cale> | zong_sharo: In function bindings, pattern matching forces evaluation when the function is applied. In pattern bindings, it's like there's an implicit ~ at the front of the pattern. The pattern is only matched if you use one of the variables it binds. |
| 19:09:11 | <Beelsebob> | Peaker: yes |
| 19:09:18 | <Cale> | Peaker: no |
| 19:09:31 | <pumpkin> | Peaker: maybe (given the previous two answers) |
| 19:09:35 | <Peaker> | heh |
| 19:09:37 | <Beelsebob> | the first one will start evaluating the right hand side before the (_|_, _|_) is produced |
| 19:10:10 | <cob_jonas> | but note that |
| 19:10:13 | <Beelsebob> | > let f ~(x,y) = 5 in f undefined |
| 19:10:15 | <lambdabot> | 5 |
| 19:10:18 | <Beelsebob> | > let f (x,y) = 5 in f undefined |
| 19:10:19 | <lambdabot> | * Exception: Prelude.undefined |
| 19:10:22 | <cob_jonas> | > let { f (x, y) = (); } in seq (f undefined) () |
| 19:10:23 | <lambdabot> | * Exception: Prelude.undefined |
| 19:10:24 | <Beelsebob> | see... there's a difference |
| 19:10:26 | <cob_jonas> | > let { f (x, y) _ = (); } in seq (f undefined) () |
| 19:10:28 | <lambdabot> | () |
| 19:10:33 | <Peaker> | > let (x,y) = undefined in 5 |
| 19:10:35 | <lambdabot> | 5 |
| 19:10:38 | <Peaker> | > let ~(x,y) = undefined in 5 |
| 19:10:39 | <Cale> | 'A pattern binding binds variables to values. A simple pattern binding has form p = e. The pattern p is matched "lazily" as an irrefutable pattern, as if there were an implicit ~ in front of it.' |
| 19:10:39 | <lambdabot> | 5 |
| 19:10:42 | <Peaker> | this behavior is weird |
| 19:10:44 | <zong_sharo> | Cale: thx |
| 19:10:52 | <Cale> | (From the Report) |
| 19:10:58 | <cob_jonas> | Peaker: it is, but it's right |
| 19:10:59 | <Beelsebob> | oh hang on, I read your pattern wrong |
| 19:11:05 | <mmorrow> | Peaker: the let match is never attempted if it isn't needed |
| 19:11:32 | <Cale> | However, ! has the power to turn let into case :) |
| 19:11:40 | <Cale> | > let !(x,y) = undefined in 5 |
| 19:11:43 | <lambdabot> | * Exception: Prelude.undefined |
| 19:11:43 | <Peaker> | I see -- so argument pattern matches of functions defined by let are not irrefutable |
| 19:11:47 | <mmorrow> | bang! |
| 19:12:04 | <Peaker> | hmm.. I think let ~(x,y) ... should be a syntax error if its no different to let (x,y) = ... |
| 19:12:17 | <cob_jonas> | Peaker: why? that wouldn't be really consistent |
| 19:12:31 | <Cale> | Of course you should be able to nest ~'s |
| 19:12:39 | <Peaker> | cob_jonas: its already inconsistent -- let has different semantics, why should it have the same syntax? |
| 19:12:44 | <Cale> | They're idempotent, but it doesn't hurt to allow it. |
| 19:13:36 | <Cale> | Peaker: It's unnatural to have only one place in a pattern where ~ isn't allowed and only in the case of let |
| 19:14:05 | <Cale> | Note that things like let (~(x:xs),ys) = ... can still be useful |
| 19:14:09 | <cob_jonas> | Cale: well, let woulnd't be the only case |
| 19:14:31 | <cob_jonas> | top-level bindings and postfix where and do-let statements has that too |
| 19:14:38 | <Cale> | Well, sure. |
| 19:14:51 | <cob_jonas> | but I think there's no point banning ~ there |
| 19:14:56 | <Cale> | I suppose I mean "only pattern bindings" |
| 19:16:06 | <Cale> | > let x + 1 = 0 in 5 + 1 |
| 19:16:08 | <lambdabot> | 0 |
| 19:16:12 | <Cale> | > let (x + 1) = 0 in 5 + 1 |
| 19:16:14 | <lambdabot> | 6 |
| 19:16:19 | <Peaker> | Cale: it can also be disallowed to use ! in case !foo .. |
| 19:16:29 | <Cale> | > let (x + 1) = 0 in x |
| 19:16:31 | <lambdabot> | * Exception: <interactive>:1:145-155: Irrefutable pattern failed for patter... |
| 19:16:38 | <Cale> | > let (x + 1) = 5 in x |
| 19:16:40 | <lambdabot> | 4 |
| 19:16:56 | <Lemmih> | ACTION grins. |
| 19:16:57 | <Cale> | > let x + 1 = 5 in x |
| 19:16:59 | <lambdabot> | x |
| 19:17:04 | <Cale> | :) |
| 19:17:14 | <Cale> | lol, simplereflect |
| 19:17:17 | <cob_jonas> | Peaker: oh no, ! is completely different I think |
| 19:17:29 | <Peaker> | Cale: I see, I think my problem is that let is irrefutable by default on the outside, and not irrefutable anywhere else, that's weird |
| 19:17:45 | <Peaker> | why isn't let strict like case? add ~ for irrefutable ones? |
| 19:18:13 | <Cale> | Well, usually you don't want all your let-bound things evaluating before they're needed. |
| 19:18:32 | <arcatan> | i want to use hGetBuf, but how can I create a buffer where it would write? |
| 19:18:36 | <Cale> | (and I'm including the top-level and where clauses, etc. in that) |
| 19:18:50 | <hatds> | lazy lets are useful, if you made it strict I'd demand a lazy replacement :) |
| 19:18:52 | <Cale> | let is all about putting things on the heap, not evaluation. |
| 19:18:55 | <cob_jonas> | Cale: that's not _all_ your let bound things, only the rarer case when you let bind to a constructor pattern (or numeric etc) |
| 19:19:06 | <cob_jonas> | still I think the current haskell semantics is great |
| 19:19:13 | <Peaker> | Cale: yeah, I see, I think the "right" thing is to just not allow lets to pattern-match, but that would be a little inconvenient given current syntax |
| 19:19:21 | <cob_jonas> | it's easy to remember and is chosen right |
| 19:19:24 | <Cale> | cob_jonas: Well, sure, function bindings are already in WHNF :) |
| 19:19:39 | <cob_jonas> | Cale: also plain bindings to a variable |
| 19:19:42 | <Cale> | Peaker: It's handy, and it does what you want. :) |
| 19:20:02 | <Peaker> | it behaves weird, though |
| 19:20:18 | <Cale> | Peaker: It just takes a little thinking to realise that this strange-seeming behaviour really is what you want most of the time :) |
| 19:21:34 | <Baughn> | What was the difference between HNF and WHNF again, exactly? |
| 19:21:42 | <Cale> | > let fibs@(x:fibs') = 0 : 1 : zipWith (+) fibs fibs' in fibs |
| 19:21:44 | <lambdabot> | [0,1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,1597,2584,4181,6765,10946... |
| 19:21:58 | <Cale> | Baughn: I seem to recall something about evaluation under lambdas? |
| 19:22:49 | <Cale> | right. |
| 19:23:02 | <Cale> | \x -> ((\y -> y+x) 2) |
| 19:23:08 | <Cale> | is in WHNF, but not HNF. |
| 19:23:12 | <Peaker> | Baughn: http://encyclopedia2.thefreedictionary.com/Weak+Head+Normal+Form |
| 19:23:18 | <pumpkin> | how does Clean's uniqueness typing deal with forking and concurrency? |
| 19:23:39 | <Cale> | So the difference is that WHNF doesn't evaluate underneath a lambda |
| 19:25:35 | <Peaker> | It could probably do the reduction inside inner lambda's, I don't see why it would have a rename problem - it doesn't actually need to use string names.. |
| 19:25:39 | <Baughn> | , tipe `fmap` getClosureData 42 |
| 19:25:41 | <lunabot> | luna: Not in scope: `tipe' |
| 19:26:05 | <Phyx-> | :type getClosureData |
| 19:26:10 | <Phyx-> | @type getClosureData |
| 19:26:11 | <lambdabot> | Not in scope: `getClosureData' |
| 19:26:16 | <Cale> | Peaker: hm? |
| 19:26:25 | <Baughn> | Peaker: Okay, so HNF is a subset of WHNF |
| 19:26:26 | <Baughn> | That makes sense |
| 19:26:27 | <Cale> | Peaker: HNF reduces inside lambdas, WHNF doesn't |
| 19:27:44 | <Baughn> | ACTION continues mutilating haskell's semantics |
| 19:27:51 | <pumpkin> | Baughn: did you figure out if you could link to that table? |
| 19:28:09 | <Baughn> | pumpkin: Not yet, had an exam today. I'm just starting on that now. |
| 19:28:59 | <pumpkin> | Baughn: do you see what I mean by the U symbol though? |
| 19:29:12 | <Baughn> | pumpkin: Yes, but it's mistaken |
| 19:29:28 | <Baughn> | Each RTS .a defines /multiple/ closure_flags symbols |
| 19:29:36 | <Baughn> | One D, the others U |
| 19:29:50 | <pumpkin> | hmm |
| 19:29:55 | <pumpkin> | I didn't see that in mine |
| 19:29:57 | <hackagebot> | hack-middleware-gzip 0.0.0 |
| 19:30:27 | <Baughn> | pumpkin: for i in *a; do echo $i; nm $i |grep closure_flags; done |
| 19:30:32 | <Cale> | Odd, despite the language spec being called "The Concurrent Clean Language Report", I'm having trouble finding any actual mention of concurrency in it at all. |
| 19:30:34 | <Baughn> | In /usr/local/lib/ghc*/ |
| 19:30:59 | <Cale> | Is it just the report itself which is concurrent? |
| 19:32:40 | <pumpkin> | Baughn: oh I see |
| 19:33:41 | <Baughn> | pumpkin: So I'll get this working now, but the overhead from actually /linking/ that is so enormous, it'll have to wait for 6.12 |
| 19:33:45 | <Baughn> | And dynamic linking |
| 19:33:55 | <pumpkin> | why? |
| 19:33:58 | <Cale> | Oh, version 1.3.1 had process annotations which look like they're related to parallelism or concurrency, but they were apparently removed in 2.0 |
| 19:34:02 | <Baughn> | 22MB hello,world |
| 19:34:24 | <Cale> | That's somewhat embarrassing if the most recent standard for Concurrent Clean doesn't support concurrency though. |
| 19:34:46 | <pumpkin> | lol |
| 19:34:49 | <pumpkin> | yeah |
| 19:34:56 | <pumpkin> | how would uniqueness typing deal with that though? |
| 19:34:59 | <pumpkin> | was it just too complicated? |
| 19:35:12 | <Peaker> | Cale: was talking about what http://encyclopedia2.thefreedictionary.com/Weak+Head+Normal+Form said |
| 19:35:56 | <deech_> | Hi all, is there a Haskell library that will convert an HTML text with diacritics into a Haskell String? |
| 19:36:30 | <Cale> | pumpkin: hmm, it doesn't say anything about the interation of parallelism with I/O |
| 19:37:31 | <Cale> | pumpkin: Oh, hmm, it appears that I'm looking in the wrong place for stuff about concurrency. There's supposed to be a library... |
| 19:39:42 | <andouille> | I saw that yesterday: http://en.wikibooks.org/wiki/Haskell/Solutions/List_processing and I didn't manage to understand little things like 'x == y' in the encode function |
| 19:39:52 | <andouille> | Can you help me please, it's for coding a RLE |
| 19:40:11 | <Cale> | okay |
| 19:40:23 | <Cale> | deech_: I'm not sure. There are various HTML parsing libraries though |
| 19:41:02 | <Cale> | andouille: The x == y is a guard |
| 19:41:18 | <Cale> | andouille: Only if x == y gives True does that equation apply. |
| 19:41:32 | <Cale> | andouille: Otherwise, the 'otherwise' case is used. |
| 19:41:59 | <Cale> | That is, if x == y then the result of encode (x:y:xs) is succHead (encode (y:xs)) |
| 19:42:02 | <Baughn> | andouille: "otherwise" is just a global binding to True, by the way. It's not syntax. |
| 19:42:24 | <andouille> | SO if 'x == y', what does it means concretly for the list ? |
| 19:42:36 | <cob_jonas> | @type (==) |
| 19:42:37 | <lambdabot> | forall a. (Eq a) => a -> a -> Bool |
| 19:42:40 | <Cale> | andouille: That the first two elements are equal |
| 19:42:45 | <cob_jonas> | > 3 == 5 |
| 19:42:46 | <lambdabot> | False |
| 19:42:48 | <cob_jonas> | > 3 == 3 |
| 19:42:49 | <lambdabot> | True |
| 19:42:50 | <cob_jonas> | > 3 == 2 |
| 19:42:51 | <andouille> | does it means that @type(==) |
| 19:42:52 | <lambdabot> | False |
| 19:42:54 | <Baughn> | andouille: (x:y:xs), see |
| 19:42:58 | <andouille> | omg sorry |
| 19:43:09 | <andouille> | Ok thanks |
| 19:43:11 | <Phyx-> | > otherwise && otherwise |
| 19:43:12 | <lambdabot> | True |
| 19:43:14 | <Phyx-> | lol |
| 19:43:16 | <Cale> | andouille: (x:y:xs) is the list whose first two elements are x and y respectively, and the rest is called xs |
| 19:43:18 | <Phyx-> | now that's funny |
| 19:43:53 | <Peaker> | > otherwise |
| 19:43:54 | <lambdabot> | True |
| 19:44:02 | <Cale> | andouille: I think I should point out that this way uses way too much explicit recursion, and isn't really making the most of library functions :) |
| 19:44:09 | <andouille> | Ok, I used to think that it was the first element that's x, the rest that's y and the last one that's xs. |
| 19:44:12 | <Baughn> | andouille: Or, in a pattern-match context, it's a pattern-match that decomposes such a list into the originating x, y and xs :) |
| 19:44:12 | <andouille> | Thanks |
| 19:44:22 | <Baughn> | > 2:3:[4..7] |
| 19:44:22 | <Cale> | > map (\xs -> (length xs, head xs)) . group $ "mississippi" |
| 19:44:23 | <lambdabot> | [2,3,4,5,6,7] |
| 19:44:24 | <lambdabot> | [(1,'m'),(1,'i'),(2,'s'),(1,'i'),(2,'s'),(1,'i'),(2,'p'),(1,'i')] |
| 19:44:40 | <Baughn> | > 2:3:0:[4..7] -- andouille: See? Simple. |
| 19:44:41 | <lambdabot> | [2,3,0,4,5,6,7] |
| 19:44:50 | <Cale> | > map (\xs -> (length xs, head xs)) . group $ "ruuuuunnnnnn lllleeeennnnnngggttthh" |
| 19:44:52 | <lambdabot> | [(1,'r'),(5,'u'),(6,'n'),(3,' '),(4,'l'),(4,'e'),(6,'n'),(3,'g'),(3,'t'),(2... |
| 19:44:55 | <andouille> | :D |
| 19:45:18 | <pumpkin> | aw, no &&& ? |
| 19:45:31 | <pumpkin> | Control.Arrow needs lovin too |
| 19:45:34 | <Baughn> | > map (length &&& head) . group $ "ruuuun length" |
| 19:45:35 | <lambdabot> | [(1,'r'),(4,'u'),(1,'n'),(1,' '),(1,'l'),(1,'e'),(1,'n'),(1,'g'),(1,'t'),(1... |
| 19:46:01 | <hackagebot> | hack-handler-kibro 2009.5.27 |
| 19:46:01 | <hackagebot> | bamboo 2009.5.27 |
| 19:46:22 | <pumpkin> | > concatMap (uncurry replicate) . map (length &&& head) . group $ "ruuuun length" |
| 19:46:23 | <lambdabot> | "ruuuun length" |
| 19:46:26 | <Cale> | > concatMap (\(n,x) -> replicate n x) $ [(1,'r'),(5,'u'),(6,'n'),(3,' '),(4,'l'),(4,'e'),(6,'n'),(3,'g'),(3,'t'),(2,h)] |
| 19:46:28 | <lambdabot> | No instance for (SimpleReflect.FromExpr GHC.Types.Char) |
| 19:46:28 | <lambdabot> | arising from a u... |
| 19:46:32 | <andouille> | How could I find a really good tutorial or a documentation for all the "operators" like '.' or '$' please |
| 19:46:32 | <Cale> | oops |
| 19:46:37 | <Cale> | > concatMap (\(n,x) -> replicate n x) $ [(1,'r'),(5,'u'),(6,'n'),(3,' '),(4,'l'),(4,'e'),(6,'n'),(3,'g'),(3,'t'),(2,'h')] |
| 19:46:38 | <lambdabot> | "ruuuuunnnnnn lllleeeennnnnngggttthh" |
| 19:47:03 | <cob_jonas> | ($) is just identity restricted to functions, (.) is function composition |
| 19:47:05 | <Cale> | So basically, whoever wrote that code didn't know about... map, concatMap, group, replicate... :) |
| 19:47:08 | <Baughn> | andouille: Well, . and $ are just function composition and application respectively |
| 19:47:23 | <pumpkin> | > uncurry replicate =<< (map (length &&& head) . group $ "ruuuun length") |
| 19:47:24 | <lambdabot> | "ruuuun length" |
| 19:47:25 | <Cale> | @src (.) |
| 19:47:26 | <lambdabot> | (f . g) x = f (g x) |
| 19:47:34 | <hatds> | I think what you are asking for is to be directed towards a list of prelude functions and their definitions |
| 19:47:46 | <andouille> | ok, but where can I learn to use map, replicate or other things lique that (pre-built functions ?) ? |
| 19:47:48 | <Cale> | andouille: (.) takes two functions f and g and makes a function which when applied to x gives f (g x) |
| 19:48:04 | <andouille> | hatds, exactly ;) |
| 19:48:12 | <cob_jonas> | dunno, some book? |
| 19:48:12 | <Cale> | andouille: $ takes a function and a value to apply it to, and applies the function |
| 19:48:16 | <Cale> | @src ($) |
| 19:48:17 | <hatds> | http://www.haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html |
| 19:48:18 | <lambdabot> | f $ x = f x |
| 19:48:22 | <Baughn> | andouille: I don't recall ever reading such a tutorial; you learn by using them |
| 19:48:34 | <Baughn> | andouille: Start by walking through all the prelude functions. :) |
| 19:48:38 | <Cale> | This seems pointless, but the main purpose of it is that $ has really low precedence |
| 19:48:54 | <Baughn> | > map ($ 3) [(+1),(*2)] -- Also this |
| 19:48:56 | <lambdabot> | [4,6] |
| 19:49:03 | <Cale> | So it's as if you've wrapped both sides in parens |
| 19:49:20 | <andouille> | ok |
| 19:49:28 | <andouille> | thank you very much |
| 19:49:37 | <cob_jonas> | (and then all functions of Data.List and Control.Monad and Data.Maybe, most importantly foldr and foldl') |
| 19:51:59 | <cob_jonas> | but another method to learn all the funny function is to hang around here and listen and ask questions and sooner or later you'll meet the more useful functions |
| 19:52:05 | <cob_jonas> | at least I found that works |
| 19:52:09 | <Cale> | He quit for some reason |
| 19:52:36 | <cob_jonas> | yeah, I see |
| 19:52:39 | <cob_jonas> | still |
| 19:53:49 | <cob_jonas> | I found that works |
| 19:54:04 | <cob_jonas> | I mean how'd I guess which of the lots of functions to look at? |
| 19:54:16 | <cob_jonas> | if I see them here in use I can pick the useful modules and functions |
| 19:54:43 | <cob_jonas> | @type liftM2 |
| 19:54:45 | <lambdabot> | forall a1 a2 r (m :: * -> *). (Monad m) => (a1 -> a2 -> r) -> m a1 -> m a2 -> m r |
| 19:54:45 | <cob_jonas> | @type liftA2 |
| 19:54:47 | <lambdabot> | forall a b c (f :: * -> *). (Applicative f) => (a -> b -> c) -> f a -> f b -> f c |
| 19:57:51 | <kniu> | Do full record types make positionally-accessed types obsolete? |
| 19:59:00 | <cob_jonas> | kniu: what positionally accessed types? |
| 19:59:03 | <Twey> | kniu: They should do, for flexibility |
| 19:59:29 | <Twey> | A record type is usually a big type whose members are likely to change during the course of development |
| 19:59:54 | <Twey> | Accessing it solely via record syntax and the provided getters allows that to be done without it becoming a problem |
| 20:00:04 | <Twey> | Accessing it positionally would break that |
| 20:00:14 | <kniu> | k |
| 20:03:48 | <Baughn> | "isHNF :: a -> IO Bool" <-- Oh yeah, there we go. |
| 20:04:27 | <pumpkin> | does it actually work right? Cale tried that code we found on the mailing list last night and it didn't look too correct |
| 20:04:45 | <Cale> | What? |
| 20:04:48 | <Baughn> | ..well, I'm about to find out. |
| 20:05:04 | <Cale> | I found an isWHNF on the mailing list, but it was totally broken. |
| 20:05:11 | <pumpkin> | yeah :) |
| 20:05:43 | <Cale> | Also, it still had the problem that error "foo" has the same ClosureType as 5 |
| 20:06:29 | <Baughn> | Even after rwhnf'ing 5? |
| 20:07:02 | <pumpkin> | does that do anything? |
| 20:07:08 | <Cale> | yeah. |
| 20:07:24 | <pumpkin> | what type does it give 5? |
| 20:07:24 | <Cale> | Or making it monomorphic. |
| 20:07:26 | <Cale> | AP |
| 20:08:09 | <Cale> | oh... |
| 20:08:32 | <Cale> | *Main Control.Parallel.Strategies> let x = 5 :: Integer in rwhnf x `seq` getClosureType x |
| 20:08:32 | <Cale> | Indirection 28 |
| 20:08:45 | <Cale> | But the code which they had for handling indirections is broken. |
| 20:09:53 | <Baughn> | So I'll have to fix that, I guess |
| 20:11:07 | <hackagebot> | hack-middleware-jsonp 0.0.0 |
| 20:12:37 | <Cale> | Baughn: http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5284#a5284 |
| 20:14:23 | <Baughn> | Cale: An AP's a thunk type, though |
| 20:14:42 | <Baughn> | Cale: It may have been rwhnf'd, but it.. isn't in HNF |
| 20:15:07 | <Cale> | It's because x is polymorphic |
| 20:15:26 | <Cale> | But somehow it doesn't show up as Fun like I'd expect. |
| 20:18:04 | <Cale> | (It ought to be a function of the typeclass dictionary, shouldn't it? |
| 20:18:05 | <Cale> | ) |
| 20:18:17 | <Cale> | Oh, I see. |
| 20:18:31 | <Cale> | Those are two separate x's. |
| 20:19:41 | <Cale> | So it's like rwhnf (x instanceNumInteger) `seq` getClosureType (x instanceNumInteger) |
| 20:19:46 | <Cale> | It doesn't help :) |
| 20:19:55 | <Cale> | *Main Control.Parallel.Strategies> let x = 5; y = x :: Integer in rwhnf y `seq` getClosureType y |
| 20:19:56 | <Cale> | Indirection 28 |
| 20:20:01 | <Cale> | That works though. |
| 20:20:31 | <Cale> | *Main Control.Parallel.Strategies> let x = 5; y = x :: Integer in y `seq` getClosureType y |
| 20:20:31 | <Cale> | Constr |
| 20:20:32 | <Cale> | and that |
| 20:21:14 | <hackagebot> | hack-middleware-cleanpath 0.0.0 |
| 20:21:21 | <Cale> | Now, if only we could see past the indirections... |
| 20:22:05 | <Cale> | Baughn: oh, another strange and unexpected one: |
| 20:22:08 | <Cale> | *Main Control.Parallel.Strategies> getClosureType "a" |
| 20:22:08 | <Cale> | Constr |
| 20:22:08 | <Cale> | *Main Control.Parallel.Strategies> getClosureType "ab" |
| 20:22:08 | <Cale> | AP |
| 20:22:23 | <Cale> | *Main Control.Parallel.Strategies> getClosureType ('a':'b':[]) |
| 20:22:23 | <Cale> | Constr |
| 20:22:33 | <pumpkin> | why are those different? |
| 20:23:04 | <Cale> | I have no idea. I thought it might have something to do with the polymorphic strings extension. |
| 20:23:13 | <Cale> | But "a" is still in string syntax. |
| 20:23:36 | <Cale> | So if it really was that extension, it should be AP too. |
| 20:23:39 | <pumpkin> | yeah |
| 20:23:49 | <Cale> | (because it'd be fromString "a" or whatever) |
| 20:23:58 | <pumpkin> | you could try running it all under XOverloadedStrings ? |
| 20:24:19 | <Cale> | same results |
| 20:29:42 | <Jedai> | There is all this optimisation stuff with unpackCString and so on |
| 20:30:13 | <Jedai> | It could be what's causing the difference between those case |
| 20:30:25 | <pumpkin> | I thought that was only when you actually compile things |
| 20:30:57 | <Jedai> | pumpkin: I must admit that I'm not too sure of wether that's the case or not |
| 20:31:30 | <Jedai> | It was just an hypothesis to try and explain this weird result |
| 20:34:18 | <Baughn> | ..oh dear, got to use an unsafeCoerce here |
| 20:34:51 | <Baughn> | @index unsafeCoerce |
| 20:34:52 | <lambdabot> | bzzt |
| 20:35:01 | <Botje> | System.Unsafe, i guess? |
| 20:35:07 | <Baughn> | Unsafe.Coerce, actually |
| 20:35:13 | <Botje> | oh. boo :) |
| 20:37:07 | <pumpkin> | nothing more fun than unsafeCoerce |
| 20:37:10 | <pumpkin> | except unsafeCoerce# |
| 20:37:39 | <pumpkin> | actually, probably a lot of things more fun than that :P |
| 20:38:22 | <pumpkin> | bbl :) |
| 20:38:56 | <Peaker> | @type System.Unsafe.Coerce.unsafeCoerce |
| 20:38:58 | <lambdabot> | Couldn't find qualified module. |
| 20:39:01 | <Peaker> | @type Unsafe.Coerce.unsafeCoerce |
| 20:39:03 | <lambdabot> | forall a b. a -> b |
| 20:39:13 | <Peaker> | System.Unsafe vs Unsafe? Hmm |
| 20:44:27 | <Cale> | Baughn: I tried using unsafeCoerce for following the indirections, but wasn't able to get anything but a segfault. However, I have no idea what I'm doing :) |
| 20:46:07 | <Baughn> | Cale: Hm. Well, basically HValue is a wrapper for.. any lifted type |
| 20:46:15 | <Baughn> | I got it working. :D |
| 20:46:23 | <Cale> | Oh, interesting. |
| 20:46:43 | <Baughn> | http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5285#a5285 |
| 20:47:08 | <duaneb> | man |
| 20:47:15 | <duaneb> | ocaml is so unfunctional |
| 20:47:16 | <duaneb> | :P |
| 20:47:22 | <duaneb> | it's kind of painful to read ocaml code |
| 20:47:30 | <Cale> | Oh, heh, I see what I did wrong. :) |
| 20:47:30 | <duaneb> | it's like a really ugly c |
| 20:47:48 | <Baughn> | Cale: That would be? |
| 20:48:19 | <Cale> | Getting the parameters in the wrong order and not being warned by the typechecker because one was unsafeCoerced and the other polymorphic :) |
| 20:48:19 | <arcatan> | no, ocaml is like better C |
| 20:48:27 | <Baughn> | Cale: Eheh. ^^; |
| 20:48:33 | <duaneb> | arcatan: how so? |
| 20:48:33 | <lament> | better, uglier C? |
| 20:48:51 | <duaneb> | it seems like a less-f'd up C++ |
| 20:48:59 | <duaneb> | but with boxed types |
| 20:49:22 | <duaneb> | and an option for tail recursion :P |
| 20:50:09 | <Cale> | Baughn: Should there be any difference between unsafeCoerce and unsafeCoerce# here? |
| 20:50:40 | <Baughn> | Cale: No, they're equal |
| 20:51:15 | <Cale> | *Main Control.Parallel.Strategies> let x = 5 :: Integer in rwhnf x `seq` getClosureType x |
| 20:51:15 | <Cale> | Indirection 28 |
| 20:51:15 | <Cale> | *Main Control.Parallel.Strategies> let x = 5 :: Integer in rwhnf x `seq` removingIndirections getClosureType x |
| 20:51:15 | <Cale> | AP |
| 20:51:21 | <Cale> | hmm |
| 20:53:00 | <Cale> | ACTION suddenly wishes that GHC preserved expressions somehow. :) |
| 20:54:20 | <Cale> | Baughn: Shouldn't it still be isWHNF? You're actually not looking underneath functions... |
| 20:54:46 | <Baughn> | Cale: Near as I can tell, HNF is a subset of WHNF, and this function is only complete for HNF |
| 20:54:50 | <Baughn> | ..well, not even that, really |
| 20:55:01 | <Baughn> | But I'm not very sure of the terminology. :/ |
| 20:55:12 | <Cale> | I get PAP for (\x -> x+1) which is in HNF |
| 20:55:34 | <Cale> | and your function will produce False for that... |
| 20:55:50 | <Cale> | (it's also in WHNF) |
| 20:56:09 | <Baughn> | True. I'm not sure whether producing True for PAP is /safe/ or not, since I'm not sure what PAP really is. |
| 20:56:23 | <Baughn> | In this case, bogus False is safe; bogus True isn't |
| 20:56:26 | <Cale> | yeah, it would be good to figure that out... :) |
| 20:56:47 | <Cale> | I wonder where all these types are really documented... |
| 20:58:40 | <Cale> | "Entry Code for an AP (a PAP with arity zero)." |
| 20:58:57 | <Baughn> | I see |
| 20:59:10 | <Baughn> | So.. (\x -> error "foo") would be PAP too |
| 20:59:18 | <Baughn> | Well, certainly can't return True for that. :) |
| 20:59:23 | <Baughn> | Hm. Actually, I could |
| 20:59:27 | <Baughn> | .. |
| 20:59:27 | <Cale> | That should be in WHNF |
| 20:59:40 | <Baughn> | Right, evaluating a function succeeds, even if /calling/ the function would fail |
| 20:59:44 | <Baughn> | So PAP => True is safe |
| 20:59:57 | <Baughn> | AP, not so much |
| 21:00:05 | <Cale> | right |
| 21:00:29 | <mib_xxfkjqs6> | hey |
| 21:00:37 | <mib_xxfkjqs6> | wondering if anone can help me |
| 21:00:39 | <Baughn> | I didn't bother with defining a case for Blackhole, but have you seen anything that produces it? |
| 21:00:56 | <mib_xxfkjqs6> | im trying to sort some data in haskell |
| 21:00:59 | <mib_xxfkjqs6> | http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5286 |
| 21:01:18 | <mib_xxfkjqs6> | by fans has anyone got any ideas |
| 21:01:25 | <Cale> | Baughn: It probably ought to be treated as not in WHNF |
| 21:01:39 | <Baughn> | Cale: Yes, but if it's at all useful I might add a third return value |
| 21:01:49 | <Baughn> | WHNF, Undecided and Bottom |
| 21:02:05 | <Cale> | mib_xxfkjqs6: By number of fans? |
| 21:02:12 | <mib_xxfkjqs6> | yea |
| 21:02:38 | <Cale> | fanCount (Film t d y fs) = length fs |
| 21:02:43 | <mib_xxfkjqs6> | was going to length the fan list |
| 21:02:52 | <Cale> | and then, sortBy (comparing fanCount) films |
| 21:03:03 | <mib_xxfkjqs6> | ah awesome |
| 21:03:04 | <Cale> | But that's not terribly efficient. |
| 21:03:06 | <mib_xxfkjqs6> | thanks |
| 21:03:28 | <mib_xxfkjqs6> | ok |
| 21:03:41 | <Cale> | another way is to map (\x -> (fanCount x, x)) over the list and then sortBy (comparing fst) |
| 21:03:44 | <mib_xxfkjqs6> | is there a better way that i could look into |
| 21:03:54 | <Baughn> | @tell conal http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5289#a5290 <-- Here's the latest version of Unamb, with WHNF-detection. It appears to work, but YMMV. |
| 21:03:54 | <lambdabot> | Consider it noted. |
| 21:04:08 | <Cale> | map snd . sortBy (comparing fst) $ [(fancount x, x) | x <- films] |
| 21:04:33 | <Cale> | That way, you only compute the number of fans once per film. |
| 21:04:44 | <Cale> | Rather than every time two are compared. |
| 21:05:59 | <Baughn> | Cale: Thanks for your help. This will either blow up spectacularily, or improve performance dramatically. : |
| 21:06:02 | <Baughn> | :) |
| 21:06:04 | <Cale> | hehe |
| 21:06:31 | <Cale> | Baughn: I wonder if this is at all related to any of the bugs that I added to the reactive trac |
| 21:06:46 | <mib_xxfkjqs6> | thanks cale |
| 21:08:05 | <Baughn> | Cale: It probably is. The currently-on-hackage Unamb is fundamentally broken. |
| 21:08:11 | <Baughn> | Cale: You should try mine, though perhaps without isHNF. |
| 21:08:20 | <Baughn> | @tell conal Oh, and I updated the comments. |
| 21:08:21 | <lambdabot> | Consider it noted. |
| 21:11:17 | <skorpan> | how do you pronounce <*>? "sequence?" |
| 21:11:40 | <Baughn> | "ap" |
| 21:11:44 | <Peaker> | @hoogle --info discriminate |
| 21:11:45 | <lambdabot> | Parse error: |
| 21:11:45 | <lambdabot> | --count=20 "--info discriminate" |
| 21:11:45 | <lambdabot> | ^ |
| 21:11:51 | <Peaker> | @hoogle discriminate --info |
| 21:11:52 | <lambdabot> | No results found |
| 21:12:02 | <Peaker> | oh, silly me |
| 21:12:03 | <Baughn> | @hoogle discriminate |
| 21:12:03 | <lambdabot> | No results found |
| 21:12:12 | <Baughn> | Peaker: ..but what are you checking that for? |
| 21:12:16 | <Peaker> | @hoogle tipe --info |
| 21:12:17 | <lambdabot> | No results found |
| 21:12:20 | <Peaker> | Baughn: trying to read your paste |
| 21:12:32 | <Peaker> | discriminate is right there, I missed it |
| 21:13:30 | <Peaker> | Baughn: what about blocking in the do block of unsafePerformIO? What if you get an early exception? |
| 21:14:01 | <Baughn> | Peaker: THen it'll simply get restarted automatically. |
| 21:14:35 | <Baughn> | Peaker: You only need to worry about exceptions in unsafePerformIO if you do any exception handling. Otherwise it's totally transparent. |
| 21:14:43 | <Peaker> | unsafePerformIO just loops around execution of the IO until it stops throwing exceptions? |
| 21:15:04 | <Baughn> | Actually, it /pauses/ the execution if the thread throws an exception (or receives one) |
| 21:15:09 | <Baughn> | Then it restarts it from where it stopped |
| 21:15:27 | <Baughn> | I'm not sure I want to think too much about how that is implemented, but it's semantically correct. |
| 21:15:44 | <Baughn> | I only need to worry about it because I use an exception handler to kill some threads if that happens, and I need to restart them. |
| 21:15:58 | <Peaker> | Baughn: in what sense it is paused if it is then resumed immediately? |
| 21:16:06 | <Baughn> | Peaker: It isn't resumed immediately |
| 21:16:14 | <Baughn> | Peaker: let a = unsafePerformIO something |
| 21:16:28 | <Baughn> | Peaker: If you evaluate a and, while that happens, throw/receive an exception, the evaluation is paused |
| 21:16:39 | <Peaker> | until what? |
| 21:16:39 | <Baughn> | But /your thread is killed/, or at least thrown back out to some higher level |
| 21:16:53 | <Baughn> | It restarts once some thread - any thread - starts evaluating a again |
| 21:17:03 | <Peaker> | the whole *thread* that happened to use the thunk with the unsafePerformIO is killed? |
| 21:17:03 | <Baughn> | Well. Unpauses. |
| 21:17:28 | <Peaker> | does unsafePerformIO start a new thread for the action? |
| 21:17:35 | <Baughn> | Peaker: Whatever would normally happen for an exception happens. If there are no exception handlers, then sure. |
| 21:17:38 | <Baughn> | And no. |
| 21:17:40 | <Cale> | skorpan: yeah, <*> is equivalent to Control.Monad.ap, so that's how I'd normally pronounce it too |
| 21:17:51 | <skorpan> | okay |
| 21:17:52 | <Cale> | (apart from having a more general type) |
| 21:18:09 | <Baughn> | Peaker: If you don't touch exceptions inside your unsafePerformIO code (except perhaps to throw one).. |
| 21:18:12 | <skorpan> | can you use constructors infix? e.g. 1 `Hello` 3, where Hello :: Int -> Int -> Hello |
| 21:18:16 | <Cale> | yes |
| 21:18:16 | <Baughn> | Peaker: ..then it works the same way as a throw from pure code. |
| 21:18:25 | <skorpan> | thanks |
| 21:18:34 | <Baughn> | Peaker: You *can't immediately resume the evaluation*, since an exception *handler* has to be in IO |
| 21:18:36 | <Peaker> | Baughn: oh, so thread A uses unsafePerformIO on an action -- it raises, thread A gets a bottom, but Haskell remembers that internal action's state. Another guy tries to use the thunk, it continues execution of that remembered action in the context of a new thread? |
| 21:18:41 | <Cale> | Apart from pattern matching, constructors are normal functions and work exactly the same as them in every way. |
| 21:18:46 | <Baughn> | Peaker: Yes |
| 21:19:14 | <Cale> | Well, I suppose there's record syntax too... |
| 21:19:14 | <Baughn> | Peaker: One gotcha here is that if the exception is /from/ the unsafePerformIO (eg. throwIO (or throw)), then that continuation will just re-throw the exception. :P |
| 21:19:24 | <Peaker> | Baughn: so this is a pretty special thing, as IO actions can migrate between threads (the only place it ever happens?) |
| 21:19:27 | <Cale> | (but that's unsurprising :) |
| 21:19:33 | <hackagebot> | buster 2.2 |
| 21:19:43 | <Baughn> | Peaker: Yes |
| 21:19:44 | <Cale> | hackagebot! You should give a link! |
| 21:19:51 | <Peaker> | Baughn: what a weird implementation |
| 21:20:03 | <Baughn> | Peaker: So in my code I need to throw an exception, but only /once/, to the thread that it's currently executing in |
| 21:20:09 | <Baughn> | Peaker: Thus the throwTo myId |
| 21:20:22 | <Peaker> | Baughn: why doesn't it just restart the whole action in that case? |
| 21:20:35 | <Baughn> | Peaker: To avoid lost work |
| 21:20:56 | <Baughn> | Peaker: Exceptions are defined to never destroy in-progress evaluation, only pause them |
| 21:21:02 | <Peaker> | oh, there's the issue that unsafePerformIO tries to guarantee the action will run just once |
| 21:21:36 | <Baughn> | Peaker: Anyway. Once another thread resumes the unamb, the throwTo will be re-executed; *however*, the thread ID it gets is now dead, so nothing happens and the code continues from where it left off |
| 21:21:40 | <Peaker> | I see the logic of this choice.. the action is run for someone who needs the value.. doesn't need it anymore? pause until someone does |
| 21:21:48 | <Baughn> | Right |
| 21:22:23 | <Cale> | I wonder if you can rig it so that two consecutive calls to myThreadId return different things :) |
| 21:22:27 | <Baughn> | It got a bit hacky for me, but only because I want to throw an exception /only once/ |
| 21:22:46 | <Peaker> | Baughn: I think this could probably be abstracted away more nicely by an unsafePerformIO wrapper? |
| 21:23:00 | <Baughn> | Peaker: That's basically what retry is |
| 21:23:25 | <Baughn> | It allows actions to be restarted instead of resumed |
| 21:23:29 | <Peaker> | Baughn: make it its own function - it may be very useful on its own then |
| 21:23:45 | <Baughn> | Peaker: Considering how much trouble figuring it out was, yeah, I bet. |
| 21:23:52 | <Baughn> | Peaker: But I won't until I'm sure I know it works right. |
| 21:24:08 | <Cale> | I wonder if unamb might have an easier time were it to be implemented as a GHC primop. |
| 21:24:19 | <Peaker> | Baughn: btw, if you re-call (retry act) you might want to memoize the result of (retry act), e.g: retry act = result where result = ... code |
| 21:24:28 | <Baughn> | Cale: Given isHNF..? Oh yeah. |
| 21:24:59 | <Baughn> | Peaker: No point. If I got the result, there would be no exception. |
| 21:25:04 | <duaneb> | I need new coding music. |
| 21:25:33 | <Peaker> | Baughn: is it ok that race assumes that f b does not throwIO? |
| 21:26:06 | <Peaker> | Baughn: "result" would not be the result you got, it would just be the memoized action instead of rebinding it each time |
| 21:26:12 | <Peaker> | Baughn: similarly to: |
| 21:26:14 | <Peaker> | @src forever |
| 21:26:15 | <lambdabot> | Source not found. This mission is too important for me to allow you to jeopardize it. |
| 21:26:17 | <Baughn> | Peaker: I don't see how race assumes that |
| 21:26:29 | <nimred> | hello #haskell |
| 21:26:30 | <Peaker> | forever act = loop where loop = act >> loop |
| 21:26:47 | <Peaker> | Baughn: instead of: forever act = act >> forever act |
| 21:27:20 | <Baughn> | Peaker: Please keep in mind that the restart is inside an exception handler. No exception, no restart. |
| 21:27:34 | <Baughn> | If exception, no return value |
| 21:27:53 | <Cale> | nimred: hello! |
| 21:27:55 | <nimred> | i am trying to build X11 binding using cabal. so i read i need to run autoreconf first, but can you please tell me wich way ? |
| 21:28:15 | <Cale> | nimred: What? autoreconf? |
| 21:28:19 | <Baughn> | nimred: "cabal install X11" always worked for me |
| 21:28:23 | <Peaker> | Baughn: you'll recall "catch" multiple times if you handle multiple exceptions to build the catching action, instead of just re-using the previous "catch" result |
| 21:28:48 | <Cale> | Yeah, cabal install ought to work fine... |
| 21:28:59 | <Baughn> | Peaker: I still don't see what result you're talking about |
| 21:29:19 | <nimred> | Cale http://darcs.haskell.org/X11/README |
| 21:29:20 | <Baughn> | By the time there /is/ a result anywhere, my job is already done and it's returning to whatever called unamb |
| 21:29:39 | <Cale> | nimred: Oh, you're installing the darcs version rather than the one on Hackage? |
| 21:30:00 | <Peaker> | Baughn: just give a name to "retry act" so the *IO action* is memoized, not any runtime result |
| 21:30:16 | <Cale> | nimred: It appears to have the same version number as the one on hackage anyway... |
| 21:30:38 | <Baughn> | Peaker: ..what would this buy me? |
| 21:30:42 | <nimred> | Cale i am trying to install xmonad from hand on OpenBSD |
| 21:31:18 | <Cale> | nimred: I would start by making sure that cabal-install is installed, as it will make solving dependency problems much simpler. |
| 21:31:19 | <nimred> | OpenBSD package system doesn't include xmonad-contrib |
| 21:31:35 | <nimred> | cabal-install ? |
| 21:31:40 | <Peaker> | Baughn: "throwTo myid e >> retry act" here will re-compute (retry act) - i.e recall "catch"/etc. If you just give it a name it will save a bit of runtime and perhaps memory (in case of repeated exceptions, maybe its even significant), just a convention that I find useful in general to memoize my function with the args if I recurse to it with the same args |
| 21:31:52 | <Cale> | yes, it's a tool for downloading and installing Haskell programs and libraries |
| 21:31:59 | <Cale> | http://hackage.haskell.org/packages/archive/pkg-list.html is the list of packages available |
| 21:32:16 | <Baughn> | Peaker: I find it hard to believe that will make any difference whatsoever. Keep in mind, GHC doesn't do partial evaluation. |
| 21:32:16 | <Cale> | http://hackage.haskell.org/cgi-bin/hackage-scripts/package/xmonad |
| 21:32:32 | <Cale> | If you have cabal-install, you should be able to type cabal install xmonad and be done. |
| 21:32:33 | <nimred> | isn't it included in http://www.haskell.org/cabal/release/cabal-1.6.0.2/Cabal-1.6.0.2.tar.gz that i installed ? |
| 21:32:44 | <Cale> | No, that's the Cabal library. |
| 21:32:45 | <Baughn> | Peaker: (Even if it did, the cost of code generation here would enormously dwarf the cost of not generating code; the number of retry calls will usually be very small) |
| 21:32:55 | <nimred> | Cale ah |
| 21:32:59 | <Peaker> | Baughn: why is forever act = act >> forever act worse than forever act = result where result = act >> result ? |
| 21:33:14 | <Cale> | nimred: Also, you shouldn't need to get that manually. |
| 21:33:16 | <tibbe> | How can we emulate something like this http://www.hpaste.org/fastcgi/hpaste.fcgi/view?id=5292#a5292 in Haskell? |
| 21:33:19 | <Cale> | nimred: It comes with GHC anyway. |
| 21:33:32 | <tibbe> | the use case is a web app that gets fed data incrementally |
| 21:33:36 | <Baughn> | Peaker: It isn't. It's the same exact thing. |
| 21:34:02 | <nimred> | Cale let me see |
| 21:34:08 | <Cale> | http://hackage.haskell.org/packages/archive/cabal-install/0.6.2/cabal-install-0.6.2.tar.gz -- you can get the source for cabal-install here. Inside you'll find a bootstrap.sh which, supposing you're not missing libraries that come with GHC, should get you started. |
| 21:34:08 | <Peaker> | Baughn: Why is fix f = f (fix f) worse than fix f = result where result = f result ? |
| 21:34:38 | <Peaker> | Baughn: its different - because ghc memoizes stuff that has a name, but not function applications |
| 21:34:57 | <Baughn> | Peaker: In /that/ case it's different |
| 21:35:21 | <mwc_> | What's the story on why Parsec 3.0 isn't widely used yet? Some sort of horrible bug? |
| 21:35:24 | <Cale> | nimred: I think by default it installs to ~/.cabal/bin. Normally, I make that into a link to ~/bin pre-emptively, but you could also just add it to your path. |
| 21:35:57 | <mwc_> | or is it just that parsec 2.1 is the version shipped with ghc? |
| 21:36:03 | <Peaker> | Baughn: Are you sure the forever case doesn't make a difference? I'm pretty sure Control.Monad.forever uses the seemingly pointless "where" clause |
| 21:36:04 | <Cale> | (it's where binaries for cabal packages end up getting installed when you install as user) |
| 21:36:16 | <Cale> | mwc_: I bet the latter. |
| 21:36:37 | <Baughn> | Peaker: I'm sure it makes no difference for IO. Other monads, again, are different; it makes no difference in this case because IO is strict. |
| 21:37:58 | <nimred> | Cale : i have ghc installed on my system but no cabal-install binary |
| 21:38:02 | <Peaker> | Baughn: Ok, I don't know enough about the implementation details of IO bind, maybe you're right |
| 21:38:11 | <Cale> | nimred: Right. |
| 21:38:22 | <Cale> | nimred: So, get that tarball I linked to |
| 21:38:27 | <Cale> | http://hackage.haskell.org/packages/archive/cabal-install/0.6.2/cabal-install-0.6.2.tar.gz |
| 21:38:43 | <Cale> | and inside you'll find bootstrap.sh which you should try running |
| 21:38:56 | <Baughn> | Peaker: For another monad, forever can build up an arbitrarily long chain of applications (even infinite.. doh, I guess), which if would've blown the stack when evaluated |
| 21:39:28 | <ray> | stacks only get "blown" in haskell, i've noticed |
| 21:39:37 | <Baughn> | Peaker: For IO, evaluation is strict; I /sort/ of build a retry thunk, but it doesn't get nested; thunk A is being evaluated (running retry) before B (the recursive call) even gets started, and by the time B is constructed A can be GC'd |
| 21:39:57 | <Baughn> | ray: As opposed to? |
| 21:39:57 | <nimred> | Cale --> http://pastebin.com/m6fe3006a :/ |
| 21:40:14 | <ray> | overflown or whatever |
| 21:40:34 | <Peaker> | Baughn: the nested thunks is not the only reason you want not to build them - its also unnecessary extra work |
| 21:40:44 | <Baughn> | Peaker: Which is unnoticable |
| 21:40:50 | <Cale> | nimred: Okay, your ghc is missing packages... |
| 21:40:59 | <ray> | i like blown, it comes with the mental image of a stack bursting through an invisible sheet of plastic wrap, causing disaster |
| 21:41:06 | <Cale> | nimred: Which normally come with ghc. |
| 21:41:10 | <byorgey> | nimred: are you using ghc 6.6.1 ? |
| 21:41:11 | <Baughn> | Peaker: Trust me, you won't notice something like five instructions between the two forkIO calls, the MVar stuff and the RTS closure inspections. |
| 21:41:12 | <Peaker> | Baughn: anyhow, great work on unamb there, I think your discoveries should probably be put into a library meant to make unsafePerformIO more usable |
| 21:41:29 | <Peaker> | Baughn: Maybe abstracted a bit more for generality, though |
| 21:41:32 | <nimred> | Cale : |
| 21:41:33 | <nimred> | $ pkg_info | grep ghc |
| 21:41:34 | <nimred> | ghc-6.6.1p2 compiler for the functional language Haskell |
| 21:41:36 | <Baughn> | Peaker: Once I'm sure it works. :) |
| 21:41:47 | <Cale> | nimred: Oh, haha, that's like a few years old. |
| 21:42:03 | <Cale> | nimred: I'll be surprised if you can get xmonad to compile with it :) |
| 21:42:11 | <ray> | ghc 6.6.1 is 2 minor major versions old |
| 21:42:16 | <Peaker> | Baughn: why is loop trying twice? |
| 21:42:21 | <byorgey> | yeah, I'm not sure if we still support 6.6 |
| 21:42:23 | <nimred> | Cale --> http://openports.se/lang/ghc |
| 21:42:25 | <byorgey> | xmonad, that is |
| 21:42:30 | <Baughn> | Peaker: Two threads. |
| 21:42:37 | <Baughn> | Peaker: It counts the number of running threads, basically |
| 21:42:54 | <Cale> | Version 6.6.1 (released 26 April 2007) |
| 21:43:33 | <Peaker> | Baughn: oh, I see, because you changed it to put in the MVar even if it fails |
| 21:43:49 | <nimred> | Cale : what version would i need ? |
| 21:43:54 | <arjanb> | what is a practical way to debug a loop in a big knot tying piece of code? |
| 21:44:16 | <byorgey> | nimred: 6.8 should be fine, but as long as you're upgrading might as well get the latest release, 6.10.3 |
| 21:44:17 | <Baughn> | arjanb: Hum. I think i could invent one. |
| 21:44:18 | <ray> | does openbsd still hate haskell? |
| 21:44:18 | <Twey> | Unravel it into nice simple code :-P |
| 21:44:22 | <Baughn> | arjanb: It would be useful |
| 21:44:27 | <byorgey> | nimred: you can get it here: http://haskell.org/ghc/ |
| 21:44:33 | <byorgey> | should be a binary package that will work |
| 21:44:42 | <Cale> | byorgey: But he's on OpenBSD, will it really? |
| 21:44:46 | <nimred> | Cale : ok but wich way to install ? |
| 21:45:14 | <byorgey> | hmm, the ghc page says the OpenBSD package is maintained by dons. |
| 21:45:26 | <Baughn> | arjanb: Anyway, vacuum. I don't know if it already does this, but it'd be possible to have it survive meeting bottom and show those as well |
| 21:45:27 | <Cale> | dons!! |
| 21:45:29 | <Cale> | hehe |
| 21:45:40 | <byorgey> | nimred: check this page: http://haskell.org/ghc/distribution_packages.html#netbsd |
| 21:45:55 | <byorgey> | it says 'GHC is in the OpenBSG ports tree as lang/ghc' |
| 21:46:02 | <byorgey> | is that the same thing you had before? |
| 21:46:22 | <byorgey> | ACTION knows nothing about OpenBSD |
| 21:46:40 | <Baughn> | , vacuum [2,3,undefined] |
| 21:46:43 | <ray> | they appear to hate haskell |
| 21:46:44 | <lunabot> | luna: Prelude.undefined |
| 21:46:54 | <Baughn> | arjanb: ..yep, will take a little work |
| 21:46:58 | <nimred> | Cale : i know that see http://pkgsrc.se/search.php?so=ghc |
| 21:47:04 | <arjanb> | Baughn: nice idea but will it survive the stackoverflow? |
| 21:47:08 | <Baughn> | mmorrow: How do you feel about fixing up vacuum to show (some) bottoms? |
| 21:47:08 | <copumpkin> | Baughn: is your isWHNF for vacuum? |
| 21:47:11 | <Botje> | ray: they should, it makes their "secure C code" look pathetic :o) |
| 21:47:19 | <byorgey> | nimred: ah, that looks better |
| 21:47:20 | <Baughn> | copumpkin: No, unamb |
| 21:47:20 | <Cale> | nimred: Did you really mean to address that to me? |
| 21:47:22 | <copumpkin> | ah |
| 21:47:42 | <copumpkin> | vacuum should never evaluate anything unless it's already been evaluated! |
| 21:47:44 | <Baughn> | copumpkin: Vacuum doesn't need it. :) |
| 21:47:56 | <Baughn> | copumpkin: ..ooh, good idea |
| 21:48:08 | <byorgey> | nimred: the lang/ghc one (6.8.3) should be fine |
| 21:48:21 | <Baughn> | mmorrow: http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5289#a5290 <-- Oh, and here's some code you may find useful to make vacuum /not/ follow thunks. :D |
| 21:48:23 | <nimred> | ok see you in a moment i switch to NetBSD |
| 21:48:32 | <Cale> | nimred: ... |
| 21:48:35 | <copumpkin> | who'da thunk it? |
| 21:48:49 | <Baughn> | copumpkin: ..you die. Slowly, painfully, and with flowers. |
| 21:49:21 | <copumpkin> | lol |
| 21:49:25 | <Cale> | ah, it is netbsd |
| 21:49:26 | <Cale> | hehe |
| 21:49:36 | <ray> | i'm a lazy thunk, and nobody ever evaluates me |
| 21:49:37 | <copumpkin> | ACTION feels the love |
| 21:50:32 | <Cale> | nimred: if we can get dons here, he'd probably know, though I think he's using ArchLinux these days. |
| 21:51:08 | <mmorrow> | Baughn: i just removed the ghc pkg dep from vacuum, and improved a few other things. no 30MB binaries!! :) |
| 21:51:22 | <copumpkin> | nice |
| 21:51:36 | <copumpkin> | mmorrow: is what I said above possible? |
| 21:51:37 | <mmorrow> | Baughn: (and its getClosureType is s.t. you can use it for your isWHNF now) |
| 21:51:46 | <mmorrow> | um, /me looks |
| 21:51:48 | <Cale> | http://www.cse.unsw.edu.au/~dons/haskell_openbsd.html -- this hasn't been updated since 2005... へ_へ; |
| 21:51:49 | <copumpkin> | to not evaluate anything unless it's already been evaluated |
| 21:51:59 | <copumpkin> | zomg kana smiley |
| 21:52:04 | <Baughn> | mmorrow: Well, if you can duplicate the indirection, that's nice. :) |
| 21:52:05 | <mmorrow> | copumpkin: yes, i found out why things were segfaulting |
| 21:52:12 | <copumpkin> | nice! |
| 21:52:35 | <mmorrow> | i'm gonna add a vacuumNoForce (can you think of a better name?) |
| 21:52:45 | <Baughn> | vacuumNoEvaluate? |
| 21:52:46 | <copumpkin> | featherPaw |
| 21:52:50 | <mmorrow> | the only thing with that though is that you'll always have to run it like: |
| 21:52:53 | <copumpkin> | stealthyLikeACar |
| 21:52:55 | <copumpkin> | *Cat |
| 21:52:58 | <mmorrow> | a `seq` vacuumNoForce |
| 21:52:59 | <Baughn> | gentleSucktion |
| 21:53:04 | <guenni> | does anybody know where I can find the docs for parsec 3.0? |
| 21:53:07 | <mmorrow> | or you'll always just get a single node AP |
| 21:53:08 | <arjanb> | lazyVacuum |
| 21:53:17 | <Baughn> | mmorrow: Well, can't you move that seq inside the vacuum? |
| 21:53:25 | <copumpkin> | mmorrow: gentleVacuum? |
| 21:53:27 | <guenni> | mmorrow: hi |
| 21:53:30 | <mmorrow> | Baughn: hmm, good point |
| 21:53:36 | <mmorrow> | guenni: hi |
| 21:54:20 | <copumpkin> | alright bbiab :) |
| 21:54:39 | <byorgey> | guenni: on hackage? |
| 21:54:45 | <byorgey> | http://hackage.haskell.org/cgi-bin/hackage-scripts/package/parsec |
| 21:54:57 | <guenni> | byorgey: whereever |
| 21:55:36 | <guenni> | sry I should have said "user manual" |
| 21:55:43 | <Cale> | Huh, there are a lot of people on various mailing lists reporting struggle in terms of getting recent releases of GHC on OpenBSD. |
| 21:55:57 | <mmorrow> | Baughn: hmm, i'll have to think about doing what's in that paste by default. that's an interesting idea though |
| 21:56:05 | <byorgey> | guenni: I don't think there is such a thing. The Haddock documentation looks detailed, though. |
| 21:56:32 | <guenni> | byorgey: thx |
| 21:56:33 | <Baughn> | mmorrow: Well, by 6.12 the size shouldn't be a problem anymore |
| 21:56:42 | <mmorrow> | Baughn: (i think indirs will only ever show up if things aren't being forced) |
| 21:57:05 | <Baughn> | mmorrow: ..yes, but that's the general idea, so... |
| 21:57:11 | <mmorrow> | cool :) |
| 21:57:56 | <mmorrow> | Baughn: (in fact, that's basically exactly how vacuum works, it just keeps doing that to get all reachables) |
| 21:58:18 | <Baughn> | Indirections show up a /lot/, due to the GC |
| 21:59:52 | <cads> | hey, I've got a representation of a vector space, and I want to test it for consistency |
| 22:00:33 | <Cale> | QuickCheck properties for the vector space axioms? :) |
| 22:00:42 | <nimred> | Cale ah. to tell the truth i didn't search for on google :/ |
| 22:01:07 | <cads> | cale, that's essentially what I did |
| 22:01:28 | <cads> | I run random vectors through the axiom properties :) |
| 22:01:30 | <Cale> | nimred: I haven't found a solution, except that it might be possible to work your way up from 6.6.1 by building it from source... |
| 22:01:45 | <cads> | it checks out perfectly for integers and rationals |
| 22:01:47 | <mmorrow> | Baughn: yes, vacuum catches the exception thrown by `undefined', then vacuums that! :) |
| 22:02:03 | <Cale> | nimred: Would probably be a good idea to contribute a binary package if you got it working. |
| 22:02:24 | <Baughn> | , vacuum undefined |
| 22:02:25 | <mmorrow> | Baughn: http://moonpatio.com/vacuum/gallery/undefined.png |
| 22:02:26 | <lunabot> | luna: Prelude.undefined |
| 22:02:29 | <mmorrow> | not lunabot's |
| 22:02:33 | <Cale> | cads: Right, for floating point, you'll probably find lots of problems :) |
| 22:02:34 | <Baughn> | Ah |
| 22:02:49 | <nimred> | let's me try first on NetBSD with 6.8.3... |
| 22:02:52 | <mmorrow> | (lunabot's is from before the vacuum pkg actually, version -1) |
| 22:03:08 | <Cale> | nimred: Ah, if that's a realistic option, then it might work out for you :) |
| 22:03:31 | <Cale> | nimred: If you're switching operating systems altogether though, linux is much more convenient :P |
| 22:03:31 | <mmorrow> | (that list of chars you see in the image is "Prelude: unde..." |
| 22:03:51 | <cads> | Cale: you have an idea how I could write tests that would show that the floats are doing as well as they can in representing the vectors? |
| 22:04:12 | <guenni> | btw: is parsec still *the* recommended parsing library? |
| 22:04:49 | <cads> | I could use equality within a thresh-hold to show that the floats aren't off like crazy |
| 22:05:11 | <cads> | in fact, I think I'll find out what the error really is, I bet it's tiny |
| 22:05:24 | <nimred> | Cale well i will try on linux if i can't get it working on NetBSD neither... |
| 22:05:26 | <Botje> | is the Data instance for Data.Set broken? |
| 22:06:56 | <mmorrow> | Botje: it's crippled "to preserve abstraction" :( |
| 22:07:38 | <Botje> | mmorrow: uh oh. is this documented somewhere? |
| 22:07:51 | <Cale> | cads: I wonder... you could certainly write tests which said that the relative error was less than some bound or something. |
| 22:08:01 | <cads> | cale, I think I need to look up a little numerical analysis, I bet it's still possible to write theorems about floats, just with a little extra detail |
| 22:08:06 | <mmorrow> | Botje: in the comment above the instance decl in the Data.{[Int]Map,[Int]Set} src |
| 22:08:14 | <cads> | maybe a lot of extra detail, heh |
| 22:08:39 | <Cale> | cads: Yeah, I don't really know a lot about numerical analysis of that sort apart from the basic "Floating point arithmetic satisfies little other than commutativity" |
| 22:08:49 | <mmorrow> | -- This instance preserves data abstraction at the cost of inefficiency. |
| 22:08:49 | <mmorrow> | -- We omit reflection services for the sake of data abstraction |
| 22:09:01 | <cads> | heh, it's commutative? |
| 22:09:16 | <Botje> | well, it kind of breaks uniplate for Sets :) |
| 22:09:33 | <Cale> | Yeah, not that it means much in the face of the fact that it's not associative. |
| 22:09:54 | <mmorrow> | Botje: looks like you need to create a personal Data.Set fork :) |
| 22:10:05 | <Botje> | i'll .. consider it :p |
| 22:10:10 | <Botje> | thanks for the info! |
| 22:10:13 | <mmorrow> | np |
| 22:10:44 | <cads> | floating points are a little disturbing like that |
| 22:11:36 | <Cale> | Also, equality testing for NaN is stupid :) |
| 22:11:48 | <Cale> | > let x = 0/0 in x == x |
| 22:11:50 | <lambdabot> | False |
| 22:12:29 | <cads> | my tests would have to be truncated to some digit threshold if I was using computable reals :/ |
| 22:12:30 | <mmorrow> | what should it do? |
| 22:12:37 | <mmorrow> | NaB(ool)? |
| 22:12:57 | <Cale> | Well, you'd normally want == to at least be an equivalence relation |
| 22:13:01 | <cads> | > let x = 1/0 in x == x |
| 22:13:03 | <lambdabot> | True |
| 22:13:10 | <Cale> | x == x should be unconditionally true |
| 22:13:12 | <mmorrow> | ohhhh |
| 22:13:18 | <cads> | that's funky |
| 22:13:21 | <mmorrow> | i just realized that's what you did |
| 22:13:36 | <mmorrow> | yeah, that is annoying |
| 22:14:09 | <Cale> | It's arguable that since NaN represents a failure anyway then all its comparisons should fail, but then we have: |
| 22:14:12 | <Cale> | > let x = 0/0 in x /= x |
| 22:14:14 | <lambdabot> | True |
| 22:14:43 | <davidL> | is there an algorithm to convert a turing machine to a pushdown automata? |
| 22:14:49 | <Cale> | davidL: No. |
| 22:14:53 | <mmorrow> | , let a .==. b = if (isNaN a && isNaN b) || a == b then True else False in let x = 0/0 in x .==. x |
| 22:14:54 | <lunabot> | True |
| 22:15:03 | <Cale> | davidL: Because PDAs can only recognise context free languages. |
| 22:15:10 | <xian> | Hi, I'm having a stupid question: I have a function f x y and I partially apply it by supplying a value for x. There's a let-binding z inside f depending only on x. I want z evaluated when g = f x is called so that it isn't evaluated every time I call g y. |
| 22:15:21 | <mmorrow> | yeah, the NaN equality thing could be argued both ways i guess |
| 22:15:24 | <davidL> | Cale: errr, rather, a TM that is known to be context-free |
| 22:16:05 | <cads> | mmorrow: is nan also supposed to be a kind of "bottom" value as well? |
| 22:16:10 | <Cale> | davidL: That's a more interesting question. I have no idea. I suspect you might be able to use the *proof* that it's context free to generate a PDA. |
| 22:16:43 | <Cale> | xian: It probably ought to already |
| 22:16:48 | <mmorrow> | you mean in the sense that it takes everything else with it? |
| 22:16:55 | <Cale> | xian: But if not, then you can force the matter with something like... |
| 22:16:57 | <mmorrow> | , (0/0) * 1 |
| 22:16:58 | <lunabot> | NaN |
| 22:17:01 | <mmorrow> | etc |
| 22:17:02 | <mmorrow> | ? |
| 22:17:03 | <Cale> | f x = let .... in \y -> ... |
| 22:17:07 | <davidL> | Cale: how would you go about proving that the problem of deciding whether a turing machine is context-free is undecidable? (without appealing to rice's theorem) |
| 22:17:26 | <xian> | Cale: Yes, that's what I did (and it works), but I find it somewhat inelegant. |
| 22:17:48 | <mmorrow> | cads: i guess in a sense, but i'd hesitate to say in the same sense as `undefined' |
| 22:17:51 | <Cale> | xian: I think probably compiling with optimisations will do something similar. |
| 22:18:06 | <cads> | no, in the sense that it denotes a computation that's failed (which it does) |
| 22:18:30 | <cads> | but it doesn't cover computations that just wouldn't terminate |
| 22:18:55 | <mmorrow> | cads: if you can ever get NaN by over/underflow then i agree |
| 22:19:06 | <mmorrow> | (i'm not sure off the top of my head) |
| 22:19:25 | <mmorrow> | ie is (0/0) the only way to get NaN? |
| 22:19:35 | <mmorrow> | (excluding using NaN in a computation of course) |
| 22:19:42 | <RayNbow> | ACTION finally found some use for his gmail account: receiving and sorting mailing list messages... ^_^ |
| 22:19:43 | <cads> | sqrt(-1) usually gives nan |
| 22:19:52 | <mmorrow> | ah, true |
| 22:19:55 | <RayNbow> | (but damn, Haskell-Cafe is way too active :p) |
| 22:20:28 | <mmorrow> | cads: i guess i'd say s/error/you tried to map to a number not in R/ |
| 22:20:36 | <mmorrow> | (other than infinity) |
| 22:20:50 | <Cale> | RayNbow: I'm starting to consider auto-archiving all of those... |
| 22:21:05 | <Cale> | RayNbow: I've missed normal mail because my inbox fills too quickly. |
| 22:21:15 | <RayNbow> | Cale: yeah |
| 22:21:18 | <Traveler8> | WHATS UP |
| 22:21:36 | <RayNbow> | I recently found a page that showed how to setup filters/labels for mailing lists |
| 22:21:47 | <Traveler8> | AWSOME |
| 22:21:55 | <Traveler8> | WHERE |
| 22:21:59 | <nimred> | Cale must bootstrp.sh be run as root ? |
| 22:22:15 | <Cale> | nimred: I don't think so. |
| 22:22:15 | <Traveler8> | FUCK U MAN U SHIT |
| 22:22:26 | <mwc_> | if you mean bootstrap.sh to set up cabal install, then no |
| 22:22:35 | <mwc_> | and I would further advise you NOT to run it as root |
| 22:22:43 | <RayNbow> | Cale: and there's a greasemonkey script so you can have a tree view of your labels in gmail |
| 22:23:23 | <RayNbow> | (called Folders4Gmail) |
| 22:23:36 | <nimred> | mwc i get permission pb |
| 22:24:31 | <Cale> | nimred: hmm, it should be trying to install everything as user, but which GHC do you have? |
| 22:24:58 | <nimred> | Cale you ask me if i have GHC ? |
| 22:25:22 | <nimred> | yes i have : |
| 22:25:22 | <nimred> | vohfi% pkg_info | grep ghc |
| 22:25:23 | <nimred> | ghc-6.8.3 Compiler for the functional language Haskell |
| 22:26:03 | <Cale> | nimred: The bootstrap.sh script does explicitly request to install the packages as user. What permission issue are you getting? |
| 22:26:41 | <mmorrow> | Baughn: removing indirections is going to be needed for vacuumLazy |
| 22:26:43 | <Cale> | davidL: Hmm, I'm not sure. |
| 22:27:00 | <Baughn> | mmorrow: Right. I think I've got the right code for that, so use mine |
| 22:27:04 | <mwc> | Does 6.8.x's ghc-pkg honor --user? I can't remember |
| 22:27:22 | <mmorrow> | Baughn: making sure you not to duplicate nodes is going to be more .. interesting too |
| 22:27:26 | <nimred> | Cale while compiling zlib : |
| 22:27:27 | <Cale> | davidL: It seems to me that there might be a way to use the halting problem... |
| 22:27:43 | <Baughn> | mmorrow: Well.. block GCs, use reallyUnsafePointerEquality? |
| 22:27:45 | <Cale> | mwc: I think so. It just wasn't the default then. |
| 22:27:50 | <nimred> | Error during cabal-install bootstrap: |
| 22:27:54 | <nimred> | Building the zlib package failed |
| 22:28:02 | <nimred> | oups |
| 22:28:18 | <Cale> | nimred: Do you have the headers etc. for the C zlib library installed? |
| 22:28:22 | <nimred> | sorry |
| 22:28:24 | <RayNbow> | Cale, http://xs539.xs.to/xs539/09222/gmail-mailinglists838.png :) |
| 22:28:25 | <mmorrow> | Baughn: vacuum already does essentially that, so it'd just be a matter of not adding indirection nodes to the graph, and then following their children |
| 22:28:35 | <Cale> | RayNbow: cool |
| 22:28:41 | <nimred> | it in fact is : "ld: cannot find -lgmp" |
| 22:28:47 | <Cale> | nimred: aha |
| 22:28:48 | <mmorrow> | (and inserting the children as if they were the indirection node) |
| 22:28:59 | <Baughn> | mmorrow: Hang on, it does that /now/? |
| 22:29:11 | <nimred> | Cale :P |
| 22:29:13 | <Cale> | nimred: That's a bit surprising, as it's a dependency for GHC too. |
| 22:29:14 | <Baughn> | mmorrow: What happens if evaluating some structure takes lots of memoery? |
| 22:29:15 | <mmorrow> | Baughn: no, now it adds nodes regardless of closure type |
| 22:29:31 | <Cale> | nimred: But anyway, you should install libgmp and its development files. |
| 22:29:31 | <xian> | Cale: I can't seem to figure out what optimization flag might be responsible for the kind of optimization you mentioned above. Do you know which one I may have to turn on? |
| 22:29:45 | <mmorrow> | Baughn: it sucks up the entirety of the structure now |
| 22:29:46 | <Cale> | xian: Does -O2 work? |
| 22:29:53 | <nimred> | libgmp ? |
| 22:29:57 | <Cale> | xian: If not, then I suppose there's no cure but to write it that way. |
| 22:30:07 | <Baughn> | mmorrow: I mean, if you block GCs.. some evaluations end up with a small structure, but use lots of memory to construct it |
| 22:30:10 | <Cale> | nimred: It's used for the Integer type. |
| 22:30:21 | <Cale> | nimred: It's an arbitrary precision arithmetic library. |
| 22:30:30 | <Baughn> | mmorrow: I'd think it'd be safer to first walk the tree with GC /on/, and then redo it to construct your graph, only then turning it off |
| 22:30:31 | <mmorrow> | Baughn: (there was a mysterious segfault that'd occur if everything wasn't forced which i just found the reason behind last week or so) |
| 22:30:50 | <nimred> | Cale ok thanks for your help |
| 22:30:57 | <nimred> | i am compiling gmp |
| 22:31:28 | <nimred> | looks like it will take some time... |
| 22:31:47 | <xian> | Cale: Okay, I see. Then I'll have to resort to writing that function in an awkward way. Thanks for your assistance. |
| 22:32:04 | <mmorrow> | Baughn: i think it's going to be interesting figuring out how to best walk the graph without forcing :) |
| 22:32:20 | <Baughn> | Have fun. :P |
| 22:33:55 | <nimred> | Cale : ach doesn't work neither |
| 22:34:00 | <nimred> | still getting the same message |
| 22:34:37 | <mmorrow> | Baughn: (the reason for the segfault was that the bytecode assembler creates info tables that are specialized, and the reference to those infotabs only exist until that constructor is forced for the first time (globally). so the "fix" is check whether the # of ptrs/lits the infotable (gotten from a Storable instance) says there are is a sane number (bytecode assembler-constructed itables happen to claim to have somehting like 11172634 p |
| 22:34:38 | <mmorrow> | trs and lits when viewed through the regular infotab storable instance)) |
| 22:35:34 | <mmorrow> | (by "specialized" i mean have a different layout completely) |
| 22:35:35 | <Baughn> | mmorrow: ..I salute the utter horror of that solution. It is truly worthy of RTS hackery. |
| 22:35:39 | <mmorrow> | err, not completely |
| 22:35:45 | <mmorrow> | Baughn: heh |
| 22:37:25 | <Peaker> | What are "bags"? Data structures that are mentioned in "Taste of Haskell"? |
| 22:37:51 | <Baughn> | Multi-sets? |
| 22:38:12 | <Peaker> | ah, like maps to element counts or histograms? |
| 22:38:40 | <Baughn> | More like maps to lists of elements |
| 22:38:57 | <Baughn> | I've seen a few different definitions of "bag", though. |
| 22:39:08 | <Cale> | xian: You might also choose to use 'where' which should work just as well |
| 22:39:13 | <Cale> | xian: like... |
| 22:39:36 | <Cale> | xian: f x = g where <other constants>; g y = ... |
| 22:39:41 | <Baughn> | Peaker: Sort of Map k [k], assuming that Eq is sometimes "mistaken" |
| 22:39:47 | <Baughn> | Peaker: Or, rather, Ord |
| 22:40:01 | <Cale> | xian: maybe a little prettier :) |
| 22:40:30 | <Cale> | nimred: That message means that libgmp isn't found in your library path. |
| 22:40:32 | <Peaker> | Baughn: ah |
| 22:40:40 | <Cale> | nimred: So I don't know what to tell you. |
| 22:40:46 | <Baughn> | Peaker: Otherwise you could use Map k Int, sure |
| 22:41:05 | <Baughn> | Map k Natural? |
| 22:41:05 | <wli> | I use Map k Integer |
| 22:41:10 | <Cale> | I usually think of Map k Natural or Map k Integer |
| 22:41:15 | <Baughn> | ACTION tends to assume 64-bit for some reason |
| 22:41:25 | <Baughn> | I'd probably use Map k Word64 |
| 22:41:31 | <Cale> | I hate the Int type and wish it would go away. |
| 22:41:32 | <Cale> | hehe |
| 22:41:44 | <Cale> | Stupid premature optimisation :) |
| 22:42:40 | <Baughn> | Cale: "Don't prematurely optimize" is one thing |
| 22:42:45 | <Cale> | Well, mostly the problem is all the Prelude functions which produce or require Int |
| 22:43:02 | <Baughn> | Cale: I also like to follow "Don't bother *not* optimizing if the optimized version is no more code, no more complex, and is staggeringly obvious" |
| 22:43:08 | <Cale> | Which means I have to explicitly stick fromIntegral in there or use the generic* things from Data.List |
| 22:43:11 | <RayNbow> | hmm, Data.MultiSet uses type Occur = Int... |
| 22:43:17 | <Peaker> | my friend is learning Haskell and just complained that he has to sprinkle fromIntegral everywhere because of Ints in the Prelude |
| 22:43:25 | <Cale> | Baughn: I usually need/want Integer |
| 22:43:32 | <Baughn> | RayNbow: Well, that's just wrong. You can very easily overflow it on a 32-bit system |
| 22:43:51 | <RayNbow> | Baughn: don't tell me, tell twanvl :p |
| 22:44:15 | <Baughn> | twanvl: You can very easily overflow a 32-bit Int. Don't use it for multiset occurences. Geez. |
| 22:44:26 | <Cale> | and all the occurrences of Int mean that I can't rely on the fact that Integer is the default numeric type |
| 22:44:42 | <RayNbow> | (but 32 bits ought to be enough for everyone :p) |
| 22:44:46 | <RayNbow> | ACTION hides |
| 22:45:00 | <FalconNL> | I don't suppose there's an easier implementation for the function getModuleSource :: String -> IO String than downloading it off Hackage? |
| 22:45:17 | <Baughn> | FalconNL: Nope |
| 22:45:29 | <Cale> | FalconNL: That's about all you can do apart from checking if it's in the cabal cache. |
| 22:45:33 | <Baughn> | There's no reason to think your system even has a copy of the source |
| 22:45:45 | <Baughn> | *Faster* implementations, sure. Easier, no. ;) |
| 22:46:11 | <Cale> | Even if it is in the cabal cache, you'll still have to unpack it. |
| 22:46:16 | <FalconNL> | Figured as much. Out of curiosity, what would the faster implementation be? |
| 22:46:34 | <Baughn> | FalconNL: Checking the cache. |
| 22:46:38 | <Cale> | FalconNL: Checking if it's already in ~/.cabal/packages/hackage.haskell.org |
| 22:47:12 | <Cale> | But even if it does happen to be there, it'll still be in a .tar.gz |
| 22:47:35 | <Cale> | Maybe Cabal has a way to manage the cache... |
| 22:48:00 | <FalconNL> | I'll stick with downloading for now. Now to figure out how to download a file with Haskell... |
| 22:48:00 | <Baughn> | A .tar.gz is what you'd get from Hackage too |
| 22:48:14 | <Peaker> | can one implement co-routines on top of callCC (ala stackless Python tasklets/etc)? I want to demonstrate the power of monad transformers |
| 22:48:30 | <Baughn> | FalconNL: I'd go with "cabal fetch"; then you /know/ it'll be in the cache. |
| 22:49:16 | <FalconNL> | heh. Gotta love hackage. Searching for "download" reveals the package named download. That should do nicely :) |
| 22:49:43 | <Baughn> | ..cabal fetch... |
| 22:50:03 | <Cale> | Yeah, I agree, cabal fetch followed by looking in the cabal cache is a better idea. |
| 22:50:27 | <Philonous> | FalconNL: download depends on linux' c-lib if I remember correctly |
| 22:50:49 | <Cale> | HTTP would be the normal package to use for that... |
| 22:50:59 | <FalconNL> | Philonous: yeah, I noticed. I'll try cabal fetch instead. |
| 22:54:51 | <nimred> | Cale well i have to go to bed. see you tomorrow. thanks for your help :) |
| 22:55:22 | <altmattr> | I have hit what I think is essentially the expression problem |
| 22:55:23 | <altmattr> | http://moonpatio.com/fastcgi/hpaste.fcgi/view?id=2501#a2501 |
| 22:55:34 | <FalconNL> | Hm. "cabal fetch base" results in "cabal: internal error: impossible". |
| 22:55:36 | <altmattr> | I have written up a little example specific to my problem |
| 22:55:47 | <altmattr> | can I get any suggestions for the best way thru? |
| 22:56:41 | <altmattr> | I am sure just about everyone here has had the same problem |
| 22:56:42 | <altmattr> | :) |
| 22:59:37 | <FalconNL> | Does anyone know why base would not be cabal-fetchable? |
| 23:00:04 | <altmattr> | FalconNL: fraid not, it sounds like cabal doesn't know either |
| 23:00:04 | <pumpkin> | is it on hackage? |
| 23:00:23 | <FalconNL> | pumpkin: yeah, it's the package that contains the Prelude |
| 23:00:34 | <pumpkin> | well, I know the package contains that |
| 23:00:37 | <pumpkin> | but I didn't know it was on hackage |
| 23:00:44 | <pumpkin> | I mean, rts is a package too |
| 23:00:46 | <pumpkin> | as is ghc |
| 23:00:54 | <pumpkin> | but they're not "real" |
| 23:01:12 | <sjanssen> | FalconNL: 'cabal install base' is intentionally disabled |
| 23:02:13 | <sjanssen> | FalconNL: perhaps fetch was also disabled by mistake or conservative programming |
| 23:02:18 | <MyCatVerbs> | sjanssen: ahahaha, that would break in so many fun ways. :3 |
| 23:02:29 | <FalconNL> | sjanssen: Wonderful. Guess it's back to downloading off Hackage, since the Prelude is one of the more important modules I need the source from. |
| 23:02:47 | <pumpkin> | @hackage base |
| 23:02:47 | <lambdabot> | http://hackage.haskell.org/cgi-bin/hackage-scripts/package/base |
| 23:02:56 | <pumpkin> | ah, cool |
| 23:03:04 | <pumpkin> | @hackage rts |
| 23:03:04 | <lambdabot> | http://hackage.haskell.org/cgi-bin/hackage-scripts/package/rts |
| 23:05:41 | <altmattr> | All-right, how about a rephrased version? |
| 23:05:42 | <altmattr> | What is best practice for adding a new field to an existing constructor without rewriting every function over that constructor (or at least minimising the pain)? |
| 23:06:06 | <pumpkin> | use {} |
| 23:06:39 | <pumpkin> | if you had case x of Constructor _ _ _ -> ... use case x of Constructor{} -> ... |
| 23:06:43 | <Peaker> | gtk2hs is not cabalized? |
| 23:06:52 | <pumpkin> | naming the constructor fields helps if you actually need the values |
| 23:07:05 | <pumpkin> | Peaker: I heard it was too complicated to build for cabal |
| 23:07:09 | <pumpkin> | at least in its current state |
| 23:07:38 | <Phyx-> | ahh, taking a step back and reading the code does help :) |
| 23:07:57 | <altmattr> | pumpkin: you just made my jaw drop - I didn't even know you could do that! |
| 23:08:05 | <altmattr> | how did I miss that? |
| 23:08:57 | <pumpkin> | I only came across it recently, can't remember where |
| 23:09:22 | <altmattr> | now I am off to rewrite every pattern matching function I ever wrote |
| 23:09:25 | <Peaker> | pumpkin: cabal lets it have its own build executables? |
| 23:10:45 | <Phyx-> | @type (*** id) |
| 23:10:46 | <lambdabot> | forall b c b'. (b -> c) -> (b, b') -> (c, b') |
| 23:11:13 | <Phyx-> | @type (*** id) (++"-") |
| 23:11:14 | <lambdabot> | forall b'. ([Char], b') -> ([Char], b') |
| 23:11:18 | <goalieca2> | is there no ubuntu 9.04 package for cabal? it is not in haskell-utils and it doesnt come up in a repo search |
| 23:11:25 | <pumpkin> | Peaker: yeah, but I guess they decided it wasn't worth cabalizing if all the work was going to be done by configure and make? not sure |
| 23:11:40 | <Phyx-> | @type (*** (++"-")) id |
| 23:11:41 | <lambdabot> | forall c. (c, [Char]) -> (c, [Char]) |
| 23:11:45 | <Phyx-> | ah |
| 23:11:47 | <Phyx-> | that's the one |
| 23:11:56 | <Peaker> | pumpkin: at least get deps? |
| 23:12:10 | <pumpkin> | Peaker: beats me :) that's just what I heard |
| 23:12:17 | <Phyx-> | arrow is really handy |
| 23:12:27 | <Twey> | Sometimes |
| 23:12:33 | <Twey> | Not very often, though, alas |
| 23:12:36 | <Phyx-> | hehe |
| 23:12:46 | <pumpkin> | I find it useful pretty often! |
| 23:12:50 | <pumpkin> | it got my par down to 3 |
| 23:12:57 | <Phyx-> | hmm this doesn't look so nice... a function with 8 class constraints |
| 23:13:13 | <pumpkin> | Phyx-: http://blog.omega-prime.co.uk/ |
| 23:13:20 | <Phyx-> | ACTION looks |
| 23:13:41 | <Phyx-> | oh that's nice |
| 23:13:45 | <Phyx-> | thanks :) |
| 23:13:55 | <Phyx-> | i can clean up qute a bit with that |
| 23:14:32 | <Peaker> | pumpkin: what's "context" ? |
| 23:15:24 | <Phyx-> | hmm seems to be just a proposal at this point pumpkin ? |
| 23:15:27 | <Phyx-> | too bad :( |
| 23:16:19 | <ray> | peaker: context is what's behind that link |
| 23:17:10 | <Phyx-> | I like the proposal though |
| 23:17:40 | <ray> | i've decided instance (Lots, Of, Different, Classes, At, Once) Foo where ... would be cool |
| 23:17:45 | <Peaker> | ray: I directly skimmed to code examples, without reading the top :) It sounds like class aliases |
| 23:18:10 | <ray> | the first bit is |
| 23:18:48 | <ray> | (and of course, substituting a class alias for that thing in parentheses should work) |
| 23:19:24 | <Phyx-> | union dataK dataB :: [Buchi (Integer, [Char]) [Char]] <-- atleast it type checks :) |
| 23:20:13 | <Phyx-> | "[*** Exception: Prelude.undefined" <-- always hate these errors |
| 23:20:16 | <Phyx-> | now where is it.. |
| 23:20:50 | <Cale> | Phyx-: are you explicitly using undefined somewhere? |
| 23:21:00 | <Twey> | Phyx-: C-s undefined |
| 23:21:12 | <Twey> | undefined is the new TODO |
| 23:21:19 | <Phyx-> | Cale: i used them to get a stub working, but i should have removed them by now i think |
| 23:21:25 | <Cale> | ah :) |
| 23:21:39 | <Twey> | But perhaps we should stick with TODOs for a while, in case of explicit undefineds... |
| 23:21:53 | <Cale> | error would be a little better |
| 23:22:02 | <Cale> | since then at least you'd know which one :) |
| 23:22:09 | <Phyx-> | found it, heehe |
| 23:22:11 | <Twey> | foo = error "NIH" |
| 23:22:12 | <ray> | TODO can be an empty data declaration |
| 23:22:17 | <Phyx-> | i had a boilerplate let code |
| 23:22:32 | <Phyx-> | quick question |
| 23:22:35 | <Twey> | ray: How do you mean? |
| 23:22:43 | <ray> | data TODO |
| 23:22:52 | <Phyx-> | why didn't this spit out a "redifining variable 'e'" error? |
| 23:22:53 | <Phyx-> | e@(e1,e2) <- ask |
| 23:22:53 | <Phyx-> | let e = undefined |
| 23:22:55 | <ray> | with a ghc extension enabled |
| 23:22:57 | <Twey> | But how would we use it? |
| 23:23:06 | <Phyx-> | i had the second by accident |
| 23:23:11 | <Twey> | Phyx-: It will simply shadow it |
| 23:23:12 | <Cale> | Phyx-: Because shadowing isn't normally something it warns about |
| 23:23:17 | <ray> | then, you could write functions like [(a,b)] -> TODO |
| 23:23:41 | <Twey> | It will only warn (or was it an error?) about redefining if you do it in the same let block, I think |
| 23:23:55 | <ray> | where TODO is a Map-like data structure you haven't written yet |
| 23:23:58 | <Phyx-> | i could swear i used an interpreter before that warned about shadowing |
| 23:24:00 | <Phyx-> | hmm |
| 23:24:02 | <ray> | your code won't compile, and you'll remember to implement it |
| 23:24:03 | <Twey> | ray: But then the types would be different |
| 23:24:14 | <Cale> | Phyx-: if you set -Wall I think it will warn |
| 23:24:16 | <ray> | that's the idea |
| 23:24:18 | <Twey> | The idea is to get the code to compile so we can make sure it type-checks |
| 23:24:27 | <Twey> | Before implementing |
| 23:24:38 | <Cale> | But -Wall is annoying :P |
| 23:24:43 | <Phyx-> | Cale: ah, lol |
| 23:24:49 | <Phyx-> | was it on at some version of ghci? |
| 23:24:53 | <Phyx-> | by default i mean |
| 23:24:55 | <Cale> | I don't know. |
| 23:24:56 | <ray> | that's the idea of undefined |
| 23:25:04 | <ray> | my idea is different |
| 23:25:12 | <ray> | and forces you to remember to implement stuff |
| 23:25:23 | <ray> | unless you use undefined in conjunction with it |
| 23:26:02 | <Cale> | ray: I think the point is that he wanted to load the code in ghci, and so stubbed some stuff out with undefined. |
| 23:26:20 | <Cale> | ray: If you want it not to compile, you can just fail to write it altogether :) |
| 23:26:23 | <ray> | yeah, that's totally different from my crazy idea, it just happened to inspire it |
| 23:26:25 | <Twey> | Wow, -Wall really is annoying. |
| 23:26:37 | <Phyx-> | hm. why does foldl1 return an exception when the list is empty? i was expecting an empty list |
| 23:26:45 | <Twey> | It warns about missing type signatures :( |
| 23:26:53 | <Cale> | Phyx-: Because... that's the point of it |
| 23:26:56 | <ray> | well, i want to write the function body and the type signature, but not define the return type :) |
| 23:26:56 | <Twey> | Phyx-: Because it needs the first element |
| 23:27:03 | <Cale> | :t foldl |
| 23:27:04 | <Cale> | :t foldl1 |
| 23:27:05 | <lambdabot> | forall a b. (a -> b -> a) -> a -> [b] -> a |
| 23:27:05 | <ray> | you want foldl |
| 23:27:06 | <lambdabot> | forall a. (a -> a -> a) -> [a] -> a |
| 23:27:09 | <lament> | why would fold return a list? |
| 23:27:37 | <Cale> | You only use foldl1 when the function you're writing makes no sense for an empty list. |
| 23:27:48 | <Phyx-> | aha |
| 23:27:59 | <Phyx-> | lament: when you're folding over [[a]] |
| 23:28:21 | <Cale> | Since it's polymorphic, it can't do anything different in the list case than in any other. |
| 23:28:36 | <Phyx-> | hmm |
| 23:29:09 | <Phyx-> | aha |
| 23:29:09 | <hackagebot> | Hieroglyph 2.23 |
| 23:29:09 | <Phyx-> | works |
| 23:29:17 | <ray> | lots of languages throw around the word "polymorphic", but only haskell throws around "monomorphic" too |
| 23:29:40 | <FalconNL> | Well that's nice: the example in http://hackage.haskell.org/packages/archive/HTTP/4000.0.5/doc/html/Network-HTTP.html fails with "openFile: does not exist (No such file or directory)". Is the example wrong or am I missing something? |
| 23:29:45 | <Cale> | That use of monomorphism is really confusing to me. |
| 23:30:01 | <Cale> | Because it conflicts with the standard meaning in mathematics. |
| 23:30:25 | <Cale> | Or it was, I'm pretty much used to it by now :) |
| 23:30:55 | <ray> | yeah, it's monomorphism the adjective not monomorphism the noun |
| 23:31:09 | <ray> | er |
| 23:31:09 | <kniu> | Since haskell has Data.Map, couldn't record types be implemented with Template Haskell, since they're just maps of names to values and their types? |
| 23:31:13 | <ray> | i think i'm right |
| 23:31:21 | <Cale> | I think so too. |
| 23:31:36 | <mmorrow> | Cale: heh, i thought the monomorphismrestriction had to do with some sort of injective mapping for the first while when i was learning haskell |
| 23:31:55 | <Cale> | kniu: Not with the same syntax. |
| 23:32:01 | <Cale> | mmorrow: me too |
| 23:34:26 | <Cale> | kniu: You could perhaps approximate the record syntax by constructing a plain algebraic type along with such a mapping, and then do lots of quasiquoter manipulations... |
| 23:35:15 | <Cale> | Seems like a troublesome thing to do, anyway. |
| 23:35:39 | <pumpkin> | damn overloaded words |
| 23:36:17 | <kniu> | Cale, I thought Template Haskell allowed you to do all sorts of crazy stuff with the syntax. |
| 23:37:23 | <Cale> | Not really. splices always look like $( ... ) where what's inside the parens is some code which evaluates to a Haskell syntax tree. |
| 23:37:27 | <EvilTerran> | kniu, template haskell is pretty noisy, it's not really changing the syntax |
| 23:37:43 | <kniu> | huh. |
| 23:37:53 | <Cale> | Though we now have a quasiquoter syntax which lets you do arbitrary parsing, but you still need a surrounding bracket. |
| 23:38:10 | <EvilTerran> | [$qqName| ... |], at that |
| 23:38:47 | <FalconNL> | Does anyone know any reasons why the first example in http://hackage.haskell.org/packages/archive/HTTP/4000.0.7/doc/html/Network-HTTP.html could fail? |
| 23:38:48 | <Twey> | http://moonpatio.com:8080/fastcgi/hpaste.fcgi/view?id=2502#a2502 — why is this considered non-exhaustive? |
| 23:39:32 | <Twey> | I would have thought it exhaustively covered by the x (y : z) pattern |
| 23:39:36 | <Twey> | (the ones it mentions) |
| 23:39:46 | <Twey> | And the one about not matching _... |
| 23:40:16 | <Cale> | Heh, I think the pattern match exhaustiveness checker is sort of broken |
| 23:40:38 | <Twey> | Is it not covering that because I've specified guards? |
| 23:40:38 | <Cale> | That, or it just doesn't like your crazy moon-language. |
| 23:40:46 | <Zao> | What about fanva "h"? |
| 23:40:48 | <Twey> | Haha |
| 23:40:57 | <Cale> | oh, maybe it can't tell that the guards are exhaustive? |
| 23:41:14 | <Twey> | Zao: Gets caught by (lerfu : loilErfu) | not $ isAlphaNum lerfu |
| 23:41:26 | <Zao> | Twey: But it's alpha. |
| 23:41:37 | <Twey> | ACTION blinks. |
| 23:41:39 | <Twey> | Point |
| 23:41:56 | <Twey> | ACTION nodnods. |
| 23:42:16 | <Cale> | I don't know how it would figure that out though. |
| 23:42:46 | <Cale> | It would either have to assume that the guards always fail or that one of them always succeeds... I don't think it's smart enough to really tell. |
| 23:43:15 | <Twey> | I would suspect it considers them incomplete if there's no ‘otherwise’ |
| 23:43:25 | <Cale> | yeah, maybe that's it |
| 23:43:36 | <Twey> | After adding one, it seems okay with it |
| 23:43:53 | <Twey> | And I can feel elitist pride at getting -Wall to accept my measly code |
| 23:46:41 | <Cale> | Twey: hopefully after the other case though... |
| 23:46:51 | <Twey> | Other case? |
| 23:47:01 | <Cale> | fanva (zunsna : karsna : loilErfu) = |
| 23:47:03 | <Twey> | Oh, yes |
| 23:47:06 | <Twey> | I switched them :) |
| 23:47:10 | <Cale> | ah |
| 23:47:48 | <Twey> | The order of patterns and their matches can get quite delicate in complex use cases |
| 23:48:43 | <MyCatVerbs> | What language of variable name are zunsna, karsna and liolErfu? |
| 23:48:59 | <Twey> | loi** |
| 23:49:00 | <MyCatVerbs> | AIEEEE |
| 23:49:01 | <Twey> | Lojban |
| 23:49:10 | <Twey> | ACTION blinks. |
| 23:49:12 | <MyCatVerbs> | Ah, oops. Thanks. |
| 23:49:18 | <Twey> | Usually the screaming happens *after* I mention that it's Lojban. |
| 23:49:27 | <MyCatVerbs> | Not that, pumpkin. |
| 23:49:32 | <Twey> | Ohh. |
| 23:49:35 | <Twey> | A Thwog. |
| 23:49:44 | <MyCatVerbs> | The Thwog, apparently. |
| 23:49:48 | <MyCatVerbs> | I'm scared that he might try to help us. |
| 23:49:57 | <Thwog> | No. |
| 23:50:14 | <MyCatVerbs> | Phew. |
| 23:50:19 | <Twey> | Yes, I'm trying to work out a set of conventions that adhere to both Lojban and Haskell requirements |
| 23:50:43 | <Twey> | Luckily, Lojban allows word-demarcation by stress, so no separators are required |
| 23:50:55 | <Twey> | And Haskell allows ' in names, which is also very cool. |
| 23:51:03 | <Thwog> | no it doesn't |
| 23:51:16 | <Twey> | Thwog: Haskell disagrees. |
| 23:51:23 | <Thwog> | yeah, but I'm incompetent |
| 23:51:26 | <Twey> | > let ' = "foo" in ' |
| 23:51:27 | <lambdabot> | <no location info>: |
| 23:51:27 | <lambdabot> | lexical error in string/character literal at chara... |
| 23:51:28 | <MyCatVerbs> | > let let'ssee = "whether or not it does" in let'ssee |
| 23:51:29 | <lambdabot> | "whether or not it does" |
| 23:51:30 | <Twey> | Aw. |
| 23:51:34 | <Twey> | Not there, apparently. |
| 23:51:42 | <Thwog> | http://thwog.kyth.org/Book_of_Thwog/book_of_thwog.html |
| 23:51:59 | <MyCatVerbs> | > let 'avaunt = "I can't remember what this word means" in "bacon" |
| 23:52:00 | <lambdabot> | <no location info>: |
| 23:52:00 | <lambdabot> | lexical error in string/character literal at chara... |
| 23:52:05 | <MyCatVerbs> | Not there, either. :3 |
| 23:52:40 | <Twey> | thou: Bahaha |
| 23:52:48 | <Twey> | MyCatVerbs: It thinks it's a character literal |
| 23:53:13 | <MyCatVerbs> | Twey: yes, I can read the error message. ;P |
| 23:53:15 | <Twey> | Which is kind of silly — it should really be obvious that it isn't |
| 23:53:21 | <MyCatVerbs> | Erk! |
| 23:53:41 | <Twey> | A character literal will always be of the form '<char>' or '\<char>' |
| 23:53:56 | <Twey> | I guess it requires backtracking, though. Do we avoid that? |
| 23:54:22 | <MyCatVerbs> | "It should be really obvious that..." <- no, please no. I like my parsers to be as simple as possible. The simpler the parser, the easier it is to understand why it is barfing on some given piece of text. |
| 23:54:25 | <Cale> | > '\SOH' |
| 23:54:27 | <lambdabot> | '\SOH' |
| 23:54:33 | <MyCatVerbs> | Yes, we avoid that as much as possible. |
| 23:54:33 | <Phyx-> | hrm... my trace statements became impressively useless since ghc reordered them |
| 23:54:34 | <Phyx-> | lol |
| 23:54:40 | <Twey> | MyCatVerbs: Heh, okay. |
| 23:54:41 | <MyCatVerbs> | Heehee. "avaunt - interjection - [archaic] begone! go away! (N.B. useful for telemarketers)" |
| 23:54:57 | <Cale> | > "\SO" ++ "H" |
| 23:54:59 | <lambdabot> | "\SO\&H" |
| 23:55:41 | <Twey> | What does \SO mean? |
| 23:55:56 | <MyCatVerbs> | > chr '\SO' |
| 23:55:57 | <lambdabot> | Couldn't match expected type `GHC.Types.Int' |
| 23:56:02 | <Twey> | > "\S" ++ "OH" |
| 23:56:03 | <lambdabot> | <no location info>: |
| 23:56:04 | <lambdabot> | lexical error in string/character literal at chara... |
| 23:56:05 | <MyCatVerbs> | > ord '\SO' |
| 23:56:07 | <lambdabot> | 14 |
| 23:56:13 | <pumpkin> | Cale: do you know why lambdabot has been giving low-level type names in errors recently? |
| 23:56:21 | <Cale> | Shift Out |
| 23:56:24 | <Twey> | Is \& a no-op? |
| 23:56:27 | <pumpkin> | a lot of GHC.Types.* instead of the more obvious ones |
| 23:56:37 | <MyCatVerbs> | "Shift Out". Which means...? |
| 23:56:46 | <Cale> | Twey: yeah, it's just there as a separator for that one special case :) |
| 23:56:54 | <Twey> | Heh |
| 23:56:54 | <Peaker> | I wonder if you can implement Python-like generators (yield) with ContT |
| 23:57:00 | <Twey> | > length "\&" |
| 23:57:01 | <lambdabot> | 0 |
| 23:57:03 | <Cale> | http://en.wikipedia.org/wiki/Shift_Out_and_Shift_In_characters |
| 23:57:14 | <MyCatVerbs> | I sometimes wonder whether ∃ anyone on the planet who can remember what most of the control characters in ASCII mean, anyway. :D |
| 23:57:16 | <Twey> | Peaker: I believe you can, yes |
| 23:57:29 | <Twey> | Why is there an ‘exists’ in the middle of that sentence? |
| 23:57:30 | <MyCatVerbs> | Peaker: spoiler, you can implement Python-like generators with lazy lists. :P |
| 23:57:38 | <Twey> | ACTION laughs. |
| 23:57:42 | <Peaker> | MyCatVerbs: nope, Python generators do side effects |
| 23:57:45 | <Twey> | Only for pure values |
| 23:57:49 | <Twey> | ACTION nods. |
| 23:58:16 | <MyCatVerbs> | Peaker: unsafeInterleaveIO. ^^ |
| 23:58:23 | <Peaker> | hah |
| 23:58:28 | <Twey> | >.< |
| 23:58:31 | <Peaker> | Twey: I am new to ContT, it seems like a horrible thing to ever use, but I want to get to know it and use it to write coroutines/etc so I can impress people with Haskell's mojo :) |
| 23:59:22 | <Twey> | Oh, it's not that horrible |
| 23:59:36 | <Twey> | It *can* be a bit mind-bending, but that's your responsibility :-P |
| 23:59:39 | <RayNbow> | btw Cale, what do you use to type Japanese? (as you did here http://www.reddit.com/r/programming/comments/8mmcu/i_tried_to_translate_the_ironpython_code_to/c09rkdu ) |
| 23:59:47 | <Cale> | RayNbow: SCIM |
| 23:59:52 | <Berengal> | Continuations are not for the weak of mind |
| 23:59:53 | <Cale> | +Anthy |
| 23:59:58 | <Peaker> | Twey: it provides a "function" that never returns, and actually performs a goto/jump |
Back to channel and daily index: content-negotiated html turtle