Available formats: content-negotiated html turtle (see SIOC for the vocabulary)
Back to channel and daily index: content-negotiated html turtle
These logs are provided as an experiment in indexing discussions using IRCHub.py, Irc2RDF.hs, and SIOC.
| 00:00:03 | <dons> | to abstract out the parameter passing |
| 00:00:14 | <dons> | ?go Random Supply site:haskell.org |
| 00:00:17 | <lambdabot> | http://www.haskell.org/ghc/docs/latest/html/libraries/base/System-Random.html |
| 00:00:28 | <dons> | hmm, there's a wiki page showing a few of the possible designs |
| 00:00:31 | <ToxicFrog> | I would just rather not have to hand around the list and/or generator, as it makes my signatures way nastier and, in the end, probably removes any clarity of ease-of-dev benefit from using Haskell in the first place. |
| 00:00:48 | <dons> | would you like example code? its really rather clean |
| 00:00:59 | <ToxicFrog> | I would greatly appreciate that, yes. |
| 00:01:05 | <dons> | i'm not quite sure what you're envisaging the code as |
| 00:01:14 | <yitz> | No, it's not all that bad. But yes, using a State monad makes this nice in my opinion. |
| 00:01:15 | <dons> | so perhaps an example, using explicit parameters, and then State |
| 00:01:21 | <dons> | yeah |
| 00:01:57 | <dibblego> | ?src Either return |
| 00:01:58 | <lambdabot> | return = Right |
| 00:04:12 | <dmwit> | ?src Either fail |
| 00:04:13 | <lambdabot> | fail msg = Left (strMsg msg) |
| 00:04:22 | <dmwit> | :t strMsg |
| 00:04:25 | <lambdabot> | forall a. (Error a) => String -> a |
| 00:06:53 | <omnId> | @instances Error |
| 00:06:55 | <lambdabot> | IOError, [Char] |
| 00:09:38 | <hpaste> | dons pasted "a State threading a list of randoms" at http://hpaste.org/3293 |
| 00:09:45 | <dibblego> | ?check \f x -> Left (x :: Int) >>= (f :: Int -> Either Int Int) == Left x |
| 00:09:46 | <lambdabot> | Couldn't match expected type `Int -> Either Int Int' |
| 00:10:22 | <dons> | ToxicFrog: so if you look at that hpaste, you see the 'main', in io, getting a new seed. then mapMaybe applies a function to a list, depending on a random Bool value threaded in the State |
| 00:10:31 | <dons> | we run it a few times to see the randoms change |
| 00:11:05 | <dons> | so all your code for manipulating stuff based on randoms is pure, everything past the zipWith |
| 00:11:30 | <omnId> | more n = State (splitAt n) |
| 00:12:01 | <dons> | yeah, refactor as you wish. you can compress it a fair bit more if needed |
| 00:12:14 | <ricky_clarkson> | Would the digits of PI be an adequate random number generator? |
| 00:12:32 | <omnId> | ricky_clarkson: they're always the same :) |
| 00:12:41 | <dons> | so you'd need a random offset into the digits |
| 00:12:50 | <ricky_clarkson> | omnId: What isn't? |
| 00:12:53 | <monochrom> | I think it's an open question. |
| 00:13:24 | <ricky_clarkson> | Well, if you find that they're not adequate, you're probably about to become famous. |
| 00:13:47 | <dons> | ToxicFrog: so, any questions? |
| 00:13:57 | <monochrom> | The actual open question is: lim n->oo (# of occurences of d in the first n digits)/n = 1/10? |
| 00:14:31 | <ToxicFrog> | dons: lots, starting with what evalState and zipWith do, but I think I can hit the docs for those |
| 00:14:41 | <nornagon> | dons: you couldn't really do that in a nice way, because finding the nth digit of pi is not an O(1) operation |
| 00:14:45 | <ToxicFrog> | and mapMaybe can be called from pure code? |
| 00:15:01 | <nornagon> | :t mapMaybe |
| 00:15:04 | <lambdabot> | forall a b. (a -> Maybe b) -> [a] -> [b] |
| 00:15:06 | <dons> | its not that one. sorry |
| 00:15:16 | <dons> | but we could use it |
| 00:15:37 | <dons> | ToxicFrog: so evalState threads the randoms through your code |
| 00:16:38 | <omnId> | *Main> :t mapMaybe |
| 00:16:38 | <omnId> | mapMaybe :: (MonadState [Bool] t) => (a -> a) -> [a] -> t [a] |
| 00:17:58 | <_achilles_> | is it possible to add two items in a list comprehension, without doing tuples? |
| 00:18:26 | <ddarius> | > [x + y | x <- [1..10], y <- [10..14]] |
| 00:18:26 | <mauke> | huh? |
| 00:18:28 | <lambdabot> | [11,12,13,14,15,12,13,14,15,16,13,14,15,16,17,14,15,16,17,18,15,16,17,18,19,... |
| 00:18:56 | <dons> | > zipWith (+) [1..10] [10..20] -- zipwith strikes again |
| 00:18:58 | <lambdabot> | [11,13,15,17,19,21,23,25,27,29] |
| 00:19:24 | <dons> | you can use parallel list comprehensions too, though they're newish |
| 00:19:33 | <_achilles_> | [x : y | x <- [1..5], y <- [1..10]] |
| 00:19:33 | <omnId> | the first does all combinations |
| 00:19:46 | <omnId> | y would have to have type [Int] |
| 00:19:46 | <mauke> | _achilles_: type error |
| 00:19:51 | <_achilles_> | right |
| 00:19:52 | <chessguy> | what are parallel list comprehensions? |
| 00:19:57 | <_achilles_> | I'm asking if it's possible |
| 00:19:58 | <mauke> | No instance for Num [Integer] |
| 00:20:04 | <Tac-Tics> | > [[x, y] | x <- [1..5], y <- [1..10]] |
| 00:20:07 | <lambdabot> | [[1,1],[1,2],[1,3],[1,4],[1,5],[1,6],[1,7],[1,8],[1,9],[1,10],[2,1],[2,2],[2... |
| 00:20:16 | <_achilles_> | hmmm |
| 00:20:24 | <omnId> | > [x+y | x <- [1..3] | y <- [4..6]] -- chessguy |
| 00:20:25 | <lambdabot> | Parse error |
| 00:20:39 | <omnId> | not the right syntax? Never used 'em. |
| 00:21:05 | <chessguy> | maybe they're in HEAD |
| 00:21:09 | <mauke> | lambdabot doesn't parse the syntax |
| 00:21:21 | <_achilles_> | I'm looking for a more...consise way to do it |
| 00:21:22 | <dons> | that's the syntax, but its not h98 |
| 00:21:33 | <dons> | _achilles_: zipwith is the best i can think of |
| 00:21:33 | <omnId> | parallel would give: [5,7,9] vs ordinary: [5,6,7,6,7,8,7,8,9] |
| 00:21:34 | <_achilles_> | I want the lists concated |
| 00:21:44 | <mauke> | > [1..5] ++ [1..10] |
| 00:21:46 | <lambdabot> | [1,2,3,4,5,1,2,3,4,5,6,7,8,9,10] |
| 00:22:00 | <dons> | `add two items in a list comprehension' ? |
| 00:22:04 | <_achilles_> | yeah, granted my example is more complicated than that |
| 00:22:11 | <_achilles_> | hah |
| 00:22:17 | <_achilles_> | now I get why you're confused |
| 00:22:26 | <_achilles_> | apped two items in a list comprehension |
| 00:22:30 | <ricky_clarkson> | Example input, example output. |
| 00:22:30 | <_achilles_> | append*** |
| 00:22:41 | <nornagon> | :t (***) |
| 00:22:43 | <lambdabot> | forall (a :: * -> * -> *) b c b' c'. (Arrow a) => a b c -> a b' c' -> a (b, b') (c, c') |
| 00:22:49 | <omnId> | [ x : xs | x <- heads, xs <- tails] ? |
| 00:22:49 | <nornagon> | :t append |
| 00:22:52 | <lambdabot> | Not in scope: `append' |
| 00:23:03 | <nornagon> | rats. |
| 00:23:13 | <chessguy> | @type heads |
| 00:23:15 | <lambdabot> | Not in scope: `heads' |
| 00:23:21 | <_achilles_> | [x : x ^ 2 | x <- [1..4]] |
| 00:23:24 | <_achilles_> | output |
| 00:23:24 | <nornagon> | heads is equal to 'the list' |
| 00:23:43 | <_achilles_> | [1,1,2,4,3,8,4,16] |
| 00:23:49 | <nornagon> | @let heads l = l :: forall a. [a] -> [a] |
| 00:23:50 | <lambdabot> | Parse error |
| 00:23:50 | <omnId> | > concatMap (\x -> [x, x^2]) [1..4] |
| 00:23:52 | <lambdabot> | [1,1,2,4,3,9,4,16] |
| 00:24:01 | <mauke> | _achilles_: stop misusing : |
| 00:24:02 | <_achilles_> | ahhhhh |
| 00:24:04 | <_achilles_> | damnit! |
| 00:24:13 | <_achilles_> | I knew I could do it with concatMap |
| 00:24:20 | <_achilles_> | my brain's dead tonight |
| 00:24:22 | <_achilles_> | thanks! |
| 00:24:22 | <omnId> | > concat [[x, x^2] | x <- [1..4]] |
| 00:24:23 | <lambdabot> | [1,1,2,4,3,9,4,16] |
| 00:24:36 | <mauke> | > [ y | x <- [1 .. 4], y <- [x, x ^ 2] ] |
| 00:24:37 | <_achilles_> | ooo...beuty omnld |
| 00:24:38 | <lambdabot> | [1,1,2,4,3,9,4,16] |
| 00:24:41 | <mauke> | surprise! |
| 00:24:46 | <omnId> | oh, silly me |
| 00:24:53 | <_achilles_> | beauty* |
| 00:24:53 | <Pseudonym> | > foldr (.) [] [ (x:) . (x^2:) | x <- [1..4] ] |
| 00:24:54 | <lambdabot> | Couldn't match expected type `a -> c' against inferred type `[a1]' |
| 00:25:17 | <ricky_clarkson> | > foldl (++) [] $ map (\x -> x : x^2) [1..4] |
| 00:25:18 | <lambdabot> | Occurs check: cannot construct the infinite type: a = [a] |
| 00:25:18 | <lambdabot> | Expected... |
| 00:25:34 | <omnId> | Pseudonym: s/[]/id/ then add [] to the end? |
| 00:25:48 | <Pseudonym> | Yeah, that's what I just did. |
| 00:25:49 | <_achilles_> | slick. thanks! |
| 00:25:55 | <Pseudonym> | But I don't like it. |
| 00:26:24 | <mauke> | > do x <- [1 .. 4]; y <- [x, x ^ 2]; return y |
| 00:26:26 | <lambdabot> | [1,1,2,4,3,9,4,16] |
| 00:26:28 | <ricky_clarkson> | > foldl (++) [] $ map (\x -> [x,x^2]) [1..4] |
| 00:26:30 | <lambdabot> | [1,1,2,4,3,9,4,16] |
| 00:26:33 | <shachaf> | ricky_clarkson: You mean (x : [x^2]) (or just [x,x^2]). |
| 00:26:39 | <Pseudonym> | > [1..4] >>= \x -> [x,x^2] |
| 00:26:41 | <lambdabot> | [1,1,2,4,3,9,4,16] |
| 00:26:52 | <shachaf> | Why foldl (++) []? |
| 00:27:03 | <omnId> | foldr'd be much better |
| 00:27:07 | <Pseudonym> | > concatMap (\x _> [x,x^2]) [1..4] |
| 00:27:07 | <lambdabot> | Parse error |
| 00:27:13 | <Pseudonym> | > concatMap (\x -> [x,x^2]) [1..4] |
| 00:27:13 | <omnId> | and anyway concat is already defined :) |
| 00:27:14 | <lambdabot> | [1,1,2,4,3,9,4,16] |
| 00:27:22 | <mauke> | > [1 .. 4] >>= id &&& (^2) |
| 00:27:23 | <mauke> | wait, no |
| 00:27:23 | <lambdabot> | Couldn't match expected type `[]' against inferred type `(,) t' |
| 00:27:28 | <ricky_clarkson> | shachaf: What else? |
| 00:27:37 | <shachaf> | ricky_clarkson: foldr (or concat). |
| 00:27:40 | <omnId> | ricky_clarkson: foldr! |
| 00:27:50 | <mauke> | > [1 .. 4] >>= sequence [id, (^2)] |
| 00:27:52 | <lambdabot> | [1,1,2,4,3,9,4,16] |
| 00:28:02 | <omnId> | (xs ++ ys) ++ zs walks over xs twice vs. xs ++ (ys ++ zs) |
| 00:28:24 | <ricky_clarkson> | shachaf: Same line, but s/foldl/foldr/ ? |
| 00:28:29 | <shachaf> | @src concat |
| 00:28:29 | <lambdabot> | concat = foldr (++) [] |
| 00:28:35 | <shachaf> | ricky_clarkson: But yes, otherwise. |
| 00:28:45 | <shachaf> | ricky_clarkson: Since lists are lazy enough, foldr is better. |
| 00:29:11 | <shachaf> | ricky_clarkson: http://haskell.org/haskellwiki/Stack_overflow |
| 00:29:12 | <lambdabot> | Title: Stack overflow - HaskellWiki |
| 00:29:24 | <ricky_clarkson> | Gotcha. |
| 00:30:21 | <shachaf> | ricky_clarkson: If you were using foldl, you'd probably want foldl', anyway. Not that it really matters with lambdabot. |
| 00:31:36 | <monochrom> | Yeah, lambdabot cuts your job short anyway. :) |
| 00:32:38 | <ricky_clarkson> | I'm guessing concatMap is the same as concat map, but I'm struggling to actually see that. |
| 00:32:53 | <lambdabot> | Don't tell them that. I'm gonna be asked so many homework questions. Sign. |
| 00:33:00 | <lambdabot> | Sigh. |
| 00:33:04 | <shachaf> | Wouldn't -O2 optimize it in this case? |
| 00:33:18 | <ddarius> | @src concatMap |
| 00:33:18 | <lambdabot> | concatMap f = foldr ((++) . f) [] |
| 00:33:22 | <shachaf> | ricky_clarkson: concatMap f xs = concat (map f xs) |
| 00:33:27 | <Pseudonym> | >/msg lambdabot ?help check |
| 00:33:36 | <Pseudonym> | D'oh. |
| 00:33:55 | <Pseudonym> | ?check \f xs -> concatMap f xs == concat (map f xs) |
| 00:33:56 | <lambdabot> | Add a type signature |
| 00:33:59 | <ddarius> | concatMap f = concat . map f |
| 00:34:14 | <Pseudonym> | ?check \f xs -> concatMap (f::Integer->Integer) xs == concat (map f xs) |
| 00:34:15 | <lambdabot> | Couldn't match expected type `[b]' against inferred type `Integer' |
| 00:34:26 | <Pseudonym> | ?check \f xs -> concatMap (f::Integer->Integer) (xs::Integer) == concat (map f xs) |
| 00:34:27 | <lambdabot> | Couldn't match expected type `[b]' against inferred type `Integer' |
| 00:34:31 | <shachaf> | concatMap = (concat .) . map |
| 00:34:35 | <Pseudonym> | ?check \f xs -> concatMap (f::Integer->Integer) (xs::[Integer]) == concat (map f xs) |
| 00:34:36 | <lambdabot> | Couldn't match expected type `[b]' against inferred type `Integer' |
| 00:34:40 | <Pseudonym> | Grrr. |
| 00:34:42 | <ddarius> | :t concatMap |
| 00:34:44 | <lambdabot> | forall a b. (a -> [b]) -> [a] -> [b] |
| 00:34:52 | <yitz> | @pl concatMap |
| 00:34:52 | <lambdabot> | (=<<) |
| 00:35:04 | <ddarius> | shachaf: Indeed, but I think the concat . map f is perhaps the clearest form |
| 00:35:04 | <wolverian> | heh |
| 00:35:13 | <shachaf> | ddarius: Yes. |
| 00:35:15 | <Pseudonym> | ?check (\f xs -> concatMap f xs == concat (map f xs)) :: (Int -> Int) -> [Int] -> Bool |
| 00:35:16 | <lambdabot> | Couldn't match expected type `[b]' against inferred type `Int' |
| 00:35:25 | <shachaf> | ddarius: Or the concatMap f xs = ... version. |
| 00:35:32 | <Pseudonym> | Oh. |
| 00:35:42 | <Pseudonym> | ?check (\f xs -> concatMap f xs == concat (map f xs)) :: (Int -> [Int]) -> [Int] -> Bool |
| 00:35:47 | <lambdabot> | Terminated |
| 00:35:50 | <ddarius> | If we expand concat into foldr (++) [], we get foldr (++) [] . map f which by foldr/map is foldr ((++) . f) [] |
| 00:35:51 | <Pseudonym> | Hrm. |
| 00:35:54 | <ddarius> | @src concatMap |
| 00:35:54 | <lambdabot> | concatMap f = foldr ((++) . f) [] |
| 00:37:58 | <ddarius> | That is what "point-free" style is supposed to look like. |
| 00:38:19 | <Pseudonym> | ?pl \f -> foldr ((++).f) [] |
| 00:38:19 | <lambdabot> | flip foldr [] . ((++) .) |
| 00:40:14 | <LoganCapaldo> | this is madness |
| 00:40:22 | <LoganCapaldo> | this is blaspemy |
| 00:40:31 | <LoganCapaldo> | this is POINTFREE! |
| 00:40:50 | <mauke> | SPARTA CALCULUS |
| 00:40:52 | <ricky_clarkson> | I love it. |
| 00:41:12 | <LoganCapaldo> | I have yet to wear that out for myself |
| 00:41:26 | <LoganCapaldo> | which is pretty impressive I think, since its so very formulaic |
| 00:42:26 | <monochrom> | Sparta? |
| 00:46:39 | <Beelsebob> | gyah |
| 00:46:47 | <Beelsebob> | need a good example of patern matching, without recursion |
| 00:47:15 | <LoganCapaldo> | @src isJust |
| 00:47:15 | <lambdabot> | isJust Nothing = False |
| 00:47:15 | <lambdabot> | isJust _ = True |
| 00:47:28 | <LoganCapaldo> | that's not recursive |
| 00:47:43 | <Beelsebob> | hmm, could work |
| 00:47:47 | <LoganCapaldo> | @src head |
| 00:47:47 | <lambdabot> | head (x:_) = x |
| 00:47:47 | <lambdabot> | head [] = undefined |
| 00:47:53 | <LoganCapaldo> | @src tail |
| 00:47:53 | <lambdabot> | tail (_:xs) = xs |
| 00:47:53 | <lambdabot> | tail [] = undefined |
| 00:48:05 | <LoganCapaldo> | @src maybe |
| 00:48:05 | <lambdabot> | maybe n _ Nothing = n |
| 00:48:05 | <lambdabot> | maybe _ f (Just x) = f x |
| 00:48:58 | <LoganCapaldo> | @src either |
| 00:48:58 | <lambdabot> | either f _ (Left x) = f x |
| 00:48:58 | <lambdabot> | either _ g (Right y) = g y |
| 00:49:09 | <Beelsebob> | yeh, that works |
| 00:49:14 | <Beelsebob> | thanks |
| 00:49:14 | <LoganCapaldo> | etc. etc. |
| 00:49:22 | <Beelsebob> | don't know why my brain couldn't come up with any of them |
| 00:49:34 | <Beelsebob> | I was coming up with contrived examples involving witches and ducks |
| 00:49:41 | <LoganCapaldo> | LOL |
| 00:49:48 | <LoganCapaldo> | I want to see those examples! |
| 00:49:53 | <Beelsebob> | hehe |
| 00:50:07 | <Beelsebob> | I couldn't express it in a purely pattern matching way :( |
| 00:50:08 | <monochrom> | witches I understand. ducks? |
| 00:50:24 | <Beelsebob> | monochrom: watch monty python and the holy grail |
| 00:50:25 | <LoganCapaldo> | if she weighs the same as a duck... |
| 00:50:32 | <LoganCapaldo> | then |
| 00:50:36 | <LoganCapaldo> | She's a witch! |
| 00:50:41 | <LoganCapaldo> | burn her burn her! |
| 00:50:53 | <Pseudonym> | That's the flaw with duck typing. |
| 00:50:55 | <monochrom> | OK, I haven't watched monty python anyway. BTW, I haven't watched python anything either. |
| 00:51:03 | <Beelsebob> | it follows the best piece of un-logic in existance |
| 00:51:12 | <Pseudonym> | If it weighs the same as a duck, it may be a witch. |
| 00:51:17 | <Beelsebob> | how to identify a witch... |
| 00:51:18 | <yitz> | ni |
| 00:51:25 | <Beelsebob> | what do you do with witches? Burn them |
| 00:51:35 | <Beelsebob> | why do witches burn? Because they're made of wood |
| 00:51:37 | <Pseudonym> | Build a bridge out of them? |
| 00:51:38 | <monochrom> | data She = Witch | Duck; f Witch = True; f Duck = false |
| 00:51:59 | <LoganCapaldo> | small stones! |
| 00:52:26 | <Beelsebob> | what else does wood do? Float |
| 00:52:34 | <Beelsebob> | what else floats? Ducks |
| 00:52:46 | <Beelsebob> | so if something weighs the same as a duck, it must be a witch |
| 00:52:47 | <Beelsebob> | :) |
| 00:52:55 | <yitz> | favoriteColor = const Red |
| 00:53:18 | <monochrom> | If something has the same density as a Duck, then it's a Float? |
| 00:53:52 | <monochrom> | @type isIEEE |
| 00:53:54 | <lambdabot> | forall a. (RealFloat a) => a -> Bool |
| 00:54:02 | <monochrom> | And so it's also a RealFloat? |
| 00:54:06 | <Sgeo> | const? Sorry, it's been a while since I've worked with Haskell |
| 00:54:17 | <Sgeo> | @type const |
| 00:54:19 | <lambdabot> | forall a b. a -> b -> a |
| 00:54:27 | <mrd> | @djinn a -> b -> a |
| 00:54:27 | <lambdabot> | f a _ = a |
| 00:54:30 | <Sgeo> | oh |
| 00:54:31 | <ddarius> | @. djinn type const |
| 00:54:33 | <lambdabot> | f a _ = a |
| 00:56:28 | <LoganCapaldo> | I like constantly |
| 00:56:37 | <LoganCapaldo> | constantly True |
| 00:56:45 | <LoganCapaldo> | but that's a lot of typing |
| 00:56:47 | <mauke> | forevermore |
| 00:56:52 | <LoganCapaldo> | oooo |
| 00:56:55 | <LoganCapaldo> | pretty |
| 00:57:04 | <ddarius> | @quote λ |
| 00:57:04 | <lambdabot> | No quotes match. I've seen penguins that can type better than that. |
| 00:57:19 | <LoganCapaldo> | and that's impressive |
| 00:57:23 | <LoganCapaldo> | because penguins lack fingers |
| 00:57:33 | <LoganCapaldo> | not to mention opposable thumbs |
| 00:57:34 | <Beelsebob> | @quote+ λx x |
| 00:57:34 | <lambdabot> | No quotes for this person. Just what do you think you're doing Dave? |
| 00:57:38 | <ToxicFrog> | Argh. |
| 00:57:47 | <Beelsebob> | bah |
| 00:57:50 | <mauke> | @quote |
| 00:57:51 | <lambdabot> | xahlee says: The Haskell Logo is the perfection of logos |
| 00:57:52 | <Beelsebob> | how do you add a quote |
| 00:58:07 | <shachaf> | @remember |
| 00:58:07 | <Beelsebob> | and can we make the quote system into a complete term rewriter :D |
| 00:58:09 | <Sgeo> | @quote Sgeo |
| 00:58:10 | <lambdabot> | No quotes match. I've seen penguins that can type better than that. |
| 00:58:12 | <ToxicFrog> | I keep getting "cannot construct the infinite type a -> [a]" |
| 00:58:12 | <LoganCapaldo> | @remember Beelsebob how do you add a quote |
| 00:58:12 | <lambdabot> | Done. |
| 00:58:14 | <Sgeo> | @quote goldilocks |
| 00:58:15 | <lambdabot> | No quotes match. Are you on drugs? |
| 00:58:23 | <ddarius> | There's no consistency in lambdabot's user interface |
| 00:58:32 | <Beelsebob> | indeed |
| 00:58:33 | <LoganCapaldo> | @ is pretty consistent |
| 00:58:42 | <ddarius> | ?bot |
| 00:58:43 | <lambdabot> | :) |
| 00:58:43 | <mauke> | ?vixen is it? |
| 00:58:44 | <Beelsebob> | > no "it's not" |
| 00:58:44 | <lambdabot> | yeah, it is |
| 00:58:45 | <lambdabot> | Not in scope: `no' |
| 00:58:45 | <LoganCapaldo> | except you can use ? instead |
| 00:58:56 | <Pseudonym> | Oooh, another Monty Python reference. |
| 00:58:56 | <LoganCapaldo> | and theres > which is short for @run |
| 00:59:10 | <Pseudonym> | "What's that on the IRC channel?" "Looks like a penguin!" |
| 00:59:34 | <mauke> | @eval (\x -> x x) (\x -> x x) |
| 00:59:45 | <Pseudonym> | :t \x -> x x |
| 00:59:47 | <lambdabot> | Occurs check: cannot construct the infinite type: t = t -> t1 |
| 00:59:47 | <lambdabot> | Probable cause: `x' is applied to too many arguments |
| 01:00:03 | <ddarius> | :t \(x :: forall a.a -> a) -> x x |
| 01:00:05 | <lambdabot> | forall a. (forall a1. a1 -> a1) -> a -> a |
| 01:00:12 | <ToxicFrog> | dons: still around? |
| 01:00:34 | <Pseudonym> | :t let f = \(x :: forall a. a -> a) -> x x in f f |
| 01:00:36 | <lambdabot> | Couldn't match expected type `a' (a rigid variable) |
| 01:00:37 | <lambdabot> | against inferred type `forall a1. a1 -> a1' |
| 01:01:50 | <ToxicFrog> | Hrm. At first I thought the problem was recursion, but even with a non-recursive function it blows up |
| 01:08:06 | <ToxicFrog> | ...and if I give it an explicit signature, I get "cannot match expected type State s t against inferred type [Integer]" in the caller, and "cannot match expected type Integer against inferred type [Integer]" in the definition. |
| 01:08:18 | <mauke> | you're doing it wrong |
| 01:08:44 | <vonBergmann> | i'd like to fold the min function over every second element of a list of tuples and return that tuple |
| 01:08:47 | <vonBergmann> | foldr1 min [(8,2),(3,4),(5,6)] |
| 01:09:00 | <ToxicFrog> | mauke: I noticed. |
| 01:09:01 | <vonBergmann> | is pretty close but it's folding min over the first element and not the second |
| 01:09:09 | <mauke> | > minimumBy snd [(8,2),(3,4),(5,6)] |
| 01:09:10 | <lambdabot> | Occurs check: cannot construct the infinite type: |
| 01:09:10 | <lambdabot> | b = (a, b) -> Or... |
| 01:09:14 | <mauke> | argh, right |
| 01:09:27 | <mauke> | > minimumBy (comparing snd) [(8,2),(3,4),(5,6)] |
| 01:09:29 | <lambdabot> | (8,2) |
| 01:09:44 | <vonBergmann> | actually i lied, i'd actually like to fold over triples |
| 01:09:47 | <vonBergmann> | over the third element |
| 01:10:16 | <vonBergmann> | can i access that third element without pattern matching? |
| 01:10:19 | <mauke> | > minimumBy (comparing (\(_,_,x) -> x)) [(8,2,"foo"),(3,4,"bar"),(5,6,"baz")] |
| 01:10:21 | <lambdabot> | (3,4,"bar") |
| 01:10:57 | <ToxicFrog> | It works fine as long as monads aren't involved, but that breaks the randomness. Aaaaaaaagh |
| 01:11:30 | <vonBergmann> | ok not quite sure i understand the example but i study and work through it for a bit, thanks mauke |
| 01:12:01 | <mauke> | :t minimumBy |
| 01:12:05 | <lambdabot> | forall a. (a -> a -> Ordering) -> [a] -> a |
| 01:12:13 | <vonBergmann> | :t comparing |
| 01:12:15 | <lambdabot> | forall b a. (Ord a) => (b -> a) -> b -> b -> Ordering |
| 01:14:32 | <ToxicFrog> | ...ok, what the fuck? |
| 01:14:45 | <ToxicFrog> | If I take the code that works without a signature... |
| 01:15:01 | <ToxicFrog> | Ask ghci for the type (which is 'mutate :: (Ord t, MonadState [t] t1, Num a, Fractional t) => [a] -> t1 [a]')... |
| 01:15:05 | <ToxicFrog> | ...and add that to the source... |
| 01:15:07 | <newsham> | ddarius: falseElim np2false = orElim exclMiddle (\p -> p) (\np -> absurd (np2false np)) |
| 01:15:16 | <ToxicFrog> | It says it's an illegal type declaration. |
| 01:15:16 | <vonBergmann> | i've never used minimumBy before and looking it up at sites like: http://www.zvon.org/other/haskell/Outputglobal/index.html isn't very helpful because the documentation is incomplete.... what are some better sources? |
| 01:15:18 | <lambdabot> | Title: Haskell |
| 01:15:22 | <conal> | does anyone have a pretty printer for haskell code that handles precedence (paren insertion)? |
| 01:17:05 | <mauke> | @source Data.List |
| 01:17:05 | <lambdabot> | http://darcs.haskell.org/packages/base/Data/List.hs |
| 01:17:10 | <mauke> | @docs Data.List |
| 01:17:11 | <lambdabot> | http://haskell.org/ghc/docs/latest/html/libraries/base/Data-List.html |
| 01:20:47 | <vonBergmann> | sorry another dumb question, so is the best source for all the documentation at haskell.org? how does looking up haskell documentation compare to something like the java api? |
| 01:21:18 | <vonBergmann> | is minimumby not available at zvon because it is relatively new? |
| 01:21:23 | <mauke> | I don't know about java but I usually start at http://www.haskell.org/ghc/docs/latest/html/libraries/ |
| 01:30:18 | <newsham> | http://www.thenewsh.com/%7Enewsham/formal/curryhoward/Theorems3.hs |
| 01:30:21 | <lambdabot> | http://tinyurl.com/2zhgbh |
| 01:32:11 | <ToxicFrog> | Maybe I should just give up on this and return to Haskell later, for a project that doesn't need random numbers. |
| 01:32:17 | <monochrom> | I have never heard of zvon. |
| 01:32:20 | <Philippa> | ACTION wishes she could get away with writing lhs `infix' p` rhs as a parser :-( |
| 01:32:49 | <Philippa> | (where p would be dropped, lhs and rhs are arbitrary parsers - the problem is that you can only do `<identifier>`) |
| 01:32:57 | <Philippa> | and it'd be cute |
| 01:33:11 | <shachaf> | Philippa: There was that trick with... -: and :-, I think? |
| 01:33:32 | <Philippa> | yeah, that's getting obscure enough not to be worth it in terms of readability though |
| 01:36:33 | <newsham> | i wish you could put bars/superscripts/hats over operators to do something like that. |
| 01:36:45 | <newsham> | ie. +^ = liftM 2 (+) |
| 01:37:20 | <shachaf> | newsham: That's a slippery slope that leads to J-land. |
| 01:37:52 | <newsham> | I dont know J, but I've been looking at funmath (notation, not computer language) and i like it |
| 01:38:23 | <newsham> | they have symbols above binops for lifting into (->) in various ways |
| 01:38:38 | <newsham> | (lift binary, lift just left section, lift right section) |
| 01:39:59 | <FMota> | hey guys / gals |
| 01:40:26 | <FMota> | is there a way to cut off from a list when a certain condition is met? |
| 01:40:42 | <newsham> | takeWhile / dropWhile? |
| 01:40:43 | <mauke> | takeWhile |
| 01:40:46 | <FMota> | I mean, a way to extract the first x values of the list, that depends on the values |
| 01:40:48 | <FMota> | ah, ty |
| 01:41:09 | <mauke> | > takeWhile even [ 2 .. 20 ] |
| 01:41:11 | <lambdabot> | [2] |
| 01:41:16 | <newsham> | > dropWhile (<10) [1..30] |
| 01:41:17 | <lambdabot> | [10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30] |
| 01:41:53 | <FMota> | ACTION is doing the euler project :) |
| 01:47:03 | <SamB> | ACTION wonders how he came to be a latex user |
| 01:47:06 | <FMota> | ...and what about a function to see if an item is in a list? |
| 01:47:34 | <LoganCapaldo> | @type find |
| 01:47:37 | <lambdabot> | forall a. (a -> Bool) -> [a] -> Maybe a |
| 01:47:40 | <LoganCapaldo> | @type filter |
| 01:47:43 | <lambdabot> | forall a. (a -> Bool) -> [a] -> [a] |
| 01:47:44 | <idnar> | :t elem |
| 01:47:47 | <lambdabot> | forall a. (Eq a) => a -> [a] -> Bool |
| 01:47:49 | <FMota> | aha |
| 01:47:50 | <LoganCapaldo> | @type any |
| 01:47:52 | <FMota> | thank you! |
| 01:47:52 | <lambdabot> | forall a. (a -> Bool) -> [a] -> Bool |
| 01:47:54 | <FMota> | elem :) |
| 01:48:36 | <idnar> | > let l = [1..10] in (elem 5 l, elem 15 l) |
| 01:48:41 | <newsham> | ?docs Data.List |
| 01:48:41 | <lambdabot> | http://haskell.org/ghc/docs/latest/html/libraries/base/Data-List.html |
| 01:48:42 | <lambdabot> | (True,False) |
| 01:49:09 | <LoganCapaldo> | I wonder if elem is written with any or elemIndex? |
| 01:49:14 | <LoganCapaldo> | @src elem |
| 01:49:14 | <lambdabot> | elem x = any (== x) |
| 01:50:15 | <chessguy> | @type elemIndex |
| 01:50:17 | <lambdabot> | forall a. (Eq a) => a -> [a] -> Maybe Int |
| 01:50:30 | <chessguy> | @src elemIndex |
| 01:50:30 | <lambdabot> | elemIndex x = findIndex (x==) |
| 01:50:41 | <chessguy> | @src findIndex |
| 01:50:42 | <lambdabot> | findIndex p = listToMaybe . findIndices p |
| 01:51:04 | <chessguy> | quite a few levels of abstraction |
| 01:51:12 | <chessguy> | @src findIndices |
| 01:51:12 | <lambdabot> | findIndices p xs = [ i | (x,i) <- zip xs [0..], p x] |
| 01:51:50 | <chessguy> | @src listToMaybe |
| 01:51:50 | <lambdabot> | listToMaybe [] = Nothing |
| 01:51:51 | <lambdabot> | listToMaybe (a:_) = Just a |
| 01:53:50 | <mudge> | hey chessguy, hey LoganCapaldo |
| 01:54:12 | <chessguy> | 'evening, sir |
| 01:54:31 | <LoganCapaldo> | hola |
| 01:56:41 | <ToxicFrog> | Argh. Bollocks to this, I don't have time to sort it out, I'll come back to Haskell for the next project. |
| 01:57:09 | <chessguy> | what sort of project are you working on, ToxicFrog ? |
| 01:57:41 | <LoganCapaldo> | a frog antitoxin? |
| 01:57:46 | <ToxicFrog> | Genetic algorithms. |
| 01:57:51 | <ToxicFrog> | For which I need random numbers. |
| 01:57:54 | <ToxicFrog> | Which are made of pain. |
| 01:58:00 | <chessguy> | lol |
| 01:58:15 | <chessguy> | i've done some working on genetic programming in haskell |
| 01:58:22 | <Pseudonym> | Oh, we have a mechanism for pain in Haskell. |
| 01:58:23 | <chessguy> | never did find a way to do it that satisfied me |
| 01:58:26 | <ToxicFrog> | The whole thing is pretty clean and elegant in Haskell until I get to the random numbers. |
| 01:58:29 | <Pseudonym> | http://andrew.bromage.org/unsafe.jpeg |
| 01:58:31 | <chessguy> | @quote pain |
| 01:58:31 | <lambdabot> | <basti_> says: Snow doeth lay upon the lands. Even with cunning newtype; deriving the newtype is recursive. Great leaders brings less pain. |
| 01:58:32 | <LoganCapaldo> | unsafePerformTorture |
| 01:59:12 | <LoganCapaldo> | the # is the perfect touch |
| 01:59:17 | <Pseudonym> | Yeah. |
| 01:59:20 | <ToxicFrog> | Then I feel sorrow. |
| 01:59:23 | <ToxicFrog> | So much sorrow./ |
| 01:59:49 | <Pseudonym> | I did some genetic programming, but my mutation/breeding/whatever stuff was pretty simple. |
| 01:59:57 | <Pseudonym> | I thought it was pretty elegant. |
| 02:00:04 | <Pseudonym> | Probably because of the simplicity. |
| 02:00:08 | <ToxicFrog> | So's mine, but it needs randoms. |
| 02:00:12 | <chessguy> | Pseudonym, i'd like to see that sometime |
| 02:00:14 | <LoganCapaldo> | What about the Random monad? does thtat ease the pain? |
| 02:00:28 | <ToxicFrog> | The Random monad is the source of the pain |
| 02:01:01 | <ToxicFrog> | If I use non-monadic mkStdGen it works fine, but it's also not usefully random. |
| 02:01:21 | <LoganCapaldo> | you could use newStdGen |
| 02:01:33 | <LoganCapaldo> | but then you're stuck in IO instead of Random |
| 02:01:36 | <Pseudonym> | IIRC, I just put everything in the IO monad. |
| 02:01:43 | <Pseudonym> | Or some transformer on top of IO. |
| 02:01:51 | <ToxicFrog> | If I use newStdGen, it works great until I try actually writing non-trivial code that uses it. |
| 02:02:02 | <ToxicFrog> | At which point the type-inference engine develops a hunger for human flesh. |
| 02:02:19 | <Pseudonym> | unsafeTypeChecker |
| 02:02:23 | <chessguy> | oh, that's what unsafeWoodenStake is for |
| 02:02:42 | <Pseudonym> | ?type Braanes! |
| 02:02:44 | <lambdabot> | parse error (possibly incorrect indentation) |
| 02:03:25 | <dibblego> | why is there no instance for Maybe? |
| 02:03:26 | <chessguy> | braanes? |
| 02:03:29 | <dibblego> | of Arbitrary |
| 02:03:35 | <ToxicFrog> | I mean, ok, I have a function pmap :: Float -> (a -> b) -> [a] -> [b], which is a probabilistic version of map |
| 02:03:41 | <mrd> | oh no, the monad has tasted human blood! |
| 02:04:02 | <ToxicFrog> | I have a function mutate, called from main as ( do a <- mutate [0,0,0,0,0,0,0,0]; return a ) |
| 02:04:13 | <monochrom> | I advocate infinite lists. I don't just mean use an infinite list of random numbers. Much much more than that. Your whole algorithm your whole program, is structured around infinite lists. The fact that random numbers are found in an infinite list is just a small corollary of that. It will be beauitful and stateless. It is also a total paradigm shift. |
| 02:04:16 | <ToxicFrog> | mutate li = pmap 0.5 (+1) li -- this works |
| 02:04:34 | <FMota> | :t take |
| 02:04:36 | <lambdabot> | forall a. Int -> [a] -> [a] |
| 02:04:37 | <FMota> | :t drop |
| 02:04:39 | <lambdabot> | forall a. Int -> [a] -> [a] |
| 02:05:05 | <ToxicFrog> | mutate li = if (head li) == 1 then li else pmap 0.5 (+1) li -- this causes a "cannot construct the infinite type a -> [a]" error |
| 02:05:16 | <monochrom> | IOW use infinite lists for everything else in your program. That's what I advocate. |
| 02:05:27 | <ToxicFrog> | Note that as long as random isn't involved, the above declaration of mutate works fine |
| 02:06:27 | <chessguy> | out of curiosity, what's the 0.5 there? |
| 02:07:13 | <ToxicFrog> | Probability of application to each list element. |
| 02:07:27 | <shachaf> | ToxicFrog: What is mutate's type supposed to be? |
| 02:07:34 | <ToxicFrog> | pmap prob func list is the same as map func list, except that func only has a prob chance of being applied. |
| 02:07:56 | <ToxicFrog> | ...which I suppose means that the signature is actually Float -> (a -> a) -> [a] -> [a], but that's fine |
| 02:08:03 | <shachaf> | ToxicFrog: That looks like it should work, can you give more context? |
| 02:08:09 | <chessguy> | @type mutate li@(1:xs) = li; mutate li = ?pmap 0.5 (+1) li |
| 02:08:11 | <lambdabot> | parse error on input `=' |
| 02:08:29 | <ToxicFrog> | Hang on, I'll pastebin it. |
| 02:08:38 | <mauke> | @type \li -> if head li == 1 then li else ?pmap 0.5 (+1) li |
| 02:08:40 | <lambdabot> | forall a t a1. (Num a, ?pmap::t -> (a1 -> a1) -> [a] -> [a], Fractional t, Num a1) => [a] -> [a] |
| 02:08:45 | <monochrom> | Gosh! ContT r m a ≅ Cont (m r) a. I never noticed it, but it's now staring at me. |
| 02:08:49 | <LoganCapaldo> | I was gonna say shouldn't the type be like Float -> (a -> b) -> [a] -> [Either a b] |
| 02:09:44 | <hpaste> | (anonymous) pasted "(no title)" at http://hpaste.org/3294 |
| 02:10:12 | <ToxicFrog> | The first three functions are based on http://hpaste.org/3293 , kindly provided by dons |
| 02:11:06 | <shachaf> | ToxicFrog: pmap's type is the problem. |
| 02:11:22 | <shachaf> | ToxicFrog: What you have is pmap :: (Ord a1, MonadState [a1] t) => a1 -> (a -> a) -> [a] -> t [a] |
| 02:11:35 | <shachaf> | You aren't runState-ing it. |
| 02:11:43 | <chessguy> | ToxicFrog, type annotations are your friends |
| 02:11:53 | <shachaf> | ToxicFrog: And what chessguy said. |
| 02:12:30 | <chessguy> | stop fighting the type system |
| 02:12:37 | <hpaste> | omnId annotated "(no title)" with "typechecks." at http://hpaste.org/3294#a1 |
| 02:12:45 | <shachaf> | @wiki New monads/MonadSupply |
| 02:12:45 | <lambdabot> | http://www.haskell.org/haskellwiki/New_monads/MonadSupply |
| 02:12:50 | <shachaf> | Maybe that's relevant? |
| 02:12:50 | <omnId> | diff: http://hpaste.org/3294/diff?old=0&new=1 |
| 02:13:54 | <shachaf> | Yes, return li is better, of course. |
| 02:14:03 | <shachaf> | Since mutate is also in State. |
| 02:14:20 | <chessguy> | glguy! |
| 02:14:26 | <omnId> | pmap results in a State action, but mutate resulted in either a list, or a list in a State action, you have to return the first case into State. |
| 02:14:43 | <glguy> | \o/ |
| 02:15:11 | <chessguy> | how's things in galois-land? |
| 02:15:19 | <glguy> | green |
| 02:15:30 | <chessguy> | umm |
| 02:15:33 | <glguy> | Why do you ask? looking for interviews? ;) |
| 02:15:34 | <ToxicFrog> | ...it would probably help here if I understood (1) monads in general (2) State in specific |
| 02:15:35 | <chessguy> | i guess that's a good thing.. |
| 02:15:40 | <chessguy> | .lol |
| 02:15:47 | <chessguy> | i wouldn't waste their time or mine :) |
| 02:15:53 | <chessguy> | not yet anyway. maybe someday |
| 02:15:57 | <omnId> | ToxicFrog: the thing to understand is that [a] /= State [Bool] [a] |
| 02:16:05 | <glguy> | well, at least you're considerate then! |
| 02:16:24 | <omnId> | s/Bool/Double/ |
| 02:16:32 | <chessguy> | besides, i think my fiancee would kill me if i told her i was moving again :) |
| 02:16:35 | <omnId> | return puts your [a] into the State [Double] monad |
| 02:17:28 | <omnId> | in the expression: (if (head li) == 1 then li else pmap 0.5 (+1) li), the 'then' case, "li" has type [a], but the 'else' case "pmap 0.5 (+1) li" has type State [Double] [a] |
| 02:17:32 | <omnId> | they don't match |
| 02:17:34 | <glguy> | Yeah, I'm definitely not an Oregonian :) |
| 02:17:36 | <ToxicFrog> | Ok. And State [Double] [a] is a monad representing something with a persistent state of type [Double], and a return value from some state-specific computation of type [a]? |
| 02:17:44 | <shachaf> | ToxicFrog: Try reimplementing State yourself -- it's helpful in understanding it. |
| 02:18:14 | <chessguy> | ToxicFrog, no, State is a monad. State [Double] [a] is not |
| 02:18:24 | <omnId> | ToxicFrog: yep, though the word "monad" specifically refers the the unapplied type State [Double], the State [Double] [a] is called an action. |
| 02:18:27 | <shachaf> | chessguy: State [Double] is a monad. |
| 02:18:30 | <chessguy> | err, right |
| 02:18:38 | <chessguy> | ACTION goes back to feeling dumb |
| 02:18:43 | <omnId> | :) |
| 02:18:55 | <LoganCapaldo> | State is walking down the road towards being a monad :) |
| 02:19:06 | <LoganCapaldo> | it hasn't met it's body s yet :) |
| 02:19:12 | <LoganCapaldo> | s/body/buddy/ |
| 02:19:14 | <chessguy> | a curried monad? :) |
| 02:19:25 | <shachaf> | Yum. |
| 02:19:56 | <ToxicFrog> | Aah. Ok. |
| 02:20:18 | <ToxicFrog> | So State [Double] [a] is an action that, when...executed? updates its internal [Double] and returns an [a]? |
| 02:20:28 | <omnId> | exactly! |
| 02:20:55 | <chessguy> | well, of course, it may or may not have an effect on its state |
| 02:21:00 | <LoganCapaldo> | (might update the [Double]) |
| 02:21:09 | <omnId> | the do block hooks together the actions and they are executed when the top level does a runState and passes in the initial state value. |
| 02:21:44 | <omnId> | @src State (>>=) |
| 02:21:45 | <lambdabot> | Source not found. My pet ferret can type better than you! |
| 02:21:58 | <mauke> | @src State >>= |
| 02:21:59 | <lambdabot> | Source not found. Just what do you think you're doing Dave? |
| 02:21:59 | <shachaf> | ToxicFrog: State [Double] [a] is a function :: [Double] -> ([a],[Double]), wrapped up in a State type. |
| 02:22:18 | <ToxicFrog> | Ok. |
| 02:22:29 | <omnId> | m >>= k = State (\s -> let (a, s') = runState m in runState (k a) s') |
| 02:22:32 | <shachaf> | newtype State s a = State (s -> (a,s)) |
| 02:22:37 | <dons> | ?unmtl State [Double] [a] |
| 02:22:38 | <lambdabot> | [Double] -> ([a], [Double]) |
| 02:22:38 | <omnId> | (I hope I didn't make any errors. |
| 02:22:53 | <ToxicFrog> | And pmap has this type? So when pmap is evaluated, it generates not an [a], but an action which must be executed to produce an [a]? |
| 02:22:55 | <shachaf> | runState (State x) = x |
| 02:23:03 | <omnId> | ToxicFrog: yes |
| 02:23:04 | <shachaf> | ToxicFrog: Yes. |
| 02:23:06 | <shachaf> | ToxicFrog: Just like IO. |
| 02:23:21 | <ToxicFrog> | I haven't used IO, I've never needed it. |
| 02:23:22 | <shachaf> | ToxicFrog: (Or any monad.) |
| 02:23:27 | <ToxicFrog> | But ok, this is starting to make sense. |
| 02:23:42 | <shachaf> | ToxicFrog: Your main is :: IO (). |
| 02:23:42 | <LoganCapaldo> | heh never needed IO. Impressive :) |
| 02:23:51 | <ToxicFrog> | Ok, never explicitly used IO. |
| 02:23:56 | <ToxicFrog> | Apart from that print. |
| 02:23:57 | <omnId> | ToxicFrog: though in actuality, the return type is even more general: MonadState [Double] m => m [a], meaning that the monad type itself can be State [Double], or something else that behaves the same. |
| 02:23:58 | <Tela> | ToxicFrog: You implicitly use IO in every program. Your main function is IO () and it's "executed" when the program runs. |
| 02:24:07 | <shachaf> | And newStdgen, and print. |
| 02:24:25 | <ToxicFrog> | So...could I, in theory, wrap pmap in a function that executes the action returned by pmap, and returns the result of that action? |
| 02:24:38 | <shachaf> | ToxicFrog: Yes. |
| 02:24:53 | <shachaf> | ToxicFrog: But that wouldn't have much point, possibly. |
| 02:24:57 | <ToxicFrog> | ...why not |
| 02:24:58 | <ToxicFrog> | ? |
| 02:25:03 | <omnId> | pmap' p f xs ds = runState (pmap p f xs) ds |
| 02:25:06 | <Tela> | ToxicFrog, but then realize that you'll have to give it a random seed in order to execute your state |
| 02:25:06 | <shachaf> | ToxicFrog: Since there's no point in returning the [Double] if you don't use that. |
| 02:25:12 | <FMota> | question: how can I se large integers in Haskell? |
| 02:25:16 | <FMota> | *I use |
| 02:25:19 | <shachaf> | FMota: Integer. |
| 02:25:21 | <FMota> | do I need some import? |
| 02:25:25 | <mauke> | just do it |
| 02:25:26 | <mauke> | no |
| 02:25:26 | <ToxicFrog> | shachaf: I would return the result, not the updated state |
| 02:25:28 | <LoganCapaldo> | > 348345884537573857387575843758347857385782378123787258578345 :: Integer |
| 02:25:30 | <lambdabot> | 348345884537573857387575843758347857385782378123787258578345 |
| 02:25:39 | <FMota> | mk |
| 02:25:43 | <mauke> | ToxicFrog: if you drop the updated state, why use State at all? |
| 02:25:45 | <chessguy> | > maxBound :: Int |
| 02:25:46 | <omnId> | pmap' p f xs ds = evalState (pmap p f xs) ds -- evalState ignores the final state value |
| 02:25:46 | <lambdabot> | 2147483647 |
| 02:25:50 | <LoganCapaldo> | > 348345884537573857387575843758347857385782378123787258578345588846 -- no type annotation necessary |
| 02:25:51 | <lambdabot> | 348345884537573857387575843758347857385782378123787258578345588846 |
| 02:25:54 | <ToxicFrog> | mauke: I thought State updated it! |
| 02:26:00 | <FMota> | > succ (12123412312414324234 :: Integer) |
| 02:26:01 | <shachaf> | ToxicFrog: So there's no point in writing pmap in terms of State. |
| 02:26:01 | <lambdabot> | 12123412312414324235 |
| 02:26:08 | <mauke> | ToxicFrog: yes, and when you use runState, it gives you the result |
| 02:26:12 | <mauke> | there is no magic here |
| 02:26:13 | <ToxicFrog> | ...but...that doesn't make any sense, from what you said earlier... |
| 02:26:16 | <shachaf> | LoganCapaldo: That's just because of defaulting. |
| 02:26:24 | <SamB> | heh. now that's overkill - TeX uses units smaller than the wavelengths of visible light |
| 02:26:27 | <LoganCapaldo> | But that's the default default though right? |
| 02:26:43 | <Pseudonym> | SamB: But I want to use TeX for nanolithography! |
| 02:26:45 | <omnId> | ToxicFrog: I think he's saying that you *don't* want to drop the state value, since then it would be incorrect. |
| 02:26:48 | <shachaf> | ToxicFrog: It doesn't *really* update it. |
| 02:26:49 | <chessguy> | @quote magic |
| 02:26:49 | <lambdabot> | malig says: I have to admit I'm still stunned when "tying the knot" actually works. it's like I just performed the kind of magic that normally requires a lot more goat's blood |
| 02:27:05 | <omnId> | ToxicFrog: the State monads take care of the passing around for you. |
| 02:27:12 | <SamB> | Pseudonym: well, there's always magnification anyway |
| 02:27:18 | <Pseudonym> | I guess. |
| 02:27:23 | <Pseudonym> | ACTION grumbles... not the same... |
| 02:27:44 | <LoganCapaldo> | State is sort of like composing all your functions together instead of executing them and at the very end you run the giant function with some intial state |
| 02:28:00 | <chessguy> | @index modify |
| 02:28:00 | <lambdabot> | Control.Monad.State, Control.Monad.RWS |
| 02:28:04 | <omnId> | s/sort of like/like/ |
| 02:28:05 | <shachaf> | LoganCapaldo: Again, just like IO. |
| 02:28:33 | <chessguy> | err, why isn't modify listed on http://www.haskell.org/ghc/docs/latest/html/libraries/mtl/Control-Monad-State-Lazy.html ? |
| 02:28:35 | <lambdabot> | http://tinyurl.com/2dn8t6 |
| 02:28:37 | <LoganCapaldo> | yeah but maybe if it gets said enough different ways one of them will click for ToxicFrog :) |
| 02:29:00 | <omnId> | @index modify |
| 02:29:00 | <lambdabot> | Control.Monad.State, Control.Monad.RWS |
| 02:29:07 | <omnId> | chessguy: 'twould seem not to be there |
| 02:29:11 | <chessguy> | hm, i actually rather like LoganCapaldo's way of saying it |
| 02:29:32 | <shachaf> | chessguy: Maybe it's in Control.Monad.State.Class? |
| 02:29:32 | <chessguy> | omnId, but it's not at http://www.haskell.org/ghc/docs/latest/html/libraries/mtl/Control-Monad-State.html |
| 02:29:34 | <chessguy> | either |
| 02:29:34 | <lambdabot> | http://tinyurl.com/yx2t8w |
| 02:29:38 | <shachaf> | If such a thing exists? |
| 02:29:45 | <ToxicFrog> | ...all I want is a probabilistic map function that I can call from pure code... |
| 02:29:47 | <ToxicFrog> | ACTION weeps |
| 02:29:55 | <mauke> | ToxicFrog: no such thing |
| 02:29:55 | <chessguy> | oh, there it is |
| 02:29:57 | <chessguy> | weird |
| 02:30:11 | <omnId> | chessguy: -Class? |
| 02:30:15 | <mauke> | rand() isn't pure |
| 02:30:18 | <Tela> | ToxicFrog: That's just the point. Code purity ensures that such a thing can't exist. |
| 02:30:22 | <chessguy> | ToxicFrog, random numbers are inherently impure |
| 02:30:47 | <chessguy> | omnId, it's at http://www.haskell.org/ghc/docs/latest/html/libraries/mtl/Control-Monad-State-Class.html |
| 02:30:48 | <lambdabot> | http://tinyurl.com/37tgec |
| 02:31:00 | <Pseudonym> | I wonder if this would be better expressed as an Arrow. |
| 02:31:13 | <Pseudonym> | Which is close enough to a "function". |
| 02:31:14 | <ToxicFrog> | ...so, wait. |
| 02:31:17 | <Tela> | ToxicFrog: the neat part is that once you /do/ refactor this problem into something that works with Haskell, you'll very clearly be able to see exactly what parts of your problem are pure. |
| 02:31:32 | <mauke> | reading existentials is hard. let's go shopping! |
| 02:31:41 | <ToxicFrog> | If I need random numbers at a low level, everything above that becomes impure? |
| 02:31:52 | <chessguy> | @remember mauke reading existentials is hard. let's go shopping! |
| 02:31:52 | <lambdabot> | Done. |
| 02:32:04 | <mauke> | depends |
| 02:32:16 | <Tela> | ToxicFrog: As long as your random parts don't preserve referential transparency |
| 02:32:26 | <mauke> | "random" numbers need state. you can do explicit state passing. |
| 02:32:31 | <omnId> | ToxicFrog: usually people do the impure stuff once on top and generate what they need, then they pass it all to pure code that works on pure values. |
| 02:32:31 | <chessguy> | couldn't ToxicFrog just get a random list of numbers in main and pass it into the rest of the program? |
| 02:32:43 | <omnId> | chessguy: yes |
| 02:32:54 | <FMota> | :t take |
| 02:32:56 | <lambdabot> | forall a. Int -> [a] -> [a] |
| 02:32:58 | <omnId> | chessguy: though State makes the passing part less tedious. |
| 02:33:02 | <FMota> | :/ |
| 02:33:02 | <ToxicFrog> | I mean, I have an iteration function, which is defined in terms of a transition function, which is defined in terms of a mutation function, which is defined in terms of pmap, which needs random numbers. |
| 02:33:14 | <FMota> | is there a way to do take with Integers instead of with Ints ? |
| 02:33:18 | <ToxicFrog> | And it needs different random numbers each time, as otherwise the mutation function is not useful. |
| 02:33:19 | <FMota> | or do I have to make my own? :/ |
| 02:33:20 | <omnId> | FMota: genericTake |
| 02:33:21 | <sorear> | :t genericTake |
| 02:33:21 | <mauke> | ToxicFrog: you'll have to pass some sort of state through all of that |
| 02:33:23 | <lambdabot> | forall i a. (Integral i) => i -> [a] -> [a] |
| 02:33:25 | <FMota> | ty |
| 02:34:09 | <ToxicFrog> | mauke: so, basically, I'm in function signature hell, as I have to pass and return the remainder of the list of random numbers through way too many layers of evaluation for comfort. |
| 02:34:30 | <FMota> | ugh |
| 02:34:30 | <mauke> | ToxicFrog: yes |
| 02:34:35 | <Tela> | You're thinking that just one part of your program requires inpurity, but really the entire algorithm you just described is impure. In some sense, the core of your program is impure, but you'll likely be able to extract a lot of pure pieces. |
| 02:34:36 | <FMota> | genericTake not in scope |
| 02:34:36 | <mauke> | or you could hide it behind State |
| 02:34:57 | <mauke> | you'll still have to tag your State-using functions with State |
| 02:35:05 | <mauke> | @index genericTake |
| 02:35:06 | <lambdabot> | Data.List |
| 02:35:12 | <FMota> | ty |
| 02:35:23 | <omnId> | ToxicFrog: if your algorithm needs a source of random numbers, they have to come from somewhere. You can think of most imperative languages as always recieving the state of the real world as an argument, so they can interact with it, then always returning an updated real world. |
| 02:35:28 | <ToxicFrog> | Tela: well, yes, in that only two operations in the entire program (breed and mutate) need randomness, but the entire program is defined in terms of those operations. |
| 02:35:49 | <FMota> | well, now the program doesn't stop, but at least it runs ;) |
| 02:36:21 | <Tela> | ToxicFrog Yeah, so your entire program needs to maintain state else it'll repeat itself. |
| 02:36:22 | <ToxicFrog> | mauke: see, that's what dons was trying to help me with earlier. However, while I now have a better understanding of what State is thanks to your-plural efforts, I don't fully grasp how to use it. |
| 02:36:32 | <ToxicFrog> | Nor how passing State around is better than passing [Double] around. |
| 02:36:47 | <mauke> | ToxicFrog: less typing |
| 02:37:07 | <mauke> | instead of a -> b -> c -> [Double] -> ([Double], z) you can write a -> b -> c -> State [Double] z |
| 02:37:09 | <omnId> | ToxicFrog: try passing the [Double]s around yourself and making sure you thread everything right first. It's tedious, but possible. |
| 02:37:46 | <ToxicFrog> | omnId: see, this is the point where, as mentioned earlier, I switch to an imperative language and come back to Haskell when I have a project that doesn't require state. |
| 02:38:04 | <omnId> | ToxicFrog: if your functions make State actions instead, then those actions can be hooked together with the standard bind that passes for you. |
| 02:38:21 | <ToxicFrog> | "the standard bind"? |
| 02:38:35 | <omnId> | Monad's (>>=), which is inserted with do notation. |
| 02:38:48 | <dons> | huh, andrew coppin really did unsubscribe from -cafe@ |
| 02:39:05 | <Pseudonym> | I say we Cc him on everything. |
| 02:39:12 | <dons> | heh |
| 02:39:21 | <omnId> | > runState (get >>= \x -> return (x + 1)) 3 |
| 02:39:23 | <lambdabot> | (4,3) |
| 02:39:35 | <omnId> | > runState (do x <- get ; return (x + 1)) 3 |
| 02:39:36 | <lambdabot> | (4,3) |
| 02:39:45 | <mauke> | ToxicFrog: er. then what are you going to use Haskell for? |
| 02:40:06 | <mauke> | state is pretty common |
| 02:40:23 | <chessguy> | ToxicFrog, what are you breeding, anyway? |
| 02:40:49 | <ToxicFrog> | mauke: I don't know! Genetic algorithms and ant colony optimization both need an entropy pool. Something will present itself eventually. Perhaps. |
| 02:40:53 | <omnId> | > runState (State (\s -> (s,s)) >>= \x -> State (\s -> (x + 1, s))) 3 |
| 02:40:55 | <ToxicFrog> | chessguy: solutions to a function. |
| 02:40:55 | <lambdabot> | (4,3) |
| 02:41:15 | <FMota> | wha, it's complaining about fractional integers now |
| 02:41:26 | <omnId> | FMota: fromIntegral might help |
| 02:41:26 | <mauke> | FMota: are you using / somewhere? |
| 02:41:32 | <FMota> | is there anyway to just do simple integer division? |
| 02:41:35 | <iank> | div |
| 02:41:35 | <omnId> | div |
| 02:41:37 | <mauke> | `div` |
| 02:41:39 | <shachaf> | > runState (State (\s -> (s + 1, s))) 3 -- As long as you're expanding it, there's no need to use get |
| 02:41:40 | <FMota> | oh, ok |
| 02:41:40 | <lambdabot> | (4,3) |
| 02:41:40 | <Tac-Tics> | > 5 `div` 2 |
| 02:41:41 | <FMota> | ty |
| 02:41:42 | <lambdabot> | 2 |
| 02:41:59 | <omnId> | shachaf: one step at a time :) |
| 02:42:13 | <omnId> | > (\s -> (s + 1, s)) 3 |
| 02:42:14 | <lambdabot> | (4,3) |
| 02:42:21 | <Pseudonym> | BTW, is it a rite of passage for a community to get its first "I'm leaving in a huff"? |
| 02:42:38 | <shachaf> | > runState (State ((+1) &&& id)) 3 |
| 02:42:39 | <ToxicFrog> | Ok. runState takes an action and an initial state? And the action can use get and put to manipulate said state? |
| 02:42:39 | <lambdabot> | (4,3) |
| 02:42:48 | <omnId> | yep |
| 02:42:53 | <mauke> | ToxicFrog: yes |
| 02:42:54 | <omnId> | @src State get |
| 02:42:54 | <lambdabot> | Source not found. This mission is too important for me to allow you to jeopardize it. |
| 02:43:01 | <ToxicFrog> | And returns a tuple containing the return value, followed by the state? |
| 02:43:02 | <shachaf> | ToxicFrog: Now try to reimplement State. |
| 02:43:06 | <omnId> | get = State (\s -> (s, s)) |
| 02:43:17 | <omnId> | put x = State (\s -> ((), x)) |
| 02:43:19 | <mauke> | > runState (do modify (+1); modify (*2); modify (+1); return "Thursday") 42 |
| 02:43:21 | <lambdabot> | ("Thursday",87) |
| 02:43:21 | <shachaf> | newtype State s a = State (s -> (a,s)); runstate (State x) = x -- Start with that. |
| 02:43:22 | <omnId> | @type get |
| 02:43:24 | <omnId> | @type put |
| 02:43:24 | <lambdabot> | forall (m :: * -> *) s. (MonadState s m) => m s |
| 02:43:26 | <lambdabot> | forall s (m :: * -> *). (MonadState s m) => s -> m () |
| 02:44:11 | <omnId> | runState (State f) x = f x -- if the eta reduced version is too hard to read. |
| 02:44:45 | <omnId> | the key is (>>=) which threads the state around rather smartly |
| 02:45:04 | <chessguy> | smartly? |
| 02:45:10 | <dons> | jerzy's got some interesting reminiscenes, re. Gofer: " At that time we knew that |
| 02:45:11 | <ToxicFrog> | ...but f only returns an r, whereas runState returns (r,s) |
| 02:45:13 | <dons> | Haskell was for the brave, not for people making money... Almost everybody |
| 02:45:15 | <dons> | was a newbie" |
| 02:45:31 | <omnId> | ToxicFrog: "f"? |
| 02:45:55 | <omnId> | @type State -- the State constructor requires that it's argument function returns a pair. |
| 02:45:57 | <lambdabot> | forall s a. (s -> (a, s)) -> State s a |
| 02:46:08 | <ToxicFrog> | runState (State f) x = f x -- I read that as "runState (State f) x is equivalent to applying the function the State is wrapped around to x" |
| 02:46:21 | <omnId> | yes |
| 02:46:23 | <ToxicFrog> | But in that case you'd only get one return, rather than the (return,state) tuple |
| 02:46:28 | <mauke> | ToxicFrog: no, f returns (r,s) |
| 02:46:30 | <omnId> | and f :: s -> (a, s) |
| 02:46:44 | <ToxicFrog> | But f says it returns r! |
| 02:46:53 | <ToxicFrog> | It returns (r,s) only implicitly! |
| 02:47:04 | <omnId> | if it's wrapped in the State constructor, it must have type s -> (a, s) |
| 02:47:20 | <mauke> | f :: State r where State x = s -> (x, s) |
| 02:47:57 | <ToxicFrog> | (do x <- get ; return (x + 1)) -- this looks like it returns x+1, not (x+1,x), even though the latter is what actually falls out when you run it |
| 02:47:59 | <omnId> | @type State -- look at the constructor's type again |
| 02:48:01 | <lambdabot> | forall s a. (s -> (a, s)) -> State s a |
| 02:48:33 | <omnId> | ToxicFrog: maybe you're confused about the "return" function? |
| 02:48:43 | <omnId> | return x = State (\s -> (x, s)) |
| 02:48:52 | <ToxicFrog> | ...oh. |
| 02:48:53 | <ToxicFrog> | Oops. |
| 02:48:56 | <ToxicFrog> | Ok, now it makes sense. |
| 02:49:31 | <omnId> | you think you're ready for (>>=) now? |
| 02:49:39 | <mauke> | > runState (do return 1; return 2; return "butter"; return "Thursday") 42 |
| 02:49:40 | <ToxicFrog> | Probably not! |
| 02:49:40 | <lambdabot> | ("Thursday",42) |
| 02:50:19 | <omnId> | action >>= k = State (\s -> let (result, new_s) = runState action s in runState (k result) new_s) |
| 02:50:28 | <omnId> | read through that slowly |
| 02:51:36 | <omnId> | it makes a new function that hooks together 'action' and 'k' and passes each value to the correct place. |
| 02:51:41 | <JohnnyL> | How can one write a compose function for a list of functions with varied arguments (in amount)? |
| 02:51:57 | <mauke> | @where oleg |
| 02:51:58 | <lambdabot> | http://okmij.org/ftp/ |
| 02:51:59 | <FMota> | yay, euler #3 finally down... :o |
| 02:52:15 | <dons> | JohnnyL: well, hmm. how would you use this thing? |
| 02:52:33 | <JohnnyL> | dons, combing mathematical functions. |
| 02:52:36 | <mauke> | http://okmij.org/ftp/Haskell/types.html#polyvar-comp |
| 02:52:37 | <lambdabot> | Title: Haskell Programming: Types |
| 02:52:53 | <dons> | and (.) doesn't work? |
| 02:53:00 | <dons> | with appropirate lambdas/ |
| 02:53:12 | <FMota> | > rev "abc" |
| 02:53:13 | <lambdabot> | Not in scope: `rev' |
| 02:53:18 | <JohnnyL> | i am new. it's a dynamtic list of functions. |
| 02:53:18 | <FMota> | > reverse "abc" |
| 02:53:19 | <lambdabot> | "cba" |
| 02:53:24 | <ToxicFrog> | augh, my brain |
| 02:53:47 | <sclv> | JohnnyL: maybe you could make up and operator that in imaginaryland did what you wanted, then write some pseudocode with the operator, so you could then show us what you wanted to do . |
| 02:53:58 | <omnId> | it hooks together: (action >>= \result_from_action -> new_action) |
| 02:54:56 | <JohnnyL> | sclv a list of sins and coses or printing sins and cos. |
| 02:55:09 | <omnId> | it gets the (result, new_s) pair by running action, then passes result to k to get a new_action. |
| 02:55:44 | <omnId> | new_s is passed to the new_action, and the whole thing results in new_action's return value. |
| 02:56:08 | <ToxicFrog> | So, hang on |
| 02:56:31 | <sclv> | JohnnyL so you want to have [Sin 12, Cos 22, Sin 17], for example, and then pass it to a function that either evals it or prints it? |
| 02:56:31 | <ToxicFrog> | Where does it get the old s from? |
| 02:56:41 | <ToxicFrog> | I mean, I see it's the argument to that lambda, but what's the lambda called with? |
| 02:56:45 | <omnId> | ToxicFrog: action >>= k = State (\s -> ...) |
| 02:56:50 | <omnId> | runState! |
| 02:56:55 | <ToxicFrog> | Ok. |
| 02:57:05 | <omnId> | (>>=) just hooks together actions into a bigger actions! |
| 02:57:17 | <omnId> | The whole thing is subsequently run with runState! |
| 02:57:21 | <ToxicFrog> | So if I did runState theAction theInitialState, then s in that scope is initialState? |
| 02:57:22 | <JohnnyL> | svlv, yeah but the list size is not definite. |
| 02:57:25 | <omnId> | excalmation point! |
| 02:57:30 | <ToxicFrog> | Er, theInitialState? |
| 02:57:34 | <omnId> | yes!!! |
| 02:57:59 | <omnId> | (though most actions are built up from raw lambdas and the State constructor) |
| 02:58:10 | <sclv> | JohnnyL, define, e.g., Data Expr = Sin Float | Cos Float and the rest follows... |
| 02:58:13 | <omnId> | (usually you use get, put, return, modify to do it for you) |
| 02:58:47 | <omnId> | s/are/aren't/ |
| 02:59:08 | <omnId> | most actions *aren't* built up from raw lambdas the the constructor |
| 02:59:19 | <omnId> | ACTION types types quickly |
| 02:59:25 | <ToxicFrog> | Ok. And then, having done that, it takes the new state and return value it got from (action s), and stuffs that through k as runState (k retval) newstate? |
| 02:59:37 | <omnId> | yep |
| 02:59:52 | <sclv> | JohnnyL: like, then you can have eval :: Expr -> Float where eval x = case x of Sin a -> sin a; Sin b -> sin b; and then you can just map eval over yr. list |
| 03:00:18 | <omnId> | (>>=), effectively, is fancy function composition in the State monads. |
| 03:00:23 | <ToxicFrog> | So in effect, action >>= k (is an action that?) runs action, updates state based on that, and feeds the result and new state to k, and returns the result of k and the new new state? |
| 03:00:36 | <omnId> | yes, yes, yes! |
| 03:00:44 | <dfranke_> | is there any way to match case-insensitive patterns in Alex? |
| 03:00:52 | <omnId> | :D |
| 03:01:11 | <Tela> | Although, this is done lazily, so that computation wont actually occur until you demand it with run/eval/execState |
| 03:01:19 | <ToxicFrog> | Alright. And get and put are actions that manipulate the state, which is how the given implementation of more works? |
| 03:01:44 | <ToxicFrog> | Ie, it gets the state, yanks a bunch of stuff off the front, puts what's left back into the state, and returns the stuff it pulled off? |
| 03:01:48 | <sclv> | anyway, my silly question for the community is this: is there a standard function like succ but that "wraps around" on bounded values? |
| 03:02:08 | <omnId> | ToxicFrog: I can't stop saying yes! |
| 03:02:45 | <omnId> | (incidentally, more can also be written: more n = State (splitAt n), can you see why?) |
| 03:02:59 | <monochrom> | I can say no. Unfortunately that's for sclv's question. :) |
| 03:03:08 | <ToxicFrog> | ACTION examines that |
| 03:03:54 | <omnId> | State (\s -> let (result, new_s) = splitAt n s in (result, new_s)) -- maybe with more explicitness :) |
| 03:04:28 | <omnId> | splitAt just happens to return the correct type of pair :) |
| 03:04:59 | <ToxicFrog> | Aaah. So there's no magic going on there, it's a fortuitious interaction of signatures. |
| 03:05:10 | <omnId> | nicely said! |
| 03:05:31 | <ToxicFrog> | So the partial application of splitAt is turned into an action, which is given the state, and returns two lists that happen to be the correct values for the return value and the new state. |
| 03:06:02 | <chessguy> | ACTION hasn't been paying attention. what does splitAt have to do with State? |
| 03:06:04 | <omnId> | @vixen will you say "Yes" for me? My "yes" box is getting worn out. |
| 03:06:05 | <lambdabot> | i'll hafta plead the fifth on that one. |
| 03:06:17 | <omnId> | :) |
| 03:06:48 | <Tac-Tics> | :t splitAt 5 |
| 03:06:51 | <lambdabot> | forall a. [a] -> ([a], [a]) |
| 03:06:56 | <Tac-Tics> | :t State |
| 03:06:58 | <lambdabot> | forall s a. (s -> (a, s)) -> State s a |
| 03:07:18 | <Tac-Tics> | splitAt sounds very lending to State |
| 03:07:29 | <omnId> | as do many of the random functions |
| 03:07:31 | <omnId> | @type random |
| 03:07:33 | <lambdabot> | forall g a. (Random a, RandomGen g) => g -> (a, g) |
| 03:07:39 | <Tac-Tics> | :t \n -> State (splitAt n) |
| 03:07:41 | <lambdabot> | forall a. Int -> State [a] [a] |
| 03:07:41 | <chessguy> | well, assuming the state is a list, sure |
| 03:07:59 | <Tac-Tics> | a list is a nice kind of state |
| 03:08:19 | <Tac-Tics> | it allows you to pretend you're working with many states at once |
| 03:09:03 | <omnId> | ToxicFrog: so you see, in the end, the list is passed around everywhere, but you don't have to much about with it yourself. |
| 03:09:16 | <omnId> | muck* |
| 03:09:25 | <ToxicFrog> | Right. |
| 03:10:26 | <omnId> | also incidentally, the real definition of runState is as a record selector on the State type: newtype State s a = State { runState :: s -> (a, s) } |
| 03:10:43 | <omnId> | if you don't know much about record selectors, you can happily ignore this :) |
| 03:11:02 | <FMota> | > [1,2,3,4] !! 3 |
| 03:11:02 | <shachaf> | You people are still going on about State? |
| 03:11:03 | <lambdabot> | 4 |
| 03:11:34 | <omnId> | shachaf: there's learning happening! |
| 03:11:48 | <shachaf> | Learning is good. |
| 03:12:47 | <omnId> | ToxicFrog: things still falling in place? Anything you're fuzzy on? |
| 03:13:13 | <omnId> | You know the translation of do notation into (>>=), yes? |
| 03:13:46 | <FMota> | ACTION 's computer is taking ages to compute the 10001st prime number. |
| 03:13:54 | <dons> | i love these epic weekend learners. |
| 03:14:01 | <shachaf> | FMota: s/computer/algorithm/ ? |
| 03:14:10 | <dons> | ToxicFrog: its great you've stuck with it. you must be in a completely different place to earlier in the day? |
| 03:14:12 | <FMota> | eh |
| 03:14:19 | <FMota> | I'm using a sieve, as per usual |
| 03:14:28 | <FMota> | although I could optimize it. |
| 03:14:30 | <ToxicFrog> | dons: no, not as such. I know much more about State and >>= than I did, though. |
| 03:14:34 | <FMota> | s/could/should |
| 03:14:35 | <mauke> | FMota: dude, just use sockets and download the list |
| 03:14:40 | <mauke> | faster than computing it yourself |
| 03:14:44 | <FMota> | lol. |
| 03:14:58 | <FMota> | that's cheating :/ |
| 03:15:09 | <mauke> | OPTIMIZED |
| 03:15:22 | <sorear> | FMota: my system can do it in 0.01s |
| 03:15:53 | <sorear> | although it segfaults in the process |
| 03:16:02 | <FMota> | ACTION is jealous :o |
| 03:16:40 | <ToxicFrog> | omnId: I don't, and I'm trying to look it up, but the index has defeated me |
| 03:16:52 | <stoic_> | heh, that's a projecteuler problem |
| 03:17:17 | <FMota> | yep |
| 03:17:27 | <mauke> | what's the problem id? |
| 03:17:30 | <ToxicFrog> | I'd guess, though, that it's something like a >>= b = do tmp <- a; b tmp; |
| 03:17:36 | <omnId> | do { pat <- expr ; ... } = expr >>= \pat -> do { ... } |
| 03:17:37 | <FMota> | promple # 7 |
| 03:17:39 | <ToxicFrog> | Add more tmps as necessary. |
| 03:17:48 | <ToxicFrog> | Aah. |
| 03:18:04 | <ToxicFrog> | That's rather more elegant. |
| 03:18:08 | <omnId> | do { let decls ; ... } = let decls in do { ... } |
| 03:18:32 | <mauke> | FMota: my solution takes 10 seconds |
| 03:18:39 | <omnId> | do { stmt ; ... } = stmt >> do { ... }, which is equivalent to stmt >>= \_ -> do { ... } |
| 03:18:50 | <omnId> | do { stmt } = stmt |
| 03:19:06 | <stoic_> | haha, one of the J solutions to problem 7 in the forums is great: p: 10000 ...0.000953769 seconds |
| 03:19:07 | <FMota> | yay! |
| 03:19:11 | <Cale> | "reddit is currently in read only mode due to a database upgrade. we should be back in a few weeks." |
| 03:19:12 | <FMota> | I got it. Really fast. |
| 03:19:15 | <FMota> | ... and it makes no sense~ |
| 03:19:32 | <omnId> | Cale: *jawdrop*! *WEEKS?* |
| 03:19:39 | <FMota> | 10002 is not a prime number! :/ |
| 03:19:39 | <Cale> | I'm kidding :) |
| 03:19:49 | <omnId> | you bastard! |
| 03:19:51 | <Cale> | It's just that it's been a little more than a "few" hours now |
| 03:20:10 | <FMota> | yes Cale, thati s infuritain |
| 03:20:14 | <FMota> | *infuriating |
| 03:20:22 | <FMota> | which is why I'm doing project euler. :/ |
| 03:20:23 | <mauke> | primes = 2 : sieve [3, 5 ..]; sieve (p : ns) = p : sieve (filter ((0 /=) . (`mod` p)) ns) |
| 03:20:29 | <FMota> | and failing miserably, I might add. |
| 03:21:39 | <stoic_> | > (nubBy(((>1).).gcd)[2..]) !! 10001 |
| 03:21:53 | <lambdabot> | Terminated |
| 03:22:42 | <ddarius> | Take this a a good chance to leave reddit behind. |
| 03:23:30 | <FMota> | mauke: I hate and love you. :) |
| 03:23:52 | <mauke> | what |
| 03:24:06 | <idnar> | primes = 2 : filter isPrime [3, 5..] where isPrime n = all (not . (`divides` n)) (takeWhile (\p -> p * p <= n) primes) |
| 03:24:34 | <mauke> | pfft, you kids and your fancy algorithms |
| 03:25:11 | <idnar> | mauke: my initial implementation was something like yours, but it took too long to find all the primes below 1 million :P |
| 03:25:38 | <idnar> | I'm not sure if a Sieve of Eratosthenes or Atkins is faster than that, though |
| 03:25:59 | <mauke> | is that problem 10? |
| 03:26:02 | <Tela> | The type system is Haskell's parentheses. Hate, then hate, then hate, then divinity. |
| 03:26:23 | <Tac-Tics> | @let divisors n = [x | x <- [1..n], n `mod` x == 0] |
| 03:26:23 | <FMota> | heh, @remember-bait |
| 03:26:28 | <lambdabot> | Defined. |
| 03:26:35 | <mauke> | main = print $ sum $ takeWhile (< 1000000) primes |
| 03:26:39 | <Tac-Tics> | @let prime n = length (divisors n) == 2 |
| 03:26:40 | <lambdabot> | <local>:19:0: Multiple declarations of `L.prime' Declared at: <local>... |
| 03:26:48 | <newsham> | tela: then agda? |
| 03:26:49 | <mauke> | > prime 42 |
| 03:26:51 | <lambdabot> | False |
| 03:26:52 | <Tela> | Not denying it. I like the parallel though. Reminds me way too much of macros |
| 03:27:04 | <ToxicFrog> | 'agda'? |
| 03:27:09 | <idnar> | mauke: yeah |
| 03:27:14 | <shachaf> | @where agda |
| 03:27:14 | <lambdabot> | http://www.cs.chalmers.se/~catarina/agda/ |
| 03:27:15 | <newsham> | agda has a more powerful type system than haskell |
| 03:27:15 | <Tac-Tics> | > filter prime [1..101] |
| 03:27:17 | <lambdabot> | [1,2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101] |
| 03:27:28 | <mauke> | > (filter prime [2 ..]) !! 1000 |
| 03:27:30 | <lambdabot> | 7927 |
| 03:27:30 | <ToxicFrog> | Aah. |
| 03:27:33 | <mauke> | > (filter prime [2 ..]) !! 10000 |
| 03:27:35 | <lambdabot> | 104743 |
| 03:27:41 | <shachaf> | > prime 1 -- ! |
| 03:27:43 | <lambdabot> | True |
| 03:27:45 | <mauke> | wow, this is fast |
| 03:27:49 | <ToxicFrog> | Ok. So I now know how to implicitly pass state along. Now I need to pass it down. |
| 03:28:00 | <shachaf> | ToxicFrog: "down"? |
| 03:28:09 | <shachaf> | ToxicFrog: Did you reimplement State yet, by the way? |
| 03:28:20 | <newsham> | I think http://unit.aist.go.jp/cvs/Agda/ is a newer url than the chalmers one |
| 03:28:21 | <lambdabot> | Title: Agda Official Web Site |
| 03:28:25 | <idnar> | @src prime |
| 03:28:25 | <lambdabot> | Source not found. Are you on drugs? |
| 03:28:44 | <shachaf> | < Tac-Tics> @let prime n = length (divisors n) == 2 |
| 03:28:48 | <ToxicFrog> | shachaf: no, I haven't. And by down, I mean I have an action that doesn't directly use the state, but is defined in terms of something else that does. |
| 03:28:59 | <idnar> | shachaf: but < lambdabot> <local>:19:0: Multiple declarations of `L.prime' Declared at: <local>... |
| 03:29:00 | <shachaf> | ToxicFrog: runState? |
| 03:29:03 | <idnar> | shachaf: I thought that meant the @let failed |
| 03:29:08 | <ToxicFrog> | Or rather, is defined in terms of something else which is defined in terms of something else which does. |
| 03:29:13 | <stoic_> | > 2 : (filter prime [3,5..]) !! 20000 |
| 03:29:14 | <lambdabot> | Couldn't match expected type `[t]' against inferred type `Integer' |
| 03:29:18 | <shachaf> | Oh. |
| 03:29:20 | <shachaf> | Hmm. |
| 03:29:34 | <mauke> | > (2 : filter prime [3,5..]) !! 20000 |
| 03:29:36 | <lambdabot> | 224743 |
| 03:30:14 | <idnar> | > sum $ takeWhile (<1000000) (2: filter prime [3, 5...]) |
| 03:30:14 | <lambdabot> | Parse error |
| 03:30:25 | <idnar> | > sum $ takeWhile (<1000000) (2 : filter prime [3, 5...]) |
| 03:30:25 | <lambdabot> | Parse error |
| 03:30:41 | <stoic_> | extra dot? |
| 03:30:46 | <idnar> | oh, oops |
| 03:30:47 | <idnar> | > sum $ takeWhile (<1000000) (2 : filter prime [3, 5..]) |
| 03:30:52 | <lambdabot> | Terminated |
| 03:30:54 | <idnar> | heh |
| 03:31:20 | <mauke> | @let primes = 2 : filter prime [3, 5 ..] |
| 03:31:20 | <lambdabot> | <local>:19:0: Multiple declarations of `L.primes' Declared at: <local... |
| 03:31:32 | <ToxicFrog> | shachaf: that is to say, main calls a lambda action (is that the right term? it's a (do ...) block passed directly to runState), which calls mutate, which calls pmap, which calls more, which uses the state. |
| 03:31:33 | <mauke> | > takeWhile (<1000000) primes |
| 03:31:35 | <lambdabot> | [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,... |
| 03:32:27 | <shachaf> | ToxicFrog: It's a bit like IO. |
| 03:32:29 | <idnar> | > length $ takeWhile (<1000000) primes |
| 03:32:33 | <lambdabot> | Terminated |
| 03:32:33 | <shachaf> | ToxicFrog: Except you can run it. |
| 03:32:46 | <shachaf> | ToxicFrog: If something uses the state, it has to be in State. |
| 03:32:59 | <stoic_> | > last primes |
| 03:33:00 | <Tac-Tics> | @let foo n = head $ let primes = filter prime [2..] in do x <- primes; y <- primes; guard (x + y == n) |
| 03:33:03 | <shachaf> | ToxicFrog: Or have an initial state to runState with (which is equivalent). |
| 03:33:09 | <lambdabot> | Defined. |
| 03:33:10 | <lambdabot> | Terminated |
| 03:33:19 | <Tac-Tics> | @let foo2 n = head $ let primes = filter prime [2..] in do x <- primes; y <- primes; guard (x + y == n); return [x, y] |
| 03:33:24 | <omnId> | @. elite run last [1..] |
| 03:33:25 | <lambdabot> | Defined. |
| 03:33:29 | <lambdabot> | tER/\/\iNA73d |
| 03:33:30 | <Tac-Tics> | > foo2 12 |
| 03:33:34 | <lambdabot> | Terminated |
| 03:33:54 | <Tac-Tics> | sadness |
| 03:34:02 | <Tac-Tics> | > foo2 4 |
| 03:34:04 | <lambdabot> | [2,2] |
| 03:34:23 | <mauke> | > foo2 6 |
| 03:34:27 | <ToxicFrog> | shachaf: I do have an initial state. |
| 03:34:27 | <lambdabot> | Terminated |
| 03:34:32 | <mauke> | huhu |
| 03:34:35 | <Tac-Tics> | so much for the naive approach |
| 03:34:45 | <sclv> | it never stops taking from the first primes to take from the 2nd |
| 03:34:57 | <shachaf> | ToxicFrog: So what's the point? |
| 03:35:05 | <Tac-Tics> | yeah |
| 03:35:08 | <ToxicFrog> | main = do { rs <- (...generate initial state...); evalState (do mutate ...); |
| 03:35:13 | <Tac-Tics> | it's looking for 2 + p = 6 |
| 03:35:15 | <Tac-Tics> | and there is none |
| 03:35:16 | <ToxicFrog> | Er. |
| 03:35:21 | <ToxicFrog> | evalState (do mutate ...) rs |
| 03:35:23 | <shachaf> | ToxicFrog: You have a state, you call a function that isn't in State, and then you call a function that is in state from that? |
| 03:35:35 | <shachaf> | ToxicFrog: You might as well keep everything in State. |
| 03:35:45 | <ToxicFrog> | That's what I'm trying to do. |
| 03:35:47 | <idnar> | @let foo3 n = head $ let primes = filter prime [2..] in do x <- takeWhile (<n) primes; y <- takeWhile (<n) primes; guard (x + y == n); return [x, y] |
| 03:35:54 | <lambdabot> | Defined. |
| 03:35:59 | <shachaf> | ToxicFrog: Can you @paste, maybe? |
| 03:36:05 | <mauke> | > foo3 6 |
| 03:36:07 | <sclv> | I wrote a way to take a useful cartesian product of infinite lists once. then i realized that cartesian products were overkill. hmm.. i might have the code somewhere |
| 03:36:07 | <lambdabot> | [3,3] |
| 03:36:07 | <idnar> | > foo3 6 |
| 03:36:08 | <lambdabot> | [3,3] |
| 03:36:14 | <idnar> | > foo3 27 |
| 03:36:15 | <lambdabot> | Exception: Prelude.head: empty list |
| 03:36:20 | <Tac-Tics> | @let bar n = head $ let primes = filter prime [2..] in do x <- primes; guard (x <= n); y <- primes; guard (x + y == n); return [x, y] |
| 03:36:28 | <lambdabot> | Defined. |
| 03:36:28 | <Tac-Tics> | > bar 6 |
| 03:36:32 | <lambdabot> | Terminated |
| 03:36:33 | <idnar> | > foo3 20 |
| 03:36:34 | <lambdabot> | [3,17] |
| 03:36:52 | <sclv> | or yep, that'll do. |
| 03:37:18 | <mauke> | > foo3 100 |
| 03:37:18 | <idnar> | the guard isn't enough |
| 03:37:20 | <lambdabot> | [3,97] |
| 03:37:24 | <mauke> | Tac-Tics: guard is filter, not takeWhile |
| 03:37:39 | <idnar> | what he said ;) |
| 03:37:48 | <ToxicFrog> | Hmm. That worked. |
| 03:37:51 | <ToxicFrog> | mutate li = State (\n -> runState (do pmap 0.5 (+1) li) n) |
| 03:38:10 | <mauke> | State/runState? o_O |
| 03:38:21 | <idnar> | if anyone cares, my Project Euler solutions are at http://slipgate.za.net/~mithrandi/darcs/projecteuler/ |
| 03:38:23 | <lambdabot> | Title: Index of /~mithrandi/darcs/projecteuler |
| 03:38:25 | <Tac-Tics> | > foo3 23456 |
| 03:38:27 | <lambdabot> | [163,23293] |
| 03:38:29 | <mauke> | mutate li = pmap 0.5 (+1) li |
| 03:38:31 | <shachaf> | ToxicFrog: You shouldn't use State yourself. |
| 03:38:44 | <stoic_> | Tac-Tics: are you trying to do prime factors? |
| 03:38:47 | <idnar> | (in most cases I just tried to solve it as quickly as possible, rather than striving for elegant / optimal solutions) |
| 03:38:49 | <Tac-Tics> | no |
| 03:38:54 | <idnar> | (and, obviously, don't look there if you don't want any spoilers :P) |
| 03:39:03 | <Tac-Tics> | It's the goldbach conjecture, I think, right? |
| 03:39:04 | <sclv> | > let bar2 n = head $ let primes = filter prime [2..] in do x <- primes; y <- takeWhile (<x) primes; guard (x + y == n); return [x, y] in bar2 23456 |
| 03:39:06 | <lambdabot> | [11779,11677] |
| 03:39:08 | <omnId> | mutate xs = pmap 0.5 (+1) xs |
| 03:39:25 | <ToxicFrog> | omnId: that works too. |
| 03:39:29 | <ToxicFrog> | However...oh, wait, I think I see |
| 03:39:47 | <omnId> | pmap results in your action, mutate just gives defaults to pmap |
| 03:39:58 | <ToxicFrog> | mutate li = if (head li) == 1 then return li else pmap 0.5 (+1) li |
| 03:40:17 | <omnId> | if the first == 1 then don't pmap? |
| 03:40:20 | <stoic_> | idnar: have you done problem 160? |
| 03:40:21 | <idnar> | Tac-Tics: for even n, yes |
| 03:40:22 | <ToxicFrog> | Yep. |
| 03:40:31 | <omnId> | that should work fine |
| 03:40:36 | <idnar> | stoic_: I've only done 1 through 20 |
| 03:40:44 | <kaol> | why does "return Nothing >>= return >> return $ Just ()" fail but "return Nothing >>= return >> return (Just ())" doesn't? |
| 03:40:44 | <ToxicFrog> | Not what the final logic looks like (which calls a seperate function to determine whether to pmap or not) but that's the idea. |
| 03:40:45 | <stoic_> | oh :-( |
| 03:40:50 | <luqui> | I installed ghc from a binary tarball; how do I get the runhaskell program? |
| 03:41:02 | <dons> | should be in your path |
| 03:41:02 | <ToxicFrog> | The problem I kept running into earlier was that 'mutate li = if (head li) == 1 then li else pmap 0.5 (+1) li' wouldn't work. |
| 03:41:08 | <omnId> | since the else clause results in an action, the then clause must too, (via return) |
| 03:41:13 | <sclv> | > let primes = filter prime [2..]; bar2 n= head $ do{ x <- primes; y <- takeWhile (<x) primes; guard (x + y == n); return [x, y]} in bar2 23456 |
| 03:41:13 | <mauke> | :t (>>= return) |
| 03:41:13 | <lambdabot> | [11779,11677] |
| 03:41:13 | <lambdabot> | forall (m :: * -> *) a. (Monad m) => m a -> m a |
| 03:41:20 | <ToxicFrog> | Because I didn't fully realize that 'pmap 0.5 (+1) li' returns an action, but |
| 03:41:23 | <ToxicFrog> | 'li' returns a list. |
| 03:41:34 | <luqui> | kaol, operator precedence |
| 03:41:38 | <dons> | now you're learning to think in types, ToxicFrog :) |
| 03:41:41 | <dons> | be careful: its addicative |
| 03:41:41 | <omnId> | li is a list, but return li is a list in the State [Double] Monad. |
| 03:41:43 | <kaol> | thought it would be something like that |
| 03:41:47 | <shachaf> | ToxicFrog: Do keep in mind that that won't work for the empty list. |
| 03:41:50 | <luqui> | kaol, (return Nothing >>= return >> return) (Just ()) should work fine |
| 03:41:51 | <dons> | you'll be inferring types for everything soon enough |
| 03:41:54 | <ToxicFrog> | shachaf: yes, I know. |
| 03:42:01 | <ToxicFrog> | I'm still putting stuff together. |
| 03:42:17 | <luqui> | kaol, actually... uh, no it shouldn't |
| 03:42:20 | <Tac-Tics> | dons: it's like you don't even need documentation on a function any more... you just see the type and assume you know what it should do |
| 03:42:21 | <omnId> | it takes time, you'll get there :) |
| 03:42:22 | <luqui> | but that's what it means at least |
| 03:42:36 | <ToxicFrog> | dons: well, the issue was that I expected both of them to return lists. |
| 03:42:42 | <FMota> | yay. |
| 03:42:52 | <omnId> | Tac-Tics: /me did exactly that when I futzed around with template haskell :) |
| 03:42:52 | <shachaf> | ToxicFrog: Somebody else had the solution "mutate li@(1:xs) = ...; mutate li = li" or so. |
| 03:42:54 | <FMota> | I used pfactors and it got me the answer in ~10 seconds |
| 03:43:04 | <omnId> | Tac-Tics: which was good since I couldn't find any good docs :D |
| 03:43:09 | <Tac-Tics> | yeah |
| 03:43:10 | <dons> | Tac-Tics: exactly. given purity and an expressive type , the type does in fact tell you everything |
| 03:43:14 | <dons> | ?djinn a -> a |
| 03:43:14 | <lambdabot> | f a = a |
| 03:43:18 | <kaol> | > return Nothing >>= return >> return (Just ()) |
| 03:43:19 | <lambdabot> | add an instance declaration for (Show (m (Maybe ()))) |
| 03:43:27 | <Tac-Tics> | type(f) = type(g) => f = g |
| 03:43:29 | <dons> | only one non-trivial function with that type: the type really is a good, machine checked spec |
| 03:43:29 | <shachaf> | @ty take |
| 03:43:31 | <lambdabot> | forall a. Int -> [a] -> [a] |
| 03:43:32 | <shachaf> | @ty drop |
| 03:43:34 | <lambdabot> | forall a. Int -> [a] -> [a] |
| 03:43:51 | <ToxicFrog> | shachaf: which is cool, but since the final logic will be something like 'if completed li then return get-best li else mutate (pmap 0.5 breed li)' |
| 03:43:54 | <kaol> | > return Nothing >>= return >> return (Just "") |
| 03:43:55 | <lambdabot> | add an instance declaration for (Show (m (Maybe [Char]))) |
| 03:44:22 | <omnId> | ToxicFrog: and get-best doesn't rely on any incoming stream of randoms or anything? |
| 03:44:27 | <ToxicFrog> | Nope. |
| 03:44:34 | <luqui> | > return Nothing >>= return >>= return (Just "") -- is this what you meant? |
| 03:44:36 | <lambdabot> | Just "" |
| 03:44:37 | <chessguy> | ToxicFrog, you're searching for a fitness of 1? |
| 03:44:45 | <ToxicFrog> | chessguy: in effect. |
| 03:44:48 | <shachaf> | Hmm... @djinn is implementation inference. :-) |
| 03:45:01 | <ToxicFrog> | While I can't guarantee that's the range fitness is in, get-best just returns the element of the list with the highest fitness value. |
| 03:45:09 | <luqui> | > Nothing >>= return >>= Just "" -- or maybe this? |
| 03:45:10 | <lambdabot> | Couldn't match expected type `a -> Maybe b' |
| 03:45:12 | <ToxicFrog> | The fitness function itself is, of course, pure. |
| 03:45:12 | <luqui> | oops |
| 03:45:16 | <luqui> | > Nothing >>= return >> Just "" -- or maybe this? |
| 03:45:16 | <FMota> | pfactors = pf 2; pf x 1 = []; pf x n | x * x > n = [n]; pf x n | mod n x == 0 = x : pf x (div n x); pf x n = pf (succ x) n |
| 03:45:17 | <lambdabot> | Nothing |
| 03:45:24 | <omnId> | > return Nothing >>= return (Just "") |
| 03:45:26 | <lambdabot> | Just "" |
| 03:45:44 | <omnId> | (>>= return) = id |
| 03:45:55 | <ToxicFrog> | And completed li = fitness (get-best li) >= fitness-requirement |
| 03:46:04 | <FMota> | > let pfactors = pf 2; pf x 1 = []; pf x n | x * x > n = [n]; pf x n | mod n x == 0 = x : pf x (div n x); pf x n = pf (succ x) n in pfactors 1001 |
| 03:46:05 | <lambdabot> | [7,11,13] |
| 03:46:10 | <kaol> | the example was a bit trivial, but that was the basic scenario I had |
| 03:46:16 | <FMota> | > product [7, 11, 13] |
| 03:46:17 | <lambdabot> | 1001 |
| 03:46:20 | <FMota> | :) |
| 03:46:23 | <stoic_> | FMota: does projecteuler work? I'm getting a mysql error :( |
| 03:46:29 | <FMota> | heh |
| 03:46:35 | <FMota> | I must've broke it! :o |
| 03:46:48 | <ToxicFrog> | And now that I actually have some form of handle on this, I'm going to have dinner. |
| 03:46:48 | <FMota> | Maybe I divided by zero? |
| 03:46:50 | <ToxicFrog> | At midnight. |
| 03:46:53 | <ToxicFrog> | Thank you, all. |
| 03:47:02 | <omnId> | hehe, you're most welcome |
| 03:47:18 | <Tac-Tics> | ah |
| 03:47:20 | <Tac-Tics> | I found it |
| 03:47:25 | <Tac-Tics> | nub (mersennes >>= primeDivisors) == tail primes? |
| 03:47:50 | <Tac-Tics> | that's a neat question I came up with last year in my shitty math research class |
| 03:48:12 | <omnId> | Tac-Tics: maybe a sort there too? |
| 03:48:32 | <Tac-Tics> | it's hard to sort that kind of list |
| 03:48:37 | <omnId> | ACTION doesn't know what a mersenne prime is |
| 03:48:50 | <Tac-Tics> | mersenne n = 2 ^ (n+2) - 1 |
| 03:48:50 | <Tac-Tics> | mersennes = map mersenne [1..] |
| 03:48:50 | <omnId> | (>>=) is in []? |
| 03:48:51 | <shachaf> | omnId: 2^n-1 |
| 03:48:57 | <Tac-Tics> | they are not necessarily mersenne primes |
| 03:49:00 | <jql> | they're the cool primes |
| 03:49:02 | <Tac-Tics> | they are just mersenne numbers |
| 03:49:14 | <Tac-Tics> | in my question, that is |
| 03:49:21 | <omnId> | oh, duh, or they wouldn't have many primeDivisors :) |
| 03:50:48 | <Tac-Tics> | they'd have themselves as divisors |
| 03:53:13 | <Tac-Tics> | I can get about 23 primes and then sadness |
| 03:55:56 | <FMota> | :[] is still my favorite haskell expression :) |
| 03:56:41 | <mauke> | @quote fmap |
| 03:56:41 | <lambdabot> | mauke says: fmap fix return is the e^(i*pi)+1 of haskell |
| 03:56:46 | <FMota> | > product . map read . map (:[]) . take 5 $ "1234567" |
| 03:56:57 | <lambdabot> | 120 |
| 03:57:00 | <FMota> | lol |
| 03:57:04 | <FMota> | that took awhile. |
| 03:57:10 | <newsham> | ?type fmap fix return |
| 03:57:12 | <lambdabot> | forall a. a -> a |
| 03:57:16 | <omnId> | = id |
| 03:57:30 | <omnId> | fmap = (.), return = const |
| 03:57:32 | <mauke> | > product `liftM` liftM read `liftM` liftM return `liftM` take 5 $ "1234567" |
| 03:57:34 | <lambdabot> | 120 |
| 03:57:44 | <omnId> | fix . const = \x -> fix (const x) = \x -> x |
| 03:58:11 | <FMota> | mauke... maybe you should be in jail? |
| 03:58:15 | <FMota> | :o ;p |
| 03:58:33 | <FMota> | @index ap |
| 03:58:33 | <lambdabot> | Control.Monad, Control.Monad.Reader, Control.Monad.Writer, Control.Monad.State, Control.Monad.RWS, Control.Monad.Identity, Control.Monad.Cont, Control.Monad.Error, Control.Monad.List, Data.Graph. |
| 03:58:33 | <lambdabot> | Inductive.Query.ArtPoint, Data.Graph.Inductive.Query, Data.Graph.Inductive |
| 03:58:50 | <shachaf> | ap = liftM2 id |
| 03:58:53 | <shachaf> | @src ap |
| 03:58:53 | <lambdabot> | ap = liftM2 id |
| 03:59:02 | <ddarius> | @remember mauke product `liftM` liftM read `liftM` liftM return `liftM` take 5 $ "1234567" |
| 03:59:02 | <lambdabot> | Done. |
| 03:59:18 | <omnId> | yuck |
| 03:59:55 | <mauke> | > liftM product (liftM (liftM (liftM read return)) (take 5)) $ "1234567" |
| 03:59:57 | <lambdabot> | 120 |
| 04:00:17 | <mauke> | @unpl liftM product (liftM (liftM (liftM read return)) (take 5)) $ "1234567" |
| 04:00:17 | <lambdabot> | (liftM product (liftM (liftM (liftM read return)) (take 5)) "1234567") |
| 04:00:26 | <mauke> | hah |
| 04:00:27 | <omnId> | > let (.) = fmap in product . (read .) . (return .) . take 5 $ "1234567" |
| 04:00:28 | <lambdabot> | Occurs check: cannot construct the infinite type: |
| 04:00:28 | <lambdabot> | f = (->) (f Stri... |
| 04:00:38 | <shachaf> | > product `liftM` (read `liftM` return `liftM`) `liftM` take 5 $ "1234567" |
| 04:00:39 | <lambdabot> | 120 |
| 04:01:27 | <omnId> | > let (.) = fmap ; (.)::Functor f=>(a->b)->f a->f b in product . (read .) . (return .) . take 5 $ "1234567" -- mmr? |
| 04:01:29 | <lambdabot> | 120 |
| 04:03:06 | <shachaf> | > let (.) x = fmap x in product . (read .) . (return .) . take 5 $ "1234567" -- Simpler? |
| 04:03:07 | <lambdabot> | 120 |
| 04:03:40 | <shachaf> | > let (.) x = fmap x in product . (read . return .) . take 5 $ "1234567" |
| 04:03:42 | <lambdabot> | 120 |
| 04:04:36 | <shachaf> | @ty liftM(.)fmap |
| 04:04:37 | <lambdabot> | forall a a1 b (f :: * -> *). (Functor f) => (a1 -> b) -> (a -> f a1) -> a -> f b |
| 04:04:49 | <shachaf> | @ty (liftM(.)fmap<$>) |
| 04:04:51 | <lambdabot> | forall a a1 b (f :: * -> *) (f1 :: * -> *). (Functor f, Functor f1) => f1 (a1 -> b) -> f1 ((a -> f a1) -> a -> f b) |
| 04:04:59 | <omnId> | oh gawd |
| 04:05:00 | <shachaf> | @ty (liftM(.)fmap<$>map) |
| 04:05:02 | <lambdabot> | forall a (f :: * -> *) a1 b. (Functor f) => (a1 -> b) -> (a -> f [a1]) -> a -> f [b] |
| 04:05:08 | <omnId> | make it stop! |
| 04:05:16 | <omnId> | that's *five* names |
| 04:05:41 | <omnId> | @ty (liftA(liftM(.)fmap<$>map)) |
| 04:05:43 | <lambdabot> | forall a (f :: * -> *) a1 b (f1 :: * -> *). (Functor f, Applicative f1) => f1 (a1 -> b) -> f1 ((a -> f [a1]) -> a -> f [b]) |
| 04:06:31 | <mauke> | :t [fmap,liftA,liftM,(.)] |
| 04:06:33 | <lambdabot> | forall a b a1. [(a -> b) -> (a1 -> a) -> a1 -> b] |
| 04:06:59 | <omnId> | forgot (<$>) |
| 04:07:10 | <mauke> | :t [fmap,liftA,liftM,(.),(<$>)] |
| 04:07:12 | <lambdabot> | forall a b a1. [(a -> b) -> (a1 -> a) -> a1 -> b] |
| 04:07:27 | <omnId> | that's a lot of names for function compose. |
| 04:07:36 | <shachaf> | @ty liftA(liftM.fmap<$>map) |
| 04:07:38 | <lambdabot> | forall (m :: * -> *) (f :: * -> *) a b (f1 :: * -> *). (Monad m, Functor f, Applicative f1) => f1 (a -> b) -> f1 (m (f [a]) -> m (f [b])) |
| 04:07:51 | <omnId> | @src liftA |
| 04:07:51 | <lambdabot> | liftA f a = pure f <*> a |
| 04:08:04 | <omnId> | odd, you'd think liftA = fmap, since it does have the Functor context |
| 04:08:17 | <shachaf> | No. |
| 04:08:18 | <omnId> | @src liftA2 -- this, however, would need the <*> |
| 04:08:18 | <lambdabot> | Source not found. I've seen penguins that can type better than that. |
| 04:08:19 | <shachaf> | @ty liftA |
| 04:08:21 | <lambdabot> | forall a b (f :: * -> *). (Applicative f) => (a -> b) -> f a -> f b |
| 04:08:26 | <omnId> | liftA = fmap |
| 04:08:35 | <ddarius> | @src Applicative |
| 04:08:36 | <lambdabot> | class Functor f => Applicative f where |
| 04:08:36 | <lambdabot> | pure :: a -> f a |
| 04:08:36 | <lambdabot> | (<*>) :: f (a -> b) -> f a -> f b |
| 04:08:59 | <shachaf> | (<$>) is Applicative's rename of fmap. |
| 04:09:01 | <omnId> | @src liftA2 |
| 04:09:02 | <lambdabot> | liftA2 f a b = f <$> a <*> b |
| 04:09:08 | <omnId> | liftA as well |
| 04:09:46 | <shachaf> | omnId: Yes, but that has an Applicative constraint. |
| 04:09:57 | <omnId> | shachaf: which implies Functor |
| 04:10:00 | <shachaf> | Maybe it's there to test Applicative laws. |
| 04:10:31 | <omnId> | Oh, I see what you mean. |
| 04:10:51 | <omnId> | liftA is a more specific (<$>) |
| 04:10:57 | <shachaf> | Yes. |
| 04:11:37 | <newsham> | is there a good ref on the Applicative module? seems the paper doesnt use the same notation/defs as the module. |
| 04:11:52 | <omnId> | could still define it liftA = fmap, since it has the more specific type |
| 04:13:42 | <shachaf> | @ty second(liftA liftM.fmap<$>map) |
| 04:13:43 | <lambdabot> | forall a1 (m :: * -> *) a b d. (Monad m) => (d, a -> b) -> (d, (a1 -> [a]) -> m a1 -> m [b]) |
| 04:13:50 | <shachaf> | > fmap (+1) (2,3) |
| 04:13:55 | <lambdabot> | (2,4) |
| 04:13:56 | <shachaf> | > second (+1) (2,3) |
| 04:13:57 | <lambdabot> | (2,4) |
| 04:13:58 | <shachaf> | :-) |
| 04:14:02 | <omnId> | oh gawd |
| 04:14:14 | <omnId> | @slap shachaf |
| 04:14:14 | <lambdabot> | why on earth would I slap shachaf |
| 04:14:40 | <omnId> | (,) a Functor vs. (->) Arrow |
| 04:14:41 | <pastorn-rr> | @src randomR |
| 04:14:41 | <lambdabot> | Source not found. Sorry about this, I know it's a bit silly. |
| 04:14:47 | <pastorn-rr> | @src System.RandomrandomR |
| 04:14:48 | <lambdabot> | Source not found. My pet ferret can type better than you! |
| 04:14:53 | <pastorn-rr> | @src System.Random.randomR |
| 04:14:53 | <lambdabot> | Source not found. Are you on drugs? |
| 04:15:07 | <omnId> | @source System.Random |
| 04:15:07 | <lambdabot> | http://darcs.haskell.org/packages/base/System/Random.hs |
| 04:15:17 | <omnId> | 404! |
| 04:15:57 | <omnId> | http://darcs.haskell.org/packages/random/System/Random.hs |
| 04:15:58 | <Mr_Awesome> | i think someones trying to tell you to give up ;) |
| 04:16:16 | <pastorn-rr> | omnId: thanks :D |
| 04:16:25 | <Mr_Awesome> | bah, you found it |
| 04:16:35 | <omnId> | ACTION does not quit so easily |
| 04:16:55 | <omnId> | seems a random package was split from base |
| 04:16:57 | <Mr_Awesome> | you and your optimism |
| 04:17:23 | <omnId> | ACTION attacks Mr_Awesome with a refreshing beam of happy. |
| 04:17:43 | <Mr_Awesome> | ACTION curls into the fetal position |
| 04:17:49 | <omnId> | not to be confused with Happy |
| 04:18:16 | <shachaf> | @ty \f a -> a >>> arr f -- Hmm... |
| 04:18:18 | <lambdabot> | forall (a :: * -> * -> *) b c d. (Arrow a) => (c -> d) -> a b c -> a b d |
| 04:18:53 | <omnId> | @type WrappedArrow |
| 04:18:53 | <lambdabot> | Not in scope: data constructor `WrappedArrow' |
| 04:19:05 | <omnId> | @type WrapArrow |
| 04:19:06 | <lambdabot> | forall (a :: * -> * -> *) b c. a b c -> WrappedArrow a b c |
| 04:19:10 | <omnId> | that'll give you a monad |
| 04:19:21 | <Mr_Awesome> | @src (->) (>>>) |
| 04:19:21 | <lambdabot> | f >>> g = g . f |
| 04:19:26 | <Mr_Awesome> | @src (->) loop |
| 04:19:27 | <lambdabot> | Source not found. This mission is too important for me to allow you to jeopardize it. |
| 04:19:29 | <omnId> | @src WrappedArrow (>>=) |
| 04:19:29 | <lambdabot> | Source not found. My mind is going. I can feel it. |
| 04:19:34 | <Mr_Awesome> | why not?! |
| 04:19:46 | <Mr_Awesome> | ACTION quits |
| 04:19:49 | <shachaf> | Oh, right, (>>>). |
| 04:19:52 | <shachaf> | ACTION feels silly. |
| 04:20:05 | <shachaf> | @ty second(liftA liftM.fmap<$>map>>>) |
| 04:20:07 | <lambdabot> | forall a1 (m :: * -> *) a b d d1. (Monad m) => (d1, ((a1 -> [a]) -> m a1 -> m [b]) -> d) -> (d1, (a -> b) -> d) |
| 04:20:13 | <omnId> | ACTION cries |
| 04:20:28 | <omnId> | so many names! |
| 04:20:30 | <shachaf> | @ty second(liftA>>>liftM.fmap<$>map) |
| 04:20:32 | <lambdabot> | forall a b (f :: * -> *) (m :: * -> *) (f1 :: * -> *) d. (Applicative f, Monad m, Functor f1) => (d, a -> b) -> (d, m (f1 [f a]) -> m (f1 [f b])) |
| 04:21:14 | <omnId> | (.), map, and second all are different specifications of the others |
| 04:21:50 | <shachaf> | omnId: True enough. |
| 04:22:02 | <shachaf> | omnId: But you *could* set them all to fmap. |
| 04:22:43 | <shachaf> | @ty Data.Traversable.fmapDefault |
| 04:22:44 | <lambdabot> | forall a b (t :: * -> *). (Data.Traversable.Traversable t) => (a -> b) -> t a -> t b |
| 04:23:24 | <omnId> | *sigh* this should be a sport or something, find as many names for fmap as you can! |
| 04:24:15 | <nornagon> | > zip [1..] $ fix (fmap:) |
| 04:24:16 | <lambdabot> | Add a type signature |
| 04:24:26 | <shachaf> | @ty let fmapDefault = Data.Traversable.fmapDefault in second(fmapDefault(liftA>>>liftM).fmap<$>map) |
| 04:24:28 | <lambdabot> | forall a (f :: * -> *) (m :: * -> *) a1 b d. (Data.Traversable.Traversable ((->) (a -> [a1])), Applicative f, Monad m) => (d, a1 -> b) -> (d, (a -> [a1]) -> m (f a) -> m (f [b])) |
| 04:24:40 | <nornagon> | O_o |
| 04:25:14 | <omnId> | ACTION wonders what would happen if you provide the correct arguments. |
| 04:25:28 | <omnId> | The world would end abruptly |
| 04:26:31 | <shachaf> | @ty let fmapDefault = Data.Traversable.fmapDefault; amap = Data.Array.IArray.amap in second(fmapDefault(liftA>>>liftM).amap(fmap<$>map)) |
| 04:26:32 | <lambdabot> | forall (a :: * -> * -> *) i (f :: * -> *) (m :: * -> *) (f1 :: * -> *) a1 b d. (Ix i, Data.Array.Base.IArray a (f1 [a1] -> f1 [b]), Data.Array.Base.IArray a (a1 -> b), Data.Traversable.Traversable ( |
| 04:26:33 | <lambdabot> | a i), Applicative f, Monad m, Functor f1) => (d, a i (a1 -> b)) -> (d, a i (m (f (f1 [a1])) -> m (f (f1 [b])))) |
| 04:26:35 | <omnId> | > (let fmapDefault = Data.Traversable.fmapDefault in second(fmapDefault(liftA>>>liftM).fmap<$>map)) ((), id) ((), (:[])) [[()]] [[[()]]] |
| 04:26:36 | <lambdabot> | Couldn't match expected type `t1 -> t2 -> t3 -> t' |
| 04:27:12 | <omnId> | did the type get truncated? |
| 04:27:20 | <shachaf> | No. |
| 04:27:26 | <shachaf> | I don't think so, it got split. |
| 04:27:32 | <FMota> | problem #10 :/ |
| 04:28:01 | <omnId> | erm, I guess I gave the wrong type |
| 04:28:29 | <omnId> | > (let fmapDefault = Data.Traversable.fmapDefault in second(fmapDefault(liftA>>>liftM).fmap<$>map)) ((), id) ((), (\_ _ -> [[()]])) |
| 04:28:30 | <lambdabot> | Couldn't match expected type `t1 -> t' |
| 04:28:35 | <omnId> | closer :) |
| 04:29:12 | <omnId> | ACTION attempts to end the world |
| 04:29:27 | <FMota> | hey, how do you force strict evaluation? |
| 04:29:56 | <shachaf> | @ty let fmapDefault = Data.Traversable.fmapDefault; amap = Data.Array.IArray.amap; mapP = GHC.PArr.mapP in second`fmap`(fmapDefault(liftA>>>liftM).amap(mapP<$>map)) |
| 04:29:59 | <lambdabot> | forall (a :: * -> * -> *) i d (f :: * -> *) (m :: * -> *) a1 b. (Ix i, Data.Array.Base.IArray a ([:[a1]:] -> [:[b]:]), Data.Array.Base.IArray a (a1 -> b), Data.Traversable.Traversable (a i), Arrow a, |
| 04:29:59 | <lambdabot> | Applicative f, Monad m) => a i (a1 -> b) -> a (d, i) (d, m (f [:[a1]:]) -> m (f [:[b]:])) |
| 04:30:06 | <ddarius> | omnId: Probably too late for you now, but this may help http://qntm.org/destroy |
| 04:30:24 | <FMota> | how do you force strict evaluation? :/ |
| 04:30:54 | <omnId> | ddarius: "How to destroy the Earth"? I've read it, good read :) |
| 04:31:28 | <shachaf> | @ty let fmapDefault = Data.Traversable.fmapDefault; amap = Data.Array.IArray.amap; mapP = GHC.PArr.mapP in second`fmap`(fmapDefault(liftA>>>liftM).amap(mapP<$>map)) -- Any ideas from here on? |
| 04:31:31 | <lambdabot> | forall (a :: * -> * -> *) i d (f :: * -> *) (m :: * -> *) a1 b. (Ix i, Data.Array.Base.IArray a ([:[a1]:] -> [:[b]:]), Data.Array.Base.IArray a (a1 -> b), Data.Traversable.Traversable (a i), Arrow a, |
| 04:31:31 | <lambdabot> | Applicative f, Monad m) => a i (a1 -> b) -> a (d, i) (d, m (f [:[a1]:]) -> m (f [:[b]:])) |
| 04:31:44 | <FMota> | > !(1 + 1) |
| 04:31:45 | <lambdabot> | parse error on input `!' |
| 04:31:50 | <FMota> | > (1 + 1)! |
| 04:31:50 | <lambdabot> | parse error on input `}' |
| 04:31:54 | <FMota> | :/ |
| 04:32:07 | <shachaf> | FMota: That's only for function arguments/data declarations. |
| 04:32:07 | <omnId> | > length [1..10^10] `seq` "blah!" |
| 04:32:12 | <lambdabot> | Terminated |
| 04:32:13 | <shachaf> | FMota: Try seq. |
| 04:32:20 | <omnId> | > length [1..10^4] `seq` "blah!" |
| 04:32:21 | <lambdabot> | "blah!" |
| 04:32:24 | <shachaf> | FMota: seq a b = force a, return b |
| 04:32:32 | <shachaf> | FMota: (Force only to WHNF.) |
| 04:32:58 | <FMota> | hm |
| 04:33:09 | <FMota> | how does one use seq? |
| 04:33:09 | <omnId> | > let x = 1 + 1 in x `seq` x * x |
| 04:33:11 | <lambdabot> | 4 |
| 04:33:20 | <omnId> | @src ($!) |
| 04:33:20 | <lambdabot> | Source not found. Do you think like you type? |
| 04:33:22 | <FMota> | oh |
| 04:33:23 | <FMota> | I see |
| 04:33:37 | <omnId> | f $! x = x `seq` f x |
| 04:34:03 | <FMota> | that works for me :) |
| 04:34:27 | <FMota> | thank yous |
| 04:34:31 | <omnId> | remember, it only forces the outermost constructor, you'll have to depend on more if you want to eval more |
| 04:34:51 | <omnId> | (length xs `seq` ...) forces the spine of xs |
| 04:35:27 | <FMota> | so essentially it tells haskell what order to eval things. |
| 04:35:37 | <omnId> | which is somewhat evil |
| 04:35:56 | <FMota> | :o XD |
| 04:36:22 | <ddarius> | seq is evil. Or at least it is at it's type. |
| 04:36:35 | <omnId> | class Eval? |
| 04:36:43 | <shachaf> | ddarius: At its type? |
| 04:36:45 | <FMota> | class Evil ! |
| 04:36:49 | <geocalc> | > sum [1..sum[1..8]] |
| 04:36:49 | <shachaf> | ddarius: What do you |
| 04:36:51 | <lambdabot> | 666 |
| 04:36:54 | <shachaf> | mean? |
| 04:36:58 | <FMota> | lol |
| 04:37:04 | <ddarius> | shachaf: It should not be fully polymorphic. |
| 04:37:18 | <shachaf> | Oh. |
| 04:37:22 | <ddarius> | It should be in a class like in the good 'ole days. |
| 04:38:07 | <luqui> | how come? |
| 04:39:54 | <ddarius> | Because it complicates the equational properties of the language. It complicates parametricity. |
| 04:40:23 | <luqui> | hm |
| 04:40:46 | <ddarius> | @free seq |
| 04:40:48 | <lambdabot> | g . seq x = seq (f x) . g |
| 04:41:00 | <luqui> | @help free |
| 04:41:00 | <lambdabot> | free <ident>. Generate theorems for free |
| 04:41:26 | <ddarius> | This theorem is false. |
| 04:41:44 | <luqui> | oh I remember that paper. I read it when I was first learning haskell. I didn't understand it at all (maybe I should go back now) |
| 04:42:06 | <Pseudonym> | ddarius: seq is not realisable in Haskell. |
| 04:42:58 | <FMota> | hmm |
| 04:43:13 | <FMota> | it only took about 10 minutes to calculate the sum of 1 million primes. |
| 04:43:23 | <luqui> | that is quite a long time |
| 04:43:27 | <Pseudonym> | Yes, it is. |
| 04:43:28 | <ddarius> | Pseudonym: Indeed it is not. |
| 04:43:28 | <kaol> | was the result a prime? |
| 04:43:31 | <Pseudonym> | Which million was it? |
| 04:43:37 | <FMota> | I wonder if using seq speeded it up or slowed it down |
| 04:43:40 | <Pseudonym> | :type seq |
| 04:43:45 | <Pseudonym> | :t seq |
| 04:43:47 | <lambdabot> | forall a t. a -> t -> t |
| 04:43:51 | <Pseudonym> | ?djinn a -> t -> t |
| 04:43:51 | <ddarius> | sped |
| 04:43:51 | <lambdabot> | f _ a = a |
| 04:44:03 | <Pseudonym> | That function satisfies the free theorem. |
| 04:44:05 | <FMota> | ONE MILLION DOLLARS *snickers, pinkie in mouth* |
| 04:44:19 | <ddarius> | Pseudonym: Indeed it does. |
| 04:44:20 | <FMota> | er, first million primes |
| 04:44:41 | <shachaf> | > let f !a b = b in f undefined 5 |
| 04:44:42 | <lambdabot> | Parse error in pattern |
| 04:45:28 | <kaol> | > let f (!a) b = b in f undefined 5 |
| 04:45:28 | <lambdabot> | Parse error in pattern |
| 04:46:18 | <lament> | one time, I counted to a billion. |
| 04:47:19 | <shachaf> | @set -XBangPatterns |
| 04:47:19 | <lambdabot> | Parse error |
| 04:47:31 | <shachaf> | Hmm, what does that get corrected to? |
| 04:47:36 | <omnId> | > 10^9 / 86400 |
| 04:47:37 | <shachaf> | Oh, @let. |
| 04:47:41 | <lambdabot> | 11574.074074074075 |
| 04:47:51 | <omnId> | > 11574 / 365 |
| 04:47:53 | <lambdabot> | 31.70958904109589 |
| 04:48:02 | <omnId> | if you counted once per second, it'd take 32 years |
| 04:48:50 | <omnId> | @google 1 billion seconds in years |
| 04:48:53 | <lambdabot> | http://en.wikipedia.org/wiki/1_E17_s |
| 04:48:53 | <lambdabot> | Title: 1 E17 s - Wikipedia, the free encyclopedia |
| 04:49:07 | <omnId> | @google 1000000000 seconds in years |
| 04:49:08 | <lambdabot> | 1,000,000,000 seconds = 31.6887646 years |
| 04:49:16 | <Pseudonym> | ?google pi seconds in nanocenturies |
| 04:49:19 | <lambdabot> | http://ircarchive.info/haskell/2007/2/28/4.html |
| 04:49:19 | <lambdabot> | Title: haskell heh Why get the processor to do it when there's a perfectly good bot in ... |
| 04:49:28 | <Pseudonym> | ?google 3.14159 seconds in nanocenturies |
| 04:49:29 | <lambdabot> | No Result Found. |
| 04:49:36 | <allbery_b> | *snerk* |
| 04:49:37 | <Pseudonym> | ?google pi seconds in centuries |
| 04:49:38 | <omnId> | ?frink |
| 04:49:39 | <lambdabot> | pi seconds = 9.95531902 x 10^-10 centuries |
| 04:49:45 | <luqui> | counting to a billion as long as you don't specify where to count from... |
| 04:50:10 | <luqui> | > [0,500000000,1000000000] |
| 04:50:12 | <lambdabot> | [0,500000000,1000000000] |
| 04:50:14 | <luqui> | > [0,500000000,..1000000000] |
| 04:50:15 | <lambdabot> | Parse error |
| 04:50:16 | <shachaf> | @go pi furlongs per fortnight in metric inches per century |
| 04:50:17 | <luqui> | > [0,500000000..1000000000] |
| 04:50:18 | <lambdabot> | http://en.wikipedia.org/wiki/List_of_unusual_units_of_measurement |
| 04:50:18 | <lambdabot> | Title: List of unusual units of measurement - Wikipedia, the free encyclopedia |
| 04:50:18 | <lambdabot> | [0,500000000,1000000000] |
| 04:50:20 | <luqui> | there |
| 04:50:22 | <luqui> | finally |
| 04:51:52 | <omnId> | "metric inches"? |
| 04:52:09 | <shachaf> | 2.5 centimeters, I think. |
| 04:52:30 | <omnId> | hasn't the ordinary inch been redefined as 2.54 centimeters? |
| 04:52:36 | <FMota> | :t elem |
| 04:52:38 | <lambdabot> | forall a. (Eq a) => a -> [a] -> Bool |
| 04:52:50 | <shachaf> | omnId: Yes, I think so. |
| 04:53:17 | <lament> | inches are so cool |
| 04:53:22 | <lament> | i used to be against the imperial system |
| 04:53:40 | <lament> | but it's really cool that it's still around, it's a living relic of the past! |
| 04:54:06 | <platypus> | Like the appendix. |
| 04:54:22 | <omnId> | we should switch to planck units. |
| 04:54:34 | <omnId> | it's the most logical decision |
| 04:54:42 | <shachaf> | lament: And now you're against the imperative system? |
| 04:54:59 | <lament> | shachaf: badum-ts? |
| 04:55:22 | <shachaf> | lament: ? |
| 04:55:26 | <FMota> | wtf? I got a stack overflow! |
| 04:55:27 | <FMota> | wow. |
| 04:55:53 | <shachaf> | > foldr (+) 0 [1..10000000] -- Not hard |
| 04:55:55 | <lambdabot> | Exception: stack overflow |
| 04:56:12 | <omnId> | "I used to be against the imperial system" "And now you're against the imperial system?" There's been a misunderstanding here. |
| 04:56:21 | <omnId> | imperative! |
| 04:56:30 | <omnId> | ACTION misunderstood |
| 04:56:41 | <lament> | omnId: yes, just as you said :) |
| 04:56:42 | <ddarius> | FMota: You're doing something wrong |
| 04:56:46 | <FMota> | :/ |
| 04:57:02 | <FMota> | either that or I'm using too much memory |
| 04:57:18 | <FMota> | but since haskell is lazy, that shouldn't be happening |
| 04:57:23 | <shachaf> | #vim (see? I'm not the only one!): < lumgwada> 5j |
| 04:57:42 | <platypus> | FMota: Do you have a space leak? |
| 04:57:50 | <FMota> | idk |
| 04:57:53 | <shachaf> | FMota: What are you doing that's causing it? |
| 04:58:47 | <FMota> | I'm counting the total number of letters in the english words for 1 to 1000 inclusive |
| 04:58:51 | <FMota> | problem # 17 |
| 04:59:33 | <FMota> | oh |
| 04:59:34 | <FMota> | hm |
| 04:59:39 | <FMota> | :/ |
| 04:59:41 | <lament> | that should neither run out of memory nor produce stack overflows. |
| 04:59:43 | <FMota> | humbug |
| 05:00:24 | <FMota> | word x | x < 100 = word (x - mod x 10) ++ "-" ++ word (mod x 10) |
| 05:00:31 | <FMota> | ACTION wonders if that is causing it. |
| 05:00:40 | <FMota> | and doubts it, somehow |
| 05:01:05 | <shachaf> | FMota: "NOTE: Do not count spaces or hyphens." |
| 05:01:11 | <FMota> | I know |
| 05:01:17 | <shachaf> | OK. |
| 05:01:25 | <FMota> | but I'm doing the masochistic way of filtering those out afterwards |
| 05:02:42 | <ddarius> | FMota: Actually, it's sadistic. You aren't doing the symbol munging. |
| 05:03:01 | <FMota> | but I am forcing myself to wait, so perhaps it's both |
| 05:04:10 | <luqui> | it doesn't seem like the curry-howard isomorphism works for (a -> a) -> a |
| 05:04:34 | <shachaf> | luqui: Y doesn't type-check. |
| 05:04:43 | <shachaf> | luqui: It has to be provided as primitive, somehow. |
| 05:04:48 | <luqui> | ahh |
| 05:04:52 | <ddarius> | luqui: Y isn't something you want in your logic. |
| 05:04:55 | <ddarius> | :t fix id |
| 05:04:57 | <lambdabot> | forall a. a |
| 05:05:15 | <ddarius> | There's a prood of falsity straight from the most basic axiom and Y. |
| 05:05:23 | <FMota> | you think maybe it was my british spelling of forty? :o |
| 05:05:59 | <luqui> | interesting. that has something to do with the fact that representation of Y is equivalent to undecidability.... |
| 05:06:01 | <luqui> | ? |
| 05:06:05 | <luqui> | well, more like ! |
| 05:06:43 | <FMota> | /lol/ |
| 05:06:49 | <FMota> | I found out what it was |
| 05:06:59 | <ddarius> | Recursive let? |
| 05:07:01 | <FMota> | I hadn't specified a "word 8" |
| 05:07:38 | <FMota> | obv, the number is wrong now |
| 05:07:45 | <FMota> | but at least it finishes |
| 05:09:35 | <FMota> | yay, got it right after 3 tries! |
| 05:11:00 | <FMota> | > let fact 0 = 1; fact n = fact $ n - 1 in fact 100 |
| 05:11:01 | <lambdabot> | 1 |
| 05:11:04 | <FMota> | :o |
| 05:11:11 | <FMota> | oops. |
| 05:11:25 | <allbery_b> | that's not going to work too well :) |
| 05:11:28 | <ddarius> | Count Down To Unity! |
| 05:11:34 | <FMota> | > let fact 0 = 1; fact n = n * (fact (n - 1)) in fact 100 |
| 05:11:36 | <lambdabot> | 9332621544394415268169923885626670049071596826438162146859296389521759999322... |
| 05:11:39 | <FMota> | xd |
| 05:13:00 | <luqui> | > product [1..100] + 1 |
| 05:13:02 | <lambdabot> | 9332621544394415268169923885626670049071596826438162146859296389521759999322... |
| 05:13:09 | <luqui> | My dad is richer than your dad! |
| 05:13:34 | <shachaf> | > fix (+1) |
| 05:13:35 | <lambdabot> | Exception: <<loop>> |
| 05:13:50 | <shachaf> | <<loop>>? Clever of it. |
| 05:13:58 | <FMota> | yummy, I get to use map (:[]) again :) |
| 05:14:20 | <omnId> | @quote \:\[ |
| 05:14:20 | <lambdabot> | psykotic says: (:[]) is the happy monkey operator |
| 05:14:29 | <FMota> | XD |
| 05:14:32 | <luqui> | :[]... never thought of that, I always used return |
| 05:14:46 | <FMota> | :[] is a lot nicer :) |
| 05:15:02 | <omnId> | @quote \:\[\{ |
| 05:15:03 | <lambdabot> | SamB_XP says: I once saw it eat a comment (:[{- Help! -}]) |
| 05:15:12 | <shachaf> | > fix (:[]) |
| 05:15:13 | <lambdabot> | Occurs check: cannot construct the infinite type: a = [a] |
| 05:15:13 | <lambdabot> | Expected... |
| 05:15:29 | <giles_bowkett> | @google haskell regex |
| 05:15:32 | <lambdabot> | http://www.dcs.gla.ac.uk/~meurig/regexp/ |
| 05:15:32 | <lambdabot> | Title: Regular Expressions in Haskell |
| 05:16:01 | <dfranke_> | I'm trying to write a case-insensitive version of the Parsec combinator 'string'. Here's what I have; is there any better way? |
| 05:16:04 | <FMota> | I love expressions like this: |
| 05:16:05 | <dfranke_> | ciString :: String -> CharParser st String |
| 05:16:07 | <dfranke_> | ciString s = foldr (\a b -> do { a' <- a; b' <- b; return (a' : b')}) (return "") [ oneOf [toLower c, toUpper c] | c <- s ] |
| 05:16:15 | <FMota> | sum . map read . map (:[]) . show $ num |
| 05:16:48 | <omnId> | (\a b -> ...) = (liftM2 (:)) |
| 05:16:55 | <ddarius> | dfranke_: What the bloody hell?! |
| 05:17:34 | <omnId> | @src sequence |
| 05:17:34 | <lambdabot> | sequence ms = foldr k (return []) ms |
| 05:17:34 | <lambdabot> | where |
| 05:17:34 | <lambdabot> | k m m' = do { x <- m; xs <- m'; return (x:xs) } |
| 05:17:38 | <luqui> | ddarius, thank you, he was making me feel stupid |
| 05:17:54 | <omnId> | sequence [ ... ] |
| 05:18:13 | <luqui> | thinking to myself, "I hope that's not the best way, because i don't understand that at all..." |
| 05:18:16 | <ddarius> | mapM (\c -> satisfy ((toUpper c ==) . toUpper)) |
| 05:18:39 | <shachaf> | ddarius: Not toLower? |
| 05:19:14 | <luqui> | :t satisfy |
| 05:19:16 | <lambdabot> | Not in scope: `satisfy' |
| 05:19:17 | <dfranke_> | ah, right. sequence. |
| 05:19:19 | <luqui> | oh it's a combinator |
| 05:19:32 | <ddarius> | Let's interpret ci as case-invariant, mapM (\c -> satisfy ((toUpper c ==) . toLower)) |
| 05:20:48 | <omnId> | @src mapM |
| 05:20:48 | <lambdabot> | mapM f as = sequence (map f as) |
| 05:21:11 | <omnId> | turns a [Char] into a [Parser Char], then sequence into Parser [Char] |
| 05:22:54 | <luqui> | @hoogle Either (a -> b) (c -> d) -> Either a c -> Either b d |
| 05:22:55 | <lambdabot> | No matches, try a more general search |
| 05:24:14 | <shachaf> | luqui: How would you write that? |
| 05:24:52 | <shachaf> | luqui: What if you got an (a -> b) and a c? |
| 05:25:45 | <luqui> | oh right |
| 05:26:04 | <omnId> | @type either |
| 05:26:06 | <lambdabot> | forall a c b. (a -> c) -> (b -> c) -> Either a b -> c |
| 05:26:28 | <luqui> | I meant |
| 05:26:31 | <omnId> | @hoogle (a->c) -> (b->d) -> Either a b -> Either c d |
| 05:26:31 | <lambdabot> | No matches, try a more general search |
| 05:26:42 | <luqui> | yes, that omnId |
| 05:27:07 | <mauke> | :t \f g -> either (Left . f) (Right . g) |
| 05:27:09 | <lambdabot> | forall a b a1 b1. (a -> a1) -> (b1 -> b) -> Either a b1 -> Either a1 b |
| 05:27:23 | <omnId> | --@type \f g -> either (Left . f) (Righ... bah |
| 05:27:47 | <shachaf> | @djinn (a->c) -> (b->d) -> Either a b -> Either c d |
| 05:27:47 | <lambdabot> | f a b c = |
| 05:27:47 | <lambdabot> | case c of |
| 05:27:47 | <lambdabot> | Left d -> Left (a d) |
| 05:27:47 | <lambdabot> | Right e -> Right (b e) |
| 05:28:02 | <omnId> | @. pl djinn (a->c) -> (b->d) -> Either a b -> Either c d |
| 05:28:02 | <lambdabot> | (line 3, column 12): |
| 05:28:02 | <lambdabot> | unexpected ">" or "-" |
| 05:28:02 | <lambdabot> | expecting variable, "(", operator or end of input |
| 05:28:04 | <shachaf> | @. pl djinn (a->c) -> (b->d) -> Either a b -> Either c d |
| 05:28:04 | <lambdabot> | (line 3, column 12): |
| 05:28:04 | <lambdabot> | unexpected ">" or "-" |
| 05:28:04 | <lambdabot> | expecting variable, "(", operator or end of input |
| 05:28:16 | <omnId> | @pl \f g -> either (Left . f) (Right . g) |
| 05:28:17 | <lambdabot> | (. (Right .)) . either . (Left .) |
| 05:28:25 | <luqui> | I'll use that one |
| 05:28:29 | <luqui> | it seems to be the clearest ;-) |
| 05:28:37 | <omnId> | riiiiiiiiight |
| 05:29:22 | <omnId> | @type liftM2 either (Left .) (Right .) |
| 05:29:24 | <lambdabot> | forall a a1. (a -> a1) -> Either a a -> Either a1 a1 |
| 05:29:31 | <omnId> | nope |
| 05:30:27 | <FMota> | :) I like TextMate. It makes Haskell easy |
| 05:30:50 | <ddarius> | Apparently not easy enough. |
| 05:31:11 | <shachaf> | I like vim. It makes Haskell fun. :-) |
| 05:31:42 | <FMota> | lol |
| 05:31:57 | <FMota> | *easier |
| 05:44:53 | <Tac-Tics2> | what does it mean for something to be "boxed" or "unboxed" in functional programming? |
| 05:45:03 | <Tac-Tics2> | I have a vague idea, but I can't find a good concrete definition |
| 05:46:09 | <shachaf> | ?wiki Unboxed type |
| 05:46:10 | <lambdabot> | http://www.haskell.org/haskellwiki/Unboxed_type |
| 05:46:32 | <Tac-Tics2> | kind #? |
| 05:47:44 | <Tac-Tics2> | that's not very explanative of what the term means =-( |
| 05:49:01 | <Tac-Tics2> | it has something to do with strictness, doesn't it? |
| 05:49:10 | <LeCamarade> | Yeah. That wiki page needs some work, it appears. |
| 05:50:20 | <lokimaf> | what's the reverse of read that converts Int to String ? |
| 05:50:33 | <Tac-Tics2> | show |
| 05:50:37 | <lokimaf> | thanks |
| 05:50:37 | <Tac-Tics2> | > show 55 |
| 05:50:39 | <lambdabot> | "55" |
| 05:50:44 | <Tac-Tics2> | > read $ show 55 :: Int |
| 05:50:45 | <lambdabot> | 55 |
| 05:59:44 | <FMota> | ACTION likes certain points-free definitions |
| 05:59:48 | <FMota> | like this one: |
| 05:59:54 | <FMota> | circular - all prime . rots |
| 06:00:02 | <FMota> | * circular = all prime . rots |
| 06:02:06 | <lekro> | does anyone know the binary extended gcd algorithm by Knuth? I'm struggling with finding the right formula for computing the s, t such that s*a + t*b = gcd(a,b). And unfortunately I don't have a copy of TAOCP here. |
| 06:02:37 | <sorear> | don't need TAOCP |
| 06:02:47 | <sorear> | any book on number theory will suffice |
| 06:03:21 | <lekro> | it's the extended *binary* gcd algorithm |
| 06:04:06 | <sorear> | oh, I thought you meant dyadic |
| 06:04:15 | <sorear> | as opposed to N-adic |
| 06:04:33 | <lekro> | what is dyadic in this context? |
| 06:05:27 | <lekro> | I mean this algorithm: http://en.wikipedia.org/wiki/Binary_GCD_algorithm |
| 06:05:27 | <lambdabot> | Title: Binary GCD algorithm - Wikipedia, the free encyclopedia |
| 06:06:33 | <lekro> | just a hint in the right direction would be enough. |
| 06:09:14 | <Pseudonym> | lekro: Have you seen the slides for Stepanov's talk about this? |
| 06:09:21 | <lekro> | no. |
| 06:09:43 | <Pseudonym> | http://www.stepanovpapers.com/gcd.pdf |
| 06:13:04 | <lekro> | Pseudonym: as far as I can see it only describes the "basic" binary gcd algorithm and not the extended. |
| 06:13:18 | <Pseudonym> | Oh, right. |
| 06:13:28 | <Pseudonym> | It's still a fascinating read. :-) |
| 06:14:11 | <lekro> | sure, I saved it |
| 06:17:08 | <lekro> | it shouldn't be so complicated I guess. I just can't see the right way |
| 06:17:40 | <Pseudonym> | Which case can't you do? |
| 06:17:56 | <lekro> | I don't have an idea how to construct the s and t values |
| 06:18:06 | <lekro> | such that s*a + t*b = gcd(a, b) |
| 06:18:23 | <lekro> | all ideas I tried involved dividing by 2. |
| 06:18:39 | <Pseudonym> | You know how to do it using the Euclidean algorithm? |
| 06:18:45 | <lekro> | yes |
| 06:19:25 | <lekro> | I'm beginning to think that dividing by 2 may be necessary. Then the only problem is to make sure the integer that is divided by 2 is even. |
| 06:19:30 | <Pseudonym> | OK, let's work this out. |
| 06:19:58 | <Pseudonym> | gcd n 0 = n, s = 1, t = 0 |
| 06:20:11 | <Pseudonym> | gcd 0 n = n, s = 0, t = 1 |
| 06:20:28 | <Pseudonym> | gcd 2n 2m = 2 * gcd m n |
| 06:20:43 | <Pseudonym> | So if s*m + t*n = gcd m n |
| 06:20:49 | <Pseudonym> | Then 2*s*m + 2*t*n = 2*gcd m n |
| 06:21:02 | <Pseudonym> | Following so far? |
| 06:21:02 | <lekro> | this case doesn't affect s and t |
| 06:21:13 | <Pseudonym> | Sure it does. It multiplies them by 2. |
| 06:21:23 | <lekro> | but it multiplies gcd by 2 as well |
| 06:21:29 | <Pseudonym> | Right. |
| 06:21:36 | <Pseudonym> | Let's get more concrete. |
| 06:21:52 | <Pseudonym> | @let steinGcd n 0 = (n, 1, 0) |
| 06:21:58 | <Pseudonym> | @let steinGcd 0 n = (n, 0, 1) |
| 06:22:00 | <lambdabot> | Defined. |
| 06:22:07 | <lambdabot> | Defined. |
| 06:22:43 | <Pseudonym> | @let steinGcd (2*n) (2*m) = let (g,s,t) = gcd n m in (2*g,2*s,2*t) |
| 06:22:43 | <lambdabot> | Parse error in pattern |
| 06:22:57 | <Pseudonym> | Crap, this isn't gofer. |
| 06:23:26 | <Pseudonym> | @let steinGcd n m | even n && even m = let (g,s,t) = gcd (n`div`2) (m `div`2) in (2*g,2*s,2*t) |
| 06:23:26 | <lambdabot> | <local>:25:77: Occurs check: cannot construct the infinite type: t = (t, ... |
| 06:23:40 | <Pseudonym> | @let steinGcd n m | even n && even m = let (g,s,t) = gcd (n `div` 2) (m `div` 2) in (2*g,2*s,2*t) |
| 06:23:41 | <lambdabot> | <local>:25:80: Occurs check: cannot construct the infinite type: t = (t, ... |
| 06:23:48 | <Pseudonym> | @let steinGcd n m | even n && even m = let (g,s,t) = steinGcd (n `div` 2) (m `div` 2) in (2*g,2*s,2*t) |
| 06:23:56 | <lambdabot> | Defined. |
| 06:23:58 | <Pseudonym> | That's it. |
| 06:24:03 | <Pseudonym> | OK, those are the easy cases. |
| 06:24:31 | <Pseudonym> | Now. gcd 2n (2m+1) = gcd n (2m+1) |
| 06:24:41 | <lekro> | I don't get why s and t are multiplied by 2 |
| 06:24:52 | <Pseudonym> | Suppose s*n + t*m = g |
| 06:25:05 | <Pseudonym> | That's what the recursive call gives you. |
| 06:25:07 | <Pseudonym> | Right? |
| 06:25:15 | <lekro> | gcd 2 2 calls gcd 1 1 which should give us something like (1, 1, 0). |
| 06:25:20 | <Pseudonym> | Right. |
| 06:25:27 | <Pseudonym> | Hang on, think abstractly. |
| 06:25:29 | <lekro> | gcd 2 2 should give us (2, 1, 0) |
| 06:25:34 | <lekro> | no change in s. |
| 06:25:36 | <Pseudonym> | The Stein algorithm gives: |
| 06:25:45 | <Pseudonym> | gcd (2n) (2m) = 2 gcd n m |
| 06:25:47 | <Pseudonym> | Right? |
| 06:25:50 | <lekro> | right |
| 06:25:58 | <Pseudonym> | Consider the recursive call. |
| 06:26:17 | <Pseudonym> | That should give us s and t such that s*n + t*m = gcd n m |
| 06:26:19 | <lekro> | this gives me s and t such that s*n + t*m = gcd n m |
| 06:26:22 | <Pseudonym> | Right. |
| 06:26:28 | <Pseudonym> | Oh, right. |
| 06:26:31 | <Pseudonym> | Yeah. |
| 06:26:45 | <Pseudonym> | We want s and t such that s*(2n) + t*(2m) = 2 gcd n m |
| 06:26:51 | <Pseudonym> | ?forget |
| 06:26:52 | <lambdabot> | Incorrect arguments to quote |
| 06:27:17 | <Pseudonym> | ?undefine |
| 06:27:19 | <lambdabot> | Undefined. |
| 06:27:31 | <Pseudonym> | @let steinGcd n 0 = (n, 1, 0) |
| 06:27:32 | <lambdabot> | Defined. |
| 06:27:48 | <Pseudonym> | @let steinGcd 0 n = (n, 0, 1) |
| 06:27:50 | <lambdabot> | Defined. |
| 06:28:01 | <Pseudonym> | @let steinGcd n m | even n && even m = let (g,s,t) = steinGcd (n `div` 2) (m `div` 2) in (2*g,s,t) |
| 06:28:04 | <Pseudonym> | That's right. |
| 06:28:04 | <lambdabot> | Defined. |
| 06:28:18 | <Pseudonym> | OK, do you follow that? |
| 06:28:26 | <lekro> | yes. |
| 06:28:31 | <Pseudonym> | Now. |
| 06:28:42 | <Pseudonym> | gcd 2n (2m+1) = gcd n (2m+1) |
| 06:28:56 | <Pseudonym> | Suppose you have s and t such that s*n + t*(2m+1) = gcd n (2m+1) |
| 06:29:23 | <Pseudonym> | Then you want s' and t' such that s'*(2n) + t'*(2m+1) = gcd 2n (2m+1) |
| 06:29:45 | <lekro> | and gcd 2n (2m+1) equals gcd n (2m+1) |
| 06:29:51 | <Pseudonym> | Right. |
| 06:30:28 | <lekro> | and this case is where I'm stuck. |
| 06:31:00 | <lekro> | of course I cannot say s' = s `div` 2 because s might be odd |
| 06:32:05 | <Pseudonym> | ACTION does some arithmetic on paper |
| 06:32:09 | <lekro> | either I'm missing something obvious or you need more information at that point. |
| 06:32:22 | <Pseudonym> | If s is even, you're okay. |
| 06:33:26 | <Pseudonym> | If s is odd, then s = 2p+1 for some p. |
| 06:34:00 | <Pseudonym> | ACTION thinks |
| 06:34:10 | <Pseudonym> | You should be able to transfer the extra n over to t'. |
| 06:37:32 | <FMota> | Programming in Haskell is a transformational experience. Who said Haskell was side-effect free? |
| 06:40:20 | <Pseudonym> | Nope, sorry. |
| 06:40:30 | <Pseudonym> | There's some obvious trick here that I'm not getting. |
| 06:40:36 | <Pseudonym> | I _suspect_ you have to deal with mod 4. |
| 06:45:20 | <lekro> | thanks anyway, I'll try to do something with mod 4 |
| 06:46:53 | <lekro> | n is a multiple of gcd n (2m+1) |
| 06:47:33 | <lekro> | no, doesn't really help |
| 06:47:59 | <earthy> | FMota: nobody. Haskell *does* make explicit what the side-effects can be and where they can occur though. |
| 06:48:49 | <FMota> | really? then what is the type of haskell? |
| 06:49:03 | <FMota> | Haskell :: Programmer -> Better Programmer ? |
| 06:49:37 | <FMota> | heh, Haskell is the constructor for the Better monad. |
| 06:50:34 | <FMota> | if only "Better" were a monad... the world would be a Better place... |
| 06:51:00 | <nornagon> | someone built a better type system, so haskell built a Better monad. |
| 06:51:06 | <FMota> | lol |
| 06:51:26 | <Pseudonym> | You could make the RealWorld a better place with BetterT IO. |
| 06:52:08 | <nornagon> | heh |
| 06:52:55 | <nornagon> | a >>= b = (Better a) b |
| 06:54:04 | <FMota> | (>>=) :: Better a -> (a -> Better b) -> Better b -- a suddenly becomes altruistic and lets b do his thing |
| 06:54:51 | <FMota> | hmm, I'm equating selfishness with Betterness... probably a cue that I should go to sleep. |
| 06:58:00 | <swix> | I'm trying to convert (sqrt n) for use in [1..x] |
| 06:58:06 | <swix> | I get all sorts of ambigous type issues |
| 06:58:30 | <Pseudonym> | Sorry, could you explain what you're trying to do? |
| 06:58:34 | <FMota> | implement your own sqrt |
| 06:58:35 | <FMota> | ;) |
| 06:59:16 | <swix> | I want [1..(sqrt n)] |
| 06:59:19 | <swix> | but that's a float |
| 06:59:26 | <swix> | so I want [1..(truncate (sqrt n))] |
| 06:59:36 | <Pseudonym> | Right. |
| 06:59:38 | <swix> | but I get all sorts of RealFrac, Floating not defined... |
| 06:59:53 | <Pseudonym> | [1 .. truncate (sqrt (fromIntegral n))] |
| 06:59:59 | <FMota> | you know what haskell needs? subtyping. |
| 07:00:06 | <Pseudonym> | However... |
| 07:00:13 | <Pseudonym> | isqrt :: Integer -> Integer |
| 07:00:21 | <Pseudonym> | isqrt = truncate . sqrt . fromIntegral |
| 07:00:24 | <Pseudonym> | Now: |
| 07:00:26 | <Pseudonym> | [1..isqrt n] |
| 07:00:33 | <FMota> | > isqrt 4 |
| 07:00:35 | <lambdabot> | Not in scope: `isqrt' |
| 07:00:47 | <Pseudonym> | @let isqrt = truncate . sqrt . fromIntegral |
| 07:00:50 | <lambdabot> | Defined. |
| 07:00:52 | <Pseudonym> | > isqrt 4 |
| 07:00:54 | <lambdabot> | 2 |
| 07:00:54 | <FMota> | > let isqrt = truncate . sqrt . fromIntegral in 4 |
| 07:00:55 | <lambdabot> | 4 |
| 07:00:57 | <Pseudonym> | > isqrt 9 |
| 07:00:58 | <FMota> | lol |
| 07:00:58 | <lambdabot> | 3 |
| 07:01:01 | <Pseudonym> | > isqrt 10 |
| 07:01:03 | <lambdabot> | 3 |
| 07:01:05 | <FMota> | I always mess things up |
| 07:01:06 | <Pseudonym> | However. |
| 07:01:18 | <FMota> | > isqrt 8 |
| 07:01:19 | <lambdabot> | 2 |
| 07:01:24 | <Pseudonym> | This will fail if your integers can't be represented exactly in Doubles. |
| 07:01:40 | <Pseudonym> | However, in that case, you probably won't be doing [1..isqrt n]. |
| 07:06:41 | <heanol> | join Reddit |
| 07:06:43 | <heanol> | oops |
| 07:08:18 | <FMota> | :index find |
| 07:08:26 | <FMota> | @index find |
| 07:08:26 | <lambdabot> | Data.List |
| 07:08:33 | <FMota> | @index fromJust |
| 07:08:33 | <lambdabot> | Data.Maybe |
| 07:08:52 | <FMota> | :t find |
| 07:08:54 | <lambdabot> | forall a. (a -> Bool) -> [a] -> Maybe a |
| 07:10:36 | <dfranke_> | what's the syntax for a unicode escape? |
| 07:11:24 | <FMota> | sq x = x * x |
| 07:11:41 | <FMota> | isqrt n = pred . fromJust . find (flip (>) n . sq) $ [1..] |
| 07:12:59 | <FMota> | that should work for just about any integer. |
| 07:13:47 | <lokimaf> | Haskell is for uber cool people |
| 07:14:26 | <allbery_b> | dfranke_: '\n' where n is a decimal (*not* octal!) integer |
| 07:14:28 | <FMota> | that's pretty much true of everyone in #haskell. (me excluded, ofc) |
| 07:14:42 | <lokimaf> | I made a Haskell tutorial: http://lokamaf.blogspot.com/2007/10/lokis-tutorial.html |
| 07:14:43 | <lambdabot> | Title: la.ma'aselyTCAna. pela.lokimaf.: Loki's हस्केल्ल Tut ... |
| 07:14:44 | <allbery_b> | cool? me?> as if. |
| 07:15:20 | <lokimaf> | tell me what you think at a skim |
| 07:15:23 | <Pseudonym> | When cool people start using Haskell, that's when I jump ship. |
| 07:15:28 | <FMota> | instance HaskellProgrammer p => Cool a |
| 07:15:31 | <FMota> | *Cool p |
| 07:15:37 | <Pseudonym> | ACTION is hipster hacker |
| 07:15:45 | <allbery_b> | ACTION too old to be cool |
| 07:15:55 | <lokimaf> | ACTION has girls chase him around begging to have sex with him |
| 07:15:59 | <allbery_b> | (or awake, given that it's 3am local, but...) |
| 07:17:09 | <lokimaf> | this one girl got to my room took off her clothes and begged me to fuck her, i don't bring random girls to my house anymore... |
| 07:17:18 | <lokimaf> | hmmm maybe should tone down |
| 07:17:21 | <lokimaf> | oh well |
| 07:17:36 | <lokimaf> | anyways, i like Haskell :D |
| 07:17:37 | <Pseudonym> | Yes, you should. |
| 07:17:38 | <Pseudonym> | haskell-blah |
| 07:17:49 | <Pseudonym> | That's what it's for. |
| 07:18:13 | <lokimaf> | yep, i usually just talk functions |
| 07:18:35 | <FMota> | lokimaf, I understand your plight, and you have my sympathy. Next time wear a rainbow shirt -- you'll still have girls flocking around you, but at least they won't get nekid. |
| 07:18:46 | <FMota> | [/blah] |
| 07:19:56 | <lokimaf> | hmm well i have an understanding that it's actually the tarot cards, but that's just like haskell random number generator with some additions |
| 07:20:05 | <FMota> | #haskell :: HaskellProgramm p => Channel p |
| 07:20:10 | <FMota> | *HaskellProgrammer |
| 07:21:02 | <FMota> | #haskell = filter (not . blah) programmers |
| 07:21:10 | <FMota> | w/e |
| 07:21:13 | <lokimaf> | agoode has an ipv6 address that's pretty cool |
| 07:21:21 | <FMota> | it's late, and I'm rambling. |
| 07:21:48 | <lokimaf> | tzal gyd |
| 07:21:56 | <FMota> | but I can't get off because Metric is on. oh well... |
| 07:22:06 | <swix> | how do you get a list less the first 1000 elements? |
| 07:22:24 | <FMota> | you mean without the first 1000 elements? |
| 07:22:28 | <swix> | yes |
| 07:22:29 | <FMota> | drop 1000 list |
| 07:22:32 | <swix> | cool |
| 07:22:35 | <FMota> | np :) |
| 07:22:54 | <lokimaf> | :D |
| 07:23:43 | <lokimaf> | kk well i'll go back to working on my speakable haskell derivative LOGJbang |
| 07:24:25 | <nornagon> | that doesn't look very speakable to me |
| 07:24:28 | <FMota> | :o |
| 07:24:45 | <nornagon> | how do you even pronounce that?! |
| 07:25:30 | <FMota> | Haskell isn't very good for speaking with. Ambiguity is actually quite a nice feature of natural languages. |
| 07:25:54 | <FMota> | and Haskell has very little ambiguity. |
| 07:26:05 | <nornagon> | lojban is not a natural language |
| 07:26:21 | <nornagon> | it's a conlang designed to be unambiguous |
| 07:26:25 | <FMota> | plus, anything without dependent types is not suited for speaking in |
| 07:26:48 | <FMota> | nornagon: right. still, my point stands. |
| 07:27:14 | <nornagon> | ACTION tips it over |
| 07:27:38 | <FMota> | how? points are 0-dimensional objects. They can't be tipped! |
| 07:28:59 | <nornagon> | FMota: they can if you lift them into the 3-dimension monad |
| 07:29:54 | <FMota> | that's bogus |
| 07:30:07 | <FMota> | how can you tip something without length, width, or height? |
| 07:30:23 | <FMota> | Or even duration, for that matter. |
| 07:30:57 | <nornagon> | well, if you have a point in 2-space, then you sweep it through a curve, you have a curve, which is a 2-object |
| 07:31:08 | <nornagon> | then sweep the 2-object to obtain a 3-object |
| 07:31:11 | <nornagon> | then tip it over |
| 07:32:02 | <FMota> | fair enough |
| 07:32:13 | <FMota> | but then it's no longer a point! :o |
| 07:32:55 | <nornagon> | that's because it's been lifted into 3-space :) |
| 07:33:05 | <FMota> | indeed |
| 07:35:07 | <geocalc> | nornagon=<< can you paste an exemple |
| 07:35:18 | <nornagon> | uh, what? |
| 07:35:45 | <geocalc> | 3-space point |
| 07:36:37 | <nornagon> | perhaps you missed the irony, i wasn't really being serious :P |
| 07:36:44 | <FMota> | sweepTo3 trajectory2 . sweepTo2 trajectory1 $ point |
| 07:39:57 | <geocalc> | > let evil = sum [1..sum[1..8]] |
| 07:39:57 | <lambdabot> | Parse error |
| 07:41:23 | <geocalc> | @let evil = sum [1..sum[1..8]] |
| 07:41:26 | <lambdabot> | Defined. |
| 07:41:45 | <geocalc> | > evil |
| 07:41:46 | <lambdabot> | 666 |
| 07:41:50 | <LeCamarade> | :-o |
| 07:41:54 | <LeCamarade> | ACTION runs away |
| 07:42:06 | <LeCamarade> | + |
| 07:42:09 | <LeCamarade> | + |
| 07:42:12 | <mauke> | > sqrt 666 |
| 07:42:13 | <LeCamarade> | + |
| 07:42:14 | <LeCamarade> | + |
| 07:42:14 | <LeCamarade> | + |
| 07:42:14 | <lambdabot> | 25.80697580112788 |
| 07:42:19 | <LeCamarade> | + |
| 07:42:28 | <ibid> | /away |
| 07:42:32 | <ibid> | gah |
| 07:42:41 | <Pseudonym> | > sqrt evil == money |
| 07:42:42 | <lambdabot> | Not in scope: `money' |
| 07:42:44 | <ibid> | ACTION is un-away, though :) |
| 07:42:58 | <sclv> | I'm writing a webapp framework in squiggol, but the IO support is awful. |
| 07:43:04 | <Pseudonym> | > isqrt evil |
| 07:43:06 | <lambdabot> | 25 |
| 07:43:23 | <FMota> | lol |
| 07:43:35 | <FMota> | > 5^2 |
| 07:43:36 | <lambdabot> | 25 |
| 07:43:39 | <Pseudonym> | @let money = 25 |
| 07:43:41 | <FMota> | > 5^2^2 |
| 07:43:41 | <lambdabot> | Defined. |
| 07:43:43 | <lambdabot> | 625 |
| 07:43:44 | <Pseudonym> | Now it's true. |
| 07:43:50 | <Pseudonym> | > money == isqrt evil |
| 07:43:51 | <lambdabot> | True |
| 07:43:52 | <FMota> | 5^2^2 + 5^2 |
| 07:43:57 | <LeCamarade> | :o) |
| 07:44:00 | <FMota> | > 5^2^2 + 5^2 |
| 07:44:01 | <lambdabot> | 650 |
| 07:44:09 | <FMota> | > 5^2^2 + 5^2 + 5 + 11 |
| 07:44:11 | <lambdabot> | 666 |
| 07:44:19 | <ibid> | > money^2 == evil |
| 07:44:21 | <lambdabot> | False |
| 07:44:21 | <Pseudonym> | > 562^2 + 5^2 + 2^4 |
| 07:44:23 | <lambdabot> | 315885 |
| 07:44:26 | <Pseudonym> | > 5^2^2 + 5^2 + 2^4 |
| 07:44:28 | <lambdabot> | 666 |
| 07:44:33 | <FMota> | well... it's not elegant, but it works. |
| 07:44:49 | <mauke> | > sqrt (2 * 666) |
| 07:44:50 | <lambdabot> | 36.49657518178932 |
| 07:44:51 | <LeCamarade> | (money == isqrt 666) && (money == isqrt evil) |
| 07:45:18 | <LeCamarade> | @let rootOfAll = isqrt |
| 07:45:21 | <lambdabot> | Defined. |
| 07:45:25 | <FMota> | > sum[1..sum[1..8]] |
| 07:45:26 | <lambdabot> | 666 |
| 07:45:40 | <LeCamarade> | > money == rootOfAll evil |
| 07:45:42 | <lambdabot> | True |
| 07:45:46 | <LeCamarade> | Be frank lambdabot |
| 07:45:47 | <FMota> | lol |
| 07:45:50 | <LeCamarade> | :-o |
| 07:45:51 | <LeCamarade> | + |
| 07:45:52 | <LeCamarade> | + |
| 07:45:53 | <LeCamarade> | + |
| 07:45:54 | <LeCamarade> | + |
| 07:45:59 | <ibid> | that's wrong, btw :) |
| 07:46:11 | <osfameron> | what's with the +s ? |
| 07:46:16 | <LeCamarade> | Cross. |
| 07:46:22 | <ibid> | @let premature x = x ^ 2 |
| 07:46:25 | <lambdabot> | Defined. |
| 07:46:29 | <ibid> | @let optimization = 5 |
| 07:46:32 | <lambdabot> | Defined. |
| 07:46:42 | <ibid> | > permature optimization == rootOfAll evil |
| 07:46:43 | <lambdabot> | Not in scope: `permature' |
| 07:46:50 | <ibid> | > premature optimization == rootOfAll evil |
| 07:46:51 | <Pseudonym> | Gotta go. Night. |
| 07:46:51 | <lambdabot> | True |
| 07:47:12 | <FMota> | :p |
| 07:47:27 | <LeCamarade> | @let root = (\_ _ _ -> isqrt) -- Monomorphism rest., you there? |
| 07:47:29 | <sclv> | :t Money |
| 07:47:30 | <lambdabot> | Defined. |
| 07:47:31 | <lambdabot> | Not in scope: data constructor `Money' |
| 07:47:43 | <sclv> | (fromIntegral Money) ** 2.0197391959991466 |
| 07:48:00 | <sclv> | > (fromIntegral Money) ** 2.0197391959991466 |
| 07:48:01 | <lambdabot> | Not in scope: data constructor `Money' |
| 07:48:03 | <FMota> | @let local x = sum [1..x] |
| 07:48:06 | <LeCamarade> | @let root = (\_ _ -> isqrt) -- Monomorphism rest., you there? |
| 07:48:06 | <lambdabot> | Defined. |
| 07:48:07 | <lambdabot> | <local>:12:0: Multiple declarations of `L.root' Declared at: <local>:... |
| 07:48:14 | <sclv> | > (fromIntegral money) ** 2.0197391959991466 |
| 07:48:16 | <lambdabot> | 666.0000000000003 |
| 07:48:23 | <LeCamarade> | money == (root "of" "all") evil |
| 07:48:30 | <FMota> | @let variables = local 8 |
| 07:48:30 | <lambdabot> | <local>:12:12: Ambiguous occurrence `local' It could refer to either ... |
| 07:48:37 | <FMota> | :/ |
| 07:48:40 | <LeCamarade> | > money == (root "of" "all") evil |
| 07:48:40 | <FMota> | darn |
| 07:48:41 | <lambdabot> | Couldn't match expected type `Integer' |
| 07:48:58 | <LeCamarade> | :o( |
| 07:49:03 | <LeCamarade> | Get back to work, you! |
| 07:49:04 | <FMota> | @let local_ x = sum [1..x] |
| 07:49:07 | <lambdabot> | Defined. |
| 07:49:13 | <FMota> | @let variables = local_ 8 |
| 07:49:17 | <lambdabot> | Defined. |
| 07:49:19 | <ibid> | ACTION is compiling a kernel module |
| 07:49:24 | <FMota> | > local_ variables == evil |
| 07:49:25 | <lambdabot> | True |
| 07:50:41 | <LeCamarade> | Reddit won't get out or RO mode! |
| 07:53:37 | <mauke> | > iterate (sum . enumFromTo 1) 8 |
| 07:53:42 | <lambdabot> | Terminated |
| 07:55:55 | <mauke> | > join (.) (sum . enumFromTo 1) 8 |
| 07:55:57 | <lambdabot> | 666 |
| 07:56:12 | <geocalc> | fear haskell |
| 07:56:14 | <osfameron> | the return value of the beast! |
| 07:59:47 | <nornagon> | join is like concat in that case, yes? |
| 08:00:12 | <geocalc> | @loosers |
| 08:00:12 | <lambdabot> | Unknown command, try @list |
| 08:00:18 | <nornagon> | @losers |
| 08:00:18 | <lambdabot> | Maximum users seen in #haskell: 420, currently: 362 (86.2%), active: 14 (3.9%) |
| 08:00:30 | <nornagon> | (learn to spell!) |
| 08:01:04 | <TSC> | @src join |
| 08:01:04 | <lambdabot> | join x = x >>= id |
| 08:01:16 | <nornagon> | ah. |
| 08:01:45 | <nornagon> | :t join (.) |
| 08:01:47 | <mauke> | in the list monad, >>= id is concatMap id, so concat == join |
| 08:01:47 | <lambdabot> | forall b. (b -> b) -> b -> b |
| 08:02:52 | <pastorn-rr> | @src join |
| 08:02:52 | <lambdabot> | join x = x >>= id |
| 08:03:00 | <mauke> | > join (.) sqrt 2 |
| 08:03:06 | <lambdabot> | 1.189207115002721 |
| 08:03:20 | <nornagon> | > sqrt 2 |
| 08:03:21 | <lambdabot> | 1.4142135623730951 |
| 08:03:25 | <osfameron> | huh? |
| 08:03:27 | <nornagon> | ?? |
| 08:03:44 | <mauke> | > (.) sqrt sqrt 2 |
| 08:03:46 | <lambdabot> | 1.189207115002721 |
| 08:04:03 | <nornagon> | oh ah |
| 08:04:21 | <mauke> | > join (^) 3 |
| 08:04:21 | <osfameron> | but why twice? |
| 08:04:23 | <lambdabot> | 27 |
| 08:04:27 | <nornagon> | so join (.) a is like a . a |
| 08:04:40 | <mauke> | join f x = f x x |
| 08:05:04 | <nornagon> | i still don't understand that :) |
| 08:05:12 | <nornagon> | how does that come from (>>= id) ? |
| 08:05:38 | <mauke> | @src (->) >>= |
| 08:05:39 | <lambdabot> | Source not found. Maybe if you used more than just two fingers... |
| 08:05:42 | <byorgey> | @src (->) (>>=) |
| 08:05:43 | <lambdabot> | f >>= k = \ r -> k (f r) r |
| 08:06:07 | <mauke> | see the duplicated r? |
| 08:06:12 | <nornagon> | zany |
| 08:07:35 | <byorgey> | it's the environment, aka "reader" monad, (r ->) |
| 08:08:11 | <byorgey> | @type join |
| 08:08:13 | <lambdabot> | forall (m :: * -> *) a. (Monad m) => m (m a) -> m a |
| 08:08:35 | <mauke> | (r -> (r -> a)) -> (r -> a) |
| 08:08:43 | <mauke> | @djinn (r -> (r -> a)) -> (r -> a) |
| 08:08:43 | <lambdabot> | f a b = a b b |
| 08:09:34 | <byorgey> | that is, the "environment" b gets passed in to both arguments of a two-arguement function, thus making a one-argument function. |
| 08:10:11 | <greentea> | Hi all. i can't seem to work out how to create a new type at the GHCi prompt, e.g. i'd like to be able to create MyBool = False | True. Can someone point me in the right direction, please? |
| 08:10:21 | <byorgey> | greentea: you can't, unfortunately. |
| 08:10:36 | <byorgey> | greentea: you'll need to write the type in a file and load the file into ghci. |
| 08:10:38 | <greentea> | Ah. Well, that explains that - thanks. :-) |
| 08:10:44 | <greentea> | Yeah, that's what i've been doing. |
| 08:11:14 | <Cale> | greentea: If that's the case, then you perhaps forgot the data keyword? |
| 08:11:42 | <osfameron> | hmmm, where is the "join" above coming from? In ghci I did :m +Control.Monad, and it complains No instance for (Monad ((->) a)) |
| 08:11:54 | <mauke> | :m +Control.Monad.Reader |
| 08:11:55 | <Cale> | osfameron: Control.Monad.Instances |
| 08:12:00 | <Cale> | (or Reader) |
| 08:12:04 | <greentea> | Oh,no, i mean, it works when i load the file into GHCi, just wanted to know if there was some way of doing it without having to load up a file. |
| 08:12:09 | <mauke> | Reader is shorter and works in 6.4 :-) |
| 08:12:10 | <osfameron> | oh, so there are different definitions of it all over the shop? |
| 08:12:22 | <Cale> | osfameron: no, they're the same instance |
| 08:12:27 | <mauke> | osfameron: no, there's only one join. you're missing a Monad instance |
| 08:13:01 | <osfameron> | but the: join (^) 3 works fine with .Reader, and doesn't with C.M on its own |
| 08:13:08 | <mauke> | yes |
| 08:13:25 | <byorgey> | hm, does anyone know if the inability to define data types at the ghci prompt is due to a theoretical limitation, or is it simply an unimplemented feature? |
| 08:14:07 | <goalieca> | :type &&& |
| 08:14:13 | <goalieca> | :t &&& |
| 08:14:15 | <lambdabot> | parse error on input `&&&' |
| 08:14:54 | <goalieca> | tabarnac |
| 08:15:00 | <byorgey> | goalieca: need parens |
| 08:15:03 | <byorgey> | @type (&&&) |
| 08:15:05 | <lambdabot> | forall (a :: * -> * -> *) b c c'. (Arrow a) => a b c -> a b c' -> a b (c, c') |
| 08:15:07 | <Cale> | osfameron: Control.Monad doesn't export the instance of Monad for ((->) e) |
| 08:15:20 | <mauke> | s/export/contain/ |
| 08:15:27 | <mauke> | instances are always exported |
| 08:15:31 | <Cale> | Well, that too :) |
| 08:15:39 | <byorgey> | goalieca: for the function instance of Arrows, f &&& g = \x -> (f x, g x) |
| 08:16:00 | <Cale> | osfameron: Personally, I think it ought to go into the Prelude :) |
| 08:16:21 | <goalieca> | byorgey, thank you. |
| 08:17:02 | <osfameron> | Cale, mauke: ok, ta. Actually, I can't see where the monads come into it at all, I'll come back to it at some point when I'm not at work... |
| 08:17:21 | <Cale> | :t join |
| 08:17:22 | <lambdabot> | forall (m :: * -> *) a. (Monad m) => m (m a) -> m a |
| 08:17:26 | <Cale> | That's where |
| 08:18:24 | <osfameron> | oh, because functions are monads |
| 08:19:59 | <wli> | What's the join for function monads? |
| 08:20:09 | <Cale> | join f x = f x x |
| 08:21:10 | <Cale> | join :: Monad m => m (m a) -> m a, so if m = ((->) e), then join :: (e -> e -> a) -> e -> a |
| 08:21:43 | <Cale> | which could really be only one thing :) |
| 08:23:41 | <byorgey> | Cale: how much do you know about the Waterloo CS department? |
| 08:23:50 | <Cale> | not a whole lot |
| 08:23:57 | <byorgey> | ok, just wondering |
| 08:24:05 | <byorgey> | I'm applying to PhD programs |
| 08:24:13 | <Cale> | cool |
| 08:25:31 | <Cale> | Shallit is there, I think, if you're into formal language stuff. |
| 08:26:26 | <byorgey> | hm, ok, thanks, I'll take a look. Formal language stuff sounds good (I think). |
| 08:28:22 | <Itkovian> | Can one say that Java is strongly typed? |
| 08:30:22 | <Cale> | Itkovian: Yes, in some sense of the term |
| 08:30:47 | <Itkovian> | ok |
| 08:31:29 | <Cale> | Though I think its type system is a rather poor example if you want to show off strong static typing. |
| 08:32:11 | <mauke> | @docs Numeric |
| 08:32:11 | <lambdabot> | http://haskell.org/ghc/docs/latest/html/libraries/base/Numeric.html |
| 08:32:46 | <Itkovian> | Cale: no, I'm just reading a draft of a friend's PhD and it was menioned, and I wanted to make certain before commenting on it |
| 08:39:15 | <dmwit> | 1% of my lines of code start with -- TODO: |
| 08:39:18 | <dmwit> | =( |
| 08:40:57 | <Cale> | Better than 100% |
| 08:44:22 | <mux> | bah, it's insanely hard to run a simple command, get output and the return status of the executable in haskell |
| 08:44:43 | <dmwit> | mux: Yeah. =( |
| 08:45:08 | <mux> | I fought against laziness so that I could use pOpen or hPipeFrom (from MissingH package), and now it works but I have other problems |
| 08:45:38 | <mux> | I get error messages from the command I'm running printed on the screen, and no easy/portable way to shut those off |
| 08:46:33 | <dmwit> | mux: I have a function runWithInput that I copied from jcreigh that is pretty nice, are you interested? |
| 08:46:34 | <mux> | I guess I could hack the pipe stuff from MissingH so that I also get stderr in the pipe and thus no screen pollution |
| 08:46:45 | <mux> | dmwit: very much, yes! thanks |
| 08:47:04 | <quicksilver> | is the missingH stuff lazy? |
| 08:47:34 | <mux> | the pipe* is described as such, but the hPipe* one isn't, the problem is that since I have a Handle, I have nothing but hGetContents to call |
| 08:47:39 | <mux> | and hGetContents is lazy |
| 08:48:07 | <quicksilver> | in that circumstance, I write my own strict hGetContents |
| 08:48:09 | <mux> | I just quicly wrote a strict hGetContents' |
| 08:48:12 | <mux> | yes |
| 08:48:14 | <mux> | I did that |
| 08:48:18 | <quicksilver> | normally I just iterate hGetLine |
| 08:48:19 | <hpaste> | dmwit pasted "for running programs in Haskell" at http://hpaste.org/3297 |
| 08:48:27 | <mux> | I want the full output to parse it with Parsec |
| 08:48:31 | <quicksilver> | (and I curse the haskell gods for only giving us lazy hGetContents) |
| 08:48:32 | <mux> | I don't want to split it by lines |
| 08:48:41 | <mauke> | http://hpaste.org/3296 |
| 08:48:58 | <quicksilver> | mux: well I join it up again afterwards :) |
| 08:49:06 | <quicksilver> | mux: it's just hGetLine is convenient and strict :P |
| 08:49:07 | <mux> | output <- pOpen ReadFromPipe "ldd" [f] hGetContents' |
| 08:49:22 | <mux> | once you have a strict hGetContents, this is very convenient =) |
| 08:49:29 | <mauke> | output <- getPipe "ldd" [f] |
| 08:49:37 | <mux> | if only it could pipe stderr as well so my screen doesn't get polluted |
| 08:49:55 | <mux> | mauke: thanks, will try this out |
| 08:49:57 | <roconnor> | hGetContents has broken semantics ... that can be useful /sometimes/, but not always. |
| 08:49:58 | <Itkovian> | dmwit: only 1%? |
| 08:50:10 | <mux> | mauke: oh, it's using forkProcess |
| 08:50:22 | <dmwit> | Itkovian: I also have a separate TODO file which has big, unfinished tasks (new features). |
| 08:50:24 | <dmwit> | =/ |
| 08:50:28 | <mux> | mauke: I was trying to stay portable =) though of course ldd(1) isn't supposed to exist or be useful under Windows |
| 08:50:29 | <Itkovian> | lol |
| 08:50:31 | <roconnor> | really hGetContents should be called hUnsoundGetContents. |
| 08:50:48 | <Itkovian> | dmwit: you should see my Phd draft ;-) |
| 08:50:50 | <osfameron> | ACTION briefly pimps the London Perl Workshop: http://www.mccarroll.org.uk/~gem/pages/lpw2007-announce.txt |
| 08:50:51 | <mauke> | mux: fork is portable enough :-) |
| 08:50:58 | <dmwit> | hehehe |
| 08:50:59 | <mux> | for my concern, it sure is |
| 08:51:06 | <mux> | and that will drop the dependency on MissingH I guess |
| 08:51:09 | <osfameron> | looking for good, short talks, accessible to a general audience. If anyon'e interested. |
| 08:51:15 | <mux> | mauke: thanks =) |
| 08:52:00 | <roconnor> | MissingH seems like a broken idea. Independent functions out to be independently packaged. |
| 08:52:08 | <roconnor> | s/out/ought/ |
| 08:52:16 | <mux> | I agree, but I found some stuff there that I didn't find elsewhere |
| 08:52:37 | <mux> | now that I know about FileManip though for instance, I won't use their glob function anymore =) |
| 08:52:44 | <mux> | FileManip is nice |
| 08:52:50 | <mux> | the find and glob APIs are good |
| 09:00:35 | <quicksilver> | roconnor: I believe that, when cosmicray started writing that, he wasn't sure how much of it he was reinventing and what should go where |
| 09:00:49 | <quicksilver> | roconnor: and it is his intention to slowly separate + repackage those parts which seem important |
| 09:00:58 | <roconnor> | :) |
| 09:01:15 | <roconnor> | MissingH is certainly better than nothing ... I think |
| 09:01:49 | <roconnor> | and presumably MissingH was made before we had such a nice Cabal/Hackage system? |
| 09:02:56 | <quicksilver> | yes |
| 09:03:38 | <roconnor> | presumably getting at a bunch of little packages should be easier. |
| 09:03:44 | <roconnor> | or maybe we need cabal install first. |
| 09:03:58 | <roconnor> | probably no need to wait. |
| 09:06:33 | <quicksilver> | CosmicRay is a bit too keen on lazy IO for my liking, too :) |
| 09:07:07 | <roconnor> | I don't pay him enought not to be lazy. |
| 09:07:11 | <quicksilver> | hdbc is lazy by default and I believe that is a bad decision in a DB library. |
| 09:07:57 | <roconnor> | oh, that sort of lazy |
| 09:08:09 | <roconnor> | I thought you were claiming he was lazy about dividing up MissingH ;) |
| 09:10:37 | <mauke> | @hoogle genericSplit |
| 09:10:38 | <lambdabot> | List.genericSplitAt :: Integral a => a -> [b] -> ([b], [b]) |
| 09:10:38 | <lambdabot> | Data.List.genericSplitAt :: Integral i => i -> [b] -> ([b], [b]) |
| 09:14:48 | <takamura> | hello |
| 09:15:14 | <lokimaf_> | what would be your name written in Kanji? |
| 09:15:20 | <Vq^> | hello takamura |
| 09:15:36 | <dcoutts> | @seen pgavin |
| 09:15:36 | <lambdabot> | I saw pgavin leaving #haskell 13h 22m 56s ago, and . |
| 09:15:59 | <dcoutts> | @tell pgavin gstreamer/Media/Streaming/GStreamer/Core/Types.chs:244:11: Not in scope: `cObjectUnfloat' |
| 09:15:59 | <lambdabot> | Consider it noted. |
| 09:16:08 | <takamura> | lokimaf_, I cant write kanji in this computer |
| 09:16:23 | <lokimaf_> | kk was just wondering |
| 09:16:40 | <takamura> | taka is high and mura is town |
| 09:17:14 | <lokimaf_> | cool, so would that be high in terms of elevation? |
| 09:17:37 | <takamura> | yes, many Japanese names are names of natural places |
| 09:17:55 | <lokimaf_> | makes sense |
| 09:18:22 | <takamura> | its the same for other languages |
| 09:18:32 | <takamura> | names of places, jobs, etc. |
| 09:18:59 | <takamura> | or town names |
| 09:19:35 | <takamura> | anyway, i'm not japanese :p |
| 09:19:41 | <lokimaf_> | i just noticed that your name was in abugida form and figured it was Japanese |
| 09:19:59 | <lokimaf_> | oh so is it an anime fascination? |
| 09:20:17 | <lokimaf_> | tzal gyd |
| 09:20:20 | <takamura> | what's abugida? |
| 09:20:38 | <lokimaf_> | where constonants are inherantly associated with a vowel |
| 09:20:46 | <takamura> | no, it's a japanese poet, Takamura Koutarou |
| 09:20:57 | <takamura> | ah |
| 09:21:45 | <lokimaf_> | so there arent any crunchy constonants in many asian languages |
| 09:21:51 | <takamura> | a friend of mine show me some works of Takamura and i liked it |
| 09:21:55 | <takamura> | and choose the nick |
| 09:22:49 | <takamura> | mm i dont know, japanese is not much related to other asian languages, except korean |
| 09:23:02 | <takamura> | it is also related to finnish |
| 09:23:06 | <takamura> | iirc |
| 09:23:39 | <osfameron> | don't think so |
| 09:23:43 | <lokimaf_> | hindi is abugida style language as well |
| 09:23:52 | <takamura> | some scholars say it is an uralo-altaic language |
| 09:23:53 | <osfameron> | finnish is related to estonian, and allegedly to Hungarian, but not really |
| 09:23:54 | <quicksilver> | finnish is related to hungarian |
| 09:24:03 | <takamura> | spanish is abugida also |
| 09:24:10 | <quicksilver> | the finno-ugrian (sp.?) languages are a small group |
| 09:24:29 | <lokimaf_> | naw spanish uses latin letters |
| 09:25:01 | <lokimaf_> | they can have constonant combinations like tcokolat |
| 09:25:12 | <takamura> | mm, then i didnt understood well what abugida means |
| 09:25:21 | <roconnor> | mmm tcokolat |
| 09:25:23 | <lokimaf_> | http://en.wikipedia.org/wiki/Abugida |
| 09:25:24 | <lambdabot> | Title: Abugida - Wikipedia, the free encyclopedia |
| 09:25:25 | <roconnor> | :P |
| 09:25:35 | <osfameron> | lokimaf_: I've seen txokolat, in Catalan and Basque writing |
| 09:25:50 | <osfameron> | quicksilver: I've read it as "finno-ugric" |
| 09:26:03 | <takamura> | tcokolat is not spanish |
| 09:26:06 | <takamura> | chocolate |
| 09:26:42 | <lokimaf_> | tcokolat iz inglic |
| 09:27:01 | <lokimaf_> | fonetik englic |
| 09:27:19 | <lokimaf_> | c = sh |
| 09:27:28 | <takamura> | now i checked some japanese grammar, and it says japanese can be a uralic or altaic language |
| 09:27:35 | <takamura> | ah |
| 09:28:40 | <takamura> | i allways wondered why english spelling is so difficult, why so many consonants? >_< |
| 09:28:45 | <lokimaf_> | xaskel = haskell |
| 09:29:38 | <lokimaf_> | konsonants ar a strengt |
| 09:30:03 | <lokimaf_> | do tzal gyd |
| 09:30:47 | <takamura> | now i read wikipedia, japanese is not abugida |
| 09:30:48 | <lokimaf_> | oh well |
| 09:30:52 | <takamura> | demotic egiptian is, i think |
| 09:31:19 | <raxas> | takamura: did you considered learning czech? "Plch zdrhl skrz drn, prv zhltl hrst zrn." is a correct and meaningfull czech sentence |
| 09:31:42 | <lokimaf_> | what does it mean |
| 09:31:43 | <takamura> | raxas, oh my god!! |
| 09:32:07 | <lokimaf_> | ? |
| 09:32:36 | <raxas> | plch is kind of mouse. so it is about he ate some grain and run away through the grass |
| 09:33:10 | <takamura> | wow |
| 09:33:49 | <takamura> | what languages are related to czech? |
| 09:34:22 | <lokimaf_> | k uel aim of tu pretend tu bi produktiv, meibi sliip iven, iz 5:30am |
| 09:34:25 | <raxas> | takamura: slovak and polish |
| 09:34:41 | <lokimaf_> | leitrz |
| 09:34:52 | <ivanm> | I finally managed to fix the looping problems in my (first-ever) STM-based app... except that even after it finishes ghci is still using large amounts of CPU... is there a way of killing off the threads? |
| 09:35:40 | <sjanssen> | ivanm: killThread? |
| 09:35:55 | <takamura> | lokimaf_, inglic is easier than english :D |
| 09:36:08 | <ivanm> | @where killthread |
| 09:36:08 | <lambdabot> | I know nothing about killthread. |
| 09:36:12 | <ivanm> | @where killThread |
| 09:36:13 | <lambdabot> | I know nothing about killthread. |
| 09:36:16 | <takamura> | i will try to learn it |
| 09:36:19 | <ivanm> | dammit, wrong command |
| 09:39:10 | <mux> | @src error |
| 09:39:11 | <lambdabot> | error s = throw (ErrorCall s) |
| 09:39:54 | <ivanm> | sjanssen: is there an easier way for a thread to kill itself or for the controlling thread to kill all sub-threads? |
| 09:40:05 | <ivanm> | or can I just go: killThread myThreadId ? |
| 09:40:27 | <sjanssen> | hmm, I'm not sure what will happen with killThread myThreadId |
| 09:41:01 | <ivanm> | ACTION goes off to try |
| 09:41:17 | <sjanssen> | yeah, that's safe |
| 09:41:36 | <sjanssen> | or you could just throw an exception |
| 09:41:45 | <ivanm> | doesn't work... |
| 09:41:49 | <ivanm> | @type killThread |
| 09:41:50 | <lambdabot> | Not in scope: `killThread' |
| 09:41:52 | <ivanm> | @type myThreadId |
| 09:41:53 | <lambdabot> | Not in scope: `myThreadId' |
| 09:41:59 | <ivanm> | grr... |
| 09:42:10 | <ivanm> | @type Control.Concurrent.myThreadId |
| 09:42:12 | <lambdabot> | IO GHC.Conc.ThreadId |
| 09:42:17 | <ivanm> | @type Control.Concurrent.killThread |
| 09:42:19 | <lambdabot> | GHC.Conc.ThreadId -> IO () |
| 09:42:21 | <sjanssen> | killThread =<< myThreadId |
| 09:42:26 | <ivanm> | yeah |
| 09:42:36 | <ivanm> | but my point was, just doing "killThread myThreadId" won't work :p |
| 09:43:25 | <ivanm> | stack overflow :( |
| 09:44:05 | <ivanm> | I don't know if its my code, or how busy my comp is, forkIO or STM, but the results it should be printing out every "timestep" come out in a rather jerky fashion :s |
| 09:44:37 | <scook0_> | buffering, maybe? |
| 09:44:53 | <hpaste> | ivanm pasted "Stack overflow with STM" at http://hpaste.org/3298 |
| 09:48:08 | <Lemmih> | ivanm: 'return ()' instead of 'killThread =<< myThreadId' still gives a stack overflow. |
| 09:48:25 | <ivanm> | Lemmih: well, it didn't for me... maybe I had more RAM without it :s |
| 09:48:37 | <ivanm> | s/without it/before when I didn't have it |
| 09:49:06 | <quicksilver> | I would personally always collect threadIds when I fork |
| 09:49:12 | <ivanm> | OK |
| 09:49:24 | <ivanm> | so, how could I do that? |
| 09:49:35 | <quicksilver> | thread <- forkIO ... |
| 09:49:38 | <ivanm> | shift the forkIO from the newAnt to where I do the mapM_ ? |
| 09:49:57 | <quicksilver> | change newAnt's type to IO ThreadID? |
| 09:50:00 | <quicksilver> | and remove the return () |
| 09:50:40 | <scook0> | (I'm personally not seeing a stack overflow, compiled or not) |
| 09:50:42 | <ivanm> | quicksilver: then turn mapM_ to mapM ? |
| 09:50:45 | <quicksilver> | yes |
| 09:50:49 | <ivanm> | *nod* |
| 09:50:57 | <quicksilver> | and presumably keep the list of threadIds around somewhere |
| 09:51:01 | <quicksilver> | to kill them all off at the end |
| 09:51:07 | <ivanm> | *nod* |
| 09:51:39 | <quicksilver> | this is, by the way, an annoyance of thread based programming in ghci |
| 09:51:43 | <quicksilver> | I submitted a bug about it |
| 09:52:06 | <quicksilver> | http://hackage.haskell.org/trac/ghc/ticket/1399 |
| 09:52:08 | <lambdabot> | Title: #1399 (better support for developing threaded applications in ghci) - GHC - Trac |
| 09:52:23 | <quicksilver> | still it's probably good practice to collect thread IDs |
| 09:52:28 | <quicksilver> | and kill em all off when that job is done |
| 09:52:34 | <quicksilver> | (unless they are coded to die automatically) |
| 09:52:49 | <ivanm> | yay! it worked! |
| 09:53:12 | <LeCamarade> | Me, what I wanted was to do ... |
| 09:53:17 | <quicksilver> | I love how easy it is to change a couple of types in a program :) |
| 09:53:27 | <quicksilver> | changing somethign from IO () to IO ThreadId is so logical |
| 09:53:29 | <quicksilver> | ... |
| 09:53:44 | <ivanm> | I changed "mapM_ ..." to "ants <- mapM ...", and then at the end of runSystem added "mapM_ killThread ants" |
| 09:53:46 | <LeCamarade> | A list of IO actions in parallel and have 'em return something. |
| 09:54:01 | <LeCamarade> | And I failed. |
| 09:55:09 | <ivanm> | LeCamarade: :( |
| 09:57:31 | <hpaste> | sjanssen pasted "parsequence" at http://hpaste.org/3299 |
| 09:57:36 | <sjanssen> | LeCamarade: ^^^ |
| 09:58:41 | <LeCamarade> | See, thread stuff take IO (). Which doesn't return sane values. So ... I can't fetch say web pages in parallel. Short of IORef, which me no like. |
| 09:58:52 | <EvilRanter> | sjanssen, wouldn't a channel be perfect for that sort of thing? |
| 09:59:01 | <LeCamarade> | Oh. Wait. Nice paste. |
| 09:59:10 | <sjanssen> | EvilRanter: perhaps, depends on whether the result order matters |
| 09:59:30 | <EvilRanter> | ah, yes, i see. yours preserves order. |
| 09:59:43 | <LeCamarade> | Well, I am re-writing my spider from Ruby. In Ruby it did: |
| 10:01:14 | <LeCamarade> | [url1, url2, url3].map {|x| open(x) {|f| f.read} } # Result is ... [data1, data2 ...] |
| 10:01:17 | <Lemmih> | Beware of exceptions. |
| 10:01:26 | <LeCamarade> | Sorry it is Miranda. ;o) |
| 10:01:40 | <LeCamarade> | Miranda is a Trademark of Research Software. |
| 10:02:34 | <LeCamarade> | And the Haskell version didn't quite fit. That's clean. Lemme stab again soon. |
| 10:02:42 | <ivanm> | looks like my problem still isn't fully solved... since if I run it a few times I still keep getting stack overflow errors :s |
| 10:03:17 | <sjanssen> | Lemmih: yes, I should catch the exception and stick it into the MVar |
| 10:03:31 | <ivanm> | and for some reason, if I take away the "killThread =<< myThreadID" bit, it crashes even earlier :s |
| 10:03:35 | <Lemmih> | ivanm: writeTVar state $! val |
| 10:03:56 | <sjanssen> | of course, the program will crash with "blocked indefinitely", which is almost equivalent :) |
| 10:04:07 | <ivanm> | yeah |
| 10:04:12 | <ivanm> | which it looks like what it's doing :s |
| 10:05:44 | <ivanm> | OK, for some reason when "threadKill =<< myThreadId" is removed, then ghci doesn't reduce in CPU/Mem usage :s |
| 10:06:12 | <Lemmih> | Works for me. |
| 10:07:34 | <sjanssen> | LeCamarade: the Haskell equivalent is mapM (\x -> open x >>= read) [url1, url2, url3] -- assuming valid definitions of open and read |
| 10:08:05 | <ivanm> | OK, looks like there's a bug with my code :s |
| 10:08:06 | <quicksilver> | or forM [url1,url2,url3] (\x -> open x >>= read) if you prefer that order |
| 10:08:37 | <quicksilver> | but it's not parallel which is what LeCamarade is after |
| 10:08:47 | <sjanssen> | is the Ruby version parallel? |
| 10:09:01 | <sjanssen> | also, it is trivial to write parMapM |
| 10:09:14 | <quicksilver> | you just did :) |
| 10:09:16 | <quicksilver> | more or less |
| 10:09:20 | <sjanssen> | right |
| 10:10:24 | <hpaste> | sjanssen annotated "parsequence" with "factor into a futures library" at http://hpaste.org/3299#a1 |
| 10:14:02 | <quicksilver> | sjanssen: nice, except you forget to catch the exceptions |
| 10:14:11 | <sjanssen> | quicksilver: yeah, that was a half edited copy |
| 10:14:25 | <sjanssen> | I forgot I was in the middle of adding exception support :) |
| 10:16:13 | <quicksilver> | nice idea of a Future type though |
| 10:17:10 | <hpaste> | sjanssen annotated "parsequence" with "with exceptions" at http://hpaste.org/3299#a2 |
| 10:17:14 | <sjanssen> | Haskell rocks. |
| 10:17:29 | <SamB_XP_> | parsequence? |
| 10:19:17 | <sjanssen> | SamB_XP_: yep, a version of sequence that runs each action concurrently |
| 10:19:51 | <osfameron> | ACTION worked through the "Tying the Knot" with lazy lets at weekend |
| 10:20:05 | <SamB_XP_> | shouldn't it take some kind of ... strategy for ensuring the evaluation of the return value? |
| 10:20:15 | <SamB_XP_> | (if desired) |
| 10:20:26 | <sjanssen> | ACTION thinks readMVar m >>= either throw return is beautiful |
| 10:20:29 | <osfameron> | to generate a doubly linked list. Actually the hardest thing was traversing the list (because of all the Maybe's getting in the way) |
| 10:20:41 | <sjanssen> | SamB_XP_: the client is responsible for that |
| 10:21:10 | <SamB_XP_> | sjanssen: hmm. |
| 10:21:45 | <SamB_XP_> | so, like, each IO action has to apply said strategy before returning? |
| 10:21:53 | <sjanssen> | sure |
| 10:22:00 | <quicksilver> | well this was designed for cases where the IO is what you actually 'want' to do |
| 10:22:05 | <SamB_XP_> | fair enough, I guess |
| 10:22:10 | <quicksilver> | if your code was doing 'pure work' then yes |
| 10:22:14 | <quicksilver> | a strategy might make sense |
| 10:22:39 | <quicksilver> | in very many cases the IO is enoguh though |
| 10:22:45 | <SamB_XP_> | I guess so |
| 10:22:47 | <quicksilver> | (as long as you're not using brokenlazyIO :P) |
| 10:23:00 | <SamB_XP_> | hehe |
| 11:21:19 | <ivanm> | I don't suppose there is an easy way in ghci to find all threads in that session? |
| 11:21:27 | <ivanm> | just to see if I forgot to close any, etc. |
| 11:21:44 | <quicksilver> | no |
| 11:21:49 | <quicksilver> | see my bug report :) |
| 11:32:53 | <ivanm> | quicksilver: heh, true |
| 11:35:18 | <ivan`> | is there a normal way to do distributed computing in haskell? |
| 11:35:21 | <ivan`> | ie, objects over network |
| 11:35:48 | <Lemmih> | Nope. |
| 11:36:36 | <quicksilver> | no |
| 11:36:42 | <quicksilver> | that's a hard problem (TM) |
| 11:36:58 | <quicksilver> | actually immutability makes some parts of it much easier, theoretically |
| 11:36:58 | <ivan`> | there's nothing like python's twisted? |
| 11:37:07 | <quicksilver> | not that I've heard of |
| 11:37:19 | <matthew_-> | well, there're json bindings |
| 11:37:24 | <matthew_-> | and there's Data.Binary |
| 11:37:31 | <quicksilver> | that's not the same thing :P |
| 11:37:36 | <quicksilver> | that's just APIs which might help you build one |
| 11:37:39 | <matthew_-> | indeed |
| 11:37:44 | <matthew_-> | also, it has a different name |
| 11:37:49 | <quicksilver> | ;P |
| 11:37:52 | <matthew_-> | ;) |
| 11:39:15 | <ivan`> | ACTION wanders back to his simple little python world |
| 11:39:31 | <ivan`> | with lack of lazy and messy stream code |
| 11:41:02 | <quicksilver> | ivanm: a "transparent" distribution architecture for haskell would be a beautiful thing, though |
| 11:41:15 | <quicksilver> | ivanm: although you'd have to make some decisions about how 'transparent' you really wanted it to be |
| 11:41:19 | <ivanm> | how do you mean "transparent" ? |
| 11:41:30 | <ivan`> | is erlang the only thing that does both SMP and network distribution properly? |
| 11:41:36 | <ivan`> | it seems like i can't have both worlds |
| 11:41:38 | <Botje> | see-through lingerie for cabal packages! |
| 11:42:36 | <matthew_-> | ivan`: yeah, that wouldn't surprise me |
| 11:42:45 | <quicksilver> | ivanm: well, so that code didn't need to be aware it was running on multiple machines |
| 11:42:50 | <matthew_-> | the only issue is that erlang's SMP support is currently rubbish |
| 11:42:52 | <quicksilver> | ivanm: to some extent, at least |
| 11:43:11 | <ivanm> | quicksilver: *nod* |
| 11:43:15 | <ivan`> | if there's any confusion i'm not ivanm |
| 11:43:18 | <ivan`> | nor ivan |
| 11:43:22 | <matthew_-> | so running the erlang VM with SMP support turned on often results in things running more slowly across multiple cores than on a single core |
| 11:43:29 | <ivanm> | ivan`: nor ivant? :p |
| 11:43:38 | <ivan`> | heh |
| 11:43:53 | <matthew_-> | I reckon you are the same person and just like talking to yourself ;) |
| 11:44:14 | <Botje> | ivanBACKQUOTE |
| 11:44:17 | <ivan`> | backtick |
| 11:44:44 | <pejo> | ivan, did you check GdH? |
| 11:44:48 | <hkBst> | nasty insects, them backticks |
| 11:44:48 | <quicksilver> | I was aware that you were different people |
| 11:44:58 | <quicksilver> | but tab-complete did get the wrong one at one point :) |
| 11:45:06 | <quicksilver> | thus drawing ivanm into the conversaton by mistake :) |
| 11:45:19 | <ivan`> | i'm looking at GdH |
| 11:45:27 | <quicksilver> | tab-complete always seems to prefer pure alpha names to partly punctuation names... |
| 11:45:43 | <pejo> | But as you mention, Erlang has a pretty good track record in the kind of thing you seem to want to do. |
| 11:45:43 | <ivan`> | last-used order works for me |
| 11:49:08 | <mux> | System.FilePath.Find is really sexy |
| 11:51:14 | <yitz> | @seen bos |
| 11:51:14 | <lambdabot> | bos is in #haskell and #ghc. I last heard bos speak 1d 5h 42m 51s ago. |
| 11:51:26 | <yitz> | Well, let him know that next time you see him. |
| 11:51:40 | <mux> | yeah, I intend to :-) |
| 11:52:28 | <quicksilver> | although 'find' should be called unsafeDontUseThisFind |
| 11:52:32 | <quicksilver> | 'fold' is nice though :) |
| 11:52:50 | <mux> | what's so unsafe about find ? *gulps* |
| 11:52:54 | <mux> | I just switched to using it |
| 11:52:59 | <quicksilver> | it's unsafe interleaving IO |
| 11:53:05 | <mux> | files <- find always (anyPerms 0111) path |
| 11:53:15 | <mux> | recursing over all executable files in a directory |
| 11:53:20 | <mux> | so, ugh, you're saying the above code is unsafe? |
| 11:53:21 | <yitz> | It's not _so_ unsafe - just a little. |
| 11:53:23 | <quicksilver> | you could do really strange stuff if you do anythign which changes the predicate |
| 11:53:29 | <mux> | ah |
| 11:53:32 | <quicksilver> | before you'd consumed the whole list |
| 11:53:37 | <mux> | I guess my usage is ok though |
| 11:53:53 | <mux> | it's not doing anything funky with the predicates |
| 11:54:06 | <quicksilver> | as long as you know that none of the code that operates on files would affect the output of files |
| 11:54:09 | <quicksilver> | as it were |
| 11:54:15 | <quicksilver> | e.g. as long as none of it is changing permissions |
| 11:54:21 | <yitz> | I think the only issue is that if something changes in the fs while you are iterating you may get weird results. |
| 11:54:22 | <quicksilver> | creating new dirs |
| 11:54:22 | <quicksilver> | etc |
| 11:54:25 | <mux> | okay, I'm not doing this |
| 11:54:38 | <quicksilver> | yitz: or if *you* change something in the fs, while you are iterating |
| 11:54:45 | <yitz> | right. |
| 11:54:52 | <quicksilver> | yitz: you could easily set up an infinite loop if you create a directory, e.g. |
| 11:54:56 | <mux> | both sound unpleasant |
| 11:55:04 | <yitz> | unless you are careful |
| 11:55:08 | <quicksilver> | right |
| 11:55:30 | <quicksilver> | I just hate it when people add new referentially opaque features to the language |
| 11:55:47 | <quicksilver> | when I'm busy trying to tell people that referential transparency is one of the reasons I use haskell :) |
| 11:56:07 | <quicksilver> | have to keep adding "as long as you don't use... hdbc, FilePath.Find .... " |
| 11:56:12 | <mux> | I think people are conspiring to get you to stop using haskell :-) |
| 11:56:14 | <ico> | where can I find the haskell's select() implementation, for asynchronously waiting on multiple file descriptors ? |
| 11:56:27 | <quicksilver> | ico: the canonical answer is 'just use threads' |
| 11:56:32 | <mux> | ico: you tipically don't use select() / poll() / whatever in haskell, we have threads |
| 11:56:36 | <quicksilver> | ico: threads do the right thing (they use select() internally) |
| 11:56:40 | <ico> | ok, I see |
| 11:56:53 | <ico> | My imperative brain is hurting more and more ... |
| 11:56:59 | <quicksilver> | if you really want it, it's somehwere in System.POSIX or therabouts |
| 11:57:00 | <mux> | that's expected |
| 11:57:09 | <quicksilver> | ico: threads in haskell are really really cheap. Almost free. |
| 11:57:20 | <mux> | and soooooooooooooo damn easy |
| 11:57:20 | <mux> | forkIO, that's it. |
| 11:57:20 | <ico> | I'll take your advice and do the thread thing then |
| 11:57:23 | <quicksilver> | ico: so it's quite safe to fork two new threads for every file descriptor |
| 11:57:27 | <quicksilver> | (one for reading, one for writing) |
| 11:57:38 | <ico> | new to haskell threading though, more to learn today |
| 11:58:37 | <mux> | ACTION garbage collects the countless 'do' that end up being useless after code refactoring |
| 11:58:47 | <mux> | I always, always forget about those |
| 11:59:32 | <mux> | it's not as if they were harmful, but I find it quite unaesthetic to have many of those scaterred around the code |
| 12:00:24 | <quicksilver> | makes your code read like frank sinatra |
| 12:00:26 | <quicksilver> | do be do be do |
| 12:00:35 | <mux> | heheh |
| 12:04:17 | <TSC> | I "do" it my way? |
| 12:15:39 | <ndm> | @seen dcoutts |
| 12:15:39 | <lambdabot> | dcoutts is in #gentoo-haskell, #haskell, #ghc and #haskell-overflow. I last heard dcoutts speak 34m 22s ago. |
| 12:16:06 | <ndm> | @slap dcoutts |
| 12:16:06 | <lambdabot> | ACTION smacks dcoutts about with a large trout |
| 12:21:36 | <dcoutts> | hia ndm |
| 12:21:53 | <LeCamarade> | Phew. Reddit is back. |
| 12:24:15 | <yitz> | Besides threads, you can also use hGetBufNonBlocking |
| 12:25:45 | <yitz> | Underneath the hood, I don't think GHC uses select/poll/epoll at all. |
| 12:26:17 | <dcoutts> | yitz: yes it does |
| 12:26:32 | <mux> | it has no choice but using those functions |
| 12:26:33 | <yitz> | I heard that Einar K. experimented with these in his network-alt library. |
| 12:26:48 | <mux> | otherwise you just cannot implement forkIO |
| 12:26:49 | <yitz> | oh yeah? interesting. |
| 12:26:53 | <dcoutts> | that's exactly how ghc does all blocking and non-blocking IO |
| 12:27:06 | <mux> | that's exactly how any 100% userland threading library does it |
| 12:27:08 | <yitz> | OK |
| 12:27:13 | <mux> | ie, libc_r under FreeBSD is doing the same |
| 12:27:28 | <mux> | you have no choice about it, you _need_ to prevent blocking |
| 12:28:31 | <dcoutts> | yitz: it could be improved to use system-specific improvements over poll/select |
| 12:28:35 | <dcoutts> | ie kpoll, epoll etc |
| 12:30:56 | <mux> | kqueue, kevent |
| 12:31:05 | <dcoutts> | oh, right |
| 12:31:15 | <mux> | it sure would help for cases where we have many threads |
| 12:31:20 | <profmakx> | anyone tried bootstrapping ghc on FreeBSD-Current/amd64? I am getting stuck when compiling the rts |
| 12:31:42 | <dcoutts> | mux: that should be easier to do now in the threaded rts |
| 12:31:42 | <mux> | profmakx: what's the error message? |
| 12:31:53 | <mux> | dcoutts: I need to take a look at this code |
| 12:31:53 | <dcoutts> | mux: since the IO manager thread is implemented in Haskell |
| 12:31:58 | <mux> | hmm, nice |
| 12:32:12 | <dcoutts> | mux: so it should be easier to do system-specific impls of it |
| 12:32:16 | <mux> | ACTION nods |
| 12:32:35 | <profmakx> | mux Linker.c:3556:0: error: `R_X86_64_32S' undeclared (first use in this function) |
| 12:32:46 | <mux> | hmm, unfriendly message :-) |
| 12:33:22 | <yitz> | There are Simon posts that report problems with poll/select. He says readNonBlockingFD is implemented using read with O_NONBLOCK. http://www.haskell.org/pipermail/haskell-cafe/2006-February/014619.html |
| 12:33:25 | <lambdabot> | Title: [Haskell-cafe] Re: standard poll/select interface, http://tinyurl.com/2xxajz |
| 12:33:26 | <profmakx> | it has something todo with "MAP_32BIT" |
| 12:33:34 | <dcoutts> | mux, profmakx: it'll be some #ifdef problem I expect |
| 12:33:39 | <mux> | yeah |
| 12:33:46 | <mux> | it's hard to tell without more context though |
| 12:33:52 | <mux> | and context may be totally lost at this point |
| 12:33:56 | <dcoutts> | "MAP_32BIT" is a linux thing I think |
| 12:34:05 | <profmakx> | yes it is |
| 12:34:07 | <dcoutts> | it's to mmap into the first 32bit of the address space |
| 12:34:15 | <mux> | profmakx: I have yet to test building GHC on RELENG_7, but I'll do soon |
| 12:34:16 | <dcoutts> | eg for loading code |
| 12:34:34 | <mux> | since 7.0-R is for soon now, we'd better make it possible for people that install it to use ghc |
| 12:34:43 | <mux> | dcoutts: oh, evil |
| 12:34:56 | <profmakx> | unfortunately i am in no way a ghc expert i don't know where to start :) |
| 12:35:00 | <mux> | it's the kind of things wine uses |
| 12:35:09 | <mux> | to map DLLs at their expected address |
| 12:35:18 | <dcoutts> | mux: no, that's MAP_FIXED |
| 12:35:34 | <mux> | MAP_FIXED is portable |
| 12:35:38 | <mux> | I'm definitely talking about something else |
| 12:36:04 | <dcoutts> | mux: I thought it was to do with the 'small' code model, where function pointers are 32bit and get sign-extended to 64bit |
| 12:36:06 | <mux> | (and MAP_FIXED can fail) |
| 12:36:33 | <mux> | dcoutts: I know there's something else: we are lacking some feature that wine needs, and wine is thus failing for us |
| 12:36:38 | <mux> | maybe that has been fixed though |
| 12:36:39 | <profmakx> | thats what it says in linker.c |
| 12:36:59 | <mux> | anyways, undefined MAP_32BIT sounds like worth trying, at least |
| 12:37:14 | <profmakx> | well i defined MAP_32BIT to be 0 |
| 12:37:25 | <profmakx> | then the error i pasted earlier turned up |
| 12:37:50 | <mux> | beware, they may check for it using #fdef |
| 12:38:01 | <mux> | in which case, it would still succeed if you defined MAP_32BIT to 0 |
| 12:38:05 | <mux> | try #undef MAP_32BIT |
| 12:39:26 | <profmakx> | i might also have gotten something wrong with the bootstrap setup, because they #ifdef x86_64_HOST_ARCH |
| 12:39:30 | <profmakx> | but the host is 32bit |
| 12:39:36 | <profmakx> | the target is 64 |
| 12:39:52 | <profmakx> | i think i will try a clean start first :) |
| 12:42:23 | <ekidd> | Good morning. |
| 12:44:30 | <LeCamarade> | ekidd: Good afternoon. |
| 12:45:20 | <TomMD> | @time LeCamarade |
| 12:45:22 | <lambdabot> | Local time for LeCamarade is Mon Oct 15 15:45:17 2007 |
| 12:47:57 | <profmakx> | LeCamarade is ahead of my timezone! |
| 12:51:11 | <LeCamarade> | :o) |
| 13:03:23 | <mux> | damn, and I thought haskell-cafe@ would be low volume |
| 13:06:33 | <roconnor> | *l* |
| 13:06:48 | <roconnor> | apparently haskell-cafe is a flamewar fest |
| 13:07:38 | <ndm> | yeah |
| 13:07:52 | <ndm> | but jerzy seems to have started 2 in 2 days |
| 13:09:39 | <quicksilver> | jerzy appears to be failing to communicate effectively in some cases |
| 13:09:44 | <quicksilver> | a lot of cross-purposes going on |
| 13:09:59 | <quicksilver> | I recommend a good user agent for reading the cafe :) |
| 13:10:44 | <quicksilver> | does anyone know if isaac dupree is an IRCer? |
| 13:14:12 | <pierre-> | hi all |
| 13:14:34 | <ndm> | hi pierre- |
| 13:24:52 | <igel> | is there a Vector type in haskell? |
| 13:25:11 | <igel> | one that allows indiced access to elements in O(1)? |
| 13:25:17 | <kpreid> | igel: Data.Array |
| 13:25:39 | <igel> | yeah sure, but i mean one that has insert and delete already implemented |
| 13:25:53 | <igel> | so that the array is replaced if it is to small |
| 13:26:22 | <ADEpt> | igel: you need growable one? Data.Sequence. Not O(1), but O (nlogn) (IIRC) |
| 13:27:01 | <ADEpt> | igel: besides, you might be better off with Data.Map or Data.IntMap, depending on your task |
| 13:27:35 | <igel> | there is no task, i was just wondering |
| 13:27:51 | <ADEpt> | igel: then, DataIntMap it is :) |
| 13:30:25 | <igel> | how come IntMap a is faster than Map Int a? |
| 13:30:41 | <quicksilver> | cleverer algorithm |
| 13:30:51 | <quicksilver> | using the internal structure of ints |
| 13:31:31 | <quicksilver> | Data.Sequence does things in O(log (distance from nearest end)) |
| 13:31:41 | <quicksilver> | which is as good as O(1) in practice, in many cases |
| 13:31:46 | <ADEpt> | +1 |
| 13:32:05 | <igel> | hmm, i have some time today |
| 13:32:10 | <quicksilver> | of course it does some things faster |
| 13:32:32 | <igel> | i'll just check out data.seq and write a Vector |
| 13:32:48 | <quicksilver> | append is O(log(smaller sequence)) |
| 13:33:02 | <quicksilver> | whereas append in a naive vector is O(sum of sizes of two sequences) |
| 13:33:23 | <igel> | sure, a vector is quite static |
| 13:33:30 | <igel> | but reading is fast |
| 13:33:45 | <igel> | i normally use vectors for, say, guis |
| 13:33:54 | <igel> | if you represent a list |
| 13:34:11 | <igel> | and everytime it is displayed, you need index-based access to the elements |
| 13:34:19 | <quicksilver> | but you don't, of course :) |
| 13:34:23 | <igel> | much more often that changing the original strucutre |
| 13:34:30 | <quicksilver> | typically displaying a list involves iterating through it |
| 13:34:35 | <quicksilver> | or iterating through a sublist |
| 13:34:39 | <quicksilver> | not indexed access... |
| 13:34:49 | <etnt> | I just noticed the binary stuff, now I wonder if there exist anything similar to Erlang's bitsyntax ? |
| 13:35:10 | <igel> | hmm that sounds reasonable^^ :) |
| 13:35:34 | <quicksilver> | igel: in practice I would be very surprised if a sequence fails to provide good enoguh performance |
| 13:36:02 | <quicksilver> | the main disadvantage of a sequence over traditional imperative structures is not O(1) access, but memory locality |
| 13:36:23 | <igel> | well it might prove ineffective for index-based replacing then |
| 13:36:24 | <quicksilver> | so if you used a sequence for 1 million elements in a very random access fashion |
| 13:36:42 | <MyCatSchemes> | quicksilver: my cache hurts at the very prospect. |
| 13:36:47 | <quicksilver> | then your main problem would be that the imperative C++ array-based vector has locality |
| 13:36:53 | <quicksilver> | exactly, MyCatSchemes |
| 13:37:16 | <quicksilver> | igel: update on sequence is O(log (distance to nearest end)) |
| 13:37:42 | <quicksilver> | cache locality and memory access patterns are much more important than notional O(1) access |
| 13:37:53 | <quicksilver> | This is, in fact, because O(1) access isn't really O(1) :) |
| 13:38:04 | <quicksilver> | O(1) access is only O(1) if you also have a cache hit |
| 13:38:12 | <igel> | do you mean paging issues? |
| 13:38:12 | <EvilRanter> | or, depending on how you look at it, O(log n) is really O(1) |
| 13:38:14 | <quicksilver> | and C++-arrays are much more likely to get cache hits most of the time |
| 13:38:24 | <EvilRanter> | ;) |
| 13:38:26 | <quicksilver> | igel: well not paging in the OS sense, no |
| 13:38:42 | <quicksilver> | igel: but caching at the CPU cache level |
| 13:38:49 | <quicksilver> | similar ideas of course |
| 13:39:08 | <igel> | ok.. that's new to me |
| 13:39:45 | <quicksilver> | for "normal" applications, such as your GUI example, you will not find the data structure to be the bottleneck |
| 13:39:57 | <quicksilver> | and you would be please with Data.Sequence's performance |
| 13:40:12 | <quicksilver> | you might even win somethign over the C++ equivalent due to fast growing and appending |
| 13:40:15 | <quicksilver> | in some cases |
| 13:40:19 | <quicksilver> | and you get cheap undo support for free! |
| 13:40:20 | <igel> | well i'm not really into gui programming with haskell |
| 13:40:21 | <quicksilver> | which is really nice |
| 13:40:42 | <quicksilver> | the main kind of example where data locality would bite you would be writing a graphics package |
| 13:40:44 | <igel> | the last gui framework i really learned was awt/swing |
| 13:40:52 | <quicksilver> | you wouldn't want to Data.Seq an entire image of pixels |
| 13:40:57 | <quicksilver> | that would be painful |
| 13:41:09 | <quicksilver> | say, 80 million pixels, 4 bytes each :) |
| 13:41:25 | <igel> | and implementing a swing model means implementing interfaces with methods like "elementAt(int)" |
| 13:41:57 | <igel> | and if such a method is invoked once for each displayed index, it is better to have random access :) |
| 13:45:19 | <quicksilver> | typically it's enough that the complexity is not O(n) |
| 13:45:31 | <quicksilver> | O(log n) is much much better than O(n) |
| 13:46:01 | <quicksilver> | it's unusual to find examples where O(1) vs O(log n) matters; it's also fiendishly hard to demonstrate and analyse |
| 13:46:16 | <quicksilver> | because various hardware issues confuse the difference between the two anyway |
| 13:46:34 | <roconnor> | ACTION prefers O(inverse ackermann(n)) |
| 13:46:46 | <iank> | roconnor: :'D |
| 13:47:05 | <MyCatSchemes> | ACTION prefers O(inverse ackermann(n,graham's number)) |
| 13:47:25 | <igel> | :D |
| 13:47:26 | <LeCamarade> | O(0) |
| 13:47:28 | <iank> | ACTION prefers O(3) |
| 13:47:38 | <roconnor> | O(3)=O(1) |
| 13:47:54 | <iank> | .. I know. |
| 13:47:55 | <LeCamarade> | o(-1) -- Predicts. |
| 13:48:06 | <iank> | But I rather like to bullshit that O(3) takes three times as long :) |
| 13:48:07 | <osfameron> | at YAPC::Vienna Damian Conway showed us how to write code in O(-1) time |
| 13:48:15 | <MyCatSchemes> | O(busybeaver-inverse(n)) |
| 13:48:36 | <osfameron> | using positronic variables that travel back in time |
| 13:48:36 | <roconnor> | MyCatSchemes: know any non-constant algorithms known to be of that order? |
| 13:48:46 | <LeCamarade> | :o) |
| 13:49:13 | <LeCamarade> | Bottom algorithms? |
| 13:49:21 | <MyCatSchemes> | roconnor: depends what you're measuring. Certainly none of that order in time. ^_^ |
| 13:49:59 | <profmakx> | mux, i seem to have got the rts to compile by undefining x86_64_HOST_ARCH |
| 13:50:04 | <roconnor> | There is some unification algorithm that is O(n*inverse achermann(n))? |
| 13:57:37 | <kosmikus> | ndm: ping |
| 13:58:58 | <fasta> | Can I catch stack overflows? |
| 13:59:37 | <roconnor> | interesting question |
| 13:59:45 | <roconnor> | should be easy to test |
| 14:00:12 | <fasta> | It doesn't say ***Exception Foobar |
| 14:00:24 | <fasta> | So, it seems that it works on a different level. |
| 14:00:33 | <fasta> | Which would imply the answer was no. |
| 14:01:28 | <LeCamarade> | > let die () = 0 + die () in die () |
| 14:01:33 | <lambdabot> | Exception: <<loop>> |
| 14:01:34 | <roconnor> | :( |
| 14:01:51 | <LeCamarade> | It says Exception for me. |
| 14:02:27 | <roconnor> | LeCamarade: that isn't a stack overflow |
| 14:02:28 | <vincenz> | it's not that simple in general tho |
| 14:02:33 | <vincenz> | with lazy data structures |
| 14:02:39 | <vincenz> | you coudl have the overflow during consumption and not construction |
| 14:02:40 | <roconnor> | > foldl (+) 0 [1..] |
| 14:02:48 | <lambdabot> | Terminated |
| 14:02:52 | <roconnor> | > foldr (+) 0 [1..] |
| 14:02:55 | <lambdabot> | Exception: stack overflow |
| 14:03:01 | <vincenz> | ^^^^^^^^ |
| 14:03:04 | <LeCamarade> | From GHCi: *** Exception: stack overflow |
| 14:03:16 | <vincenz> | @hoogle catch |
| 14:03:17 | <lambdabot> | Prelude.catch :: IO a -> (IOError -> IO a) -> IO a |
| 14:03:17 | <lambdabot> | Control.Exception.catch :: IO a -> (Exception -> IO a) -> IO a |
| 14:03:17 | <lambdabot> | GHC.ConsoleHandler.Catch :: (ConsoleEvent -> IO ()) -> Handler |
| 14:03:47 | <ToRA> | Prelude Control.Monad.Fix Data.List Control.Exception> Control.Exception.catch (print $ foldr1 (+) [0..]) (const $ putStrLn "caught") |
| 14:03:48 | <ToRA> | caught |
| 14:03:52 | <LeCamarade> | catch is for IO actions only, no? |
| 14:04:01 | <vincenz> | add a return :) |
| 14:04:13 | <vincenz> | ToRA: try "return" iso "print"? |
| 14:04:18 | <Olathe> | ACTION returns. |
| 14:04:34 | <fasta> | Maybe it is because I use xc that the Exception *** isn't printed in compiled programs. |
| 14:05:03 | <roconnor> | LeCamarade: correct. You have to catch an IO action that demands a stack overflow |
| 14:05:12 | <ToRA> | vincenz: if you s/return/print then it fails |
| 14:05:15 | <roconnor> | otherwise there would never be a stack overflow |
| 14:05:16 | <ToRA> | but i'd expect it to |
| 14:05:33 | <ToRA> | since it's the print call in ghc that is forcing the foldr1 |
| 14:05:38 | <ToRA> | *ghci |
| 14:05:59 | <LeCamarade> | Oh. :o) |
| 14:06:01 | <vincenz> | i guess you'd need to seq it |
| 14:06:39 | <quicksilver> | even imprecise exceptions can only be caught in IO |
| 14:06:40 | <Saizan> | ?type evaluate |
| 14:06:40 | <ToRA> | ah nice, with ghci 6.8 |
| 14:06:42 | <ToRA> | Prelude> foldr1 (+) [0..] |
| 14:06:42 | <ToRA> | Stopped at <exception thrown> |
| 14:06:42 | <ToRA> | _exception :: e = stack overflow |
| 14:06:42 | <lambdabot> | Not in scope: `evaluate' |
| 14:06:43 | <ToRA> | [<exception thrown>] Prelude> |
| 14:06:45 | <quicksilver> | see the awkward squad paper |
| 14:07:12 | <quicksilver> | unless I'm mistaken |
| 14:07:58 | <LeCamarade> | :t par |
| 14:08:00 | <lambdabot> | forall a b. a -> b -> b |
| 14:09:42 | <quicksilver> | catching imprecise exceptions in pure code would violate referential transparency, I think |
| 14:10:22 | <vincenz> | yep |
| 14:10:33 | <LeCamarade> | But I don't know if I'll ever grow to like exceptions. Even before I knew about Maybe a, I didn't like them. |
| 14:11:55 | <quicksilver> | I think they have their place |
| 14:12:20 | <quicksilver> | but in many (most?) situations there are preferrable alternatives |
| 14:12:21 | <roconnor> | whare are imprecise exceptions? Violations of the abstract machine? |
| 14:12:38 | <ndm> | kosmikus: pong |
| 14:12:38 | <quicksilver> | they're a kind of _|_ |
| 14:12:53 | <quicksilver> | as such, I think they're denotationally ok |
| 14:13:07 | <roconnor> | stack overflow isn't _|_ |
| 14:13:18 | <quicksilver> | the strange part is that you can catch them.. |
| 14:13:24 | <quicksilver> | but IO is allowed to be strange |
| 14:13:30 | <dcoutts> | roconnor: that's an asynchronous exception |
| 14:13:35 | <roconnor> | oh |
| 14:13:40 | <dcoutts> | as is heap overflow |
| 14:13:48 | <dcoutts> | or an exception thrown from another thread |
| 14:13:56 | <roconnor> | quicksilver: I keep encountering things which are both outside and inside. |
| 14:14:02 | <fasta> | So, can I happily continue the complete program despite the stack overflow? |
| 14:14:25 | <dcoutts> | fasta: you can catch it in some outside exception handler in IO |
| 14:14:31 | <quicksilver> | fasta: in general it's hard to tell "how far things got" before the overflow |
| 14:14:38 | <roconnor> | fasta: doesn't seem so unreasonable. The entire IO action is aborted, stack is cleaned up, everyone is happy. |
| 14:14:41 | <quicksilver> | fasta: but if you don't care, then you can continue |
| 14:14:55 | <quicksilver> | if you do care, then you hace to implement some kind of 'checkpointing' into IORef/Mvar |
| 14:14:59 | <quicksilver> | or similar |
| 14:15:12 | <dcoutts> | fasta: ghci catches does exactly that for example. |
| 14:15:29 | <dcoutts> | it catches all exceptions, prints them and goes back to the read/eval loop |
| 14:15:31 | <roconnor> | well, the IO action is aborted baddly. Side-effects stay. |
| 14:15:36 | <fasta> | quicksilver: The application is that I do a thousand "tasks" and I either want to know how long the took or whether they failed. |
| 14:15:46 | <quicksilver> | roconnor: "aborted" rather than "rolled back" |
| 14:15:50 | <quicksilver> | fasta: yes, that should be fine |
| 14:15:53 | <fasta> | quicksilver: but I don't want to babysit the machine, so it seems like it should work |
| 14:16:05 | <fasta> | they* |
| 14:16:10 | <quicksilver> | fasta: but if some of the tasks have IO side-effects, it is possible that the failed ones caused partial side-effects |
| 14:16:17 | <dcoutts> | quicksilver: though if you use bracket carefully you could arrange to roll things back explicitly |
| 14:16:25 | <quicksilver> | dcoutts: absolutely |
| 14:16:26 | <dcoutts> | eg deleting temp files etc etc |
| 14:16:35 | <fasta> | quicksilver: the tasks only have side-effects at the beginning |
| 14:16:37 | <quicksilver> | dcoutts: but the dfault behaviour alone doesn't do that :) |
| 14:16:41 | <dcoutts> | yes |
| 14:16:42 | <quicksilver> | fasta: then it should be quite fin |
| 14:16:51 | <quicksilver> | fasta: see sjanssen's earlier post about futures |
| 14:16:54 | <fasta> | quicksilver: which are guaranteed to be completed before a stack overflow can occur. |
| 14:17:17 | <fasta> | quicksilver: I am not subscribed anymore, since there was too much noise. |
| 14:17:41 | <fasta> | I do check the archives occasionally, but I used to read everything |
| 14:17:44 | <wsdo_okadr> | I would like to ask regarding Context-Dependent grammars |
| 14:17:55 | <wsdo_okadr> | for example I read in some textbook I have(wich I find pretty good that) |
| 14:18:08 | <wsdo_okadr> | LR1={wcw | w in (0,1)*} |
| 14:18:11 | <wsdo_okadr> | wich is quite ok |
| 14:18:14 | <wsdo_okadr> | but c is not quite defined |
| 14:18:33 | <fasta> | And Google isn't what it used to be either. |
| 14:18:35 | <wsdo_okadr> | I have a hunch it's some context |
| 14:18:57 | <wsdo_okadr> | but What is it more exactly ? |
| 14:19:21 | <fasta> | wsdo_okadr: it seems some constant expression |
| 14:19:21 | <wsdo_okadr> | (0,1)* I know that is the freegroup generated by 2 elements(0 and 1 in this case) |
| 14:19:50 | <wsdo_okadr> | all sequences of 0 and 1 that have at some point a constant |
| 14:20:06 | <fasta> | wsdo_okadr: you should complain to whoever gave you that book :) |
| 14:20:39 | <mrd> | not quite. it has to be the same sequence of 0s and 1s on either side of c |
| 14:20:50 | <mrd> | what you described is regular |
| 14:21:53 | <glen_quagmire> | hai my name is lolcatz i here to conquore |
| 14:23:00 | <wsdo_okadr> | mrd: yes you're right,I wasn't paying enough attention |
| 14:23:29 | <wsdo_okadr> | What is usually understood by |w| where w is some word generated by {0,1} ? |
| 14:23:35 | <wsdo_okadr> | in the context of formal languages |
| 14:23:50 | <wsdo_okadr> | I forgot it was written at the start of the book. |
| 14:25:20 | <quicksilver> | fasta: I actually meant h paste post :) |
| 14:25:26 | <quicksilver> | fasta: he said something here about it |
| 14:25:31 | <quicksilver> | fasta: I'll find it for you |
| 14:25:39 | <fasta> | quicksilver: oh, so Google is still fine ;) |
| 14:26:00 | <quicksilver> | fasta: http://hpaste.org/3299 |
| 14:26:03 | <kosmikus> | ndm: well, I was a bit irritated about System.FilePath docs mentioning isDrive etc., but not exporting the functions |
| 14:26:08 | <quicksilver> | fasta: the thid annotation |
| 14:26:14 | <kosmikus> | ndm: but I found out that they're only exported by the Windows version |
| 14:26:19 | <quicksilver> | fasta: note that it has the exceptions in the type |
| 14:26:28 | <kosmikus> | ndm: do you happen to know what System.Info.os reports for a Windows system? |
| 14:28:03 | <fasta> | quicksilver: I don't see the significance of that, but I do something very similar already. |
| 14:28:25 | <fasta> | quicksilver: I adapted the "compete" function from the wiki. |
| 14:29:07 | <quicksilver> | the significance was that it caught all exceptions |
| 14:29:13 | <quicksilver> | including, presumably, stack overflows |
| 14:29:19 | <quicksilver> | and turned them into exception values |
| 14:30:18 | <fasta> | @type try |
| 14:30:20 | <lambdabot> | Not in scope: `try' |
| 14:33:52 | <fasta> | quicksilver: I suppose the significance is that other languages have builtin "futures" and in Haskell you can build them yourself, since otherwise this is isomorphic to what I did. |
| 14:34:51 | <quicksilver> | fasta: fair enough |
| 14:36:48 | <fasta> | quicksilver: but after a stack overflow, have I lost the rest of the control stack? |
| 14:37:10 | <quicksilver> | I don't know how threads and stack overflows inter-relate |
| 14:37:13 | <fasta> | Can I protect a part somehow? |
| 14:37:16 | <quicksilver> | I'd hope it was thread local but I'm not sure |
| 14:37:23 | <dcoutts> | fasta: it's really just like any other exception |
| 14:37:38 | <dcoutts> | fasta: you can use catch, bracket etc etc |
| 14:37:50 | <fasta> | dcoutts: ok, so it only destroys everything up to the point of the IO action that started the mess? |
| 14:38:17 | <dcoutts> | fasta: catch is a wrapper round a computation, so you don't get the result of the computation, you get the exception instead |
| 14:38:52 | <fasta> | dcoutts: ok, nice. |
| 14:39:16 | <ndm> | kosmikus: "mingw32" |
| 14:39:18 | <fasta> | "stack overflow" seemed to indicate that it overwrote the start of the stack somehow. |
| 14:39:38 | <fasta> | But I guess the implementors are not that stupid ;) |
| 14:39:41 | <quicksilver> | no, just that the stack ran out of the space it decided to allocate for it |
| 14:39:54 | <roconnor> | I think the stack allocator knows how much space is available. |
| 14:39:54 | <quicksilver> | haskell has a checked stack, in other words |
| 14:40:01 | <ndm> | kosmikus: which is pure evil, of course |
| 14:40:17 | <roconnor> | ndm: so that is why haskell is slow ;) |
| 14:40:37 | <ndm> | roconnor: ? |
| 14:40:41 | <ndm> | evil /= slow |
| 14:41:01 | <roconnor> | ndm: oh, why is a checked stack evil if not because it is slow? |
| 14:41:11 | <roconnor> | ndm: woops |
| 14:41:16 | <roconnor> | you are responding to kosmikus |
| 14:41:19 | <fasta> | When I use the xc feature, I still get a "stack trace", although I catched the exception. |
| 14:41:19 | <roconnor> | my bad |
| 14:41:25 | <ndm> | roconnor: oh, yeah, stack overflow is evil because of slowness |
| 14:41:37 | <ndm> | roconnor: but heap checks are much more easy to remove, and just as slow |
| 14:41:50 | <roconnor> | AFAIK, only prim-ops use the stack. |
| 14:42:00 | <roconnor> | but I sort of think I might be wrong. |
| 14:42:12 | <fasta> | I find it odd that I get stack overflow, though. I was expecting to run out of heap space, but I guess the two compete for the same memory at some point. |
| 14:42:26 | <ndm> | roconnor: its the Haskell stack, not the C stack |
| 14:42:51 | <ndm> | fasta: stack overflow really does mean stack overflow, not because of heap pressure |
| 14:42:54 | <roconnor> | ndm: yeah, but I thought GHC used the heap for everything other than + and *. |
| 14:43:03 | <wsdo_okadr> | hi ndm |
| 14:43:06 | <wsdo_okadr> | ndm: nice to see you :) |
| 14:43:20 | <ndm> | roconnor: it has a separate stack (which is on the C heap) |
| 14:43:26 | <ndm> | hi wsdo_okadr - have we met? |
| 14:43:33 | <roconnor> | ndm: really? |
| 14:43:38 | <roconnor> | ndm: what gets pushed? |
| 14:43:44 | <kosmikus> | ndm: I see, thanks |
| 14:43:47 | <ndm> | roconnor: yes, parameters to functions |
| 14:44:11 | <roconnor> | ndm: really? |
| 14:44:15 | <ndm> | roconnor: really :) |
| 14:44:28 | <ndm> | (with about 85% confidence) |
| 14:44:37 | <roconnor> | I figured it would just change focus on a graph when ``entering'' a function |
| 14:44:52 | <ndm> | its not really a graph reduction machine at its heart |
| 14:44:55 | <roconnor> | I should go reread how a G-machine works. |
| 14:45:00 | <ndm> | by the time its been converted to CMM etc |
| 14:45:06 | <roconnor> | ndm: oh |
| 14:45:25 | <ndm> | its kinda graph reduction, but the actually gritty details don't look much like it by the end |
| 14:45:27 | <roconnor> | does CMM have a stack? |
| 14:45:42 | <quicksilver> | In general I don't think it will push a new parameter reference on the stack if there is still one reachable |
| 14:45:43 | <ndm> | yes, but GHC creates its own "stack" in the CMM heap |
| 14:45:49 | <quicksilver> | will means it has to do it 'sometimes' |
| 14:45:56 | <quicksilver> | but not always. I think. |
| 14:46:02 | <roconnor> | ndm: interesting |
| 14:46:17 | <roconnor> | ndm: can you make an example of a stack overflow without using primops? |
| 14:46:34 | <quicksilver> | foldl' (+) 0 [1..] |
| 14:46:44 | <roconnor> | isn't (+) a primop? |
| 14:46:44 | <quicksilver> | the fact that might use primops is not relevant |
| 14:46:49 | <quicksilver> | use Integer if you like |
| 14:46:52 | <quicksilver> | or a custom Num instance |
| 14:47:09 | <quicksilver> | it's a stack overflow however (+) is written |
| 14:47:18 | <quicksilver> | as long as (+) is strict in both parameters |
| 14:47:23 | <roconnor> | quicksilver: you are claiming that will give a stack overflow even on Data Nat = Zero | Succ Nat ? |
| 14:47:37 | <roconnor> | quicksilver: ah right, no primops and no seq. |
| 14:47:47 | <quicksilver> | "as long as (+) is strict in both parameters" |
| 14:47:48 | <roconnor> | even still, I'll try your example. |
| 14:47:52 | <quicksilver> | you don't need to use seq to be strict |
| 14:47:58 | <quicksilver> | some things just are strict... |
| 14:48:18 | <quicksilver> | actually (+) only needs to be strict on one side but I was too lazy to work out which |
| 14:48:24 | <quicksilver> | the point is, you build up an infinite thunk |
| 14:48:29 | <quicksilver> | and infinite thunks are a stack overflow |
| 14:48:43 | <wsdo_okadr> | ndm: yesterday |
| 14:49:07 | <wsdo_okadr> | wsdo_okadr: I read hughes article on FP and came here to talk about it |
| 14:50:17 | <ndm> | ah, i remember |
| 14:50:22 | <ndm> | under a different username? |
| 14:50:26 | <roconnor> | quicksilver: stack overflows, not heap overflows? |
| 14:51:31 | <quicksilver> | roconnor: yes |
| 14:51:40 | <quicksilver> | roconnor: infinite thunks are stack overflows |
| 14:59:40 | <Tac-Tics> | I imagine *thunk* is the sound a thunk actually makes when it gets evaluated in Haskell |
| 15:00:06 | <roconnor> | quicksilver: I get heap exhausted |
| 15:00:12 | <roconnor> | @paste |
| 15:00:13 | <lambdabot> | Haskell pastebin: http://hpaste.org/new |
| 15:00:45 | <hpaste> | roconnor pasted "attempt to stack overflow" at http://hpaste.org/3300 |
| 15:00:55 | <ndm> | LeCamarade: just finished reading your "C sucks" article |
| 15:01:10 | <hpaste> | roconnor annotated "attempt to stack overflow" with "Result: Heap exhausted" at http://hpaste.org/3300#a1 |
| 15:01:17 | <Saizan> | roconnor: i think you need foldr to stack overflow |
| 15:01:17 | <ndm> | i love the qwe123 quote :) |
| 15:01:26 | <Saizan> | > foldr (+) 0 [1..] |
| 15:01:29 | <lambdabot> | Exception: stack overflow |
| 15:02:09 | <roconnor> | Saizan: I get a screen full of Succs, and then the same heap exhausted error. |
| 15:02:21 | <fasta> | Can this cause a stack overflow? f x = maybe (return x) (\k -> f k) (foo x) |
| 15:02:22 | <roconnor> | Saizan: the goal is to generate a stack overflow without using a prim-op |
| 15:02:52 | <Saizan> | roconnor: ah well, define (+) to pattern match on the right |
| 15:03:06 | <quicksilver> | roconnor: but you have a lazy (+) |
| 15:03:08 | <fasta> | I am currently assuming that that runs in constant space. |
| 15:03:14 | <quicksilver> | I'm talking about a strict (+) |
| 15:03:15 | <roconnor> | Saizan: will foldr (flip (+)) work fo you? |
| 15:03:23 | <fasta> | (as an iterative recursive process) |
| 15:03:30 | <roconnor> | quicksilver: how would you like me to make it strict? |
| 15:03:42 | <quicksilver> | not use the peano numbers? |
| 15:03:56 | <quicksilver> | you seem to be drawing a fallacious link between strict and primops? |
| 15:04:05 | <Saizan> | roconnor: it should, still heap overflow? |
| 15:04:06 | <quicksilver> | ok, Int is strict, and Int has primops |
| 15:04:09 | <roconnor> | quicksilver: if I don't use peano numbers, I have to use a primop ... which is my point: only prim-ops cause stack overflows. |
| 15:04:10 | <quicksilver> | but that's not the point :) |
| 15:04:16 | <quicksilver> | no, that's not true |
| 15:04:25 | <quicksilver> | a type can be strict and not primop |
| 15:04:37 | <roconnor> | quicksilver: fine, how do I make it strict? |
| 15:05:11 | <roconnor> | and not use primops |
| 15:06:28 | <roconnor> | Saizan: foldr (flip (+)) still gives me a heap exhausted error. |
| 15:07:29 | <roconnor> | I don't see how to make any operatation strict without using either a primop or perhaps using DeepSeq. |
| 15:09:04 | <roconnor> | ah, got it! |
| 15:09:12 | <roconnor> | foldr (++) [] (repeat ([]::[()])) |
| 15:09:19 | <roconnor> | stack overflow! |
| 15:09:22 | <roconnor> | w00t |
| 15:09:25 | <roconnor> | > foldr (++) [] (repeat ([]::[()])) |
| 15:09:33 | <tibbe> | if B.pack "my constant string" appears somewhere in the middle of an expression will GHC hoist it to the top level as a true constant or will it recompute it every time? |
| 15:09:37 | <lambdabot> | Exception: <<loop>> |
| 15:09:45 | <tibbe> | or will laziness do the trick? |
| 15:09:47 | <roconnor> | WTF! |
| 15:10:08 | <roconnor> | :( |
| 15:10:19 | <quicksilver> | 'loop' is essentially a way that ghc can detect certain stack overflow conditions |
| 15:10:22 | <quicksilver> | among other things |
| 15:10:23 | <roconnor> | It gave me a stack overflow on GHC 6.6 |
| 15:10:27 | <quicksilver> | obviously it's not guaranteed |
| 15:10:41 | <roconnor> | (to be honest, I was excepting loop) |
| 15:10:46 | <Saizan> | lambdabot: uses -O2 |
| 15:11:13 | <Saizan> | ?src (++) |
| 15:11:13 | <quicksilver> | tibbe: in principle it will recompute it every time, but I have a feelig there is a rewrite rule for it |
| 15:11:13 | <lambdabot> | (++) [] ys = ys |
| 15:11:13 | <lambdabot> | (++) (x:xs) ys = x : xs ++ ys |
| 15:11:38 | <quicksilver> | tibbe: and because of the rewrite rule, it will only be computed once. Not sure though. |
| 15:11:39 | <tibbe> | quicksilver: ok, I guess I should just check the -dump-simpl |
| 15:11:56 | <roconnor> | -O2 on ghc 6.6 still gives me a stack overflow |
| 15:12:01 | <quicksilver> | roconnor: to answer your question "How do I make a (+) strict without primops" the answer is generally "use case" |
| 15:12:16 | <quicksilver> | roconnor: case is the primitive haskell concept which implements strictness |
| 15:12:22 | <roconnor> | quicksilver: I understand that, but that only puts it in head normal form. |
| 15:12:26 | <quicksilver> | right |
| 15:12:35 | <roconnor> | quicksilver: is that strict enough for you? |
| 15:12:39 | <quicksilver> | but if your type is shallow that is strict enough :) |
| 15:12:46 | <quicksilver> | and in this case, it was enough for [] |
| 15:12:53 | <quicksilver> | because of the the way you were using [] |
| 15:13:02 | <quicksilver> | which "wasn't very deep" |
| 15:13:28 | <roconnor> | anyhow, I'm moderately happy I got a stack overflow |
| 15:13:36 | <roconnor> | although I'm surprised I don't get loop |
| 15:13:44 | <roconnor> | and I'm suprised lambdabot does get loop |
| 15:13:50 | <Saizan> | ?version |
| 15:13:51 | <lambdabot> | lambdabot 4p548, GHC 6.6 (Linux i686 2.66GHz) |
| 15:13:52 | <lambdabot> | darcs get http://www.cse.unsw.edu.au/~dons/lambdabot |
| 15:15:38 | <quicksilver> | I have previously observed odd behaviour with LB |
| 15:15:47 | <quicksilver> | suggesting it might have some non-standard falgs |
| 15:16:28 | <roconnor> | indeed |
| 15:20:17 | <kosmikus> | bringert: thanks a lot for the mail :) looks great! |
| 15:20:59 | <bringert> | kosmikus: you're welcome! Thanks for the typesetting help. |
| 15:21:27 | <kosmikus> | bringert: no problem. good luck for the defense. |
| 15:22:34 | <bringert> | kosmikus: btw, don't you think the font looks a bit weird? I think the glyphs have uneven line width, but noone I've asked seems to be as picky as me. Also, some of the figures are a bit crappy, dot2tex doesn't work that great. |
| 15:23:34 | <swiert> | bringert: are you defending your thesis soon? |
| 15:23:45 | <bringert> | swiert: just my lic thesis |
| 15:23:53 | <kosmikus> | bringert: they look a bit weird, but I assumed that this was beyond your influence |
| 15:23:54 | <Igloo> | lic? |
| 15:24:01 | <swiert> | bringert: ah - ok. |
| 15:24:09 | <swiert> | best of luck though. |
| 15:24:29 | <SimonRC> | hmm |
| 15:24:39 | <SimonRC> | after reading some Haskell' stuff... |
| 15:24:41 | <swiert> | Igloo: licentiate thesis, I think. |
| 15:24:51 | <kosmikus> | bringert: looks a bit like the file has been generated with PS3 fonts at a specific resolution and then been scaled. |
| 15:25:12 | <SimonRC> | has a solution to the problem with MonadWriter and associated types been fixed? |
| 15:25:20 | <SimonRC> | *found |
| 15:25:53 | <SimonRC> | (there is nowhere to put the Monoid restriction in the associated types syntax) |
| 15:25:56 | <swiert> | Igloo: It's a milestone in a Swedish PhD after 2/3 years. |
| 15:26:35 | <Igloo> | Ah, OK, thanks |
| 15:27:51 | <bringert> | kosmikus: could it have anything to do with how I generted the PDF? I use T1 and lmodern, and pdflatex without any options. Or is it the printer who messed up? |
| 15:28:08 | <bringert> | Igloo: yeah, what swiert said |
| 15:28:37 | <kosmikus> | bringert: lmodern should be safe |
| 15:29:03 | <kosmikus> | are you printing A4 and scaling later? |
| 15:33:12 | <roconnor> | > foldr const () (repeat ()) |
| 15:33:14 | <lambdabot> | () |
| 15:33:31 | <roconnor> | > foldr (flip const) () (repeat ()) |
| 15:33:32 | <lambdabot> | Exception: <<loop>> |
| 15:34:27 | <roconnor> | :/ |
| 15:34:43 | <Tac-Tics> | > repeat () |
| 15:34:45 | <lambdabot> | [(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),... |
| 15:35:15 | <puusorsa> | this seems interesting, http://hpaste.org/3299 , could someone help me a bit in figuring out how to use it? :) |
| 15:35:17 | <wsdo_okadr> | > repeat ( repeat () ) |
| 15:35:19 | <lambdabot> | [[(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),()... |
| 15:35:34 | <wsdo_okadr> | > let a () |
| 15:35:34 | <lambdabot> | Parse error |
| 15:35:36 | <wsdo_okadr> | > let a = () |
| 15:35:36 | <lambdabot> | Parse error |
| 15:35:51 | <roconnor> | > let a = () in a |
| 15:35:53 | <lambdabot> | () |
| 15:35:57 | <wsdo_okadr> | roconnor: why in a ? |
| 15:35:59 | <puusorsa> | i thought mkFuture readLine would return something that could be fed to askFuture |
| 15:36:13 | <wsdo_okadr> | > let a = () in a; repeat (); |
| 15:36:13 | <lambdabot> | Parse error |
| 15:36:24 | <wsdo_okadr> | how can I write multiple lines ? |
| 15:36:29 | <wsdo_okadr> | for the lambdabot |
| 15:36:34 | <roconnor> | wsdo_okadr: let in declares local variables for some expression |
| 15:36:54 | <wsdo_okadr> | I want to write MULTIPLE LINES :) |
| 15:37:08 | <roconnor> | wsdo_okadr: lambdabot only accepts one expession. |
| 15:37:16 | <chessguy> | wsdo_okadr, the multiple lines you wrote don't make sense |
| 15:37:31 | <roconnor> | same way the top level print-eval-loop does. |
| 15:37:38 | <roconnor> | er |
| 15:37:40 | <roconnor> | bad example |
| 15:37:54 | <roconnor> | ACTION forgot about the other let expression |
| 15:38:05 | <roconnor> | wsdo_okadr: there are two let expressions in Haskell |
| 15:38:07 | <chessguy> | > let a = () in {a; repeat () } |
| 15:38:07 | <lambdabot> | Parse error |
| 15:38:15 | <quicksilver> | puusorsa: it does for some values of 'fed' |
| 15:38:19 | <chessguy> | > let a = () { a; repeat () } |
| 15:38:20 | <lambdabot> | Parse error |
| 15:38:29 | <roconnor> | wsdo_okadr: one let expression works on expression, the other let works inside do blocks. |
| 15:38:30 | <quicksilver> | puusorsa: you have to 'feed' it via >>= since they are monadic actions |
| 15:39:00 | <puusorsa> | oh of course silly me. thanks. |
| 15:39:10 | <roconnor> | GHCi's top level print-eval-loop is much like being inside a do expression |
| 15:39:27 | <roconnor> | so GHCi's lets at the prompt are the let's that go inside do |
| 15:39:41 | <roconnor> | however lambdabot does't work inside the IO monad |
| 15:39:59 | <roconnor> | so the let expression you give are the other kind. |
| 15:40:18 | <roconnor> | (except when you give lambdabot a let statement inside a do expression) |
| 15:40:26 | <bringert> | kosmikus: the pdf is A4 (http://www.cs.chalmers.se/~bringert/publ/lic/lic.pdf), and it think it's just cut to G5 (swedish paper size, 169 x 239 mm, often used for dissertations) |
| 15:40:34 | <bringert> | s/it/I/ |
| 15:41:03 | <roconnor> | but in that case lambda bot is given something like do { let a = (); return a} , with an explicit do. |
| 15:42:38 | <kosmikus> | bringert: so it's cut, but not scaled? then I have no idea what went wrong. so if you print the file on your own printer, it also looks like that? |
| 15:43:00 | <bringert> | kosmikus: no, as far as I remember |
| 15:44:36 | <shapr> | @quote |
| 15:44:36 | <lambdabot> | spj says: it looks like hopscotch! (referring to a funny notation for lists) |
| 15:44:38 | <shapr> | w00! |
| 15:44:39 | <bringert> | kosmikus: even if it was scaled down, why would it look like that, unless they use some very crappy scaling or scale by a large factor? |
| 15:44:41 | <shapr> | @quote bringert |
| 15:44:42 | <lambdabot> | bringert says: psicho: so you are saying that your teacher gave you two days to do an assignment in a language you didn't know? |
| 15:45:24 | <kosmikus> | bringert: crappy scaling would be enough, even by a small factor |
| 15:45:35 | <shapr> | Sounds quotable |
| 15:46:23 | <kosmikus> | shapr: what are you doing these days? |
| 15:46:50 | <shapr> | kosmikus: Hacking on HAppS, trying to get back into the Haskell community, considering getting a CS degree. What about you? |
| 15:46:53 | <bringert> | kosmikus: ok, thanks. I'll have someone else print my phd thesis. |
| 15:47:04 | <dons> | ?yow! |
| 15:47:04 | <lambdabot> | Can you MAIL a BEAN CAKE? |
| 15:47:14 | <bringert> | shapr: when are you moving back to sweden? |
| 15:47:38 | <bringert> | hey dons, did you say that you have a small http implemenation we could embed in cabal-install? |
| 15:47:40 | <shapr> | bringert: I'm not. Min flickvänn har slutat vår relation. |
| 15:47:50 | <bringert> | shapr: crap |
| 15:47:53 | <dons> | bringert: ah yes. i do. |
| 15:48:04 | <exDM69> | I was reading YAHT last night, and I almost figured out how the IO monad works. |
| 15:48:12 | <shapr> | bringert: Yeah, that happened a month ago, and I'm still recovering. |
| 15:48:12 | <dons> | its in the link checker i uploaded to hackage a few months ago |
| 15:48:20 | <dons> | exDM69: sweet :) |
| 15:48:27 | <exDM69> | I still didn't quite get what do's and sequencing was about, but I guess I'll figure it out if I try it |
| 15:48:27 | <dons> | welcome! |
| 15:48:30 | <bringert> | shapr: how is it doing? |
| 15:48:36 | <shapr> | ACTION shrugs |
| 15:48:41 | <dons> | ?undo do x <- getChar ; y <- getChar ; print (x,y) |
| 15:48:41 | <lambdabot> | (getChar >>= \ x -> getChar >>= \ y -> print (x, y)) |
| 15:48:52 | <kosmikus> | bringert: so you don't have the university print it for you? |
| 15:48:55 | <dons> | >>= sequences things by gluing them in a lovely dependency order |
| 15:49:10 | <exDM69> | I just don't have an intresting idea for a Haskell project. (or in fact, any project) |
| 15:49:17 | <kosmikus> | shapr: sounds good. I'm back in Utrecht, have you heard? |
| 15:49:21 | <shapr> | No, I didn't know that! |
| 15:49:27 | <dons> | exDM69: you could contribute to an existing project, perhaps? |
| 15:49:32 | <dons> | seen xmonad, for example? |
| 15:49:33 | <shapr> | Are you there for the long term? |
| 15:49:37 | <dons> | lots of space there to add code |
| 15:49:40 | <exDM69> | dons: I don't think I have the skills yet |
| 15:49:56 | <kosmikus> | shapr: I have a position for 5 years. Let's see what happens. |
| 15:49:56 | <dons> | you never know till you try :) |
| 15:50:01 | <exDM69> | dons: and Xmonad is not exactly my brand of vodka |
| 15:50:09 | <dons> | if you're looking for small tasks, you could try the 99 haskell questions quiz on the wiki |
| 15:50:09 | <shapr> | dons: Looking at the people locations for AmeroHaskell, the most central location appears to be Portland, think we could find a venue? |
| 15:50:12 | <exDM69> | dons: I was thinking of writing a card game |
| 15:50:18 | <dons> | shapr: definitely |
| 15:50:21 | <dons> | shapr: PSU could do it |
| 15:50:26 | <exDM69> | dons: there is this one card game that has particularly intresting algorithms |
| 15:50:27 | <kosmikus> | dons, exDM69: then let's write Xapplicativefunctor ;) |
| 15:50:33 | <dons> | kosmikus: :) |
| 15:50:37 | <dons> | conal would love that |
| 15:50:45 | <dons> | kosmikus: actually, i'm looking to move more code out of the X monad |
| 15:50:58 | <dons> | user code, for example, should run in a very constrained Reader environment |
| 15:51:29 | <kosmikus> | dons: sounds good; so that users cannot easily mess up everything? |
| 15:51:34 | <dons> | right |
| 15:51:41 | <dons> | we don't really want them calling into the X server |
| 15:51:45 | <shapr> | dons: Ok, sounds like a plan. |
| 15:51:46 | <dons> | or messing up the core's internal state |
| 15:51:53 | <kosmikus> | dons: oh, you've released 0.4, right? |
| 15:51:53 | <exDM69> | dons: hey, nice. I'll try to check out the wiki. |
| 15:51:55 | <dons> | shapr: ok, let's set up a mailing list to sort this out |
| 15:51:58 | <dons> | kosmikus: later today |
| 15:52:00 | <kosmikus> | ACTION should probably upgrade again |
| 15:52:01 | <dons> | the release candidate is out |
| 15:52:08 | <kosmikus> | what's new? |
| 15:52:30 | <dons> | rules, so that you can set behaviour for particular clients: e.g. gimp always floats, or mplayer goes on workspace 2 |
| 15:52:32 | <quicksilver> | shapr: that's got to be a weird distribution to make portland central? |
| 15:52:40 | <dons> | hmm, a gazillion new extensions. gnome support |
| 15:52:43 | <quicksilver> | shapr: lots of developers in alaska shifting the centre of gravity that way? |
| 15:52:50 | <kosmikus> | dons: great. |
| 15:53:01 | <kosmikus> | but actually, I don't really find much I'd want from xmonad. |
| 15:53:07 | <kosmikus> | it just works. |
| 15:53:13 | <dons> | yeah, that's good to know |
| 15:53:18 | <shapr> | quicksilver: Mostly that Oregon and California have the most Haskellers. There's roughly ten Haskellers outside of OR & CA. |
| 15:54:11 | <dons> | shapr: if you can set up a list, i can start looking for local interest |
| 15:54:17 | <kosmikus> | oh, it's HCAR time again. |
| 15:54:20 | <shapr> | dons: Awright |
| 15:54:21 | <dons> | also, portland's close enough to .ca we might attract Cale down :) |
| 15:54:26 | <shapr> | Yeah, that would be cool :-) |
| 15:54:28 | <kosmikus> | ACTION makes a note to send out a call for contributions. |
| 15:54:42 | <dons> | kosmikus: scary. i can't imagine how we can keep track of everything new any more |
| 15:54:49 | <kosmikus> | dons: hehe |
| 15:55:01 | <kosmikus> | all the more important to have a report on it ;) |
| 15:55:01 | <dons> | i can send you the weekly news announcements since the last hcar, if you like |
| 15:55:10 | <kosmikus> | maybe |
| 15:55:19 | <kosmikus> | I'll first look through my own archives |
| 15:55:22 | <dons> | yep |
| 15:55:37 | <kosmikus> | oh, btw, I'm looking for a new editor :) |
| 15:55:42 | <kosmikus> | this will be the last HCAR I do |
| 15:55:56 | <ndm> | kosmikus: again? seems very recently the last one went round... |
| 15:56:06 | <kosmikus> | ndm: 6 months |
| 15:56:11 | <kosmikus> | it's always been like that |
| 15:56:13 | <ndm> | yeah, doesn't feel like it! |
| 15:56:19 | <dons> | been a busy 6 months |
| 15:56:25 | <kosmikus> | May and November |
| 15:56:28 | <ndm> | indeed |
| 15:56:37 | <ndm> | haven't been home for the last month, pretty much |
| 15:56:46 | <dons> | ACTION off to work to hammer out some more lambdas |
| 15:56:48 | <kosmikus> | so, if you guys know anyone who might be interested/suitable for becoming HCAR editor, please tell me |
| 15:57:08 | <LeCamarade> | dons: Wait! |
| 15:57:09 | <shapr> | dons: I'll mail you about the list |
| 15:57:15 | <dons> | LeCamarade: quick! |
| 15:57:15 | <kosmikus> | I'll send out an announcement together with the release of this HCAR that I'm going to step down |
| 15:57:23 | <dons> | kosmikus: hmm, i'll see if i can think of someone |
| 15:57:26 | <LeCamarade> | See? Damn Galois! Dem a go take away our channel friends! |
| 15:57:29 | <LeCamarade> | :o( |
| 15:57:37 | <kosmikus> | it would be a shame if it wouldn't be continued though, I think |
| 15:57:45 | <dons> | kosmikus: need to identify some promising phd student with a few years available |
| 15:57:48 | <LeCamarade> | dons: Just wanted to congratulate you on the talk - it was a concert! |
| 15:57:52 | <LeCamarade> | :o) |
| 15:57:56 | <dons> | hah :) |
| 15:57:57 | <dons> | thanks. |
| 15:58:00 | <exDM69> | dons: http://www.korttipelit.net/Kasino_in_English.htm <<-- this is the one I thaught of doing in Haskell |
| 15:58:03 | <lambdabot> | Title: Kasino |
| 15:58:03 | <kosmikus> | dons: yes, a PhD student would be good. |
| 15:58:06 | <shapr> | LeCamarade: They also fund our channel friends. It'd suck if they all had to start writing Java for a living. |
| 15:58:16 | <LeCamarade> | We should draw up tour dates for the Lambda band. SPJ and the Wailer. |
| 15:58:30 | <shapr> | SPJ and the Redexes? |
| 15:58:34 | <dons> | kosmikus: there's a bunch of guys at chalmers. and some new guys at utrecth (alexey perhaps?) |
| 15:58:41 | <dons> | kosmikus: people who came to the hackathon might be possibles.. |
| 15:59:00 | <kosmikus> | dons: yes, you can be sure that I'll ask around here in Utrecht. |
| 15:59:06 | <dons> | :) |
| 15:59:07 | <LeCamarade> | dons: But why do you people say IPI instead of API? :o) |
| 15:59:09 | <byorgey> | hm, I don't think Cale's particular slice of .ca is very close to Portland =) |
| 15:59:21 | <LeCamarade> | Okay. You're pardoned. You may rise. |
| 15:59:22 | <dons> | LeCamarade: :P I don't! your ears are broken, mate. |
| 15:59:32 | <LeCamarade> | That came out as mite! |
| 15:59:38 | <LeCamarade> | `mite' |
| 15:59:40 | <dons> | streuth |
| 15:59:48 | <LeCamarade> | pweaver. Another Galois guy. |
| 15:59:56 | <kosmikus> | ACTION & |
| 16:00:00 | <dons> | oh, huh. phil's here. cool |
| 16:00:13 | <dons> | you should all say hi next time -- he's super interesting. |
| 16:00:16 | <exDM69> | btw, how should I do random shuffling for a list (or array) in Haskell? |
| 16:00:19 | <shapr> | @seen pweaver |
| 16:00:19 | <lambdabot> | I saw pweaver leaving #haskell 36s ago, and . |
| 16:00:33 | <shapr> | hi pweaver! I hear you're interesting. |
| 16:00:39 | <dons> | exDM69: there's a new wiki article on haskell.org about random shuffling |
| 16:00:47 | <dons> | exDM69: check the 'Recent changes' page from the front page |
| 16:00:54 | <dons> | hey pweaver :) |
| 16:00:57 | <pweaver> | ? |
| 16:01:00 | <dons> | how's the serial port hacking going? |
| 16:01:11 | <pweaver> | how do people know about me, has dons been talking |
| 16:01:17 | <dons> | sssh1 |
| 16:01:23 | <LeCamarade> | pweaver: We've been told everything about you, we are dying to hear your side of the story. Is it true you speak in Haskell, and need an interpreter? |
| 16:01:37 | <exDM69> | dons: thanks, I'll check it out |
| 16:01:38 | <pweaver> | it's going well, the new guy Joel found a Haskell module for serial interface for Win32 |
| 16:01:49 | <dons> | sweet. |
| 16:01:52 | <pweaver> | ... |
| 16:01:52 | <dons> | we should bundle that up nicely |
| 16:01:56 | <shapr> | pweaver: Did you do reflective metaprogramming stuff for Rosetta? |
| 16:01:58 | <dons> | since it keeps coming up on the mailing lists |
| 16:02:01 | <LeCamarade> | ACTION & |
| 16:02:03 | <pweaver> | i think i did :) |
| 16:02:06 | <dons> | shapr: yeah, i think so. |
| 16:02:21 | <dons> | pweaver: do you have a link for that composable monadic semantics magic stuff handy |
| 16:02:26 | <exDM69> | 0.o, haskell.org is down |
| 16:02:29 | <dons> | some people here would love to poke around in that, i suspect |
| 16:02:45 | <shapr> | pweaver: That's nifty. |
| 16:02:51 | <dons> | exDM69: huh, just went down it seems.might be back up soonish |
| 16:03:45 | <pweaver> | hmm... i'm not sure |
| 16:03:49 | <Igloo> | It's not down, just very slow |
| 16:03:54 | <Igloo> | Are we being dotted again? |
| 16:04:02 | <dons> | hmm, not that i'm aware of |
| 16:04:09 | <pweaver> | it was only published a week or two ago |
| 16:04:25 | <pweaver> | there's supposed to be an October release of the code |
| 16:04:43 | <shapr> | Haskelldotted! |
| 16:04:59 | <Igloo> | LA is 130 |
| 16:05:51 | <shapr> | ? |
| 16:05:52 | <shapr> | oh |
| 16:06:44 | <pweaver> | ... either dons is invisible at his desk or is chatting from home |
| 16:06:53 | <pweaver> | or i'm not looking at the right desk |
| 16:08:05 | <dons> | i'm at home :) getting some furniture delivered today to our new apartment |
| 16:08:19 | <pweaver> | ah, cool |
| 16:08:23 | <dons> | Igloo: hmm? |
| 16:08:58 | <Igloo> | "hmm?"? |
| 16:09:16 | <dons> | ah, 130 or 1.30? |
| 16:09:21 | <Igloo> | 130 |
| 16:09:23 | <dons> | load avg? |
| 16:09:26 | <Igloo> | Yup |
| 16:09:28 | <dons> | crap |
| 16:09:51 | <Igloo> | It's fallen to 90 now, so whatever it was might be over |
| 16:10:37 | <bringert> | dons: I had a quick look at that yesterday, I can't see that it gets the body |
| 16:11:04 | <bringert> | dons: but that should be easy to fix |
| 16:11:40 | <bringert> | dons: I guess it could get the body straight to a file |
| 16:12:53 | <dons> | bringert: yeah, it should be easy enough to hack up , to avoid that dependency |
| 16:13:04 | <dons> | and maybe do it in bytestrings at the same time |
| 16:14:06 | <Igloo> | There's no obvious guily page, other than the front page |
| 16:14:28 | <apfelmus> | hi :) |
| 16:14:37 | <apfelmus> | i'm looking for file system semantics |
| 16:14:59 | <apfelmus> | but i'm stumbling in the dark currently |
| 16:15:35 | <shapr> | apfelmus: Did you see Simon Marlow's email about how getContents only works if the file system also has pure FP semantics? |
| 16:15:52 | <Mortez> | omg, how can I resolve ambiguous (-) when trying to make a type an instance of class Num :S I need (-) operator for the fields, but ghci will not understand what I want :( |
| 16:16:14 | <shapr> | apfelmus: It's several months old, but the summary is that lazy file reading only works if the contents of the file do not change between reads. |
| 16:16:21 | <hpaste> | BoudewijnE pasted "SIRDS problem" at http://hpaste.org/3302 |
| 16:16:30 | <boudewijne> | can someone help me on an image-generation problem? |
| 16:16:39 | <boudewijne> | I can create images using the code on hpaste |
| 16:16:52 | <apfelmus> | shapr: no, i didn't see it. link? |
| 16:16:52 | <boudewijne> | but they have a 'line' through them |
| 16:17:49 | <shapr> | apfelmus: http://permalink.gmane.org/gmane.comp.lang.haskell.libraries/4759 & http://permalink.gmane.org/gmane.comp.lang.haskell.libraries/4761 |
| 16:17:50 | <lambdabot> | Title: gmane.comp.lang.haskell.libraries |
| 16:18:01 | <Dybber> | Why is maximum not tail-recursive? I get stack overflow when finding maximum of a list with 1 mio items |
| 16:18:09 | <shapr> | apfelmus: It was on my blog, but my blog does not exist anymore. |
| 16:18:18 | <apfelmus> | :'( |
| 16:18:44 | <shapr> | I'll make a new blog when HAppS-Begin is usable for that purpose. |
| 16:19:06 | <Igloo> | :-) |
| 16:19:15 | <Dybber> | >maximum [1..1000000] |
| 16:19:28 | <apfelmus> | actually, i was more interested in the usual POSIX semantics |
| 16:19:41 | <apfelmus> | how to do atomic file write and stuff? |
| 16:19:51 | <boudewijne> | can someone please help me? |
| 16:19:54 | <shapr> | apfelmus: Have you seen http://www.haskell.org/halfs/ ? |
| 16:19:54 | <lambdabot> | Title: Halfs, A Haskell Filesystem |
| 16:20:05 | <shapr> | @where halfs |
| 16:20:05 | <lambdabot> | http://www.haskell.org/halfs |
| 16:20:46 | <byorgey> | Mortez: maybe paste the code you are having trouble with on hpaste? |
| 16:20:47 | <pgavin> | @src Bounded |
| 16:20:47 | <lambdabot> | class Bounded a where |
| 16:20:47 | <lambdabot> | minBound, maxBound :: a |
| 16:21:06 | <byorgey> | Dybber: the problem isn't that maximum isn't tail recursive, it's that it isn't strict enough. |
| 16:21:48 | <byorgey> | Dybber: use foldl1' max instead. |
| 16:21:50 | <dons> | Igloo: i note the page count for the front page has jumped by about 10k since yesterday |
| 16:21:58 | <byorgey> | > maximum [1..1000000] |
| 16:22:00 | <lambdabot> | 1000000 |
| 16:22:00 | <dons> | its over the 900k mark now |
| 16:22:10 | <byorgey> | well, that works anyway since lambdabot uses -O2. |
| 16:22:37 | <byorgey> | > foldl1' max [1..1000000] |
| 16:22:39 | <lambdabot> | 1000000 |
| 16:22:57 | <Igloo> | dons: Do you know if that's faster than normal? |
| 16:22:58 | <dons> | apfelmus: seen Oleg's zipper file system paper? |
| 16:23:00 | <Dybber> | byorgey, what do you mean that it "isnt strict enough"? |
| 16:23:12 | <dons> | Igloo: yes, way faster. typically we see 1-2k per day on the front page |
| 16:23:27 | <apfelmus> | ACTION saw it all ;) |
| 16:23:30 | <dons> | i suspect a lot of that 10k came in the past hour, since i don't recall it being over 900k earlier |
| 16:23:37 | <shapr> | Sounds it'd be interesting to see the referrers for the past 24 hours. |
| 16:23:54 | <Igloo> | dons: The only easy fix I have is to make it static. It would be great if someone could look properly at making the wiki more resilient to lots of hits |
| 16:24:02 | <apfelmus> | i mean, i'm not (yet) looking for a new fp-filesystem |
| 16:24:08 | <dons> | hmm, the front page really could be static |
| 16:24:10 | <fasta> | I get the stack overflow during unsafeFreeze |
| 16:24:21 | <fasta> | I thought that was a noop. |
| 16:24:22 | <apfelmus> | just how exactly the "normal" filesystem on my box handles concurrency |
| 16:24:29 | <Dybber> | I thought the stack exception was because of to many recursive calls |
| 16:24:40 | <Igloo> | dons: It has the events and news on |
| 16:24:50 | <dons> | Igloo: but those are static |
| 16:24:54 | <quicksilver> | Igloo: there are well-known solutions to that sort of thing |
| 16:24:57 | <dons> | you have to 'flush' to get the front page regenerated |
| 16:25:01 | <Igloo> | And it would also look like you weren't logged in |
| 16:25:12 | <apfelmus> | are files locked when two processes try to read them? to write them? |
| 16:25:13 | <quicksilver> | Igloo: mostly they involve putting a mostly-transparent proxy in front |
| 16:25:16 | <byorgey> | Dybber: the important point is that Haskell is lazy, i.e. expressions do not have to be evaluated until their results are needed. |
| 16:25:18 | <Igloo> | quicksilver: I know, but we need someone to find a good one and apply it to haskell.org's wiki |
| 16:25:29 | <quicksilver> | apfelmus: on unix-style systems, there is no locking by default |
| 16:25:39 | <quicksilver> | apfelmus: on win32-style systems, there is crude pessimistic locking by default |
| 16:26:08 | <byorgey> | Dybber: so, a call like maximum [1..1000000] might end up as the (yet unevaluated) expression, max 1 (max 2 (max 3 (max 4 ... |
| 16:26:27 | <apfelmus> | quicksilver: so, it's nondeterministic on unix? |
| 16:26:27 | <byorgey> | Dybber: then, when the result is finally needed, that huge expression will be evaluated, which will cause a stack overflow. |
| 16:26:36 | <Dybber> | foldr1 max [1..1000000] is also giving stack overflow. My own tail recursive version doesn't |
| 16:26:42 | <Igloo> | The Haskell98 file operations impose single-writer-or-multiple-reader locks, IIRC |
| 16:26:45 | <Dybber> | byorgey, ok |
| 16:26:54 | <quicksilver> | apfelmus: in some sense, yes. The affect of two proceses concurrently modifying the same file is subject to the whims of the kernel scheduler |
| 16:26:59 | <Igloo> | s/operations/functions/ |
| 16:27:17 | <quicksilver> | apfelmus: in practice however this is a very useful thing to be able to do, and processes choose whatever locking discipline suits them best |
| 16:27:23 | <byorgey> | Dybber: it's possible that your own version doesn't overflow not because it is tail recursive per se, but because the compiler was able to figure out some optimization that it couldn't with maximum. |
| 16:27:37 | <byorgey> | Dybber: tail recursion is much less important in a lazy language like Haskell. |
| 16:27:47 | <fasta> | Can unsafeFreeze handle negative indices? |
| 16:27:50 | <Igloo> | dons: Where is the hit counter? |
| 16:27:56 | <byorgey> | Dybber: I'd point you to an excellent page discussing this and related issues on the wiki, but it appears to be very slow at the moment... |
| 16:28:05 | <apfelmus> | quicksilver: ah. so, there is a separate mechanism for locking files? (i'm a unix n00b) |
| 16:28:24 | <dons> | Igloo: when you're logged in, there's one at the bottom of each page (in my style, anyway), and on the special pages |
| 16:28:30 | <dons> | click on 'popularity' |
| 16:29:11 | <Tac-Tics> | byorgey: why is tail recursion less important? |
| 16:29:19 | <Dybber> | byorgey, ok thanks, i dont really know how the lazyness is implemented, could be fun to look into. |
| 16:29:43 | <Igloo> | ACTION logs in, but finds no counter or popularity |
| 16:30:22 | <dons> | Igloo: hmm, maybe its only in text mode browsers.. ? |
| 16:30:24 | <bringert> | dons: would you have time to hack cabal-install to use your http module? |
| 16:30:32 | <apfelmus> | quicksilver: i mean, i basically ponder the implementation of a wiki with flat files storage and want to get the concurrency right. |
| 16:30:38 | <Igloo> | Ah, it's just not in the default skin |
| 16:30:43 | <dons> | bringert: possibly, during this week |
| 16:30:46 | <dons> | Igloo: ah yes |
| 16:31:01 | <dons> | Igloo: http://haskell.org/haskellwiki/Special:Popularpages |
| 16:31:02 | <lambdabot> | Title: Popular pages - HaskellWiki |
| 16:31:28 | <hpaste> | Mortez pasted "Help on resolving ambiguity.." at http://hpaste.org/3303 |
| 16:31:35 | <Igloo> | dons: Ah, is there a Popularinthelast24hours? |
| 16:31:53 | <bringert> | dons: great. I'm using my minial spare time to work on various other parts, like installing local packages, install directories and verbosity |
| 16:31:54 | <Igloo> | Or 1 hour, or anything? |
| 16:32:09 | <dons> | bringert: yeah, verbosity is one thing. |
| 16:32:24 | <byorgey> | Tac-Tics: for several reasons. First of all, even with a tail-recursive function you can still get stack overflows due to too much laziness. |
| 16:32:26 | <dons> | so i might look at the http stuff |
| 16:32:39 | <dons> | Igloo: not that i know of, but maybe someone else is more familiar with mediawiki admin |
| 16:32:51 | <dons> | Igloo: glguy might know, if he logs in soon |
| 16:33:04 | <Igloo> | OK, ta |
| 16:33:15 | <Igloo> | Anyway, I have http://www.haskell.org/static/Haskell.html ready if we have problems again |
| 16:33:15 | <lambdabot> | Title: Haskell - HaskellWiki |
| 16:33:20 | <byorgey> | Tac-Tics: and from the other angle, sometimes laziness creates opportunities for efficiency even in non-tail-recursive functions that would be inefficient in a strict language. |
| 16:33:22 | <bringert> | dons: 'cabal install' can now install the package in the current dir btw, like your cbi |
| 16:33:26 | <quicksilver> | apfelmus: if everything that accesses the file is using haskell, I believe you may be safe already |
| 16:33:27 | <dons> | cool |
| 16:33:32 | <byorgey> | Tac-Tics: although I can't think of an example off the top of my head. |
| 16:33:45 | <apfelmus> | quicksilver: oh? |
| 16:33:51 | <ddarius> | byorgey: concat |
| 16:33:52 | <bringert> | dons: it doesn't install in /usr/local even with --global, but I'm fixing that now |
| 16:33:59 | <ddarius> | byorgey: In fact any usage of foldr |
| 16:34:15 | <dons> | bringert: ah right, but --user should use --prefix=$HOME by default? |
| 16:34:22 | <dons> | (that's an faq on #xmonad) |
| 16:34:54 | <byorgey> | ddarius: oh right, thanks |
| 16:35:04 | <bringert> | dons: it uses $HOME/.cabal now |
| 16:35:10 | <ddarius> | ACTION wonders how dons got 'an'; 'an' eff ay que ? |
| 16:35:11 | <apfelmus> | quicksilver: ah, "Implementations should enforce as far as possible, at least locally to the Haskell process, multiple-reader single-writer locking on files" |
| 16:35:17 | <byorgey> | Dybber: here's the page I was referring to, I think you'll probably find it enlightening: http://www.haskell.org/haskellwiki/Stack_overflow |
| 16:35:18 | <lambdabot> | Title: Stack overflow - HaskellWiki |
| 16:35:31 | <apfelmus> | quicksilver: what about several Haskell processes? |
| 16:35:47 | <dons> | bringert: right, cool. |
| 16:36:09 | <Choko_> | is there some nice fast way of computing ``n! mod h'' ? |
| 16:36:11 | <Dybber> | byorgey, thanks I will read that |
| 16:36:29 | <dons> | ddarius: faq = "eff ae queue" :) |
| 16:37:13 | <Mortez> | byorgey: http://hpaste.org/3303 haskell just owns me :/ |
| 16:37:31 | <quicksilver> | apfelmus: then I suspect you should do your own locking |
| 16:38:27 | <apfelmus> | yeah, i suppose. i don't know how, though, i know next to nothing about posix file operations |
| 16:39:03 | <quicksilver> | I'd be inclined to have a single long-running haskell server |
| 16:39:18 | <quicksilver> | and have the "CGI-scripts" access mediated via the single server |
| 16:39:24 | <quicksilver> | using sockets, I suppose |
| 16:39:35 | <quicksilver> | maybe that's more heavy-weight than you want :( |
| 16:40:13 | <apfelmus> | i think so :( |
| 16:40:43 | <apfelmus> | isn't there a posix function that somehow locks stuff? |
| 16:41:35 | <ibid> | there's advisory locking and (optional) mandatory locking |
| 16:41:36 | <apfelmus> | i mean, the ideal thing would be STM for the file system |
| 16:41:52 | <apfelmus> | ibid: what's that? |
| 16:41:54 | <ddarius> | ACTION tends to pronounce it 'fack' |
| 16:42:10 | <ibid> | in flock(2) and fcntl(2) |
| 16:42:18 | <ibid> | apfelmus: what's which? |
| 16:42:53 | <ibid> | fctntl F_GETLK F_SETLK and F_SETLKW are advisory locking |
| 16:43:33 | <ibid> | ah, could also be mandatory locking if the kernel and the file system support it |
| 16:43:34 | <kolmodin> | I'm a lambdabot and I'm ok, I hack all night and I surf all day! |
| 16:44:09 | <apfelmus> | ibid: is there any online text/tutorial about that besides the man pages? |
| 16:44:15 | <dons> | kolmodin: :) |
| 16:44:22 | <hpaste> | fasta pasted "Stack overflow minimal case" at http://hpaste.org/3304 |
| 16:44:24 | <ibid> | apfelmus: probably. use google :) |
| 16:44:25 | <quicksilver> | a good book on unix systems programming would cover it |
| 16:44:32 | <ibid> | but flock/fcntl locking isn't reliable if you have to support all read-world scenarios |
| 16:44:44 | <kolmodin> | :) |
| 16:44:47 | <quicksilver> | ibid: it's fine if you can assume that only your processses access it |
| 16:44:50 | <fasta> | I create an array with about one million elements; any modern computer should be able to do that. |
| 16:44:59 | <kolmodin> | dons: did my patch work for you on 64bits? |
| 16:45:02 | <quicksilver> | ibid: or, you don't care too badly if some other process screws it up |
| 16:45:09 | <dons> | kolmodin: getting to it. but seems like the right thing |
| 16:45:15 | <ibid> | quicksilver: that's assuming the filesystem implements it |
| 16:45:26 | <kolmodin> | aye. it's what Tim said, but his patch didn't apply any more |
| 16:45:27 | <ibid> | quicksilver: some NFS filesystems, iirc, disregard it completely |
| 16:45:42 | <quicksilver> | hmm that rings a bell |
| 16:45:46 | <kolmodin> | ?localtime dons |
| 16:45:46 | <quicksilver> | but I'm not sure you're right |
| 16:45:48 | <lambdabot> | Local time for dons is Mon Oct 15 09:45:46 2007 |
| 16:45:51 | <kolmodin> | oo :) |
| 16:45:56 | <quicksilver> | I think they disregard it w.r.t. other clients machines |
| 16:46:08 | <quicksilver> | but for two clients on the same physical machine, it works? |
| 16:46:30 | <quicksilver> | (that is, worst case. Good NFS servers get it right even in the hard case) |
| 16:46:44 | <ibid> | quicksilver: possible |
| 16:47:02 | <ibid> | quicksilver: as i said, if you have to support all real-world scenarios :) |
| 16:48:30 | <fasta> | Why doesn't this work? http://hpaste.org/3304 |
| 16:48:36 | <apfelmus> | hm, now i'm scanning google results for an online unix systems tutorial ... |
| 16:49:07 | <apfelmus> | but i just want STM for files. no brain damage, just atomic $ readFile a >>= writeFile b |
| 16:50:21 | <ibid> | apfelmus: you want a transactional file system. there aren't any for unix, as far as i know |
| 16:50:34 | <ibid> | apfelmus: unless you count database engines |
| 16:50:41 | <apfelmus> | that would be fine if i could implement it myself |
| 16:51:02 | <apfelmus> | i mean, the database engines have to do it in some way, too |
| 16:51:26 | <osfameron> | would that be hard to implement efficiently? |
| 16:51:54 | <osfameron> | I mean, would you end up storing a lot of swap files and so on with uncommitted changes? The design must be quite interesting. |
| 16:52:01 | <apfelmus> | i.e. i'm fine with a directory that only my Haskell code can read/write to |
| 16:52:27 | <astrolabe> | fasta: which compiler? |
| 16:52:31 | <fasta> | astrolabe: GHC |
| 16:53:02 | <astrolabe> | fasta: My only guess is that you could increase the stacksize of the run time system. |
| 16:53:14 | <ibid> | osfameron: basically, it's a journaling filesystem done with some care and with a transaction API attached |
| 16:53:19 | <apfelmus> | osfameron: well, i hope i could get away with making STF an applicative functor instead of a full monad |
| 16:53:32 | <fasta> | astrolabe: I don't understand why it would use a lot of stack in the first place. |
| 16:54:14 | <ibid> | osfameron: the basic idea is that all data is written in an append-only journal, and you build (disposable) indexes to speed up access |
| 16:54:21 | <astrolabe> | fasta: The default memory grabbed by the RTS is pretty small if I recall correctly. |
| 16:54:30 | <fasta> | astrolabe: 16MB, IIRC |
| 16:55:01 | <osfameron> | ibid: a bit like a piece table but done at the filesystem basis? |
| 16:55:01 | <bos> | you can easily push that way down. i've run with an initial heap size of 256KB. |
| 16:55:12 | <ibid> | osfameron: no idea what a piece table is |
| 16:55:19 | <fasta> | bos: Why doesn't this work? http://hpaste.org/3304 |
| 16:55:31 | <fasta> | bos: that's the problem we are talking about |
| 16:56:01 | <astrolabe> | fasta: Isn't that small? How much room does a Maybe Int take? |
| 16:56:14 | <osfameron> | ibid: it's a way of storing text for a text-editor or similar structure. You keep a list of all the "pieces" of text, as indices against a) the original text buffer and b) an appendable buffer of "new" text (insertions/modifications or appends) |
| 16:56:38 | <ibid> | osfameron: sounds similar |
| 16:56:41 | <fasta> | astrolabe: I don't know exact numbers but it's less than 20 bytes, I think. |
| 16:57:05 | <fasta> | astrolabe: but there's no need to have more than a constant number of elements on the stack |
| 16:57:59 | <ibid> | osfameron: the log basically contains "inode 634 block 4200 was xyz now it is foo, changed by process quux" entries |
| 16:58:33 | <fasta> | Maybe I can reimplement newArray |
| 16:58:38 | <ibid> | osfameron: so it's an undo list, only it's authoritative |
| 16:58:51 | <osfameron> | ibid: sounds interesting, I'll have to read up on it. |
| 16:58:58 | <osfameron> | "authoritative" in what sense ? |
| 17:00:22 | <ibid> | osfameron: think a text editor. you have the editor buffer and you have an undo list. the authoritative version of the data is the edit buffer, and the undo list is just to support the undo feature. in a jornalling design, the editor buffer is just a cache, and the authoritative version of the data is what you can piece together by running through the journal (the undo list) |
| 17:01:08 | <osfameron> | ah ok. Very like a piece table/enfilade. |
| 17:01:12 | <ibid> | osfameron: authoritative in the sense that if it's out of sync with your buffer, it's the buffer that gets thrown out and not the journal |
| 17:01:34 | <ibid> | osfameron: enfilade, the xanadu concept? |
| 17:01:35 | <osfameron> | ibid: I'll read up ta. (Heading off now though... I shouldn't get involved in interesting things at end of day...) |
| 17:01:41 | <osfameron> | see yas |
| 17:01:45 | <ibid> | osfameron: i know that one :) and it's similar yes |
| 17:02:06 | <osfameron> | ibid: yeah, enfilads rock (they're basically like the piece table but with a balanced tree managing the pieces, so more efficient) |
| 17:02:22 | <ibid> | osfameron: i used to collaborate with ted :) |
| 17:02:24 | <osfameron> | ibid: I keep on meaning to get time to write a text editor based on one (in Perl or Haskell) |
| 17:02:37 | <osfameron> | ibid: really! That must have been interesting |
| 17:02:44 | <hpaste> | byorgey annotated "Help on resolving ambiguity.." with "fixed" at http://hpaste.org/3303#a1 |
| 17:03:11 | <ibid> | osfameron: it was until ted lost patience with us geeks :) |
| 17:03:23 | <osfameron> | ibid: I'm really interested in discussing enfilades some more at some point if you have time. |
| 17:03:23 | <byorgey> | Mortez: ^^ that should work. |
| 17:03:29 | <ibid> | osfameron: osfameron have a look at http://antti-juhani.kaijanaho.fi/ie/ |
| 17:03:31 | <lambdabot> | Title: Ibid's Editor |
| 17:03:42 | <osfameron> | ibid: but right now I'd better go as I promised it's my turn to cook tonight :-) |
| 17:03:56 | <ibid> | (no history support) |
| 17:04:43 | <osfameron> | cool! ((laters)) |
| 17:05:11 | <Mortez> | byorgey++ |
| 17:08:07 | <dons> | http://programming.reddit.com/info/5yc9f/details :) |
| 17:08:08 | <lambdabot> | Title: programming: Testing your web applications with Haskell |
| 17:09:19 | <shapr> | I like that binding. |
| 17:12:44 | <bos> | fasta: i don't know why you're getting a stack overflow, sorry. |
| 17:12:57 | <fasta> | bos: I think it depends on whether profiling is on or off. |
| 17:13:08 | <fasta> | bos: I just tried it in ghci and there it works. |
| 17:13:22 | <fasta> | bos: when I compile the example program without profiling it also works |
| 17:13:28 | <bos> | fasta: so it works if profiling is off? huh. |
| 17:14:00 | <fasta> | bos: yes, I verified it now |
| 17:20:59 | <MyCatSchemes> | > liftM Char.toUpper "foo bar baz" |
| 17:21:01 | <lambdabot> | "FOO BAR BAZ" |
| 17:21:07 | <MyCatSchemes> | :t liftM |
| 17:21:09 | <lambdabot> | forall a1 r (m :: * -> *). (Monad m) => (a1 -> r) -> m a1 -> m r |
| 17:21:11 | <MyCatSchemes> | :t map |
| 17:21:13 | <lambdabot> | forall a b. (a -> b) -> [a] -> [b] |
| 17:21:23 | <dmwit> | :t liftM `asTypeOf` map |
| 17:21:25 | <lambdabot> | forall a1 r. (a1 -> r) -> [a1] -> [r] |
| 17:21:36 | <MyCatSchemes> | ACTION brainexplode. |
| 17:21:47 | <MyCatSchemes> | dmwit: where the Hell did you get asTypeOf from? That was awesome. :) |
| 17:21:57 | <dmwit> | =) |
| 17:22:09 | <dmwit> | It's a throwback to before type annotations, I gather. =) |
| 17:22:27 | <mrd> | it's in haskell for dealing with things that lexical type variables would do |
| 17:22:52 | <MyCatSchemes> | :t asTypeOf |
| 17:22:52 | <dmwit> | asTypeOf is just a type-restricted const. |
| 17:22:54 | <lambdabot> | forall a. a -> a -> a |
| 17:23:20 | <MyCatSchemes> | @djinn a -> a -> a |
| 17:23:20 | <lambdabot> | f _ a = a |
| 17:23:54 | <oerjan> | @src asTypeOf |
| 17:23:55 | <lambdabot> | asTypeOf = const |
| 17:24:02 | <oerjan> | @src const |
| 17:24:02 | <lambdabot> | const x _ = x |
| 17:24:20 | <MyCatSchemes> | :t liftM `const` map |
| 17:24:22 | <lambdabot> | forall a1 r (m :: * -> *). (Monad m) => (a1 -> r) -> m a1 -> m r |
| 17:24:41 | <MyCatSchemes> | :t map `const` liftM |
| 17:24:41 | <dmwit> | :t (const :: a -> a -> a) liftM map |
| 17:24:43 | <lambdabot> | forall a1 r. (a1 -> r) -> [a1] -> [r] |
| 17:24:44 | <lambdabot> | Ambiguous type variable `m' in the constraint: |
| 17:24:44 | <lambdabot> | `Monad m' arising from use of `liftM' at <interactive>:1:12-16 |
| 17:25:07 | <oerjan> | MyCatSchemes: the last argument of const has no effect on the type of the result |
| 17:25:26 | <MyCatSchemes> | oerjan: ah. Is the effect of asTypeOf a hack in the compiler, then? |
| 17:25:32 | <oerjan> | asTypeOf has the same _value_ definition as const, but _not_ the same type |
| 17:25:43 | <oerjan> | no, it simply has a type annotation |
| 17:26:25 | <fax> | good afternoon |
| 17:27:20 | <MyCatSchemes> | oerjan: ahhh, I see. Thank you. |
| 17:27:26 | <MyCatSchemes> | fadec: good evening. |
| 17:27:42 | <fax> | wow |
| 17:27:50 | <fax> | very nice cats |
| 17:27:52 | <dmwit> | fax: Also, good morning. |
| 17:28:38 | <dmwit> | "boxed cat has a uniform representation" |
| 17:28:40 | <fax> | oh geez "catmorphism" |
| 17:28:41 | <fax> | lol |
| 17:30:27 | <dmwit> | KittyT |
| 17:30:47 | <MyCatSchemes> | "Tail recursion", heehee. |
| 17:31:15 | <dmwit> | That one is so cute! |
| 17:33:14 | <birkenfeld> | http://pocoo.org/~gbrandl/monomorph.png :) |
| 17:33:51 | <liyang2> | Oh man. Are we still on the \cats? @_@ |
| 17:39:54 | <liyang2> | I'm getting all the jokes apart from `The impossible'. Halp? |
| 17:40:23 | <Beelsebob> | it's getting out the box |
| 17:40:28 | <dmwit> | It looks like the cat's leg is way way long. |
| 17:40:35 | <dmwit> | ...impossibly long. |
| 17:40:42 | <oerjan> | it's a ghc error message for compiler bugs, i think |
| 17:40:59 | <dmwit> | liyang2: And one of GHC's famous error messages is "The impossible has happened! Report it." or something like that. |
| 17:41:06 | <Beelsebob> | heh |
| 17:41:11 | <liyang2> | oerjan: I know that much. ^^; |
| 17:41:26 | <Beelsebob> | my personal favorite has to be lazy bitestring |
| 17:41:29 | <oerjan> | liyang2: wasn't sure which part you were not getting :) |
| 17:41:33 | <liyang2> | Beelsebob: guess that makes some sort of sense for me. ^^; |
| 17:42:06 | <liyang2> | maybe it just failed to tickle me on the right parts. ^^; |
| 17:42:16 | <Beelsebob> | someone needs to do an amerous cat, with some comment about playing with IO and my monads |
| 17:42:43 | <liyang2> | ACTION likes olegcat |
| 17:42:56 | <Beelsebob> | it's too much of an in joke |
| 17:43:22 | <oerjan> | they all are |
| 17:43:25 | <liyang2> | Don't kid yourself. The whole site is too much of an in-joke. :p |
| 17:43:37 | <Beelsebob> | yeh... but that one is *too much* of an in joke |
| 17:43:44 | <Beelsebob> | it requires knowledge of the community |
| 17:43:47 | <Beelsebob> | not just the languag |
| 17:43:47 | <liyang2> | ACTION loevs KittehT more |
| 17:43:50 | <Beelsebob> | language* |
| 17:43:59 | <Beelsebob> | yeh, the kittehT rocks |
| 17:44:02 | <liyang2> | And my. simoncat's looking cool. |
| 17:44:36 | <fax> | hehehe |
| 17:44:41 | <liyang2> | Beelsebob: and the compiler, let's not forget. :) |
| 17:44:48 | <Beelsebob> | that too |
| 17:45:22 | <liyang2> | Hang on, did I just say *the* compiler? I didn't mean that. There are other Haskell compilers... |
| 17:45:27 | <liyang2> | (Right guys?) |
| 17:48:20 | <Spark> | there are no haskell compilers |
| 17:48:49 | <HodriUser-381> | selam |
| 17:49:16 | <dmwit> | Hi asd! |
| 17:49:59 | <dolio> | There is no spoon. |
| 17:50:25 | <dmwit> | There is no red pill. |
| 17:50:47 | <oerjan> | Ceci n'est pas un pipe. |
| 17:51:08 | <oerjan> | *une |
| 17:52:21 | <mrd> | someone wrote that on a steam pipe in a building here |
| 17:52:23 | <mrd> | =) |
| 17:52:46 | <dmwit> | "There is no pipe"? |
| 17:52:57 | <dmwit> | ?babel fr en ceci n'est pas un pipe |
| 17:52:58 | <lambdabot> | this is not a pipe |
| 17:53:07 | <Spark> | lol, pipe is feminine |
| 17:53:17 | <mrd> | ?google magritte ceci n'est pas une pipe |
| 17:53:19 | <lambdabot> | http://en.wikipedia.org/wiki/The_Treachery_of_Images |
| 17:53:19 | <lambdabot> | Title: The Treachery Of Images - Wikipedia, the free encyclopedia |
| 17:53:58 | <Spark> | i saw that referred in some pixel pushing art once |
| 17:54:08 | <Spark> | ceci n'est pas une pixele |
| 17:54:12 | <Spark> | or something like that |
| 17:54:36 | <liyang2> | This is not my fist on your FACE. |
| 17:54:39 | <Spark> | because it had a pixel under a magnifying glass, and it was a rabbit or something |
| 17:56:10 | <liyang2> | Spark: how's London? :-/ |
| 17:58:42 | <Spark> | i'm living in the 4th least pleasant place to live in the UK |
| 18:01:22 | <ivant> | yay, we had our first official Haskell User Group meeting in St.Petersburg on Saturday! |
| 18:01:45 | <bos> | excellent! |
| 18:01:56 | <Spark> | did you have a group hug |
| 18:01:58 | <ivant> | 26 people were there! |
| 18:02:15 | <ivant> | oh, we forgot about a group hug :-) |
| 18:02:16 | <bos> | nice. |
| 18:03:31 | <ivant> | if somebody ever decide to come to St.Petersburg, be sure to prepare a talk for our HUG :-) |
| 18:05:39 | <pierre-> | ivant: yeah, spbhug was really great |
| 18:07:35 | <byorgey> | @seen shapr |
| 18:07:35 | <lambdabot> | shapr is in #scannedinavian, #xmonad, #haskell-blah and #haskell. I last heard shapr speak 58m 16s ago. |
| 18:08:08 | <byorgey> | shapr: so AmeroHaskell might be in the northwest instead of southeast now? |
| 18:08:18 | <shapr> | yup |
| 18:08:32 | <mrd> | catty corner |
| 18:08:48 | <shapr> | Portland seems like the easiest place to get a venue, and where the most potential attendees are already located. |
| 18:09:06 | <mrd> | ACTION is in another corner |
| 18:09:23 | <byorgey> | shapr: yeah, that makes sense. it's a bit farther away for me of course, but I'll see if I can still come, depending on when it is and whether I can get cheap plane tickets |
| 18:11:53 | <shapr> | cool |
| 18:15:32 | <bos> | portland would be perfect. where's the wiki page again? |
| 18:15:34 | <byorgey> | I'm actually planning to apply to PSU, so 'twould be a good chance to visit, especially if it happens before December. dunno how likely that is though. |
| 18:16:01 | <byorgey> | @wiki AmeroHaskel |
| 18:16:01 | <lambdabot> | http://www.haskell.org/haskellwiki/AmeroHaskel |
| 18:16:08 | <byorgey> | erm, but spelled correctly =P |
| 18:20:04 | <MyCatSchemes> | @seen Zeppelin |
| 18:20:05 | <lambdabot> | I haven't seen Zeppelin. |
| 18:20:09 | <MyCatSchemes> | @seen Jesus |
| 18:20:09 | <lambdabot> | I haven't seen Jesus. |
| 18:20:21 | <MyCatSchemes> | @seen The_Invisible_Pink_Unicorn |
| 18:20:21 | <lambdabot> | I haven't seen The_Invisible_Pink_Unicorn. |
| 18:20:23 | <Baughn> | @seen me |
| 18:20:23 | <lambdabot> | me has changed nick to olsner. |
| 18:20:23 | <lambdabot> | I saw olsner leaving #haskell 1d 7h 55m 6s ago, and . |
| 18:20:37 | <Baughn> | MyCatSchemes: Also, it's an invisible pink dragon. Get it right. |
| 18:21:04 | <MyCatSchemes> | @seen my_toes_in_fourty_years._So_now_I_go_to_weightwatchers. |
| 18:21:04 | <lambdabot> | I haven't seen my_toes_in_fourty_years._So_now_I_go_to_weightwatchers.. |
| 18:21:21 | <Baughn> | @seen lambdabot |
| 18:21:22 | <lambdabot> | Yes, I'm here. I'm in #friendly-coders, #scannedinavian, #gentoo-haskell, ##logic, #xmonad, #unicycling, #perl6, #parrot, #jtiger, #haskell-soc, #haskell-overflow, #haskell-blah, #scala, #haskell, # |
| 18:21:22 | <lambdabot> | ghc and #darcs |
| 18:21:56 | <MyCatSchemes> | Baughn: wikipedia disagrees. |
| 18:22:35 | <MyCatSchemes> | Hell, even Google's keyword completion in Firefox immediately comes up with "unicorn" whenever I type "invisible pink" |
| 18:22:53 | <Baughn> | I was wondering what was up with those search words |
| 18:23:07 | <Baughn> | Google, you say. Fun. |
| 18:23:19 | <fax> | lambdabot can unicycle too? |
| 18:23:32 | <Baughn> | lambdabot, can you unicycle? |
| 18:23:38 | <oerjan> | @unicycle |
| 18:23:39 | <lambdabot> | Unknown command, try @list |
| 18:23:50 | <Baughn> | Guess not. She's too embarrassed to answer. |
| 18:26:05 | <roconnor> | @vixen can you unicycle? |
| 18:26:06 | <lambdabot> | i sure can |
| 18:26:31 | <Baughn> | @seen dons |
| 18:26:31 | <lambdabot> | dons is in #xmonad and #haskell. I last heard dons speak 8m 44s ago. |
| 18:44:32 | <shapr> | Is there a headless X server? Something that can run without display hardware? |
| 18:44:46 | <shapr> | I want to run automated tests with the recent selenium binding from Galois on a machine without a display. |
| 18:45:14 | <dons> | shapr: hmm, i think it needs a real browser running javascript |
| 18:45:24 | <dons> | i'm unaware of a way to run it 'offline' as such |
| 18:45:41 | <kaol> | like xserver-xorg-video-dummy? (on Debian, at least) |
| 18:46:03 | <liyang2> | shapr: a VNC server? |
| 18:46:18 | <ToxicFrog> | shapr: NX? You'll need a remote system with an X terminal to get it started, though. |
| 18:46:37 | <dmwit> | liyang2: And how would you control the VNC server, without a display? |
| 18:47:00 | <ToxicFrog> | ...hmm. |
| 18:47:01 | <liyang2> | dmwit: same question goes to the original request. :) |
| 18:47:07 | <liyang2> | (XTEST?) |
| 18:47:30 | <dmwit> | liyang2: You can surely get remote connection that has no X in it to control the server, but that doesn't help control VNC. |
| 18:47:33 | <shapr> | Selenium starts up the browser by itself. |
| 18:47:43 | <ToxicFrog> | I have pmap :: Double -> (a -> a) -> [a] -> State b [a] |
| 18:48:20 | <liyang2> | well, some early VNC servers manifest themselves as X11 servers that don't require display hardware. That's all I know. |
| 18:48:31 | <ToxicFrog> | I have mutate_one :: Solution -> Solution, where Solution = [Int], and it calls pmap.. |
| 18:48:38 | <shapr> | liyang2: That's an idea, thanks. |
| 18:48:47 | <ToxicFrog> | It needs to become Solution -> State b Solution, yes? |
| 18:48:50 | <shapr> | kaol: -dummy sounds good, I can try that locally. |
| 18:49:22 | <byorgey> | ToxicFrog: not necessarily. There are functions like runState, execState, and evalState that let you extract things from the State monad. |
| 18:49:33 | <byorgey> | ToxicFrog: it depends what you want. |
| 18:49:56 | <oerjan> | ToxicFrog: is the b really polymorphic? in which case i don't see how pmap could use the state at all? |
| 18:50:01 | <ToxicFrog> | Hrm |
| 18:51:24 | <ToxicFrog> | ACTION tries to figure out how to explain this |
| 18:51:47 | <ivant> | shapr, AFAIR, there is a thing called x virtual framebuffer server |
| 18:51:54 | <ToxicFrog> | I have this function, mutate, which takes a Solution and creates a new Solution out of it; data Solution = Solution [Int] |
| 18:52:04 | <ToxicFrog> | So, ideally, the definition is |
| 18:52:35 | <ToxicFrog> | mutate (Solution s) = Solution (pmap 0.5 (+1) s) |
| 18:52:50 | <roconnor> | ACTION gets a version of iowidget to typecheck |
| 18:52:57 | <oerjan> | ToxicFrog: what is the _actual_ type of pmap? |
| 18:53:01 | <roconnor> | Now to attempt to create my first widget! |
| 18:53:02 | <ToxicFrog> | However, pmap doesn't return an [a], it returns a State [Double] [a], because internally it needs state |
| 18:53:11 | <oerjan> | ok |
| 18:53:20 | <oerjan> | so b = [Double] |
| 18:53:36 | <ToxicFrog> | pmap :: forall a. Double -> (a -> a) -> [a] -> State [Double] [a] |
| 18:54:02 | <byorgey> | @type execState |
| 18:54:03 | <ToxicFrog> | Yes, sorry |
| 18:54:04 | <lambdabot> | forall s a. State s a -> s -> s |
| 18:54:10 | <byorgey> | @type evalState |
| 18:54:12 | <lambdabot> | forall s a. State s a -> s -> a |
| 18:54:35 | <oerjan> | seems like you want evalState |
| 18:55:02 | <byorgey> | ToxicFrog: I think you want mutate (Solution s) = Solution (evalState (pmap 0.5 (+1) s) ??) |
| 18:55:10 | <byorgey> | where the ?? is whatever the appropriate initial state is |
| 18:55:40 | <roconnor> | what is the basic Gtk2hs widget for a simple text entry box? |
| 18:55:53 | <ToxicFrog> | The initial state comes from the attached State monad via get, I think |
| 18:55:54 | <dcoutts_> | roconnor: Entry |
| 18:56:26 | <ToxicFrog> | Basically, mutate needs to be in State, and I'm having trouble with the interaction between State and user-defined types |
| 18:56:40 | <roconnor> | thx |
| 18:57:02 | <oerjan> | ToxicFrog: every state monad needs to get its initial state on "startup" |
| 18:57:26 | <ToxicFrog> | oerjan: the original initial state is created and passed in by main |
| 18:57:43 | <oerjan> | oh, so there is a global State monad? |
| 18:57:48 | <ToxicFrog> | From there, it gets carried around until more_randoms way at the bottom of the call graph needs it. |
| 18:58:18 | <ToxicFrog> | Which I had working back when I was just using [[Int]] |
| 18:58:24 | <ToxicFrog> | Rather than [Solution] |
| 18:58:36 | <ToxicFrog> | The problem I'm running into is that I can' |
| 18:58:38 | <shapr> | ivant: xvfb looks like exactly what I need, thanks! |
| 18:58:46 | <oerjan> | in that case you probably cannot escape State that easily |
| 18:58:54 | <ToxicFrog> | I'm not trying to escape it! |
| 18:59:09 | <ToxicFrog> | The issue is that I want to return a State [Double] Solution |
| 18:59:34 | <ToxicFrog> | But I can't see how to turn a State [Double] [Int] into a State [Double] (Solution [Int]) |
| 18:59:44 | <oerjan> | liftM Solution |
| 18:59:56 | <ToxicFrog> | @type liftM |
| 18:59:58 | <lambdabot> | forall a1 r (m :: * -> *). (Monad m) => (a1 -> r) -> m a1 -> m r |
| 19:01:27 | <roconnor> | dcoutts_: Is it possible to invoke the onEditableChanged callback by hand? I don't see a function for that. |
| 19:01:44 | <ToxicFrog> | Erm. I don't have a monad going in, only coming out. |
| 19:02:01 | <ToxicFrog> | And the signature isn't (a->b), it's (a->m a) |
| 19:02:03 | <oerjan> | but pmap is in the monad |
| 19:02:06 | <dcoutts_> | roconnor: not sure, lemme look. In general you can't poke all callbacks, since many of them have extra arguments |
| 19:02:18 | <ToxicFrog> | Yes. That's the problem. I give it a list, I get a monad list out. |
| 19:02:27 | <byorgey> | i.e. mutate (Solution s) = liftM Solution $ pmap 0.5 (+1) s |
| 19:02:38 | <ToxicFrog> | ...oh, right |
| 19:02:58 | <roconnor> | dcoutts_: If I change an attribute by hand, will the callback be called? |
| 19:03:08 | <ToxicFrog> | ...right, right! Solution has type [Int] -> Solution |
| 19:03:12 | <ToxicFrog> | Didn't realize that |
| 19:03:12 | <roconnor> | dcoutts_: change an attribute with set |
| 19:03:13 | <ToxicFrog> | Thank you |
| 19:03:33 | <dcoutts_> | roconnor: sure, if you modify the content of the Entry then the changed signal will fire |
| 19:03:57 | <dcoutts_> | roconnor: you have to go to greater lengths to get the opposite behaviour, to modify without getting the signal |
| 19:04:55 | <roconnor> | so I should set the callback and then set the inital value to have the callback called on initialization? |
| 19:05:15 | <roconnor> | I think I can do that |
| 19:06:54 | <Saul_> | Hey guys |
| 19:07:09 | <Saul_> | I have a bit of a problem (not really, more of a mental exercise) |
| 19:07:26 | <dmwit> | Hi Saul_! |
| 19:07:36 | <dmwit> | We all love mental exercise. |
| 19:07:54 | <Saul_> | I have a problem that is defined using snoc lists, but I want to rewrite it to a definition using cons lists |
| 19:08:06 | <Saul_> | the list itself shouldn't be reversed though |
| 19:08:14 | <Saul_> | and it should be proven correct |
| 19:08:48 | <Saul_> | the function I have is: |
| 19:08:52 | <Saul_> | f [] = 0 |
| 19:09:14 | <Saul_> | f (s <| b) = 10 * f s + b |
| 19:09:52 | <Saul_> | dmwit: Hi |
| 19:10:54 | <oerjan> | Saul_: sounds like you essentially want to change a foldr (on snocs) to a foldl (on conses) |
| 19:11:48 | <oerjan> | (well, a foldl on snocs, which has the same structure as a foldr on conses) |
| 19:11:59 | <Saul_> | oerjan: I guess (aren't foldrs on cons though, and foldls on snoc)? |
| 19:12:56 | <oerjan> | you can have foldls and foldrs on both, but mirrored |
| 19:13:22 | <Saul_> | I see |
| 19:13:37 | <Saul_> | But that is way too generic, I just need it in this specific case |
| 19:13:44 | <oerjan> | so the way to write each for a snoc is to write the opposite for a cons |
| 19:14:03 | <Saul_> | the function basically turns [1, 2, 3, 4] into 1234 |
| 19:14:08 | <oerjan> | well you need to use the same structure |
| 19:15:11 | <roconnor> | dcoutts_: It kinda works!!!! |
| 19:15:23 | <oerjan> | actually you need to generalize slightly, because a foldl on (cons) lists requires passing the accumulating argument |
| 19:15:23 | <dcoutts_> | roconnor: only kinda? |
| 19:15:40 | <roconnor> | dcoutts_: well, it didn't quite initialize properly |
| 19:15:49 | <roconnor> | but once it got going to worked |
| 19:15:55 | <dcoutts_> | ok |
| 19:15:58 | <roconnor> | I build an echo dialog |
| 19:16:07 | <roconnor> | using two entry boxes |
| 19:16:15 | <Saul_> | Well I already have a accumulating function that calculates the same as f already, but I need to derive one from the definition of f |
| 19:16:29 | <roconnor> | using Phooey with a Gtk2hs backend! |
| 19:16:41 | <dcoutts_> | roconnor: oh, cool! |
| 19:17:16 | <dcoutts_> | roconnor: so to do all that nicer you want a way to get a signal for a specific attribute |
| 19:17:27 | <dcoutts_> | roconnor: which is possible in Gtk+, but we've not bound it yet |
| 19:17:33 | <dcoutts_> | and I should look into doing so |
| 19:17:34 | <roconnor> | dcoutts_: ah yes |
| 19:17:39 | <roconnor> | that would be much better |
| 19:17:46 | <Saul_> | @src foldl |
| 19:17:46 | <lambdabot> | foldl f z xs = lgo z xs |
| 19:17:46 | <lambdabot> | where lgo z [] = z |
| 19:17:46 | <lambdabot> | lgo z (x:xs) = lgo (f z x) xs |
| 19:17:51 | <Saul_> | @src foldr |
| 19:17:51 | <lambdabot> | foldr k z xs = go xs |
| 19:17:52 | <lambdabot> | where go [] = z |
| 19:17:52 | <lambdabot> | go (y:ys) = y `k` go ys |
| 19:18:22 | <dcoutts_> | roconnor: something like: on widget (attrChanged attr) $ do ... |
| 19:18:35 | <oerjan> | as you see, go is the function you already have essentially |
| 19:19:18 | <oerjan> | so you probably want the corresponding lgo |
| 19:19:21 | <Saul_> | I basically also have lgo as well |
| 19:19:58 | <roconnor> | dcoutts_: that would look more like the existing wxHaskell code |
| 19:20:14 | <dcoutts_> | roconnor: what api does it use? |
| 19:20:15 | <Saul_> | I really don't have much of a problem with writing accumulating functions and stuff, but the exercise is to derive one from the other |
| 19:21:22 | <Saul_> | I have g a [] = a |
| 19:21:40 | <Saul_> | and g a (x:xs) = g (10 * a + x) xs |
| 19:21:48 | <oerjan> | yeah |
| 19:21:50 | <Saul_> | g 1 = f |
| 19:21:58 | <dcoutts_> | roconnor: or rather, what would you write in wx to get the same effect ? |
| 19:22:40 | <Saul_> | I even derived a weird accumulating version of f, but it still works with snoc lists |
| 19:22:43 | <Beelsebob> | Saul_: use fold |
| 19:22:58 | <oerjan> | i am not sure, but maybe one could view it has a kind of CPS transformation? |
| 19:23:02 | <oerjan> | *as |
| 19:23:13 | <Saul_> | g x y [] = y |
| 19:23:37 | <roconnor> | dcoutts_: I'm not certain. I don't fully appreciate what the wxHaskell code I'm replacing does. |
| 19:23:41 | <Saul_> | g x y (s <| b) = g (x * 10) (x * b + y) s |
| 19:23:47 | <Saul_> | g 1 0 = f |
| 19:23:49 | <dcoutts_> | roconnor: ok :-) |
| 19:23:51 | <Saul_> | CPS? |
| 19:23:59 | <roconnor> | dcoutts_: but there is a fair amount of use of `on` |
| 19:24:07 | <roconnor> | which I've replaced |
| 19:24:22 | <Saul_> | Beelsebob: I would first have to derive fold, so that would probably make it more work |
| 19:24:33 | <Saul_> | oerjan: CPS? |
| 19:24:35 | <dcoutts_> | robreim: I think their 'on' means turn a signal into a function valued attribute |
| 19:24:38 | <dcoutts_> | oops |
| 19:24:43 | <dcoutts_> | roconnor: ^^ |
| 19:24:49 | <oerjan> | continuation passing style |
| 19:24:57 | <roconnor> | dcoutts_: right, I have no idea at this point |
| 19:25:01 | <Saul_> | ah ok |
| 19:26:20 | <Saul_> | I don't really have a lot of experience with that, and I would also have to prove it correct first |
| 19:27:50 | <oerjan> | do you have a proven function for converting between snoc and cons lists? perhaps you could compose it with that, and somehow unravel the result |
| 19:28:32 | <Saul_> | Nope, that's the problem |
| 19:28:47 | <fox86> | anyone know how to completely turn off indentation when using haskell-mode in emacs? (remove-hook 'haskell-mode-hook 'turn-on-haskell-indent) does disable some of the fancier stuff, but not everything. i would like "return" to just make a newline without indenting at all and then rather tab my way to where i want to be. maybe this is a question for #emacs, but they don't seem to use haskell-mode |
| 19:29:06 | <Saul_> | I do have some calculation rules, but they aren't much help |
| 19:29:32 | <oerjan> | maybe make that first, as otherwise it would seem hard to even define what it means for your original exercise to be correct... |
| 19:30:23 | <Saul_> | Yeah I've tried some things, but no luck so far :( |
| 19:30:37 | <oerjan> | although when i think about it, such a conversion function would essentially also be a foldl... |
| 19:31:34 | <dons> | http://programming.reddit.com/info/5yciu/details |
| 19:31:35 | <lambdabot> | Title: programming: Ask Reddit: How do I get a job hacking Haskell all day? |
| 19:31:39 | <dons> | anyone else have suggestions? |
| 19:32:17 | <oerjan> | calculation rules? like a : (b <| c) = (a : b) <| c ? |
| 19:32:34 | <Lemmih> | @seen dcoutts_ |
| 19:32:34 | <lambdabot> | dcoutts_ is in #gentoo-haskell, #haskell, #ghc and #haskell-overflow. I last heard dcoutts_ speak 7m 50s ago. |
| 19:32:41 | <dcoutts_> | hia Lemmih |
| 19:32:45 | <Saul_> | Yeah like those (although that particular one is missing) |
| 19:33:06 | <araujo> | dons, starting your own startup |
| 19:33:09 | <oerjan> | actually i guess <| could be defined as a haskell function (not to be pattern matched on, though) |
| 19:33:20 | <roconnor> | dcoutts_: Hmm, I guess when the text attribue on an entry is set, the onEntryActivate callback isn't fired? |
| 19:33:22 | <beschmi> | fox86: what function gets called by "return"? C-h k RET |
| 19:33:51 | <dcoutts_> | roconnor: the activate is what happens when you press enter in the Entry box |
| 19:34:16 | <Saul_> | well the calculation rule you suggested in reverse would be a proper definition |
| 19:34:18 | <ivant> | oh, I wish one day I could get a job hacking Haskell |
| 19:34:30 | <roconnor> | dcoutts_: I think I will have to fire that initally by hand |
| 19:34:37 | <eyeris> | How can I make ghc infer Float from `Int / (Int + Int)`? (the Int is being returned by `length :: [a] -> Int`) |
| 19:34:40 | <fox86> | beschmi:" RET runs the command newline-and-indent-relative" |
| 19:34:42 | <oerjan> | right |
| 19:34:42 | <Saul_> | combined with [] <| b = b : [] |
| 19:35:34 | <oerjan> | eyeris: use fromIntegral or genericLength |
| 19:35:51 | <dcoutts_> | roconnor: I don't think I understand, that signal does not correspond to any property of the widget, it's more like the signal you get when someone presses a button widget |
| 19:35:54 | <Lemmih> | dcoutts_: I've been told that SOE/Gtk once had problems on Windows. HsSDL is now in the same situation. Do you have any wise words or hints? |
| 19:36:11 | <dcoutts_> | Lemmih: what kind of problems? |
| 19:36:13 | <Saul_> | I've tried using those, but then I got stuck |
| 19:36:20 | <eyeris> | oerjan thanks |
| 19:36:29 | <dcoutts_> | Lemmih: most of our problems were to do with making it easy for windows users to install |
| 19:37:04 | <dcoutts_> | Lemmih: so you could make an installer, the hint there is InnoSetup, it's what gtk2hs and ghc-6.8 use |
| 19:37:25 | <roconnor> | dcoutts_: yeah, I want to initalize the edit box with a string, and then notify the event handler, as if the enter key was pressed. Seems like a reasonable initalization routine to me. |
| 19:37:38 | <beschmi> | fox86, runs command newline here in haskell-mode |
| 19:38:53 | <dcoutts_> | roconnor: hmm, so is the behaviour that you want, that the values calculated based on the entry's text should only update when the user presses enter in the box ? |
| 19:39:43 | <roconnor> | dcoutts_: I think so. I think updating as they type would be really annoying in most cases. |
| 19:40:22 | <roconnor> | ... I should test to see what the wxHaskell version did |
| 19:40:28 | <dcoutts_> | roconnor: you should ask conal how he manages that kind of update policy |
| 19:40:58 | <roconnor> | I should, but I think he was able to always fire any event handler. |
| 19:43:19 | <dcoutts_> | roconnor: of course you can always run the event handler directly if you were the one who connected it |
| 19:45:50 | <dons> | augustss with his hackathon tshirt :) http://catenova.org/~lemmih/ICFP07/images/pa040054.jpg |
| 19:49:17 | <earthy> | nice shirt, btw. I like the axe in the lambda. |
| 19:49:31 | <earthy> | (mrchebas had his on today) |
| 19:51:42 | <Saul_> | Argh, I give up |
| 19:51:53 | <Saul_> | oerjan: Thanks for your help |
| 19:53:07 | <dons> | earthy: cool :) |
| 20:09:34 | <eyeris> | I'm trying to use the Text.CSV package. I import Text.CSV and Text.ParserCombinators.Parsec but ghci still tells me that both CSV and ParseError are not in scope. |
| 20:09:49 | <dons> | how do you import them? |
| 20:09:59 | <dons> | and did you touch your .hs file, so ghci can see non-exported symbols? |
| 20:10:49 | <eyeris> | I import them at the top of my .hs with "import Text.CSV" |
| 20:11:45 | <eyeris> | I'm not sure what you mean by touching the .hs file. I can touch it with the unix command touch, but that doesn't change anything |
| 20:12:13 | <sjanssen> | eyeris: how did you install Text.CSV? |
| 20:14:00 | <eyeris> | runghc Setup.hs build/install or something like that -- from the instructions |
| 20:14:24 | <eyeris> | I might just be using it wrong. Here is my code (on hpaste) |
| 20:14:41 | <hpaste> | eyeris pasted "csverror" at http://hpaste.org/3310 |
| 20:15:27 | <sjanssen> | eyeris: yes, you're doing it wrong :P |
| 20:15:31 | <eyeris> | figures |
| 20:16:24 | <hpaste> | sjanssen annotated "csverror" with "parseCSVFromFile returns Either ParseError CSV" at http://hpaste.org/3310#a1 |
| 20:17:11 | <eyeris> | Ok, so I misunderstood now Either works... trying to use it more like Maybe? |
| 20:17:31 | <oerjan> | Maybe doesn't work like that either :D |
| 20:18:23 | <oerjan> | you need Just and Nothing like you need Left and Right |
| 20:18:29 | <eyeris> | ok yeah |
| 20:19:22 | <eyeris> | yay! it works! |
| 20:25:41 | <n00b> | how do i write a recursicve function to sum all the elements in list |
| 20:25:55 | <dons> | > sum [1..10] |
| 20:25:57 | <lambdabot> | 55 |
| 20:25:58 | <dons> | ?src sum |
| 20:25:58 | <lambdabot> | sum = foldl (+) 0 |
| 20:26:01 | <dons> | ?src foldl |
| 20:26:04 | <lambdabot> | foldl f z xs = lgo z xs |
| 20:26:04 | <lambdabot> | where lgo z [] = z |
| 20:26:04 | <lambdabot> | lgo z (x:xs) = lgo (f z x) xs |
| 20:26:06 | <dons> | :) |
| 20:26:15 | <oerjan> | ?src foldl' |
| 20:26:16 | <lambdabot> | foldl' f a [] = a |
| 20:26:16 | <lambdabot> | foldl' f a (x:xs) = let a' = f a x in a' `seq` foldl' f a' xs |
| 20:26:21 | <byorgey> | a bit over-general for that specific problem, perhaps, but... |
| 20:26:23 | <dons> | well, that's over the top. |
| 20:26:34 | <wli> | mySum [] = 0 ; mySum (x:xs) = x + mySum xs |
| 20:26:35 | <dons> | n00b: what have you got so far? |
| 20:28:24 | <n00b> | i am gonna hpaste it |
| 20:30:49 | <hpaste> | n00b pasted "sumAll" at http://hpaste.org/3311 |
| 20:31:19 | <dmwit> | n00b: That looks fine. |
| 20:31:24 | <dmwit> | Are you having a problem with it? |
| 20:31:41 | <n00b> | kinda learning list |
| 20:31:52 | <n00b> | I wrote based on you guys replies |
| 20:31:59 | <dmwit> | aha |
| 20:33:41 | <n00b> | <dmwit> ??? |
| 20:35:46 | <n00b> | how do I write a rursive definition for div in haskell ? |
| 20:36:15 | <Heffalump> | how efficient do you want? |
| 20:36:28 | <Heffalump> | ls |
| 20:36:31 | <Heffalump> | sorry |
| 20:36:42 | <wli> | I think he can take dogslow. |
| 20:36:44 | <mrd> | ACTION lists Heffalump's directories |
| 20:36:48 | <dmwit> | n00b: Do you mean, how do you divide each element of a list by a certain number, or do you really want to define div? |
| 20:36:54 | <n00b> | Implement the following operators (over the natural numbers i.e. positive integers) using recursive definitions: (a) * (multiplication) (b) div (division) (c) mod (modulus) |
| 20:37:10 | <Heffalump> | well, I suggest you consider two possible cases. |
| 20:37:21 | <Heffalump> | Either (a) the answer is 0 or (b) the answer is not 0. |
| 20:51:07 | <hpaste> | (anonymous) pasted "numDigits" at http://hpaste.org/3312 |
| 20:51:47 | <n00b> | i am writing a recursive function to count the number of digits in a numbers |
| 20:52:00 | <n00b> | help pleas !!!! |
| 20:52:34 | <oerjan> | n00b: you might try div'ing by 10 |
| 20:53:24 | <byorgey> | n00b: the first case looks good. In the other case, you know it has at least one digit, plus some more. How will you use numDigits to count the rest? |
| 20:55:21 | <n00b> | could i break down the number each time by using |
| 20:55:24 | <n00b> | mod |
| 20:55:25 | <n00b> | ?? |
| 20:55:32 | <oerjan> | n00b: div, i said :) |
| 20:55:40 | <n00b> | ok |
| 20:55:47 | <byorgey> | if you mod by 10 you'll get the last digit of the number. |
| 20:55:56 | <byorgey> | if you div by 10 you'll get everything BUT the last digit. |
| 20:56:41 | <abell> | Does it have to be recursive? |
| 20:56:47 | <n00b> | let a = 14 `div` 10 in if a <= 9 = 1 else a+1 |
| 20:56:55 | <n00b> | >let a = 14 `div` 10 in if a <= 9 = 1 else a+1 |
| 20:56:58 | <n00b> | yes |
| 20:57:03 | <n00b> | > let a = 14 `div` 10 in if a <= 9 = 1 else a+1 |
| 20:57:03 | <lambdabot> | Parse error |
| 20:57:07 | <TomMD> | > do Nothing |
| 20:57:09 | <lambdabot> | Nothing |
| 20:58:01 | <oerjan> | n00b: then not = |
| 20:59:16 | <byorgey> | n00b: that's closer, but it's still not recursive. and also, you need 'if a <= 9 then 1' instead of '... = 1', as oerjan mentioned. |
| 20:59:33 | <n00b> | i tried it and I keep getting a stack overflow |
| 21:00:01 | <n00b> | otherwise = numDigits a `div` 10 |
| 21:00:22 | <oerjan> | n00b: you need parentheses |
| 21:01:05 | <oerjan> | function application binds tighter than operators |
| 21:01:25 | <n00b> | answer always 1 |
| 21:01:42 | <hpaste> | n00b pasted "numDigits" at http://hpaste.org/3313 |
| 21:02:10 | <byorgey> | think about what that says. "otherwise = numDigits (a `div` 10)" means that if a >= 10, a has the same number of digits as a/10. is that true? |
| 21:03:11 | <n00b> | don't understand |
| 21:03:37 | <byorgey> | ok, let's try an example. |
| 21:03:41 | <byorgey> | suppose a = 587. |
| 21:03:42 | <oerjan> | n00b: what is numDigits (14 `div` 10)? |
| 21:04:11 | <byorgey> | how would evaluation of numDigits 587 proceed? |
| 21:04:13 | <oerjan> | (that is, what should it be?) |
| 21:07:51 | <n00b> | don't understand |
| 21:08:07 | <n00b> | i get the last digit, but what should it do ?? |
| 21:08:30 | <Botje> | n00b: numDigits "15" = 1 + numDigits "5" = 2 |
| 21:08:41 | <n00b> | ok |
| 21:08:49 | <Botje> | n00b: your code does numDigits "15" = numDigits "5" = 1 |
| 21:08:56 | <Botje> | do you spot what's missing? |
| 21:08:57 | <n00b> | so one is added to the previous |
| 21:09:58 | <shapr> | I'm trying to start a Haskell program in a subshell with ( program ) & but I always get "Main: <stdin>: hGetChar: end of file" any idea why? |
| 21:10:11 | <shapr> | I tried piping some random text to the program, but I still get the same error. |
| 21:10:30 | <shachaf> | shapr: Does it work otherwise? |
| 21:10:47 | <wli> | botched SIGTTIN handling? |
| 21:10:55 | <bos> | shapr: probably because it's doing non-blocking IO on stdin |
| 21:11:28 | <shapr> | shachaf: Yes, the program works if stdin is available. |
| 21:11:50 | <bringert> | dcoutts: thanks for pushing those patches to cabal-1.2 |
| 21:12:37 | <n00b> | getting a stack overflow |
| 21:13:17 | <hpaste> | n00b pasted "(no title)" at http://hpaste.org/3314 |
| 21:13:27 | <n00b> | check that |
| 21:14:58 | <omnId> | numDigits 12 = (1 + numDigits 12) `div` 10 = (1 + numDigits ((1 + numDigits 12) `div` 10))) `div` 10 |
| 21:15:18 | <byorgey> | n00b: your parentheses aren't in the right place. see if you can figure out why. |
| 21:15:37 | <omnId> | when you call numDigits recursively, it needs to take a smaller case or it'll just keep calling it forever. |
| 21:16:02 | <n00b> | ??? |
| 21:16:04 | <byorgey> | n00b: a very good exercise in this sort of situation is to see if you can "simulate" the code on a particular example by hand, to see if you understand what is happening. |
| 21:16:49 | <omnId> | n00b: in the example I showed, you need to `div` the 12 by 10 before passing it to numDigits |
| 21:18:42 | <eyeris> | !! is linear time, right? |
| 21:18:48 | <byorgey> | eyeris: yup. |
| 21:18:49 | <mauke> | what's a good algorithm for computing all digits of sqrt 2? |
| 21:19:09 | <eyeris> | So is there a more efficient way of writing something like this: |
| 21:19:16 | <eyeris> | let as = "abcdefg"; [ as !! x | x <- [1,4,6] ] |
| 21:19:24 | <byorgey> | mauke: by "good" do you mean "simple", "efficient", or what? |
| 21:19:51 | <mauke> | byorgey: fast |
| 21:20:07 | <mauke> | I need to generate more than 100000 digits in less than 20 seconds :-) |
| 21:20:22 | <oerjan> | eyeris: we discussed that the other day |
| 21:20:44 | <eyeris> | oerjan you and I did? Is there a #haskell log somewhere? |
| 21:21:01 | <mauke> | @where logs |
| 21:21:01 | <oerjan> | i don't remember if you were involved :) |
| 21:21:01 | <lambdabot> | http://tunes.org/~nef/logs/haskell/ http://meme.b9.com/cdates.html?channel=haskell |
| 21:21:42 | <Olathe> | @pl \x f -> f x |
| 21:21:42 | <lambdabot> | flip id |
| 21:21:59 | <byorgey> | mauke: maybe something on here will help? http://numbers.computation.free.fr/Constants/constants.html |
| 21:22:00 | <lambdabot> | Title: Mathematical Constants and computation |
| 21:22:10 | <Olathe> | > (flip id) 3 (+1) |
| 21:22:12 | <lambdabot> | 4 |
| 21:22:13 | <mauke> | ah, thanks |
| 21:22:18 | <hpaste> | omnId annotated "(no title)" with "n00b:" at http://hpaste.org/3314#a1 |
| 21:22:45 | <oerjan> | i think i did something with scanl drop... |
| 21:23:09 | <byorgey> | mauke: I know simple ways to compute sqrt 2 to arbitrary precision, but not fast =) |
| 21:23:12 | <omnId> | Olathe: s/id/($)/ is you want it to be a little clearer |
| 21:23:15 | <Olathe> | > flip id 3 (+1) |
| 21:23:16 | <lambdabot> | 4 |
| 21:23:18 | <omnId> | if* |
| 21:23:38 | <Olathe> | > 3 id (+1) |
| 21:23:38 | <lambdabot> | add an instance declaration for |
| 21:23:39 | <lambdabot> | (Num ((a -> a) -> (a1 -> a1) -> ... |
| 21:23:50 | <omnId> | > 3 `id` (+1) |
| 21:23:51 | <lambdabot> | add an instance declaration for (Num ((a -> a) -> a1)) |
| 21:23:58 | <omnId> | erm, oops |
| 21:24:02 | <Olathe> | > (+1) (id 3) |
| 21:24:03 | <lambdabot> | 4 |
| 21:24:06 | <omnId> | > (+1) `id` 3 |
| 21:24:07 | <lambdabot> | 4 |
| 21:24:09 | <mauke> | byorgey: my current approach is iterate (\x -> x / 2 + recip x) |
| 21:24:20 | <mauke> | byorgey: with unfoldr (\a -> let (d, r) = a `divMod` b in Just (toEnum (fromInteger d + 48), r * 10)) to generate the digits |
| 21:24:34 | <omnId> | ($) f x vs. flip ($) x f |
| 21:25:43 | <byorgey> | mauke: right, I'd guess that's probably not very fast =) |
| 21:26:18 | <oerjan> | > map head . tail . scanl (flip drop) "abcdefg" . ap (zipWith (-)) (0:) $ [1,4,6] |
| 21:26:20 | <lambdabot> | "beg" |
| 21:26:20 | <mauke> | fast enough to get 100343 digits in 16 iterations |
| 21:26:46 | <byorgey> | > 2^16 |
| 21:26:47 | <lambdabot> | 65536 |
| 21:26:52 | <byorgey> | > 2^17 |
| 21:26:53 | <lambdabot> | 131072 |
| 21:26:56 | <byorgey> | yup =) |
| 21:27:29 | <Olathe> | @pl \fs -> (\x -> map (\f -> f x) fs) |
| 21:27:29 | <lambdabot> | flip (map . flip id) |
| 21:27:34 | <byorgey> | it's the memory management and printing that take a long time. |
| 21:28:58 | <byorgey> | I wonder if there's a way to generate it stream-style. with your method it has to calculate the entire rational value in memory before printing anything out. |
| 21:29:37 | <wli> | The long division analogue for square roots. |
| 21:29:40 | <mauke> | the first iterations seem to take almost no time |
| 21:29:51 | <mauke> | but the last few rounds are really expensive |
| 21:30:31 | <mauke> | crap. lifting the first 14 iterations to compile time doesn't help. |
| 21:31:01 | <Olathe> | Usually, you have map f xs. What's a good name for q in q fs x ? |
| 21:31:07 | <byorgey> | wli: ah, right. I wonder if that would be faster? |
| 21:31:14 | <mauke> | Olathe: sequence? |
| 21:31:29 | <quicksilver> | KatieHuber: around? or any other openGL experts? |
| 21:31:54 | <omnId> | map ($ x) fs works too |
| 21:32:09 | <Olathe> | Right, but this is for Mathematica naming. |
| 21:32:42 | <byorgey> | how about Pam? |
| 21:32:54 | <omnId> | mapApply? |
| 21:33:01 | <byorgey> | ACTION only half joking |
| 21:33:29 | <byorgey> | ApplyEachInAListOfFunctionsToAValue? |
| 21:33:45 | <ddarius> | sequence |
| 21:33:48 | <KatieHuber> | quicksilver: here |
| 21:34:02 | <quicksilver> | KatieHuber: I'm trying to optimise my particle engine |
| 21:34:25 | <quicksilver> | KatieHuber: currently it's moving + drawing about 12,000 particles (triangles) per second |
| 21:34:42 | <quicksilver> | KatieHuber: which is better than the 3000 it was doing at the beginning of the evening |
| 21:34:50 | <KatieHuber> | you mean, 12000 particles @ 60fps? |
| 21:34:52 | <quicksilver> | KatieHuber: does that sounds like a reasonable speed? |
| 21:35:02 | <quicksilver> | no, 3000 particles at 40fps |
| 21:35:09 | <quicksilver> | erm |
| 21:35:19 | <quicksilver> | which is 120,000 particles per second in fact :) |
| 21:35:29 | <quicksilver> | clearly my maths is a bit limited... |
| 21:35:53 | <KatieHuber> | well, particle systems are almost always limited by fill rate, since they tend to be blended |
| 21:36:17 | <KatieHuber> | so the number of particles shouldn't matter nearly as much as the number that are on the screen |
| 21:36:25 | <quicksilver> | they're all onscreen |
| 21:36:39 | <KatieHuber> | so try taking them all offscreen, and see what your framerate does |
| 21:36:46 | <quicksilver> | ;) |
| 21:36:50 | <KatieHuber> | if it improves massively, there's little point optimizing further |
| 21:36:52 | <quicksilver> | ACTION tries that |
| 21:36:53 | <n00b> | how do you implement operators recusively |
| 21:37:01 | <KatieHuber> | if it stays the same, then you can probably still optimize |
| 21:37:06 | <n00b> | ??? |
| 21:37:19 | <omnId> | n00b: the same as any other function? |
| 21:37:20 | <n00b> | for example the mod or div operator |
| 21:37:20 | <byorgey> | n00b: a function is recursive if it is defined in terms of itself. |
| 21:37:31 | <n00b> | ok |
| 21:37:35 | <byorgey> | n00b: usually, this means there will be a simple case called the 'base case' with no recursion. |
| 21:37:38 | <quicksilver> | KatieHuber: went up from 40fps to 44fps |
| 21:37:45 | <byorgey> | i.e. it's so simple you know the answer right away. |
| 21:38:00 | <quicksilver> | KatieHuber: I guess that means I'm still CPU-bound |
| 21:38:01 | <byorgey> | for example, numDigits a, when a <= 9. |
| 21:38:03 | <quicksilver> | KatieHuber: right? |
| 21:38:05 | <KatieHuber> | sounds that way |
| 21:38:08 | <quicksilver> | ACTION nods |
| 21:38:09 | <n00b> | so can a div operator call itself |
| 21:38:11 | <n00b> | ?? |
| 21:38:21 | <quicksilver> | well the haskell is doing quite a lot of work |
| 21:38:30 | <byorgey> | n00b: and the other case is the recursive case, where the function calls itself on a *simpler* version of the problem, and somehow uses that to build the complete answer. |
| 21:38:32 | <quicksilver> | perlin-noise generated wind turbulence |
| 21:38:37 | <byorgey> | n00b: sure, any Haskell function can call itself. |
| 21:38:55 | <KatieHuber> | time for profiling to see where the CPU time is going, then |
| 21:38:58 | <quicksilver> | ACTION nods |
| 21:39:13 | <byorgey> | n00b: for example, the recurisve case for numDigits was to recognize that if you divide the number by 10, there's one less digit, so you can count the digits of that and then add one. |
| 21:39:18 | <quicksilver> | I might try some simpler particle systems which don't use the perlin noise for comparison :) |
| 21:39:26 | <byorgey> | i.e. numDigits a = 1 + numDigits (a `div` 10) |
| 21:39:27 | <n00b> | base case would be like if n < 0 = error "Positive number only" else n = n + (div n) |
| 21:39:55 | <byorgey> | hold on, you're putting too much in there =) |
| 21:39:58 | <byorgey> | one thing at a time |
| 21:40:02 | <omnId> | n00b: probably div x y | y > x = 0 |
| 21:40:20 | <KatieHuber> | I mean, a double-buffered STREAM_DRAW VBO, and writing directly to the MapBuffer'd pointer (can you even do that in Haskell?) would be the fastest way to get the vertices to the card |
| 21:40:22 | <n00b> | just a algorithm |
| 21:40:41 | <KatieHuber> | but there's a good chance that your problem isn't in the GL at all |
| 21:40:47 | <quicksilver> | KatieHuber: I've not tried using vertex buffer stuff |
| 21:41:02 | <quicksilver> | KatieHuber: this is all a great begin glBegin(GL_TRIANGLES) |
| 21:41:07 | <KatieHuber> | OMG :/ |
| 21:41:11 | <KatieHuber> | well, start there then :p |
| 21:41:30 | <quicksilver> | can you change colour in the middle of a vertex buffer? |
| 21:41:38 | <n00b> | remember it must be recursive |
| 21:41:49 | <KatieHuber> | you can submit a color array |
| 21:42:32 | <omnId> | n00b: what's div 2 3? |
| 21:42:57 | <n00b> | 0 |
| 21:43:07 | <quicksilver> | KatieHuber: yeah, I'm fairly sure it's my physics engine not my GL code which is the limiting factor |
| 21:43:08 | <omnId> | n00b: what made you figure that out? |
| 21:43:21 | <quicksilver> | KatieHuber: I wasn't sure though, until you pointed that out :) so, thanks. |
| 21:43:34 | <omnId> | n00b: 3 > 2 |
| 21:43:46 | <omnId> | n00b: and div 4 3? |
| 21:43:59 | <n00b> | 1 |
| 21:44:04 | <quicksilver> | KatieHuber: perlin noise is slow, probably I should cache some values to avoid recomputation. |
| 21:44:23 | <n00b> | so it is possible to recursively div two numbers |
| 21:44:41 | <n00b> | or more |
| 21:44:41 | <omnId> | n00b: div 4 3 = 1 + div (4 - 3) 3 |
| 21:45:38 | <omnId> | you can think of division as iterated subtraction |
| 21:48:16 | <hpaste> | n00b pasted "(no title)" at http://hpaste.org/3315 |
| 21:48:27 | <n00b> | getting a stack overflow |
| 21:48:37 | <omnId> | n00b: y > x |
| 21:48:46 | <omnId> | div 2 3 | 3 > 2 = 0 |
| 21:48:52 | <omnId> | or x < y |
| 21:51:24 | <quicksilver> | KatieHuber: Ah. If i try a larger number of simpler particles (10,000 particles with just simple ballistic movement), then I get 20fps onscreen but 40fps offscreen |
| 21:51:39 | <quicksilver> | KatieHuber: so there is in fact definite room for improvement :) |
| 21:52:27 | <KatieHuber> | yup |
| 21:52:45 | <dibblego> | ?check \f -> (Nothing >>= (f :: Int -> Maybe Int)) == Nothing -- why is there no instance of Arbitrary for Maybe? |
| 21:52:46 | <lambdabot> | add an instance declaration for (Arbitrary (Maybe Int)) In the exp... |
| 21:53:11 | <quicksilver> | KatieHuber: is there a rough order of magnitude I ought to be aiming for? 100,000 simply textured particles at 60fps, perhaps? |
| 21:53:18 | <quicksilver> | KatieHuber: this is a fairly modern laptop |
| 21:53:54 | <KatieHuber> | again, depends far more on blending and particle size than on the number of particles |
| 21:54:26 | <quicksilver> | I'm definitely using alpha and modulate |
| 21:54:34 | <quicksilver> | some particles I use additive blending on |
| 21:56:20 | <KatieHuber> | if all the particles are offscreen, 100000@60fps doesn't sound unreasonable |
| 21:56:26 | <quicksilver> | ACTION nods |
| 21:56:29 | <shapr> | Would "installHandler keyboardSignal" try to read from stdin? |
| 21:57:05 | <KatieHuber> | if they're all onscreen and blended and say, 30ish pixels square, you'll get many fewer, maybe 5-10k@60fps |
| 21:57:14 | <KatieHuber> | depends massively on your graphics card |
| 21:57:32 | <KatieHuber> | really not possible to give a sensible answer :/ |
| 21:57:37 | <quicksilver> | ACTION nods |
| 21:57:39 | <quicksilver> | understood |
| 21:57:51 | <quicksilver> | it's possible to point me in the direction of the right order of magnitude though :) |
| 21:57:54 | <quicksilver> | which you have... |
| 21:58:09 | <quicksilver> | OK, now to learn about vertex arrays and VBOs |
| 21:59:43 | <vincenz> | @seen psykotic |
| 21:59:44 | <lambdabot> | I saw psykotic leaving #haskell 2h 34m 16s ago, and . |
| 22:01:00 | <TomMD> | Does anyone know if ndm made supero available anywhere? I really would like to play with it. |
| 22:01:24 | <ddarius> | ndm knows. |
| 22:01:45 | <TomMD> | Yes, but lambdabot hasn't seen him for 5 hours and I keep missing him. |
| 22:01:54 | <omnId> | @ask him |
| 22:01:55 | <nopcode> | hey :) |
| 22:02:04 | <abell> | dibblego, I think defining an arbitrary for Maybe would choose frequencies which wouldn't be appropriate in most cases |
| 22:02:17 | <abell> | Like returning Nothing half of the times |
| 22:02:24 | <dibblego> | abell, I guess |
| 22:02:28 | <nopcode> | how do i get, for each item in a list, the item and the rest of the list? |
| 22:02:32 | <nopcode> | (with the item removed) |
| 22:02:49 | <dibblego> | > tails [1..10] |
| 22:02:52 | <lambdabot> | [[1,2,3,4,5,6,7,8,9,10],[2,3,4,5,6,7,8,9,10],[3,4,5,6,7,8,9,10],[4,5,6,7,8,9... |
| 22:02:57 | <dibblego> | like that? |
| 22:03:16 | <Olathe> | @pl xs -> zip (heads xs) (tails xs) |
| 22:03:16 | <lambdabot> | (line 1, column 4): |
| 22:03:16 | <lambdabot> | unexpected ">" or "-" |
| 22:03:16 | <lambdabot> | expecting variable, "(", operator or end of input |
| 22:03:17 | <nopcode> | no, i want to pick an item in the middle of the list too, resulting in the item and the list without that item |
| 22:03:25 | <Olathe> | O...K |
| 22:03:26 | <dmwit> | see |
| 22:03:28 | <omnId> | f [1,2,3] = [(1,[2,3]), (2,[1,3]), (3,[1,2])]? |
| 22:03:31 | <dmwit> | http://okmij.org/ftp/Haskell/perfect-shuffle.txt |
| 22:03:38 | <dibblego> | @pl \xs -> zip (heads xs) (tails xs) |
| 22:03:39 | <lambdabot> | liftM2 zip heads tails |
| 22:03:47 | <dmwit> | There's a function there called "extract" which does what you're describing. |
| 22:03:49 | <Olathe> | @pl \xs -> zip (heads xs) (tails xs) |
| 22:03:49 | <lambdabot> | liftM2 zip heads tails |
| 22:03:54 | <Olathe> | Take that ! |
| 22:03:59 | <oerjan> | @let extract l = [(x,bef++aft) | (bef,x:aft) <- zip (inits l) (tails l)] |
| 22:04:04 | <lambdabot> | Defined. |
| 22:04:08 | <omnId> | > liftM2 zip heads tails [1,2,3] |
| 22:04:08 | <lambdabot> | Not in scope: `heads' |
| 22:04:12 | <oerjan> | > extract [1..10] |
| 22:04:14 | <lambdabot> | [(1,[2,3,4,5,6,7,8,9,10]),(2,[1,3,4,5,6,7,8,9,10]),(3,[1,2,4,5,6,7,8,9,10]),... |
| 22:04:20 | <Olathe> | Ahh, inits. |
| 22:04:27 | <omnId> | > liftM2 zip inits tails [1,2,3] |
| 22:04:29 | <lambdabot> | [([],[1,2,3]),([1],[2,3]),([1,2],[3]),([1,2,3],[])] |
| 22:04:34 | <TomMD> | @ask ndm Is superO available to the public? I've got a MD5 implementation (2-5x slower than C when using GHC -O2) I thought might be fun to test with superO... provided I can get it setup with Data.ByteString |
| 22:04:35 | <lambdabot> | Consider it noted. |
| 22:04:40 | <Olathe> | Bah. |
| 22:04:46 | <Olathe> | @pl \xs -> zip xs (tails xs) |
| 22:04:46 | <lambdabot> | ap zip tails |
| 22:04:58 | <omnId> | > map (\(xs,y:ys) -> (y, xs++ys)) $ liftM2 zip inits tails [1,2,3] |
| 22:05:00 | <lambdabot> | Non-exhaustive patterns in lambda |
| 22:05:03 | <Olathe> | > (ap zip tails) [1, 2, 3, 4] |
| 22:05:04 | <lambdabot> | [(1,[1,2,3,4]),(2,[2,3,4]),(3,[3,4]),(4,[4])] |
| 22:05:15 | <nopcode> | hm :) |
| 22:05:16 | <ddarius> | > fix ((0:) . (1:) . ap (zipWith (+)) tail) |
| 22:05:18 | <lambdabot> | [0,1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,1597,2584,4181,6765,10946,... |
| 22:05:27 | <Olathe> | @pl \xs -> zip xs (tail (tails xs)) |
| 22:05:27 | <lambdabot> | ap zip (tail . tails) |
| 22:05:38 | <Olathe> | > (ap zip (tail . tails)) [1, 2, 3, 4] |
| 22:05:39 | <lambdabot> | [(1,[2,3,4]),(2,[3,4]),(3,[4]),(4,[])] |
| 22:05:42 | <shapr> | Aha! it was installHandler keyboardSignal! |
| 22:05:52 | <omnId> | > take 3 $ map (\(xs,y:ys) -> (y, xs++ys)) $ tail $ liftM2 zip inits tails [1,2,3] |
| 22:05:54 | <lambdabot> | Non-exhaustive patterns in lambda |
| 22:06:17 | <ddarius> | > let f !a = a in f 3 |
| 22:06:19 | <lambdabot> | Not in scope: `f' |
| 22:06:22 | <Olathe> | @pl \xs -> map (\t -> (head t, tail t)) (tails xs) |
| 22:06:23 | <lambdabot> | map (liftM2 (,) head tail) . tails |
| 22:06:31 | <Olathe> | > (map (liftM2 (,) head tail) . tails) [1, 2, 3, 4] |
| 22:06:32 | <lambdabot> | Exception: Prelude.head: empty list |
| 22:06:49 | <omnId> | > init $ map (\(xs,y:ys) -> (y, xs++ys)) $ liftM2 zip inits tails [1,2,3] |
| 22:06:50 | <lambdabot> | [(1,[2,3]),(2,[1,3]),(3,[1,2])] |
| 22:06:56 | <omnId> | :D |
| 22:07:15 | <Olathe> | @src mapWhile |
| 22:07:15 | <lambdabot> | Source not found. Just what do you think you're doing Dave? |
| 22:07:29 | <TomMD> | @src infinity |
| 22:07:29 | <lambdabot> | Source not found. Your mind just hasn't been the same since the electro-shock, has it? |
| 22:07:36 | <dmwit> | map f . takeWhile p ? |
| 22:07:44 | <dmwit> | ?src Infinity |
| 22:07:45 | <lambdabot> | Source not found. I can't hear you -- I'm using the scrambler. |
| 22:08:17 | <oerjan> | Infinity is only a Read/Show thing, not a real constructor |
| 22:08:20 | <Olathe> | @pl \xs -> map (\t -> (head t, tail t)) (takeWhile (not . null) (tails xs)) |
| 22:08:21 | <lambdabot> | map (liftM2 (,) head tail) . takeWhile (not . null) . tails |
| 22:08:33 | <Olathe> | > (map (liftM2 (,) head tail) . takeWhile (not . null) . tails) [1, 2, 3, 4] |
| 22:08:34 | <lambdabot> | [(1,[2,3,4]),(2,[3,4]),(3,[4]),(4,[])] |
| 22:08:43 | <omnId> | > init $ map (\(xs,y:ys) -> (y, xs++ys)) $ liftM2 zip inits tails [1,2,3,4] |
| 22:08:45 | <lambdabot> | [(1,[2,3,4]),(2,[1,3,4]),(3,[1,2,4]),(4,[1,2,3])] |
| 22:08:45 | <ddarius> | @let fib n = fib' n 0 1 0 1 where fib' 0 a b c d = a; fib' n a b p q | a `seq` b `seq` p `seq` q `seq` False | even n = fib' (n `div` 2) a b (p*p+q*q) (2*p*q+q*q) | otherwise = fib' (n - 1) ((p+q)*a+q*b) (q*a+p*b) p q |
| 22:08:46 | <lambdabot> | Parse error |
| 22:09:04 | <Olathe> | Oh. |
| 22:09:15 | <Olathe> | I've been doing it wrong this whole time. |
| 22:09:39 | <dmwit> | > let extract n xs = let (b, m:e) = splitAt n xs in (m, b++e) in extract 5 [1..10] |
| 22:09:40 | <lambdabot> | (6,[1,2,3,4,5,7,8,9,10]) |
| 22:10:45 | <ddarius> | @let fib n = fib' n 0 1 0 1 where fib' n a b p q | n `seq` a `seq` b `seq` p `seq` q `seq` False = undefined;fib' 0 a _ _ _ = a; fib' n a b p q | even n = fib' (n `div` 2) a b (p*p+q*q) (2*p*q+q*q) | otherwise = fib' (n - 1) ((p+q)*a+q*b) (q*a+p*b) p q |
| 22:10:49 | <omnId> | > zipWith (\i xs -> (xs !! i, take i xs ++ drop (i+1) xs) [0..] $ (\xs -> map (const xs) xs) [1,2,3,4] |
| 22:10:49 | <lambdabot> | Unbalanced parenthesis |
| 22:10:51 | <lambdabot> | Defined. |
| 22:11:00 | <ddarius> | > fib 20 |
| 22:11:01 | <omnId> | > zipWith (\i xs -> (xs !! i, take i xs ++ drop (i+1) xs)) [0..] $ (\xs -> map (const xs) xs) [1,2,3,4] |
| 22:11:03 | <lambdabot> | [(1,[2,3,4]),(2,[1,3,4]),(3,[1,2,4]),(4,[1,2,3])] |
| 22:11:03 | <lambdabot> | 6765 |
| 22:11:14 | <ddarius> | > map fib [1..20] |
| 22:11:15 | <lambdabot> | [1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,1597,2584,4181,6765] |
| 22:11:30 | <AndyC> | Hi, can anyone help me with a Parsec question please? |
| 22:11:48 | <dmwit> | shoot! |
| 22:11:53 | <Olathe> | > map fibs [270,273..280] |
| 22:11:54 | <lambdabot> | Not in scope: `fibs' |
| 22:11:58 | <Olathe> | > map fib [270,273..280] |
| 22:12:00 | <lambdabot> | [119447720249892581203851665820676436622934188700177088360,50598866273592314... |
| 22:12:30 | <AndyC> | Thanks. I am trying to parse some binary data (actually it's a Java class file). |
| 22:12:31 | <jonathanv> | my goodness, this fib function confuses me |
| 22:13:05 | <AndyC> | I'm looking at the bytecode that can be a variable number of bytes. |
| 22:13:54 | <AndyC> | I want to parse the first byte, do a case of on it to work out how many more bytes to read, read them then return something. |
| 22:14:26 | <AndyC> | I'm fine up until the second bit of parsing e.g. read in two more bytes. |
| 22:14:38 | <dmwit> | > let phi = (1 + sqrt 5) / 2; fib n = round ((phi ** n - (negate phi) ** (negate n)) / sqrt 5) in fib 1 |
| 22:14:40 | <lambdabot> | 1 |
| 22:14:43 | <AndyC> | Any ideas on a direction please? |
| 22:14:46 | <dmwit> | > let phi = (1 + sqrt 5) / 2; fib n = round ((phi ** n - (negate phi) ** (negate n)) / sqrt 5) in map fib [1..10] |
| 22:14:47 | <lambdabot> | [1,1,2,3,5,8,13,21,34,55] |
| 22:15:07 | <dmwit> | > let phi = (1 + sqrt 5) / 2; fib n = round ((phi ** n - (negate phi) ** (negate n)) / sqrt 5) in map fib [270,273..280] |
| 22:15:08 | <lambdabot> | [119447720249893657237202506912376692627920328520374419456,50598866273592779... |
| 22:15:12 | <omnId> | do n <- anyToken; bytes <- sequence (replicate n anyToken); ... -- something like that maybe |
| 22:15:21 | <dmwit> | Doesn't seem exact. |
| 22:15:24 | <nopcode> | hm |
| 22:15:32 | <nopcode> | i guess this would be easier if i just removed the element from the list |
| 22:15:43 | <nopcode> | by searching for it |
| 22:15:48 | <dmwit> | nopcode: What are you trying to do? |
| 22:15:55 | <oerjan> | :t replicateM |
| 22:15:57 | <lambdabot> | forall (m :: * -> *) a. (Monad m) => Int -> m a -> m [a] |
| 22:15:58 | <dmwit> | omnId: Are you familiar with do-notation for monads? |
| 22:16:07 | <dmwit> | err... |
| 22:16:08 | <AndyC> | After the first anyToken I need to look at n and decide how many more to read. |
| 22:16:09 | <nopcode> | dmwit: well it's a logic puzzle |
| 22:16:19 | <omnId> | dmwit: AndyC*? :) |
| 22:16:22 | <dmwit> | yes |
| 22:16:24 | <dmwit> | sorry |
| 22:16:32 | <AndyC> | yes |
| 22:16:33 | <AndyC> | ish |
| 22:16:34 | <nopcode> | dmwit: people walking over the bridge... i need to expand the state |
| 22:16:37 | <dmwit> | AndyC: Okay, no problem. |
| 22:17:02 | <nopcode> | i've got a state with lists l and r, representing the list of people on each side |
| 22:17:25 | <glguy> | ACTION reminds hpasters to use the annotate functionality when pasting revisions of existing code |
| 22:17:28 | <nopcode> | now i want to get all states which can be derived from this by moving one person in list 'r' to list 'l' |
| 22:17:36 | <dmwit> | varLength = do { length <- number; case length of { 0 -> fail "bad file"; n -> replicateM n anyToken } } |
| 22:17:47 | <dmwit> | AndyC: But more likely, you'd want: |
| 22:17:59 | <dmwit> | varLength = number >>= replicateM anyToken |
| 22:18:02 | <dmwit> | :t replicateM |
| 22:18:04 | <lambdabot> | forall (m :: * -> *) a. (Monad m) => Int -> m a -> m [a] |
| 22:18:06 | <nopcode> | so, how do i get a list with the first occurence of a given item removed? |
| 22:18:11 | <AndyC> | Ah, sorry. Hang on. |
| 22:18:23 | <dmwit> | AndyC: Well, you get the idea, though there might need to be a "flip" in my code somewhere. =P |
| 22:18:30 | <omnId> | you're parsing [Byte]? |
| 22:18:35 | <AndyC> | The first byte I read isn't how many more to read. It's an opcode. |
| 22:18:58 | <AndyC> | Some opcodes want two more bytes, some want one, some don't need any. |
| 22:19:15 | <dmwit> | AndyC: It doesn't matter what you're reading; the technique I just showed should apply equally well. |
| 22:19:55 | <dmwit> | nopcode: delete? |
| 22:19:55 | <AndyC> | So I want to say something like do op <- anyToken; case op of 0 -> arg <- parseIndex; return C op arg; |
| 22:19:56 | <dmwit> | :t delete |
| 22:19:57 | <oerjan> | AndyC: btw Parsec defines count which i guess is a restricted synonym for replicateM |
| 22:19:58 | <lambdabot> | forall a. (Eq a) => a -> [a] -> [a] |
| 22:20:00 | <TomMD> | nopcode: Look at Data.List (delete, deleteBy, deleteFirstBy) |
| 22:20:17 | <puusorsa> | .. damn |
| 22:20:36 | <dmwit> | AndyC: right |
| 22:20:36 | <AndyC> | oerjan: Thanks, I've used that elsewhere already. |
| 22:20:39 | <nopcode> | ok thanks |
| 22:20:42 | <puusorsa> | 20sec too slow, almost managed to say something helpful :) |
| 22:21:24 | <dmwit> | AndyC: Though in the case statement, you'll need to add the "do" keyword again, because at that point you're out of the original do block. |
| 22:21:33 | <TomMD> | puusorsa: That would have made four. I already came in third - its no wonder our community is small, I keep forgetting people don't like being smothered. |
| 22:22:25 | <AndyC> | dmwit: Yeah, I tried that and I can't get it just so. Is the state after the 1st do still getting threaded into the 2nd do? |
| 22:22:48 | <dmwit> | AndyC: Things in scope in the first do should still be in scope in the case statement. |
| 22:23:02 | <dmwit> | AndyC: Why don't you paste the code you're trying to use? It will be a lot easier for us to help you. |
| 22:23:03 | <dmwit> | ?hpaste |
| 22:23:03 | <lambdabot> | Haskell pastebin: http://hpaste.org/new |
| 22:23:32 | <AndyC> | Cos, it's on a different computer at work :-( |
| 22:24:00 | <AndyC> | It's my first time daring to enter. I don't know what I was afraid of. |
| 22:24:00 | <dmwit> | ... |
| 22:24:30 | <dmwit> | ok |
| 22:24:41 | <AndyC> | I'll come back another time with something to show you. Thanks very much for your help. |
| 22:24:49 | <dmwit> | Well, good luck! |
| 22:24:50 | <dmwit> | =) |
| 22:25:58 | <ddarius> | He should join some other IRC channels... |
| 22:46:35 | <raxas> | ACTION failed miserably to coerce his girlfriend into haskell |
| 22:47:26 | <dmwit> | ACTION failed miserably to coerce his girlfriend into programming |
| 22:47:42 | <dmwit> | You're one step ahead of the game, raxas. =) |
| 22:48:49 | <Spark> | every so often, when we're on enough drugs, i try to teach my girlfriend about programming |
| 22:48:56 | <Spark> | usually she gets bored and i get frustrated and then the drugs wear off |
| 22:49:05 | <dolio> | That's the best time to learn stuff. |
| 22:49:28 | <jonathanv> | what drugs |
| 22:49:43 | <Spark> | amphetamine usually |
| 22:49:51 | <jonathanv> | gross |
| 22:50:10 | <nopcode> | how do i apply a function to a tuple of arguments? |
| 22:50:23 | <dmwit> | Same as usual, put them next to each other. |
| 22:50:25 | <raxas> | dmwit: Of course. We keep dating for more than 12 years now. But she said "No, I am too old for such a crazy coding." |
| 22:50:29 | <dmwit> | f (a, b, c) |
| 22:50:42 | <jonathanv> | why can't people just stick to weed |
| 22:50:44 | <nopcode> | nah i mean i want each element of the tuple to become one argument |
| 22:50:46 | <dmwit> | raxas: Hahaha, that's a pretty awesome quote. |
| 22:50:50 | <Japsu> | nopcode: use uncurry |
| 22:51:02 | <omnId> | (\(x,y,z) -> f x y z) |
| 22:51:14 | <Japsu> | > uncurry (\x y -> x + y) $ (1,2) |
| 22:51:16 | <lambdabot> | 3 |
| 22:51:24 | <omnId> | @src uncurry |
| 22:51:24 | <lambdabot> | uncurry f p = f (fst p) (snd p) |
| 22:51:28 | <Spark> | jonathanv: maybe because it makes you fall asleep or go insane |
| 22:51:30 | <omnId> | already does it for (x, y) |
| 22:51:40 | <Japsu> | hmm |
| 22:51:48 | <dmwit> | > (+1) &&& concat $ (3, [[4,5],[6,7,8]]) |
| 22:51:49 | <lambdabot> | Couldn't match expected type `[[a]]' |
| 22:51:54 | <Japsu> | @pl \f (x,y,z) -> f x y z |
| 22:51:54 | <lambdabot> | (line 1, column 8): |
| 22:51:55 | <lambdabot> | unexpected "," |
| 22:51:55 | <lambdabot> | expecting letter or digit, operator or ")" |
| 22:51:55 | <lambdabot> | ambiguous use of a non associative operator |
| 22:51:56 | <jonathanv> | if weed makes you fall asleep, maybe you need that sleep |
| 22:52:01 | <dmwit> | > ((+1) &&& concat) (3, [[4,5],[6,7,8]]) |
| 22:52:02 | <lambdabot> | Couldn't match expected type `[[a]]' |
| 22:52:03 | <omnId> | dmwit: (***) |
| 22:52:10 | <dmwit> | oh, right |
| 22:52:20 | <dmwit> | > (+1) *** concat $ (3, [[4,5],[6,7,8]]) |
| 22:52:21 | <lambdabot> | (4,[4,5,6,7,8]) |
| 22:53:49 | <Japsu> | why can't I suddenly pattern match with a triplet |
| 22:53:56 | <Japsu> | in a lambda |
| 22:53:57 | <Japsu> | @pl let uc3 f (x,y,z) = f x y z in uc3 |
| 22:53:58 | <lambdabot> | (line 1, column 15): |
| 22:53:58 | <lambdabot> | unexpected "," |
| 22:53:58 | <lambdabot> | expecting letter or digit, operator or ")" |
| 22:53:58 | <lambdabot> | ambiguous use of a non associative operator |
| 22:54:06 | <dmwit> | Japsu: You can, it's just ?pl that doesn't know about that. |
| 22:54:09 | <Japsu> | right |
| 22:54:13 | <oerjan> | Japsu: since there are no functions to unpack a triplet, @pl cannot do anything about them |
| 22:54:21 | <Japsu> | k |
| 22:54:34 | <dmwit> | > (\(x, y, z) -> x + y + z) (3,4,7) |
| 22:54:36 | <lambdabot> | 14 |
| 22:55:01 | <omnId> | @type let uc3 f (x,y,z) = f x y z in uc3 |
| 22:55:02 | <lambdabot> | forall t t1 t2 t3. (t -> t1 -> t2 -> t3) -> (t, t1, t2) -> t3 |
| 22:57:15 | <omnId> | @pl (\f ((x,y),z) -> f x y z) -- it works if you use nested pairs, not pretty though :) |
| 22:57:15 | <lambdabot> | (`ap` snd) . (. fst) . (`ap` snd) . (. fst) |
| 22:59:42 | <Olathe> | @shorten (`ap` snd) . (. fst) . (`ap` snd) . (. fst) |
| 22:59:42 | <lambdabot> | Unknown command, try @list |
| 22:59:44 | <Olathe> | :( |
| 23:00:02 | <omnId> | (\f ((x,y),z) -> f x y z) -- :) |
| 23:00:24 | <omnId> | @type (`ap` snd) . fst |
| 23:00:26 | <lambdabot> | forall b a b1 b2. ((a, b1) -> b1 -> b, b2) -> (a, b1) -> b |
| 23:00:38 | <oerjan> | :t uncurry.uncurry |
| 23:00:41 | <lambdabot> | forall b c a b1. (a -> b1 -> b -> c) -> ((a, b1), b) -> c |
| 23:02:00 | <oerjan> | short enough? :) |
| 23:02:08 | <nopcode> | %) |
| 23:06:22 | <ivanm> | what's the difference between record-style types and "standard" types? |
| 23:06:33 | <ivanm> | record-style types are just named versions of the latter? |
| 23:06:44 | <sjanssen> | ivanm: not very much |
| 23:06:59 | <ivanm> | *nod* |
| 23:07:03 | <Vulpyne> | It's usually easier to deal with stuff by name than position. |
| 23:07:18 | <Vulpyne> | Especially if you reorder things or add/remove fields. |
| 23:07:21 | <sjanssen> | record style just introduces accessor functions and allows the {} pattern matching and update syntax |
| 23:07:27 | <ivanm> | so can you use record-style with pattern matching like with normal types? |
| 23:08:07 | <ivanm> | e.g. data FooBar = FB {foo :: String, bar :: String} ... f :: FooBar -> String, f FB f b = f ++ b |
| 23:08:10 | <ivanm> | would that work? |
| 23:08:18 | <omnId> | data T = C { x :: U } is like data T = C U; x (C a) = a |
| 23:08:20 | <ivanm> | make that f (FB f b) |
| 23:08:45 | <ivanm> | so does pattern matching work? |
| 23:09:03 | <omnId> | yes |
| 23:09:28 | <omnId> | also f (FB {foo = f, bar = b}) = f ++ b |
| 23:09:34 | <ivanm> | *nod* |
| 23:09:57 | <ivanm> | though presumably record-style makes it easier to extract one particular variable than in non-record style or by using a tuple? |
| 23:09:57 | <oerjan> | > case Just 1 of Just {} -> True; _ -> False |
| 23:10:03 | <lambdabot> | True |
| 23:10:26 | <ivanm> | how did that work? the {} matches everything? |
| 23:10:57 | <EvilRanter> | it's a curiosity of the grammar |
| 23:11:06 | <ivanm> | *nod* |
| 23:11:16 | <EvilRanter> | it's record syntax for "record with no fixed fields" |
| 23:11:22 | <ivanm> | ahhh |
| 23:11:33 | <ivanm> | so {} is equivalent to _ ? |
| 23:11:33 | <EvilRanter> | but it happens to work for constructors that weren't defined as records, too |
| 23:11:45 | <ddarius> | ivanm: No. |
| 23:11:52 | <omnId> | ivanm: a record pattern needs a Constructor |
| 23:11:54 | <EvilRanter> | it's independent of number of parameters on the constructor |
| 23:11:55 | <ivanm> | so is that a curiosity as defined in H98, or just implementation-specific |
| 23:12:00 | <ivanm> | ddarius, omnId: *nod* |
| 23:12:10 | <ivanm> | EvilRanter: ahhhhh |
| 23:12:13 | <oerjan> | H98 |
| 23:12:17 | <EvilRanter> | > case (1,2) of (,) {} -> True; _ -> False |
| 23:12:18 | <lambdabot> | Warning: Pattern match(es) are overlapped |
| 23:12:18 | <lambdabot> | In a case alterna... |
| 23:12:35 | <EvilRanter> | hm. well, it parsed, so it made my point :) |
| 23:12:39 | <ivanm> | so its a way of pattern matching constructors rather than just the parameters? |
| 23:12:47 | <ivanm> | i.e. working out which constructor was used |
| 23:12:56 | <omnId> | Just {} is equivalent to Just _ |
| 23:13:20 | <oerjan> | would have been nice if you could do the opposite - pattern match on a field regardless of constructor |
| 23:13:24 | <omnId> | say Constr has 3 fields, Constr {} is Constr _ _ _ |
| 23:13:34 | <ivanm> | *nod* |
| 23:13:35 | <oerjan> | but alas |
| 23:13:36 | <ddarius> | oerjan: That would rarely make sense. |
| 23:14:06 | <ivanm> | oerjan: wouldn't that only work with constructors with the same number of parameters, and possibly the same types of parameters? |
| 23:14:09 | <oerjan> | ddarius: say if you have a type with two constructors that share a field |
| 23:14:45 | <ddarius> | I didn't say it never made sense. |
| 23:14:58 | <omnId> | ivanm: different constructors can share a field name, but it must have the same type. |
| 23:15:17 | <ivanm> | *nod* |
| 23:15:17 | <omnId> | data Foo = Bar { x :: String, y :: Int } | Baz { x :: String } |
| 23:15:25 | <omnId> | x :: Foo -> String |
| 23:15:55 | <ivanm> | so to access the x field, if fb :: Foo, then its just fb.x ? |
| 23:16:06 | <ddarius> | This isn't Java. |
| 23:16:06 | <omnId> | x fb |
| 23:16:13 | <omnId> | x is a selector function |
| 23:16:21 | <ddarius> | x is just a function |
| 23:16:24 | <omnId> | hence x :: Foo -> String |
| 23:17:36 | <ivanm> | oh.... I was going off this: http://research.microsoft.com/~simonpj/Haskell/records.html |
| 23:17:43 | <ivanm> | or is this just a proposal? |
| 23:18:00 | <omnId> | just a proposal |
| 23:18:37 | <omnId> | modifyX f foo@(Foo {x = oldx}) = foo {x = f oldx} -- a sensible modifyX definition |
| 23:20:11 | <ivanm> | ahhh |
| 23:23:40 | <Betovsky> | hi |
| 23:23:43 | <Betovsky> | one question |
| 23:24:06 | <shapr> | ? |
| 23:24:20 | <Betovsky> | let fun = (scanl1 (*)) . enumFromTo 1 |
| 23:24:23 | <Betovsky> | this works |
| 23:24:32 | <Betovsky> | let fun = (scanl1 (*)) . enumFromTo |
| 23:24:36 | <Betovsky> | this doesnt work |
| 23:24:51 | <Betovsky> | shouldnt be able to work? |
| 23:24:59 | <Betovsky> | being fun to receive 2 args |
| 23:25:02 | <EvilRanter> | ?type (scanl1 (*)) . enumFromTo |
| 23:25:03 | <chessguy> | @type (scanl1 (*)) . enumFromTo |
| 23:25:07 | <lambdabot> | Couldn't match expected type `[a]' |
| 23:25:07 | <lambdabot> | against inferred type `a1 -> [a1]' |
| 23:25:09 | <lambdabot> | Couldn't match expected type `[a]' |
| 23:25:09 | <lambdabot> | against inferred type `a1 -> [a1]' |
| 23:25:13 | <EvilRanter> | ?type (.) |
| 23:25:16 | <lambdabot> | forall b c a. (b -> c) -> (a -> b) -> a -> c |
| 23:25:16 | <oerjan> | . always threads exactly one argument |
| 23:25:19 | <EvilRanter> | ?type scanl1 (*) |
| 23:25:21 | <lambdabot> | forall a. (Num a) => [a] -> [a] |
| 23:25:26 | <EvilRanter> | ?type enumFromTo |
| 23:25:28 | <lambdabot> | forall a. (Enum a) => a -> a -> [a] |
| 23:25:29 | <omnId> | fun1 x = scanl1 (*) [1..x] ; fun2 x = scanl1 (*) [x .. ???] |
| 23:25:57 | <EvilRanter> | ?src (.) |
| 23:25:57 | <lambdabot> | (.) f g x = f (g x) |
| 23:25:59 | <Betovsky> | hmm i think i see |
| 23:26:07 | <EvilRanter> | (f . g) x = f (g x) |
| 23:26:13 | <EvilRanter> | so (f . g) x y = f (g x) y |
| 23:26:34 | <Betovsky> | isn't there something like (.) but the second function receives 2 args? |
| 23:26:41 | <omnId> | @type let (f .: g) x y = f (g x y) in scanl1 (*) .: enumFromTo |
| 23:26:43 | <lambdabot> | forall a. (Num a, Enum a) => a -> a -> [a] |
| 23:27:09 | <oerjan> | @pl \f g x y -> f (g x y) |
| 23:27:10 | <lambdabot> | (.) . (.) |
| 23:27:25 | <omnId> | ((f .) . g) x y = (f .) (g x) y = (f . g x) y = f (g x y) |
| 23:27:28 | <chessguy> | ah, the old hooter |
| 23:27:43 | <omnId> | @type (scanl1 (*) .) . enumFromTo |
| 23:27:45 | <lambdabot> | forall a. (Num a, Enum a) => a -> a -> [a] |
| 23:28:29 | <Betovsky> | hehe |
| 23:28:33 | <Betovsky> | thx |
| 23:28:35 | <oerjan> | more generally, you pack the first function inside as many (_ .) as you need |
| 23:28:59 | <omnId> | @pl \x y z -> f (g x y z) |
| 23:28:59 | <lambdabot> | ((f .) .) . g |
| 23:29:21 | <oerjan> | @pl \f g x y z -> f (g x y z) |
| 23:29:21 | <lambdabot> | (.) . (.) . (.) |
| 23:29:59 | <Betovsky> | hmm |
| 23:30:12 | <chessguy> | by the way everyone, it's now been proven that any 2 numbers are equal to each other. all of mathematics is screwed. time to go home. http://www.mathbin.net/15013 |
| 23:30:16 | <lambdabot> | Title: MathBin.net - Proof that any 2 numbers are equal to each other |
| 23:31:28 | <oerjan> | @slap chessguy |
| 23:31:29 | <lambdabot> | ACTION smacks chessguy about with a large trout |
| 23:31:38 | <chessguy> | ACTION grins |
| 23:34:36 | <roconnor> | conal: I made my first phooey application with a gtk2hs backend. |
| 23:34:55 | <roconnor> | conal: runUI (stringEntry "Initial String" >>= stringDisplay) |
| 23:40:14 | <roconnor> | ACTION doesn't believe that the limit of integrals is the same as the integral of a limit. |
| 23:40:39 | <oerjan> | indeed not without further restrictions |
| 23:43:25 | <gwern> | hey everyone. I remember someone once telling me that a way to improve on 'nub' performance was instead a (toList . fromList) using Data.Set or whatever, but that the latter did not produce the exact same output as the former somehow - that the better performance came at a cost |
| 23:43:33 | <gwern> | does anyone remember what the difference was? |
| 23:43:43 | <gwern> | (I'd test for myself, but my ghc is currently broken) |
| 23:43:45 | <oerjan> | order |
| 23:43:59 | <bos> | you'll get your list sorted if you pipe it through a Map or Set. |
| 23:44:33 | <gwern> | a Map too? but I thought it was Set's feature that it didn't admit duplicates |
| 23:45:03 | <bos> | it does, but if you put in [4,3,3,2,5,1], you'll get out [1,2,3,4,5] |
| 23:45:11 | <bos> | doesn't, that is |
| 23:45:26 | <oerjan> | map doesn't admit duplicates either |
| 23:45:52 | <Olathe> | @src nub\ |
| 23:45:52 | <lambdabot> | Source not found. Have you considered trying to match wits with a rutabaga? |
| 23:45:53 | <Olathe> | @src nub |
| 23:45:53 | <lambdabot> | nub = nubBy (==) |
| 23:45:56 | <Olathe> | @src nubBy |
| 23:45:56 | <lambdabot> | nubBy eq [] = [] |
| 23:45:57 | <lambdabot> | nubBy eq (x:xs) = x : nubBy eq (filter (\ y -> not (eq x y)) xs) |
| 23:46:14 | <gwern> | huh. so what exactly is a Map then? (I know I should look this up but I'm feeling lazy) |
| 23:46:40 | <EvilRanter> | a map is a "function" from its key type to its value type |
| 23:46:48 | <omnId> | > M.fromList [(1,'a'), (2,'b')] M.! 2 |
| 23:46:50 | <lambdabot> | 'b' |
| 23:47:06 | <EvilRanter> | so you can have several keys pointing to the same value, but not several instances of the same key |
| 23:47:11 | <gwern> | hmm. so... a little like an array then? |
| 23:47:24 | <EvilRanter> | a (Set a) is kinda like a (Map a ()) |
| 23:47:29 | <oerjan> | i think you can do something hairy with zip [0..] to preserve order using map to nub |
| 23:47:30 | <omnId> | other languages call them hashes or associative arrays. |
| 23:47:53 | <gwern> | ah, I see then |
| 23:47:57 | <EvilRanter> | it is kinda like an array, yeah, in some respects |
| 23:48:10 | <EvilRanter> | but it's got different constraints on the key, and is much less space-efficient |
| 23:48:34 | <EvilRanter> | but better algorithmically for a lot of things; heck, it can even be more space-efficient, if your keys are very spread out |
| 23:48:34 | <oerjan> | actually you may not even need a map, just sortBy |
| 23:48:35 | <jbauman> | tail recursion? |
| 23:48:49 | <jbauman> | oops, scrolled up |
| 23:49:38 | <Olathe> | > let uniq = uniqBy (==); uniqBy eq = uniqBy' eq []; uniqBy _ _ [] = []; uniqBy eq ps (x:xs) = if (elem x ps) then x:(uniqBy' eq (x:ps) xs) else uniqBy' eq ps xs in uniq [5, 2, 3, 5, 4, 2] |
| 23:49:39 | <lambdabot> | arity mismatch for 'uniqBy' |
| 23:49:48 | <Olathe> | > let uniq = uniqBy (==); uniqBy eq = uniqBy' eq []; uniqBy _ _ [] = []; uniqBy' eq ps (x:xs) = if (elem x ps) then x:(uniqBy' eq (x:ps) xs) else uniqBy' eq ps xs in uniq [5, 2, 3, 5, 4, 2] |
| 23:49:48 | <lambdabot> | arity mismatch for 'uniqBy' |
| 23:49:53 | <Olathe> | > let uniq = uniqBy (==); uniqBy eq = uniqBy' eq []; uniqBy' _ _ [] = []; uniqBy' eq ps (x:xs) = if (elem x ps) then x:(uniqBy' eq (x:ps) xs) else uniqBy' eq ps xs in uniq [5, 2, 3, 5, 4, 2] |
| 23:49:56 | <lambdabot> | [] |
| 23:49:59 | <Olathe> | Bah. |
| 23:50:12 | <dcoutts_> | @seen dons |
| 23:50:13 | <lambdabot> | dons is in #xmonad and #haskell. I last heard dons speak 22m ago. |
| 23:50:53 | <Olathe> | > let uniq = uniqBy (==); uniqBy eq = uniqBy' eq []; uniqBy' _ _ [] = []; uniqBy' eq ps (x:xs) = if (any (eq x) ps) then x:(uniqBy' eq (x:ps) xs) else uniqBy' eq ps xs in uniq [5, 2, 3, 5, 4, 2] |
| 23:50:54 | <oerjan> | Olathe: you cannot use elem |
| 23:50:54 | <lambdabot> | [] |
| 23:51:03 | <dcoutts_> | dons: I'd like to do a binary 0.4.1 point release with ghc-6.4, 6.6, 6.8 compatibility |
| 23:51:04 | <oerjan> | too slow :) |
| 23:51:08 | <omnId> | (map head . group . sort) I think would do quickly enough. I'm not sure how it compares to (toList . fromList) |
| 23:51:09 | <Olathe> | I know. |
| 23:51:23 | <Olathe> | I'm doing it with a list, which can then be converted to using a set or something. |
| 23:51:45 | <Olathe> | > let uniq = uniqBy (==); uniqBy eq = uniqBy' eq []; uniqBy' _ _ [] = []; uniqBy' eq ps (x:xs) = if (any (x `eq') ps) then x:(uniqBy' eq (x:ps) xs) else uniqBy' eq ps xs in uniq [5, 2, 3, 5, 4, 2] |
| 23:51:46 | <lambdabot> | Parse error |
| 23:51:50 | <Olathe> | > let uniq = uniqBy (==); uniqBy eq = uniqBy' eq []; uniqBy' _ _ [] = []; uniqBy' eq ps (x:xs) = if (any (x `eq`) ps) then x:(uniqBy' eq (x:ps) xs) else uniqBy' eq ps xs in uniq [5, 2, 3, 5, 4, 2] |
| 23:51:52 | <lambdabot> | [] |
| 23:51:54 | <Olathe> | Bah. |
| 23:52:23 | <Olathe> | > let uniq = uniqBy (==); uniqBy eq = uniqBy' eq []; uniqBy' _ _ [] = []; uniqBy' eq ps (x:xs) = if (any (x `eq`) ps) then uniqBy' eq ps xs else x:(uniqBy' eq (x:ps) xs) in uniq [5, 2, 3, 5, 4, 2] |
| 23:52:24 | <lambdabot> | [5,2,3,4] |
| 23:52:26 | <Olathe> | There. |
| 23:52:31 | <Olathe> | Ordering is preserved. |
| 23:52:46 | <oerjan> | that's just nubBy |
| 23:52:46 | <Olathe> | Not sure how to use sets, though. |
| 23:52:59 | <Olathe> | Right, but you can replace the list with a set to get the speedup. |
| 23:53:06 | <Olathe> | With nubBy, you can't. |
| 23:53:13 | <Olathe> | @src nubBy |
| 23:53:13 | <lambdabot> | nubBy eq [] = [] |
| 23:53:13 | <lambdabot> | nubBy eq (x:xs) = x : nubBy eq (filter (\ y -> not (eq x y)) xs) |
| 23:54:00 | <dons> | dcoutts_: seems reasonable |
| 23:54:05 | <dons> | there was a 32 bit import issue anyway |
| 23:54:09 | <dons> | so we hvae to do a minor release |
| 23:54:18 | <dons> | but backporting all the constructor changes is just sucky |
| 23:54:30 | <dcoutts_> | dons: I've done it, it was easy |
| 23:54:36 | <dcoutts_> | dons: and it's easy to make bytestring-0.9 build with ghc-6.4 and 6.6 |
| 23:54:46 | <dcoutts_> | I've got all the changes locally |
| 23:54:58 | <dcoutts_> | I'm just building the latest ghc snapshot so I can test with 6.8 |
| 23:55:05 | <oerjan> | @let on e f x y = f x `e` f y |
| 23:55:10 | <lambdabot> | Defined. |
| 23:55:35 | <dcoutts_> | dons: and I'll send the changes to unix-compat and tar to bringert |
| 23:55:40 | <dons> | huh, http://alberrto.googlepages.com/easyvision |
| 23:55:42 | <lambdabot> | Title: Alberrto - easyVision |
| 23:55:51 | <dons> | dcoutts_: great work. |
| 23:55:59 | <dons> | that'll keep people happy then |
| 23:56:04 | <dons> | `This is an experimental Haskell system for fast prototyping of computer vision and image processing applications' |
| 23:56:25 | <dcoutts_> | dons: what we need is for cabal-install to support local package repos, so one can test packaging changes locally |
| 23:56:26 | <Olathe> | Ahh, uniqBy won't work, just uniq. |
| 23:56:51 | <dcoutts_> | dons: even better would be 'unpacked' local package repos |
| 23:56:55 | <dons> | mm |
| 23:57:02 | <oerjan> | > map snd . sortBy (comparing fst) . map head . groupBy ((==) `on` snd) . sortBy (comparing snd) . zip [0..] $ [5,2,3,5,4,2] |
| 23:57:04 | <lambdabot> | [5,2,3,4] |
| 23:57:05 | <dcoutts_> | dons: so that it builds from the source tree, rather than a tarball |
| 23:57:41 | <dcoutts_> | dons: imaging unpacking all the tarballs in a hackage repo in place, then just editing and building |
| 23:58:10 | <dons> | yeah |
| 23:59:03 | <Olathe> | > let uniq = uniq' Data.Set.empty; uniq' _ [] = []; uniq' set (x:xs) = if (Data.Set.member x set) then uniq' set xs else (x:uniq' (Data.Set.insert x set) xs) in uniq [5, 2, 3, 5, 4, 2] |
| 23:59:05 | <lambdabot> | [5,2,3,4] |
| 23:59:08 | <Olathe> | There we are. |
Back to channel and daily index: content-negotiated html turtle