Experimental IRC log haskell-2009-05-29

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:07<mmorrow>ACTION gives up trying to figure out the flow from the asm
00:00:10<TomMD>I guess that tells me there isn't any other solid info on the web when IRC logs dominate the first page.
00:00:12<mmorrow>too many indirect jumps
00:01:10<shapr>TomMD: Can't argue with that.
00:03:01<dibblego>@type [minBound..maxBound] -- is this in the standard library?
00:03:03<lambdabot>forall a. (Bounded a, Enum a) => [a]
00:03:07<dibblego>@hoogle (Bounded a, Enum a) => [a]
00:03:08<lambdabot>Prelude enumFrom :: Enum a => a -> [a]
00:03:08<lambdabot>Prelude maxBound :: Bounded a => a
00:03:08<lambdabot>Prelude minBound :: Bounded a => a
00:04:15<mmorrow>oh, maybe that "took" isn't getting stuff unboxed since it's just that single function in its own module, so nothing can be specialized
00:04:46<dolio>Yeah.
00:04:46<mmorrow>preflex: zdec ghczmprim_GHCziTypes_ZC_con_info
00:04:47<preflex> ghc-prim_GHC.Types_:_con_info
00:07:56<iop>ah i see
00:08:18<iop>read 00229 ::Int obv drops the zeros
00:09:01<iop>is there a function: f :: String -> [Char] ?
00:09:16<TomMD>iop: id
00:09:24<TomMD>:-)
00:09:39<ksf_>String _is_ [Char]]
00:09:51<TomMD>hence 'id' will work fine.
00:15:55<iop>i have a String and want to turn each char to an int
00:16:02<iop>String -> [Int]
00:16:06<iop>how?
00:16:17<iop>> map (\x -> read x :: Int) "123"
00:16:18<lambdabot> Couldn't match expected type `[GHC.Types.Char]'
00:16:31<ziman>> map digitToInt "123"
00:16:33<lambdabot> [1,2,3]
00:16:34<skorpan>@hoogle Integer -> Char
00:16:35<lambdabot>Prelude fromInteger :: Num a => Integer -> a
00:16:35<lambdabot>Unsafe.Coerce unsafeCoerce :: a -> b
00:16:35<lambdabot>Prelude show :: Show a => a -> String
00:16:49<skorpan>@hoogle Char -> Integer
00:16:50<lambdabot>Unsafe.Coerce unsafeCoerce :: a -> b
00:16:50<lambdabot>Prelude floatRadix :: RealFloat a => a -> Integer
00:16:50<lambdabot>Prelude toInteger :: Integral a => a -> Integer
00:16:58<skorpan>ah, unsafeCoerce, there we have it
00:17:00<ziman>> map ord "123"
00:17:02<lambdabot> [49,50,51]
00:17:10<ksf_>showDecimal n = showIntAtBase 10 intToDigit n ""
00:17:15<ziman>> unsafeCoerce 0 :: String
00:17:17<lambdabot> Not in scope: `unsafeCoerce'
00:17:25<centrinia>> map (chr. ord) "Hello World!"
00:17:27<lambdabot> "Hello World!"
00:17:29<ksf_>ah, we alrealy have a string
00:17:45<skorpan>> map ((-(ord '0')) . ord) "123"
00:17:47<lambdabot> Couldn't match expected type `b -> c'
00:17:49<skorpan>bah
00:19:14<iop_>> map digitToInt "123"
00:19:16<lambdabot> [1,2,3]
00:19:29<iop_>@index digitToInt
00:19:29<lambdabot>Data.Char
00:20:04<iop_>@src digitToInt
00:20:04<lambdabot>Source not found. And you call yourself a Rocket Scientist!
00:20:26<ksf_>:t (-(1))
00:20:28<lambdabot>forall a. (Num a) => a
00:20:42<ksf_>hmmm... shouldn't that be a (-) section?
00:21:24<amz>> map (-(1)) [1..5]
00:21:25<lambdabot> No instance for (GHC.Num.Num (a -> b))
00:21:25<lambdabot> arising from a use of syntactic n...
00:21:59<amz>guess that it's simply interpreting it as -1
00:22:15<amz>> map ((-)1) [1..5]
00:22:17<lambdabot> [0,-1,-2,-3,-4]
00:22:28<amz>meh
00:22:33<twanvl>> map (subtract 1) [1..5]
00:22:34<lambdabot> [0,1,2,3,4]
00:25:44<jimmyjazz14>map (+) 7) [1..10]
00:25:58<jimmyjazz14>map ((+) 7) [1..10]
00:26:24<jimmyjazz14>lambdabot: :t map
00:26:34<jimmyjazz14>lambdabot: help
00:26:43<shapr>@help
00:26:43<lambdabot>help <command>. Ask for help for <command>. Try 'list' for all commands
00:26:52<shapr>> map (+ 7) [1..10]
00:26:53<lambdabot> [8,9,10,11,12,13,14,15,16,17]
00:27:40<jimmyjazz14>> map ((+) 4) [1..20]
00:27:41<lambdabot> [5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24]
00:27:42<shapr>jimmyjazz14: Do you have ghci installed? Many things that work in ghci will work if you put them after > here on #haskell
00:27:51<jimmyjazz14>heh cool
00:27:53<shapr>:t (+ 4)
00:27:54<lambdabot>forall a. (Num a) => a -> a
00:28:14<jimmyjazz14>:t map
00:28:15<lambdabot>forall a b. (a -> b) -> [a] -> [b]
00:29:20<shapr>:t \a b -> b a
00:29:21<lambdabot>forall t t1. t -> (t -> t1) -> t1
00:29:29<jimmyjazz14>I've been trying to get lambdabot to run on Arch
00:29:39<jimmyjazz14>anyone got that going?
00:29:41<shapr>Not working?
00:29:48<shapr>I haven't tried to build lambdabot recently.
00:29:56<sjanssen>jimmyjazz14: getting lambdabot to build is always a bit of a chore
00:30:55<jimmyjazz14>I was trying to do it with AUR
00:31:13<jimmyjazz14>I get dependency problems with haskell-brainfuck
00:31:28<shapr>I use debian, I assume AUR is the package management system for Arch?
00:31:49<jimmyjazz14>yeah
00:31:55<skorpan>shapr: the user repo stuff
00:32:05<jimmyjazz14>kinda
00:32:05<shapr>oh
00:32:29<skorpan>jimmyjazz14: i think you're just better off cabal installing everything haskellish
00:32:43<skorpan>the AUR has bitten me so many times and cabal mostly works better
00:32:43<jimmyjazz14>yeah I'll probably just do that
00:32:53<skorpan>i never use the AUR for haskell packages anymore
00:33:12<jimmyjazz14>yeah its been a bit of a pain for me
00:34:04<iop_>how do I convert from Int to Double? apparently fromIntegral fosnt do that
00:35:38<sjanssen>iop_: fromIntegral does do that
00:35:45<sjanssen>> fromIntegral (1 :: Int) :: Double
00:35:46<amz>> (fromInteger 5) :: Double
00:35:47<lambdabot> 1.0
00:35:48<lambdabot> 5.0
00:37:19<skorpan>:t fromIntegral
00:37:20<lambdabot>forall a b. (Integral a, Num b) => a -> b
00:37:36<skorpan>:t fromInteger
00:37:38<lambdabot>forall a. (Num a) => Integer -> a
00:37:51<skorpan>so, basically there is no point in using fromInteger as opposed to fromIntegral?
00:38:42<jbauman>> (fromIntegral 1) :: Double
00:38:43<lambdabot> 1.0
00:38:57<skorpan>...is there?
00:39:37<Cale>skorpan: It's important when defining Num instances, and that's about it.
00:39:46<skorpan>how so?
00:39:51<mmorrow>in ghc fromIntegral is implemented with {-# RULES ... #-} for all the types, so it's guaranteed to be the most efficient possible way
00:40:25<Cale>Because fromInteger is a method of the Num class which is responsible for the interpretation of integer literals.
00:40:45<Cale>But other than that, fromIntegral is usually more convenient.
00:41:36<mmorrow>skorpan: yeah, fromInteger is what implicitly happens with all integer literals
00:41:55<mmorrow>1 :: Tree (Maybe (Either (Map () ()) Int))
00:42:00<mmorrow>==> fromInteger 1
00:42:05<Cale>When you write 5435789341075439, the compiler desugars that to fromInteger (5435789341075439 :: Integer)
00:42:33<skorpan>Cale: why is ":: Integer" necessary?
00:42:49<dolio>It isn't.
00:42:53<mmorrow>i think he was just to being explicit
00:42:58<skorpan>oh
00:43:06<Cale>I was just being explicit that it's *actually* an integer there
00:43:30<skorpan>okay, so it does fromInteger... but what is the result type?
00:43:32<Cale>(and not another polymorphic integer literal, because that would be silly)
00:43:32<skorpan>Num a?
00:43:36<Cale>yeah
00:43:47<Cale>:t 5
00:43:49<lambdabot>forall t. (Num t) => t
00:43:58<skorpan>i see
00:44:00<mmorrow>> 1 :: Tree (Maybe (Either (Either () ()) Int))
00:44:01<lambdabot> No instance for (GHC.Num.Num
00:44:01<lambdabot> (Data.Tree.Tree
00:44:01<lambdabot> ...
00:44:06<skorpan>:t fromInteger (2434 :: Integer)
00:44:08<lambdabot>forall a. (Num a) => a
00:44:30<skorpan>:t Tree
00:44:32<lambdabot>Not in scope: data constructor `Tree'
00:44:53<skorpan>does lambdabot have any "builtin" natural number type?
00:45:12<skorpan>as in something like data Nat = Succ Nat | Zero
00:45:28<mmorrow>data E = Lit Integer | E :+ E | E :* E deriving(Eq,Ord,Read,Show); instance Num E where fromInteger = Lit; (+) = (:+); (*) = (:*); signum = undefined; abs = undefined
00:45:44<mmorrow>, src ''Tree
00:45:47<lunabot> data Tree a = Node {rootLabel :: a, subForest :: (Forest a)}
00:46:04<shepheb>having a parsec issue. I've got a parser for variable declarations, and another for statements. the parser for a procedure expects variable declarations followed by statements, but it fails in the vardecls one, on the first statement. it's like it doesn't backtrack far enough.
00:46:52<mmorrow>shepheb: are you using 'try' enough? parsec does depth-first search, so once it commits to a subtree without try, it never looks back
00:47:05<shepheb>possibly not.
00:47:06<mauke>o/` if at first you don't succeed ... o/`
00:47:19<skorpan>the lesson is "never try"
00:47:23<Botje>.. get a bigger gun?
00:47:33<mmorrow>.. cheat?
00:47:53<Botje>.oO(aimbots written in haskell)
00:48:08<Twey>ACTION laughs.
00:48:35<skorpan>:t Nat
00:48:37<lambdabot>Not in scope: data constructor `Nat'
00:48:49<skorpan>so lambdabot does *not* have any builtin natural number type?
00:49:54<roconnor>> 1 : Natural
00:49:55<lambdabot> Not in scope: data constructor `Natural'
00:50:08<roconnor>> 1 :: Natural
00:50:09<lambdabot> 1
00:50:23<skorpan>@src Natural
00:50:23<lambdabot>Source not found. My mind is going. I can feel it.
00:50:28<skorpan>hm...
00:50:37<roconnor>> infinity :: Natural
00:50:39<lambdabot> * Exception: stack overflow
00:50:44<skorpan>> (1 :: Natural) - (2 :: Natural)
00:50:46<lambdabot> * Exception: Natural: (-)
00:50:53<skorpan>> (1 :: Natural) - (1 :: Natural)
00:50:54<lambdabot> 0
00:51:11<skorpan>> fromIntegral (1 :: Natural) :: Integer
00:51:12<lambdabot> 1
00:51:18<skorpan>> fromIntegral (1 :: Natural)
00:51:20<lambdabot> 1
00:51:24<skorpan>> :t fromIntegral (1 :: Natural)
00:51:26<lambdabot> <no location info>: parse error on input `:'
00:51:30<skorpan>:t fromIntegral (1 :: Natural)
00:51:31<lambdabot>forall b. (Num b) => b
00:52:40<skorpan>> (1383148184848 :: Natural) - (1 :: Natural)
00:52:44<lambdabot> * Exception: stack overflow
00:52:48<skorpan>> (1383148184 :: Natural) - (1 :: Natural)
00:52:51<lambdabot> * Exception: stack overflow
00:52:53<skorpan>> (1383148 :: Natural) - (1 :: Natural)
00:52:56<lambdabot> * Exception: stack overflow
00:52:58<skorpan>> (1383 :: Natural) - (1 :: Natural)
00:53:00<lambdabot> 1382
00:53:05<skorpan>there we are
00:53:44<skorpan>> (1383 :: Natural) - (1 :: Integer)
00:53:45<lambdabot> Couldn't match expected type `Data.Number.Natural.Natural'
00:53:58<skorpan>:t (-)
00:53:59<lambdabot>forall a. (Num a) => a -> a -> a
00:54:07<skorpan>ah
00:54:51<BMeph>Hello, everyone. (Back from my stay-cation.)
01:05:00<chessguy>so i've been thinking a lot lately about building a chess strategy DSL
01:05:36<chessguy>my thinking is that i can define very simple engines
01:05:57<chessguy>and then combinators which take 2 (or maybe even more) engines, and create another engine
01:06:03<mightybyte>How will you compose those engines?
01:06:12<chessguy>oh pipe down, you :)
01:06:35<chessguy>haha, i was boring mightybyte with these ideas all day
01:07:16<skorpan>chessguy: you're being pretty abstract right now :P
01:07:55<mightybyte>The worst thing is not the boringness...it's that he's not using haskell.
01:08:29<iop>m = toMatrix "C:/users/saftarn/desktop/sudoku.txt" >>= \r -> return $ fromList $ head r ?
01:08:37<chessguy>i've been re-thinking that, mightybyte
01:08:48<mightybyte>Oh, excellent.
01:08:55<skorpan>:t toMatrix
01:08:57<lambdabot>Not in scope: `toMatrix'
01:09:01<skorpan>oh, uhm... never mind.
01:09:09<chessguy>skorpan: my idea is to sort of have a parsec-like API
01:09:19<skorpan>iop: ... >>= return . fromList . head
01:10:11<skorpan>or maybe ... >>= fromList <$> head, but i'm not sure
01:10:22<skorpan>:t liftM
01:10:24<lambdabot>forall a1 r (m :: * -> *). (Monad m) => (a1 -> r) -> m a1 -> m r
01:10:28<sjanssen>no, fmap (fromList . head) ...
01:10:31<skorpan>no, that doesn't work
01:10:38<sjanssen>or fromList . head <$> ...
01:10:55<skorpan>oh, right
01:12:54<skorpan>:t fmap
01:12:56<lambdabot>forall a b (f :: * -> *). (Functor f) => (a -> b) -> f a -> f b
01:13:06<skorpan>so fmap is just a slightly more general version of liftM, right?
01:13:46<chessguy>mightybyte: i'm back to thinking each engine should just be a function from (Position,LegalMoves) -> Maybe Move
01:13:48<skorpan>hm, no...
01:13:54<sjanssen>liftM is an artifact of some brokenness in the Prelude
01:14:09<aavogt>@hoogle liftM
01:14:10<lambdabot>Control.Monad liftM :: Monad m => (a1 -> r) -> m a1 -> m r
01:14:10<lambdabot>Control.Monad liftM2 :: Monad m => (a1 -> a2 -> r) -> m a1 -> m a2 -> m r
01:14:10<lambdabot>Control.Monad liftM3 :: Monad m => (a1 -> a2 -> a3 -> r) -> m a1 -> m a2 -> m a3 -> m r
01:14:14<skorpan>sjanssen: but what i said isn't true though, is it? because i thought Monad somehow required Functor
01:14:19<sjanssen>skorpan: all monads are functors, but the Prelude classes don't enforce that
01:14:31<aavogt>and its not even in the prelude
01:14:32<skorpan>well, then we sorted that out
01:14:48<skorpan>but how can all monads be functors?
01:15:01<sjanssen>if you've got bind and return:
01:15:03<ddarius>Anyone interested in a decent chunk of a (raw) binding to libusb-1.0 and/or (Haskell) code that talks to Owon oscilloscopes over USB?
01:15:04<sjanssen>@src liftM
01:15:05<lambdabot>liftM f m1 = do { x1 <- m1; return (f x1) }
01:15:58<skorpan>oh... so basically this could hold for any monad: fmap = liftM?
01:16:09<roconnor>yes
01:16:11<sjanssen>yes, that should be true
01:16:32<skorpan>will this prelude brokenness be handled in haskell prime?
01:16:47<sjanssen>probably not
01:16:57<sjanssen>Haskell' isn't very ambitious in that way
01:17:36<aavogt>when did Haskell' start? 1999?
01:17:42<dibblego>it's not? then why bother with Haskell' at all?
01:17:56<chessguy>aavogt: err, try in the 80's sometime, i believe
01:18:03<ddarius>dibblego: Because 1998 was over ten years ago.
01:18:11<sjanssen>aavogt: Haskell' started more recently, 2007 maybe?
01:18:12<chessguy>aavogt: there's a great history of haskell paper out there
01:18:32<chessguy>oh! i mis-read, sorry. missed the "'"
01:18:51<skorpan>heh
01:19:12<sjanssen>dibblego: Haskell' is supposedly an iterative process, with out much backwards incompatible changes
01:19:44<sjanssen>dibblego: but it also hasn't seen too much progress, so who knows what will really come of it
01:19:54<kniu>What's the difference between Text.ParserCombinators.Parsec
01:19:57<ddarius>Well, if anyone is interested in the USB bindings, email me, because I'm not interested in finishing them or maintaining them.
01:19:59<kniu>and Text.Parsec?
01:20:05<chessguy>byorgey: we need some lambdabot love in #haskell-hackphi!
01:20:13<ddarius>Text.Parsec is parsec3 Text.ParserCombinators.Parsec is parsec2
01:20:18<sjanssen>lambdabot: @join #haskell-hackphi
01:20:32<chessguy>sjanssen: no k in hacphi, sorry
01:20:36<sjanssen>chessguy: you'll need to talk to Cale if you want to make it permanent
01:20:42<sjanssen>lambdabot: @part #haskell-hackphi
01:20:49<sjanssen>lambdabot: @join #haskell-hacphi
01:20:50<chessguy>i ken seplll reel gut
01:20:52<kniu>why have parsec2 installed if you already have parsec3?
01:21:07<aavogt>hmm, there's some mentions of haskell two somewheres, any leads? my searches turn up nothings
01:21:12<ddarius>parsec2 is faster and what most libraries expect.
01:21:23<kniu>huh
01:24:03<aavogt>sjanssen: the mailing list archives for H' go back to 2006
01:29:56<Tsion>data Integral a => Ratio a = !a :% !a deriving (Eq)
01:30:08<Tsion>What do the !s mean?
01:30:38<jaredj>strictness
01:31:13<Tsion>So it will evaluate them right away?
01:31:33<jaredj>yes, rather than store them as thunks and evaluate them when they're needed.
01:31:48<Tsion>Okay, thanks jaredj
01:34:38<Cale>Tsion: More precisely, anything which evaluates a Ratio value will cause both the fields to be evaluated at that point
01:36:41<Cale>(The report defines it in a slightly different way actually, but I'm fairly sure the difference only matters if you're mixing strict and non-strict fields)
01:38:26<sm>Cale: good evening, fyi I haven't been able to see a speedup with your fast tree builder. I wonder if I lost the benefit by converting it. http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5360#a5360
01:39:46<Cale>hmm
01:40:28<Cale>Well, I used it at the time to construct some very large trees rather quickly...
01:40:34<mmorrow>ddarius lives
01:41:16<Cale>sm: it looks like you're doing lots of (xs ++ [a]) ?
01:42:06<sm>I guess.. I wanted the full path in each node, not just the node name
01:42:12<Cale>sm: Note that (xs ++ [a]) eventually costs O(length xs) time to evaluate
01:42:25<Cale>and so if you keep doing it, it'll be quadratic time
01:42:29<sm>aha
01:42:34<mmorrow>oh, ddarius has quit
01:42:58<sm>gosh I really need to learn these costs
01:43:50<sm>still, the max length of xs there is the depth of the tree
01:44:14<sm>about 8
01:44:49<sm>I wish, I wish, for a more readable/friendly profiler
01:45:00<Cale>What does the profiling output say?
01:45:31<fracture>is there a prefered way to put named constants into haskell code?
01:45:37<jaredj>In python, by convention, methods starting with _ are more or less for internal use only. Is there a convention about identifiers starting with _ in Haskell?
01:45:43<fracture>just foo = value maybe?
01:45:48<Cale>fracture: yeah
01:45:56<Cale>fracture: Everything is a named constant anyway ;)
01:45:58<fracture>any naming conventions?
01:46:02<fracture>ah good point
01:46:08<fracture>nm then
01:46:26<Cale>jaredj: Usually that's a hint that the parameter is unused.
01:46:39<Cale>(If it's part of a pattern match)
01:46:48<jaredj>uhh. right, but that's if _ is the whole thing
01:46:53<jaredj>what about _x
01:47:01<Cale>Well, if _ is the whole thing then it *really* is unused
01:47:04<jaredj>sure
01:47:11<chessguy>i've never seen _x as an identifier
01:47:13<sm>Cale: before http://joyful.com/repos/hledger/profs/200905250945.prof , after http://joyful.com/repos/hledger/profs/200905250949.prof
01:47:24<jaredj>wait this whole thing is dumb
01:47:28<Cale>But I've seen the convention where something like _x was used to give a parameter a name even though it goes unused.
01:47:41<mmorrow>sm: ooh, are you making a hierarchical Trie of account (which may have subaccounts which may have..) and then attaching values to the leaves? (i did something very similar at one point)
01:47:46<chessguy>Cale: that's....weird
01:47:51<chessguy>why not just leave it at _ then?
01:47:52<jaredj>if i have a little convenience function needed by two functions i expect others to use, i just don't export it from the module. right?
01:48:07<Berengal>chessguy: Documentation
01:48:09<sm>mmorrow: just a tree, I do not speak trie yet
01:48:26<Cale>jaredj: right
01:48:52<jaredj>ok. thx
01:49:00<Cale>My Tree is effectively a Trie with a large alphabet :)
01:49:28<jaredj>has anyone made a trae yet?
01:49:33<mmorrow>sm: hmm, so are you grouping subaccounts of account underneath their parent account, and so on recursively?
01:49:34<sm>ACTION 's head spins.. steady..
01:50:02<sm>mmorrow: yes indeed.. I make a tree of account names (the chart of accounts) to start
01:50:10<gwern>jaredj: as a child, I frequently ate off traes
01:50:15<sm>then I transform that into a richer data structure
01:50:28<mmorrow>cool
01:50:35<Cale>sm: hmm... This is the profiling output from the optimised version, yeah?
01:50:40<jaredj>haha
01:51:03<sm>the "after" link is, I'm 98% sure
01:51:06<Cale>The profiling output is harder to read even though it's more accurate when you turn optimisations on.
01:51:08<dibblego>@hoogle Seq a -> [a]
01:51:09<lambdabot>Data.Foldable toList :: Foldable t => t a -> [a]
01:51:09<lambdabot>Prelude repeat :: a -> [a]
01:51:09<lambdabot>Data.List repeat :: a -> [a]
01:51:23<Cale>I'm seeing all these ==_a6iI etc, which are strange.
01:51:34<sm>hmm. I think this profile is unoptimised
01:51:39<gwern>I was very disapointed to find that the Show instance for Seq was 'fromList [...]'
01:51:49<Cale>I'm guessing they're specialisations of equality tests...
01:53:13<Cale>anyway, it looks like in either case, the major time centre is ledgerAccount, and the major allocation centre is isAccountNamePrefixOf
01:53:31<Cale>The latter seems suspicious.
01:53:40<Cale>What does that function look like?
01:53:53<Cale>gwern: What's wrong with that?
01:54:29<gwern>Cale: well, it's inefficient. here we have a strict, finite list, and we're re-using the machinery of regular lists?
01:54:54<Cale>gwern: But it gives you valid Haskell code for reconstructing the list, which is all that it's meant for.
01:55:31<gwern>I know, but we shouldn't need to switch to data.binary every time we need even a tiny bit of performance; the defaults should be reasonably performant
01:55:39<Cale>Huh?
01:55:51<Cale>Lists perform very well for the kind of access which show does.
01:56:30<Cale>In fact, by comparison, Data.Seq would be slower.
01:56:44<gwern>when I was dealing with large Seqs, I noticed data.binary was faster than read/show for seq
01:56:55<Cale>Well, of course.
01:56:58<sm>Cale: it's about a third of the way down http://joyful.com/repos/hledger/Ledger/AccountName.hs
01:58:45<dibblego>is there any way to use two equally named functions from different modules in the same source file without using import qualified?
01:59:10<Cale>sm: Even though it might destroy correctness, will you try something for a moment? Remove that ++ [acctsepchar]
01:59:20<sm>sure thing
02:00:14<Cale>The only way I imagine that function is doing allocation is when it creates that new list.
02:00:49<Cale>Though, I wouldn't expect it to change the time-performance much
02:01:56<mauke>dibblego: yes, just qualify them
02:02:46<sm>Cale: a second slower, but 600M less allocation - http://joyful.com/repos/hledger/profs/200905281900.prof
02:02:58<cads>bleh, currying a variadic function is so ugly
02:03:14<Cale>sm: That's interesting that it would be slower
02:03:54<cads>have to say something like ((curry * 3) 2 4 2 1 :end) => 48
02:03:58<Cale>sm: anyway, the main cost in time is ledgerAccount, but looking at the code for that, it's probably not ledgerAccount's fault.
02:04:03<hatds>dibblego: no, but if they are highly related functions there might be a way around it
02:04:22<Cale>It's the fact that you're calling it 821149 times...
02:04:24<sm>it's funny I don't see anything under the ledgerAccount 40% line
02:04:26<sm>oh!
02:04:27<sm>that
02:04:34<sm>right you are
02:04:44<Cale>(plus a few)
02:05:01<Cale>and it's all from ledgerAccountTree
02:05:14<sm>isSubAccountNameOf 2 million times
02:06:35<Cale>But apparently that's much cheaper :)
02:06:37<sshc>how do I operator overload in Haskell?
02:07:00<Cale>sshc: Typeclasses
02:07:04<sshc>is it possible to define two functions with the same names but take completely different types of arguments?
02:07:28<dibblego>sshc, yes, using type-classes
02:07:34<Cale>sshc: Yes. You define a typeclass for the set of operations which you want to make general, and then instances for each of the types you want to implement them at
02:07:50<Cale>sm: Where is treemap defined?
02:08:23<fracture>I have a long computation where I want to see what's happening; seems like printf-style debugging is basically impossible in haskell
02:08:29<fracture>is there a way to trace through stuff in ghci?
02:08:35<sm>Cale: http://joyful.com/repos/hledger/Ledger/Utils.hs
02:08:36<hatds>you should also consider whether (say) your 2 functions f1: a1 -> b and f2: a2 -> b are actually representing one function f : a -> b where a is a bigger type
02:08:42<aavogt>@hoogle trace
02:08:42<lambdabot>Debug.Trace trace :: String -> a -> a
02:08:42<lambdabot>module Debug.Trace
02:08:42<lambdabot>package traced
02:08:55<Cale>fracture: Yes, there's a debugger and Debug.Trace.trace
02:09:14<fracture>cool I'll look into that
02:09:15<fracture>thanks
02:09:21<Cale>fracture: But you might find that things happen in a very different order than you expected, if you're not so familiar with lazy evaluation
02:09:32<hatds>fracture: you might find the ghci evaluation stepper more useful than the trace for just understanding how the execution goes
02:09:57<dblazakis>wasn't there a monad reader article on using the ghci debugger?
02:10:02<sm>really.. I found the ghci debugger much more confusing than trace
02:10:24<hatds>sm: meaning, the :step debugging?
02:11:42<fracture>ah yes... the :step output is weird
02:11:46<fracture>I think I need to read the manual for this :)
02:12:50<hatds>Yea, I've never used :step to debug a full fledged program, but I've found it invaluable for learning the finer points about Haskell semantics
02:13:29<fracture>seems like it could be more useful with integration into an editor
02:13:34<fracture>it's cumbersome to type :list every time
02:13:52<fracture>I'll try trace (in other languages I'd most likely printf debug this situation too)
02:14:28<hatds>there's a command to make it :list after every step
02:14:33<fracture>ah
02:14:40<hatds>the ghc user manual has a small tutorial
02:14:50<fracture>:set stop :list
02:14:56<fracture>yay
02:15:01<fracture>;)
02:15:02<sm>hatds: yeah.. worth learning, but tricksy! It may be a bit better now
02:15:35<sm>it was semi-useful when I tried
02:15:53<sm>peter hercek has been doing cool enhancements
02:17:26<kniu>@src foldl
02:17:27<lambdabot>foldl f z [] = z
02:17:27<lambdabot>foldl f z (x:xs) = foldl f (f z x) xs
02:17:41<fracture>wow this is really neat (seeing how the laziness works)
02:17:57<sm>oh man it's good to be back on the big monitor..
02:18:54<kniu>@src foldr
02:18:55<lambdabot>foldr f z [] = z
02:18:55<lambdabot>foldr f z (x:xs) = f x (foldr f z xs)
02:27:56<iop>is bitC an ongoing project?
02:28:36<sm>there's something I don't understand in this profile excerpt: http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5361#a5361
02:29:17<sm>is it telling me ledgerAccountTree, called 2457 times, called all of treeprune, ledgerAccount and treemap 800k times ?
02:30:01<sm>and how can that be since it is just: ledgerAccountTree depth l = treemap (ledgerAccount l) $ treeprune depth $ accountnametree l
02:30:35<sm>oh I see.. treemap/treeprune recurse
02:32:12<Cale>There must be a lot of nodes in that tree.
02:32:30<sm>I think I see..
02:33:15<sm>there are 600 nodes
02:33:38<fracture>hmm
02:33:40<sm>max depth is about 10
02:33:46<fracture>trying to run the profiler on a program that doesn't terminate
02:33:58<fracture>and the prof file doesn't get anything when I sigint it
02:34:08<fracture>is there any way to do that?
02:34:15<sm>fracture: someone posted recently on-list about a real-time profiler thing
02:34:45<fracture>maybe I can limit my thing to a maximum depth somehow and have it terminate there
02:34:54<Cale>sm: Is it a different tree each time?
02:34:57<fracture>pass an n to my expression and when n > 10000 do an error or something
02:35:01<Cale>sm: Or are you repeating work?
02:35:39<sm>Cale: there's only one tree for the duration of the program.. I guess I must be repeating work somehow
02:35:41<gwern>well, if you're interested in memory, I believe the PS heap profilign output is continuous
02:35:49<fracture>more interested in time
02:36:05<fracture>memory usage seems constant for the program (I think it is GCing everything after it uses it as I proc stuff)
02:36:05<Cale>sm: Perhaps you could compute that treemap higher up and pass the result in?
02:37:11<sm>I don't quite see it
02:37:24<sm>what you mean
02:39:41<Cale>sm: I suppose it's impossible, because it's dependent on l...
02:39:50<Cale>(looking at the code)
02:39:55<sm>I'm not sure why I'm getting this big multiplier effect.. according to me, it does things in stages: first builds the 600-node account name tree; then prunes it; then maps ledgerAccount l to each node
02:40:13<Cale>actually, no, that's not at all what it does
02:41:00<Cale>The first thing to happen is that treemap is applied to (ledgerAccount l), and then that does a pattern match on the tree, which causes treeprune to be evaluated...
02:42:17<Cale>and treeprune also ends up wanting to see the root of the tree, and so accountnametree l is evaluated just enough to construct the root, at which point treeprune matches against it, and then treemap applies the function ledgerAccount l to the root and returns a Branch node.
02:42:31<sm>woah.. rewiring my mental map
02:42:46<Cale>and the treemap and treeprune continue when the subtrees get pattern matched
02:44:24<sm>laziness takes a long time to understand :)
02:45:05<sm>that explanation is a very helpful reminder
02:46:31<sm>then my haskell-sense tells me that I could make something strict here, and it would behave better
02:46:35<Cale>Is there a particular reason you didn't like my way of organising the account names in the tree?
02:46:53<sm>you mean just having the node name at each node ?
02:47:10<Cale>Yeah, and having a Map at each level
02:47:13<MyCatVerbs>sm: meh, laziness. I'll get around to understanding it later, since it's not strictly necessary right away. ;D
02:47:37<Cale>Well, in fact...
02:47:40<sm>Cale: just that it requires rethinking the rest of the app
02:48:03<sm>if I absolutely have to change the whole app to make this perform, I guess I will
02:48:16<hackagebot>HSFFIG 1.1
02:48:49<Cale>Well, I'm still not certain enough about what this is doing in order to say whether it's necessary/recommendable :)
02:48:58<sm>I mean, it probably won't mean a lot of changes, but a fair bit of thought
02:49:04<Cale>What is it that is being computed here?
02:49:17<Cale>I noticed 'isInteresting'
02:49:56<sm>well, what I've been trying to optimise is just this:
02:49:57<sm>-- | Convert a list of account names to a tree.
02:49:57<sm>accountNameTreeFrom ∷ [AccountName] → Tree AccountName
02:51:07<mmorrow>sm: is an AccountName something like AccountName = (SubAccountName, AccountName) ?
02:51:29<sm>and now I have shifted to understanding why there's such a high multiplier effect
02:51:33<Cale>type AccountName = String
02:51:52<mmorrow>(which could manifest itself it different ways i guess, e.g. "Foo.Bar.Baz.Sales")
02:51:54<Berengal>Sounds like the perfect job for a trie...
02:52:41<mmorrow>exactly, then once you've built the trie, you can turn it into a Tree fairly easily
02:52:48<sm>ACTION is converting ["assets", "assets:bank", "assets:bank:checking", "expenses:food"] to a tree
02:52:56<mmorrow>perfect
02:52:59<sm>and it had been O(n^2)
02:53:20<mmorrow>bb in a minute
02:54:09<sm>and Cale gave me a non-n^2 tree builder which worked for him.. but doesn't have much effect in my app yet
02:55:37<sm>I'm also trying to learn how to efficiently profile and tune haskell. Part of my brain is saying "you wouldn't be spending this time if it was python"
02:56:51<MyCatVerbs>sm: you also wouldn't get anywhere near the same ceiling if it was Python, so meh.
02:57:13<MyCatVerbs>sm: anyways, I trust you are using ghc-core for the awkward tuning bits?
02:57:26<Cale>MyCatVerbs: Nothing at that level
02:58:02<Cale>ghc-core is useful when you're worried about how things are optimised... this is an asymptotic problem, most likely
02:58:20<MyCatVerbs>Oh? Oh, aye. Excuse my thinking in constant factors. ^^
02:58:43<Cale>sm: Is that darcs repo current?
02:59:18<sm>no it isn't.. I'll make it so
03:01:16<thoughtpolice>ACTION hopes he can make it to hac phi...
03:01:24<thoughtpolice>thank goodness it's in july; I won't have class :)
03:02:07<sm>Cale: pushed the latest
03:02:55<sm>if you are profiling, I should make you a data file like the one I have here
03:03:24<mgsloan>has anyone thought about writing a tool to analyze large volumes of haskell code (spider for code on the internet), and generate a list of functions which abstract the most frequent replications?
03:05:51<dmwit>mgsloan: I know of at least one person who has thought about it.
03:06:16<mgsloan>and that's me! just kidding. it would be very interesting.
03:06:25<dmwit>Yeah, it would be!
03:06:29<dmwit>You should definitely do it.
03:07:35<mgsloan>Maybe this summer I'll give it a go :) interning at adobe might be enough coding for the summer though, hrmm
03:08:29<myname>any body uses xmobar's Mail plugin?
03:08:49<dmwit>myname: Ask on #xmonad, there's more likely to be people using xmobar there.
03:09:00<idnar>sm: if you think profiling and tuning python is easy, I'd love to know what your secret weapon is :P
03:09:02<myname>thanks
03:09:08<mgsloan>You would probably need some sort of canonical form, which minimizes the difference between re-expression of a similar concepts
03:09:48<idnar>sm: I actually think GHC's tools are a lot better in several areas
03:11:15<dmwit>> groupBy (/=) [1,2,3,2,1,2,3]
03:11:17<lambdabot> [[1,2,3,2],[1,2,3]]
03:11:24<dmwit>Oh, that is just too slick.
03:11:31<dmwit>I'm going to hate myself tomorrow for writing the code this way.
03:11:58<idnar>how the heck does that work?
03:12:14<idnar>@src groupBy
03:12:14<lambdabot>groupBy _ [] = []
03:12:15<lambdabot>groupBy eq (x:xs) = (x:ys) : groupBy eq zs
03:12:15<lambdabot> where (ys,zs) = span (eq x) xs
03:12:21<Gracenotes>groups by the first element of the list
03:12:35<Gracenotes>into blocks beginning with that element
03:12:53<idnar>oh, groupBy isn't what I thought
03:13:06<Cale>sm: I have something for you to test. Not sure if it will improve performance, but it's something to try.
03:13:10<dmwit>> groupBy (/=) []
03:13:12<lambdabot> []
03:13:17<dmwit>ah, rats
03:13:28<dmwit>Oh well, I can just declare that nobody pass me [].
03:13:49<sm>Cale: great
03:13:57<Cale>http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5362#a5362
03:15:06<sm>idnar: you may be right. That part of my brain is just saying that mutability would - in practice, for me writing this app - avoid all this in the first place. Bringing other costs with it down the road of course.
03:15:32<idnar>sm: I think it's all about trade-offs
03:15:54<sm>indeed. I'd like to understand those well
03:15:58<idnar>sm: not only trade-offs in the language itself, but also in what you're familiar with, and the "community knowledge" that exists
03:16:10<sm>agreed
03:18:23<idnar>I'm kinda optimisation-weary right now; I've spent the last week and a half optimising Python code :)
03:18:34<sm>Cale: total time = 4.98 secs (249 ticks @ 20 ms)
03:18:34<sm> total alloc = 1,803,104,924 bytes (excludes profiling overheads)
03:18:43<idnar>fortunately I've been targetting CPU time, not memory usage
03:19:00<Cale>Better?
03:19:10<sm>yes it seems a couple of secs faster
03:19:40<Cale>It's a lot of allocation, but it should all be immediate garbage.
03:20:37<sm>just for reference, the Competition (c++ ledger) does this in .4s
03:21:21<sm>I was using this quite happily, then some boor pointed this out on the list..
03:21:52<idnar>heh
03:22:08<Cale>Well, you are using a lot of Strings...
03:22:28<p_l>sm: which c++ ledger?
03:22:30<Cale>It's also probably possible to do this tree construction more directly
03:22:57<sm>p_l: http://wiki.github.com/jwiegley/ledger
03:23:15<Cale>Seems a bit of a shame to switch back and forth between a Trie of the components and a Data.Tree...
03:23:38<p_l>sm: wasn't it obsoleted by the author? :)
03:23:57<sm>not at all.. 3.0 will be out when he gets back to it
03:24:09<sm>meanwhile I have been hacking on our righteous http://hledger.org
03:24:09<p_l>sm: Right, seems like the C++ version still gets some work
03:25:32<sm>Cale: maybe time I read up on trie and used it throughout then. I still wonder if any of this "advanced" optimisation is required.. if I would just not call these things 800k or 2 million times
03:25:38<mmorrow>sm: here's some Trie code that i use a bunch and a speed test (builds a Tree of 1000 random [String]'s by way of an intermediate Trie) that's pretty speedy http://moonpatio.com/repos/trie-test/
03:25:52<Cale>sm: Right, that's sort of what I was asking about before.
03:25:56<dibblego>is there a safe (!!)? (to return Maybe)?
03:26:42<Cale>sm: Actually it would be interesting to see the new profile
03:26:44<mmorrow>(i used this trie-code when i was doing that account grouping thing too, and it worked out well (thousands of hierarchical accounts from a db and treeify -> webpage (w/ sparklines!))
03:27:27<Cale>It's not exactly a conventional Trie which I was using either, but one where the account name path components are the alphabet :)
03:27:49<mmorrow>exactly
03:28:10<mmorrow>(which is a Trie in my book)
03:28:12<Cale>Which I think models the directory tree structure that it's going for best anyway
03:28:14<sm>brb
03:28:31<Cale>So it might be worthwhile to make other code in the program use that type.
03:28:48<mmorrow>my trie type is:
03:28:54<mmorrow>newtype Trie m k a = Trie (Maybe a, m (SubKey k) (Trie m k a))
03:28:58<Cale>newtype Tree' a = T (Map a (Tree' a))
03:29:00<mmorrow>type family SubKey k
03:29:00<mmorrow>type instance SubKey [k] =
03:29:04<mmorrow>k
03:29:19<mmorrow>(and i'm using Data.Map for the m)
03:29:34<Cale>cool
03:29:58<mmorrow>i used okasaki's trie chapter from purely funcitonal datastructures
03:29:59<mmorrow>http://moonpatio.com/repos/trie-test/Trie.hs
03:30:30<mmorrow>(i had to use a function on haskell records of functions to model his sml functor though)
03:30:42<mmorrow>trie :: M m k (Trie m [k] a) -> M (Trie m) [k] a
03:31:06<mmorrow>(is the "sml functor")
03:32:02<sm>Cale: latest profile with your change: http://joyful.com/repos/hledger/profs/200905282017.prof
03:32:24<Cale>Oh, interesting.
03:32:35<Cale>So now it's *really* ledgerAccount which we need to attack
03:33:01<Cale>Well, or the need to call that in the first place
03:33:56<mmorrow>what does ledgerAccount do?
03:34:05<Cale>It's just a map lookup, I think.
03:34:16<Cale>The real problem is that it's being called 800,000 times
03:34:34<Cale>(when the map is nowhere near that large, even)
03:35:13<mmorrow>what's the Map of?
03:35:13<Cale>hmmm
03:35:40<mmorrow>(and what's the Map's key type?)
03:35:41<Cale>Damnit I hate firefox's copy/paste shenanigans
03:35:52<Cale>> 821161 / 2457
03:35:54<lambdabot> 334.2128612128612
03:35:56<Cale>hmm
03:36:47<Cale>mmorrow: String
03:37:01<Cale>ledgerAccount :: Ledger -> AccountName -> Account
03:37:01<Cale>ledgerAccount l a = (accountmap l) ! a
03:37:23<mmorrow>ooh, String will kill
03:37:48<Cale>Yeah, but I somehow don't think that's the main problem.
03:37:55<mmorrow>personally i'd map strings to Ints somehow, and use IntMap
03:38:20<Cale>I don't care for IntMap very much somehow. It's always seemed like an ugly hack to me.
03:38:31<mmorrow>i dunno, Int compare is like a single machine instr, whereas String compare is ..
03:38:40<Cale>(but I'm morally opposed to Int in the first place ;)
03:38:50<mmorrow>Cale: i never cared for it either, until i saw how cool of a structure it is
03:39:00<mmorrow>for instance, it never needs rebalancing
03:39:06<mmorrow>and union is best-case O(1)
03:39:18<Cale>String comparisons are lexicographical though, so, most of the time you don't compare the whole thing
03:40:06<Cale>sm: Is the average number of accounts per ledger around 300?
03:40:13<Cale>That seems high...
03:40:17<mmorrow>(and IntMap nodes have the Int key unboxed into them, whereas Map nodes have a ptr to the key)
03:41:12<Cale>mmorrow: Yeah, but this is all stuff which should be hidden behind the Data.Map library. I shouldn't have to import a separate module and use a different datatype.
03:41:39<Cale>Maps which happen to have Int keys should just be fast :)
03:41:53<mmorrow>IntMap could just as well be IntegerMap, the only thing it needs is the ability to do bitwise ops on the key type
03:42:02<mmorrow>(it's a BitTrie..)
03:42:24<sm>Cale: I think it would lower for most..
03:42:25<mmorrow>Map and IntMap are totally diff structures
03:42:43<Cale>mmorrow: Right, getting the polymorphic stuff to work is hard.
03:43:12<Cale>sm:
03:43:12<mmorrow>yeah, and patricia trees don't even work if you can't do bitwise stuff on the key
03:43:15<Cale>> 821161 / 2457
03:43:17<lambdabot> 334.2128612128612
03:44:13<fracture>anyone know if there's a way to :step in ghci that doesn't doesn't step into stuff it needs to compute to get the current expression?
03:44:23<fracture>or like a step out
03:44:26<fracture>couldn't find it in the manual
03:44:43<Cale>I think the stepping commands are somewhat limited...
03:44:50<Cale>fracture: what are you trying to analyse?
03:45:12<fracture>well, I have this search thing that I've figured out is going into an infinite loop
03:45:21<fracture>and I'm trying to understand the conditions that cause it to do so
03:45:36<fracture>(at least I think it's going infinite)
03:45:49<Cale>Maybe start by plonking a Debug.Trace.trace into it which prints the parameters that it's called with each time.
03:46:10<Cale>that way you can figure out how it's being called at least
03:46:26<fracture>the data structure is somewhat large... it'd be nicer to be able to inspect it in the debugger
03:46:50<Cale>Do you know which function it is?
03:46:52<fracture>how do you put a trace in, by the way? const function?
03:46:54<fracture>yeah
03:47:22<Cale>What's it's type?
03:47:28<fracture>like .. const foo (trace "asd") ?
03:47:36<fracture>solve :: Board -> Int -> Maybe Board
03:47:47<fracture>board is data Board = Board (Array (Int,Int) Int) deriving Show
03:47:51<Cale>okay
03:47:57<Cale>add a case:
03:48:38<Cale>solve b i | trace (concat ["solve: ", show b, " ", show i]) False = undefined
03:48:42<Cale>at the top
03:49:00<fracture>ok
03:49:02<Cale>The guard will always fail, but its evaluation will print that message
03:49:20<fracture>ah nice
03:49:38<Cale>Then you can comment out that line to stop tracing.
03:51:12<mmorrow>ooh, handay
03:51:38<fracture>cool; this should work to debug this (thanks)
03:51:40<Cale>In general, trace str x is a value which is the same as x, but when x gets pattern matched against, the string str is printed on stderr
03:51:43<bos>is anyone planning on going to hac φ?
03:51:55<fracture>got ya
03:51:55<mmorrow>bos: i'd like to
03:52:01<bos>ACTION is thinking about it
03:52:18<mmorrow>nice
03:52:38<mauke>oleg++
03:53:16<mauke>hmm, this may have the unintended side effect of strictifying solve
03:53:23<mauke>deep strict
03:53:25<Cale>Yes, it will.
03:53:34<Cale>I've had that be a problem before too ;)
03:53:40<fracture>hmm... now I'm not so sure it's in an infinite loop :)
03:53:43<fracture>guess I gotta think about this more
03:53:47<ivanm>mauke: what has oleg done this time?
03:54:28<mauke>AFAIK he invented the | ... False = undefined trick; at least that's where I learned about it
03:54:42<Cale>I stole it from the original definition of undefined
03:54:50<Cale>Which was
03:54:53<mmorrow>mauke: i heard that if you say oleg's name 3 times into a mirror in the darc he'll appear out of nowhere and delimit your continuation
03:54:57<Cale>undefined | False = undefined
03:55:20<mauke>redundant
03:55:34<Cale>It's undefined, but not an infinite loop.
03:55:38<mmorrow>i thought undefined was
03:55:42<mmorrow>undefined = undefined
03:55:55<mauke>http://okmij.org/ftp/Haskell/#making-function-strict
03:55:57<Cale>This way you get a pattern match failure.
03:56:18<Cale>Yeah, it's good for that sort of thing too.
03:56:31<mmorrow>i've heard people say they like the "undefined = undefined" way more because it was more "instructive" :)
03:56:38<Cale>Though not usually necessary now that we have bang patterns.
03:56:55<mauke>__ = __ -- to quote oleg again
03:57:12<mmorrow>um
03:57:12<ivanm>mmorrow: though doesn't ghc define it as an error?
03:57:18<mmorrow>ivanm: yes
03:57:37<Berengal>@src undefined
03:57:37<lambdabot>undefined = error "Prelude.undefined"
03:57:38<mmorrow>oh, no
03:57:40<mmorrow>err,m yeah
03:57:48<mmorrow>which itself is UserError or something
03:57:50<hatds>which is, of course, more useful :)
03:57:53<ivanm>so that strictness tricks evaluates everything, but because the actual value is False, it never returns undefined?
03:58:12<fracture>hmm.. so in an imperative language, I could add some of these Boards to a map and look them up to see if I've called the function with exactly that before
03:58:15<fracture>any similar trick in this?
03:58:18<Berengal>ivanm: Well, as long as none of the arguments being forced are undefined
03:58:23<fracture>or should I just pipe stderr to some file and use perl :) (hah)
03:58:52<fracture>(they are too large to really verify by hand)
03:59:29<fracture>seems like that concept doesn't really carry over here...
03:59:37<mauke>memoizing?
03:59:44<dmwit>http://article.gmane.org/gmane.comp.lang.haskell.cafe/7737
03:59:46<mmorrow>ivanm: (undefined used to be undefined = undefined from what i understand..)
03:59:48<dmwit>(@fracture)
03:59:56<ivanm>mmorrow: *nod*
04:00:03<ivanm>except then it would never return anything?
04:00:04<fracture>well, except in this situation memoizing to aid debugging (hah)
04:00:11<mmorrow>ivanm: heh, exactly
04:00:15<ivanm>and would cause your program to loop rather than return an error?
04:00:20<mmorrow>yup
04:00:21<ivanm>s/return/throw/
04:00:26<mmorrow>"instructive" ;)
04:00:34<fracture>yeah
04:00:35<mmorrow>(for some value thereof)
04:02:32<Berengal>I used to find it more instructive that errors and infinite loops were the "same"
04:06:09<mmorrow>i'd find it amusing maybe the first time, then just get pissed :)
04:06:24<mmorrow>(if undefined = undefined)
04:11:11<mauke><<loop>>
04:11:37<mauke>you know, I have this esoteric language with no errors
04:11:47<mauke>any sequence of characters is a valid program
04:11:58<ray>you mean godel numbering?
04:12:13<mauke>nothing as fancy as that
04:12:34<mauke>any runtime problems (such as a jump to a non-existing label) are "reported" by falling into an infinite loop
04:12:49<ray>that's not so esoteric
04:13:08<mauke>well, it's some kind of bottom, but I didn't know that when I "designed" it
04:13:38<ray>i should say, it doesn't sound too esoteric for #haskell
04:13:44<mauke>it used to do that simply because I did a linear search over all instruction, wrapping back to the beginning
04:13:53<mauke>+s
04:14:13<mauke>(oh, and it didn't even read the program into memory, so it was a fgets() loop + rewind())
04:15:07<ray>sounds like the paradigm of the future
04:16:04<mauke>the new (completely rewritten) interpreter does create an in-memory representation of the program and detects some infinite loops, optimizing them to sleep() calls
04:16:44<whoppix>awesome.
04:20:18<sm> ack.. gf phone call + a plumbing emergency
04:20:28<ray>@quote infinitely
04:20:28<lambdabot>Berengal says: [On infinitely fast computers] The OS probably has a failsafe built in: If a program is running it's in an infinite loop and needs to be killed...
04:21:21<sm>don't these people understand I am *debugging*
04:23:43<inimino>mauke: interesting idea, I was thinking about total parsing, where every string is a valid parse
04:24:15<inimino>mauke: I guess you could write a language to make APL look verbose
04:24:46<mauke>http://home.cs.tum.edu/~mai/ploki/ploki-0.6.4/examples/calc.pk
04:25:46<mmorrow>mauke: yeah true, i guess that'd just die with a <<loop>>
04:26:16<inimino>heh
04:26:37<mriou>I'm looking for pointers to implement a binary tree efficiently (mostly, not recreate the whole tree to change one leaf)
04:27:21<mriou>is there anything I should look at?
04:27:30<mauke>data Tree a = Leaf | Node a (Tree a) (Tree a)
04:27:39<mmorrow>mriou: if you just replace a node, the whole tree won't be copied
04:28:07<sjanssen>mriou: I recommend Okasaki's data structures book if you can get it from your local library
04:28:14<mmorrow>mriou: since haskell uses graph reduction that falls out for free
04:28:40<mriou>mmorrow that's sweet, didn't know that :)
04:29:30<mriou>mauke: the only difference is that my tree has no node value
04:29:35<mriou>just leaf values
04:30:25<mriou>thanks for the pointer sjanssen
04:31:18<hatds>data CallStack a = Return a | Push (Env -> CallStack a) with: (>>=) (Push g) f = Push $ \e -> g e >>= f
04:31:31<hatds>heh, what do we think? :)
04:34:03<mmorrow>hatds: how will you unwind though?
04:34:30<hatds>hm
04:34:30<mmorrow>(and recover the Envs you pass in to the Push functions)
04:34:36<Cale>Hmm, is that a monad?
04:34:40<hatds>I'm assuming Env isn't changed
04:34:43<hatds>yea, I think so
04:35:44<hatds>I think one can write a function CallStack a -> a, yea?
04:36:06<Cale>Env -> CallStack a -> a, certainly
04:36:57<hatds>I wonder if it is efficient
04:37:10<mmorrow>i've used (data Cxt a b = Top a | Loc b (b -> Cxt a b)) before
04:37:36<mmorrow>it seems like something is inside-out about that CallStack though (i can't quite put my finger on it though)
04:38:39<mmorrow>actually, Cxt a = Top a | Loc a (a -> Cxt a) is easier to deal with
04:39:04<mmorrow>(and you'd need a (into :: a -> Cxt a))
04:39:36<hatds>into = return for the Cxt monad?
04:39:42<bitfish>hi, i'm always getting this error while trying to `run` the following file: http://paste.pocoo.org/show/phVbwbCUssN1GIKItI3x/
04:39:58<mmorrow>hmm, it's not quite return.. it'd be dependent on your particular 'a'
04:40:07<bitfish>and the error: foo.hs:2:0: parse error (possibly incorrect indentation)
04:40:10<mauke>bitfish: yeah, you can't do that
04:40:14<mmorrow>and there'd probably be more than one into
04:40:15<bitfish>any ideas what i'm doing wrong?
04:40:23<bitfish>mauke: what do you mean?
04:40:26<Cale>bitfish: .hs files should consist of declarations
04:40:27<mmorrow>data T a = Tip a | T (T a) (T a)
04:40:36<mauke>bitfish: you can't just put some statements in a .hs file
04:40:46<Cale>bitfish: write something like
04:40:47<bitfish>mauke: i can't?
04:40:59<Cale>hw = "Hello, World!"
04:41:04<Cale>main = print hw
04:41:17<bitfish>okay
04:41:18<Cale>(or putStrLn instead of print)
04:41:21<mmorrow>left (Loc (T l r) k) = Loc l (\l -> k (T l r))
04:41:25<mmorrow>right = ...
04:41:39<mauke>main = do { let hw = "Hello, world!\n"; putStr hw; }
04:41:41<mauke>:-)
04:41:47<hatds>what's the monad instance for Cxt?
04:41:56<mmorrow>err, i messed up the description of into..
04:42:03<mmorrow>hatds: there isn't one
04:42:10<mmorrow>(maybe there is, not sure)
04:42:12<hatds>that's no fun then
04:42:18<mmorrow>heh
04:42:20<wahjava>hi
04:42:23<hatds>I wanted something where return was like the C keyword
04:42:39<mmorrow>which one? return?
04:42:43<ray>sounds hard
04:42:48<bitfish>mauke: heh, well, i'm a bloody newb to haskell, not to programming at all. its fun to learn a new language ;)
04:42:52<hatds>here's the whole thing
04:42:57<hatds>data CallStack a = Return a | Push (Env -> CallStack a)
04:42:59<hatds>instance Monad CallStack
04:43:01<hatds> return a = Return a
04:43:02<hatds> (>>=) (Return a) f = f a
04:43:04<hatds> (>>=) (Push g) f = Push $ \e -> g e >>= f
04:43:20<Cale>Note that (Push g) >>= f = Push (g >=> f)
04:43:31<wahjava>is there any 'trim' function in haskell library ? 'trim' is supposed to remove continuous occurence of a specific character at the start and end of the string.
04:43:49<hatds>nice, Cale
04:43:49<mauke>dropWhile
04:44:17<SamB>why does the kleisli arrow look like a fish ?
04:44:24<Cale>bitfish: The basic idea is that declarations go in a file, you load that in ghci and you can type expressions to evaluate them.
04:44:38<mmorrow>so you're really using Return as a way to _call_ a function, and Push as a way to (in a sense) return
04:44:50<bitfish>Cale: that sounds rather irritating
04:44:53<Cale>bitfish: In a compiled program, you define an IO action value which says what to do when the program runs.
04:44:59<mmorrow>(Return a >>= f to call a function)
04:45:04<hatds>bitfish: think of a .hs structured more like a C file rather than a list of statements for ghci
04:45:14<Cale>bitfish: It's not bad. Just keep two terminal windows open, one with your editor, and one with ghci
04:45:28<bitfish>okay
04:45:29<Cale>bitfish: When you edit the file, typing :r in ghci will reload it.
04:45:45<Cale>and you can continue to test things
04:45:48<mmorrow>hatds: i dunno, do you have an example of CallStack being used?
04:46:16<hatds>this is potentially part of my mini-GUI library design
04:46:19<SamB>or you could use a text editor that actually runs natively under your window system, like emacs ;-)
04:46:24<rzezeski>can someone look at this paste and tell me if I'm tracing functions correctly... http://paste.lisp.org/display/81003
04:46:38<hatds>and Env = Event
04:46:48<mmorrow>hatds: or maybe i should say, what is CallStack's purpose?
04:46:54<mmorrow>hmm
04:46:54<wahjava>mauke, > dropWhile Data.Char.isSpace " wahjava "
04:47:02<bitfish>SamB: i always use the KDE Kate editor (under GNOME) to edit files
04:47:11<Cale>rzezeski: I would if paste.lisp.org resolved for me...
04:47:14<bitfish>SamB: i'll think about that :P
04:47:16<Cale>oh, there we go
04:47:21<wahjava>mauke, that only removes spaces at beginning, what about removal of spaces at the end ?
04:47:32<rzezeski>Cale: thx for looking Cale
04:47:33<hatds>mmorrow: a GUI is a lot like f : Event -> IO (), but maybe I have two such functions f1 and f2 and I want to "switch over" to f2 after this event
04:47:36<mauke>wahjava: reverse . dropWhile _ . reverse
04:47:39<SamB>bitfish: that obviously also runs natively under your window system
04:47:42<SamB>;-)
04:47:47<bitfish>i know, heh
04:47:48<wahjava>mauke, okay. thanks :)
04:48:24<Cale>rzezeski: You're a little off, it should be foldl step (step 0 '9') "85"
04:49:02<Cale>rzezeski: Also, it's the outermost step which evaluates first
04:49:16<sm>argh.. what function converts 'a' and 'b' to "ab" ?
04:49:26<mauke>\a b -> [a, b]
04:49:42<sm>phew, thank you
04:50:11<rzezeski>Cale: when you say outtermost step, do you mean after the foldl is done doing its thing?
04:50:19<hatds>I guess 'return ()' is like poping the stack
04:50:50<Cale>yeah
04:50:57<Cale>the outermost call to 'step'
04:51:07<rzezeski>Cale: I think you can annotate my paste, if you want to be a super nice guy :)
04:51:41<Cale>rzezeski: I'm writing out a trace already :)
04:51:52<rzezeski>Cale: thx, you tha man!
04:53:14<rzezeski>Cale: BTW, the reason I did the innermost first is because I thought parens took precedence over a function precedence...I'm sure your trace will clear it up for me
04:53:38<mauke>precedence is not evaluation order
04:54:29<rzezeski>mauke: so what is evaluate first in this contrived example: fn1 (fn2 somarg2) somearg1
04:54:51<mauke>fn1
04:55:00<Cale>http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5366#a5366
04:55:10<rzezeski>ahh, and that's where I have gone astray it seems
04:55:27<Cale>oops, I doubled a line there
04:56:17<Cale>I'll show how it goes with foldl'
04:57:20<rzezeski>Cale: I see what you mean now, I think I have to re-read the RWH section about evaluation, apparently I still have it wrong
04:57:49<copumpkin>how long until someone on-ups bos' pidigits entry?
04:58:34<dmwit>In Haskell or at all?
04:58:36<rzezeski>BTW, I like hpaste, it doesn't blow up like paste.lisp when I tell it to colorize for Haskell
04:58:51<bos>copumpkin: i'd be thrilled if someone did
04:59:04<copumpkin>bos: I meant in c :(
04:59:09<mauke>http://www.spoj.pl/ranks/PIVAL/ ?
04:59:10<sm>uniquenames = map (λa→[a]) "abcdefghijklmnopqrstuvwxyz" ++ (zipWith (++) uniquenames uniquenames)
04:59:28<copumpkin>I wonder how parallelizable it is... it feels pretty sequential to me
04:59:34<bos>copumpkin: i think that's probably not possible.
04:59:41<sm>would someone have a nicer implementation ? I'd like eg 1000 or 10000 readable randomish similarish-length unique strings
05:00:49<mauke>:t showIntAtBase
05:00:50<lambdabot>forall a. (Integral a) => a -> (Int -> Char) -> a -> String -> String
05:01:00<hatds>unique strings or just random-y?
05:01:16<mauke>> map (\n -> showIntAtBase 26 (['a' .. 'z'] !!) n "") [0 ..]
05:01:18<lambdabot> ["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s...
05:01:20<dmwit>uniquenames = [1..] >>= \n -> replicateM n ['a'..'z'] >>= id
05:01:22<sm>hatds: unique.. they don't have to be random
05:01:34<mauke>>>= id is join
05:01:38<dmwit>> do { n <- [1..]; s <- replicateM n ['a'..'z']; s }
05:01:40<lambdabot> "abcdefghijklmnopqrstuvwxyzaaabacadaeafagahaiajakalamanaoapaqarasatauavawax...
05:01:57<dmwit>mauke: I know. But then I'd have to prefix that, and it breaks the beauty of it. Plus it's wrong.
05:02:00<hatds>sm: fromEnum :: Int -> Char, now just get random nums?
05:02:01<dmwit>> do { n <- [1..]; s <- replicateM n ['a'..'z'] }
05:02:04<lambdabot> <no location info>:
05:02:04<lambdabot> The last statement in a 'do' construct must be an ...
05:02:04<dmwit>bah
05:02:08<dmwit>> do { n <- [1..]; replicateM n ['a'..'z'] }
05:02:10<lambdabot> ["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s...
05:02:16<Cale>rzezeski: http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5366#a5367
05:02:33<dmwit>:t [1..] >>= flip replicateM ['a'..'z']
05:02:36<lambdabot>[[Char]]
05:02:43<copumpkin>bos: I'm curious how limiting gmp's function boundaries are for this (i.e., if we had a pure haskell multiprecision lib almost as fast as GMP and good ways of fusing adjacent operations, whether we could do better)
05:03:16<Cale>rzezeski: While it may look like more steps, it's mostly because I included steps for trivial things which are not really steps, like substituting let-bound things into expressions.
05:03:44<Cale>(and eliminating seq when the variable is evaluated)
05:03:46<jfredett_>do there exist Object-relational model database libraries for haskell? HDBC and HaskellDB both appear to be SQL executors.
05:04:10<bos>copumpkin: i don't know for sure, but i'm dubious.
05:04:20<jfredett_>or will I need to build one? :)
05:04:39<Cale>jfredett_: What would the interface look like?
05:05:06<sm>jfredett_: I think you will need to build it
05:05:54<jfredett_>Cale: I don't know- I suppose one could hijack Data.Map and just have the fields be a autogenerated datatype based on the table info...
05:06:03<Cale>Has anyone here tried HaskellDB lately?
05:06:11<Cale>Is it still cool? :)
05:06:49<jfredett_>Reason being, I'm trying to write a binding to an API/Database for EVE online, and I wanted to provide a consistent, mostly pure interface to the database (which houses worldmap and item info).
05:07:08<rzezeski>Cale: Thx, you've been a big help, again!
05:07:16<Cale>rzezeski: No problem :)
05:07:17<jfredett_>and I thought about building a big record, but it's a _big_ record for even one or two tables, and it's somewhat unwieldy looking
05:08:23<Cale>jfredett: You might want to look at the way that HaskellDB does things for inspiration
05:08:39<Cale>jfredett: It takes a more functional approach than an object oriented one though
05:08:45<jfredett>interesting
05:09:00<jfredett>I'll have to take a peek
05:10:32<Cale>I wonder if there's a good tutorial lying around... things have gotten more elaborate than last time I looked at it :)
05:10:36<jfredett>see- ideally, I'd like to take the table definition and have it roll some datatype defs and accessor-y database quereys.
05:10:50<jfredett>HDBC is lovely, very no nonsense.
05:11:19<jfredett>not super featureful, but nice for hacking.
05:11:45<Cale>HaskellDB's approach is that it provides you operators for writing queries such that the type of the result can be inferred.
05:12:08<jfredett>featureful in the sense of doing lots of fancy things, as opposed to actual useful properties, of which there are many.
05:13:18<jfredett>Cale: see, thats what I would want- a powerfully-typed database. I'm not well-versed in database-fu, but it seems that stronger type information could be useful in databases...
05:13:48<Cale>http://www.cs.chalmers.se/~bringert/publ/haskelldb/haskelldb-db-2005.pdf
05:13:56<Cale>Some intro slides :)
05:14:02<jfredett>excellent
05:14:20<ivanm>Cale: but is there some conc slides as well? :p
05:14:23<jfredett>ACTION sends to his kindle
05:14:31<jfredett>huzzah.
05:16:50<Cale>jfredett: HaskellDB is less of an Object Relational Mapper and more of a Relation Relational Mapper :)
05:17:29<jfredett>hehe
05:17:30<Cale>(That is, it gives you operations for directly manipulating the relations expressed in the database, and constructing new ones (which correspond to queries)
05:17:42<Cale>)
05:17:44<Cale>hehe
05:17:47<ivanm>jfredett: what, reading it on your computer not good enough for you?
05:17:47<ivanm>;-)
05:18:01<jfredett>ivanm: well, I'm not on my computer 24/7
05:18:17<jfredett>Cale: I definitely like the static checking of queries.
05:18:18<ivanm>but you're on your kindle 24/7?
05:18:20<ivanm>:p
05:18:44<jfredett>ivanm: well, the set of times I'm on my computer union the set of times I have my kindle available = 24/7
05:18:51<ivanm>heh
05:18:57<ray>`union`
05:19:04<ivanm>though my initial point was because I figured you'd just read it _now_...
05:19:22<jfredett>ivanm: I'll scan it, but it'll be nice to have on my kindle as well
05:19:35<ivanm>ACTION ponders ways in which a kindle can not be functioning whilst jfredett isn't on his computer...
05:19:42<ivanm>batteries, etc.
05:19:49<ivanm>thereby not making the union == 24/7 :p
05:19:59<jfredett>I tag it, it gets sorted with all the other haskell stuff I have on there
05:20:11<Nafai>I think I'd like a kindle
05:20:54<ivanm>ACTION thinks he'd like the money for a kindle, and then spend it on something more worth-while
05:21:04<jfredett>Nafai: wait for the new one thats coming out soon, it's gonna have a better pdf reader
05:21:08<jfredett>it might even remember math
05:21:14<jfredett>err- render *
05:21:17<ivanm>heh
05:21:21<jfredett>too many conversations.... :/
05:21:35<Gracenotes>I can remember math. sort of.
05:21:42<ivanm>I've pondered getting an XO for a while just because unlike other netbooks, you can use it as an ebook reader
05:21:46<Cale>Odd... the documentation for 'divide' is "Not in SQL92."
05:22:07<Cale>http://hackage.haskell.org/packages/archive/haskelldb/0.12/doc/html/Database-HaskellDB.html#v%3Adivide
05:22:14<ivanm>Cale: as in the official documentation? or the hDB documentation?
05:22:17<ivanm>ahhh, the latter
05:22:25<p_l>ACTION was thinking of gettin iLliad or similar, as they are simply PDA's with ePaper display :D
05:22:41<ivanm>p_l: never heard of iLliad
05:22:52<jfredett>Cale: I imagine that a kind of Object-Functional Relational Model could be concieved -- purity + ORM could make things very interesting.
05:23:03<ivanm>what's the significance of the capital for the second letter? to iMitate aPple? :p
05:23:12<jfredett>that and a strongly typed database could be very cool.
05:23:45<Cale>Hey, this lecture was apparently given by nibro... he's been around lately hasn't he?
05:24:09<p_l>ivanm: I don't know.
05:24:10<ivanm>@seen nibro
05:24:10<lambdabot>I saw nibro leaving #haskell 5h 49m 36s ago, and .
05:24:20<ivanm>Cale: he was around...
05:24:28<ivanm>s/was/_was_/ ;-)
05:25:02<jfredett>partially though, I'm just afraid I'm going to fall down the, "This is such an awesome idea, I should totally do this project too" rabbit hole, and pop out the other side with 1500 projects all stealing my time. :/
05:25:48<Cale>It's too bad that we don't have a proper record system in Haskell. If we did, HaskellDB could be a good deal prettier.
05:25:52<jfredett>Thats the problem with haskell, it makes too many awesome ideas possible, so I get stuck with too many projects... :/
05:25:56<jfredett>Cale: I agree.
05:26:13<Cale>Currently it has to cheat and use typeclass trickery to simulate proper records
05:26:35<jfredett>then again, I would have never had this question (or set thereof) if it did, so perhaps it's a good thing.
05:26:44<jfredett>got me thinking about interesting database stuff.
05:27:25<ivanm>Cale: what would you call a "proper record system"?
05:27:58<ivanm>the only real problem I have with the current one is that it's annoying doing foo {bar = succ (bar foo)}
05:27:59<ivanm>:s
05:28:24<jfredett>ivanm: dunno what Cale would say, but some kind of namespacing so that I could have data Foo = Foo {bar :: Int} and data Fuz = Fuz {bar :: String}
05:28:31<Cale>Well, the existing record syntax is a syntax for algebraic types which is different than what I'm thinking of
05:28:33<jfredett>without having a type error...
05:28:53<ivanm>jfredett: well, that can be argued both ways, since bar :: Foo -> Int and bar :: Fuz -> String
05:29:29<Cale>What I'm thinking of is extensible records with named/typed fields that are part of the record type, along with row polymorphism, and various operations on row types
05:29:44<ivanm>Cale: example?
05:29:52<ivanm>(so I know wtf you mean :p )
05:30:44<Cale>So you could have a function... raise :: Integer -> { 'salary :: Integer | row } -> { 'salary :: Integer | row }
05:31:03<jfredett>... wuuuuhhh?
05:31:04<Cale>Which would operate on any record type having a 'salary field.
05:31:09<jfredett>ooh
05:31:10<Cale>(of type integer)
05:31:11<jfredett>interesting.
05:31:30<Cale>Regardless of what other fields were in there.
05:31:54<ivanm>Cale: how does one define a 'salary field? the prime at the beginning denoting shared or something?
05:31:58<ivanm>and what does | row mean?
05:32:14<Cale>row is a variable representing the remainder of the fields in the record
05:32:25<Cale>So this expresses that it doesn't affect those
05:32:49<ivanm>and in the type sig, it means it's allowed to have other fields?
05:32:56<Cale>yes
05:33:50<Cale>These labels, distinguished by the fact that they start with ' and are not Char values, occur at both the value and type level.
05:33:53<jfredett>why would you need the | row at all then? if you have a record with one field -- I mean, it just seems pointless... :/
05:34:00<Cale>and there would be various operations...
05:34:22<ivanm>Cale: "and are not Char values" <-- hmmm?
05:34:32<Cale>get 'salary rec :: { 'salary :: t | row } -> t
05:34:42<Cale>Well, 'a' :: Char
05:34:50<ivanm>ahhh, no closing quote
05:34:52<Cale>right
05:35:03<ivanm>jfredett: I guess it's the same as having a catch-all _ case in pattern matching
05:35:32<Cale>jfredett: In order to express where the rows move around when you have lots of records floating about
05:35:36<jfredett>but- i guess I'm trying to say- is there ever a case where you _wouldn't have the remainder there?
05:35:51<Cale>There would presumably be operations like record concatenation
05:35:59<mmorrow>hatds: i was trying to figure out how to use CallStack and came up with this http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5368#a5368
05:36:17<Cale>jfredett: Yes, if you wanted to ensure there were no other fields.
05:36:19<jfredett>sure- but the `| row` doesn't appear to indicate ordering at all.
05:36:44<mmorrow>hatds: i'm still confused though about whether or not it's useful, because i can't figure out how to use it
05:36:46<Cale>Only the fields with the same name and type have an ordering (and act like a stack)
05:36:54<Cale>Otherwise, the fields are unordered.
05:37:27<hatds>mmorrow: reading your hpaste... but yea I'm having trouble since the place I wanted to use it needs to be able to perform IO
05:37:45<mmorrow>hatds: ooh, i was thinking about that, you could:
05:37:53<Cale>The stacklike behaviour may seem strange, but it means that you never have to worry about whether a record already has a field which you want to extend it with
05:38:40<Cale>(Some records systems require your types to contain predicates that some record lacks a given field, which seem more unnatural.)
05:38:58<hatds>mmorrow: actually I think I can modify my example to not use IO and it would still be 'useful', I can hpaste that for you
05:39:14<Cale>You'd have operations...
05:40:04<Cale>get :: (l :: Label) -> { l :: t | r } -> t
05:40:15<Cale>delete :: (l :: Label) -> { l :: t | r } -> { r }
05:40:40<Cale>extend :: (l :: Label) -> t -> { r } -> { l :: t | r }
05:41:02<mmorrow>hatds: arg, i was just trying to add a monad to it, but the Push (>>=) case is giving me trouble
05:41:16<Cale>put :: (l :: Label) -> t -> { l :: t | r } -> { l :: t | r }
05:41:19<mmorrow>hatds: cool, yeah
05:41:33<jfredett>wouldn't it be just put :: Label -> blahblah...
05:41:38<jfredett>rather than (l :: Label) ?
05:41:45<Cale>Label is the *kind* of l
05:41:55<jfredett>...
05:42:20<jfredett>so- thats kind of like... dependent types? Kindof?
05:42:24<Cale>l is something at the type level, which is like a type having exactly one value with the same name, and you don't have to declare it
05:42:34<jfredett>interesting.
05:42:41<Cale>Similarly, the kind of r would be Row
05:42:58<sjanssen>Cale: "l :: Label" is a bit confusing as far as syntax
05:43:02<Cale>It wouldn't do for r to be something like Integer :)
05:43:18<Cale>Well, the kind could be inferred there
05:43:28<Cale>I was just being explicit
05:43:35<sjanssen>oh, it's a kind annotation. Makes a bit more sense when you think of that
05:43:47<jfredett>Sure, but do you really need a full type? I imagine all of this -- all of it could sit at the type level...
05:43:56<jfredett>I just don't see the need... :/
05:44:21<Cale>Well, you have these things called labels which are like type-level values, so they should belong to a kind
05:44:25<nimred>wich way can i uninstall a package using cabal ?
05:44:42<Cale>You could just allow any type to act as a label, but that might be weird.
05:44:57<sjanssen>nimred: you can't actually uninstall. You can make GHC forget it exists with 'ghc-pkg unregister foo'
05:45:11<Cale>and it would require you to declare all your label-types by hand
05:45:25<Cale>(might be a good thing, but I think we can do without it)
05:45:37<jfredett>no- I mean- maybe I'm thinking to lispily, but have a datatype "label" which is a wrapper on string
05:45:55<jfredett>put (label "foo") ...
05:45:56<Cale>Oh, but Strings aren't available at compile time.
05:46:04<jfredett>ooh.
05:46:06<Cale>This is still statically checked.
05:46:13<jfredett>you are correct...
05:46:27<nimred>sjanssen and what about reinstall ?
05:46:28<sjanssen>Cale: the system you're describing is in some paper, who wrote it?
05:46:38<jfredett>sjanssen: good point.
05:46:43<sjanssen>nimred: reinstall is just installing it again
05:47:43<Cale>sjanssen: It's roughly the system which Daan Leijen described, but with minor changes in syntax
05:48:45<sjanssen>http://research.microsoft.com/en-us/um/people/daan/download/papers/scopedlabels.pdf
05:48:50<Cale>yeah
05:49:16<jfredett>excellent, more for the kindle. :)
05:49:31<Cale>He actually describes two similar but subtly different record systems in his two papers, but I haven't really made up my mind which I like better.
05:50:04<sjanssen>Cale: oh, interesting. I don't remember which I read
05:50:36<nimred>sjanssen ok thx
05:50:43<Cale>Also, while I like my 'lens-like' syntax idea, it's possible that a more general syntax for constructing records all at once is needed.
05:50:57<Cale>I really just don't like the use of . for field selection.
05:51:30<sjanssen>yeah, . is already overoverloaded
05:51:51<Cale>(If it had been me, we would have | for the module path separator)
05:53:08<sjanssen>interesting, Leijen's system also gives us variants
05:53:13<Cale>yes
05:55:50<Cale>Oh, actually, his first paper uses lacks predicates, which I don't care for so much.
05:56:02<hatds>mmorrow: hmm, I see a problem
05:56:27<jfredett>which paper am I reading here, it's the one sjanssen linked.
05:56:36<hatds>mmorrow: the way I intended to use this was with a function that takes an Event and runs the top thing on the call stack
05:56:41<Cale>You're reading the one which is closer to what I like then :)
05:57:07<cads>> :t curry
05:57:07<hatds>mmorrow: but you can't turn a "Return a" into a new, pop'ed callstack
05:57:09<lambdabot> <no location info>: parse error on input `:'
05:57:20<jfredett>okay, I'll happily follow along which your opinion, as it is most certainly better informed than mine. :)
05:57:29<hatds>mmorrow: I'll hpaste this to show you how I was envisioning of using it
06:00:21<sohum>so, I have a query. Could the compiler, when it notices that a function call doesn't typecheck, attempt to apply the appropriate liftM to the function, and accept that if it does typecheck?
06:00:52<ivanm>I doubt it
06:00:56<Cale>sohum: that would be confusing to do, but it could be done.
06:01:10<Cale>I wouldn't want it :)
06:01:30<ski>a type error isn't necessarily located to one place in the source
06:01:35<sohum>no? it seems as if that would simplify but only to the level of sugar writing monadic code
06:03:08<hatds>mmorrow: now if only I can get my hpaste to typecheck.. one sec :)
06:03:20<Cale>Well, blurring the lines between lifted and unlifted operations might seem like it would be convenient, but I think it makes the cases where both versions would typecheck a good bit more confusing...
06:03:52<Cale>You have to reason that something won't typecheck in order for the lifting to be there...
06:04:41<sohum>are there cases where both versions would typecheck?
06:04:44<Cale>yeah
06:05:09<sohum>oh, hm, I suppose there could be through typeclasses and such
06:05:23<Cale>> sequence [[[1,2,3], [4,5]], [[6,7,8], [9,10]]]
06:05:25<lambdabot> [[[1,2,3],[6,7,8]],[[1,2,3],[9,10]],[[4,5],[6,7,8]],[[4,5],[9,10]]]
06:05:30<Cale>> liftM sequence [[[1,2,3], [4,5]], [[6,7,8], [9,10]]]
06:05:32<lambdabot> [[[1,4],[1,5],[2,4],[2,5],[3,4],[3,5]],[[6,9],[6,10],[7,9],[7,10],[8,9],[8,...
06:06:07<Cale>(perhaps not too realistic an example, but probably more common ones exist too :)
06:06:16<Cale>Basically, anywhere that you have enough polymorphism
06:06:41<sohum>right
06:06:45<cads>for the type of curry, as defined by wikipedia :P, we have ::((A x B) -> C) -> (A -> (B -> C)). Knowing curry we see that that our curried function will take a value in A and return a partially applied function that takes a remaining value in C, and this is where I'm confused, the result seems to be a value in C, which doesn't give any insight into how curry worked for functions with more than two arguments
06:07:05<Cale>in B
06:07:05<cads>how do we write the type of the curry function in general?
06:07:19<Cale>curry f x y = f (x,y)
06:07:28<Cale>er
06:07:34<Cale>the type of it?
06:07:38<Cale>:t curry
06:07:40<lambdabot>forall a b c. ((a, b) -> c) -> a -> b -> c
06:07:55<cads>cale, yeah, the first "in C" should be "in B"
06:08:19<Cale>Currying functions of more arguments extends like...
06:08:27<sohum>huh, the haskell curry function splits apart pairs
06:08:29<sohum>cool.
06:08:32<Cale>:t let curry3 f x y z = f (x,y,z) in curry3
06:08:34<lambdabot>forall t t1 t2 t3. ((t, t1, t2) -> t3) -> t -> t1 -> t2 -> t3
06:08:51<cads>> (curry (/ x y z q -> (sum x y z q))) 1 2 3)
06:08:53<lambdabot> <no location info>: parse error on input `->'
06:08:54<cads>ack
06:09:02<sohum>lisp!
06:09:03<cads>> ((curry (/ x y z q -> (sum x y z q))) 1 2 3) 4)
06:09:06<lambdabot> <no location info>: parse error on input `->'
06:09:10<Cale>\
06:09:17<cads>noooo, I'm forgetting haskell!!!!!
06:09:23<Cale>> ((curry (\x y z q -> (sum x y z q))) 1 2 3) 4)
06:09:26<lambdabot> <no location info>: parse error on input `)'
06:09:28<cads>sohum, your accusation was right!
06:09:34<cads>> ((curry (\ x y z q -> (sum x y z q))) 1 2 3) 4)
06:09:36<cads>lemme
06:09:36<lambdabot> <no location info>: parse error on input `)'
06:09:44<cads>> ((curry (\ x y z q -> (sum x y z q))) 1 2 3) 4
06:09:46<lambdabot> Couldn't match expected type `[a]' against inferred type `(a1, b)'
06:09:47<sohum>twas not an accusation, my good man, but recognition!
06:09:47<Cale>I don't know which bracketing you want :)
06:09:48<hatds>mmorrow: okay http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5368#a5369
06:09:49<dmwit>> curry (\x y z q -> sum [x, y, z, q]) (1, 2) 3 4
06:09:51<lambdabot> Overlapping instances for GHC.Show.Show
06:09:51<lambdabot> (((t, ...
06:09:55<dmwit>:t curry
06:09:57<lambdabot>forall a b c. ((a, b) -> c) -> a -> b -> c
06:10:10<hatds>mmorrow: gonna go back to reading yours for the moment
06:10:11<dmwit>> curry (\(x, y) z q -> sum [x, y, z, q]) 1 2 3 4
06:10:13<lambdabot> 10
06:10:46<Cale>> (curry . curry) (\((x,y),z) q -> sum [x,y,z,q]) 1 2 3 4
06:10:49<lambdabot> 10
06:10:58<Cale>> (curry . curry . curry) (\(((x,y),z),q) -> sum [x,y,z,q]) 1 2 3 4
06:11:00<lambdabot> 10
06:11:12<dmwit>Also, q?
06:11:17<dmwit>How about w x y z instead. =P
06:11:31<cads>hey man, it's late
06:11:45<cads>this bugs me, I always thought curry could do
06:12:12<cads>> (((curry (\ (x, y, z, q) -> sum [x y z q])) 1) 2 3) 4
06:12:14<lambdabot> Couldn't match expected type `(a, b)'
06:12:17<Cale>nope
06:12:20<dmwit>:t curry4
06:12:22<lambdabot>Not in scope: `curry4'
06:12:27<cads>haha
06:12:29<cads>really?
06:12:32<dmwit>nope
06:12:40<Cale>@let curry4 f w x y z = f (w,x,y,z)
06:12:43<lambdabot> Defined.
06:12:55<Cale>> curry4 (\ (x, y, z, q) -> sum [x y z q]) 1 2 3 4
06:12:57<lambdabot> Add a type signature
06:13:01<dmwit>commas
06:13:15<Cale>> curry4 (\ (x, y, z, q) -> sum [x, y, z, q]) 1 2 3 4
06:13:17<lambdabot> 10
06:13:20<dmwit>> curry4 (\(w, x, y, z) -> sum [w x y z]) id id id 4
06:13:22<lambdabot> 4
06:13:26<Cale>haha
06:13:37<Cale>good call
06:13:41<cads>aw well, they curry function I've been playing with in my head was a bit muddled because I didn't think about tuples
06:14:05<Cale>Tuples are all separate types in Haskell, so there's no one curry function which will handle them all
06:14:24<cads>I think it's stronger that normal curry, but its type depends on the function you give it
06:14:37<Cale>normal curry?
06:14:50<cads>yeah, that weak stuff you buy in packets
06:14:53<Cale>hehe
06:15:00<cads>this curry will blow your socks off
06:15:09<Cale>and then there's uncurry
06:15:19<Cale>uncurry is to pairs what foldr is to lists
06:15:32<sohum>:t uncurry
06:15:33<cads>:type uncurry
06:15:34<lambdabot>forall a b c. (a -> b -> c) -> (a, b) -> c
06:15:39<Cale>> uncurry (\x y -> x + y) (3,5)
06:15:41<lambdabot> 8
06:15:49<cads>yeah, I like uncurry
06:16:15<Cale>maybe is another one of this family of functions
06:16:18<Cale>:t maybe
06:16:20<lambdabot>forall b a. b -> (a -> b) -> Maybe a -> b
06:16:24<cads>man, functional programming without the type system there to show you what you did is tough
06:16:36<Cale>:t either
06:16:38<lambdabot>forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
06:16:48<Cale>:t foldr
06:16:50<lambdabot>forall a b. (a -> b -> b) -> b -> [a] -> b
06:17:16<Cale>The similarity here is that they take a parameter which serves as a replacement for each of the constructors of the datatype
06:17:26<Cale>and a value of that type
06:17:34<Cale>and make the replacements throughout
06:17:53<Gracenotes>lthough, list is a recursive datatype.
06:17:54<Gracenotes>a
06:17:56<Cale>right
06:18:02<sohum>incidentally
06:18:07<sohum>is there a List typeclass?
06:18:09<Gracenotes>so why foldr and not foldl? Because foldr folds "along" a list?
06:18:23<hatds>mmorrow: yea, I think it needs to be a list-like structure, but maybe Push isn't the only cons operator, what if Return is also cons-like?
06:18:27<sohum>that say : and the [x:xs] destructuring is defined in terms of?
06:18:34<Gracenotes>whereas foldl just takes an accumulator as you go
06:18:59<Cale>Gracenotes: foldl does a more complicated structural transformation
06:19:04<Cale>I have some diagrams...
06:19:11<Gracenotes>yeah :)
06:19:12<Cale>http://cale.yi.org/index.php/Fold_Diagrams
06:19:19<Gracenotes>ACTION has it bookmarked
06:19:27<Gracenotes>I see
06:19:29<ray>wikipedia has about half those diagrams
06:19:36<ray>er, not half
06:19:48<Cale>Right, I wrote 90% of the wikipedia article on folds
06:20:08<ray>i figured you either wrote or rewrote it when i saw those
06:20:34<Cale>Well, what was there before was almost complete garbage, so I rewrote it.
06:21:35<sohum>hahaha, nice
06:21:41<sohum>crowdsourcing fte)
06:21:44<sohum>*ftw
06:21:49<Gracenotes>it probably helps to have a CT understand of folds
06:22:07<Gracenotes>they are everywhere. even in set theory, you have k-folds via union/intersection...
06:22:12<cads>forgetting about laziness, there's a difference between a left and right fold only iff the function you're folding the list over does not commute, right?
06:22:23<Cale>Oh, there's a new language comparison table there :)
06:22:43<cads>Gracenotes: even a union is a fold?
06:23:02<Gracenotes>I think you could consider a big union a fold of unions
06:23:12<cads>certainly
06:23:17<ray>they're different if it doesn't commute, but i'm not sure about iff
06:23:36<cads>no it's not iff, sorry
06:24:00<cads>they can be the same even if f doesn't commute in general
06:24:23<Gracenotes>I'm pretty sure associative is required though, hmm?
06:24:42<Gracenotes>I've wondered about the class of operators for which left fold == right fold...
06:24:50<cads>it just has to have the right type
06:25:26<Gracenotes>if foldl f z xs compiles, foldr (flip f) z xs will compile. so type isn't so hard...
06:26:03<copumpkin>commutative?
06:26:13<copumpkin>if you want foldl to equal foldr?
06:26:15<dmwit>> foldr f z [x, y, z]
06:26:17<lambdabot> Ambiguous occurrence `f'
06:26:17<lambdabot> It could refer to either `L.f', defined at <local...
06:26:25<dmwit>> foldr g z [x, y, z]
06:26:27<lambdabot> Ambiguous occurrence `g'
06:26:27<lambdabot> It could refer to either `L.g', defined at <local...
06:26:31<dmwit>booo
06:26:36<copumpkin>@undefine
06:26:41<dmwit>> foldr f z [x, y, z]
06:26:43<lambdabot> f x (f y (f z z))
06:26:46<dmwit>> foldl (flip f) z [x, y, z]
06:26:48<lambdabot> f z (f y (f x z))
06:26:59<copumpkin>zomg noes
06:26:59<Gracenotes>copumpkin: for all input, yes
06:27:03<dmwit>Oh, let's try that again, with less z's this time.
06:27:07<Gracenotes>finite input, let's say, to keep it simple
06:27:20<dmwit>> (foldr f z [w, x, y], foldl (flip f) z [w, x, y])
06:27:22<lambdabot> (f w (f x (f y z)),f y (f x (f w z)))
06:27:30<Gracenotes>works for (+) for instance
06:27:45<dmwit>Looks like it has to be at least commutative.
06:28:04<Gracenotes>there may be non-commutative though. I'm not quite sure :)
06:28:14<copumpkin>well since it's going in the opposite "direction"
06:28:26<copumpkin>it's going to take a lot of "commutation" to get it back into the right direction :)
06:28:31<dmwit>> (foldr f z [x, y], foldl (flip f) [x, y])
06:28:33<copumpkin>seems like that's all that's needed though
06:28:33<lambdabot> No instance for (SimpleReflect.FromExpr [SimpleReflect.Expr])
06:28:33<lambdabot> arising fr...
06:28:37<cads>I think it needs to be associative as well. Given the commutativity, it seems like if foldl f a = foldr f a, f::a->a->a
06:28:38<dmwit>> (foldr f z [x, y], foldl (flip f) z [x, y])
06:28:40<lambdabot> (f x (f y z),f y (f x z))
06:29:08<copumpkin>oh yeah, I meant in addition to the associativity that Gracenotes mentioned earlier
06:29:14<dmwit>Gracenotes: Well, if the function has any fixed-point, the above proves that it must also be commutative for left- and right-folds to be equal.
06:29:39<Gracenotes>a fix-point? on two parameters?
06:29:50<dmwit>duh, I mean identity
06:29:51<copumpkin>> foldr (+) 0 (replicate 1000 0.01)
06:29:52<lambdabot> 9.999999999999831
06:29:55<copumpkin>> foldl (+) 0 (replicate 1000 0.01)
06:29:57<lambdabot> 9.999999999999831
06:30:10<copumpkin>not associative?
06:30:23<Gracenotes>hm
06:30:31<copumpkin>not sure that counts as a proof though ;)
06:30:34<Gracenotes>someone needs to write a proof or something! not it.
06:30:56<Gracenotes>I'll see if there's anything online...
06:31:10<dmwit>copumpkin: If it's not commutative, there is x and y such that f x y /= f y x. Taking z to be the identity, then f x (f y z) /= f y (f x z). QED
06:31:25<copumpkin>hmm?
06:31:31<copumpkin>I wasn't questioning the commutativity
06:31:33<dmwit>oh
06:31:34<dmwit>heh
06:31:40<copumpkin>the associativity though?
06:32:00<copumpkin>I don't think it needs it
06:32:03<dmwit>Yeah, I'm not sure I see where associativity comes in, either.
06:32:47<dmwit>Quick! Somebody think of a function that's commutative but not associative.
06:32:57<copumpkin>floating point addition :P
06:33:33<dmwit>prove it
06:33:42<dmwit>No, don't bother.
06:33:48<dmwit>It's not helpful the way I thought it would be.
06:34:09<Cale>Floating point addition is not associative
06:34:14<dmwit>I know.
06:34:23<Gracenotes>I saw this: http://portal.acm.org/citation.cfm?id=156301.156303
06:34:28<dmwit>I was just asking for a specific example that shows off that fact. =)
06:34:31<copumpkin>@check \x y z -> (x + y) + z == (x :: Float) + (y + z)
06:34:32<Gracenotes>"when floating-point addition isn't commutative"
06:34:32<lambdabot> "Falsifiable, after 11 tests:\n-1.6\n1.8\n4.5\n"
06:34:54<Gracenotes>unfortunately it's ACM, so... *arghhhhhhh darn you ACM*
06:35:05<copumpkin>you don't have access?
06:35:08<Cale>Oh, when foldr f z and foldl f z are equal? Well, a sufficient condition is for f and z to give a monoid.
06:35:24<copumpkin>really?
06:35:26<copumpkin>hmm
06:35:27<Cale>yes
06:35:28<Gracenotes>Cale: iff?
06:35:28<dmwit>Yeah, but that's too much.
06:35:36<dmwit>Because monoids are associative.
06:35:40<Cale>Obviously it's not a necessary condition.
06:35:45<dmwit>I don't think associativity is necessary.
06:35:47<Cale>Associativity is important.
06:35:54<dmwit>oh?
06:36:05<Cale>That's most of the difference between the two
06:36:05<Gracenotes>and there's also: foldr f z vs. foldl (flip f) z, which allows list type != accumulator type in comparison
06:36:21<Cale>The only other difference is that they put the z on opposite ends
06:36:48<dmwit>Wait, hold up a tick: are we comparing foldr f and foldl f, or foldr f and foldl (flip f)?
06:36:54<Cale>But I don't think there's a nice necessary+sufficient condition.
06:37:01<dmwit>For the former, I could believe associativity matters; for the latter, not so much.
06:37:12<Cale>foldr f z and foldl f z
06:37:23<Gracenotes>> (foldl (-) 0 [1..100], foldr subtract 0 [1..100])
06:37:25<lambdabot> (-5050,-5050)
06:37:28<Cale>foldl (flip f) z is like foldr f z . reverse
06:37:47<Gracenotes>Cale: yes...
06:38:09<Gracenotes>hm. So if f is commutative, that might be an easier condition...
06:38:14<Cale>wait...
06:38:23<Cale>> foldl (flip f) z [1,2,3,4,5]
06:38:25<lambdabot> f 5 (f 4 (f 3 (f 2 (f 1 z))))
06:38:37<Cale>right, yes
06:39:05<Cale>But for the other way, f being commutative doesn't help.
06:39:23<Cale>hmm
06:40:58<mmorrow>, foldr (.) id [f,f,f,f] x
06:41:00<lunabot> f (f (f (f x)))
06:41:04<mmorrow>, foldl (flip id) x [f,f,f,f]
06:41:07<lunabot> f (f (f (f x)))
06:41:19<copumpkin>cheat0r
06:41:28<mmorrow>z0mg
06:42:21<dmwit>, foldr ($) x [f, f, f, f]
06:42:23<lunabot> f (f (f (f x)))
06:42:51<dmwit>, iterate f x !! 4
06:42:54<lunabot> f (f (f (f x)))
06:43:18<copumpkin>, f (f (f (f x)))
06:43:20<lunabot> luna: Ambiguous type variable `a' in the constraints:
06:43:24<copumpkin>ACTION fails :)
06:43:29<copumpkin>, f (f (f (f x))) :: Expr
06:43:31<lunabot> luna: Ambiguous type variable `t' in the constraints:
06:43:38<copumpkin>ACTION fails again
06:43:56<mmorrow>ah yeah, that's annoying
06:44:02<mmorrow>, fix (h . g . f)
06:44:04<lunabot> luna: Ambiguous type variable `c' in the constraints:
06:44:09<mmorrow>, fix ((h::Expr->Expr) . g . f)
06:44:10<lunabot> luna: Ambiguous type variable `b' in the constraints:
06:44:12<copumpkin>failuna
06:44:15<mmorrow>, fix ((h::Expr->Expr) . (g::Expr->Expr) . f)
06:44:17<lunabot> h (g (f (h (g (f (h (g (f (h (g (f (h (g (f (h (g (f (h (g (f (h (g (f (h...
06:44:36<mmorrow>you can't have more than one 'f' (or whatever) "in a row"
06:44:41<mmorrow>without an annotation
06:45:00<Gracenotes>because FromExpr is just Expr a => (Expr -> a)
06:45:05<mmorrow>i think it's for the same reason that (read . show) doesn't work
06:45:09<mmorrow>yeah
06:45:19<Gracenotes>er. s/Expr/FromExpr/g
06:45:40<Gracenotes>actually, more general than I thought. (Show a, FromExpr b) => FromExpr (a -> b)
06:46:19<mmorrow>@type [($),id]
06:46:20<lambdabot>forall a b. [(a -> b) -> a -> b]
06:46:36<Gracenotes>> f (Just "hello there") :: Expr
06:46:37<lambdabot> f (Just "hello there")
06:46:39<mmorrow>foldr ($) === foldl (flip id)
06:47:01<mmorrow>(at least wrt the result)
06:47:17<mmorrow>err, s/result/type/
06:47:31<cads>we have 1) (((a* + a) + b) + c). I don't think we can we transform 2) ((a* + c) + b) + a) into 1) unless + is both assoc and commie. Using associativity lets us rewrite this as (a* + c + b + a). Using commutativity allows us to rewrite 2) to (a + (b + (a* + c))), but to break the a* out and bring it to the front, we need assoc
06:47:35<mmorrow>(and foldr ($) = foldr id ;)
06:48:37<mmorrow>the thing with fold direction too is (i've wondered how to say without hand-waving) that you usually (always?) want to fold in the direction of an op's fixity
06:48:50<mmorrow>, src '(.)
06:48:53<lunabot> ) :: forall b c a . (b -> c) -> (a -> b) -> a -> c
06:48:53<lunabot> infixr 9 )
06:48:58<mmorrow>:o
06:49:15<Cale>> fix (\g -> (1:) . g) []
06:49:18<lambdabot> [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,...
06:49:20<mmorrow>infix infixr 5 ++
06:49:22<Cale>> fix (\g -> g . (1:)) []
06:49:30<lambdabot> mueval-core: Prelude.read: no parse
06:49:30<lambdabot> mueval: ExitFailure 1
06:49:42<dmwit>> fromExpr "hey" x
06:49:46<lambdabot> Not in scope: `fromExpr'
06:50:50<mmorrow>hatds: hmm, i played with it a little more, but i feel like every time i write an expression that uses Push, the Pushes are just extraneous
06:50:51<Cale>mmorrow: That's because people choose the fixity the same way they'd choose a fold, because a left fold produces a left-associated expression and a right fold produces a right associated one :)
06:51:01<mmorrow>Cale: heh, good point
06:51:02<cads>fixpoints are kind of ungodly powerful
06:51:15<mmorrow>Cale: self-fulfilling prophecyish
06:52:21<Gracenotes>> fun "Hello there" "person" :: Expr
06:52:23<lambdabot> Hello there "person"
06:52:37<dmwit>cads: Yep, anything you can do with recursion...
06:53:59<mmorrow>fix === a while(1), a single var, and the ability to break or continue..
06:55:14<cads>dmwit, even elsewhere. For example the fixpoint theorem from metric spaces in analysis lets you do some sick stuff as far as proving the existance of solutions to some crazy integral equations and other things
06:55:30<mmorrow>well, it's more i guess kinda
06:55:48<mmorrow>, fix (\x -> Node () [x,x]) {- self-referent structures -}
06:55:50<lunabot> Node {rootLabel = (), subForest = [Node {rootLabel = (), subForest = [Nod...
06:56:20<Gracenotes>mmorrow: hm... not so sure about that?
06:56:27<mmorrow>void *xs[2]; xs[0] = xs; xs[1] = xs;
06:56:33<cads>using fixed points and their properties we can write out a very nice computability theory, too
06:56:49<mmorrow>Gracenotes: about what?
06:56:50<Gracenotes>you can have recursive fib with fixpoint after all. It is really just recursion. not sure if it's general, but I woudln't be surprised...
06:58:49<mmorrow>i don't understand
06:59:19<mmorrow>int x[] = {0,1}; int tmp; while(1){printf("%d\n",x[0]); tmp = x[0]; x[0] = x[1]; x[1] += tmp;}
06:59:35<mmorrow>, fix (\k m n -> m : k n (m+n)) 0 1
06:59:36<lunabot> [0,1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,1597,2584,4181,6765,109...
07:00:13<Gracenotes>mmorrow: that's not recursive fib :)
07:00:20<mmorrow>but doing "void *xs[2]; xs[0] = xs; xs[1] = xs;" is kinda a different concept than a while loop
07:00:29<mmorrow>Gracenotes: it's recursing :)
07:00:30<Cale>Gracenotes: But it sort of is...
07:00:53<Cale>fix f = x where x = f x
07:01:00<Cale>So...
07:01:05<Cale>fix (\k m n -> m : k n (m+n)) 0 1
07:01:39<Cale>= x 0 1 where x = (\k m n -> m : k n (m+n)) x
07:01:55<Cale>= x 0 1 where x = \m n -> m : x n (m+n)
07:01:58<Gracenotes>> fix (\k b -> if b <= 1 then b else k (b - 1) + k (b - 2)) 10
07:01:59<lambdabot> 55
07:02:03<Cale>= x 0 1 where x m n = m : x n (m+n)
07:02:57<cads>http://aclinks.wordpress.com/ how to become a successful researcher :D
07:03:09<mmorrow>Gracenotes: you can do that with a while loop too, you just have to maintain your own call stack
07:03:15<Gracenotes>you can do branching recursion, it seems. probably even ackermann
07:03:17<cads>a talk by peyton jones on the subject is listed there, that ought to be entertaining
07:03:32<Gracenotes>which is just about as primitive-recursive-y as you can go
07:03:36<mmorrow>Gracenotes: err, fix is general recursion
07:03:37<Cale>Gracenotes: You can write *all* recursion in terms of fix
07:03:57<cads>can't fix do corecursion and junk?
07:03:59<Gracenotes>mmorrow: okay, why didn't you say so? :)
07:04:20<mmorrow>Gracenotes: heh, i didn't know what you were saying until just now
07:04:30<Gracenotes>you can write all recursion in terms of while(1) too, although when you need an explicit call stack... hrm
07:04:39<Gracenotes>as you just said
07:05:03<Gracenotes>just not tail recursive then.
07:05:05<mmorrow>well, you need the stack if you want to write it in the same style
07:05:26<mmorrow>you can always transform it i guess (maybe)
07:06:02<cads>if we have f = g . f for nonrecursive g, then doesn't f = fix g ?
07:06:07<mmorrow>as in, just compute it bottom-up
07:06:19<Gracenotes>@free fix
07:06:22<lambdabot>f . g = h . f => f (fix g) = fix h
07:06:23<mmorrow>like that bottom-up fib
07:07:13<cads>Gracenotes: so yes, neat
07:07:30<Gracenotes>hm... for what values of f, g, and h does it == your theorem?
07:08:20<cads>the rolling theorem is neat too fix (f . g) = g (fix (g . f))
07:08:23<Gracenotes>(of course both may be independant)
07:08:45<Gracenotes>cads: ooh, that's neat f . g . f . g . f . g
07:09:00<Cale>if we put g = id, then we get if f = h . f then f (fix id) = fix h
07:09:20<mmorrow>, fix ((h::Expr->Expr) . (g::Expr->Expr) . f) {- never gets old -}
07:09:22<lunabot> h (g (f (h (g (f (h (g (f (h (g (f (h (g (f (h (g (f (h (g (f (h (g (f (h...
07:09:24<cads>thanks cale
07:09:42<Cale>Which means that f = const (fix h)
07:09:55<Gracenotes>hm
07:10:53<Cale>cads: Not f (fix (g . f)) ?
07:11:16<Cale>> fix ((1:) . (2:))
07:11:18<lambdabot> [1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,...
07:11:31<Cale>> (1:) (fix ((2:) . (1:)))
07:11:33<lambdabot> [1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,...
07:11:58<cads>hrm
07:12:28<thomastc>lambdabot: can Haskell take over the world?
07:12:46<Cale>@faq can Haskell take over the world?
07:12:47<lambdabot>The answer is: Yes! Haskell can do that.
07:13:07<thomastc>ah, confused with syntax of other bot, thanks :)
07:14:05<mmorrow>, fix ((0:) . scanl (+) 1)
07:14:07<lunabot> [0,1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,1597,2584,4181,6765,109...
07:14:11<cads>ahh, cale, (f . g . f . g ...) = f (g . f . g ...), you're right; f is the "last" function we apply before our point is fixed. We can pull it out, and roll over the variables
07:14:19<cads>err, functions
07:14:26<Cale>cads: yeah
07:14:37<Cale>Or the first
07:14:45<Cale>Depending on the way you look at it
07:15:28<cads>grr, I wish I knew function composition like I knew addition and multiplication
07:15:31<Cale>ACTION is geared to thinking of evaluation as being outermost-first
07:19:12<copumpkin>fail: http://shootout.alioth.debian.org/u64q/benchmark.php?test=regexdna&lang=ghc&id=4
07:25:12<cads>Let's say a corecursive function fixes after a few iterations, like 1) (f . g . f . g) = g (f . g . f . g). Then obviously 2) f (g . f . g) is the same thing as the lhs of 1). But then 1) = fix(f . g) = 2) = f . (fix (g . f)). This is true for functions which fix in a given number of recursion, and for functions that fix in a number of recursions greater than that. I think there are a few holes, but QED.
07:25:18<cads>hehe, I need to go to bed
07:25:31<cads>take care all
07:26:22<cads>ACTION handwaves all the way to bed
07:28:55<copumpkin>night :)
07:39:52<copumpkin>is a unitary matrix positive definite?
07:42:57<Raynes>ACTION huggles copumpkin
07:44:16<ivanm>"huggles"?
07:44:35<copumpkin>ACTION huggles ivanm and Raynes
07:44:50<ivanm>stay away from me!
07:45:01<Raynes>ivanm: It's a word used by sophisticated IRC/Haskellers.
07:45:20<ivanm>ACTION quickly builds a barrier out of handy objects, furniture, people, etc. to protect against copumpkin
07:45:37<ivanm>Raynes: since when did "sophisticated" imply "can't use normal English words"?
07:45:54<olsner>ivanm: hasn't that always been the case?
07:46:06<ivanm>not that I know of
07:46:17<^Someone^>"normal"?
07:46:19<Raynes>ivanm: Since I invented the word glaseymaster.
07:46:24<copumpkin>Raynes: there's a @spam twitter account btw
07:46:49<Raynes>To report spammers?
07:46:52<Raynes>Neato.
07:46:58<ivanm>^Someone^: normal, as in words that already exist, etc.
07:47:05<^Someone^>"huggles" does exist
07:47:29<hackagebot>explicit-sharing 0.4.0
07:47:30<ivanm>Raynes: oh, I would have thought it would have been to get your daily fix of spam...
07:47:34<^Someone^>It's recently been added to the dictionary too
07:47:38<ivanm>^Someone^: formally?
07:47:45<ivanm>ACTION checks his dictionaries
07:48:02<^Someone^>Yes
07:48:48<ivanm>I can't find it in the copy of the Pocket Oxford Dictionary I have handy
07:48:55<ivanm>but there is "hugger-mugger" :s
07:49:11<^Someone^>Somewhat recently -_-
07:49:19<^Someone^>Anyway!
07:49:23<^Someone^>That's not the point
07:49:52<^Someone^>The point is that it makes sense to create and use such a word
07:51:06<^Someone^>Especially for a functional programmer, I should think : o
07:51:31<ivanm>it does?
07:51:35<ivanm>in what way?
07:51:38<^Someone^>It's almost like function composition
07:51:42<ivanm>since I have no idea wtf it means... >_>
07:51:59<^Someone^>It's a hug and a snuggle combined
07:52:09<ivanm>*shudder*
07:52:38<ivanm>function composition -/-> "making up new words by juxtapositioning one word upon another"
07:52:47<^Someone^>"almost like"
07:53:35<copumpkin>huggle = hug . cuddle
07:53:39<ivanm>*usage of function composition
07:53:53<ivanm>copumpkin: that makes even less sense than ^Someone^'s definition
07:54:08<ivanm>and it goes to show, that if you can't even decide what your made-up words mean, then we shouldn't be using them!
07:54:18<copumpkin>who says it isn't an overloaded word?
07:54:22<copumpkin>language are full of them
07:54:28<copumpkin>*languages
07:54:32<ivanm>heh
07:54:43<olsner>"portmonteau" is a nice term that I think might apply to 'huggle'
07:55:01<dmwit>?wn portmanteau
07:55:03<lambdabot>*** "portmanteau" wn "WordNet (r) 2.0"
07:55:03<lambdabot>portmanteau
07:55:03<lambdabot> n 1: a new word formed by joining two others and combining their
07:55:03<lambdabot> meanings; "`smog' is a blend of `smoke' and `fog'";
07:55:03<lambdabot> "`motel' is a portmanteau word made by combining `motor'
07:55:05<lambdabot>[5 @more lines]
07:55:08<dmwit>Your spelling sucks, but your vocabulary is impeccable.
07:55:12<copumpkin>besides, it may just be a proof that snuggle == cuddle assuming hug is a monomorphism
07:55:14<ivanm>class Definition ^Someone^ where huggle = hug . snuggle; class Definition copumpkin where huggle = hug . cuddle
07:55:15<ivanm>;-)
07:55:19<^Someone^>Yes, the words were MELDed together
07:55:21<^Someone^>; )
07:55:25<ivanm>olsner: no, IIRC portmanteau means they just join them together
07:55:28<^Someone^>Like Melt and weld xD
07:55:41<ivanm>whereas both ^Someone^ and copumpkin have dropped intermediary letters
07:55:45<copumpkin>ACTION wonders if he used monomorphism correctly there
07:56:09<copumpkin>ACTION is still reading awodey
07:56:29<dmwit>I think you used it correctly.
07:56:44<dmwit>The only other choice is epimorphism, but it's not that. =)
07:56:58<copumpkin>I prefer to call it an epic morphism win
07:57:13<ivanm>dmwit: hmmm, maybe he did
07:58:12<mornfall>ivanm: "just joining" is juxtaposition, portmanteau is smacking them together at high speed. ;)
07:58:26<ivanm>*nod*
07:58:42<ski>forall A,B. forall f : A -> B. mono f <=> forall T. forall x,y : T -> A. f . x = f . x => x = y
07:58:43<ivanm>ahhh, I used the wrong term
07:58:45<copumpkin>epic word fusion
07:58:56<copumpkin>I mean monic
07:58:57<ivanm>not juxtaposition.... which word means you put one on top of the other?
07:58:57<copumpkin>;)
07:58:58<Gracenotes>o nos
07:59:35<mornfall>ivanm: overlay maybe?
07:59:45<ivanm>maybe
08:00:00<ivanm>there's a semi-technical term though... *shrug* not that big a deal
08:00:12<dmwit>superposition?
08:00:17<osfameron>superimpose?
08:00:17<mornfall>Like jumbled printing? : - )
08:00:17<dmwit>But that's not really the same.
08:00:38<mornfall>Sounds perfectly technical to me.
08:00:49<ivanm>dmwit: that's the one
08:00:57<ivanm>that's what I was thinking of, anyway
08:01:26<ski>ACTION . o O ( M-x dissociated-press )
08:02:09<olsner>ski executes the dissociated press?
08:02:13<mornfall>Err. --> bassoon, anyway. Cya. :)
08:02:49<ivanm>ski: hmmmm, my version of emacs doesn't have that function
08:02:57<ivanm>is it from an external elisp file?
08:04:45<ski>`dissociate.el' according to <http://en.wikipedia.org/wiki/Dissociated_press>
08:17:15<dancor_>i want to be able to sequentially modify all the occurrences of the datatype Expr in my Stmt datatype
08:17:31<dancor_>it sounds like Traversable, but it's complicated by having a second type i think
08:22:30<ski>Detect Loop <http://www.getacoder.com/projects/detect_loop_106243.html>
08:23:27<dmwit>troll
08:23:37<dmwit>Hint #1: username is fermat.
08:23:44<dcoutts>ski: no problem, so long as they don't mind occasionally getting "dunno" as the answer
08:27:09<ski>dancor_ : "complicated by having a second type" ?
08:27:34<WorkyBob>ski: hehe, that one is fun
08:27:42<copumpkin>halting is decidable on LBAs anyway isn't it?
08:27:59<dmwit>LBA?
08:28:04<copumpkin>linear bounded automaton
08:28:34<copumpkin>hrm
08:28:42<dancor_>ski: Traversable vs views? http://moonpatio.com:8080/fastcgi/hpaste.fcgi/view?id=2516#a2516
08:29:02<Twey>« Hi Will be done within time and budget .............. If you have any query plz ask without any hesitation ....... Best Regards »
08:29:05<Twey>ACTION chuckles.
08:29:30<WorkyBob>shame someone pointed out the imposibility to them
08:29:31<dancor_>i think that if i had data Stmt expr = StmtBreak expr Other Stuff | .. then Traversable would be perfect
08:29:59<dancor_>but since i have data Stmt = StmtBreak Expr Other Stuff | .. i don't think i can use Traversable, is that correct?
08:30:15<Twey>« I will build the program that not only detect infinite loop as well as it will checked also improper if condition and also switch.Program also trying to read the logic of recursion and if it is improper then it will prompt the list of suggesstion.So I am confident to build your project in c# with Sql Sever.I would accept payment after you satishfied with the work. Regards Sumanta »
08:30:28<Twey>This is a real lesson in why not to use rent-a-coder sites
08:30:32<copumpkin>is that a real reasponse?
08:30:33<copumpkin>wow
08:30:35<Twey>Yeah
08:30:49<WorkyBob>>.<
08:30:51<Twey>(or C# programmers :-P)
08:30:55<Ycros>Twey: oh, I was reading that earlier, it was totally hilarious
08:30:57<copumpkin>he should've mentioned active directory, and used the word enterprise at least twice
08:31:02<Twey>Hahaha
08:31:07<WorkyBob>hahahahaha
08:31:36<copumpkin>:)
08:31:40<WorkyBob>he didn't mention XML either
08:31:46<Twey>Or Java
08:31:47<ski>dancor_ : have you seen mmorrow's `Cxt'/`View' ?
08:31:48<WorkyBob>surely XML would be needed to solve the halting problem
08:31:51<Twey>Or is Java no longer the In Thing?
08:31:55<WorkyBob>no, Java's old
08:31:57<WorkyBob>sorry
08:32:00<Twey>Damn
08:32:04<WorkyBob>you're obviously a bad programmer Twey
08:32:07<WorkyBob>not keeping up with the times
08:32:34<ski>dancor_ : btw, i'm doubtful of `class Look a b where look :: a -> View a b' to be that useful
08:33:25<dancor_>ski: i haven't where is mmorrow's stuff, #haskellogs?
08:33:28<Twey>I know, it's shocking
08:33:57<ski>mmorrow : well, <http://moonpatio.com/fastcgi/hpaste.fcgi/view?id=2486> at least .. possibly mmorrow can give better reference
08:34:38<ski>er
08:34:48<ski>s/mmorrow :/dancor_ :/
08:35:56<ski>(dancor_ : e.g. see `accumView' there)
08:37:52<dancor_>hm
08:38:14<dancor_>it is true that Traversable isn't appropriate here right?
08:38:18<dancor_>it seems so close
08:39:18<ski>`Traversable' wants to work with a parameterized type
08:39:35<dancor_>ya
08:39:36<dancor_>ok
08:39:39<ski>you just want to work with "all substructures of type `Expr'"
08:39:50<ski>there might be some SYB you could use ..
08:40:13<mmorrow>dancor: here's a paste from a few days ago http://moonpatio.com/fastcgi/hpaste.fcgi/view?id=2486
08:40:23<ski>you could of course write an `traverseExpr :: Applicative i => (Expr -> i Expr) -> (Stmt -> i Stmt)' yourself
08:40:44<dancor_>mmorrow: yes that's very interesting and your TH skills are way beyond me :)
08:41:26<mmorrow>dancor_: heh, what are you going for?
08:41:57<dancor_>well i will probably want to do this with other datatypes besides Stmt and Expr as well
08:42:16<dancor_>but maybe i'll just write traverseExpr for now then consider insane TH later
08:42:36<dancor_>mmorrow: i'm just trying to do abstract syntax tree manipulations
08:43:48<mmorrow>what i really want to be able to do is (and andyjgill's KURE pkg does this, but i haven't worked out how to generate all the instance, functions, etc code i need to be able to use it quite yet) is to be able to write a function that does some little/specific transformation to an AST, and then be able to apply that, with the choice of top-down or bottom-up, to an expression. and syb doesn't quite do it for me since i need to also thread a
08:43:49<mmorrow> monad through it.
08:44:00<mmorrow>dancor_: totally, me too
08:44:07<dancor_>hah nice
08:44:21<ski> Data.Generics.Schemes.everywhereM :: Monad m => (forall a. Data a => a -> m a) -> (forall a. Data a => a -> m a)
08:44:36<mmorrow>dancor_: (and all this is a product of being completely fed up with writing (essentially) the same traversals over each new AST)
08:44:46<ski>dancor_ : that's what i was thinking about
08:45:21<mmorrow>ski: yeah, the thing with everywhereM though is that you have no control over traversal strategy
08:45:44<mmorrow>(but everywhere(M) is totally handay, don't get me wrong)
08:46:01<ski>*nod*
08:46:43<mmorrow>hmm, i wonder ... you could find out what it's doing by using a state monad..
08:46:48<mmorrow>> everywhereM
08:46:50<lambdabot> Overlapping instances for GHC.Show.Show
08:46:50<lambdabot> (Data....
08:47:55<ski>ACTION wonders whether `everywhere' traverses into existentially hidden structures, having the `Data' constraints
08:47:59<Gracenotes>:t everywhereM
08:48:01<lambdabot>forall (m :: * -> *) a. (Data a, Monad m) => GenericM m -> a -> m a
08:48:09<mmorrow>> flip runState 0 (everywhereM (\_ -> do i <- get; put (i+1); return (i::Int)) (Node 0 [Node 1 [Node 2 []], Node 3 [Node 4 []]]))
08:48:11<lambdabot> Couldn't match expected type `a'
08:48:26<mmorrow>oh, what is the monadic mkT?
08:48:59<mmorrow>> flip runState 0 (everywhereM (mkM (\_ -> do i <- get; put (i+1); return (i::Int))) (Node 0 [Node 1 [Node 2 []], Node 3 [Node 4 []]]))
08:49:01<lambdabot> (Node {rootLabel = 0, subForest = [Node {rootLabel = 1, subForest = [Node {...
08:49:19<mmorrow>> levels (Node 0 [Node 1 [Node 2 []], Node 3 [Node 4 []]]))
08:49:20<lambdabot> <no location info>: parse error on input `)'
08:49:23<mmorrow>> levels (Node 0 [Node 1 [Node 2 []], Node 3 [Node 4 []]])
08:49:24<lambdabot> [[0],[1,3],[2,4]]
08:49:30<mmorrow>> levels $ flip runState 0 (everywhereM (mkM (\_ -> do i <- get; put (i+1); return (i::Int))) (Node 0 [Node 1 [Node 2 []], Node 3 [Node 4 []]]))
08:49:31<lambdabot> Couldn't match expected type `Data.Tree.Tree a'
08:50:01<ski>@type levels
08:50:02<lambdabot>forall a. Tree a -> [[a]]
08:50:06<re__>hi there
08:50:19<re__>anyone there who likes to help me a little with profiling?
08:50:33<mmorrow>> levels $ flip evalState 0 (everywhereM (mkM (\_ -> do i <- get; put (i+1); return (i::Int))) (Node 0 [Node 1 [Node 2 []], Node 3 [Node 4 []]]))
08:50:34<lambdabot> [[0],[1,3],[2,4]]
08:50:50<mmorrow>so i guess it's depth-first
08:50:56<mmorrow>err
08:51:04<mmorrow>yeah
08:51:15<mmorrow>no
08:51:28<mmorrow>breadth-first
08:51:46<mmorrow>top-down
08:53:59<JaffaCake>mmorrow: have you tried using StableName for vacuum, instead of unsafePtrEquality?
08:54:51<mmorrow>dancor_: anyways, the code to generate those instances of View was semi-epic... you have to build the graph of all reachable types from a type, compute the SCC that that type's in, build a Map of Type -> [(Int{-con tag-},[(Int{-field index-}, Type)]], and finally generate the View instance picking out the 'b' in (View a b) from all the places in 'a' where it occurs
08:55:32<mmorrow>JaffaCake: i haven't. do you think it would be a lot of overhead for a graph of, say, 1000+ nodes?
08:55:58<JaffaCake>well, using ptr equality is quadratic, whereas with StableName you could have a hash table
08:56:20<mmorrow>ahhh, yeah true. i have to do linear search through seen nodes with ptr equality..
08:56:25<JaffaCake>there might be a constant factor, but I think you'd win with large graphs
08:56:52<mmorrow>hmm, interesting. i'll try it out.
08:57:24<mmorrow>JaffaCake: what about the possibility of false negatives?
08:57:52<JaffaCake>I don't think it's any worse than with ptr equality
08:58:04<mmorrow>nice
08:59:07<ski>@hoogle GenParser t s [t] -> GenParser t s ()
08:59:08<lambdabot>No results found
08:59:43<dancor_>mmorrow: sorry i was playing with the tree example. it's depth-first right, since the numbering is the same
08:59:44<ski>@hoogle GenParser t s [t] -> GenParser t s a -> GenParser t s a
08:59:45<lambdabot>No results found
09:00:02<ski>> levels $ flip evalState 0 (everywhereM (mkM (\_ -> do i <- get; put (i+1); return (i::Int))) (Node 0 [fix $ \t -> Node 1 [Node 2 [t]], Node 3 [Node 4 []]]))
09:00:03<lambdabot> [[0],[1,3],[2,4],[1],[2],[1],[2],[1],[2],[1],[2],[1],[2],[1],[2],[1],[2],[1...
09:00:29<mmorrow>dancor: ah yeah, depth-first (i confused myself)
09:00:51<dancor_>mmorrow: and, about TH, it all seems very epic to me :)
09:01:58<mmorrow>dancor_: heh. once you get a code-base of it though, it starts to get self-supporting in that you can use it to generate more of it to use it to ...
09:02:24<dancor_>you don't change TH. it changes you (and itself)
09:03:16<mmorrow>for instance, once i finally figure out howtf to generate the KURE support code for the TH AST itself, then i can use kure to manipulate the TH which'll then generate the kure support code for other ast's more easily..
09:03:30<mmorrow>dancor_: totally
09:05:40<mmorrow>well, kure is more for transforming an ast than it is for building expression/whatever with that ast, but you know what i mean :)
09:06:00<dancor_>i'm reading about kure now
09:06:52<mmorrow>dancor_: it's interesting. the trickyness comes in when your ast's cons have fields like:
09:07:18<mmorrow>data Exp = ... | Foo [Exp] (Maybe Exp) ([Stmt],Maybe ..) | ....
09:07:39<mmorrow>then you have to figure out how to see through/something the []s and Maybes
09:08:03<mmorrow>(and (,,...,)s)
09:08:13<mmorrow>which is a total pita
09:09:59<quicksilver>is implementing Num to lift things into your EDSL *actually* a sensible technique
09:10:08<quicksilver>or is it in fact a rather despicable hack?
09:10:43<mmorrow>heh, it'd be nice if there was a class with only fromInteger..
09:11:13<mmorrow>because i feel like whenever i make Num instances, at least abs and signum are error "..."
09:11:27<quicksilver>ACTION nods
09:11:34<quicksilver>well I was looking at the cafe thread about bool as a type class.
09:11:45<quicksilver>but to me, it's always felt like rather an abuse to do this at all.
09:11:49<quicksilver>ACTION shrugs
09:12:04<lars9>how to understand fmap vs. map?
09:12:12<quicksilver>map only works on lists
09:12:20<quicksilver>fmap works on all functors (including lists)
09:12:41<mmorrow>@src [] fmap
09:12:42<lambdabot>fmap = map
09:12:48<mmorrow>@src [] Maybe
09:12:48<lambdabot>Source not found. Just what do you think you're doing Dave?
09:12:54<mmorrow>> fmap (*2) (Just 4)
09:12:55<lambdabot> Just 8
09:13:09<dancor_>@src Maybe fmap
09:13:09<lambdabot>fmap _ Nothing = Nothing
09:13:09<lambdabot>fmap f (Just a) = Just (f a)
09:13:15<mmorrow>heh, oops
09:13:30<dancor_>allyoops
09:13:33<lars9>>fmap (*2) [1,2,3]
09:13:42<lars9>> fmap (*2) [1,2,3]
09:13:43<lambdabot> [2,4,6]
09:13:57<lars9>> fmap (*2) (*3)
09:13:58<lambdabot> Overlapping instances for GHC.Show.Show (a -> a)
09:13:58<lambdabot> arising from a use of `...
09:14:09<mmorrow>> (fmap . fmap . fmap) (*2) [Just [4]]
09:14:10<lambdabot> [Just [8]]
09:14:13<WorkyBob>> fmap (*2) (*3) $ 6
09:14:14<lambdabot> 36
09:14:27<WorkyBob>> fmap fmap fmap fmap fmap (*2) [Just [4]]
09:14:29<lambdabot> Couldn't match expected type `a -> a1' against inferred type `[a2]'
09:14:34<WorkyBob>damn, need parens for that one
09:14:44<lars9>> (fmap (*2) (*3)) 4
09:14:44<WorkyBob>> fmap (fmap fmap fmap) fmap (*2) [Just [4]]
09:14:45<lambdabot> 24
09:14:46<lambdabot> [Just [8]]
09:15:17<lars9>hey, is fmap (*2) (*3) equal to (*6) ?
09:15:22<WorkyBob>yes
09:15:31<WorkyBob>fmap (*2) (*3) is (*2) . (*3)
09:15:41<Axman6>hmm, this seems wrong to me, but i can't think of a situation that disproves it. are powers of 2 only dividible by smaller powers of 2?
09:15:53<WorkyBob>Axman6: yes
09:15:57<WorkyBob>and it's easily proved
09:16:01<Axman6>@src (->) fmap
09:16:01<lambdabot>fmap = (.)
09:16:05<WorkyBob>break them down to prime factors
09:16:15<WorkyBob>2, 2, 2, 2, 2..... 2, 2
09:16:16<Axman6>and all you get is 2's
09:16:18<qebab>Axman6: Prime factorisation of a power of 2 consists only of 2s.
09:16:27<lars9>what does this command mean? @src
09:16:37<WorkyBob>lars9: it displays the source for a function
09:16:45<Axman6>@src map
09:16:45<lambdabot>map _ [] = []
09:16:45<lambdabot>map f (x:xs) = f x : map f xs
09:16:46<WorkyBob>as defined by the haskell report IIRC
09:17:30<lars9>@src fmap (*2) (+3)
09:17:31<lambdabot>Source not found. I can't hear you -- I'm using the scrambler.
09:17:46<lars9>@src (fmap (*2) (+3))
09:17:46<lambdabot>Source not found. Are you on drugs?
09:17:55<WorkyBob>you can't ask for the source for an expresison
09:17:57<WorkyBob>only for a function
09:18:04<Axman6>lars9: only things in the haskell report (and possibly some others) are in @src
09:18:07<ski>Axman6 : `2' is a power of `2', `2' divides `2', `2' is not smaller than `2'
09:18:08<WorkyBob>what Axman6 did was ask for the source of fmap
09:18:08<lars9>@src fmap
09:18:09<lambdabot>Source not found. I can't hear you -- I'm using the scrambler.
09:18:09<Axman6>@src Maybe
09:18:09<lambdabot>data Maybe a = Nothing | Just a
09:18:11<WorkyBob>and a specific fmap
09:18:19<WorkyBob>the fmap for the type (->)
09:18:23<WorkyBob>i.e. for functions
09:18:27<WorkyBob>@src (->) fmap
09:18:27<lambdabot>fmap = (.)
09:18:56<Axman6>ski: yeah, that's true.
09:19:25<ski>@src [] mzero
09:19:25<lambdabot>mzero = []
09:19:43<ski>(`[]' is not a function)
09:19:45<quicksilver>Axman6: the fundamental theorem of arithmetic explains why/how you can generate all factors from the prime factorisation.
09:19:49<lars9>@src forM
09:19:50<lambdabot>forM = flip mapM
09:20:01<WorkyBob>bah
09:20:05<WorkyBob>@src mapM
09:20:06<lambdabot>mapM f as = sequence (map f as)
09:20:12<WorkyBob>fmap fmap fmap sequence fmap is way better
09:20:13<WorkyBob>:(
09:21:01<lars9>ive still not got used to xxxM functions, often confused by them...
09:21:29<WorkyBob>what do you find confusing about them specifically?
09:21:39<WorkyBob>and do you understand the functor and applicative functions?
09:22:06<WorkyBob>(is guessing not, because most of the xxxM functions are actually applicative ones)
09:22:43<lars9>e.g. liftM, it converts a (a -> a) to (a -> m a) ?
09:22:51<quicksilver>:t liftM
09:22:52<lambdabot>forall a1 r (m :: * -> *). (Monad m) => (a1 -> r) -> m a1 -> m r
09:22:54<WorkyBob>liftM is also known as fmap
09:23:05<quicksilver>^^ no, it converts an (a -> a) to a (m a -> m a)
09:23:07<quicksilver>or more generally
09:23:13<WorkyBob>it converts an (a -> b) to a (m a -> m b)
09:23:14<quicksilver>it converts an (a -> b) to a (m a -> m b)
09:23:19<WorkyBob>jnix!
09:23:20<WorkyBob>:D
09:23:53<lars9>so, liftM (*2) can twice all items in a list?
09:24:01<WorkyBob>indeed
09:24:10<WorkyBob>but in general, calling it fmap is better style
09:24:18<lars9>i see.
09:24:20<WorkyBob>or calling it (<$>) if you want to use it infix
09:24:31<WorkyBob>> (*2) <$> [1,2,3]
09:24:33<lambdabot> [2,4,6]
09:25:24<lars9>and 'return' converts a -> m a?
09:25:38<lars9>:t return
09:25:39<lambdabot>forall a (m :: * -> *). (Monad m) => a -> m a
09:25:48<WorkyBob>yes, but it should really be called pure
09:25:58<lars9>:t pure
09:25:59<lambdabot>forall a (f :: * -> *). (Applicative f) => a -> f a
09:26:11<lars9>@src pure
09:26:11<lambdabot>Source not found. Just what do you think you're doing Dave?
09:26:17<WorkyBob>@src [] pure
09:26:18<lambdabot>pure = return
09:26:19<Gracenotes>return makes some sense for IO
09:26:30<WorkyBob>yeh, return makes sense as a synonym
09:26:34<Gracenotes>like sequence and forever
09:26:36<WorkyBob>in a lot of cases
09:26:49<WorkyBob>heh, but sequence is an applicative function
09:27:16<lars9>multiple notations on one function ... is sometimes confusing too
09:27:20<Gracenotes>monadic naming seems to be influenced by IO and effectful ordering in that context
09:27:21<WorkyBob>yep
09:27:32<WorkyBob>lars9: it's because monads were discovered to be useful early on
09:27:43<WorkyBob>but the more general classes higher up the tree only later
09:28:11<lars9>i dunno Applicative yet, need more reading on it.
09:28:15<WorkyBob>lars9: http://noordering.wordpress.com/2009/03/31/how-you-shouldnt-use-monad/ <-- try this as another take on monads^H^H^H^H^H^H the tree that builds up to monads
09:29:00<lars9>:t forM
09:29:01<lambdabot>forall a (m :: * -> *) b. (Monad m) => [a] -> (a -> m b) -> m [b]
09:29:49<lars9>:t zipWithM_
09:29:51<lambdabot>forall a b (m :: * -> *) c. (Monad m) => (a -> b -> m c) -> [a] -> [b] -> m ()
09:30:09<lars9>:t mapM
09:30:10<lambdabot>forall a (m :: * -> *) b. (Monad m) => (a -> m b) -> [a] -> m [b]
09:30:16<WorkyBob>all 3 of those should be in applicative
09:30:17<WorkyBob>not monad
09:30:45<lars9>is forM x y = mapM y x?
09:30:49<WorkyBob>yes
09:30:56<Axman6>@src forM
09:30:57<lambdabot>forM = flip mapM
09:31:01<Axman6>@src flip
09:31:01<lambdabot>flip f x y = f y x
09:31:12<WorkyBob>some people like to write in the style of for x in [1,3,5,6,7] do this stuff
09:31:14<Gracenotes>totally yessssssss dude
09:31:15<Axman6>> flip f x y
09:31:16<lambdabot> Add a type signature
09:31:20<Axman6>> flip f x y :: Expr
09:31:22<lambdabot> f y x
09:32:05<Gracenotes>> forM [1,2,3] (replicate 2)
09:32:07<lambdabot> [[1,2,3],[1,2,3],[1,2,3],[1,2,3],[1,2,3],[1,2,3],[1,2,3],[1,2,3]]
09:32:20<lars9>i do prefer python's 'there is only one way for one thing' way... more friendly to newbies
09:32:23<lars9>:D
09:32:34<quicksilver>but it's not actually true.
09:32:38<Axman6>but there isn't only one way to do things
09:32:46<quicksilver>all languages have multiple ways to do things
09:33:04<Gracenotes>lars9: that's the Python commuity's way of forcing idiomatic behavior in a hodge-podge language :P
09:33:13<dancor_>well, there is more consensus in python
09:33:19<dancor_>ya
09:33:25<Gracenotes>the "pythonic" epithet ;)
09:34:06<WorkyBob>I'm not sure there is more consensus in python
09:34:09<ski>@type replicateM
09:34:11<lambdabot>forall (m :: * -> *) a. (Monad m) => Int -> m a -> m [a]
09:34:23<WorkyBob>there's more consensus about how to write things that don't tend to trip over runtime type checking
09:34:28<WorkyBob>but that's not a problem we hit
09:34:40<lars9>if i have a function a -> b, but i want a -> m b, i should just use pure f?
09:34:44<dancor_>i do prefer qualified imports
09:34:47<WorkyBob>lars9: no
09:34:48<eivuokko>The scope is usually different. The python "one-way" usually refers to expression/statement level, and there are very strong idioms at that level. Haskell has only few idioms at that level. (Function composition in few forms, really.)
09:34:53<WorkyBob>pure f would give you m (a -> b)
09:35:02<ski>lars9 : `pure . f'
09:35:08<WorkyBob>or fmap pure f
09:35:17<WorkyBob>or pure <$> f
09:35:18<Gracenotes>useless use of fmap! >_>
09:35:21<lars9>:t (pure . length)
09:35:22<lambdabot>forall (f :: * -> *) a. (Applicative f) => [a] -> f Int
09:35:26<WorkyBob>Gracenotes: so true
09:35:30<Gracenotes>:P
09:35:45<lars9>:t pure <$> length
09:35:46<lambdabot>forall (f :: * -> *) a. (Applicative f) => [a] -> f Int
09:35:52<lars9>:t pure $ length
09:35:53<lambdabot>forall (f :: * -> *) a. (Applicative f) => f ([a] -> Int)
09:36:00<WorkyBob>:t return `liftM` length
09:36:01<lambdabot>forall (m :: * -> *) a. (Monad m) => [a] -> m Int
09:36:55<lars9>:t (.)
09:36:56<lambdabot>forall b c a. (b -> c) -> (a -> b) -> a -> c
09:37:05<Axman6>> pure <$> length [1..10] :: Maybe Int
09:37:06<lambdabot> Couldn't match expected type `GHC.Types.Int'
09:37:08<lars9>:t ($)
09:37:08<lambdabot>forall a b. (a -> b) -> a -> b
09:37:21<ski>@type mapAndUnzipM
09:37:22<lambdabot>forall a (m :: * -> *) b c. (Monad m) => (a -> m (b, c)) -> [a] -> m ([b], [c])
09:37:40<quicksilver>I hate the way that error message exposes something implementation dependent where the type was defined.
09:37:48<copumpkin>that's a pretty intense function
09:37:56<Gracenotes>> (pure <$> length) [1..10] :: Maybe Int
09:37:57<lambdabot> Just 10
09:38:22<ski>(quicksilver : .. seconded)
09:38:33<Axman6>oh right, bount the list to length
09:39:24<quicksilver>ski: the standard should mandate certain things about error messages. E.g. "In error messages built in types like Int may be referred to as Prelude.Int or Int, but by no other names"
09:39:29<Gracenotes>speaking about useless uses of cat, echo "hello" | cat | cat | cat | cat | cat | cat | cat | cat | cat | cat | cat | cat | cat | cat | cat | cat | cat | cat | cat | cat
09:39:56<Gracenotes>ACTION wonders how long that can go on
09:41:44<copumpkin>until you run out of FDs?
09:42:08<lars9>what kind of projects do you use haskell on?
09:42:13<dancor_>or bash 65k char limit?
09:42:21<copumpkin>lars9: I do porn administration
09:42:56<dancor_>does that make use of Set
09:42:59<Gracenotes>I ray trace .. images of pumpkin doing porn administration.
09:43:05<shapr>copumpkin: wtf?
09:43:10<copumpkin>ACTION whistles
09:43:28<dancor_>i'm just glad that copumpkin is being safe
09:43:34<shapr>Gee, I've used Haskell to index and sort mailing lists, hack on irc bots, get paid hack on webservers, and lots more.
09:43:34<copumpkin>:)
09:43:44<ski>echo "hello" | fix (cat |)
09:43:49<Gracenotes>really though, I've made hash rainbow tables, a ray tracer, working on IRC bot, regexen...
09:43:50<shapr>porn may be free of side-effects, but it's also very lonely.
09:43:57<ivanm>shapr: you use haskell to hack on webservers?
09:44:03<ivanm>so you write haskell code that writes code?
09:44:03<ivanm>;-)
09:44:07<shapr>ivanm: Well, I got paid to work on HAppS for a year.
09:44:17<ivanm>it's just the way you said it ;-)
09:44:28<shapr>ivanm: And yes, pesco and I had a QuickCheckM instance that fuzzed http at one point years ago.
09:44:35<ivanm>heh
09:44:37<shapr>But John Hughes beat us to the punch with quviq, so we gave it up.
09:44:46<ivanm>quviq? never heard of it
09:44:51<ivanm>and what do you mean by "fuzzed"?
09:44:59<shapr>@go protocol fuzzing
09:45:00<lambdabot>http://en.wikipedia.org/wiki/Fuzz_testing
09:45:19<ivanm>ahhhhh
09:45:27<lars9>:t zipWithM_
09:45:28<Gracenotes>garbage in, garbage out, huh
09:45:28<lambdabot>forall a b (m :: * -> *) c. (Monad m) => (a -> b -> m c) -> [a] -> [b] -> m ()
09:45:40<shapr>I wonder if I still have the code for that lying around, that would be fun to resurrect.
09:45:57<lars9>:t zipWithM
09:45:58<lambdabot>forall a b (m :: * -> *) c. (Monad m) => (a -> b -> m c) -> [a] -> [b] -> m [c]
09:46:06<quicksilver>a random thread interleave tester would be a very good tool for GHC.Conc testing.
09:46:44<lars9>i can understand m [c], it's a monad containing a list of c, but what is m ()?
09:46:48<lars9>:t ()
09:46:49<lambdabot>()
09:47:02<lars9>:t m ()
09:47:03<lambdabot> Couldn't match expected type `() -> t' against inferred type `Expr'
09:47:03<lambdabot> In the expression: m ()
09:47:13<Gracenotes>lars9: "m ()" is used when the result of the monad computation doesn't matter as much as the effects from it
09:47:16<Gracenotes>generally
09:47:27<Gracenotes>for example, print is IO ()
09:47:29<shapr>How else could you do a void return in Haskell?
09:47:47<ski>lars9 : s/it's a monad containing/it's a monadic action returning/
09:47:56<eivuokko>lars9, () is called unit type, you can think of it as data () = () (not valid syntax). It usually means "don't care" when you need concrete type (not type variable)
09:48:06<shapr>hei eivuokko! long time no see.
09:49:12<eivuokko>shapr, Hello. Yes, been away. How are you?
09:49:44<shapr>Busy writing C#, how's life with you?
09:49:47<Gracenotes>boolean is True | False... it's binary. Unit is unary: not two values, but one...
09:50:01<copumpkin>or two
09:50:12<copumpkin>or a hunded
09:50:15<Gracenotes>no bottoms for you
09:50:18<eivuokko>shapr, tried F# ? :) I've been playing it with lately. Although it's kinda horrible...wtb haskell for .net ;)
09:50:23<copumpkin>*hundred even
09:50:49<Axman6>Gracenotes: :(
09:50:59<copumpkin>Gracenotes: do you like bottom?
09:51:23<Gracenotes>well. you can catch most of them in the IO monad
09:51:42<lars9>:t _|_
09:51:43<lambdabot>parse error on input `|'
09:51:55<lars9>m(_ _)m
09:52:13<hatds>?instances MonadIO
09:52:14<lambdabot>ContT r m, ErrorT e m, IO, RWST r w s m, ReaderT r m, StateT s m, WriterT w m
09:52:22<Axman6>it always annoyed me that _|_ isn;t actually haskell
09:52:23<Gracenotes>> let ~ (_,_) = undefined in 0.0
09:52:25<lambdabot> 0.0
09:52:35<shapr>eivuokko: I haven't tried F#, everytime I get the urge to do something fun with .NET I have SharePoint flashbacks and buy more hardware instead.
09:52:49<Axman6>haha
09:52:54<Gracenotes>actually, ~ is implicit but anyways
09:53:14<Axman6>@quote shapr I haven't tried F#, everytime I get the urge to do something fun with .NET I have SharePoint flashbacks and buy more hardware instead.
09:53:15<lambdabot>No quotes match.
09:53:22<Axman6>@remember shapr I haven't tried F#, everytime I get the urge to do something fun with .NET I have SharePoint flashbacks and buy more hardware instead.
09:53:23<lambdabot>Okay.
09:53:25<Axman6>even
09:53:38<shapr>At this point I have enough hardware that I could actually run a usable SharePoint server. Specifically, I have an eight core Xeon with 16gb of ram.
09:53:46<eivuokko>shapr, Heh. -.-'
09:53:50<lars9>i wonder what haskell looks like in the eyes of someone who learn haskell as his/her 1st programming language.
09:54:14<shapr>lars9: I find it more interesting to hear about what C looks like to someone who learns Haskell as his/her first language.
09:54:21<Axman6>lars9: hopefully pretty nice
09:54:37<Axman6>shapr: i could go find some and ask them
09:54:43<shapr>lars9: I heard that there were a few student at Chalmers who had exactly that experience.
09:54:48<lars9>maybe as easy as we see C
09:55:16<shapr>I think it was either Anders or Björn who said that they had lots of trouble understanding C until someone told them that every function was in IO.
09:55:30<eivuokko>lars9, With somewhat right background, haskell's pretty intuitive.
09:56:41<quicksilver>shapr: that sounds a little too like what someone would say they thought because they knew other people wanted to hear it :)
09:56:44<Axman6>ACTION likes writing referencially transparent C functions
09:56:46<quicksilver>shapr: if it's true, though :)
09:57:10<shapr>quicksilver: I don't know, I haven't spoken to anyone myself who had learned Haskell first.
09:57:13<Gracenotes>Axman6: but how do you prove it??????? *wags eyebrows*
09:57:21<Axman6>hmm, i thought i'd just written one, but it may not be, considering it will be have differently on differing hardware
09:57:22<mux>ACTION likes to use __attribute__((pure))
09:57:24<lars9>i guess so, but i have no chance to experience that anymore. I'm already used to break down a problem into C code pieces. and found it's hard to think in the haskell's pure functional way.
09:57:42<Axman6>mux: is that a real thing?
09:57:49<mux>Axman6: GCC extension
09:57:50<eivuokko>It's a gcc thing.
09:57:58<quicksilver>mux: I like __attribute__((can_you_believe_how_ugly_this_syntax_is))
09:57:59<Axman6>good enough for me. what's it do?
09:58:03<mux>quicksilver: :-)
09:58:04<Gracenotes>Axman6: well. I'd like to think of referential transparency within a runtime. not from runtime instance to runtime instance.
09:58:09<mux>Axman6: tells the compiler your function is pure
09:58:12<quicksilver>Axman6: gives the optimiser a hint.
09:58:22<Axman6>and how do you use it?
09:58:24<mux>except that there are pure and pure2 attributes with subtle differences but you get the idea
09:58:32<Axman6>ACTION wants to show off to his lecturer is his current comp course
09:58:32<quicksilver>Axman6: it can for example CSE expressions using that function
09:58:40<quicksilver>Axman6: just like it can (already) CSE + and *
09:58:46<quicksilver>because it already knows + and * are pure.
09:58:47<Axman6>bah, i do CSE myself :P
09:59:06<mux>Axman6: you add that __attribute__((pure)) stuff at the end of your function prototype
09:59:07<ski>(Gracenotes : how about code mobility ? image save & restore ?)
09:59:15<Axman6>ok, thanks :)
09:59:27<quicksilver>as the optimiser gets better, opportunities for CSE may appear which aren't immediately obvious on inspection of the input source
09:59:30<mux>oh, it seems pure2 is now named 'const'
09:59:30<Gracenotes>ski: well. Then I guess it's part of the same runtime, in the context of that code.
09:59:48<mux>what a bad naming
10:00:35<Gracenotes>hmmm
10:00:43<mornfall>quicksilver: I think it's that ugly so there's no risk of conflict with any sensible future standard. ;)
10:01:01<mux>the 'const' attribute should be named 'pure', but I don't know how 'pure' should be named then
10:02:30<Axman6>quicksilver: the thing we're doing at the moment involves speeding up a fucntion by checking for powers of 2 and replacing multiplies and modulus' with <<, >> and &
10:02:53<Axman6>my version runs about 80% faster than the original :)
10:03:26<Axman6>j = j/k + (j%(k))*(n/k); --> j = (j >> powk) + ((j & mask) << nkpow);
10:03:26<lars9>im learning xmobar's source code. could anybody help me on some problems? http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5372#a5372
10:03:55<mux>yay, STM code
10:03:57<Neut>http://moonpatio.com/fastcgi/hpaste.fcgi/view?id=2519#a2519
10:04:06<Neut>what is wrong with my list comprehension in that code?
10:04:10<Axman6>g'day Neut
10:04:11<mux>lars9: what are the problems?
10:04:21<Neut>I get a non-exhaustive pattern error :/
10:04:24<Neut>hey Axman
10:04:31<Axman6>Neut: were you in the 1100 lecture today?
10:04:35<Neut>good to see you
10:04:37<Neut>sure was,
10:04:41<Neut>were you?
10:04:42<lars9>here is the code http://tinyurl.com/npu66q
10:04:51<shapr>I wasn't!
10:05:00<Axman6>yep :)
10:05:04<mux>Neut: your healthPeople function takes a PeopleStats parameters, which is a list of triples
10:05:11<Axman6>man, clem's so awesome
10:05:16<Neut>why were you there lol?
10:05:19<mux>Neut: yet you only define healthyPeople for the case where your list contains only one element
10:05:23<Axman6>funsies :P
10:05:35<mux>Neut: foo [x] = ... means you're matching the case where you get a list with exactly one element
10:05:45<Axman6>heard there were baloons, and a friend of mine hasn't ever been to a clem lecture
10:06:32<Neut>mux: how do I modify it so that isnt the case?
10:06:47<Neut>Axman6: yeah he is good fun xD
10:07:31<mux>Neut: healthyPeople peoples = [ name | (name,height,weight) <- peoples, healthy height weight ]
10:07:38<Axman6>Neut: i think the function you want is: healthyPeople people = [(name, height, weight) | (name, height, weight) <- names, healthy height weight]
10:07:51<mux>Neut: note the == True is redundant in your list compreension
10:07:52<Axman6>uh, s/names/people
10:08:03<mux>Axman6: no, he only wants to return the names of the persons
10:08:06<Teggy>G'day all.
10:08:08<Neut>why is that mux?
10:08:11<Axman6>ah ok
10:08:32<Axman6>@check \x -> (x == True) == x
10:08:33<lambdabot> "OK, passed 500 tests."
10:08:45<mux>Neut: because the healthy function already returns boolean
10:08:47<Axman6>G'day Teggy
10:08:50<Neut>oh of course
10:08:54<Neut>thanks alot
10:09:02<mux>you're welcome
10:09:27<Neut>say Axman6, if your in the exam hall next week and wana put my ID on your paper that would be fine too
10:09:29<Neut>xD
10:09:46<mux>> 70/(1.83^2)
10:09:46<Axman6>mux: when i was taking the course Neut is now, i used to see if blah then True else False all the time
10:09:48<lambdabot> 20.902385858042937
10:09:52<mux>yay, I'm healthy.
10:10:00<mux>Axman6: heh :-)
10:10:12<Axman6>> 90/(1.9^2)
10:10:13<lambdabot> 24.930747922437675
10:10:16<Axman6>:(
10:10:20<Axman6>only just
10:10:26<mux>Axman6: nearly not healthy ;-)
10:10:33<Axman6>bmi's not a great measure though
10:10:35<Neut>*Argh*, I updated my kernal today and my computer is fail slow :(
10:10:37<mux>ACTION nods
10:10:56<Axman6>i mean, i'm a bit tubby, but not exactly fat
10:12:10<Neut>Axman6: we are pushed away from using ifs for some reason
10:12:19<Axman6>good
10:12:22<mux>because ifs are unaesthetic
10:12:28<Axman6>they're often misused
10:12:48<Axman6>they have their place, but there's often better waysx
10:12:49<mux>I always try to have pattern guards instead of ifs if possible
10:13:10<Axman6>i'll use if if the alternative is a case statement
10:13:24<Neut>epic, I have to use Kate because emacs lags too hard.. what an update *cries*
10:13:40<Axman6>tried vim?
10:13:45<Axman6>(or... a good OS?)
10:13:46<Axman6>>_>
10:13:55<Neut>what do you use?
10:14:06<WorkyBob>SubEthaEdit
10:14:09<Axman6>OS X
10:14:19<Neut>bleh not a mac fan
10:14:29<WorkyBob>what do you use?
10:14:38<Neut>ubuntu
10:14:40<Axman6>Clem's got one, so's Ben L, and all the other awesome people :P
10:14:45<WorkyBob>oh, no reason not to use a mac then
10:14:46<Neut>hahaha
10:15:02<WorkyBob>just a unix box... just happens to also run more apps
10:15:30<Axman6>Neut: the reason we like macs is that basically you get the benefits of both windows and linux, without much of the fail of either
10:15:47<WorkyBob>indeed
10:16:21<Axman6>though, i do have a wintendo partition now
10:16:35<Axman6>but the windows was free, so...
10:16:36<Axman6>>_>
10:16:47<WorkyBob>what do you need that for Axman6?
10:16:54<Neut>if I win the lottery/find a wad of cash I might just buy one ;)
10:16:58<Axman6>for wintendoing
10:17:10<WorkyBob>oh, I have a PS3 for that
10:17:20<WorkyBob>Neut: meh, the expensive thing is a lie
10:17:28<Axman6>i want a PS3, but only because of the blu-ray and Cell
10:17:51<WorkyBob>you can get them for $600 brand new
10:17:51<WorkyBob>$450 even for refurbs
10:17:54<Neut>WorkyBob: the fact it isn't free makes it expensive for me
10:18:09<Axman6>was your current computer free?
10:18:13<WorkyBob>hardware always costs money
10:18:26<Axman6>not always
10:18:32<WorkyBob>Axman6: meh, BluRay is actually about the only toy I haven't used on it
10:18:41<Axman6>i can see three computers in this room that didn't cost me a cent
10:18:47<Neut>sure wasn't, Im just saying Im not going to buy a new pc sa'll
10:18:52<WorkyBob>ah, k
10:19:00<Neut>dont have the dosh,
10:19:03<WorkyBob>:(
10:19:25<WorkyBob>ACTION wants replicators
10:19:39<Axman6>anyway, back to this assignment
10:19:47<Neut>ditto
10:19:47<WorkyBob>don't you mean binding?
10:19:50<WorkyBob>>.>
10:24:59<ivanm>@seen dibblego
10:25:00<lambdabot>dibblego is in #haskell-in-depth, #xmonad, #functionaljava, #haskell and #scala. I last heard dibblego speak 1h 23m ago.
10:25:11<ivanm>dibblego: isn't it cheating to ask proggit for help on an interview question? :p
10:26:15<^Someone^>Look for dobblego
10:26:33<ivanm>@seen dobblego
10:26:33<lambdabot>dobblego is in #functionaljava, #scala and #haskell. I last heard dobblego speak 25m 19s ago.
10:26:41<ivanm>*shrug* whichever nick he's using ;-)
10:27:01<dobblego>yo
10:27:10<ivanm>isn't it cheating to ask proggit for help on an interview question? :p
10:27:39<dobblego>I've already submitted it -- just playing now :)
10:28:20<dobblego>http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5373#a5373
10:28:43<ivanm>heh
10:28:47<quicksilver>well if you can get proggit to help with your interview, then perhaps you can get proggit to help with the job when you get it. So it's not cheating, it's just an indication of one of your skill sets.
10:28:54<ivanm>quicksilver: lol
10:29:12<ivanm>@remember quicksilver well if you can get proggit to help with your interview, then perhaps you can get proggit to help with the job when you get it. So it's not cheating, it's just an indication of one of your skill sets.
10:29:12<lambdabot>Good to know.
10:29:31<WorkyBob>dobblego: perhaps tests might be better with quickcheck and a property that you can convert a number to words and back and get an id function
10:29:33<WorkyBob>and the reverse
10:29:57<dobblego>WorkyBob, g'luck using QC for testing that function
10:30:35<dobblego>WorkyBob, I considered using QC for testing parts of it
10:30:37<WorkyBob>ACTION writes a quick parser for the word based version
10:30:40<WorkyBob>done
10:30:42<WorkyBob>etc...
10:31:23<Neut>btw im doing your exam from last year ;()
10:31:50<Axman6>i think i aced that exam
10:32:04<Axman6>though... i did finish the course with 94%, so there's a good chance :P
10:34:31<Saizan>is there a general name for the kind of testing QuickCheck does?
10:34:43<Axman6>excessive
10:34:46<Axman6>>_>
10:35:28<dobblego>automated specification-based testing
10:36:29<Saizan>looks like it, thanks
10:39:56<ivanm>dobblego: well, I'd _hope_ you'd know :p
10:40:25<ivanm>dobblego: though that guy I was telling you about that loves C# wanted to know why you listed NUnit (I think... one of them) as a "manual" test tool
10:40:40<dobblego>because it is?
10:40:47<dobblego>what guy who what?
10:41:01<ivanm>at dinner, I was saying about a guy that loves C#
10:41:15<dobblego>I've considered writing a proper test automation tool for .NET using C#
10:41:42<Axman6>ivanm: still thinking of coming to ANU?
10:41:50<ivanm>Axman6: yes
10:41:53<ivanm>but it won't be till next year
10:41:55<Axman6>:)
10:42:00<dobblego>a better question might be, "what do you think is automated about nunit?"
10:42:08<ivanm>true
10:42:22<Axman6>i gave a talk today at my uni about how awesome ANU is. (which i think is true, it's an amazing place)
10:42:58<Axman6>campus wide 802.11n wireless with WPA2, connected to a 100mbit internet connection
10:42:58<ivanm>Axman6: I thought you _went_ to ANU... >_>
10:43:15<Axman6>uh, not at my uni, my old college
10:43:28<Axman6>(years 11 and 12)
10:43:39<ivanm>ahhh
10:44:01<ivanm>Axman6: so if you have old HW that can't use WPA, then you can't use wireless at ANU?
10:44:31<Axman6>nah. there's an older network too, but it's less secure and slower
10:44:53<Axman6>and you have tpo log in through a webpage before you can do anything on the network
10:45:21<ivanm>ahhh, fair enough
10:45:24<ivanm>that's what UQ uses
10:45:43<ivanm>PITA, really, when I have to start up a browser just to let my email client work :@
10:45:58<Axman6>and it's more restrictive. ANU-Secure (the awesome one) is basically a direct net connection, so you can do what ever you want (even torrent at 100mbit)
10:46:11<Axman6>s/net/internet
11:18:57<inbuninbu>i think i've got an interesting problem for you guys...
11:19:12<inbuninbu>my problem is that i want to wait for input, process the input, and output the result
11:19:27<inbuninbu>BUT! some of the evaluation might take a long time, and some of it won't. and i want to output as soon as the result becomes available
11:19:39<inbuninbu>(there will continuously be more chunks of input coming in)
11:19:52<inbuninbu>the crux: i could just use forkIO, but i need to avoid two threads outputting at the same time.
11:20:14<inbuninbu>i could try to implement some kind of concurrent mailbox... but is there a more elegant solution that i'm overlooking?
11:20:54<fR0D>hi i am new to haskell and so i am trying to write programs in it to learn it
11:21:07<Baughn>inbuninbu: The output functions are lazy
11:21:16<fR0D>can someone tell me how to take a series of integers enetered per line
11:21:18<Baughn>inbuninbu: Or, rather, they accept lazy data structures just fine
11:21:25<fR0D>and then process them one by one
11:21:30<Baughn>fR0D: One per line?
11:21:42<fR0D>yes each line has a integer
11:21:53<Baughn>inbuninbu: So "print [1..]", for example, is not going to wait for all of [1..] to be evaluated before it starts printing
11:21:54<fR0D>and say there are n such lines
11:21:55<burp>from stdin or file?
11:22:01<fR0D>stdin
11:22:17<Baughn>fR0D: do ...; int <- fmap read getLine; ...
11:22:24<mauke>readLn
11:22:31<Baughn>..or that. I keep forgetting that one.
11:22:36<mauke>:t replicateM n readLn
11:22:37<lambdabot> Couldn't match expected type `Int' against inferred type `Expr'
11:22:37<lambdabot> In the first argument of `replicateM', namely `n'
11:22:37<lambdabot> In the expression: replicateM n readLn
11:22:40<mauke>:t replicateM ?n readLn
11:22:41<lambdabot>forall a. (?n::Int, Read a) => IO [a]
11:23:03<Baughn>inbuninbu: That is, of course, assuming that you care about the order of your output
11:23:22<inbuninbu>Baughn: yes that's it exactly. i don't care about the order of my output
11:23:29<Baughn>inbuninbu: If you just want to print stuff as soon as it's evaluated, and don't care about the order, then a mailbox would be best
11:23:57<Baughn>inbuninbu: (But take care to evaluate your data /before/ putting it in the MVar, otherwise it'll just be putting a thunk in there)
11:24:08<fR0D>ok thanks i will try that
11:24:59<inbuninbu>Baughn: i was afraid of that; i was hoping there was some beautiful trick using functors or something that i could use; i guess not
11:25:24<Baughn>inbuninbu: Nope. What you're asking for is basically nondeterminicy
11:25:32<Baughn>inbuninbu: You can't have that outside IO. :)
11:25:36<Baughn>This is a feature. :P
11:25:52<Baughn>inbuninbu: Oh, and be sure to know about the tradeoffs between MVar and Chan
11:26:20<inbuninbu>Baughn: LOL. i thought though, that the list functor sort of provided nondeterminacy in some sense
11:26:56<Baughn>inbuninbu: The list /functor/ just maps. The list applicative instance does, in a sense, but only through providing every possible option. In a deterministic order.
11:27:30<Baughn>inbuninbu: And you're specifically wanting to get the result that evaluates fastest first in your result list. This is very, very indeterminate.
11:27:40<Baughn>inbuninbu: Not referentially transparent at all. :)
11:28:06<Baughn>inbuninbu: If your result values happen to be /equal/ you can use unamb, but I don't expect they are
11:28:41<inbuninbu>Baughn: ok, i think i've got it. at least to move forward. haskell is one deep forest :-)
11:28:57<inbuninbu>Baughn: thanks!
11:31:08<Baughn>inbuninbu: Re: the functor/applicative confusion. I suggest you read the Typeclassopedia.
11:32:11<inbuninbu>Baugn: thanks. actually i started chewing on that earlier today. it helps some, but will take more work on my part to really understand it well
11:37:48<ski>@type Control.Concurrent.mergeIO
11:37:49<ski>@type Control.Concurrent.nmergeIO
11:37:50<lambdabot>forall a. [a] -> [a] -> IO [a]
11:37:51<lambdabot>forall a. [[a]] -> IO [a]
11:38:08<ski>inbuninbu : maybe those're helpful ?
11:38:47<inbuninbu>ski: i saw those, but the documentation is sparse; almost a haiku
11:38:57<inbuninbu>ski: so i'll have to play with them to really understand them, maybe
11:39:59<fR0D>i am still unable to get it, suppose i have to print the sum of all the numbers how will i do it replicateM
11:40:19<fR0D>*using rreplicateM
11:40:21<Gracenotes>:O
11:40:54<ski>compute the sum of the list monadically returned by the call to `replicateM'
11:41:14<Gracenotes>hm. What is mergeIO supposed to do?
11:41:28<Gracenotes>seems to merge two lists concurrently... why would you need it
11:42:22<Saizan>Gracenotes: parallelize the evaluation, i guess
11:43:09<ski><http://www.haskell.org/ghc/docs/latest/html/libraries/base/Control-Concurrent.html#v%3AmergeIO> "The mergeIO and nmergeIO functions fork one thread for each input list that concurrently evaluates that list; the results are merged into a single output list."
11:43:11<Gracenotes>Saizan: hmmm. *checks out source*
11:43:29<shapr>ACTION boings
11:43:46<Gracenotes>looks complicated.
11:43:57<Gracenotes>uses an MVar and a semaphore
11:45:01<Gracenotes>and involving a function called "suckIO"
11:45:53<Gracenotes>and the MVar seems to be used for an impromptu Chan
11:46:33<jacobian>I haven't really properly though this through yet, but I have a tree which is infinite and lazy, I want to have errors as a I produce the tree, is this difficult?
11:46:58<Baughn>jacobian: No, that's what throw is for
11:47:00<jacobian>And if not, what is an easy approach
11:47:34<Gracenotes>exceptions. breaking control in exceptional cases
11:47:38<ivanm>jacobian: why do you want errors?
11:47:46<ivanm>aren't errors _bad_? :o
11:47:51<Baughn>jacobian: Just realize that since it's lazy, the exceptions will show up as the tree is produced - eg. while it's being consumed
11:48:05<Baughn>Nah, error-throwing from pure code is handy - to point out programming errors
11:48:46<jacobian>So Control.Exception is the way to go
11:48:49<Baughn>jacobian: For pure code, normally you'd augment the structure with some explicit error value. Either or Maybe exist for this purpose
11:48:59<Baughn>Assuming you actually want to handle the error
11:49:10<Baughn>jacobian: Read the documentation for throw carefully
11:49:21<Gracenotes>there's also monads for this
11:49:31<eivuokko>Maybe also a writer monad, if you need "a log."
11:49:34<Gracenotes>er. what he said.
11:50:12<jacobian>I need to give up if something goes wrong, so a log isn't really what I need
11:50:29<quicksilver>Maybe is great for give up if something goes wrong
11:50:36<quicksilver>give up (but with no more information abotu why you did)
11:51:06<jacobian>Information about why would also be useful
11:51:19<jacobian>I was using a hand rolled exception monad previously
11:51:36<eivuokko>And why are you switching off it?
11:51:41<ski>what if part of the tree "goes wrong" but you aren't actually using that part (for one use) ?
11:55:29<jacobian>It should be ok for parts to go wrong that aren't encountered.
12:00:15<ivanm>^Someone^: surely you can get rid of the last two carets as well...
12:00:56<^Someone^>I think when I tried Someone, it was in use/registered, but it was sometime abck
12:00:57<^Someone^>back*
12:01:05<^Someone^>However, I like this nickname now lol
12:01:58<paper_cc>hmm, is <^Someone^> an infix lifted Someone constructor?
12:02:19<ivanm>paper_cc: can't be infix, it has alphanumeric characters in it
12:02:29<quicksilver>it is infix in that syntax though
12:02:30<ivanm>and constructors have to start with a capital letter
12:02:38<mauke>S is a capital letter
12:02:38<quicksilver>it does.
12:02:39<quicksilver>S
12:02:54<ivanm>quicksilver: it starts with <, not S though...
12:02:58<paper_cc>ivanm: Control.Applicative.Infix defines (<^) and (^>)
12:03:07<quicksilver>no, that parses as <^ Someone ^>
12:03:14<quicksilver>and as paper_cc says..
12:03:16<ivanm>ahhh
12:03:27<ivanm>ACTION didn't think of that
12:05:46<Gracenotes>but the parsing is only legal if something's on both sides of <^Someone^>
12:06:10<Gracenotes>well. It lexes properly, but there are infixity issues, etc...
12:06:10<^Someone^>Find two girls ; )
12:06:36<Gracenotes>(blah <^ Someone ^>) isn't a legal section >_>
12:06:42<Gracenotes><_<
12:07:25<ivanm>@slap ^Someone^
12:07:26<lambdabot>ACTION smashes a lamp on ^Someone^'s head
12:07:29<Gracenotes>even if blah is a girl
12:07:36<^Someone^>>.>
12:07:41<ivanm>@type (<^)
12:07:43<lambdabot>Not in scope: `<^'
12:07:50<ivanm>@hoogle (<^)
12:07:50<lambdabot>Control.Arrow (<<^) :: Arrow a => a c d -> (b -> c) -> a b d
12:07:56<ivanm>what's just <^
12:07:58<ivanm>?
12:07:59<paper_cc>ACTION gives up the idea of lifted Num instances for his Applicative
12:08:08<paper_cc>, [$ty|(<^)]
12:08:09<lunabot> luna: lexical error in string/character literal at end of input
12:08:13<Gracenotes>@hoogle InfixApplicative
12:08:13<lambdabot>No results found
12:08:18<Gracenotes>@hackage InfixApplicative
12:08:19<lambdabot>http://hackage.haskell.org/cgi-bin/hackage-scripts/package/InfixApplicative
12:08:28<Gracenotes>yeah. weird thing.
12:08:41<Gracenotes>but omg ^(+)^
12:09:01<paper_cc>ivanm: (<^) = flip fmap, (^>) = (<*>)
12:09:21<Gracenotes>it's like liftA2
12:09:26<ivanm>@type (<*>)
12:09:27<lambdabot>forall (f :: * -> *) a b. (Applicative f) => f (a -> b) -> f a -> f b
12:10:00<Gracenotes>type \f x y -> f <^ x ^> y == type liftA2
12:10:20<paper_cc>err, x <^f^> y rather?
12:10:38<Gracenotes>oh. right. it's flip fmap. yes
12:10:51<ivanm>Gracenotes: I didn't know there was a type function...
12:10:52<ivanm>;-)
12:11:03<ivanm>@hoogle type
12:11:04<lambdabot>keyword type
12:11:04<lambdabot>Language.Haskell.TH data Type
12:11:04<lambdabot>Language.Haskell.TH.Syntax data Type
12:11:08<paper_cc>, [$ty|flip fmap]
12:11:09<lunabot> luna: lexical error in string/character literal at end of input
12:11:13<paper_cc>oh
12:11:15<Gracenotes>|]
12:11:20<paper_cc>, [$ty|flip fmap|]
12:11:21<Gracenotes>ivanm: in my imaginary Haskell extension
12:11:23<lunabot> forall a b c . Functor a => a c -> (c -> b) -> a b
12:11:30<ivanm>Gracenotes: ahhh
12:11:34<Gracenotes>:P
12:16:27<cnwdup>When loading haskell code using plugins' make and load_ I get "unknown symbol `base_GHCziBase_unpackCStringzh_closure'" Does anyone know how this can be caused? I do not know what to look for.
12:19:41<quicksilver>JaffaCake: any idea?
12:19:45<quicksilver>dons: ping
12:20:00<JaffaCake>no idea
12:20:06<JaffaCake>ACTION is not plugin-compatible
12:20:17<cnwdup>Lemmih, from the logs I know you have had this issue once. Can you help?
12:21:09<paper_cc>@seen Lemmih
12:21:10<lambdabot>Lemmih is in #haskell. I last heard Lemmih speak 17h 30m 37s ago.
12:29:17<paper_cc>, typ "flip id"
12:29:20<lunabot> "forall b c. b -> (b -> c) -> c"
12:29:26<paper_cc>ivanm: ^^ =)
12:29:46<ivanm>hmmm?
12:30:02<paper_cc>the type function
12:30:21<ivanm>that's a plugin
12:30:24<ivanm>not a function AFAIK
12:30:30<paper_cc>it is.
12:30:47<paper_cc>ACTION is reading $ty quasiquoter code
12:30:51<ivanm>ahhhh
12:31:08<mauke>, typ typ
12:31:10<lunabot> luna: Couldn't match expected type `GHC.Base.String'
12:31:17<mauke>, typ "typ"
12:31:19<lunabot> "GHC.Base.String -> GHC.Base.String"
12:31:33<paper_cc>, typQ "typ"
12:31:36<lunabot> AppT (AppT ArrowT (ConT String)) (ConT String)
12:34:29<quicksilver>lots of the stuff in lunabot is not technically functions
12:34:37<quicksilver>because it's not referentially transparent, etc.
12:34:42<quicksilver>at least - not haskell functions.
12:34:49<lars9>> (*2) 2
12:34:51<lambdabot> 4
12:34:54<quicksilver>more like functions on the syntax of haskell.
12:40:14<lilac>, fix typ
12:42:07<ivanm>lilac: which function's type do you want fixed?
12:42:08<ivanm>:p
12:42:56<idnar>haha
12:43:03<jacobian>erg, the most annoying thing about layout is changing the name of things can screw up the code.
12:43:29<ivanm>ACTION agrees
12:43:44<ivanm>it wouldn't be so bad if emacs' haskell-mode could auto-indent properly
12:44:00<quicksilver>ivanm: it can.
12:44:04<fasta>jacobian: like how?
12:44:07<quicksilver>ivanm: if you get the correct indentation package.
12:44:07<nvoorhies>keep hitting tab
12:44:12<quicksilver>@where kuribas-indentation
12:44:12<lambdabot>http://kuribas.hcoop.net/haskell-indentation.el
12:44:17<quicksilver>I don't recommend you keep hitting tab
12:44:19<ivanm>quicksilver: oh?
12:44:25<quicksilver>I recommend you get the better indentation mode :P
12:44:34<ivanm>how do you integrate that into haskell-mode?
12:44:45<fasta>I use Kuribas-indentation, although I hate some features of it deeply.
12:44:57<fasta>E.g. "Illegal token <something>"
12:44:59<ivanm>fasta: oh? which features?
12:45:01<quicksilver>ivanm: I shall paste the relevant parts of my .emacs
12:45:07<jacobian>complaining is always a good idea :) otherwise I'd never have seen that!
12:45:09<ivanm>what does it call an "illegal token"?
12:45:18<ivanm>jacobian: heh
12:45:20<mmorrow>, help
12:45:22<lunabot> type of an expression: , [$ty| \x -> x |]
12:45:22<lunabot> get info for a type/class: , src ''Monad
12:45:22<lunabot> get info for a var/con: , src 'fix
12:45:54<fasta>ivanm: in short, its parser is broken. As a result you get those errors.
12:46:17<fasta>ivanm: I have a complete example, if you really want it.
12:46:25<ivanm>fasta: but its parser must be better than the default one if its indentation stuff is better?
12:46:47<quicksilver>ivanm: http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5374#a5374
12:46:59<quicksilver>its parser is better, but it is more painful when you find bugs in it
12:47:06<mmorrow>ACTION realizes that no one actually needed any help
12:47:08<quicksilver>it is pretty unrepetent when it fails.
12:47:22<ivanm>quicksilver: *nod*
12:47:25<quicksilver>to be fair, kuribas fixed both bugs I found within a day.
12:47:31<quicksilver>and I think he fixed one of fasta's bugs
12:47:43<quicksilver>I'm sure he'd be open to fixing whichever one is bothering fasta now :)
12:47:54<fasta>quicksilver: oh, he did? :) I didn't know he was developing it.
12:48:04<mmorrow>paper_cc: did you find the $ty code somewhere?
12:48:08<quicksilver>he's not developing it into new exciting directions
12:48:15<quicksilver>but he is fixing bugs as they are reported.
12:48:20<ivanm>quicksilver: just bug fixing?
12:48:25<fasta>quicksilver: that's good enough for me for now
12:48:29<quicksilver>I think stefan said it's going into the next release of haskell-mode, too.
12:48:32<ivanm>is it going to be integrated into haskell-mode anytime soon?
12:48:35<fasta>ACTION happily installs the new version
12:48:38<mmorrow>paper_cc: i need to put the rest of lunabot stuff into the repo (which currently just has the bare (rewritten) infrastructure)
12:48:57<ivanm>quicksilver: are you psychic? :o
12:49:06<ivanm>you answered my question before I asked it! :o
12:49:07<paper_cc>mmorrow: looks like you put it on hpaste about 3 months ago
12:49:13<paper_cc>mmorrow: http://moonpatio.org/fastcgi/hpaste.fcgi/view?id=1514
12:49:16<mmorrow>paper_cc: nice, totally
12:49:16<quicksilver>ivanm: no, it's just network lag that makes it seem that way to you.
12:49:21<quicksilver>ivanm: relativity is a bitch.
12:49:30<quicksilver>actually I had 2 hours to research the answr and reply to you.
12:49:31<ivanm>network lag of something _I_ said? :o
12:49:38<ivanm>heh
12:49:41<mmorrow>hpaste2search++
12:50:45<mmorrow>paper_cc: ooh, that code needs to be cleaned :)
12:51:31<paper_cc>mmorrow: that code looks evil :(
12:52:10<fasta>ivanm: you should just be less predictable. ;)
12:52:10<paper_cc>, (\[$ty|foo|] -> "bar") "baz"
12:52:12<lunabot> luna: <interactive>:1:51-70: Non-exhaustive patterns in lambda
12:52:17<mmorrow>hehe
12:52:21<paper_cc>, (\[$ty|foo|] -> "bar") "zOMG epic fail."
12:52:23<lunabot> "bar"
12:52:25<mmorrow>haha
12:52:42<ivanm>fasta: heh
12:53:03<ivanm>quicksilver: would you know how much of that is necessary?
12:53:14<quicksilver>of my paste?
12:53:18<ivanm>yeah
12:53:27<ivanm>I don't have any auto-mode-alist in my config, but it's still loaded
12:53:36<ivanm>IIRC, I use the haskell-site-file that comes with haskell-mode
12:53:39<quicksilver>then you don't need that.
12:53:49<ivanm>*nod*
12:53:50<quicksilver>I can certainly tell you what every line does :)
12:53:59<ivanm>heh
12:54:06<quicksilver>the autoloads set up certain files to be launched when certain symbols are called as functions.
12:54:20<ivanm>what's max-lisp-eval-depth for?
12:54:27<quicksilver>the -mode-hook makes sure all my haskell buffers have doc-mode, decl-scan and indentation-mode
12:54:31<quicksilver>the parser is rec-descent
12:54:39<quicksilver>I tend to write very deep haskell expressions
12:54:49<ivanm>*nod*
12:55:05<quicksilver>so the default level wasn't enough
12:55:06<McManiaC>how can i easily download the whole sourcecode of the standard lib? is there something like darcs for that?
12:55:33<fasta>quicksilver: what is the default level?
12:55:41<mmorrow>@where+ lunabot http://moonpatio.com/repos/lunabot/ {- currently just the bare bot + ghc-api-eval + eval-rlimit-sandboxed-stdin->stdout (and no docs) -}
12:55:42<lambdabot>Done.
12:55:45<fasta>quicksilver: 900 seems a bit high.
12:56:08<fasta>quicksilver: 600
12:56:14<fasta>quicksilver: never mind. And o.O
12:56:45<mmorrow>quicksilver: select! http://moonpatio.com/repos/lunabot/Dup.hs
12:56:56<mmorrow>(stolen from oleg)
12:57:06<ivanm>quicksilver: so I replace this with kuribas' indentation? (add-hook 'haskell-mode-hook 'turn-on-haskell-indent)
12:58:40<Saizan>McManiaC: each package has its own repo
12:58:43<hackagebot>Emping 0.6
12:58:55<Saizan>McManiaC: they live under darcs.haskell.org/libraries/
13:02:11<ivanm>"haskell-indent-region: Auto-reindentation of a region is not supported" :(
13:02:30<ivanm>at least it shows kuribas' mode is loaded
13:03:44<hackagebot>explicit-sharing 0.4.0.1
13:03:49<quicksilver>mmorrow: awesome.
13:04:06<quicksilver>ivanm: learn how to use indent-rigidly if you want to move regions left + right
13:04:08<McManiaC>Saizan: darcs get darcs.haskell.org/libraries/getopt/ for example?
13:04:12<quicksilver>ivanm: or the rectangle commands
13:04:21<McManiaC>darcs failed: Not a repository: darcs.haskell.org/libraries/haskell98 (darcs.haskell.org/libraries/haskell98/_darcs/inventory: openBinaryFile: does not exist (No such file or directory))
13:04:25<McManiaC>is what i get
13:04:25<quicksilver>ivanm: C-4 C-x TAB = region 4 places to the right.
13:04:30<ivanm>quicksilver: I wanted to try re-indenting my entire file ;-)
13:04:32<McManiaC>s/haskell98/whatever ^^
13:04:45<Saizan>McManiaC: with http:// in front
13:05:01<McManiaC>ah! great :)
13:05:11<paper_cc>is it possible to extend wxHaskell bindings?
13:06:07<paper_cc>ACTION wants dockable windows from contrib/fl but doesn't know how the bindings are actually generated
13:09:20<shapr>@seen pesco
13:09:20<lambdabot>I haven't seen pesco.
13:10:36<cnwdup>Is it possible to express this pattern: \dyn -> maybe (maybe (...) (doSomethingElse) (fromDynamic dyn)) (doSomething) (fromDynamic dyn) into something like handle [doSomething, doSomethingElse] msg?
13:11:09<cnwdup>Or is there another convenient way to avoid boilerplate?
13:11:48<cnwdup>doSomething, doSomethingElse :: a -> m (), although not of the same a.
13:12:09<fasta>cnwdup: sounds like you need rank-2 types.
13:12:26<paper_cc>cnwdup: you can wrap doSomething* into Dynamic too if they are monomorphic
13:12:42<paper_cc>cnwdup: (if you're sure you really need dynamics)
13:12:57<ivanm>kuribas' mode isn't perfect, it still seems to be doing the whole indentation-cycle stuff
13:13:07<cnwdup>paper_cc, for the signals (dyn), yes.
13:13:18<cnwdup>Thanks. I'll use that approach if I cannot get it working with rank-2 types.
13:14:00<lilac>you might be able to do something with an existential list type
13:14:56<nibro>what's the language flag to GHC to enable generalized list comprehensions?
13:15:17<nibro>the docs don't say, and there doesn't seem to be a suitable one in Language.Haskell.Extension in cabal
13:15:36<ivanm>nibro: you mean the pragma to use in 6.10?
13:15:36<lilac>looks like you want a list :: [exists a. Typeable a => a -> b]
13:15:40<quicksilver>ivanm: it doesn't cycle in the same way. It's always TAB for the next valid position to the right, and BACKSPACE for the next valid position to the left
13:16:04<quicksilver>ivanm: much more consistent. It's also much better at getting a concise list of valid positions.
13:16:05<dcoutts>nibro: ParallelListComp
13:16:16<ivanm>quicksilver: unless the two modes are interfering, since I haven't restarted emacs since I put that in
13:16:32<nibro>dcoutts: so ParallelListComp enables both parallel and generalized comprehensions?
13:16:35<ivanm>quicksilver: is there actually any docs for this?
13:16:53<cnwdup>lilac, that gives me a parse error on `.'.
13:16:54<dcoutts>nibro: oh, no sorry, perhaps they have not registered one. Is it in a released ghc yet?
13:17:02<quicksilver>ivanm: only what is readable in the lisp source
13:17:16<quicksilver>ivanm: you probably need to turn off the old indent mode
13:17:19<ivanm>oh, if backspace is back one indent, how do you delete the char to the left of the cursor?
13:17:36<quicksilver>it's only back one indent if the cursor is at the beignning of a line
13:17:44<quicksilver>(beginning except for the intiial indentation, that is)
13:17:44<nibro>dcoutts: not sure, I'm just reading the docs, there's no mention of a version or that it's not yet supported
13:18:02<dcoutts>nibro: you're looking at the user guide for 6.10?
13:18:14<nibro>http://www.haskell.org/ghc/docs/latest/html/users_guide/syntax-extns.html
13:18:20<nibro>I believe so
13:18:36<ivanm>quicksilver: *nod*
13:19:21<dcoutts>nibro: bah, they're being naughty
13:19:42<dcoutts>nibro: no hackage packages can use that extension therefore
13:19:58<nibro>dcoutts: I wonder if that's deliberate... :)
13:20:04<dcoutts>heh
13:20:21<ivanm>what? what can't a hackage package use?
13:20:32<nibro>generalized list comprehensions
13:20:55<ivanm>why doesn't hackage accept them?
13:20:58<nibro>I can dig around in the ghc source to see what they're doing there
13:21:04<dcoutts>nibro: please
13:21:16<nibro>ivanm: because the extension is not registered with cabal, so cabal wouldn't recognize the flag
13:22:26<cnwdup>Reading the Rank-N types wiki article: One can unpack existential types?
13:22:51<ivanm>nibro: as in a compile-time-flag?
13:23:03<ivanm>would it accept it if it's listed as a PRAGMA in the actual source file?
13:23:30<fasta>cnwdup: you cannot unpack existential types.
13:23:40<quicksilver>well, arguably that's what "case" does
13:23:44<quicksilver>it depends what you think unpacking means.
13:24:09<nibro>ivanm: as in a flag corresponding to -XParallelListComp for the parallel ones
13:24:09<cnwdup>quicksilver, then how can Iunpack a type and how I cannot?
13:24:50<nibro>ivanm: yes, a source pragma would still work, but that's assuming that there actually is a flag to use
13:25:07<quicksilver>cnwdup: case x of MkFoo y -> ....
13:25:14<nibro>ivanm: and since GHC supposedly defers to cabal for the flags, that doesn't seem like it would be the case
13:25:23<quicksilver>where MkFoo is the constructor of an existential
13:25:33<quicksilver>is one possible interpretation of the phrase "unpack an existential"
13:25:46<cnwdup>Ah, but I cannot pattern match against y, right?
13:26:28<cnwdup>Although -- as I understand the example given on the Rank-N types page -- I can. Oo
13:27:09<cnwdup>Ah, my bad. No it doesn't suggest that.
13:27:13<quicksilver>depends what you think pattern match means.
13:27:22<quicksilver>case x of MkFoo y -> *is* a pattern match.
13:27:28<dcoutts>nibro: ohhh, it's called TransformListComp
13:27:43<dcoutts>nibro: but has no documentation
13:27:55<quicksilver>case x of MkFoo (y:ys) -> would be a more complex pattern match, and still permitted.
13:28:03<quicksilver>(if it made type-sense)
13:28:19<quicksilver>what you can't do is unpack the MkFoo constructor with a let. It has to be a case.
13:29:05<cnwdup>But I cannot do case foo of MkFoo (Bar a b) -> ...; MkFoo (Baz a) -> ...?
13:29:41<nibro>dcoutts: Transform O_o
13:29:44<dcoutts>nibro: you might like to point out on the ghc users list that it's a silly name given what it's called everywhere else
13:30:00<dcoutts>nibro: adding new alias and deprecating old ones is possible
13:30:25<nibro>dcoutts: indeed, it sounds like a verb form of the "AllowOverlappingInstances" style rather than the nicer "OverlappingInstances" kind
13:30:38<dcoutts>nibro: it's also annoying that in the user guide where the extensions are described the extension name is not given.
13:30:48<nibro>dcoutts: I'll flag this on the ghc list
13:30:50<dcoutts>nibro: the state of docs for the extensions is pretty poor
13:31:23<dcoutts>nibro: perhaps we can shame someone into cross referencing them and adding haddock docs for the existing ones in Language.Haskell.Extension
13:32:54<nibro>dcoutts: maybe I should wait to post until I've gone through the whole documentation, there may be more rocks to overturn... ;-)
13:33:08<dcoutts>nibro: I expect there are
13:33:19<dcoutts>nibro: a barrage of complaint is no bad thing though :-)
13:33:20<nibro>fun times ahead then :)
13:33:37<nibro>indeed, criticism is only healthy :-)
13:34:03<quicksilver>cnwdup: you can do that, yes.
13:34:12<quicksilver>cnwdup: or, I'd be surprised if you couldn't.
13:34:58<cnwdup>quicksilver, http://moonpatio.com/fastcgi/hpaste.fcgi/view?id=2520#a2520 ghci doesn't like that.
13:35:44<RayNbow>> let weird ~(x,y) = (1,x); crazy = weird crazy in crazy
13:35:46<lambdabot> (1,1)
13:36:08<RayNbow>> let weird (x,y) = (1,x); crazy = weird crazy in crazy -- this crashes GHC 6.10.1 in Windows :p
13:36:13<nibro>ACTION thinks there should be an NPlusK flag
13:36:13<lambdabot> mueval-core: Prelude.read: no parse
13:36:13<lambdabot> mueval: ExitFailure 1
13:37:40<quicksilver>cnwdup: yes, but that's not becausey ou can't use case on them
13:37:44<astrobunny>phew. parsec is pretty cool.
13:37:48<quicksilver>cnwdup: it's because you don't know what type is inside the box.
13:37:52<cnwdup>quicksilver, ok
13:37:52<astrobunny>i never thought i would write parsers like this
13:38:28<quicksilver>cnwdup: http://moonpatio.com/fastcgi/hpaste.fcgi/view?id=2520#a2521
13:38:51<cnwdup>quicksilver, ok. Now I get what you meant.
13:38:52<cnwdup>Thanks.
13:38:54<quicksilver>cnwdup: example of how you can pattern match through an existential.
13:39:08<quicksilver>cnwdup: what you tried to do was take a different branch depending what the actual type in the box was.
13:39:13<quicksilver>cnwdup: you can't do that, because you don't know
13:39:24<quicksilver>nobody knows what the type is inside the box :)
13:39:31<quicksilver>this is the problem that Typeable solves
13:39:44<quicksilver>- giving you a reification for every type so you can dispatch on that.
13:39:51<quicksilver>it's a pretty big hammer, though.
13:47:59<nibro>hmm, unboxed tuples (# x, y #) are presumably enabled with UnboxedTuples, but the docs say the (# and #) lexemes are enabled by MagicHash
13:48:27<nibro>when would you ever want those lexemes without UnboxedTuples, and vice versa?
13:50:06<Baughn>nibro: For functions with # in the name
13:50:28<Baughn>touch#, unsafeCoerce#, etc.
13:51:15<ivanm>with # denoting unboxed?
13:51:22<Baughn>No, denoting internal
13:51:36<nibro>Baughn: sure, I'm aware of those, what I meant was that (# #) lexemes have no use if UnboxedTuples aren't on, and you can't use UnboxedTuples without the (# #) lexemes, or?
13:52:00<Baughn>nibro: The lexeme MagicHash turns on is #, not (#
13:52:35<Baughn>(# is a combination of two lexemes
13:53:02<nibro>Baughn: nope
13:53:18<nibro>Baughn: you can still use # as an operator with MagicHash on
13:53:37<nibro>Baughn: and the Lexer generator lists the lexemes as (# and #)
13:53:48<Baughn>Hm. Well, that's odd then
13:54:08<nibro>Baughn:... but now you got me to look at the source, which solved the mystery
13:54:10<fasta>Is there a zip type class?
13:54:10<nibro>:)
13:54:35<nibro>Baughn: those things *are* enabled by the UnboxedTuples extension, it's just the docs that are wrong
13:54:48<fasta>There is a type class for map, fold, filter, with some trouble, but no zips, AFAIK.
13:55:03<nibro>fasta: what would you want to parametrize the class over?
13:55:40<fasta>nibro: I can write it myself, that is not the problem. But I was thinking of e.g. zipping a Data.Sequence.
13:56:01<fasta>nibro: or zipping arrays
13:56:07<nibro>fasta: right, I see, that's not an unreasonable idea I guess
13:56:13<fasta>nibro: really, there is a lot of things one could zip.
13:56:32<nibro>fasta: I would guess Data.Sequence already has a zip-like function, no?
13:57:06<fasta>nibro: it doesn't.
13:57:37<fasta>nibro: you can easily write one, though, which is what I did now, but this was not just about Data.Sequence.
13:58:07<quicksilver>fasta: you can zip an arbitrary Traversable with an arbitrary Foldable
13:58:16<quicksilver>fasta: my code for this is on the wiki
13:58:40<quicksilver>zipWithTF :: (Traversable t,Foldable f) => (a -> b -> c) -> t a -> f b -> t c
14:00:03<quicksilver>although some unmentionable "improved" my code by replacing it with a less clear version which uses an unnecessarily generic monad while my version used a neat supply monad.
14:00:07<quicksilver>but that's wikis for you.
14:00:44<fasta>quicksilver: why don't you put it on hackage? It certainly is more useful than hnop.
14:00:59<quicksilver>seems silly to put a single function on hackage.
14:01:07<quicksilver>If anything it should just go into Traversable
14:01:17<quicksilver>http://www.haskell.org/haskellwiki/Foldable_and_Traversable
14:02:45<fasta>quicksilver: it's not silly. Putting a package that does not compile on hackage is silly.
14:03:01<nibro>infix type constructors are enabled by -XTypeOperators ?
14:03:14<quicksilver>something else being *more* silly is not a good enough reason ;)
14:05:20<nibro>apparently they are on by default. Hrm!
14:06:30<fasta>quicksilver: it's just less work to do cabal install $function than to do copy paste. Also, think of the network effects. When someone just browses Hackage they might think, oh, that's nice and install it. As a result more code becomes more general.
14:07:09<Baughn>Well, except in practice Hackage is becoming too big to just browse. :)
14:07:17<dcoutts>search!
14:07:22<quicksilver>yes, but I think those advantages are also observed if I get the functions added to Data.Traversable itsel.
14:07:24<dcoutts>hoogle/hayoo
14:07:38<_SamB_>maybe it's just too disorganized
14:07:56<dcoutts>ACTION agrees with quicksilver
14:08:14<nibro>dcoutts: is there a reason why infix type constructors are allowed without naming a specific extension?
14:08:15<fasta>quicksilver: yes, that would even be better.
14:08:41<fasta>And there are too many (useless) packages on Hackage too.
14:08:41<nibro>dcoutts: I'm letting you answer to all the sins of the GHC team here ;)
14:08:54<ivanm>quicksilver: why do you use (lambda nil haskell-indentation-mode)?
14:09:12<dcoutts>nibro: sorry, you'll have to ask on the ghc list or ask JaffaCake in #ghc
14:09:32<nibro>dcoutts: alright, I'll do that
14:10:55<quicksilver>ivanm: because there isn't (or wasn't) a turn-on-haskell-indentation-mode I could use.
14:10:57<jav>Hi there! cabal question: My application includes a shell script that I would like to have installed in some way alongside the main program. How do I go about this? Is this some sort of special 'executable' or a 'data file' or something?
14:11:18<ivanm>quicksilver: you can't just use it directly? seems to be working here... >_>
14:11:29<quicksilver>then i dunno ;)
14:11:47<ivanm>heh
14:11:49<ivanm>also, why do you make (quote (...)) explicit rather than just '(..) ?
14:11:58<dev31212>hi all
14:12:08<ivanm>quicksilver: ahhh, looks like there is now
14:12:12<ivanm>turn-on-haskell-indentation
14:12:17<dev31212>is there any standard, sort of scientigfic process for identifying redundant cases in functions
14:12:20<dev31212>and reducing them out?
14:13:08<dev31212>Like one might perform in binary algebra, etc..
14:13:43<doserj>ACTION remembers why he doesn't use haskell-indentation-mode. It somehow kills delete-selection-mode...
14:14:42<Baughn>Ugh, delete-selection mode..
14:15:04<Baughn>I need to mark regions for so many /other/ reasons than copying them, that would make me lose my mind. :/
14:15:20<ivanm>quicksilver: I take it back... the documentation says it's there, but it isn't :s
14:15:37<dev31212>Is there any such proecess, or must I rely on intuition and experience?
14:15:39<dev31212>Which is fine
14:15:41<ivanm>doserj: oh? what's delete-selection-mode? selecting something and pressing delete/backspace to delete it?
14:15:47<dev31212>Just thought there might be some method to this
14:15:48<Baughn>dev31212: In the absence of guards, it should be possible to automate it. With guards..
14:16:01<dev31212>hmmm
14:16:03<Baughn>dev31212: Well, -Wall does some of it (without guards)
14:16:03<doserj>ivanm: yes
14:16:23<dev31212>Baugn, I see, thanks
14:16:38<Baughn>I think it assumes guards are always true, though
14:16:55<dev31212>ok
14:17:57<fasta>quicksilver: The generic filter definition seems to be wrong: filter (>(23::Int)) [1..50] :: (Control.Applicative.Applicative f,
14:17:57<fasta> Monoid (f Int)) =>
14:17:57<fasta> f Int
14:18:21<fasta>quicksilver: or is it so general that it also overloads on the return container?
14:19:13<fasta>Oh, yes, it appears it does that. It's not something I like :)
14:22:30<quicksilver>yes that was more by way of example
14:22:51<quicksilver>it wasn't clear what would be useful.
14:25:25<fasta>quicksilver: a filter which returns the same type as it got would make sense to me. No unresolved overloading errors etc.
14:27:17<dev31212>If I post a small code segment, Baugn, would you mind just taking a quick look to see if it can be reduced?
14:27:20<dev31212>Its just 15 lines
14:27:24<Zao>dev31212: hpaste it.
14:27:30<dev31212>The code works, I just dont want to enforce bad habits
14:27:31<dev31212>ok Zao
14:28:46<dev31212>http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5375#a5375
14:28:51<dev31212>Ok I posted the whole thing actually
14:29:02<dev31212>The function I am seeing if it is reducible is the my_remove function
14:29:07<dev31212>which removes an elemt from the list.
14:29:44<quicksilver>fasta: well if you constrain its type signature, it does?
14:29:57<quicksilver>@type foldMap
14:29:58<lambdabot>Not in scope: `foldMap'
14:30:08<fasta>quicksilver: yes, that's what I did a few minutes ago.
14:30:21<Apocalisp>@type Foldable.foldMap
14:30:22<quicksilver>my code has the type sig constrained too :)
14:30:22<lambdabot>Couldn't find qualified module.
14:30:28<Apocalisp>@type data.Foldable.foldMap
14:30:29<lambdabot>parse error on input `data'
14:30:49<fasta>quicksilver: there was no Applicative instance for Data.Sequence, so, I just wrote one. Although, I haven't checked the laws.
14:30:54<Apocalisp>@type Data.Foldable.foldMap
14:30:56<lambdabot>forall a m (t :: * -> *). (Data.Foldable.Foldable t, Monoid m) => (a -> m) -> t a -> m
14:31:00<Apocalisp>\o/
14:31:08<doserj>dev31212: typically you don't have to pattern match on the case for a single element list.
14:31:19<Berengal>Is there a way to hide a package in just one module?
14:32:04<doserj>dev31212: my_concat just seems wrong.
14:32:30<Saizan>Berengal: tried {-# OPTIONS_GHC -hide-package foo #-} ?
14:33:29<dev31212>doserj, yeah Im looking at my_remove at the moment though
14:33:40<dev31212>doserj, ok
14:33:53<dev31212>yeah I wwas thinking single ement matching might noit be needed
14:34:29<Berengal>Saizan: That tells me "unknown flag"
14:34:52<dev31212>ok, let me see if I can remove the single element case
14:35:58<doserj>dev31212: you expect my_remove to be called with counter = 0?
14:36:32<dev31212>yes doserj
14:36:42<dev31212>I could add another wrapper to do that by default
14:36:55<dev31212>the function is my_remove;
14:36:58<lilac>fasta: if you used the normal Applicative instance for Monads, it will obey the laws
14:36:59<dev31212>my_remove'
14:37:10<dev31212>I was going to add simply My_remove which calls it with 0 for the counter
14:37:22<cnwdup>> (+1, 'h':) &&& (42, "ello")
14:37:23<lambdabot> A section must be enclosed in parentheses thus: (+ 1)A section must be encl...
14:37:35<cnwdup>> ((+1), ('h':)) &&& (42, "ello")
14:37:36<lambdabot> No instance for (Control.Arrow.Arrow (,))
14:37:36<lambdabot> arising from a use of `Control...
14:37:44<doserj>dev31212: well, instead of incrementing counter and testing index==counter, you can also decrement index, and test index==0
14:37:48<cnwdup>Mh, what was the function to change both values of a tupel?
14:37:51<fasta>lilac: What do you mean? I haven't really used Applicatives.
14:37:57<dev31212>soderj, ahh!
14:38:03<dev31212>thanks, thats much better
14:38:36<lilac>fasta: instance Monad m => Applicative m where pure = return; (<*>) = ap
14:38:50<fasta>lilac: but Sequence is not a monad.
14:39:05<fasta>lilac: never mind
14:39:08<fasta>lilac: it is.
14:40:07<doserj>dev31212: of course, then you can directly pattern match agains 0, instead of having a guard
14:40:11<lilac>fasta: remember that a Seq is semantically just a stricter form of []
14:41:14<fasta>lilac: What exactly does an Applicative do? Pure is obvious, but <*>?
14:41:22<quicksilver>fasta: ap
14:41:23<quicksilver>:t ap
14:41:24<lambdabot>forall (m :: * -> *) a b. (Monad m) => m (a -> b) -> m a -> m b
14:41:25<fasta>lilac: I thought it was just like fmap
14:41:36<dev31212>doserj, right
14:41:41<dev31212>sounds much better
14:41:41<fasta>:t fmap
14:41:42<lambdabot>forall a b (f :: * -> *). (Functor f) => (a -> b) -> f a -> f b
14:41:49<dev31212>thats exactly the jkind of info I needed
14:41:51<dev31212>best practices
14:41:53<dev31212>thanks
14:42:06<quicksilver>fasta: instead of defining applicative with pure + <*>, you can define it with pure + sequence
14:42:10<doserj>fasta: (<*>) = ap = liftM2 ($)
14:42:15<quicksilver>fasta: maybe that's a better intuition.
14:42:32<quicksilver>fasta: ... it says you can run lots of actions, one after another, but none of them depends on the results of the earlier ones
14:42:41<quicksilver>(i.e. you accumulate all the results in a list)
14:42:41<fasta>quicksilver: but if they are the same, why don't we just have deriving Applicative?
14:42:50<fasta>Or just dump Applicative?
14:42:58<quicksilver>it's not the same as monad
14:43:01<Berengal>Saizan: I got it working with {-# OPTIONS_GHC -ignore-package=foo #-}
14:43:03<quicksilver>sequence isn't engouhg to define monad
14:43:09<quicksilver>you can't derive >>= from sequence
14:43:12<quicksilver>which is rather the point, here.
14:43:29<quicksilver>monads can use the result of earlier effects in later effects
14:43:33<quicksilver>applicatives can't.
14:43:39<quicksilver>actually the paper is rather readable.
14:44:39<fasta>I never ran into any performance problems with monads, so when I read the Applicative paper, it seemed kind of pointless.
14:45:04<fasta>Actually, I had some laziness issuess, but nothing with parsers or anything like that.
14:45:04<byorgey>performance isn't the issue.
14:45:23<fasta>For _high-performance_ parsing, I would not use Haskell.
14:45:26<byorgey>or at least, not the only one.
14:45:39<byorgey>Applicative often lets you code things in a more natural (*applicative*) style.
14:45:50<Berengal>Saizan: Actually, I didn't... It doesn't complain, but it doesn't hide the package either
14:46:27<quicksilver>byorgey: not really, you can code in that style with monads too :P
14:46:36<lilac>fasta: <*> applies a function in the functor to a value in the functor to produce a result in the functor
14:46:43<quicksilver>byorgey: I think that's not really the point of applicative, although it's possible an insight Applicative makes.
14:46:52<fasta>byorgey: doserj defined one of the methods in terms of monads and the other one is equivalent to return.
14:47:03<gwern>@quote stricter
14:47:03<lambdabot>gwern says: the best way to optimize a program is to make it lazier or stricter.
14:47:06<fasta>byorgey: or what quicksilver said.
14:47:29<quicksilver>the point of applicative is that some things are applicative which aren't actually monads.
14:47:41<lilac>not many things, though...
14:47:46<quicksilver>no, not many at all :)
14:48:30<Berengal>ZipList
14:48:45<lilac>Berengal: got a second example? ;-)
14:48:47<Berengal>It's the only non-monad applicative I know of...
14:49:10<Berengal>Zip... maps?
14:49:15<lilac>hehe
14:49:21<quicksilver>ZipList is actually a monad.
14:49:35<quicksilver>just a different one to []
14:49:37<lilac>quicksilver: you sure?
14:49:45<quicksilver>if you restrict to infinite streams
14:49:48<quicksilver>then diagonal is join
14:49:56<lilac>ah right, on infinite streams it's a monad
14:50:01<lilac>but not on finite ones
14:50:08<quicksilver>well it is, if they're fixed length
14:50:15<quicksilver>e.g. streams of length 8
14:50:23<quicksilver>again, diagonal
14:50:25<lilac>that's also true, but that's a rather boring case of applicative
14:50:25<quicksilver>(I think)
14:50:32<quicksilver>ACTION shrugs
14:50:37<Berengal>Does that make arrays of a gievn size monads?
14:50:44<Berengal>given*
14:50:45<quicksilver>makes ZipList a bad example of an Applicative which isn't a monad, though.
14:50:49<lilac>any fixed structure F a built from a's is an applicative
14:51:03<quicksilver>Berengal: yes, same idea.
14:51:11<quicksilver>Berengal: given an array of arrays, take the diagonal
14:51:22<lilac>quicksilver: ZipList for finite lists is still a good example
14:51:37<lilac>(finite but not necessarily equally sized lists)
14:51:40<quicksilver>I think the applicative parsers is a good example.
14:51:51<lilac>aren't they usually monads too?
14:51:54<quicksilver>no
14:52:01<quicksilver>because that's the point
14:52:10<quicksilver>the applicative-ness lets you do first-letter optimisation
14:52:17<quicksilver>build parser tables as you go
14:52:21<lilac>i thought the point was, you could semantically make them monads, but you'd lose optimization opportunities
14:52:28<quicksilver>ACTION ponders
14:52:34<lilac>so in a sense they /are/ monads, but don't have a Monad instance
14:52:42<quicksilver>depends how you define them.
14:52:51<quicksilver>if you define them concretely with the first-letter tables visible
14:52:56<quicksilver>then there is no way to make them a monad
14:53:10<Berengal>lilac: Depends on if you want to pull their inner workings into the semantics...
14:53:11<lilac>ACTION ponders
14:53:37<quicksilver>data Parser a = ([Char],String -> (a,String))
14:53:43<jacobian>I have a routine that as it searches also carries out some side computation as a result which is quite expensive and I want to keep.
14:53:48<quicksilver>or something.
14:53:48<jacobian>I want something like 'find' with type (a -> Maybe b) -> [a] -> Maybe b
14:54:00<jacobian>Does such a thing already exist?
14:54:01<quicksilver>the error applicative which collects multiple errors is another good one
14:54:06<quicksilver>(Which is not a monad)
14:54:29<lilac>quicksilver: data Parser a = Data.Map Char (Either (Maybe a) (Parser a))?
14:54:54<quicksilver>jacobian: head . catMaybes . map f
14:55:03<quicksilver>lilac: that kind of thing, yes. more than one way to do it.
14:55:19<quicksilver>jacobian: well, need a safe version of head.
14:55:19<centrinia>Is catMaybes similar to mappend?
14:55:20<jacobian>cool
14:55:26<quicksilver>msum . map f
14:55:30<quicksilver>that's better
14:55:39<quicksilver>> msum [Just 3, Just 4, Nothing, Just 5]
14:55:40<lambdabot> Just 3
14:55:41<doserj>Compose f g in general, for applicatives f and g
14:55:48<quicksilver>> msum [Nothing, Just 3, Just 4, Nothing, Just 5]
14:55:49<lambdabot> Just 3
14:55:59<quicksilver>msum is "first success" for a list of maybes.
14:56:02<jacobian>perfuct
14:56:05<centrinia>msum [Nothing]
14:56:08<centrinia>> msum [Nothing]
14:56:09<lambdabot> Nothing
14:56:22<quicksilver>doserj: sure, but that's only useful if you have a stock of other interesting applicatives to compose.
14:56:43<doserj>quicksilver: you have, any monad for example :)
14:57:15<quicksilver>well yes, but in many cases that does in fact lead to a monad again
14:57:19<centrinia>Is there a function ( \x -> case x of { Nothing -> []; Just x' -> [x'] } ) in the Prelude?
14:57:25<quicksilver>but agreed there are cases where it doesn't.
14:57:30<lilac>@type fmap (fmap msum) fmap :: (a -> Maybe b) -> [a] -> Maybe b
14:57:31<quicksilver>centrinia: maybeToList
14:57:31<lambdabot>forall a b. (a -> Maybe b) -> [a] -> Maybe b
14:57:34<quicksilver>@hoogle maybeToList
14:57:35<lambdabot>Data.Maybe maybeToList :: Maybe a -> [a]
14:57:53<lilac>@type (msum <$>) <$> fmap :: (a -> Maybe b) -> [a] -> Maybe b
14:57:54<lambdabot>forall a b. (a -> Maybe b) -> [a] -> Maybe b
14:58:00<lilac>@type (msum <$>) <$> (<$>) :: (a -> Maybe b) -> [a] -> Maybe b
14:58:01<lambdabot>forall a b. (a -> Maybe b) -> [a] -> Maybe b
14:58:03<lilac>yeah
14:58:17<centrinia>Okay, catMaybes = concatMap maybeToList ?
14:58:24<lilac>@src catMaybes
14:58:25<lambdabot>catMaybes ls = [x | Just x <- ls]
14:58:28<fasta>quicksilver: the module "illegal token" error in the haskell indent mode has not been corrected, btw.
14:58:34<idnar>@type concatMap maybeToList
14:58:36<lambdabot>forall b. [Maybe b] -> [b]
14:58:54<lilac>@check \x -> catMaybes x == concatMap maybeToList x
14:58:55<lambdabot> "OK, passed 500 tests."
14:59:04<centrinia>@type catMaybes
14:59:05<lambdabot>forall a. [Maybe a] -> [a]
14:59:16<centrinia>Their types are different. :(
14:59:19<quicksilver>fasta: send an email to kuribas. Or me :)
14:59:49<lilac>centrinia: hehe :)
14:59:58<dev31212>hi centrenia
15:00:02<dev31212>do any great good?
15:00:12<centrinia>dev31212, not yet.
15:00:20<doserj>quicksilver: I have a 2-line patch to make it work together with delete-selection-mode :)
15:01:05<lilac>dev31212: FOR GREAT JUSTICE!
15:01:12<centrinia>> bmi' 85 (5*12+7) -- I wonder if anyone cleared lambdabot's defined functions buffer.
15:01:14<lambdabot> Not in scope: `bmi''
15:01:19<quicksilver>doserj: email that to kuribas too then :)
15:01:49<fasta>quicksilver: Are you this one btw? http://www.linkedin.com/pub/jules-bean/1/5b5/29a
15:03:28<gwern>@fact XMC
15:03:28<lambdabot>I know nothing about xmc
15:06:50<lilac>gwern: XMC! = XMC * (XMC - 1) * ... * 1
15:07:07<gwern>lilac: lol?
15:07:28<gwern>anyways, I'm starting to suspect that the reason there's no happstack entry in the HCAR is because happs has never been in HCAR...
15:09:11<gwern>no wait. here's one, from 2007
15:11:29<gwern>...and only in 2007
15:11:39<gwern>although it's interesting to look at the very first HCAR http://www.haskell.org/communities/11-2001/html/report.html
15:11:47<gwern>haskell has come a very long way in just 8 yearsz
15:12:55<gwern>for exmaple, where did all those dialects go?
15:16:17<hackagebot>hashed-storage 0.3
15:18:56<fasta>gwern: a PhD lasts 4 years. 8 - 4 > 0 :)
15:19:47<Beelsebob>depends on the PhD
15:19:54<Beelsebob>some last 3 years, some never get finished
15:19:58<pejo>gwern, Concurrent Haskell is in GHC, isn't it? Phil Trinder has lots of research around GpH or similar projects. Björn Lisper's group is doing WCET analysis nowdays, O'Haskell is abandoned in favour of Timber, not sure about pH, Rita Loogen seems to still work on Eden, Generic Haskell.. is that one alive still?
15:21:55<gwern>fasta: yes, I suppose the cynical explanation is best
15:22:27<gwern>too bad, because I would've liked mobile haskell functionality - why *can't* we serialize computations and incidentally send parts of our programs over the network?
15:22:28<quicksilver>well for what ever reasons the ones that died didn't attract enough blood to stay alive
15:22:39<quicksilver>I was just about to say :)
15:22:43<quicksilver>GdH is probably the most surprising
15:22:46<quicksilver>of the casualties
15:22:47<lars9>hi, i'm using archlinux, which uses pacman as package manager. if i use cabal to install some package. will pacman conficts with cabal when installing the same package? such as haskell-x11
15:22:58<quicksilver>I would have thought distribution was a pretty intersting topi.
15:22:59<Peaker>gwern: People have done this for Python, btw
15:23:13<quicksilver>people have done it for almost every language ever written
15:23:14<gwern>Peaker: well, being interpreted, I understand makes it easier
15:23:21<Peaker>gwern: Send lambdas over a network of powerful computers to compute and send back results
15:23:52<quicksilver>ACTION sends Peaker a lambda with a hacksaw hidden inside so he can escape from his computation factory.
15:23:58<SamB>Peaker: think I've heard about something like that in connection with Yhc ...
15:24:21<gwern>quicksilver: and it's hard to blame new blood for not showing up; it'd probably take me at least a year fulltime to get up to speed and start merging mobile haskell stuff into mainline ghc, and who's going to support me?
15:24:35<Peaker>Python makes it easier, having a serialized lambda form (bytecode) (except you're not allowed to use globals/etc in such a lambda, just the args)
15:24:37<SamB>does malcolmw know what I'm talking about ?
15:24:49<SamB>'cause I sure don't
15:25:06<malcolmw>SamB: so what are you talking about?
15:25:23<quicksilver>mobile code for yhc
15:25:25<SamB>malcolmw: serializing lambdas over the network
15:25:28<quicksilver>is what he's trying to talk about.
15:25:39<gwern>SamB: yhc is like fusion - the compiler backend of the future
15:25:54<quicksilver>gwern: yeah, but how did it degrade this far? I'd have expected steady interest.
15:26:00<SamB>doesn't exist yet, you mean?
15:26:05<lilac>"the monomorphism restriction, when rendered in a system of inference rules, compromises the principal type property"
15:26:05<quicksilver>gwern: of course, in reality 0.1% of the community does 80% of the work,
15:26:11<malcolmw>Yes, Yhc can transmit its bytecodes over a network to be executed on another VM, with results being transmitted back.
15:26:23<gwern>SamB: it's the backend of the future, and always will be, is the joke I was going to
15:26:35<quicksilver>lilac: yes, and that's not all it breaks.
15:26:43<quicksilver>lilac: it breaks (one form of) eta expansion too.
15:26:57<SamB>not to mention my code
15:27:01<gwern>quicksilver: well, if there's a massive learning hump, and it's not obvious in advance it's going to die, then no new blood will show up in time
15:27:23<quicksilver>malcolmw: I didn't know that.
15:27:28<fasta>It has been done a number of times in the past already. It does not qualify as research anymore.
15:27:36<quicksilver>malcolmw: does all live data get carried over with it?
15:27:37<SamB>quicksilver: how is that possible when the community has only 610 members ?
15:27:54<gwern>SamB: I think haskell is bigger than 610
15:27:58<quicksilver>SamB: for 0.39% of his time, JaffaCake does other things :P
15:28:03<SamB>hahaha
15:28:07<quicksilver>SamB: erm, 39%.
15:29:54<malcolmw>quicksilver: I don't recall the details. Basically, you can send a value containing unevaluated thunks over the wire, and the unevaluated bits get sent as bytecodes. When they are executed, they might refer to entities which are not present on the remote machine, so those get transferred later on demand.
15:31:43<quicksilver>malcolmw: ah, so the live data gets transferred on demand
15:31:50<quicksilver>malcolmw: in the terminology I was using.
15:31:54<quicksilver>that's interesting.
15:32:51<doserj>how does garbage collection work there?
15:33:24<quicksilver>doserj: a garbage truck drives from one machine to the other
15:33:30<quicksilver>doserj: once a week, on Thursdays.
15:33:49<doserj>:)
15:34:03<doserj>even on holidays?
15:34:23<hatds>?instances Category
15:34:25<lambdabot>Couldn't find class `Category'. Try @instances-importing
15:34:33<hatds>?instances Control.Category
15:34:34<lambdabot>Couldn't find class `Control.Category'. Try @instances-importing
15:34:37<quicksilver>if there a bank holiday, the major GC will be on Friday.
15:34:47<quicksilver>in cases of extended holidays, minor GCs will be arranged.
15:35:16<jgriffin>Hi there. I'm in the process of learning Haskell, but I need a bit of advice on which direction to take. I'm self-teaching, and I have experience programming prior to learning Haskell. If I read "Programming Haskell" and "Real World Haskell", will those two books alone be sufficient for teaching the language? Some suggest also reading Haskell: The Craft
15:35:24<jgriffin>of function programming, but is it necessary?
15:35:44<quicksilver>no.
15:35:46<Peaker>jgriffin: RWH should be enough, as far as I heard. I haven't heard of Programming Haskell
15:35:52<quicksilver>many people learn by reading no books at all.
15:35:55<hatds>?instances Arrow
15:35:56<lambdabot>(->), Kleisli m
15:35:59<quicksilver>the two you mention are both good books.
15:36:12<quicksilver>Of course, all the authors visit this channel, so I have to say that :)
15:36:14<Peaker>jgriffin: I learned Haskell by experimenting with it, reading some tutorials on the web, and hanging out in #haskell
15:36:22<aledge>RWH is really good, you should be fine if you have prior experience. You'll learn the most by trying to code something, of course
15:36:41<quicksilver>I believe Hutton's book is good but aimed at undergraduate students
15:36:50<quicksilver>whilst RWH is aimed more at programmers wanting to code
15:37:04<jgriffin>Peaker: I've actually found that I retain the information best when I code myself, not when I read what others have written. I agree. :D
15:37:18<smarmy>i'd at least read RWH. yes, you can learn yourself, but like any subject, you miss a lot of the small insights that someone with experience can convey to you earlier than later
15:37:26<jgriffin>right
15:37:29<jgriffin>Okay then.
15:37:44<jgriffin>Thanks guys.
15:37:45<hatds>you should watch "A Taste of Haskell"
15:37:51<hatds>very good first pass of the language
15:38:20<jgriffin>hatds: I'll check it out.
15:48:14<Cale>jgriffin: It also might be worth pointing out
15:48:15<lambdabot>Cale: You have 1 new message. '/msg lambdabot @messages' to read it.
15:48:18<Cale>@where lyah
15:48:19<lambdabot>www.learnyouahaskell.com
15:48:27<Cale>which looks fun :)
15:48:45<Cale>I think most people end up using a mishmash of sources :)
15:49:17<jgriffin>I'm kind of getting that vibe...
15:49:18<Cale>jgriffin: and ask lots of questions here :)
15:49:43<jgriffin>I like this channel. The people don't bite too frequently...
15:49:48<TomMD>Grrrr
15:49:54<Cale>We are the documentation. :)
15:50:35<dev31212>learnyouahaskell is the first site where I started to feel like I knew what I was doing :)
15:50:38<dev31212>great site...
15:50:43<Athas>Just out of curiosity, but are the GHC hackers still going to switch away from Darcs?
15:50:44<dev31212>moved on since, of course
15:51:26<TomMD>Athas: They were talking in #ghc ten minutes ago, you could ask them.
15:51:42<shapr>I want to build GHC with eight cores and 16GB of ram, are there any command line options I can change to take advantage of the extra resources?
15:52:06<dev31212>what a beast machine.
15:52:16<jgriffin>dev31212: I think I'm past the point of "Learn you a Haskell". I've already absorbed the first half of Programming Haskell, and it looks like I've covered what goes on in that tutorial.
15:52:17<TomMD>shapr: Couldn't you use -j5?
15:52:25<TomMD>or -j9
15:52:29<dev31212>jgriffan, cool
15:52:34<shapr>TomMD: I'm using -j10, but that won't use more memory, right?
15:52:38<Cale>jgriffin: Ah, okay :)
15:52:41<CosmicRay>still trying to work around the API change in time in convertible. MIN_VERSION_time() doesn't work because it only matches the first three bits of the version number
15:52:50<CosmicRay>how else might I do it?
15:52:53<TomMD>shapr: No more than needed - it won't do cool caching.
15:52:56<dev31212>Real World Haskell...And the wikibooks book on Haskell are what I am on at the moment
15:53:06<dev31212>Well Im half way through Real World Haskell
15:53:21<shapr>I'm pretty sure GHC can build faster if each GHC compile is given more heap or something.
15:53:23<TomMD>And how many worlds have you realized?
15:53:37<dev31212>I have realized the Monadic world
15:53:42<dev31212>where the universe is just one object
15:53:45<dev31212>I have seen past
15:53:48<dev31212>present and future at once
15:53:53<dev31212>Like The Quizat Kadderach
15:54:33<hackagebot>convertible 1.0.3
15:55:23<CosmicRay>damn, that was fast
15:55:32<Baughn>conal: I realized there's a bit of a semantic problem with my implementation of makeEvent - namely, the next occurence. It's not known when (or even if) it'll happen, but it /is/ known that it won't happen before the current time, which I ought to take advantage of - otherwise, merging the event with another would be impossible, never mind joining it
15:55:36<mornfall>dev31212: How much for that stuff you are smoking? ; - )
15:56:07<Baughn>conal: I have a suspicion you already fixed this at some point in the past, though. (And also that it involves improving values). Any thoughts?
15:56:40<dev31212>mornfall, $42 :)
15:56:52<quicksilver>Baughn: that's the key problem of making "joinE" efficient, yes
15:57:00<quicksilver>Baughn: "observing information about non-occurrence"
15:57:22<quicksilver>Baughn: it's actually not required to make it semantically possible, but if you can't observe and remember non-occurrence you waste a lot of time cheking for it
15:59:17<Baughn>quicksilver: When it comes to events whose next occurence, if any, is driven by an IO sink instead of being computed some other way?
16:00:18<quicksilver>Baughn: well in some sense your implementation has to cope with all four permutations
16:00:42<quicksilver>Baughn: IOsink / IOsink, IOsink / purely computed, etc.
16:00:45<quicksilver>hmm. 3 permutations ;)
16:01:00<BioHazardSoftwar>Hey everyone
16:01:04<Baughn>quicksilver: I'd use a special Time type
16:01:10<quicksilver>one place where I disagree with conal's implementation is the amount of stuff working directly on events.
16:01:16<quicksilver>I believe it makes more sense to define most primitives on futures
16:01:42<Baughn>quicksilver: Whose exact value can't be checked without waiting for the event to occur (or the finalizer to trigger and cap it), but can be checked for inequality using unsafePerformIO to read the clock
16:02:46<Baughn>ACTION sighs
16:03:07<quicksilver>well my preference is not to use unsafePerformIO to hide things away like that
16:03:10<quicksilver>but we'll see.
16:03:13<Baughn>..it might be simpler to try implementing reactive from scratch, for learning to understand this. The existing code is.. convoluted, and I don't really understand why
16:03:22<quicksilver>my approach may fail to yield an efficient implementation.
16:03:43<hatds>is there a simple reactive example available that represents a runnable, interactive program with stdin?
16:04:06<Baughn>I've got a couple
16:04:08<Baughn>Let me see..
16:05:16<conal>Baughn: yeah. i have dealt with this issue. it's *very* important.
16:05:16<lambdabot>conal: You have 1 new message. '/msg lambdabot @messages' to read it.
16:06:36<hackagebot>Hieroglyph 2.24
16:06:38<Baughn>hatds: http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5376#a5376 <-- OKay, I guess this is about the minimal one
16:06:57<conal>Baughn: you've run into all of the awkward spots i know of in reactive: external input, correct unamb implementation, and event join.
16:07:10<Baughn>conal: Right. Obviously my current makeEvent doesn't handle it, but I did at least figure out how to get the finalizers working right
16:07:21<hatds>can you put in the imports for me?
16:07:24<Baughn>conal: So if you've already dealt with it, I'm hoping you can adapt it. :)
16:07:34<conal>Baughn: i'll look
16:08:08<Baughn>hatds: ..I'm not really sure what they are. Umh.. LegacyAdapters, Control.Applicative.. yeah, I think it's just those two.
16:08:50<Baughn>conal: If I've run into all of them, it's because I started deliberately looking for bugs. :P
16:09:19<hatds>is Reactive not really runnable then?
16:10:15<Baughn>hatds: Well, there are enough bugs that you're pretty much bound to run into them. I'm smacking them as fast as I can, but since that involves figuring out conal's code at the same time..
16:10:44<Baughn>hatds: I may be introducing new ones too. Like the makeEvent/mappend bug I just figured out I'd caused. :P
16:11:24<LeCamarade>Baughn, When I run a program in runhaskell, to what level does it get compiled?
16:11:34<Baughn>LeCamarade: Not at all.
16:11:44<LeCamarade>Ah.
16:11:50<Baughn>Well, it's compiled to bytecode; ghci/hugs aren't pure interpreters.
16:11:56<LeCamarade>Hence the variation!
16:13:05<LeCamarade>It's so surprising. There is that deadlock I told you about, and it never ever shows up when I runhaskell. But once I get the code compile, it is consistent. And I just can't trace it. (I really want to know why I'm getting it, but I may never.)
16:13:32<conal>LeCamarade: multi-threaded code?
16:13:48<conal>i think ghci runs as if linked with -threaded.
16:13:57<Cale>Yeah... try with -threaded
16:14:07<Cale>I had some strange problems like that too
16:14:37<Cale>It seems that some C library bindings don't work very well without -threaded
16:15:43<conal>i think C calls block the RTS unless -threaded
16:16:27<conal>ksf: poing
16:16:33<conal>ksf: i mean "ping"
16:17:19<bos31337_>pyongyang
16:17:40<conal>pyin/pyang
16:17:56<aledge>pinyin?
16:19:04<heatsink>If you're going to make many data types have the same field, how would you do that?
16:19:31<heatsink>I can think of adding the field to each constructor and defining a class HasField a where getField :: a -> Field; setField :: Field -> a -> a
16:19:57<heatsink>Or creating a wrapper data type, data WithField a = WithField Field a
16:20:34<lars9>:t id
16:20:35<heatsink>The latter makes pattern matching slightly more convenient, but I think the former may be easier to maintain
16:20:35<lambdabot>forall a. a -> a
16:20:44<lars9>@src id
16:20:44<lambdabot>id x = x
16:21:59<heatsink>Has anyone here seen an idiom for this in an existing project?
16:22:04<lars9>:t pure id <*> v
16:22:05<lambdabot> Couldn't match expected type `f a' against inferred type `Expr'
16:22:05<lambdabot> In the second argument of `(<*>)', namely `v'
16:22:05<lambdabot> In the expression: pure id <*> v
16:22:20<lars9>:t pure id <*> (*2)
16:22:22<lambdabot>forall a. (Num a) => a -> a
16:22:29<lars9>:t pure id <*>
16:22:30<lambdabot>parse error (possibly incorrect indentation)
16:22:41<lars9>:t ( pure id <*> )
16:22:42<lambdabot>forall a (f :: * -> *). (Applicative f) => f a -> f a
16:22:50<glguy>:t (id <$> )
16:22:52<lambdabot>forall a (f :: * -> *). (Functor f) => f a -> f a
16:23:20<lars9>:t ( pure id )
16:23:21<lambdabot>forall a (f :: * -> *). (Applicative f) => f (a -> a)
16:23:38<quicksilver>lars9: lambdabot replies to private messages.
16:23:45<quicksilver>lars9: also you can install GHCi on your own machine :)
16:24:00<quicksilver>lars9: the purpose of lamdabot in a public channel is to form part of an ongoing discussion ;)
16:24:06<lilac>heatsink: i vaguely recall a GHC extension where field names could be reused across multiple 'data'
16:24:13<quicksilver>heatsink: I've see variations of both of those.
16:24:31<quicksilver>heatsink: in the very very rare case where I want that, I favour the class HasField approach.
16:24:46<quicksilver>but I don't find the idiom that useful.
16:24:53<lilac>heatsink: do you want to be able to treat such things polymorphically?
16:24:57<quicksilver>(there is often a more useful class or HOF to use than HasField)
16:25:20<lilac>(are there any higher-level operations you wish to perform over all such data types?)
16:25:37<LeCamarade>conal, Yes, multithreaded.
16:25:41<hackagebot>checkers 0.2
16:25:55<lilac>heatsink: does this field have the same type for all datatypes? does the datatype make sense if you remove the field?
16:26:48<heatsink>lilac: I don't expect to do any interesting HOFs over such data types. They make sense without the field.
16:27:20<heatsink>lilac: In my case, the extra field is information about the source of a data structure that was produced from an input file.
16:28:01<heatsink>If it were removed, you could still do everything except report source line information together with the output.
16:28:54<Cale>heatsink: Maybe separate it into another type?
16:29:13<Cale>I don't know how inconvenient that would be...
16:29:34<lilac>heatsink: ... yeah, what Cale said :)
16:29:38<heatsink>Cale: what do you mean? Source information is another type, but it has to be attached to other data types somehow.
16:30:07<lilac>heatsink: data WithSourceInformation a = WSI { sourceInformation :: SourceInformation, body :: a }
16:30:25<lars9>what's the applicative functor in "pure id <*> (+2)"
16:30:33<lilac>lars9: reader
16:30:45<heatsink>That was one of my two proposals, above: data WithField a = WithField Field a
16:30:57<Cale>ah, okay
16:30:59<Cale>I missed that
16:32:54<heatsink>I guess the two things that I don't like about that are that it's not composable and that it introduces extra levels of indirection.
16:33:17<heatsink>What I mean about composability is, suppose I had two bits of extra information: source position and user annotations.
16:33:33<heatsink>Now WithSourceInformation (WithUserAnnotations a) /= WithUserAnnotations (WithSourceInformation a)
16:34:17<mmorrow>so it's not commutative
16:34:42<lilac>lars9: you can tell it's the reader monad because <*> takes an Appliactive on both sides and the RHS is a function
16:34:47<heatsink>Right.
16:34:53<Saizan_>you could implement extensible records in ghc
16:34:56<Saizan_>or use HList
16:34:58<heatsink>With type classes, you'd have (HasSourceInformation a, HasUserAnnotations a) => a
16:35:02<Cale>One thing you could do is just include the fields with a Maybe type.
16:35:17<Cale>But that's perhaps a little less typesafe
16:35:27<heatsink>Which is "commutative" in the sense that type class constraints are unordered.
16:35:43<lilac>lars9: incidentally, pure f <*> x = f <$> x = fmap f x, so pure id <*> x = fmap id x = x
16:36:59<Cale>(In the sense that whether the fields are present or not is a runtime property then.)
16:37:07<heatsink>right
16:37:41<lilac>lars9: (the first equality comes from the Applicative laws, the second from the Functor laws)
16:38:26<Cale>You can also have your datatype (assuming it's recursive, or else this is kind of silly) take an extra arbitrary type parameter for all the extra information that it's annotated with.
16:38:35<Athas>How do people use Parsec nowadays? Through an applicative functor interface?
16:38:43<lars9>lilac: where is <$> defined? not defed in control.applicative and control.monad
16:38:45<Cale>and then just construct a big enough type for all the annotations you want to make
16:38:55<Cale>Athas: and monadically
16:39:08<Beelsebob>lars9: Control.Applicative
16:39:14<Cale>Athas: Applicative notation is convenient sometimes though.
16:39:30<lilac>@index (<$>)
16:39:30<lambdabot>bzzt
16:39:52<Athas>Cale: yes, I noticed. But it looks like it can easily become unreadable if used indiscriminately as well.
16:40:08<heatsink>Cale: That's true, but since the code statically knows what annotations are there, I think that's kind of overkill.
16:40:42<lilac>quicksilver: (thinking back to applicative parsers), you could still make a monad instance assuming your parser is pure, by trying it on all possible first letters
16:41:29<Cale>heatsink: Well, the type that you apply it at can be different in different parts of the code then
16:42:10<heatsink>Cale: Yeah, I do that when the type changes in different parts of the code :)
16:45:08<heatsink>In my experience, overusing type variables can lead to having to insert/remove type variables in lots of signatures, even when there's no change to the code.
16:45:45<heatsink>And not solving the field problem I was asking about can lead to having to insert/remove underscores in lots of patterns, even when there's no real change to the code.
16:46:12<Cale>Well, that's what the record syntax is primarily for...
16:46:26<Cale>(not having to insert/remove underscores in patterns)
16:46:44<heatsink>oh yeah
16:46:50<heatsink>I forgot about that
16:47:15<heatsink>So that's what Saizan_ meant about extensible records
16:47:29<Cale>Actually, probably not :)
16:47:34<ray>record syntax is pretty useful, but i feel like i have to take a shower every time i use it
16:47:39<Cale>Extensible records are something that Haskell doesn't have
16:47:46<Cale>But would make your life much easier
16:49:24<Cale>Basically, it gives you a particular new kind of record type with labelled/typed fields, and a way to write functions which are polymorphic over any record that has certain fields
16:50:45<heatsink>I see
16:50:57<quicksilver>lilac: well really it's first-token not first-letter
16:51:10<quicksilver>lilac: and if the intention was for it to be 0-lookahead then you can't do that.
16:51:29<quicksilver>lilac: you can make the monad instance by backtracking, which breaks the idea of the parser, yes.
16:51:58<Cale>(and polymorphically extend any record with additional fields)
16:58:05<nibro>Cale: depends on what you mean by Haskell - there's TRex for hugs
16:58:18<Berengal>Cale: Sort of like creating a type class for each accessor function?
17:01:44<Cale>nibro: That's true
17:01:58<heatsink>Well, I feel better about going with the type class solution then :)
17:02:53<quicksilver>Berengal: well, some record typing systems allow upper as well as lower bounds on the fields
17:03:02<quicksilver>IIRC ocamls' extensible variants has this
17:03:05<quicksilver><: and :>
17:03:14<quicksilver>that would not be easy to express with typeclasses
17:03:21<quicksilver>TCs are not good at negative information.
17:03:30<quicksilver>due to being open.
17:03:35<quicksilver>hence all the hoops oleg builds around HFalse
17:06:24<Cale>With sufficiently complicated typeclasses, you can approximate it, and some libraries, like HaskellDB, actually do this
17:06:50<Cale>But it's something which would really be a lot nicer if you didn't have to use typeclasses to do it.
17:07:28<Cale>Oh, that was in reference to extensible records, though I suppose with extensible variants it also somewhat applies
17:07:55<Cale>You can use existentials and typeclasses to approximate extensible variants, like the new exceptions library does
17:08:04<Cale>But again, not the prettiest result.
17:08:58<quicksilver>Cale: but on the other hand, true extensible variants break the type system pretty badly
17:09:03<quicksilver>Cale: so maybe it's not abad thing we can't do it.
17:10:59<Cale>quicksilver: Oh? How so?
17:11:20<Cale>I think it's possible to do true extensible variants without breaking the type system.
17:12:15<quicksilver>Cale: well FSOV of "breaking"
17:12:25<quicksilver>Cale: you get something not remotely as pleasant as we have now.
17:12:39<quicksilver>Cale: in particular with the subtype/supertype polymorphism
17:13:25<quicksilver>that's the <: and :> stuff
17:13:30<quicksilver>I can't remember the details, alas.
17:14:40<Cale>As long as you confine subtyping/supertyping to the kind of variants, then I think it should be okay.
17:16:09<Cale>Well, what you really want is more or less a row variable of possible labels/types for the variant. So it's almost identical to the extensible record system.
17:17:58<hackagebot>haskeline 0.6.1.6
17:35:45<ksf>conal, pong
17:42:48<jeffersonheard>crud... is wouter swierstra on here?
17:47:54<conal>ksf: hi. i see you ran into trouble with quickcheck versions.
17:49:21<conal>ksf: i've pushed a new checkers. will push other libs as well.
17:49:59<conal>jeffersonheard: i think so. anyone remember wouter's irc handle?
17:50:03<ksf>conal, yes, C calls block, even when threaded, at least that's my best guess from how stuff behaves, I never wrote a test or something to pin the semantics down.
17:50:43<ksf>cabal update
17:50:45<ksf>grr.
17:53:41<ksf>conal, still, I'd like to have ifdef's around all test code, just to calm my engineering intuition after hitting upon that BinOp thing.
17:54:00<ksf>production code depending on test cases freaks me out.
17:55:09<conal>ksf: ifdefs around Arbitrary & CoArbitrary instances?
17:56:04<ksf>yes, around those, around the quickcheck imports, and the rest of the test case, so that you can build a version of reactive without tests enabled, and not depending on quickcheck, at all.
17:58:38<conal>ksf: does that desire come from a general wish to reduce package dependencies where possible? or maybe something more specific to quickcheck or checkers?
17:59:23<ksf>uhhh... both.
17:59:26<conal>ksf: what's the BinOp thing?
18:00:43<ksf>merge in PrimReactive uses BinOp, and it's used in a thousand instances that don't look like tests. It's out of checkers afair.
18:01:34<conal>ksf: oh, i see. yeah. BinOp has nothing do with testing, so it's not logical for me to get it from checkers.
18:01:37<ksf>...or, rather it's used in the Monoid Event instance, and that's used all over the place.
18:02:05<conal>ksf: i don't know how to manage *not* including QC instances in my libraries. other libraries & apps will need them.
18:02:15<conal>ksf: i.e., they're not just for testing *my* libs.
18:02:44<conal>i want all libs that i use to define & export QC instances. and i expect others will want the same from me.
18:02:44<ksf>well, if someone wants to run tests, they can compile with --enable-testing
18:03:11<conal>ksf: that's a separate issue, don't you think?
18:03:32<conal>and sure, for running my tests, --enable-testing would be fine.
18:03:52<conal>btw, is --enable-testing a standard flag or one i'd define in my .cabal files?
18:04:08<ksf>well, I think that test and production code should be sharply seperated, and ifdef's are the best way to ensure that, even if noone ever compiles without tests enabled.
18:04:43<ksf>dunno, I didn't look at how to integrate with cabal, yet.
18:05:18<dcoutts>conal: right, you can't (or at least should not) conditionally export stuff
18:05:21<kynky>ksf, ideal world vs real world (there are always side effects)
18:05:25<ksf>it probably should be a standard flag, though, like enable docs.
18:05:41<dcoutts>ksf: the difference is that docs do not affect the exported API
18:06:02<dcoutts>cabal flags are not supposed to affect the exported API
18:06:27<dcoutts>dependency planning relies on that, and there's deliberately no way to express a dependency on a package built with some set of flags
18:07:01<dcoutts>also such conditional package building does not translate into binary distro packages
18:08:38<Berengal>An alternative is to break a package in two, foo and foo-tests
18:09:39<dcoutts>I think it's better just to depend on QC
18:10:01<conal>Berengal: or even three: foo, foo-QC (with QC instances), and foo-tests
18:10:01<dcoutts>we'll soon get to the stage where we've got a sensible QC version as standard
18:10:25<conal>dcoutts: yeah. it's an awkward moment w.r.t QC now.
18:10:32<conal>transitional
18:10:36<dcoutts>problem is that the release of ghc-6.10 and QC2 happened at almost the same time
18:10:44<dcoutts>so ghc-6.10 shipped QC 1.2
18:10:52<dcoutts>and the platform had to follow that
18:11:09<dcoutts>but the next major release will undoubtedly update to QC2
18:11:35<conal>i was surprised at how much work it took me to change checkers over from QC1 to QC2. some pretty big changes.
18:17:57<ksf>ACTION stays stubborn and still reserves the right to write #ifndef ENABLE_TESTS around code and nag about things like BinOp
18:19:15<conal>ksf: to eliminate a QC dependency?
18:20:02<ksf>well, that's just a nice side-effect of being a nazi about minimal dependencies.
18:20:29<conal>ksf: i could split reactive into two or three packages.
18:20:42<conal>ksf: since the exports would differ
18:21:05<conal>ksf: although it depends on other package(s) that depend on QC
18:21:17<ksf>don't you need to tests non-exported functions?
18:21:48<conal>ksf: and representation. it'd be painful and ultimately unsatisfactory.
18:22:20<dcoutts>conal: I'd just stick to depending on QC, it's not a heavy dep, it's just the current issue of the transition
18:22:33<conal>ksf: and if i don't split the package, i can't support libs that build on top of reactive
18:22:44<ksf>I still don't understand why changing exports would be bad, but I've missed some of the discussion due to my network.
18:22:48<conal>ksf: i mean if i don't somehow provide dependable QC instances for reactive types.
18:23:02<ksf>otoh, the tests exports could just be calls to errors.
18:24:07<conal>dcoutts keeping QC dependence is my leaning as well. however, i want to hear ksf out. i figure he wouldn't be complaining if he didn't have a good reason in there somewhere.
18:24:21<dcoutts>ksf: the problem is that conditional exports breaks package management
18:24:22<dcoutts>conal: sure
18:24:41<ksf>the reason is BinOp, and catching such things.
18:24:53<kynky>maybe package management could be cleverer
18:25:04<Baughn>conal: Yep, figured out another problem with unamb. This one is relatively obscure, depending on the exact behavior of the caller.. you can thank Dupree for making me think about it. :P
18:25:26<Baughn>As a plus, the solution should also make unamb cleaner
18:25:36<dcoutts>kynky: it's a bit hard to change the distro package management systems
18:25:38<conal>Baughn: great! thanks Dupree!
18:25:50<dcoutts>kynky: just changing our own is not enough
18:25:52<ksf>so, in the end, it doesn't matter if reactive can be cabal-installed without test code, as long as you can complie it without tests during development, to check if stuff's in the right place.
18:26:40<conal>ksf: i don't even know how to define "in the right place" in such a way that i'd know BinOp wasn't. help?
18:26:44<kynky>gentoo package management is pretty flexible now, but some others are archaic i guess
18:27:31<ksf>well, checkers is a test library, and whole reactive depends on it in a crucial way, not just the tests.
18:28:03<ksf>I figure it should be in a package both checkers and reactive depend upon.
18:28:22<conal>ksf: yeah. or duplicated.
18:28:28<ksf>or that, yes.
18:28:41<conal>type UnOp a = a -> a
18:28:53<conal>i never know what to do with such trivial but widely useful things
18:29:08<ksf>Prelude.Conal?
18:30:34<ksf>actually, it'd be nice to have a collection of Prelude.*s, just to have a library of different coding styles, and a repository to draw from to extend the prelude.
18:32:07<Berengal>ksf: I actually like that idea...
18:32:22<conal>ksf: i can deal with UnOp/BinOp one way or another. also tests. that leaves testing functionality, which still has to get exported. don't know what to do there.
18:32:31<dcoutts>kynky: right, the binary ones are more restrictive
18:33:12<ksf>conal, don't worry.
18:33:29<conal>ksf: where testing functionality includes QC instances and other reusable support.
18:35:44<ksf>I'm going to write those defines, and leave you alone if it compiles with the test dependencies removed, I don't really care about really _installing_ a test-less reactive.
18:36:15<sayyestolife>what are some good mailing lists that one should subscribe to? (except the haskell ones, already got them!)
18:36:26<ksf>regard them as another test case, testing the independency of code from tests.
18:40:05<Berengal>Hmmm, splitting packages does make it hard to test unexported functions, ifdefs are ugly and complicate dependencies, and putting the tests in the same package as the code doesn't /really/ make sense; couldn't match expected type Code against inferred type Test in the expression 'testModule : package'
18:41:56<Berengal>If you were somehow able to give a package full access to all modules (perhaps even private declarations) in another package, splitting wouldn't be so bad
18:44:42<ksf>Berengal, you'd have to recompile the package you depend on, due to inlining and stuff.
18:45:12<Berengal>ksf: Yes, I realize that. This is the "somehow" part in my previous statement
18:45:37<Berengal>Somehow == magic, usually
18:46:11<kynky>===
18:46:39<ksf>#ifndef DISABLE_TESTS isn't ugly, but useful documentation.
18:46:59<Berengal>ksf: It mixes tests and code in files
18:47:37<ksf>yeah, but you won't get your full-access cake, ever, without recompiling.
18:47:44<Berengal>They might be separate at compile time, but to me it's more important that they're separate in the source as well
18:48:29<ksf>file-based structuring is overrated.
18:48:51<ksf>I know, I once failed an exercise because I didn't split up 200 lines of C into 4 files.
18:49:00<kynky>just a hierarchy, simple rules though
18:50:57<Berengal>ksf: I once handed in a java assignment consisting of n files of n ±2 lines each
18:51:30<ksf>yay there's a reason that there are inner classes.
18:51:31<Berengal>So I agree that it's overrated. Tests don't belong in the same code they're testing though
18:52:11<kynky>Berengal, agreed
18:52:36<kynky>or stuff that is only used by tests
18:52:41<Berengal>To me the reason why is similar enough to why we use exceptions instead of return values and nested ifs
18:52:54<ksf>hmmm. I would agree on "tests testing the api don't belong in the code they're testing"
19:00:52<rubendv>I get an occurs check error on the definition of >>= here: http://moonpatio.com/fastcgi/hpaste.fcgi/view?id=2522
19:01:01<rubendv>Anyone knows what I'm doing wrong?
19:01:12<ksf>you're defining a recursive type.
19:01:34<ksf>usually, that's an error, if it's not, you still need a newtype or data declaration to get it past the type checker.
19:01:50<rubendv>Yes, but I don't see how it is recursive?
19:02:13<byorgey>what? how is rubendv defining a recursive type?
19:02:43<rubendv>Occurs check: cannot construct the infinite type: a = structure a
19:02:45<rubendv>is what I get
19:02:53<byorgey>rubendv: well, let's see, what's the type of >>= ?
19:02:57<byorgey>@type (>>=)
19:02:59<lambdabot>forall (m :: * -> *) a b. (Monad m) => m a -> (a -> m b) -> m b
19:03:13<byorgey>so here, m = (Chat structure)
19:03:32<byorgey>so it should be of type Chat structure a -> (a -> Chat structure b) -> Chat structure b
19:03:57<byorgey>rubendv: so if you have (Chat ms) >>= f, what is the type of ms?
19:04:04<byorgey>and what is the type of f?
19:04:22<rubendv>ms :: (structure a)
19:04:27<byorgey>right
19:05:06<rubendv>oh and a itself has to be a structure too
19:05:10<rubendv>I se
19:05:12<rubendv>*see
19:05:30<byorgey>why would a have to be a structure too?
19:05:57<rubendv>because f is applied to something of type (structure a)
19:06:04<byorgey>ok, right.
19:06:39<byorgey>you can't directly apply a function a -> Chat structure b to a (structure a).
19:07:01<byorgey>if you use fmap you can get a (structure (Chat structure b))
19:07:18<byorgey>which is really just a (structure (structure b)) (after removing the 'Chat' constructor)
19:07:25<byorgey>and then you can use join to turn that into a (structure b).
19:07:39<rubendv>o_O
19:07:51<rubendv>okay let me think on that for a while :p
19:08:13<rubendv>Well it isn't really necessary for it to be a monad
19:08:37<byorgey>it isn't necessary for what to be a monad? Chat?
19:08:40<rubendv>I wanted it to be an instance of a class like Monoid or MonadPlus
19:08:42<rubendv>yes
19:08:53<rubendv>but Monoid needs things of kind *
19:09:10<rubendv>so I thought MonadPlus was the only other option?
19:09:19<rubendv>and than it had to be a Monad too
19:09:22<rubendv>*then
19:09:41<byorgey>you could use Monoid, just give it another argument
19:09:56<byorgey>like instance (Monoid (structure a)) => Monoid (Chat structure a)
19:10:30<rubendv>oh yes of course
19:10:32<byorgey>in fact if you make Chat a newtype instead of data you can just say (deriving Monoid) after it, I think
19:11:16<byorgey>also, the MonadPlus constraint on the data declaration is actually kind of useless
19:12:08<seliopou>byorgey, I believe the newtype deriving requires a language extension
19:12:28<byorgey>yes, it does
19:12:31<byorgey>GeneralizedNewtypeDeriving
19:18:50<Baughn>conal: Actually, there is no bug. This makes me nervous, since it means I don't understand how unsafePerformIO interacts with exceptions.
19:19:23<conal>Baughn: i don't understand either.
19:19:48<Baughn>conal: I'm going to try reading the source.
19:19:58<conal>cool
19:21:01<conal>Baughn: i think Sterling Clover (sclv) and Bertram Felgenhauer (forgot nick) understand. at least better than i do.
19:21:45<Baughn>@seen sclv
19:21:45<lambdabot>I saw sclv leaving #haskell-in-depth, #ghc, #haskell-blah and #haskell 2d 7h 25m 34s ago, and .
19:22:04<Baughn>conal: It might be a case for haskell-cafe, but I'll at least figuring out the source code first
19:24:18<Baughn>Oh yeah. Is it possible to have Emacs read non-Prelude function signatures for eldoc-mode somehow? Perhaps through ghci?
19:27:18<Baughn>"unsafeDupablePerformIO (IO m) = lazy (case m realWorld# of (# _, r #) -> r)" <-- *sigh*
19:33:45<defun>I am confused. Are monads not pure? or is it only the IO monad that is not pure? Furthermore, what is the definition of 'purity' (in the way haskell coders use the term).
19:34:14<Cale>Well, it's subtle. Even the IO monad is pure if you look at it in one way.
19:34:26<byorgey>defun: it is only *running* IO computations which is not pure.
19:34:26<rubendv>I think only the IO a values themselves are magic?
19:34:42<Cale>The IO a values needn't be magic, but interpreting them is.
19:34:48<pejo>defun, "What is a purely functional language": http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.27.7800
19:35:06<byorgey>defun: often monads are used as a way to package up operations which *appear* to be unpure (e.g. mutable state) in a purely functional way.
19:35:08<Cale>A value of type (IO a) is like a *description* of some stuff to do in order to produce a value of type a
19:35:38<Cale>Carrying out those instructions is the impure bit.
19:35:52<Cale>But just building up a description is pure.
19:35:57<rubendv>So you could say there is a hidden interpreter that executes the IO actions it gets in a lazy list?
19:36:30<Cale>Sort of, or pattern matches on a structure that's been built up (maybe not too list-like)
19:36:41<Cale>and carries out the steps
19:37:07<defun>thanks.
19:37:07<Cale>In a compiled Haskell program, it pattern matches against main, and recursively carries out the instructions described.
19:37:22<Cale>That pattern matching causes Haskell evaluation to happen, which is itself pure.
19:37:50<Cale>So if you were writing a Haskell implementation in Haskell, one possible implementation of IO (if you don't mind the GADT syntax) would be:
19:37:53<Cale>data IO t where
19:37:58<Cale> ReturnIO :: a -> IO a
19:38:08<Cale> BindIO :: IO a -> (a -> IO b) -> IO b
19:38:13<Cale> GetChar :: IO Char
19:38:20<Cale> PutChar :: Char -> IO ()
19:38:27<Cale> ... other IO primitives ...
19:38:41<Cale>and then the RTS would have an interpreter for this datatype
19:39:09<Cale>Which, when written in Haskell, looks a bit circular :)
19:39:20<rubendv>:)
19:39:24<Cale>execute (ReturnIO v) = return v
19:39:56<Cale>execute (BindIO x f) = do v <- execute x; execute (f v)
19:40:10<Cale>execute (GetChar) = getChar
19:40:37<Cale>But of course, the first time, it would probably actually be written in something lower level, like C.
19:40:51<aias_>Why does the following not work: http://paste.pocoo.org/show/119808/ (Error message in the code)
19:41:03<olsner>Cale: is that a hypothetical implementation of the RTS in haskell? or would you actually write that as part of the base library?
19:41:19<Cale>olsner: Hypothetical implementation of the RTS.
19:41:37<olsner>so, something like execute :: IO a -> RealIO a?
19:41:43<Cale>yeah
19:42:22<Cale>Just because I didn't feel like writing C-like code for pattern matching ;)
19:42:34<olsner>how would you extend that IO system later? would that only be possible in the base library's definition of the IO type?
19:42:49<Cale>aias_: Because / isn't implemented for Int
19:43:06<Cale>aias_: you'll need to convert x to a fractional type using fromIntegral
19:43:21<Cale>aias_: So you could use f (round (fromIntegral x / 2))
19:43:29<Cale>But you should also know about div
19:43:42<Cale>olsner: Yeah, FFI is tricky like this.
19:44:11<Cale>olsner: Adding new IO *primitives* needs to be done in that algebraic datatype.
19:44:51<olsner>(unless, of course, the IO type also contains a trapdoor-like thing like UnsafeJumpToAddress :: Word -> IO ())
19:44:55<Cale>olsner: Though perhaps you could just store enough information to figure out how to do the FFI call.
19:45:02<Cale>yeah
19:45:22<aias_>Cale: Thank you very much. It works perfectly now.
19:45:32<olsner>or FFIFunctionDescriptor a b -> a -> IO b
19:45:44<Cale>aias_: f (x `div` 2) is another option, but it means something slightly different
19:45:53<olsner>which actually also looks kind of sane
19:45:59<ninjasamauri>are you sure that's proper syntax?
19:46:17<Cale>ninjasamauri: what syntax?
19:47:52<Cale>rubendv: Anyway, to get at your actual question more...
19:48:09<Cale>Er, defun rather
19:48:22<ninjasamauri>nevermind i was confused
19:49:12<ninjasamauri>cale you were helping me with a hierarchy db problem
19:49:18<ninjasamauri> decided on a nested set representation
19:49:23<aias_>Cale: Sorry, but I can't see the difference.
19:49:49<Cale>aias_: div is like floor (x/2) and works reliably for large values of x
19:50:09<Cale>defun: The property we usually mean by purity is referential transparency
19:50:50<Cale>defun: What this is, is the property that if two functions f and g always give the same result for the same parameter, then it's safe to replace f with g in the code, without affecting the meaning of the program.
19:51:05<Cale>defun: All mathematical functions have this property
19:51:33<Cale>defun: But, for example, a function which prints something on the screen before producing its result does not.
19:51:39<aias_>Cale: Thank you. I use div now.
19:54:05<Cale>defun: does that help?
19:54:29<kuribas>What does this syntax mean: Module M (Module L,
19:55:05<kuribas>?
19:55:32<Heffalump>assuming you mean that with module not Module, it means that M re-exports everything it imported from L
19:56:40<kuribas>Ah, yes, module.
19:56:49<kuribas>Heffalump: Ok, I see.
20:00:13<gwern>@quote Zombie.*Jesus
20:00:14<lambdabot>No quotes match.
20:00:20<gwern>@quote zombie
20:00:21<lambdabot>Tac-Tics says: oerjan: I tried, but his zombie lectures were hard to follow
20:00:30<gwern>@quote zombie
20:00:30<lambdabot>Tac-Tics says: oerjan: I tried, but his zombie lectures were hard to follow
20:00:44<gwern>@quote bacon
20:00:44<lambdabot>skorpan says: i love the layout of lyah. makes me feel like having some chunky bacon.
20:00:47<gwern>@quote bacon
20:00:47<lambdabot>skorpan says: i love the layout of lyah. makes me feel like having some chunky bacon.
20:00:56<gwern>drat. what *do* all you people talk about? only one bacon and one zombie quote
20:11:11<hackagebot>convertible 1.0.5
20:14:55<sm> is there a way to cabal install --reinstall -p (all libs I depend on ?)
20:16:12<hackagebot>HDBC 2.1.1
20:16:53<dcoutts>sm: not yet no, sorry
20:17:07<sm>ok, thx dcoutts
20:17:15<dcoutts>sm: not automatically, you'll have to track back which things need rebuilding
20:18:38<sm>ACTION depends on five regex libs.. that's just silly
20:18:41<ksf>@remember gwern drat. what *do* all you people talk about? only one bacon and one zombie quote
20:18:41<lambdabot>Good to know.
20:19:10<ksf>lambdabot is a metaquotolar database now.
20:20:52<wabash>curious: do many haskellers dabble in Ocaml, MLton, etc?
20:21:45<CosmicRay>I used ocaml before switching to haskell
20:21:49<CosmicRay>but I made a pretty clean break of it.
20:21:59<CosmicRay>I think there are a number of folks that are familiar with those languages at least
20:22:25<wabash>CosmicRay: How do you feel? Haskell better in some way (your opinion).
20:23:01<CosmicRay>yes, quite so. quite a few things about ocaml annoyed me. the build process was extremely complicated and non-standardized. The I/O library was very weak
20:23:16<CosmicRay>and the separate lists vs. streams was also annoying.
20:23:21<CosmicRay>I like the purity in Haskell
20:23:47<ksf>I know of enough ocaml to prefer haskell, mostly because of purity, and going all the way. I went down the shootout list in search of a proper language to learn, and haskell was (and becomes more and more, all the time) impressive.
20:23:56<Cale>It also seems like a trivial point, but I like Haskell's syntax a lot better.
20:24:01<Heffalump>still a long way to go though
20:24:05<CosmicRay>Cale: I do too.
20:24:13<sm>"Haskell goes all the way"
20:24:40<ksf>well, coming from scheme and c, looking for a replacement for scheme, not c, i wasn't really comfortable with "for".
20:25:19<bos31337>ocaml's only substantial advantage is the module system it inherits from ML.
20:25:50<CosmicRay>that's an advantage?
20:26:39<ksf>modules not messing with semantics, only scoping can be seen as an advantage.
20:26:49<wabash>So... How about math overflow and underflow? Haskell catch it ok?
20:26:53<bos31337>i think so.
20:27:10<ksf>instance exporting is an issue, though, especially the haddock situation.