<    March 2017    >
Su Mo Tu We Th Fr Sa  
          1  2  3  4  
 5  6  7  8  9 10 11  
12 13 14 15 16 17 18  
19 20 21 22 23 _2_4 25  
26 27 28 29 30 31
00:00 <johnw> it's also always surprising how much you can abstract with just a closure
00:00 <monaddanom> hum?
00:01 <johnw> I recently create a data generator where tracks have columns, and I wanted to be able to let the user manipulate which columns were printed, and in what order. I ended up just taking a list [Row -> Text] as input, which means my algorithm didn't need to care about the columns at all.
00:01 <johnw> i.e., a list of closures, where each lambda closes over the column it cares about
00:02 louispan joined
00:02 conal joined
00:05 <monaddanom> @help
00:05 <lambdabot> help <command>. Ask for help for <command>. Try 'list' for all commands
00:05 <monaddanom> @help list
00:05 <lambdabot> list [module|command]. Show commands for [module] or the module providing [command].
00:06 <johnw> do you need some assistance, monaddanom?
00:06 <monaddanom> no i don't think so:-) new here
00:08 nakal joined
00:09 haennar joined
00:10 <Ptival> is there a pragma to disable a warning for some definition or some file?
00:11 <Tuplanolla> Put `{-# OPTIONS_GHC -fno-warn-whatever #-}` in the beginning, Ptival.
00:11 <Tuplanolla> There's also plain `OPTIONS` for common flags.
00:11 dan_f joined
00:12 markasoftware joined
00:12 markus1209 joined
00:12 markus1219 joined
00:12 earthy joined
00:13 <Ptival> Tuplanolla: thanks!
00:13 mhagemeister joined
00:14 anuxivm left
00:15 l_zzie joined
00:16 adam__ joined
00:17 cschneid_ joined
00:17 <Ptival> I hope someone works on exhaustiveness checking with simple pattern synonyms :)
00:18 dolio joined
00:22 afarmer joined
00:24 fizbin joined
00:25 shangxiao joined
00:25 plutoniix joined
00:27 mekeor joined
00:28 soLucien joined
00:28 bts- joined
00:28 MP2E joined
00:29 theDon_ joined
00:32 LordBrain joined
00:33 andyhuzhill joined
00:33 lambda-11235 joined
00:37 rcsole joined
00:38 <mniip> edwardk, hmm, the algorithm is by no means trivial, I'm looking at some example cases (of End_a Hom(Fa, Ga)) and I'm not seeing any pattern whatsoever
00:38 <mniip> and then there's stuff like End_a Hom(Hom(a+, a-), Hom(a-, a+)) = Z
00:39 systemfault joined
00:39 <mniip> errr s/Z/N/
00:40 <mniip> this sounds a lot like what djinn is donig
00:41 jbiesnecker joined
00:42 bts- joined
00:42 dfeuer joined
00:42 <Forkk> is using gmp in C code called from Haskell possible now? everything I'm finding about it on google seems dated
00:43 <Forkk> and if it is, how would one go about marshalling `Integer`s to and from C code
00:43 humboldt joined
00:43 doodlehaus joined
00:44 jeddak joined
00:44 conal joined
00:45 cschneid_ joined
00:45 <EvanR> you can import Prim something to deconstruct Integer to get a pointer to gmp object
00:45 <EvanR> im not sure about what you do in C though
00:46 lambdafan joined
00:46 dfranke joined
00:47 <Forkk> what if the garbage collector deletes the integer while C is using it though
00:48 <lambdafan> @type a -> m (a -> b) -> m b
00:48 <lambdabot> error: parse error on input ‘->’
00:48 <lambdafan> @type (a -> m (a -> b) -> m b)
00:48 <lambdabot> error:
00:48 <lambdabot> Pattern syntax in expression context: a -> m (a -> b) -> m b
00:48 <lambdabot> Did you mean to enable TypeApplications?
00:48 <lambdafan> @djinn (a -> m (a -> b) -> m b)
00:48 <lambdabot> -- f cannot be realized.
00:48 <glguy> lambdabot: What are you trying to do?
00:49 <lambdafan> @djinn a -> m (a -> b) -> m b
00:49 <lambdabot> -- f cannot be realized.
00:49 fDev2179 joined
00:49 <Sornaensis> @kind (a -> (a -> b) -> b)
00:49 <lambdabot> error: Not in scope: type variable ‘a’
00:49 <lambdabot> error: Not in scope: type variable ‘a’
00:49 <lambdabot> error: Not in scope: type variable ‘b’
00:49 <lambdafan> I'm trying to find the operator with that type
00:49 <Sornaensis> @hoogle a -> m (a -> b) -> m b
00:49 <mniip> :t fmap . flip id
00:49 <Tuplanolla> :t \ x f -> f <*> pure x
00:49 <lambdabot> Functor f => b1 -> f (b1 -> b) -> f b
00:49 <lambdabot> Control.Lens.Getter contramap :: (a -> b) -> f b -> f a
00:49 <lambdabot> Data.Functor.Compat fmap :: (a -> b) -> f a -> f b
00:49 <lambdabot> Data.Functor.Apply fmap :: (a -> b) -> f a -> f b
00:49 <lambdabot> Applicative f => a -> f (a -> b) -> f b
00:50 <mniip> it is not doable for a generic f
00:50 BlueRavenGT joined
00:50 <mniip> hence djinn's failing
00:50 <glguy> :t flip (??)
00:50 <EvanR> Forkk: well, you have a reference to it, so not sure if thats possible
00:50 <lambdabot> Functor f => a -> f (a -> b) -> f b
00:51 <Sornaensis> @hoogle Functor f => a -> f (a -> b) -> f b
00:51 <lambdabot> Prelude fmap :: Functor f => (a -> b) -> f a -> f b
00:51 <lambdabot> Prelude (<$>) :: Functor f => (a -> b) -> f a -> f b
00:51 <lambdabot> Control.Monad fmap :: Functor f => (a -> b) -> f a -> f b
00:51 argent0 joined
00:51 <lambdafan> @hoogle a -> m (a -> b) -> m b
00:51 <lambdabot> Control.Lens.Getter contramap :: (a -> b) -> f b -> f a
00:51 <lambdabot> Data.Functor.Compat fmap :: (a -> b) -> f a -> f b
00:51 <lambdabot> Data.Functor.Apply fmap :: (a -> b) -> f a -> f b
00:51 <mniip> lambdafan, you were already given an answer
00:51 <Forkk> EvanR: C code having a pointer to it doesn't count I don't think
00:51 <Forkk> I suppose I could copy it
00:51 <glguy> lambdabot: You can mess around with lambdabot in /msg
00:51 <glguy> lambdafan: : You can mess around with lambdabot in /msg
00:51 <lambdafan> ah, thanks :)
00:51 <EvanR> haskell code will have a reference to it
00:52 <mniip> EvanR, that depends on the code
00:52 <Forkk> that's not guaranteed
00:52 <mniip> you can easily have it unreferenced just as the gmp object goes into ffi
00:52 <EvanR> i mean, a reference to the object itself
00:52 <mniip> and gmp objects are what? Addr#?
00:52 <EvanR> if the integer wrapper is gone, so what
00:53 fDev2179 left
00:53 <Forkk> also, can gmp even be used in called C code
00:54 <Forkk> I've heard there were issues, but I can't find anything specific saying they were fixed
00:54 <mniip> aha
00:54 <mniip> it's a ByteArray#
00:54 <mniip> which can be spontaneously moved
00:54 <EvanR> ByteArray# can?
00:55 <mniip> if it's not pinned?
00:55 <EvanR> i know whatever ByteString uses cant
00:55 <mniip> hmm
00:55 bts- joined
00:55 <mniip> or was it mutable byte arrays
00:55 <Forkk> so integers are stored as byte arrays?
00:56 <mniip> Forkk, more like unpacked mpz_t
00:56 <Forkk> right
00:56 <Forkk> so how would I turn that into an mpz_t in C
00:56 k0001 joined
00:57 danthemyth joined
00:58 <Forkk> I'd probably want to have it copy it so it's not subject to the GC
00:59 <mniip> ah
00:59 <mniip> changed it
01:00 <lambdafan> can lambdabot tell me the fixity of an operator?
01:00 mjs2600 joined
01:00 <glguy> no, but GHCi can do that, too
01:00 <Sornaensis> lambdafan: :info at ghci prompt
01:00 <lambdafan> :)
01:00 <mniip> Forkk, so, well, there's
01:01 <mniip> mp_limb_t mpn_add (mp_limb_t *rp, const mp_limb_t *s1p, mp_size_t s1n, const mp_limb_t *s2p, mp_size_t s2n)
01:01 pheaver_ joined
01:01 <mniip> in gmp lowlevel functions
01:01 conal joined
01:01 <Forkk> ok
01:01 <mniip> and then integer-gmp just foreign imports that, and passes the bytearrays as limb arrays
01:01 afarmer joined
01:02 <mniip> you could convert it into an mpz_t in accordance with https://gmplib.org/manual/Integer-Internals.html
01:03 <EvanR> so a less pain in the ass way might be
01:03 <EvanR> render the integer as a CString, pass that through ffi, load the string into gmp on the other side
01:03 <EvanR> and vice versa
01:04 <Forkk> lol
01:04 <Forkk> I think that may work
01:05 <Forkk> I could just drop in a better replacment later if necessary
01:05 <mniip> I would recommend formatting them to hexadecimal and loading with 0x and base=0
01:05 <mniip> as a premature optimization
01:06 <Forkk> and in case gmp doesn't work this way I could use something else
01:06 <EvanR> "I would recommend... premature optimization" ;)
01:06 <Forkk> lol
01:06 roconnor joined
01:06 <mniip> but divisions by 10
01:06 <EvanR> this is the simplest possible thing that will work
01:06 <EvanR> humongs love base 10
01:07 danthemyth joined
01:07 <Forkk> thanks for the suggestion
01:08 <mniip> "Conversions from binary to a power-of-2 radix use a simple and fast O(N) bit extraction algorithm."
01:08 fizbin joined
01:08 <EvanR> honestly rendering as base 16 or base 10 is pretty much equal effort on the haskell side
01:09 bts- joined
01:09 <EvanR> :t showIntAtBase
01:09 <lambdabot> (Show a, Integral a) => a -> (Int -> Char) -> a -> ShowS
01:09 mzf joined
01:10 <EvanR> > showIntAtBase 16 intToDigit 1234
01:10 <lambdabot> <[Char] -> [Char]>
01:10 <EvanR> > showIntAtBase 16 intToDigit 1234 ""
01:10 <lambdabot> "4d2"
01:11 <mniip> foreign import ccall mpn_get_str "gmp.h mpn_get_str" :: CString -> CInt -> ByteArray# -> GmpSize#
01:11 <mniip> :p
01:12 <Forkk> {#call mpn_get_str#}
01:14 robertkennedy joined
01:14 <Forkk> what is mpn, all I see in the docs is mpz
01:15 <mniip> https://gmplib.org/manual/Low_002dlevel-Functions.html
01:15 <Forkk> oh I see
01:16 twomix joined
01:17 Levex joined
01:23 bts- joined
01:23 marchelzo joined
01:25 harfangk joined
01:30 <mniip> wait, is the (# State# a, b #) return convention the same as just 'b' ?
01:30 indi_ joined
01:32 robkennedy joined
01:32 fDev2179 joined
01:33 fDev2179 left
01:33 <hpc> i suggest reading the (non-haddock) comments around the definition of IO
01:34 <hpc> it touches a bit on that, and leads to an amusing conclusion (that is perhaps obvious in retrospect if you consider the existence of unsafePerformIO)
01:34 Unhammer joined
01:34 fDev2179 joined
01:36 fDev2179 left
01:36 bts- joined
01:37 jmg8766 joined
01:37 FreeBirdLjj joined
01:38 <mniip> hpc, which module is it defined in?
01:39 romefeller joined
01:39 <mniip> ah GHC.Types
01:40 <mniip> hpc, there aren't many comments there
01:40 <mniip> nothing seems relevant
01:41 <Ptival> is there something like (<*>) for when the right thing has to be `pure`d?
01:41 <mniip> fmap?
01:41 <mniip> aka <$>
01:41 <mniip> oh the RIGHT thing
01:41 <mniip> <&>
01:43 <Ptival> mniip: where is that from?
01:43 <mniip> oops
01:43 <mniip> it's not defined in any common packages
01:43 <Ptival> I guess I can define it locally :)
01:43 <mniip> yeah you're out of luck
01:47 Rainb joined
01:50 bts- joined
01:51 guardianN joined
01:55 <Wizek> Hey, anyone knows why this throws an exception instead of returning Left? `parseTimeM True defaultTimeLocale "%Y" "a" $> either (show .> ("fail: "<>)) ((show :: UTCTime -> _) .> ("parse: "<>)) where ($>) = flip ($)`
01:56 <glguy> because fail for either doesn't return a Left
01:56 <glguy> and that function is unfortunately defined to use fail for errors
01:56 <Wizek> that does sound deeply unfortunate
01:57 <Wizek> how come?
01:57 Apocalisp joined
01:57 <glguy> you'd have to ask the author
01:57 <hpc> mniip: er, forgot about https://downloads.haskell.org/~ghc/7.8.2/docs/html/users_guide/roles.html too
01:58 <mniip> hpc, ???
01:58 <hpc> and the docs for State#
01:58 guardianN joined
01:59 <hpc> basically, State# a has no underlying representation
01:59 <hpc> and in the unboxed tuple, the whole representation is just b
01:59 <mniip> right
01:59 cdg_ joined
01:59 <hpc> for IO that means IO a has the same representation as a
01:59 <hpc> which means ghc haskell is impure
02:00 <hpc> which it must necessarily be in order to admit unsafePerformIO in the first place
02:00 <mniip> I was asking a fairly specific question about calling conventions
02:00 <mniip> not generic IO stuff
02:00 <hpc> ah nvm then
02:00 mizu_no_oto_work joined
02:00 <mniip> just noticed that you can operate on (# State# a, b #) in ghci without object code
02:00 pheaver_ joined
02:01 <mniip> which means that by the time it hits the codegen there is already no unbox tuple
02:03 <hpc> probably part of the magic of State#
02:04 lambdafan joined
02:04 guardianN joined
02:04 bts- joined
02:04 Rizy joined
02:05 path[l] joined
02:07 dreco joined
02:08 <dolio> I don't think representing `IO a` the same way as `a` necessarily makes you impure. It's giving access to that representation that makes you impure.
02:08 indi_ joined
02:09 fkurkowski joined
02:10 michael1 joined
02:10 Levex joined
02:10 takle joined
02:11 eschnett joined
02:12 <hpc> dolio: yeah, i was taking a bit of license there ;)
02:12 Textmode joined
02:12 <hpc> it's a pretty neat thing to learn for the first time though
02:14 mhagemeister joined
02:14 guardianN joined
02:16 eacameron joined
02:18 bts- joined
02:18 alex_lu joined
02:19 juhp joined
02:20 guardianN joined
02:20 infinity0 joined
02:21 danthemyth joined
02:21 fDev2179 joined
02:22 indi_ joined
02:22 eazar001 joined
02:24 infinity0 joined
02:24 guardianN joined
02:26 zcourts joined
02:26 pleax joined
02:26 LuckyRawApe joined
02:26 infinity0 joined
02:27 eacameron joined
02:28 takle joined
02:29 infinity0 joined
02:31 steeze joined
02:32 bts- joined
02:32 infinity0 joined
02:32 juhp joined
02:33 mekeor joined
02:35 eacameron joined
02:35 Catalect` joined
02:35 skeet70 joined
02:36 takle joined
02:37 aries_liuxueyang joined
02:39 aries_liuxueyang left
02:39 sword865 joined
02:40 dfeuer joined
02:42 argent0 joined
02:42 bigos joined
02:43 cschneid_ joined
02:44 roconnor joined
02:46 eacameron joined
02:46 xall joined
02:46 serendependy joined
02:47 <doomlord> one thing that bugged me about haskell was the lack of 'dot' accessor syntax (dot is used for function composition?) .. do they have an operator like that these days. "object.field" I seem to remember being told haskell concention is always to write expressions 'right to left' (e.g. $ operator) instead of 'left to right' (the threading macro in clojure)
02:48 <Koterpillar> there's & if you want it
02:48 <marchelzo> you mean like for accessing fields of records?
02:48 <Koterpillar> :t (&)
02:48 <lambdabot> a -> (a -> b) -> b
02:49 <marchelzo> you can use lens for that and then you can just use regular . to compose
02:49 <Koterpillar> so if you have data Data = { foo :: Int, bar :: String }, then this works: data & foo
02:49 <Koterpillar> and with lenses, data & foo.bar.baz
02:49 <Koterpillar> or even without lenses
02:50 <tibbe> I'm trying to use ConstraintKinds to alias a MonadReader: type EnvM m n = MonadReader (Env n) m
02:50 eacamero_ joined
02:50 <tibbe> where Env is a concrete data type
02:50 <tibbe> but I get: Non type-variable argument in the constraint: MonadReader (Env n) m
02:50 mmachenry joined
02:50 <tibbe> why isn't this working? :)
02:51 Sgeo_ joined
02:52 <tibbe> I'm just trying to create a new, more specialized version of the MonadReader type class (i.e. with the environment fixed)
02:53 aries_liuxueyang joined
02:54 suica joined
02:56 vektorweg11 joined
02:56 <robkennedy> @hoogle (b -> c -> t b c) -> (a -> Maybe b) -> (a -> Maybe c) -> (a -> Maybe (t b c))
02:56 <lambdabot> Control.Monad.HT liftJoin4 :: Monad m => (a -> b -> c -> d -> m e) -> m a -> m b -> m c -> m d -> m e
02:56 <lambdabot> Control.Concatenative biSpM :: Monad m => (a -> m c) -> (b -> m d) -> (c -> d -> m e) -> a -> b -> m e
02:56 <lambdabot> Control.Concatenative triM :: Monad m => (a -> m b) -> (a -> m c) -> (a -> m d) -> (b -> c -> d -> m e) -> a -> m e
02:56 <pikajude> robkennedy: try liftA2
02:57 <robkennedy> :t liftA2
02:57 <lambdabot> Applicative f => (a -> b -> c) -> f a -> f b -> f c
02:57 <pikajude> > liftA2 (,) (Just 3) (just 4)
02:57 <lambdabot> error:
02:57 <lambdabot> • Variable not in scope: just :: Integer -> Maybe b
02:57 <lambdabot> • Perhaps you meant data constructor ‘Just’ (imported from Data.Maybe)
02:57 <pikajude> > liftA2 (,) (Just 3) (Just 4)
02:57 <pikajude> whoops
02:57 <lambdabot> Just (3,4)
02:57 takle joined
02:57 eacameron joined
02:57 conal joined
02:58 codesoup joined
02:58 dsantiago joined
02:58 <suica> is lpaste.net down? related to S3 issues?
02:59 bts- joined
02:59 <robkennedy> :t liftA2 (,) listToMaybe (\l -> if null l then Nothing else Just (sum l)) [1..5]
02:59 <lambdabot> (Num t, Enum t) => (Maybe t, Maybe t)
02:59 <robkennedy> pikajude: I'm hoping to join them
02:59 <threshold> I am learning about the fixed point of a functor, Fix, by reading http://www.haskellforall.com/2012/06/you-could-have-invented-free-monads.html
02:59 <pikajude> what's in them
03:00 hucksy_ joined
03:00 <robkennedy> Well if I have two functions I'm hoping to get Nothing if failure happens in either.
03:01 <threshold> Given data Toy b next = Output b next | Bell next | Done and data Fix f = Fix (f (Fix f)) What is going on here? Fix (Output 'A' (Fix Done)) :: Fix (Toy Char)
03:01 preyalone joined
03:04 lambdafan joined
03:04 <dfeuer> *headshake*. containers is full of unresolved GitHub issues, and I absolutely don't have time to work through most of them soon. (Which isn't to say I haven't been working on containers; just a lot of work all around.)
03:04 louispan joined
03:04 Rainb joined
03:05 <hpc> threshold: when used with Fix, next = Fix (Toy b)
03:05 <hpc> so it's like writing
03:05 <hpc> data Toy b = Output b (Toy b) | Bell (Toy b) | Done
03:05 takle joined
03:06 <hpc> to do it with Fix, you need to add the Fix data constructor in a few places
03:07 ludat joined
03:07 indi_ joined
03:07 lspitzner joined
03:07 exferenceBot joined
03:07 <hpc> threshold: how much have you done with fix at the value level?
03:07 sobaken joined
03:07 hexagoxel joined
03:08 <EvanR> i waiting for the article on "you could have invented free monad monad monad algebras"
03:08 <pikajude> the "you could have invented this" free monad
03:09 <hpc> i can't wait for the retrospective on haskell
03:09 <hpc> "'you could have invented lens' and other falsehoods"
03:09 shangxiao joined
03:10 <hpc> threshold: anyhoo, any understanding you are able to carry over from fix will also apply to Fix
03:10 <hpc> which can make it easier
03:11 <threshold> hpc: Today is the first day that I've heard of a fixed point, so I have very little experience with fix
03:13 chocopuff joined
03:13 TxmszLou joined
03:14 Micamo joined
03:14 <raynold> ahh it's a wonderful day
03:16 eklavya joined
03:16 eklavya joined
03:18 Rizy joined
03:20 MP2E joined
03:20 urodna joined
03:21 codesoup joined
03:22 takle joined
03:24 justicefries joined
03:24 <threshold> Maybe a better question is how does fix work?
03:25 <threshold> @src fix
03:25 <lambdabot> fix f = let x = f x in x
03:26 bts- joined
03:26 Goplat joined
03:28 fragamus joined
03:29 pleax joined
03:29 <barrucadu> Perhaps a more readable definition if `fix f = f (fix f)`
03:29 <barrucadu> *is
03:29 takle joined
03:30 juhp joined
03:30 <threshold> barrucadu: That is still mind boggling
03:30 <threshold> How do you use it?
03:32 <threshold> https://en.wikipedia.org/wiki/Fixed_point_(mathematics) should be useful in understanding?
03:33 <barrucadu> `fix` lets you do recursion without giving a name to your recursive function
03:33 <barrucadu> > fix (\go x -> if x == 0 then 1 else x * go (x-1)) 5 -- factorial
03:33 <lambdabot> 120
03:35 coltfred joined
03:35 aries_liuxueyang left
03:36 xtreak joined
03:36 fabianhu joined
03:37 Mark____ left
03:37 takle joined
03:38 uglyfigurine joined
03:39 <nshepperd> threshold: fix returns the 'least' fixed point of the function, in the domain theory sense
03:40 <Squarism> does it sound sane to "send a channel over a channel" ? =D
03:40 bts- joined
03:41 <benzrf> threshold: `fix f' is a fixpoint of f in a very boring way, by definition
03:41 raycoll joined
03:41 <benzrf> threshold: `fix f' expands to `f (fix f)' by definition, so naturally `fix f = f (fix f)'
03:41 <benzrf> then `fix f' is a fixpoint, in a very cheating-y way
03:42 <benzrf> intuitively, if you have an infinitely deeply nested list of applications of f, like `f (f (f (f (f ...))))', then adding another f won't hurt
03:42 <nshepperd> threshold: I guess http://stackoverflow.com/a/4787577 is the thing to read
03:42 <benzrf> but note that this is only useful if you have lazy evaluation - with strict evaluation, this is always an infinite loop
03:43 <benzrf> `fix f' is quite often still an infinite loop in haskell, but not always:
03:43 <benzrf> > fix (+1)
03:43 <lambdabot> mueval-core: Time limit exceeded
03:43 <benzrf> > fix (1:)
03:43 <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,1...
03:43 <benzrf> `1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + ...' is undefined, of course, but `1:1:1:1:1:1:1:...' makes sense!
03:43 <pacak> > fix error
03:43 <lambdabot> "*Exception: *Exception: *Exception: *Exception: *Exception: *Exception: *Ex...
03:44 <benzrf> :}
03:44 <pacak> Exceptions all the way down!
03:44 <benzrf> @let me = const (text "Some things are unfixable.")
03:44 <lambdabot> Defined.
03:44 <benzrf> > fix me
03:44 <lambdabot> Some things are unfixable.
03:44 <nshepperd> :{
03:47 takle joined
03:48 watabou joined
03:48 chrisdotcode joined
03:50 <MarcelineVQ> </3
03:51 cpup joined
03:51 Rizy joined
03:52 Benzi-Junior joined
03:52 ramzifu joined
03:53 bts- joined
03:54 takle joined
03:55 snowalpaca joined
03:56 govg joined
03:56 jbiesnecker joined
03:56 mizu_no_oto joined
03:56 infinity0 joined
03:57 jbiesnecker_ joined
04:01 louispan joined
04:02 connrs joined
04:03 lithie joined
04:04 takle joined
04:06 mac10688 joined
04:07 bts- joined
04:10 wtetzner joined
04:10 benl23 joined
04:11 <Squarism> Any threading person that could do a sanity check : ok to "send a channel over a channel"?
04:11 <monochrom> Yes. The pi calculus does that all the time.
04:14 mhagemeister joined
04:16 Younder joined
04:16 ebsen joined
04:16 <orion> :t fix
04:16 <lambdabot> (a -> a) -> a
04:17 cyborg-one joined
04:17 <nshepperd> Squarism: that seems perfectly fine to me
04:17 chu joined
04:17 <Squarism> nshepperd, thanks
04:17 <nshepperd> you're just putting an mvar in an mvar, which channel already does
04:20 <Koterpillar> what's that computable float type that makes it possible to fix sin?
04:20 aarvar joined
04:21 <monochrom> Is it CReal?
04:21 bts- joined
04:22 <Koterpillar> fix sin :: CReal
04:22 <Koterpillar> > fix sin :: CReal
04:22 <lambdabot> mueval-core: Time limit exceeded
04:23 <Koterpillar> > fix (\x -> x / 100) :: CReal
04:23 <lambdabot> mueval-core: Time limit exceeded
04:23 <Koterpillar> how come this doesn't converge either?
04:24 louispan joined
04:25 takle joined
04:25 shayan_ joined
04:26 otto_s_ joined
04:26 robertkennedy joined
04:26 zcourts_ joined
04:27 tmtwd joined
04:29 pleax joined
04:30 wukong12 joined
04:31 TxmszLou joined
04:34 dan_f joined
04:34 bts- joined
04:35 danthemyth joined
04:35 buttons840 joined
04:37 brynser_ joined
04:38 vlatkoB joined
04:38 jmcarthur joined
04:41 <nshepperd> for those to work you'd need sin undefined ≠ undefined
04:42 <threshold> Koterpillar: What do you mean by converge?
04:42 <nshepperd> it would have to be some weird representation with lazy continued fractions or something o_O
04:43 <threshold> nshepperd: Thank you for the Stack Overflow link. I will read through it.
04:45 augur joined
04:45 <davean> go #ghc
04:46 <Koterpillar> nshepperd: well, sin undefined <= 1
04:48 takle joined
04:48 nickr joined
04:48 bts- joined
04:50 Xanather joined
04:56 sobaken joined
04:57 <nshepperd> fix (\x -> x / 100) would work in a decimal bounded setting (0 < x < 1), then you could do x/100 = 0:0:x
04:57 <Cale> Koterpillar: But then the next step gets you, you would presumably want to know that sin (sin undefined) <= sin 1, however, to get that, you need to know something more subtle about the sine function, such as the fact that it's monotonic on [0,1]
04:58 travv0 joined
04:58 travv0 left
05:00 mitchty joined
05:02 coltfred joined
05:02 bts- joined
05:02 nighty joined
05:02 mada joined
05:02 path[l] joined
05:02 takle joined
05:05 mbuf joined
05:07 louispan joined
05:08 <Koterpillar> Cale: if I (somehow) compute sine starting from the most significant digit, then since head (sin undefined) == 0, that gives me a _better_ upper bound on sin (sin undefined)
05:09 <Cale> How though?
05:09 <Cale> I know that by using arbitrary amounts of analysis you can get that
05:10 takle joined
05:10 jshjsh joined
05:12 <Cale> Just knowing that sin (undefined) < 1 doesn't tell you much about sin (sin undefined) unless you know something about sine itself, such as monotonicity in an interval.
05:12 Levex joined
05:12 FreeBirdLjj joined
05:12 <Cale> In particular, without something special, you're not going to obtain sin (sin undefined) < sin 1 like you want
05:12 conal joined
05:14 <threshold> Do the integers for a partially ordered set with respect to the order ≤ ?
05:14 <threshold> form
05:17 <Cale> yes
05:17 <Cale> (moreover, they're totally ordered)
05:17 louispan joined
05:18 <pikajude> duuude
05:21 MrWoohoo joined
05:22 osa1 joined
05:23 <nshepperd> I think you need to take advantage of one the trigonometric identities involving sin to do this. and to be able to express such identity as a constructor of your real number type
05:23 <nshepperd> it seems like it might be possible, but I don't know how
05:24 <Cale> Yeah, maybe if you contrived your representation of the reals around the ability to do this :)
05:25 <Cale> (i.e. cheating by building in sine-related stuff)
05:26 cschneid_ joined
05:27 systemfault joined
05:27 <nshepperd> well, not quite cheating
05:27 igniting joined
05:27 uglyfigurine joined
05:27 <nshepperd> I mean, putting in a Sin constructor wouldn't help at all
05:28 pranz joined
05:28 <nshepperd> I was thinking of continued fractions or something but I don't really know
05:28 <Cale> It might help :)
05:28 <Cale> (though it would make the implementation of all your operations really annoying)
05:29 hamishmack joined
05:29 bts- joined
05:30 <nshepperd> show x@(Sin y) | accursedUnutterablePtrEquality x y = "0" -- :)
05:30 fiddlerwoaroof joined
05:30 pleax joined
05:31 BartAdv joined
05:32 <Koterpillar> a bounded constructor will help, probably
05:32 <Koterpillar> data BReal = ExactValue Float | Between Float Float BReal
05:33 <Younder> Quirky ADA :)
05:34 afarmer joined
05:34 dan_f joined
05:34 <nshepperd> hmm.... a sequence of decreasing bounds, perhaps
05:34 <nshepperd> this sounds familiar
05:35 afarmer joined
05:36 <Koterpillar> I thought this was how CReal was implemented anyway?
05:36 dan_f joined
05:36 <Cale> iirc, CReal is implemented as a sequence of rational numbers such that the nth is within 1/2^n of the limit.
05:37 <nshepperd> sin x 0 = Between (-1) 1; sin x n = Between { some function of (x (n-1)) }
05:37 <Cale> So that effectively gives you a sequence of intervals of decreasing size
05:37 <Cale> nshepperd: that first bit is a type error... ;)
05:38 <Younder> How are the size and computational properties of CReal?
05:38 <Cale> It's fairly impractical
05:38 dan_f joined
05:38 <Cale> It's okay for some things
05:38 <nshepperd> Cale: nah, I'm talking about numbers that are functions now
05:39 <nshepperd> the Int -> a kind of sequence
05:39 <Cale> > sum [1..1000] :: CReal
05:39 <lambdabot> mueval-core: Time limit exceeded
05:39 <Cale> ^^ but it's pretty bad for general computation
05:42 hamishmack joined
05:43 bts- joined
05:43 <Cale> > exp (pi * sqrt 163) :: CReal
05:43 <lambdabot> 262537412640768743.9999999999992500725971981856888793538563
05:43 <Cale> ^^ not that bad so long as the expression is simple
05:44 eklavya joined
05:44 <nshepperd> so in conclusion, I feel like maybe CReal or something like it should be able to do this, but I don't really understand its implementation
05:44 <nshepperd> unfortunately sin ⊥ is actually ⊥ in CReal though
05:45 <Cale> Well, yeah
05:45 dan_f joined
05:46 <jle`> is there any nice way to write '(,) a b
05:46 <jle`> the type
05:46 <nshepperd> even though I don't really see why because it's a function inside?
05:46 <nshepperd> like, it's not even const ⊥
05:46 watabou joined
05:47 zcourts joined
05:47 takle joined
05:47 FreeBirdLjj joined
05:47 <nshepperd> I guess probably performance reasons outweigh being able to do tricks like fix sin
05:47 raphidae\ joined
05:47 |raphida3 joined
05:47 [raph1da3 joined
05:47 `raphida3 joined
05:47 raph1da3_ joined
05:47 Catalect` joined
05:48 <Younder> Well are you familiar with Pythons implementation of numbers in it's original form. Incredibly inefficient. Feels something like that. So ADA using Python implementation methods. Neither fish nor foul!
05:48 raph1da3[ joined
05:48 raphid43- joined
05:48 ]r4ph1dae joined
05:48 raphida3^ joined
05:48 raph1dae joined
05:48 `raph1da3 joined
05:48 raph1dae] joined
05:48 r4ph1dae] joined
05:48 raph1dae` joined
05:48 ^raph1d4e joined
05:48 `raph1dae joined
05:48 [raphida3 joined
05:49 sjakobi joined
05:49 <Cale> Younder: It's almost surely more inefficient than that (but also does more)
05:52 xtreak joined
05:53 hamishmack joined
05:55 <sjakobi> Quick heads-up that Hackage has lost a few packages: https://github.com/haskell/hackage-server/issues/573
05:56 <sjakobi> stack users might run into a strange issue with nightly-2017-03-01 which contains one or more of these lost packages.
05:56 bts- joined
05:58 mikkel joined
06:00 <kadoban> Uh oh
06:01 louispan joined
06:01 fracting joined
06:04 FreeBirdLjj joined
06:06 thunderrd joined
06:06 pantsman_ joined
06:06 ner0x652 joined
06:08 dec0n joined
06:10 takle joined
06:10 Rizy joined
06:10 bts- joined
06:11 hexagoxel joined
06:13 wukong12 joined
06:14 athan joined
06:15 mhagemeister joined
06:15 jluttine joined
06:22 fizruk joined
06:24 bts- joined
06:26 mbuf joined
06:28 takle joined
06:28 aarvar joined
06:30 sz0 joined
06:30 hrumph joined
06:30 <hrumph> hi
06:31 steeze joined
06:31 pleax joined
06:32 <hrumph> hi
06:33 <hrumph> i'm looking for something you might call a "degenerate monad" or something like that
06:33 <hrumph> http://lpaste.net/353088
06:33 <hrumph> is there a standard designation for this?
06:34 tsdh joined
06:36 nemorichard joined
06:37 nemorichard joined
06:37 avn joined
06:38 bts- joined
06:38 michael1 joined
06:40 quchen joined
06:43 pleax joined
06:44 haennar joined
06:45 insitu joined
06:45 hexagoxel joined
06:45 <Ptival> what indentation mode do emacs users use? I'm getting frustrated by the lack of support of standalone deriving in the one I have now
06:47 ramzifu joined
06:49 sjakobi left
06:50 jedws joined
06:50 <osa1> my indentation script just follows the line before on enter, it works great.
06:50 slomo joined
06:50 slomo joined
06:50 danvet joined
06:51 bts- joined
06:52 <Ptival> nvm, I found out https://github.com/haskell/haskell-mode/pull/1276 it was recently fixed
06:52 <cocreature> hrumph: I’m not aware of any library that provides this
06:53 ThomasLocke joined
06:54 indi_ joined
06:55 Natch joined
06:56 plutoniix joined
06:56 indi_ joined
06:56 takuan joined
06:57 mohsen_ joined
06:57 plutoniix joined
07:00 takle joined
07:02 RusAlex joined
07:07 Nerterologistx joined
07:08 linduxed joined
07:08 takle joined
07:10 xtreak joined
07:11 raichoo joined
07:12 mohsen_ joined
07:15 zcourts_ joined
07:16 _sg joined
07:19 bts- joined
07:19 zcourts joined
07:19 edsko joined
07:20 javjarfer joined
07:20 towerio joined
07:20 javjarfer2 joined
07:21 takle joined
07:21 FreeBirdLjj joined
07:23 laz joined
07:23 zcourts_ joined
07:24 oish joined
07:28 zcourts joined
07:29 zcourts__ joined
07:30 hexagoxel joined
07:30 haennar joined
07:31 takle joined
07:31 zcourt___ joined
07:32 SeMas joined
07:33 zcourts_ joined
07:33 bts- joined
07:34 freusque joined
07:35 zcourts joined
07:36 jhrcek joined
07:36 zcourts__ joined
07:37 danthemyth joined
07:37 TheEpsylon- joined
07:38 kritzcreek_ joined
07:41 cschneid_ joined
07:43 Jacoby6000__ joined
07:45 lak joined
07:45 orion joined
07:45 orion joined
07:45 biglama joined
07:46 nemorichard joined
07:47 bts- joined
07:47 hdeshev joined
07:47 dedicated joined
07:47 linduxed joined
07:48 tsahyt joined
07:49 mohsen_1 joined
07:49 <tsahyt> @hoogle (f a -> f b) -> f (m a) -> f (m b)
07:49 <lambdabot> Data.Tuple.HT mapFst3 :: (a -> d) -> (a, b, c) -> (d, b, c)
07:49 <lambdabot> Data.Tuple.Lazy mapFst3 :: (a -> d) -> (a, b, c) -> (d, b, c)
07:49 <lambdabot> Data.Tuple.Strict mapFst3 :: (a -> d) -> (a, b, c) -> (d, b, c)
07:49 yoneda joined
07:50 ublubu joined
07:50 CurryWurst joined
07:52 CurryWurst joined
07:52 <c_wraith> tsahyt: Can do it if both f and m are Traversable - not sure about anything weaker.
07:52 otulp joined
07:53 alfredo joined
07:53 takle joined
07:53 <tsahyt> m is IO, f is not traversable in practice. there is an instance but it's not feasible to even have it because of computational constraints
07:54 <tsahyt> maybe I can write a function that does it in that special case though
07:54 Kreest__ joined
07:55 zuck007 joined
07:55 free_beard joined
07:57 koneko joined
07:59 koneko_ joined
08:00 bts- joined
08:01 takle joined
08:02 coot joined
08:02 mmn80 joined
08:04 zuck007__ joined
08:05 Beetny joined
08:07 raichoo joined
08:07 <zuck007__> DROP zuck007
08:07 jutaro joined
08:08 <zuck007__> wtf is this
08:08 <zuck007__> how do i logout from annonyms login session and regain my username
08:08 calincru joined
08:10 <mauke> you can log into your account from any nick
08:10 albertid joined
08:10 <zuck007__> ok
08:10 <mauke> /msg nickserv identify zuck007 yourpasswordhere
08:11 <zuck007__> i haven't set a password yet
08:11 <mauke> wait, do you even have an account?
08:11 <zuck007__> nope
08:11 raichoo1 joined
08:11 humboldt joined
08:12 <zuck007__> i just login from website and chose a username thatsit
08:12 Mortomes|Work joined
08:12 <mauke> then you'll have to wait until the other connection goes away by itself
08:12 <zuck007__> ok i need to read some docs on irc
08:12 <zuck007__> its my first time :)
08:12 mattyw joined
08:13 <mauke> traditional IRC doesn't have accounts/passwords at all :-)
08:13 <mauke> here's something on freenode: http://freenode.net/kb/answer/registration
08:14 Jacoby6000__ joined
08:14 bts- joined
08:14 <zuck007__> thanks @mauke
08:14 LordBrain joined
08:15 <mauke> another thing. on IRC we generally don't use the @ thing to refer to names
08:15 <mauke> clients normally just highlight any line that contains your nick, especially at the beginning of a line
08:15 <mauke> zuck007__: like this
08:15 <tsahyt> @hoogle (f a -> f b) -> m (f (m a) -> f (m b))
08:15 <lambdabot> Data.List.Split.Internals build :: ((a -> [a] -> [a]) -> [a] -> [a]) -> [a]
08:15 <lambdabot> Data.Tuple.HT mapPair :: (a -> c, b -> d) -> (a, b) -> (c, d)
08:15 <lambdabot> Data.Tuple.Lazy mapPair :: (a -> c, b -> d) -> (a, b) -> (c, d)
08:16 <tsahyt> that's not helpful either then
08:16 <mauke> ^ and that's the problem with @nick: lambdabot interprets every line starting with @ as a command
08:16 Iskarlar joined
08:16 <tsahyt> @does it fail silently?
08:16 <lambdabot> it fail silently? not available
08:17 <tsahyt> or was I just unlucky there
08:17 <mauke> @ajsdkflaskdjfks
08:17 <lambdabot> Unknown command, try @list
08:17 <mauke> bonus feature: lambdabot tries to autocorrect typos in command names
08:18 rcsole joined
08:18 <tsahyt> @hgoole (a -> b) -> f a -> f b
08:18 <lambdabot> Maybe you meant: hoogle google
08:18 <tsahyt> nice
08:19 <mauke> @quate
08:19 <lambdabot> Ezla says: Why does Haskell need so many thunks?
08:20 bruschkov joined
08:20 bruschkov joined
08:21 Gurkenglas joined
08:21 zeroed joined
08:21 zeroed joined
08:22 <tsahyt> under what circumstances can I get f a -> f b -> f (a -> b)?
08:22 <tsahyt> umm with parens
08:22 <tsahyt> (f a -> f b) -> f (a -> b)
08:22 <tsahyt> there
08:23 <tsahyt> no that's not useful either. welp, seems like I'm stuck
08:23 zuck007 left
08:24 Jacoby6000__ joined
08:24 jajvpy joined
08:25 TxmszLou joined
08:25 armyriad joined
08:26 louispan joined
08:26 guiben joined
08:27 bts- joined
08:31 Kuros` joined
08:31 <phadej> tsahyt: IIRC (a -> m b) -> m (a -> b) is stronger requirement than "Monad"
08:31 wto joined
08:32 orion joined
08:32 orion joined
08:32 <tsahyt> phadej: it seems so. at least in my case it requires "time travel" in both directions
08:32 takle joined
08:33 ljhms joined
08:33 <tsahyt> but I figured out that I can limit the scope of those time travelling things cleverly and produce functions of the required type anyhow
08:33 andyhuzhill joined
08:34 <tsahyt> and limiting the scope of computation is something that's going on in DSP all the time anyhow, so I already have those functions around to lift computations on buffers to my waves types
08:34 humboldt joined
08:35 thc202 joined
08:36 bjz joined
08:37 armyriad joined
08:38 djellemah joined
08:38 zero_byte joined
08:38 JanBessai joined
08:38 fbergmann joined
08:39 <phadej> strong monad is the one you an do (a, m b) -> m (a, b); but I have no idea what's the term for exponentiation: (,) is product, (->) is exponent
08:39 bruschkov joined
08:39 fbergmann joined
08:40 eklavya joined
08:40 <phadej> at least if you belive http://comonad.com/reader/2008/deriving-strength-from-laziness/ has terminology right
08:40 razi1 joined
08:41 fbergmann joined
08:41 bts- joined
08:42 eklavya joined
08:42 towerio joined
08:43 fizbin joined
08:46 <tsahyt> phadej: thanks, I'll add this to my reading list
08:46 lak joined
08:47 pleax joined
08:47 pellenation joined
08:47 luxii joined
08:48 oisdk joined
08:52 connrs joined
08:52 srbaker_ joined
08:55 bts- joined
08:56 Iskarlar joined
08:56 Natch joined
08:56 sigmundv joined
08:57 louispan joined
08:59 srbaker_ joined
09:00 zuck007 joined
09:01 maninalift joined
09:01 marfoldi joined
09:02 pavonia joined
09:02 digitalmentat joined
09:04 hexagoxel joined
09:06 <tsahyt> are there any kind of accepted naming conventions for specializing f a -> f b to f ~= Identity?
09:07 systadmin joined
09:07 takle joined
09:07 <tsahyt> e.g. I have some function returning f a -> f b, and for convenience I think it'd be nice to have a specialized version that just returns a -> b. the types are of course determined by the other parameters, so it's not fully polymorphic
09:08 zuck007 left
09:09 bts- joined
09:10 freusque joined
09:11 Uakh joined
09:11 takle joined
09:11 nemorichard joined
09:12 zuck007 joined
09:14 mhagemeister joined
09:15 bts- joined
09:17 <Cale> :t ala Identity
09:17 <lambdabot> Functor f => ((b -> Identity b) -> f (Identity b1)) -> f b1
09:18 <tsahyt> where is ala from?
09:19 <Cale> Newtype
09:19 <Cale> https://hackage.haskell.org/package/newtype-0.2/docs/Control-Newtype.html
09:19 koneko joined
09:19 <Cale> :t under Identity
09:19 <lambdabot> error:
09:19 <lambdabot> • Couldn't match type ‘Identity
09:19 <lambdabot> (Control.Lens.Internal.Iso.Exchange a b a (Identity b))’
09:19 <Cale> hm
09:20 <Cale> Though I would say just make the specialised function
09:20 <Gurkenglas> tsahyt, see evalState vs evalStateT etc
09:21 pickle_ joined
09:21 humboldt joined
09:21 <Cale> ohh
09:21 <Cale> :t ala
09:22 <lambdabot> (Rewrapped t s, Rewrapped s t, Functor f) => (Unwrapped s -> s) -> ((Unwrapped t -> t) -> f s) -> f (Unwrapped s)
09:22 <Cale> Right, it's lens' ala
09:22 <Cale> :t under
09:22 <lambdabot> AnIso s t a b -> (t -> s) -> b -> a
09:22 whaletechno joined
09:22 <Cale> :)
09:22 pickle__ joined
09:22 <Gurkenglas> Though it's kinda sad that the shorter type gets the shorter name, because here it feels like evalStateT would pop out first if you derived Haskell platonically optimally
09:22 augur joined
09:26 FullyFunctional joined
09:26 <zuck007> can anybody recommend some cool projects idea for haskell beginner
09:30 eacameron joined
09:30 zuck007 left
09:31 piyush-kurur joined
09:32 djellemah_ joined
09:33 tolt joined
09:34 sujeet joined
09:34 zuck007 joined
09:35 tomphp joined
09:36 Rodenbach joined
09:36 <suppi> maybe something here at the bottom? http://gilmi.xyz/post/2015/02/25/after-lyah
09:36 jaspervdj joined
09:37 <suppi> oh, left.
09:37 jgertm joined
09:38 dramforever joined
09:38 Koterpillar joined
09:39 raichoo joined
09:39 ub joined
09:39 merijn joined
09:40 bruschkov joined
09:40 mekeor joined
09:41 anler joined
09:42 haennar joined
09:44 halogenandtoast joined
09:45 howdoi joined
09:46 danza joined
09:46 lak joined
09:49 xtreak joined
09:50 pleax joined
09:51 takle joined
09:51 Faucelme joined
09:51 skeuomorf joined
09:55 JagaJaga joined
09:58 cfricke joined
10:00 mjs2600 joined
10:00 bruschkov joined
10:00 Iskarlar joined
10:02 beanbagula joined
10:03 rcat joined
10:04 takle joined
10:09 kstuart joined
10:10 Jacoby6000__ joined
10:10 systadmin joined
10:11 humboldt joined
10:12 merijn joined
10:15 systadmin joined
10:15 fre joined
10:18 xall joined
10:19 psychicist__ joined
10:20 jutaro joined
10:20 marfoldi joined
10:20 Polarina joined
10:21 t7 joined
10:21 Wizek joined
10:21 Wizek_ joined
10:23 oisdk_ joined
10:23 humboldt joined
10:24 hexagoxel joined
10:26 FullyFunctional left
10:31 insitu joined
10:31 Levex joined
10:38 tapirus joined
10:38 djellemah_ joined
10:39 jutaro joined
10:41 fendoer joined
10:42 jutaro joined
10:42 oisdk joined
10:42 mjs2600 joined
10:42 bjz_ joined
10:43 dramforever joined
10:47 oisdk joined
10:48 lak joined
10:48 dtornabene joined
10:51 gregman_ joined
10:51 Detrumi joined
10:52 bollu joined
10:53 Gurkenglas joined
10:54 chronull- joined
10:57 insitu joined
10:57 srbaker_ joined
10:59 oisdk joined
11:00 cogrendel joined
11:00 tiny_test joined
11:01 osa1 joined
11:01 osa1 joined
11:02 humboldt_ joined
11:05 descender joined
11:06 Lord_of_Life joined
11:06 dhil joined
11:07 netheranthem joined
11:09 mda1 joined
11:09 mohsen_ joined
11:10 mrbackend joined
11:11 Hudini joined
11:11 <Hudini> Is Haskell difficult?
11:12 <merijn> Hudini: "It Depends" (TM)
11:12 <Hudini> Many programmers complain that Haskell is like an ocean and is difficult
11:12 <mauke> is a string long?
11:12 <Hudini> mauke, string can be long and short
11:13 <merijn> Hudini: So, my honest assessment is: 1) Haskell is VERY different from what most programmers are used to. 2) Haskell has a rather elaborate and advanced ecosystem
11:13 <merijn> Hudini: and 3) a lot of this ecosystem is designed for "easing advanced usage", rather than "make starting easy"
11:14 <merijn> Hudini: This means, that Haskell, for many people, feels like starting from scratch. You think "writing a program that does X should be easy!", but it feels very hard, because you need to learn a lot of basics
11:15 <merijn> Hudini: Secondly, since a lot of libraries in the ecosystem are more concerned with being "correct/complete" than "easy" to use.
11:15 <merijn> Hudini: Now, does this mean Haskell is hard? Maybe. It took me a long time to get "real world" productive with Haskell
11:16 <mohsen_> merijn: What do you mea by a library that is correct?
11:16 uglyfigurine joined
11:17 <Hudini> merijn, why should I learn it? What is normally haskell used for
11:17 <merijn> Hudini: On the upside: I now feel almost every task is easier for me to do in Haskell than without Haskell. Problems that I wouldn't dare tackle without Haskell seem easy now
11:18 <Hudini> merijn, what is Haskell used for? Scientific computing?
11:18 <brynser_> I started learning Haskell ~15 months ago and can do "real world" stuff but I'd consider myself late beginner. I use it for general programming tasks, like one might use Python or Java.
11:19 <mauke> Hudini: IRC bots, websites/web apps, compilers, version control, scripting boring tasks
11:19 <merijn> mohsen_: I mean that most popular libraries are rather pedantic about enforcing correctness/errors, which often means "getting a first prototype" is often a lot more hassle, than say, in python
11:20 xtreak joined
11:20 _sg joined
11:20 <merijn> mohsen_: You know how in python you can get the first 80% of what you want in almost no time? And then you want to make things robust and then the last 20% requires like 20 times more work than the first 80% did?
11:20 <merijn> (Or replace python with: ruby, JS, whatever)
11:22 <Rembane> One interesting aspect of Haskell is that it is a research language, and research has a tendency to trickle down into popular libraries which makes things interesting.
11:22 <Hudini> merijn. Okay. I actually would like to learn it, what book is suited for people who are beginner in programmer?
11:22 <suppi> Hudini: may I ask what interested you into coming here and ask about Haskell?
11:23 <suppi> it might help us understand how to describe Haskell to you better :)
11:23 <mauke> as a beginning programmer you have a bit of an advantage because you don't have to unlearn habits from other languages
11:23 niko joined
11:23 <suppi> also www.haskellbook.com for your question :)
11:24 jomg joined
11:24 KarboniteKream joined
11:25 jutaro joined
11:25 <brynser_> I learned it using the haskellbook.com book. Although it says "Early access", it's pretty much finished, just no initial release yet.
11:25 <brynser_> official* not initial
11:25 rcsole joined
11:26 <mohsen_> I started with lyah, and not finished yet
11:28 alanb99 joined
11:28 HanlonsRazor joined
11:28 petermw joined
11:29 <Hudini> Isn't function just something like this: func (x) { print x }
11:29 <dramforever> Hudini: Surprisingly, no
11:30 <Rembane> Hudini: f x = print x
11:31 <Rembane> Hudini: Haskell is superterse. :)
11:31 <dramforever> In Haskell, a function doesn't 'do' something like 'print'.
11:31 <dramforever> (pun not intended)
11:31 <dramforever> It's more like a mathematical function that specify a relationship between the result and the arguments
11:31 <dramforever> 'f x y = a + b' means 'the result is the sum of the two arguments'
11:32 djellemah_ joined
11:33 jmg8766 joined
11:33 <bollu> what is the "wildest" example of profunctor
11:34 <mauke> that would be either f x y = x + y or f a b = a + b
11:34 <mauke> or f = (+)
11:34 <bollu> the weirdest functor when you start out is (->), right? till it's normalised. Similarly, what's something that stretches profunctor to the extreme?
11:34 <bollu> I'm trying to build up a good intuition for them
11:34 <dramforever> Oh damn
11:34 <dramforever> I can't variable
11:34 <dramforever> mauke: Thank you
11:35 <mauke> you're not very able :-D
11:35 Hudini left
11:35 kaeluka joined
11:35 mkoenig joined
11:35 <dramforever> :(
11:36 bruschkov joined
11:37 alanb99 left
11:37 bollu1 joined
11:37 vektorweg1 joined
11:38 hexagoxel joined
11:39 <fendoer> > foldr (*) 0 [1..5] :: Expr
11:39 <lambdabot> 1 * (2 * (3 * (4 * (5 * 0))))
11:40 zcourts joined
11:40 bjz joined
11:40 danthemyth joined
11:45 phaji joined
11:47 fnurglewitz joined
11:47 <lep_> :i Expr
11:48 k0001 joined
11:48 mmn80 joined
11:48 psychicist__ joined
11:48 petermw joined
11:51 <fendoer> lep_, he doesn't unterstand :i
11:52 <lep_> @src Expr
11:52 <lambdabot> Source not found. Take a stress pill and think things over.
11:53 <lep_> i was mostly interested if Expr was defined in some base package
11:53 Denth joined
11:53 <MarcelineVQ> it's from http://hackage.haskell.org/package/simple-reflect iirc
11:54 bruschkov joined
11:54 <lep_> ic
11:54 aglorei joined
11:54 bruschkov joined
11:55 _sras_ joined
11:55 athan joined
11:56 koneko joined
11:56 Mortomes|Work joined
11:56 xanadu_ joined
11:56 <_sras_> I am trying to use hdevtools. For a project that builds successfully, I get a missing instance error when I try to check one of the source files using `hdevtools --check` command
11:56 mlehmk joined
11:56 <_sras_> http://lpaste.net/353094
11:57 carlomagno joined
11:57 <_sras_> The missing instances are supposed to be generated by template haskell.
11:59 <_sras_> Also, if you see the error. The error message says that the available instances match the missing instance.
12:01 Boomerang joined
12:01 mattyw joined
12:01 buglebudabey joined
12:02 Snircle joined
12:02 mohsen_ joined
12:04 bruschkov joined
12:07 jeltsch joined
12:07 jmg8766 joined
12:12 bennofs joined
12:12 shookees joined
12:12 shookees joined
12:16 makrusak joined
12:16 Sose joined
12:17 sarkin joined
12:17 Kreest_ joined
12:17 mohsen_ joined
12:17 makrusak left
12:19 modlin joined
12:19 ramzifu joined
12:21 merijn joined
12:22 descender joined
12:24 doodlehaus joined
12:24 drdo joined
12:24 silver joined
12:29 haennar joined
12:30 dramforever joined
12:30 Jacoby6000__ joined
12:31 asthasr joined
12:33 moongazer joined
12:37 alanb99 joined
12:37 stianhj joined
12:39 twanvl joined
12:40 pleax joined
12:41 tomphp joined
12:41 drdo joined
12:43 oisdk joined
12:43 fenedoer joined
12:44 systadmin joined
12:44 Lord_of_Life joined
12:45 bruschkov joined
12:45 jmg8766 joined
12:45 lukaramu joined
12:46 bruschkov joined
12:46 sdothum joined
12:46 acowley_away joined
12:46 drdo joined
12:47 bruschkov joined
12:47 shayan_ joined
12:47 robkennedy joined
12:48 bollu joined
12:49 robertkennedy joined
12:54 pleax joined
12:56 pickle_ joined
12:57 koneko joined
12:58 OnkelTem joined
12:58 kthnnlg joined
12:59 danthemyth joined
13:00 ramzifu joined
13:00 Shatnerz0 joined
13:01 doodlehaus joined
13:03 connrs joined
13:05 jomg joined
13:07 nate_ joined
13:07 lithie joined
13:08 byte[]1 joined
13:09 schjetne joined
13:09 <nate_> Is there a convenient way to encode symmetric data types, whose constructors are coupled to each other?
13:09 <nate_> E.g., data Inner = Inner1 A | Inner2 B | ... | Inner100 Z; data Outer = Outer1 Inner1 Foo | Outer2 Inner2 Bar | ... | Outer100 Inner100 Quux
13:09 marr joined
13:10 govg joined
13:10 buglebudabey joined
13:10 LordBrain joined
13:11 <nate_> duplicating the definitions of Inner in Outer seems fragile, just using Inner is fragile, since OuterN requires InnerN in perfect correspondance.
13:11 anzuof joined
13:12 Jacoby6000__ joined
13:12 <nate_> Breaking Inner into 100 individual datatypes Inner1 through Inner100 and then having a sum type Inner over them all is tedious boilerplate.
13:12 <nate_> Is there an obvious solution to this that I'm not seeing?
13:14 cschneid_ joined
13:16 alanb99 left
13:17 <merijn> nate_: Why exactly do you have a 100 different constructors to begin with?
13:17 <merijn> That seems highly suspicious
13:18 danza joined
13:18 <nate_> I don't, it's just arbitrarily large.
13:18 justanotheruser joined
13:18 <nate_> I have 10 or maybe 20, but maybe it will change, I dunno.
13:18 <merijn> 10 or 20 already sounds like a lot. Can you tell us what you're doing?
13:18 dramforever joined
13:19 <nate_> Abstract Syntax Tree :^/
13:19 markfaction joined
13:19 <merijn> ok, then 10 sounds more reasonable. Why exactly do you have two separate types depending on each other, though?
13:19 <merijn> i.e. what are Inner and Outer representing
13:19 markfaction left
13:20 <nate_> Two different syntactic forms of the AST
13:20 ramzifu joined
13:21 KarboniteKream joined
13:21 <merijn> ?
13:21 revprez_atlanta joined
13:21 jmg8766 joined
13:21 <nate_> One of the forms has extra information, but the extra info is unique to each AST node type
13:22 <merijn> nate_: Why not have a single form and have "Maybe Annotation" on every constructor?
13:23 arianvp2_ joined
13:23 mojjo joined
13:23 <nate_> Ah, good question! Because the annotated form can only occur in certain places, and I want to be able to forbid it where it cannot occur.
13:23 <merijn> nate_: Extra parameter to your AST?
13:23 Lord_of_Life joined
13:24 <nate_> Otherwise, everything that consumes it will either have to be a partial function or throw an error or something gross
13:24 <nate_> So, like data AST a = ...?
13:24 <merijn> "data AST f a = MyNode Foo Bar (f Annotation)" and then use "AST Identity" for parts where you *can* have an annotation and "data Forget a = Forget" and "AST Forget" where you can't have annotations?
13:26 <nate_> I do that elsewhere where it's a bit more uniform, I guess I hadn't considered that for this case. It's an interesting suggestion.
13:26 PennyNeko joined
13:26 sevensor joined
13:27 <nate_> That's a bit of a Maybe at the type level, no? A little cleaner, but it would hypothetically let you parameterize it over some arbitrary f that could make no sense.
13:28 descender joined
13:28 <merijn> nate_: Yes, but you can stop that by simply not exporting the "AST" type directly
13:28 <merijn> nate_: "type AnnotatedAST = AST Identity; type UnannotatedAST = AST Forget" and then only export those two
13:28 javjarfer1 joined
13:28 dfeuer joined
13:29 <nate_> Granted.
13:29 <nate_> Alright, you've convinced me! That's a good idea, at least until I'm convinced there's a better one :^)
13:31 <merijn> nate_: I'm not sure it's the most elegant solution, but it's the first thing that I can think of that avoids painful duplication :)
13:31 wei2912 joined
13:31 <nate_> merijn: By the way, I come to this channel once every few weeks with a question, and this is probably the 5th or 6th time you've helped me; if it is not too personal to ask, do you program Haskell for a living?
13:32 fenedoer joined
13:32 <merijn> I use Haskell a lot and at work, but mostly for quick scripts not the main code
13:32 <MarcelineVQ> merijn doesn't program at all, he's from the future and his cover is that of a working programmer
13:32 lukaramu_ joined
13:33 <nate_> Escaping to the past from the dystopic nightmare of a post P=NP world?
13:34 <merijn> Mostly because my main code is GPU code written in C++, so Haskell is not really suitable for that. And lots of Python plotting scripts that, as a lot of people can attest due to my complaining, I regret not writing in Haskell :p
13:34 <merijn> Honestly, rewriting most of my python to Haskell is currently a high priority task :p
13:34 <MarcelineVQ> "nanobots grey-goo'd far-future earf, the only escape was the past, her format guardian, to mend and defend..."
13:34 halogenandtoast joined
13:34 mjs2600 joined
13:35 <nate_> That's a riot, as I just rewrote a matlab visualization tool into matplotlib...
13:35 <merijn> nate_: I used matplotlib, because "chart (haskell library) doesn't quite have all I want yet, this'll save time!" <- should've just fixed Chart
13:36 harfangk joined
13:36 <merijn> Then I used scikit-learn (machine learning library), because "I'm already using python and writing something from scratch and reinventing the wheel is inefficient" <- should've just reinvented the wheel
13:36 <merijn> Everyone else's wheel are shitty >.>
13:37 <nate_> Well, their languages are dirty. so :^P
13:37 yezariaely joined
13:37 lak joined
13:38 biglama joined
13:38 greeny joined
13:40 <merijn> Honestly, my day to day coding is a polyglot mess :p
13:41 <nate_> Eh, could be worse. My philosophy is the more languages you know, the better you can think about problems in any language. Until you get to pure math, then everything else feels like it's for peasants. Which makes it hard to go back to C++. But then you remember you like food, and not dying.
13:42 animated joined
13:42 bennofs joined
13:43 <dramforever> merijn: That moment when you realize that 'saving time in the short run' does not make sense :(
13:44 <merijn> dramforever: I was hoping to save time in the long run
13:44 sellout- joined
13:44 <merijn> dramforever: Because "these libraries are widely used, that must mean people are making them not suck"
13:45 <dramforever> Oh noooooo waaaaaay
13:45 <dramforever> That sucks even more
13:45 <nate_> Try being someone thinking of the long run and working in consumer products. Everyone has the memory of a mayfly. The long run is fiction.
13:49 mojjo joined
13:50 freechips joined
13:52 razi1 joined
13:55 steeze joined
13:56 KarboniteKream joined
13:56 Robin_Jadoul joined
13:56 shong joined
13:56 jomg joined
13:57 mada joined
13:57 Tene joined
13:57 Tene joined
13:57 hpc joined
13:59 mattyw joined
14:01 greeny joined
14:02 eschnett joined
14:02 doomlord joined
14:04 bennofs joined
14:04 Catalect` joined
14:05 <Boomerang> In Data.Map there are functions like lookupLT, how should I go about making a more general one where I can supply a custom compare function: lookupBy :: k -> (k -> k -> Ordering) -> Map k v -> Maybe (k, v)
14:06 zcourts_ joined
14:07 P1RATEZ joined
14:07 jeltsch joined
14:08 <merijn> Boomerang: You can't, really. Map always use the compare supplied by Ord
14:08 <mauke> that seems a bit pointless
14:08 <merijn> Boomerang: Since Map has to use the same comparison while constructing as it does while doing lookups
14:08 <Boomerang> Well I have a map with keys of type (Int, Int) and I want to easy compare on fst or snd depending on the situation
14:09 <Boomerang> *Map
14:09 <Boomerang> *easily
14:09 <merijn> Boomerang: There's no efficient way to do that using a single Map
14:09 KarboniteKream joined
14:09 <merijn> Because there's no efficient way that lookup could be implemented
14:10 modlin joined
14:10 nilof_ joined
14:11 halogenandtoast joined
14:11 <Boomerang> That makes sense, maybe a Map isn't an adequate data stucture for my purposes. Thanks for your inputs!
14:12 wlemuel joined
14:12 kubunto joined
14:12 bruschkov joined
14:13 Levex joined
14:13 <kubunto> I am trying to remove extra spaces in my program but I cant seem to figure it out
14:13 <kubunto> source: http://lpaste.net/353096
14:13 rgc joined
14:13 <kubunto> output: ("time" ("party" 43 35 67 ) 72 )
14:13 zcourts joined
14:14 <kubunto> i dont want space between 67 and the ) as well as between 72 and )
14:15 mekeor joined
14:15 zcourts__ joined
14:16 <Detrumi> kubunto: That's because the pattern match a:b also matches if b is the empty list
14:17 <kubunto> Detrumi: just thought of that
14:17 <kubunto> i made a case a:[] before a:b to cover
14:17 mounty joined
14:18 doodlehaus joined
14:18 <kubunto> Detrumi: is there a guard i can put in beyond just a better match for this case?
14:19 <kubunto> so i could order it however i want to
14:19 al-damiri joined
14:19 rgc joined
14:20 hydraz joined
14:20 mizu_no_oto_work joined
14:21 hydraz joined
14:21 <hexagoxel> kubunto: a:b@(_:_)
14:21 <kubunto> hexagoxel: that would check if the tail list has at least one element?
14:23 vmffkn joined
14:23 <kubunto> hexagoxel: so I would read that as a:b such that b has at least one element
14:24 <hexagoxel> kubunto: yes
14:25 cpennington joined
14:25 <kubunto> what else could the @ have in it
14:26 <hexagoxel> without underscores and better names, it is like first:tail@(second:tailtail)
14:26 <Detrumi> The @ just gives a name to a pattern
14:26 <kubunto> could i do i@(<5)?
14:26 JanBessai joined
14:27 <Detrumi> I'd just go for 3 pattern matches: [a], a:b and [], it's simple to keep them in order
14:27 dsh joined
14:27 newbie1 joined
14:27 <mauke> kubunto: the syntax is IDENTIFIER '@' PATTERN
14:27 <mauke> (<5) is not a valid pattern
14:29 ystael joined
14:31 randomclown joined
14:32 hits1911 joined
14:36 alx741 joined
14:37 <zipper> I'm having trouble converting a bytes into MB/KB because it returns some scientific notation thing :(
14:37 <zipper> I mean result
14:37 mizu_no_oto_work joined
14:37 <zipper> > 67824/1024^3
14:37 <lambdabot> 6.316602230072021e-5
14:37 <zipper> Yeah so how can I get an actual Double?
14:37 <kubunto> Detrumi: hexagoxel is my match exaughstive?
14:38 danthemyth joined
14:38 <Detrumi> kubunto: You mean the first:tail@(second:tailtail) match?
14:39 <kubunto> Detrumi: meaning the empty list case
14:39 <dramforever> > printf "%f" (67824/1024^3)
14:39 <lambdabot> error:
14:39 <lambdabot> • Ambiguous type variable ‘a0’ arising from a use of ‘show_M855349794792...
14:39 <lambdabot> prevents the constraint ‘(Show a0)’ from being solved.
14:39 <dramforever> > printf "%f" (67824/1024^3 :: Double)
14:39 <lambdabot> error:
14:39 <lambdabot> • Ambiguous type variable ‘a0’ arising from a use of ‘show_M395477717473...
14:39 <lambdabot> prevents the constraint ‘(Show a0)’ from being solved.
14:39 insitu joined
14:39 <dramforever> Screw you printf
14:40 mdarse joined
14:40 <mauke> > printf "%f" (67824/1024^3) :: String
14:40 <lambdabot> "0.00006316602230072021"
14:40 mojjo joined
14:40 <dramforever> Yes that
14:40 <dramforever> I admit that I didn't really read the error message...
14:40 mdarse joined
14:41 <zipper> mauke: Thanks
14:41 <MarcelineVQ> if you're working from bytes consider using integrals, in which case you'd use div instead of /
14:41 popsu joined
14:41 <dramforever> zipper: You likely want like 2 decimal places or something
14:41 <dramforever> > printf "%.2f" (67824/1024^3) :: String
14:41 <lambdabot> mueval-core: Time limit exceeded
14:41 <lambdabot> mueval: ExitFailure 1
14:41 <mauke> :t showFFloat
14:41 zcourts joined
14:41 <lambdabot> RealFloat a => Maybe Int -> a -> ShowS
14:41 <Detrumi> kubunto: I'm not sure what you're asking
14:41 <dramforever> That's not how it works, lambdabot
14:41 <zipper> dramforever: That's exactly what I wanted thank you :)
14:41 <dramforever> > printf "%.2f" (67824/1024^3) :: String
14:41 <lambdabot> "0.00"
14:41 <mauke> > showFFloat Nothing (67824/1024^3) ""
14:42 <lambdabot> "0.00006316602230072021"
14:42 <dramforever> Docs is your friend :)
14:42 <mauke> > showFFloat (Just 4) (67824/1024^3) ""
14:42 <lambdabot> "0.0001"
14:42 gawen joined
14:42 <dramforever> Even better, never knew that
14:42 cpennington joined
14:42 <kubunto> Detrumi: i think it wouldnt work if i gave sentence a node of Node "h" []
14:42 Levex joined
14:42 <dramforever> I'm thinking, #haskell is a bit like bittorrent
14:42 <robertkennedy> :i showFFloat
14:43 <mauke> there is no :i in lambdabot
14:43 zcourts_ joined
14:43 <robertkennedy> Darn. What module is that in?
14:43 marvin2 joined
14:43 <zipper> hmmm `showFFloat` seems great
14:43 <MarcelineVQ> Numeric
14:43 <mauke> @hoogle showFFloat
14:43 <Detrumi> kubunto: Yeah, you'll need at least 3 cases if you do it this way
14:43 <lambdabot> Numeric showFFloat :: (RealFloat a) => Maybe Int -> a -> ShowS
14:43 <lambdabot> Numeric showFFloatAlt :: (RealFloat a) => Maybe Int -> a -> ShowS
14:43 <lambdabot> Numeric.Compat showFFloatAlt :: RealFloat a => Maybe Int -> a -> ShowS
14:44 zcourt___ joined
14:44 ChristopherBurg joined
14:44 <dramforever> :t intersperse
14:44 <lambdabot> a -> [a] -> [a]
14:44 <mauke> :t intercalate
14:44 <lambdabot> [a] -> [[a]] -> [a]
14:45 <dramforever> damn
14:45 michael1 joined
14:45 <dramforever> I'm losing my Haskell skills faster than I can imagine
14:45 <MarcelineVQ> there's an option more straight-forward than intercalate as well
14:46 jutaro joined
14:46 cyphase joined
14:46 <MarcelineVQ> assuming you're working on kubunto's problem :>
14:46 <dramforever> Yeah I guess
14:46 <kubunto> Detrumi: i am getting a new error now from compilation
14:46 <robertkennedy> :t typeRep
14:46 <lambdabot> forall k (proxy :: k -> *) (a :: k). Typeable a => proxy a -> TypeRep
14:47 <dramforever> no space after 'show a', space before every 'subnode'
14:47 <robertkennedy> > typeRep (Just showFFloat)
14:47 <lambdabot> Maybe Int -> Double -> [Char] -> [Char]
14:47 msrkmo joined
14:48 <kubunto> doesnt like dealing with g as an argument to a sentence: http://lpaste.net/353097
14:48 hits1911 left
14:50 bruschkov joined
14:51 Rodya_ joined
14:51 zcourts joined
14:53 <robertkennedy> Is 'Left the same as `data HLeft` at the type level (with DataKinds)
14:54 coot joined
14:54 <robertkennedy> I mean in the case where I have defined and used HLeft, can I refactor to use 'Left?
14:59 Swizec joined
15:00 e14 joined
15:02 twomix joined
15:04 `^_^v joined
15:07 <kubunto> quite wierd
15:07 danielsmw joined
15:08 leshow joined
15:09 k_p__ joined
15:09 <kubunto> can anyone explain why i am getting an ambiguous type error in one case but when i run it standalone in ghci it works just fine?
15:09 fendor joined
15:09 <Tuplanolla> The monomorphism restriction is probably at it again, kubunto.
15:10 bruschkov joined
15:10 <kubunto> Tuplanolla: the whositwhatnow?
15:10 <mauke> @where dmr
15:10 <lambdabot> http://www.haskell.org/haskellwiki/Monomorphism_restriction
15:10 <Tuplanolla> Start your file with `{-# LANGUAGE NoMonomorphismRestriction #-}` and see if it helps, kubunto.
15:10 <Tuplanolla> If it does, read more about it there.
15:10 <merijn> No, don't do that >.<
15:11 <merijn> Disabling monomorphismrestriction is a dumb "default" reaction
15:11 <merijn> But reading that wiki page is a good idea
15:11 <Tuplanolla> Why? I always turn it off.
15:11 <merijn> Tuplanolla: What do you prefer? Compile time warnings or hard to debug silent performance degradation?
15:12 <Tuplanolla> I've never seen such a problem.
15:12 <merijn> Tuplanolla: Because if your answer is "the former", then disabling monomorphism restriction is changing your default to the latter
15:13 <Tuplanolla> All of the counterexamples I've seen have been silly.
15:13 handyc joined
15:13 <* hexagoxel> has seen silent performance degradation in one non-silly case. but i'd have to dig really much to find the code..
15:14 <merijn> It's always silly counterexamples, until one day it isn't
15:14 Catalect` left
15:14 osa1 joined
15:14 <Tuplanolla> I'll worry about the extension when it happens then.
15:14 <merijn> And then you waste two hours or more debugging an issue that wouldn't have happened if you didn't disable it. Especially since there's a trivial way to get rid of monomorphism issues without disabling it
15:15 <Tuplanolla> It's more common that there's a missing `!` somewhere.
15:15 <danielsmw> Is there a clear theoretical reason why you might expect performance degredation? I don't know much about what the monomorphism restriction is really giving you.
15:15 hvr joined
15:15 hvr joined
15:15 Levex joined
15:16 <merijn> danielsmw: Right, so let's say we have "foo = map expensiveComputation [0..]"
15:16 <merijn> danielsmw: Normally if you have an expensive top level computation you'd only expect it to be computed once, right?
15:16 Iskarlar joined
15:16 <danielsmw> Sure.
15:16 RyanGlScott joined
15:16 eacameron joined
15:17 <kubunto> merijn: if i understand it correctly, the moment i make a data structure of type graph string int, that the next time i create a new graph of string ? it will be annoyed
15:17 <merijn> Since you're just lazily building the result. But if we have a typeclass polymorphic result, like "foo :: Num a => [a]" we have a bit of a problem
15:18 <kubunto> merijn: graph is defined as Graph o p
15:18 <merijn> danielsmw: Now, what happens if I first use "foo" as "[Double]" and later as "[Int]", both are legal, based on "Num a => [a]", yes?
15:18 <danielsmw> merijn: those are both legal, yes
15:18 coltfred joined
15:18 <Tuplanolla> I don't see this as a problem, merijn. If you request two results with different types, you can expect two different computations.
15:18 <merijn> danielsmw: Now, clearly I have to compute it once in each case
15:18 <merijn> Tuplanolla: It's worse than that!
15:18 <danielsmw> merijn: sure
15:19 <lyxia> Tuplanolla: but if you require it twice with the same type it's not clear that it will be run only once.
15:19 <dramforever> Tuplanolla: Even if I request twice with the same type, it's going to recompute
15:19 <merijn> In other words, GHC can't really memoise the result, since it doesn't know which different types you are going to use
15:19 <Tuplanolla> I see.
15:19 <merijn> So even if you use it as [Int] 10 times, you recompute it all of those times
15:20 <merijn> The only other solution is to store one copy of foo per type, but if you only use it once for 10 different types that ends up wasting a ton of memory for no reason
15:20 <Tuplanolla> That's a bit annoying, but I'm not bothered.
15:20 <danielsmw> merijn: does the specialize pragma relieve this issue for particular types?
15:20 <merijn> For functions that's usually not an issue, but for values it's kinda annoying
15:20 <danielsmw> ah
15:21 <merijn> The logic being, if it's a non-function you're probably expecting it to be memoized
15:21 <dramforever> I used to do NoMonomorphismRestriction. But then I learned to write all top-level signatures, and I've never found myself needing that again
15:21 <kubunto> dramforever: toplevel sigs?
15:21 <merijn> danielsmw: So the solution chosen in the report is to say that any top-level polymorphic non-function gets monomorphised
15:21 <Rembane> I used to be a NoMonomorphismRestriction like you, but then I took a top-level signature to the knee.
15:22 <Tuplanolla> If it ever does become a problem, I'll just turn the extension off when the module is finished.
15:22 hvr joined
15:22 hvr joined
15:22 <merijn> danielsmw: So if I have "foo :: Num a => [a]" and GHC sees you use it as '[Int]' GHC simply goes 'welp...I'm just gonna assume this is *always* Int so I can have the memoised behaviour you expect of things that are not typeclass polymorphic"
15:22 robkennedy joined
15:23 <dramforever> kubunto: I don't think this will solve your problem in that code
15:23 <merijn> danielsmw: The result is: If you have a top level non-function that you only use with 1 type it "Just Works" (efficiently!). If you use it with 2 different types you get a compile error (easy to detect!)
15:23 <kubunto> dramforever: i know why the problem is there
15:24 <kubunto> cant figure out the second generic type
15:24 <merijn> danielsmw: The other solution would be, to assume it's polymorphic and always recompute. But if you're not thinking of that you get expensive recomputation at runtime (tricky to detect!)
15:24 <merijn> danielsmw: And when writing the standard "loud compile errors" were deemed preferable to silent bad performance
15:24 CoconutCrab joined
15:24 <* dramforever> is confused
15:25 _sg joined
15:25 <merijn> danielsmw: Of course, it's trivial to get rid of the error if you DO want it to be polymorphic, which is: write an explicit type signature. GHC only monomorphises top-level, non-function values without a type
15:25 <hexagoxel> Tuplanolla: i'll paraphrase my case: In some part of a synthesizer i needed silence as a default case. So i had a local let zeroVec = SV.sample 96000 (const 0.0). Due to NMMR, this had some non-monomorphic type (Fractional t => SV.Vector t), and it created a new vector for each use of that binding, even though it only ever needed Vector Floats.
15:25 <merijn> danielsmw: But that way you're at least forced to conciously decide "this should be recomputed all the time"
15:25 Levex joined
15:26 <kubunto> dramforever: my initial issue was because the compiler couldnt figure out what hte second type was for Graph op when all it had to go on was Node String
15:26 <kubunto> graph o p*
15:26 <dramforever> Oh there's a second issue?
15:27 <kubunto> dramforever: nah, that is just what started this
15:28 <danielsmw> merijn: I see.
15:29 pasukon joined
15:29 <danielsmw> merijn: So actually, I've /always/ written top level sigs, and the only time GHC has suggested NMRestriction to me is when I've used certain external libraries.
15:29 dramforever left
15:29 dramforever joined
15:29 cdg joined
15:29 <dramforever> Wait a sec
15:29 <danielsmw> But you're saying that when I have top level polymorphic functions, they're not going to be memoized?
15:29 <dramforever> That's not because of MonomorphismRestriction right?
15:29 <dramforever> That's ExtendedDefaultRules
15:30 pleax joined
15:30 <Tuplanolla> It helps to mentally treat `=>` like `->` when reasoning about performance.
15:30 <dramforever> If you start ghci with -Wall it tells you it defaulted the type of g to Graph String ()
15:30 <merijn> danielsmw: memoised isn't really the right term, but anyway. For functions it's not really relevant, since everytime you pass in a new argument you have to compute the result from scratch anyway
15:31 zcourts_ joined
15:31 <merijn> danielsmw: If you always write top level sigs the ambiguity where NMR kicks in is never there, because you're always explicitly telling GHC what you're expecting
15:31 <dramforever> wait a sec...
15:31 cdg joined
15:31 <danielsmw> merijn: Ah, okay, sure. So it really only does matter if I have constant valued top level computations, which I want to be polymorphic. Which does sort of seem edge-casey, but I can imagine it happening.
15:32 ccomb joined
15:32 <danielsmw> (in practice)
15:32 <dramforever> Enabling NoMonomorphismRestriction *does not* solve kubunto's problem
15:32 <dramforever> ExtendedDefaultRules *does*
15:32 zcourts__ joined
15:32 <merijn> danielsmw: Well, if you generate, e.g., a top-level vector of 10,000 entries, you'd probably want it to only be computed once :)
15:33 <danielsmw> merijn: Indeed :) thanks!
15:33 oisdk joined
15:33 <merijn> danielsmw: And it doesn't happen a lot, sure. It's just that *when* it does it probably results in hair pulling debugging if you let it happen silently :p
15:33 wlemuel joined
15:34 emin joined
15:34 <Cale> If apparent constants are *type class* polymorphic, then they won't be memoised, because they're secretly functions (of the type class dictionary), and the results of functions are never retained on their own (to do so automatically would basically mean giving up on garbage collecting anything ever)
15:34 <kubunto> merijn: this extended defaults thing looks right
15:34 cpennington joined
15:34 <kubunto> dramforever: is that ignored in standard ghci?
15:35 simukis__ joined
15:36 chlong joined
15:36 Levex joined
15:36 elperdut joined
15:36 <dramforever> It's turned on by default in GHCi
15:36 <dramforever> You can :set -XNoExtendedDefaultRules
15:37 <dramforever> Quick check: 'print []' changes from 'works' to 'doesn't work'
15:37 <kubunto> how would i specify a type for the generics in my definition?
15:38 <kubunto> data Num d => Graph d o = Leaf d | Node o [Graph d o] deriving (Show)
15:38 <kubunto> ignoring the num d part
15:38 zcourts joined
15:38 <dramforever> kubunto: You don't
15:38 <dramforever> because you don't need to
15:39 <delYsid> How do I write a parser combinator that works like many, but only counts occurances?
15:39 ludat joined
15:39 <Tuplanolla> You `fmap length`, delYsid?
15:39 <delYsid> the efficient version of length <$> many p
15:40 <dramforever> kubunto: You want to use -Wall
15:40 <delYsid> Tuplanolla: Yeah, thats the obvious version, but I'd like to avoid the consing.
15:40 <kubunto> dramforever: as long as ther is a leaf in the graph, it is good
15:40 <lyxia> delYsid: take the definition of many and inline length <$> into it
15:40 <kubunto> no leaf -> no compilation
15:40 <dramforever> As you can see GHC defaults your types beyond what you would like
15:41 <dramforever> This is a hint: add more signatures
15:41 <lyxia> delYsid: aren't you optimizing prematurely
15:42 jnj joined
15:42 <delYsid> lyxia: no :-)
15:42 <kubunto> dramforever: how would i specify in place of the generics in my definition
15:42 <dramforever> specify what?
15:42 <kubunto> int and char
15:42 <kubunto> int and char
15:42 <kubunto> or rather [char]
15:43 oisdk joined
15:43 <dramforever> That's not 'generics' any more
15:43 wraithm joined
15:43 sepp2k joined
15:43 <fbergmann> q
15:43 <jnj> Is something like this possible: class X a where { someThing :: a -> b } (so a type class with a single function someThing returns an unknown type 'b')
15:43 <kubunto> dramforever: i know
15:43 <kubunto> i want to know how to make it non generic
15:44 <dramforever> You want to specify the types of a through g?
15:44 <dramforever> a :: Graph Int String
15:44 <Cale> jnj: That would mean that someThing would produce a value of any result you wanted it to, which pretty much means that it has to fail.
15:45 <Cale> (by throwing an exception or running forever, as that's the only kind of thing which could be of an arbitrary type)
15:45 CurryWurst joined
15:45 <lpaste_> dramforever pasted “kubunto please see this” at http://lpaste.net/353103
15:45 <Cale> any result type* you wanted it to
15:46 eklavya joined
15:46 eklavya joined
15:46 mrkgnao joined
15:47 <dramforever> jnj: That's how 'unknown type' works
15:47 <lyxia> delYsid: count p = fmap (+1) (p *> count p) <|> return 0
15:47 <dramforever> Crap
15:47 gcross joined
15:47 <Cale> jnj: If you wanted it to mean "There exists some type b for which someThing produces a result of type b, but you can't know which", that's even less useful, because you could never ever use such a result (since you don't know what type it is, you'll never be able to inspect it)
15:47 <dramforever> That's *not* how 'unknown type' works
15:47 <jnj> Cale: I guess the error is confusing me a little: http://lpaste.net/353102 but i'll try and wrap my head around it
15:47 <Cale> You could do that with an existential type, but not a useful existential type.
15:47 <jnj> I don't see why that paste does not typecheck
15:48 <Cale> jnj: Because that function clearly produces a String
15:48 <Cale> Not a value of type b
15:48 <Cale> What if I want it to produce an Integer for me?
15:48 <Cale> I'm allowed to specify that b is Integer when I use the something function.
15:49 <jnj> I was expecting Haskell to infer that b == string I suppose, but I can see the problem in that
15:49 <* kubunto> is curious about these types im seing in ghci
15:49 <jnj> Can I have "something" return a type class?
15:50 <kubunto> what does this mean: Graph [Char] [Char] compared to (Num d, Num o) => Graph d o
15:50 groscoe joined
15:50 <Cale> Well, functions at the value level have to produce values. Type classes are type-level things, and are only around at compile time.
15:51 Polarina joined
15:51 <Cale> What are you trying to do?
15:51 <dramforever> jnj: The *caller* gets to choose what 'b' is
15:51 <Cale> Yeah, this would be clearer if all type variables were explicitly quantified
15:51 <dramforever> It means that I can call 'something', and *choose* b
15:52 oisdk joined
15:52 <dramforever> kinda like an argument
15:52 <Cale> You'd have class X a where something :: forall b. a -> b
15:52 Rodya_ joined
15:52 <Cale> Maybe what you're looking for is a class associated type
15:52 <jnj> That's producing the same error, I tried it but am not strong in forall.
15:52 <Cale> class X a where
15:52 <Cale> type XResult a
15:53 <Cale> something :: a -> XResult a
15:53 <Cale> instance X Int where
15:53 <Cale> type XResult Int = String
15:53 chlong joined
15:53 <Cale> something = const "hello world!"
15:53 malt3 joined
15:53 <dramforever> jnj: It's *very* unclear about what you're trying to achieve
15:53 <dramforever> Can you like explain further?
15:53 <Cale> jnj: That's because it's equivalent to what you wrote
15:54 uglyfigurine joined
15:54 <glguy> jnj: you don't get to pick what b is when you're defining your function. the users of your function get to pick it, so you have to be ready for any choice the user makes, you can't guess string
15:54 <Cale> jnj: It's just (hopefully) clearer that the type of something says that it should work for all types b
15:54 avn joined
15:55 <Cale> jnj: Haskell automatically sticks foralls in at the top level of type signatures to bind the type variables which occur free in them.
15:55 zcourts_ joined
15:55 <Cale> e.g. when we write map :: (a -> b) -> [a] -> [b]
15:55 <dramforever> We're getting to far away from jnj I think
15:55 <Cale> it really means map :: forall a b. (a -> b) -> [a] -> [b]
15:56 <Cale> i.e. whatever map does, it must work for all choices of types a and b
15:56 Guest70562 joined
15:57 <Cale> The way it accomplishes that is by not inspecting any values of type a or b, so that it's just passing the (pointers to) values around.
15:57 rgr joined
15:58 <jnj> this is what i wrote down, don't know if that makes sense
15:58 <jnj> http://lpaste.net/353105
15:58 <jnj> (which does not compile)
15:58 Polarina joined
15:59 <Cale> Well, the type of getCell is highly suspicious
16:00 <Cale> You probably want either a multiparameter type class with a functional dependency, or you want an associated type
16:00 <Cale> (or you don't want a type class at all)
16:00 <Cale> Also, the Monad constraint is weird
16:01 <delYsid> lyxia: ahh, nice, thanks!
16:01 xall joined
16:01 <Cale> There's very little you could do to create an action in an arbitrary monad apart from applying return, so it doesn't make much sense to bother with that
16:01 <Cale> class Row e a | a -> e where getCell :: a -> Int -> Maybe e
16:01 <Cale> makes more sense
16:02 <Cale> instance Row a (SimpleRow a) where ...
16:02 cdg joined
16:02 <jnj> I was thinking that some instances of Row might require getCell to run in for example the IO monad
16:03 <Cale> Yeah, but you haven't said that
16:03 <jnj> anyways, I'll rethink the entire thing anyways, as it's not the right way
16:03 <Cale> You said it works in *any* monad
16:03 <jnj> Oh
16:03 <Cale> So you're not required to use it in IO at all, you could use it in the list monad, or Maybe.
16:03 <dramforever> jnj: You got the type variable thing completely wrong
16:04 <kubunto> dramforever: i got how to escape the issue with an empty list
16:04 <Cale> We could also parameterise the class by a choice of monad
16:04 <kubunto> let k = Node "fitness" [] :: Num a => Graph a [Char]
16:04 <dramforever> When I have an expression e, and it is of type 'forall a. something something'
16:04 <Cale> and have that depend on the row type as well
16:04 Noldorin joined
16:04 <Cale> class Row m e a | a -> m e where
16:04 <dramforever> Then when I use 'e', *I* get to choose what 'a' is
16:04 <Cale> getCell :: a -> Int -> m (Maybe e)
16:05 <Cale> The "| a -> m e" means that the choice of a uniquely determines m and e
16:05 Luke joined
16:05 <dramforever> You know C++ templates or Java generics? It's a tiny bit like those
16:05 <Cale> The compiler will prevent you from writing more than one instance for any given type a
16:05 <Cale> but in exchange, it will infer m and e whenever it knows a
16:05 <Cale> (by looking for which instance applies)
16:06 <Cale> You can do some pretty fancy type level computation with this.
16:06 <jnj> I'll look into your suggestions, for now I need to read.. Thanks for your help
16:06 <Cale> Equivalently, using the newer TypeFamilies extension you could write:
16:07 <Cale> class Row a where
16:07 raichoo joined
16:07 <Cale> type RowM a :: * -> *
16:07 <Cale> type RowElement a
16:07 <Cale> getCell :: a -> Int -> RowM (Maybe (RowElement a))
16:08 <Cale> and then when you write the instance, you get to specify what those type synonyms expand to, when applied to the particular type a
16:09 <jnj> that might work, thanks
16:09 pheaver_ joined
16:09 <merijn> Any persistent users who can tell me whether I can have "compound" fields in my entities? i.e. I have a datatype "data Foo = Foo Int Int Int" and another thing that has "data Bar = Bar Foo Foo Foo", can I somehow represent that in persistent easily? i.e. I just want a flat row with 9 Int in my resulting database, but on the haskell side have 9 direct Int fields is annoying compared to nesting like that
16:09 mkoenig joined
16:10 <Cale> merijn: I know it's possible with groundhog, so I would be surprised if persistent didn't also do it
16:11 <merijn> Cale: I would expect something like that to be possible, but I haven't found a way yet
16:11 raichoo joined
16:12 <Cale> Wow, persistent's documentation actually manages to suck more than groundhog's
16:12 <merijn> Cale: Word :p
16:13 <merijn> Honestly, the Yesod way with lots of MPTC mtl constraints leads me to understand the complaint about unscrutable Haskell documentation >.>
16:13 Itkovian joined
16:14 <merijn> Cale: I hadn't heard of groundhog before. Would you recommend it?
16:14 mda1 joined
16:14 <Cale> Well, it's terrible, but we're using it, so that's something.
16:15 <merijn> Cale: ah...
16:15 <Cale> It's less terrible than many of the alternatives
16:15 b4ff3r joined
16:15 <merijn> That doesn't sound like a ringing endorsement for being better than persistent
16:15 <Cale> But looking at these entity definitions from persistent, it seems groundhog does a way better job of letting you specify how things are mapped to the DB
16:16 <Cale> even if you have to write a weird yaml syntax and it silently ignores anything it doesn't understand
16:16 cschneid_ joined
16:17 <merijn> Cale: yeah, but on the other hand I already figured out persistent now and I'm not tied to a schema anyway
16:17 BlueRavenGT joined
16:17 <merijn> So investing similar time into something else which is, at best, only marginally better seems a waste
16:18 kuribas joined
16:18 <Cale> https://hackage.haskell.org/package/groundhog-th-0.8/docs/Database-Groundhog-TH.html
16:18 <Cale> -- documentation by example
16:19 doux joined
16:19 mkoenig joined
16:19 <Cale> The main reason we use groundhog at this point is to get some automatic migrations (it's not bad at doing all the really easy ones), and to get a little extra type safety for the very simplest queries we need to do
16:20 <Cale> We end up using postgresql-simple to do a lot of queries, because groundhog (like persistent) doesn't support joins
16:20 <Cale> (they're compatible)
16:21 MersenneInteger joined
16:21 steeze joined
16:21 <Cale> If you've used persistent, using groundhog is usually the same -- it was actually forked from persistent somewhere along the way
16:21 <Cale> But the template haskell shenanigans seems to be quite different
16:22 Luke joined
16:23 <merijn> Cale: Basically, what I mostly need is SQLite and preferably a conduit/pipes interface to query results
16:23 <Cale> https://github.com/lykahb/groundhog/blob/master/examples/basic.hs
16:23 revtintin joined
16:23 <kuribas> Does using mutable state improve performance? (using STRefs for example)
16:24 <merijn> kuribas: "it depends"
16:24 boombanana joined
16:24 <merijn> Cale: honestly, I don't think I really need joins atm
16:25 <merijn> Cale: Also, doesn't esqueleto provide joins for persistent?
16:25 <kuribas> I am amazed how much writing haskell code in a low level way can improve performance.
16:26 <kuribas> haskell is not very cache friendly.
16:26 <brynser_> I think persistent would end up storing your Bar value as a single varchar, the contents being 'show <Bar>'. At least that's what happened when I tried storing a product data type
16:26 <merijn> kuribas: That's the same in any language, knowing what you're doing is crucial for performance
16:26 <merijn> brynser_: That's for sum datatypes, yes
16:26 <kuribas> merijn: sure
16:26 <Cale> merijn: Yeah -- I have no idea how complete it is, but it claims to do so.
16:26 <merijn> brynser_: But I just have a simple product datatype, and storing as varchar is utterly unacceptable for my usecase
16:26 <MersenneInteger> Should Haskell be my first foray into functional programming or should I learn Scheme first and work my way up to Haskell?
16:27 <merijn> Cale: I remember a presentation at Dutch FP day on esqueleto, it seemed reasonably complete
16:27 <Cale> MersenneInteger: I'd say go for Haskell directly.
16:27 <merijn> MersenneInteger: tbh, I don't think learning Scheme first will really help much
16:27 <kuribas> merijn: I don't think it matters, except for inner loops...
16:27 gienah joined
16:27 <kuribas> MersenneInteger: scheme is great, but it is rather different from haskell.
16:27 Luke joined
16:27 <brynser_> merijn: Oh right, not sure then, I've only done e.g. "data Foo = Bar Int | Baz Text | ..."
16:29 <Cale> If you were going to go for any lisp, I would say some scheme variation is probably the best to try to do functional programming in. Common lisp is quite annoying -- I've tried to program in a functional style in it, and you're basically swimming upstream.
16:29 <kuribas> MersenneInteger: scheme is strict, dynamic typed, and uses Lispy syntax.
16:29 <Cale> But no pattern matching is sort of... barely functional programming.
16:30 <MersenneInteger> Thanks for the answers, Ive never programmed in a functional language before so I didnt know where I should start. I considered reading SICP because I wasnt sure where to start. Where is a good (book) place to start with Haskell? Sorry for the noob questions.
16:30 <Cale> SICP is really good, yes
16:31 <merijn> Cale: oh, maybe I can get it to work by writing a PersistEntity class by hand
16:31 sujeet joined
16:31 <Tuplanolla> Scheme is certainly less daunting to start with, MersenneInteger.
16:31 <Cale> We don't really have anything nearly as good as that specifically for Haskell, but Graham Hutton's "Programming in Haskell" is good.
16:31 nycs joined
16:31 <Cale> If you're looking for something freely available to start off with...
16:32 <Cale> http://www.cis.upenn.edu/~cis194/spring13/
16:32 <kuribas> MersenneInteger: SICP is great, but it isn't really about scheme, it's more about programming paradigms.
16:32 <Cale> contains a bunch of lecture notes and exercises which many people have found useful
16:32 <Cale> Yeah, reading SICP / watching the SICP lectures is a lot of fun once you know a bit of Haskell too
16:33 <Cale> Because you get to see how many of the things they talked about there have been formalised into Haskell.
16:34 _Mzungu_ joined
16:34 <Cale> (Things which were merely conventions have gotten language support)
16:34 frostbit joined
16:34 doux left
16:34 <frostbit> Hey
16:34 <Cale> hello!
16:34 <frostbit> can you tell me what <+> does?
16:34 <merijn> Cale: hmm, maybe not, apparently the recommend solution "hand write a conversion from persistent entiy to your own datatype" :\
16:35 <Cale> frostbit: Probably if you can tell me which library it comes from
16:35 <frostbit> I saw it in xmonad
16:35 <frostbit> I thought it was part of standard package
16:35 <frostbit> And I hadn't read it
16:35 <frostbit> so that's why tho confusion
16:36 <Cale> ah, it's infix mappend
16:36 <suppi> MersenneInteger: www.haskellbook.com is quite good from what i read. i also like this course to get familiar with fp: https://www.coursera.org/learn/programming-languages
16:36 <Cale> But specifically, in xmonad, it's used to compose together ManageHooks
16:36 <suppi> it's standard ml but the ideas you learn there transfer to other languages like haskell, ocaml, elm, etc
16:37 <frostbit> Oh right
16:37 doodlehaus joined
16:37 <frostbit> I feel like a knobhead now
16:37 sgflt joined
16:38 <merijn> bleh, this is annoying. So I can either get decent mapping of datatype to database with groundhog, or keep the ability to add/switch to esqueleto if I need joins with persistent, but not both :\
16:38 <merijn> And groundhog apparently can't stream results either
16:38 <Cale> The result of a ManageHook is an Endo WindowSet, which is just a wrapper around a function WindowSet -> WindowSet, and it basically composes those functions together.
16:38 <Cale> merijn: Everything is terrible
16:39 <frostbit> Got it thanks
16:39 <Cale> merijn: It's one of the biggest scary things to tackle on our horizon
16:39 <frostbit> \part
16:39 frostbit left
16:39 <merijn> Cale: honestly, since I probably don't need joins I'd be fine switching to groundhog, but the lack of streaming results kinda kills me :(
16:40 <merijn> Cale: I don't wanna get lists for queries with hundreds of thousands or more results
16:41 <Cale> Yeah, we just stick LIMIT on most things
16:42 Itkovian_ joined
16:42 Swizec_ joined
16:42 <merijn> Cale: That doesn't work very well if you actually plan to use all those results ;)
16:42 <Cale> (If we ever have to deal with more than a handful of results at a time, something is wrong with our architecture anyway, due to the nature of our applications.)
16:42 doodlehaus joined
16:43 <merijn> Right now I have all my data in...plain text files, that I munge in memory before feeding it to my code, which is killing my performance now that I've 10x increased my dataset :p
16:43 <merijn> So it's one of the main reasons to wanna dump everything in an SQLite database
16:44 <merijn> Right, so persistent + ugly manual data conversion it is, for now
16:45 clmg joined
16:45 <clmg> How do I use Control.Lens.Plated?
16:46 shinX joined
16:46 monadicDuck joined
16:46 <Cale> merijn: I don't know whether you're looking to scale up to using a full database server at some point, but given that description I'd be tempted just to switch to using something like binary or attoparsec (and pipes?)
16:46 <c_wraith> clmg, are you asking about making a type compatible with it, or using its combinators to achieve a particular goal?
16:47 <merijn> Cale: No, these are just benchmark results I'm analysing/plotting
16:47 raynold joined
16:47 <clmg> c_wraith: I'm asking about what to write in the `instance Plated Foo where`
16:47 <merijn> Cale: It's just that my dataset has grown to the point where trivial scripts start to become to slow
16:47 Itkovian joined
16:47 <clmg> I need some `plate =` but I can't find any examples of how to implement Plated
16:48 <merijn> Cale: But that's not a workload that really demands a dedicated server. Especially since having all benchmark results in an SQLite file is nicely portable
16:48 <clmg> c_wraith: the structure is `Split = Split { left :: Maybe Split, right :: maybe Split }`
16:48 <clmg> I need to traverse these splits without simply deriving data.
16:49 e14 joined
16:49 <merijn> Cale: 'cause right now I have 50k text files of results, which would be a lot nicer as a single SQLite db :p And I do want to do some filtering/preprocessing in what datapoints I consider, so a straight up attoparsec+pipes thing seems a bit inconvenient
16:49 <Cale> clmg: Well, one option is just to add deriving (Data), and then write "instance Plated Split"
16:49 Luke joined
16:49 <clmg> Cale: but I'll want to add more fields to split soon. like a filepath
16:49 <clmg> Cale: can I have filepath derive data also?
16:50 <c_wraith> clmg, deriving Data is the easiest, but it's not too bad manually. you just write a traversal that returns its direct children.
16:50 <Cale> Does it not already?
16:50 <clmg> Cale nope
16:50 <Cale> ah, fair enough
16:50 <Cale> well, you can just write the traversal directly
16:50 JanBessai joined
16:50 <clmg> Cale: any examples other than the cryptic one on hackage?
16:51 <Cale> https://hackage.haskell.org/package/lens-4.15.1/docs/src/Control.Lens.Plated.html#Plated
16:51 urodna joined
16:51 <Cale> not as many good examples as I'd have hoped
16:51 <Cale> But the one for lists sort of gives the idea
16:52 <c_wraith> clmg, it's just a Traversal. if you work from the type, it's pretty obvious what it has to do.
16:52 tommd joined
16:53 <clmg> c_wraith: okay so it's traversing a list. (x:xs) is obvious. [] is obvious. What is f?
16:53 <Cale> type Traversal s t a b = forall f. Applicative f => (a -> f b) -> s -> f t
16:53 <Cale> and here, s, t, a, b are all your type
16:54 <c_wraith> f is whatever function is passed in. it's opaque. don't worry about what it *is*, just use it.
16:54 <Cale> So you want to write something of type Applicative f => (Split -> f Split) -> Split -> f Split
16:54 sternmull joined
16:55 <clmg> I think I'm in over my head a bit
16:55 <clmg> thanks guys
16:55 <leshow> i thought traverse's type was (a -> f b) -> t a -> f (t b)
16:55 <c_wraith> clmg, as an alternative, if Split has lenses for left and right, you can build the traversal out of combinators.
16:56 <lyxia> leshow: the idea is that Split is isomorphic to t Split for some t.
16:56 tabaqui1 joined
16:56 <c_wraith> leshow, Traversal is a generalization of that
16:57 <c_wraith> clmg, plate = leftLens . _Just <> rightness . _Just
16:58 wraithm joined
16:58 hackebeilchen joined
16:58 tsmish joined
16:58 <c_wraith> clmg, though in all honesty, that's more complicated than just writing it by hand.
16:58 <Cale> plate f (Split l r) = Split <$> traverse f l <*> traverse f r
16:58 alexknvl joined
16:58 <Cale> ^^ easier
16:58 <clmg> Cale: awesome this is really really helpful
16:59 danthemy_ joined
17:00 <c_wraith> as I said, writing it directly is a lot easier. :)
17:00 pleax joined
17:00 psychicist__ joined
17:01 skeet70 joined
17:01 <clmg> what if I want to add more fields to that record. where do that factor into the plate?
17:01 whaletechno joined
17:02 <ertes> :t \f (x, y) = (,) <$> f x <*> f y
17:02 <lambdabot> error:
17:02 <lambdabot> parse error on input ‘=’
17:02 <lambdabot> Perhaps you need a 'let' in a 'do' block?
17:02 <ertes> :t \f (x, y) -> (,) <$> f x <*> f y
17:02 joe9 joined
17:02 <lambdabot> Applicative f => (t -> f a) -> (t, t) -> f (a, a)
17:02 <c_wraith> clmg, just add them to the pattern match. unless they are also recursive, they don't need to be used in the body of plate
17:02 <ertes> clmg: ^ a traversal for both components of a tuple
17:02 jaspervdj joined
17:03 <ertes> @let myBoth f (x, y) = (,) <$> f x <*> f y
17:03 <lambdabot> Defined.
17:03 <ertes> > (myBoth +~ 2) & (4, 7)
17:03 rekahsoft joined
17:03 <lambdabot> error:
17:03 <lambdabot> • Couldn't match expected type ‘((Integer, Integer)
17:03 <lambdabot> -> (Integer, Integer))
17:03 <Cale> you might end up replacing the use of the constructor on the left of the <$> with a lambda that replaces the unchanging fields
17:03 <c_wraith> clmg, wait, that's not true. they do need to be used to construct the result Spkit
17:03 <c_wraith> .. Split
17:03 wtetzner joined
17:03 <ertes> > (myBoth +~ 2) (4, 7)
17:03 <lambdabot> (6,9)
17:04 <Cale> e.g. plate f (Split l x r) = (\l' r' -> Split l' x r') <$> traverse f l <*> traverse f r
17:04 jmelesky joined
17:04 <c_wraith> clmg, basically, it's the only change you can make that still compiles
17:04 <ertes> > ("hello ", "world") ^. myBoth
17:04 <lambdabot> "hello world"
17:06 <clmg> c_wraith: that compiles
17:06 fendor joined
17:06 <clmg> c_wraith: great :)
17:06 <c_wraith> clmg, the compiler is your friend. it tells you what you need to do. it just speaks an odd dialect that takes a while to get used to :)
17:06 <Cale> Yeah, looking at the traversal for both elements of a pair that ertes showed ought to be instructive
17:07 <raynold> ahh it's a wonderful day
17:07 <clmg> thanks chan
17:08 dreco joined
17:08 conal joined
17:08 Uakh joined
17:08 <Cale> You can think of a traversal as separating a data structure into the part outside the elements being traversed, which gets encoded as a function of those elements, sort of like it's the original data structure with holes blown in it, and then each of the elements you're traversing, which have the arbitrary function applied to them and then everything gets combined together with the Applicative combinators
17:09 Luke joined
17:09 Sonolin joined
17:10 <Cale> (at least, this always works for the cases where there's only finitely many things you're traversing over)
17:10 <ertes> another interpretation: a traversal takes apart a structure, applies an effectful function to it, and then reassembles it into the same structure, but with the results
17:11 <ertes> myBoth f (x, y) {- here we take apart the tuple -} = (,) {- here we reassemble it -} <$> f x <*> f y -- after applying the effectful function to each component
17:12 <dolio> Cale: Works all the time. You just can't pretend it's a list for infinite cases.
17:12 jomg joined
17:12 <dolio> (Except infinite lists.)
17:13 <Cale> dolio: Well, you can't... have a function with infinitely many parameters
17:13 <Cale> But yeah
17:13 jutaro joined
17:13 eklavya joined
17:13 <ertes> with do-notation (e.g. -XApplicativeDo) it might be a bit clearer: myBoth f {- take apart: -} (x', y') = do {- apply effect for each component: -} x <- f x'; y <- f y'; {- reassemble: -} pure (x, y)
17:14 path[l] joined
17:14 xocolatl joined
17:15 Maxou joined
17:15 <joe9> any rainbox users, please? Did you install it with stack? https://hackage.haskell.org/package/rainbox
17:15 Noldorin joined
17:16 danharaj joined
17:16 simendsjo joined
17:17 zero_byte joined
17:17 jao joined
17:17 mekeor joined
17:17 Luke joined
17:18 Rodya_ joined
17:19 mstruebing joined
17:20 k_p__ joined
17:21 danielsmw joined
17:22 trism joined
17:22 sssilver joined
17:25 vlad` joined
17:26 vlad` left
17:28 JanBessai joined
17:28 Jacoby6000__ joined
17:28 sssilver joined
17:30 xall joined
17:31 connrs joined
17:31 jmg8766 joined
17:32 sarkin joined
17:32 logicmoo joined
17:34 <ski> Cale : hmm, reminds me of something i've been thinking about ..
17:35 Rizy joined
17:36 fresheyeball joined
17:37 chronull` joined
17:38 Denthir joined
17:39 hrehf joined
17:39 jathan joined
17:40 danielsmw joined
17:40 Foras joined
17:40 wraithm joined
17:40 lithie joined
17:40 zcourts joined
17:42 ludat joined
17:46 louispan joined
17:47 serendependy joined
17:47 danielsmw joined
17:48 greeny joined
17:48 dario` joined
17:48 Lord_of_Life joined
17:50 danielsm` joined
17:51 Krisostoomus joined
17:51 Krisostoomus left
17:51 zeroed joined
17:51 k_p__ joined
17:53 pdgwien joined
17:53 raichoo joined
17:53 ertesx joined
17:54 ner0x652 joined
17:55 zipper joined
17:55 zipper joined
17:56 byorgey joined
17:56 byorgey joined
17:56 afarmer joined
17:56 danielsm` joined
17:56 <Tuplanolla> Does `ResourceT` release in the reverse allocation order or some random order?
17:57 <Tuplanolla> It's not mentioned in the documentation.
17:57 <johnw> Tuplanolla: given that they could be inter-dependent, reverse is the only thing that makes sense to me
17:58 pleax_ joined
17:58 <Arguggi> I read https://tech.channable.com/posts/2017-02-24-how-we-secretly-introduced-haskell-and-got-away-with-it.html and I don't understand why "we cannot run runWorkerLoop and runFetchLoop with forkIO, because we don’t have the right transformer stack.". Why won't liftIO work?
17:59 <Forkk> Is it possible to run valgrind on C code called from Haskell?
17:59 <johnw> forkIO *wants* an IO action
17:59 <johnw> they could do it with monad-control
17:59 <Forkk> It seems to fail setting up function redirection
17:59 danthemyth joined
17:59 <johnw> which one can do easily by using lifted-async
17:59 <Unhammer> https://www.haskell.org/hoogle/?hoogle=forkliftio
17:59 <Unhammer> missed opportunity there
18:00 Wizek joined
18:00 Wizek_ joined
18:00 <sternmull> is there a trick to see the precedence inside expressions? When i look at complex expressions i often struggle to see what ends up in which operator/function. It would be helpful to visualize the syntax tree in some way.
18:00 fiddlerwoaroof joined
18:01 <Arguggi> johnw, aaaaaah I think I understand now
18:01 danielsm` joined
18:02 <ertes> sternmull: you can ask GHCi about the precedence of individual operators via :i
18:02 <ertes> like: :i (+)
18:03 <sternmull> ertes: Yes i know... but sometimes it would be nice if it could insert brackets into an expression or something like that.
18:03 <monochrom> Arguggi: You may be thinking "liftIO (forkIO xxx)" but the issue is "forkIO runWorkerLoop"
18:03 <Cale> sternmull: The most important thing to remember about precedence (and which isn't strictly speaking a precedence rule) is that function application always binds more tightly than any infix operator
18:04 <Cale> So, regardless of the precedence of *, f x y * g z will always be (f x y) * (g z)
18:04 <sternmull> at the moment i am looking at something like "(a b . c d) e" and wonder what to think of it.
18:05 zeroed joined
18:05 <mauke> ((a b) . (c d)) e
18:05 <Cale> That's the same as a b (c d e)
18:06 <sternmull> ok, thanks. But at that point i wondered what i will do when i encounter more exotic operators. After all they can be all get their custom precedence...
18:06 <Cale> So a b and c d are functions, they're being composed and then the composite is being applied to e
18:06 <Arguggi> monochrom yes I didn't think of that for some reason. You can "run" the action returning it to IO a and then fork that action right? (which seems to be what was suggesting in the comments unlift :: m r -> m (IO r) )
18:06 pdgwien joined
18:07 haldean joined
18:07 <Cale> sternmull: Somehow I practically never find myself needing to care about the actual precedence level of operators in Haskell
18:07 Swizec joined
18:07 <davean> I only care when reading edwardk's code
18:07 haldean left
18:07 <Cale> Yeah, it's possible to go overboard
18:07 <monochrom> Yes, but this means the new thread has nothing to do with the parent thread in terms of what the transformer stack wants to carry, usually.
18:08 <flxw> Hi all. Applicative on a tupple lets me do (x,f) <*> (y,a) ==> (x <> y, f a), in case x,y are from the same Monoid. I'm for awhile trying to get <*> working with Semigroup Last on the first component of the pair. Is that not possible? I mean, memtpy should not be needed for this, no?
18:08 <sternmull> Cale: Ok. This is more like a diffuse fear. I haven't written/read enough haskell to know if this is a problem in practice.
18:08 <Cale> But for the most part, things will be obvious from the types, in cases where the precedence matters at all
18:09 <sternmull> yes, type checks will probably catch many accidents.
18:09 coot joined
18:09 <monochrom> Basic example: If you use StateT Int IO, you can pretend you have a mutable variable. But once you start doing liftIO (forkIO (runStateT ...)), the new thread's "mutable variable" is now divorced from the parent thread's.
18:10 <mauke> they're not even on speaking terms
18:10 <monochrom> And even monad-control will not change this.
18:10 <ystael> Cale: honestly I think it would be a perfectly reasonable design to say "application has precedence +inf, $ has precedence -inf, everything else *must* be parenthesized" :)
18:10 <Arguggi> monochrom, ok thanks that clears everything up
18:11 <mauke> record update has precedence inf + 1
18:11 <kuribas> > (a b . c d) e
18:11 <lambdabot> error:
18:11 <lambdabot> • Couldn't match expected type ‘Expr -> b0 -> c’
18:11 <lambdabot> with actual type ‘Expr’
18:11 LordBrain joined
18:11 jmg8766 joined
18:12 <mauke> > let [a,b,c,d] = map fun ["a","b","c","d"] in (a b . c d) e
18:12 <lambdabot> error:
18:12 <lambdabot> • Could not deduce (Show b0) arising from a use of ‘a’
18:12 <lambdabot> from the context: FromExpr c
18:12 MersenneInteger left
18:12 k_p__ joined
18:13 <mauke> oh, I'm dumb
18:13 insitu joined
18:13 _Mzungu_ joined
18:13 yorick_ joined
18:14 ortmage joined
18:14 <byorgey> flxw: mempty is not needed for <*>, but it is needed for pure.
18:14 <mauke> > let [a,c :: Expr->Expr->Expr] = map fun ["a","c"] in (a b . c d) e
18:14 <lambdabot> a b (c d e)
18:15 <catern> hey #haskell, I've constructed a type (say, a Passenger) which only makes sense/is meaningful in the context of another type (say, a Vehicle). how should I express this in types? should I add a list of passengers to vehicle, add a reference to vehicle into passengers, or do something else entirely??
18:15 <kuribas> > (f x . g y) z :: Expr
18:15 <byorgey> flxw: you may be interested in http://hackage.haskell.org/package/semigroupoids-5.1/docs/Data-Functor-Apply.html
18:15 <lambdabot> error:
18:15 <lambdabot> • Ambiguous type variable ‘b0’ arising from a use of ‘f’
18:15 <lambdabot> prevents the constraint ‘(Show b0)’ from being solved.
18:15 <Cale> catern: One of the above?
18:15 <catern> Cale: but which one :(
18:15 fendor joined
18:16 <flxw> byorgey: Oh, thank you. Yes, pure needs mempty, because it must produce a value of type a out of thin air.
18:16 <byorgey> flxw: right
18:16 <Cale> catern: That really depends on what your program does
18:16 mrkgnao joined
18:17 <catern> but I want easy answers :(
18:18 <mauke> ask easy questions
18:18 <Cale> catern: Depending on the circumstances, you might also have some sort of identifiers or references to passengers or vehicles, and you'd be using those in the fields instead.
18:18 <catern> Cale: right! that's yet another alternative!
18:19 <kuribas> > (f x . (g y :: Expr -> Expr)) (z::Expr) :: Expr
18:19 <Cale> Also, instead of a list of passengers, it's quite possible that a Set is more appropriate
18:19 <lambdabot> f x (g y z)
18:19 <Cale> Or you might have a Map Vehicle (Set Passenger)
18:19 <catern> Cale: sure sure yeah that's not directly related though
18:19 <catern> (set vs list I mean)
18:20 <Cale> Well, it makes a difference, but maybe not the difference you're concerned about :)
18:20 <catern> indeed :)
18:20 k_p__ joined
18:20 <Cale> Or a Map Passenger Vehicle
18:20 path[l] joined
18:20 <Cale> Or a Map Passenger VehicleId
18:20 <Cale> heheh
18:21 <catern> I think VehicleId would be strictly worse
18:21 <catern> at least from an abstract programming language point of view
18:21 <catern> a VehicleId is only meaningful given a Map VehicleId Vehicle
18:21 <Cale> Well, think about the case that Vehicle simply describes the characteristics of the vehicle, but doesn't identify it uniquely
18:22 sssilver joined
18:22 <Cale> In that case, having a Map Passenger Vehicle doesn't allow you to determine that two people are in the same car
18:22 <Cale> Just that they're in the same sort of car
18:22 <Sonolin> well Vehicle could have an "id" field in that case, right?
18:22 <Cale> It could
18:22 <catern> oh, sure, sure, but I think it's definitely better to have an id field in Vehicle
18:22 <Cale> (probably you wouldn't call it id)
18:23 <Cale> ;)
18:23 <Sonolin> lol, yea
18:23 <Sonolin> silly non-haskell brain
18:23 <mbrock> naming types after real world object types is often confusing, in functional programming as well as object oriented programming...
18:23 wildlander joined
18:23 e14 joined
18:23 <mbrock> there are no vehicles inside your computer!
18:23 <catern> a good point
18:24 <byorgey> on the other hand, naming everything VehicleInformationEncoding is kind of confusing too =P
18:24 <Cale> It's best to have some idea what you're going to be doing with the data as you plan out the structures you're going to store it in
18:24 <catern> but, I'm not actually talking about vehicles and passengers, but rather something that exists only in my computer :)
18:24 wildlander joined
18:24 <catern> (Vehicles and Passengers in a game, say)
18:26 wildlander joined
18:26 <catern> Cale: I mean, I find myself frequently encountering the situation where I have a type (like Passenger or VehicleLookupKey) where the values are only meaningful when considered in a context which contains a value of another type (like Vehicle or Map VehicleLookupKey Vehicle)
18:26 wraithm joined
18:26 <catern> so I would like it to be true that there was some general purpose way to think about these cases :)
18:27 <catern> some type theory construct?
18:27 cyphase joined
18:27 wildlander joined
18:28 <dminuoso> Do you folks handwrite your actions creators and reducers for REST interaction? A single endpoint produced so much ugly boilerplate...
18:28 <dminuoso> Oh boy. Wrong channel. :|
18:29 <Younder> For what it's worth there is no toxonometry that works for every case. This was proved by Wittgenstein. The best you can do is use a user case, a universe of discource, to model the data.
18:29 cpup joined
18:29 mekeor joined
18:31 <ertes> catern: i find myself using an approach like this from time to time, depending on the application: data Vehicle passenger = Vehicle { …, _passenders :: [passenger], … }
18:31 replay joined
18:32 <ertes> when it's fresh out of the database, i have a (Vehicle (Key Passenger)), which i can 'traverse' into a (Vehicle Passenger) if necessary
18:33 zipper joined
18:35 <NemesisD> hi all. i remember there being an extension or feature in recent GHC that lifted constructors to the type level (canonical example of Nat). is there a similar thing for sum types, i.e. data X = A | B, lifting A and B into the type system as distinct types?
18:36 <NemesisD> i've got something like data ClearanceLevel = TopSecret | MailRoom and am trying to create a type-level annotation like MinimumClearance TopSecret
18:36 <catern> ertes: interesting notion, I kind of like that
18:36 <NemesisD> so i'd want to reflect the constructor on the type level to the constructor in the value level
18:37 <catern> ertes: I guess you would reverse this to have data Passenger vehicle, and (Passenger (Key Vehicle)) (Passenger Vehicle)
18:37 <catern> would/could
18:37 <catern> and then passenger would be meaningful on its own...
18:38 <NemesisD> i guess i'm looking for DataKinds
18:38 vlatkoB_ joined
18:38 <ertes> NemesisD: you might also be interested in the latest goodie: -XTypeInType
18:38 Denthir joined
18:39 <ertes> it completely collapses all levels above values into a single type level
18:39 connrs joined
18:39 djellemah_ joined
18:40 Axman6 joined
18:40 fre joined
18:40 Axman6 joined
18:40 <ertes> however, communication between value and type level is still manual and ad-hoc
18:41 <catern> it's okay, I suppose, to always pass Passengers around with also Vehicles. the thing that I want to prevent, I guess, is partnering a Passenger with the wrong Vehicle... I suppose I could just make a PassengerVehicle type
18:41 <ertes> there are two major approaches: reflection (a.k.a. implicit configurations) and singletons
18:41 Luke joined
18:41 <ertes> you probably need the latter, because the former does not support type-level functions
18:41 <flxw> byorgey: thank you for the semigroupoids url. After pondering about the types for a while, I learnt that <.> does the trick. :)
18:42 igore joined
18:42 fendor joined
18:43 fendor joined
18:43 jmelesky joined
18:44 igore left
18:45 JagaJaga joined
18:46 nomotif joined
18:46 zcourts joined
18:46 <NemesisD> ertes: so i've got data Clearance = TopSecret | None, data MinClearance (clearance :: Clearance) , is it actually possible to write reflectMinClearance :: MinClearance clearance -> Clearance ?
18:46 muesli4 joined
18:46 Rodya_ joined
18:47 kmelva joined
18:47 <kmelva> is ZuriHac free to attend?
18:47 <kmelva> looking at the site there's no mention of admission price...
18:48 <johnw> kmelva: I'm pretty sure it's a hackathon, open to all, rather than an admissions-based conference
18:48 <flxw> when a functor description says "lax monoidal functor", the lax is concerned with the monoid part, and saying that the monoid laws are not valid upto equality, but just upto natural isomorphisms. Do I get this right?
18:49 <johnw> (for example, Compose)
18:49 <kmelva> johnw: ah cool, I just figured it was a regular conference where you have to pay for admission... never thought about going because I figured it would be too expensive :/
18:49 <johnw> flxw: https://en.wikipedia.org/wiki/Monoidal_functor
18:50 <dolio> flxw: Sort of. But there's no "monoid" exactly.
18:50 <flxw> because it is a tensor product?
18:50 <dolio> It's about 'preservation' of monoidal category structure being directional.
18:50 <dolio> And not up to equality.
18:51 <dolio> And not even up to isomorphism, actually.
18:51 <flxw> okay, I'll read the hinted at url.
18:51 <flxw> I see. :)
18:51 zdenal joined
18:51 coltfred joined
18:53 <dolio> In general, I think 'lax' is used when you replace isomorphisms with transformations in one direction.
18:53 csaurus joined
18:53 <dolio> And there's also 'oplax' sometimes for things that replace isomorphisms with transformations in the opposite direction.
18:54 anton__ joined
18:54 kthnnlg joined
18:55 Wurhwuri748 joined
18:55 Berra joined
18:56 edsko joined
18:56 sssilver joined
18:58 ompaul joined
18:59 <Younder> an isomorpism is by nature in both directions
18:59 raichoo joined
18:59 <Younder> You might also call it a bijective transform
19:00 <Younder> or on to one and onto. The three are equivalent
19:00 HugoDaniel joined
19:01 cdg_ joined
19:01 prophile joined
19:02 pantsman_ joined
19:02 <Younder> simulary you have a monmorphic transform which could also be called a projection
19:03 fendor joined
19:03 sssilver joined
19:04 <Younder> Perhaps 'Introduction to Lattices and Order' by Davey and Priestley can help
19:04 Apocalisp joined
19:05 edsko joined
19:05 <Tuplanolla> Help whom, Younder?
19:05 Vivek joined
19:06 wraithm joined
19:07 stoopkid joined
19:07 <Younder> Well when I was first introduced to Haskell I was overwhelmed by number of mathematical terms. So I found that my education lacked a few pointers. That book helped me understand the terminology and the frame of mind of a Haskeller better
19:08 fractalsea joined
19:11 connrs joined
19:14 srbaker_ joined
19:15 snowalpaca joined
19:16 twanvl joined
19:17 newbie joined
19:18 acarrico joined
19:19 djellemah joined
19:20 bruschkov joined
19:20 ompaul joined
19:20 <ertes> NemesisD: what should that function do?
19:21 <NemesisD> ertes: i found a workable solution, i wanted reflect from the reflection package and i just need to write reifies instances for the constructors i care about
19:25 jomg joined
19:26 doodlehaus joined
19:28 Noldorin joined
19:28 prohobo joined
19:28 <ertes> NemesisD: if you need to write Reifies instances by hand, you probably should just use singletons in the first place
19:28 crobbins joined
19:29 <NemesisD> ertes: yeah its a matter of boilerplate vs transparency imo
19:29 eazar001 joined
19:29 <NemesisD> i reckon if i've only got a few constructors to deal with its fine for me to hand write the reifies instances
19:30 chu joined
19:31 FullyFunctional joined
19:31 metalbot joined
19:34 Guest19319 joined
19:34 Yuras joined
19:36 bruschkov joined
19:36 steeze joined
19:37 bruschkov joined
19:37 Maxou joined
19:38 <ertes> NemesisD: the idea is that you shouldn't write Reifies instances except in certain cases, which are basically use cases of singletons
19:39 doodlehaus joined
19:39 danthemyth joined
19:39 <NemesisD> ertes: what is the problem i'm creating here and avoiding with singletons TH? that i could screw up one of my 3 instances of Reifies or is it something else?
19:40 doodlehaus joined
19:40 HugoDaniel joined
19:43 bruschkov joined
19:43 dhil joined
19:44 edsko joined
19:44 magnusgbr joined
19:45 mhagemeister joined
19:45 robotroll joined
19:45 bruschkov joined
19:46 e14 joined
19:46 lep-delete joined
19:47 bjz joined
19:48 <johnw> NemesisD: you could also reify a Prism
19:49 kiltzman joined
19:49 <Younder> Tuplanolla, For the record what i said about monomorpism is completely wrong its is a transorm from a space A onto A. Not a projection.
19:50 kiltzman joined
19:50 <Younder> Tuplanolla, Unfortunately it is now on record forever.
19:51 <NemesisD> johnw: interesting, i'm not sure if you could contain this in a prism though since MinClearance TopSecret and MinClearance None are different types
19:51 kiltzman joined
19:51 kiltzman joined
19:52 Wurhwuri748 joined
19:52 pleax joined
19:52 kiltzman joined
19:52 kiltzman joined
19:53 insitu joined
19:55 kubuntu_ joined
19:55 kubuntu_ joined
19:56 kubuntu_ joined
19:56 litui joined
19:56 kubuntu_ joined
19:56 kubuntu_ joined
19:57 kubuntu_ joined
19:58 niteria joined
19:59 hexagoxel left
20:00 hexagoxel joined
20:01 chlong_ joined
20:02 vadimich joined
20:03 <mnoonan> has anybody used the LibClang package before? when I try to use it in a project, I'm getting a ton of link errors of the form "undefined reference to `__c2hs_wrapped__clang_XXX`" and I'm not quite sure how to debug further.
20:03 lspitzner joined
20:04 <flxw> dolio: Hmm, a question on terminology. I've grepped four texts on category theory for "lax" (Awodey, Wells, Pierce, Riehl) now, and had not a single hit. Is it, because lax monoidal categories are a more advanced concept, or that different groups call it differently?
20:06 Wurhwuri748 left
20:06 saylu joined
20:06 <mnoonan> flwx: it's a notion from higher category theory, so I wouldn't be shocked if it was omitted from intro texts
20:07 Deide joined
20:08 <flxw> mnoonan: aha, I see. okay, then it's not for me for the time being ...
20:10 <flxw> (just for completeness sake: yes, the searched books are all on basic category theory)
20:10 bruschkov joined
20:12 connrs joined
20:14 AndreasK joined
20:14 <dmwit> flxw: You might like to look it up in ncatlab.
20:15 bruschkov joined
20:15 <dmwit> https://www.google.com/search?q=lax%20site%3Ancatlab.org has a few hits that look relevant
20:16 <dmwit> (Though beware that ncatlab does not try very hard to cater to beginners.)
20:18 coltfred joined
20:18 <Tuplanolla> I can't figure out how to write the `bracket2` analogue (http://lpaste.net/352987) of `allocate` (https://hackage.haskell.org/package/resourcet/docs/Control-Monad-Trans-Resource.html).
20:19 <Tuplanolla> It seems that `Control.Monad.Trans.Resource.Internal` doesn't expose all the internal things.
20:20 <flxw> dmwit: thanks alot for the pointers. beginner friendly: yeah, I am seeing this just now. :)
20:21 chlong_ joined
20:23 Luke joined
20:25 Jesin joined
20:25 fizruk joined
20:25 <Tuplanolla> Maybe I don't need to...
20:26 sellout- joined
20:27 fractalsea joined
20:29 dsh joined
20:31 sssilver joined
20:31 dustmote joined
20:32 Destol joined
20:32 afarmer joined
20:34 animated joined
20:34 <flxw> fmap acts on the second component of a pair. Is there a instance of fmap for (,) which acts on the first one? (Right now I'm doing swap twice)
20:34 e14 joined
20:35 <Tuplanolla> Well, `bimap f id`, but...
20:35 <opqdonut> flxw: it can't, because functor is parameterized on the last type variable
20:36 <robkennedy> There are things called Bifunctors which have that property. Overloading instances are not generally good
20:36 <kuribas> is it possible to break in ghci when a condition is met?
20:36 Wuzzy joined
20:36 <opqdonut> I'd use a lens, or Control.Arrow.first
20:36 <Forkk> Maybe I'm being stupid here, because I feel like this should be obvious, but I can't figure out how to get a Ptr from a ForeignPtr
20:37 <Forkk> is there some function to do that or something?
20:37 <MarcelineVQ> kuribas: yus https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/ghci.html#the-ghci-debugger
20:37 <EvanR> Forkk: right
20:37 <ski> @hoogle withForeignPtr
20:37 <lambdabot> Foreign.ForeignPtr withForeignPtr :: ForeignPtr a -> (Ptr a -> IO b) -> IO b
20:37 <lambdabot> Foreign.ForeignPtr.Safe withForeignPtr :: ForeignPtr a -> (Ptr a -> IO b) -> IO b
20:37 <lambdabot> Foreign.ForeignPtr.Safe.Compat withForeignPtr :: ForeignPtr a -> (Ptr a -> IO b) -> IO b
20:37 <EvanR> the dox
20:37 <Forkk> that's why I said maybe I'm being stupid :P
20:37 <Forkk> because it turns out I was lol
20:38 <ski> @type ContT . Foreign.ForeignPtr.withForeignPtr
20:38 <lambdabot> GHC.ForeignPtr.ForeignPtr a -> ContT r IO (GHC.Ptr.Ptr a)
20:38 takle joined
20:38 <kuribas> MarcelineVQ: sorry, but I don't see how to break on a condition...
20:38 <Forkk> I have no idea how I didn't see that function in the docs
20:39 <flxw> opqdonut: oh, because the type is partially applied, and the type variables are in order a b, so a is fix in (a,b), yes?
20:39 chreekat joined
20:39 <mauke> flxw: yes
20:39 <flxw> cool, again what learnt.
20:40 <ski> `(,) a' is an instance of `Functor'
20:40 <chreekat> I'm using +RTS -xc to look at some traces, and some of the entries end with a backslash, for instance "Stack.Build.build.\" . What does that mean?
20:40 <kuribas> MarcelineVQ: only at a particular line or function.
20:40 <mauke> I see your English is one wall free
20:40 <ski> one can't write `\a -> (a,b)' as a type to be an instance of `Functor'
20:41 <chreekat> Oh, I can answer my own question. It's a lambda.
20:42 albertus1 joined
20:42 albertus1 joined
20:44 insitu joined
20:44 jaga1 joined
20:44 <Zemyla> Why is Proxy not a MonadFix?
20:44 greeny__ joined
20:45 <Zemyla> instance MonadFix Proxy where mfix _ = Proxy
20:45 <Zemyla> Seems like the simplest thing in the world.
20:45 <MarcelineVQ> kuribas: Ah hmm, you'll need to make the conditon a branch of the code you're examining I guess. I suppose there isn't global state to ask about so conditions only make sense in context
20:45 <c_wraith> Zemyla, submit it to the libraries list. (some people will argue about strictness properties, probably)
20:45 roconnor joined
20:46 chrisdotcode joined
20:46 <kuribas> MarcelineVQ: well, something like "myVar > 20" or so...
20:47 eyen_ joined
20:47 petervaro joined
20:47 <kuribas> MarcelineVQ: I could of course trigger an exception when the condition occurs, then break on the exception...
20:48 XMunkki_ joined
20:48 andreass_ joined
20:48 electrostat joined
20:48 Igloo_ joined
20:48 Matajon_ joined
20:48 Tspoon_ joined
20:48 jrslepak_ joined
20:49 nikivi- joined
20:49 i-amd3_ joined
20:49 pleax joined
20:50 Raptor8m3 joined
20:50 fresheyeball joined
20:51 <ski> > undefined >>= return :: Proxy ()
20:51 <lambdabot> Proxy
20:51 augur joined
20:51 chlong_ joined
20:51 Jonno_FT1 joined
20:51 bus000_ joined
20:52 Kneiva_ joined
20:52 oleks_ joined
20:53 vili_ joined
20:53 jeltsch joined
20:53 Luke joined
20:53 Micamo joined
20:54 SAL9000 joined
20:54 arj joined
20:54 jameseb joined
20:55 jeltsch left
20:55 darthdeus joined
20:56 arj joined
20:56 wraithm joined
20:58 Denthir joined
21:00 cdg joined
21:01 rejuvyesh joined
21:03 chreekat joined
21:03 dustmote joined
21:04 fre joined
21:05 haennar joined
21:05 jeltsch joined
21:07 certainty joined
21:07 alexknvl joined
21:11 ramzifu joined
21:11 insitu joined
21:12 tdfirth joined
21:12 louispan joined
21:13 danilo2_ joined
21:14 jgertm joined
21:14 <danilo2_> Hi! :) I've got not a very popular use case here, however, I'm wondering if is it possible to re-export in a module constructors but not their types? I've got data Foo = A | B and I want a module to re-export A and B but not Foo
21:14 lyxia joined
21:14 <EvanR> how would people write type signatures...
21:15 sellout- joined
21:15 <danilo2_> EvanR: By importing the original module
21:16 <danilo2_> EvanR: the datatype is in module M1 and I want M2 to re-export only constructors if its possible.
21:16 mheinzel joined
21:17 afarmer joined
21:18 ramzifu joined
21:18 <ski> did you try only listing the data constructors ?
21:21 <danilo2_> ski: Right, I was somehow mid-closed to reexporting things like module ... (module X) where import M1 (Foo(...)) as X, but right, listening constructors explicitly would do the trick. by the way, im not using it in any prodution code, I was just wondering if ist possible not seeing a simple solution
21:21 <danilo2_> *mind-closed
21:21 raichoo joined
21:21 kritzcreek_ joined
21:25 <EvanR> I don't think parsec can't let you resume in the middle with more input. But can it at least give you the remaining input after a successful parse?
21:26 robertc joined
21:26 sobaken joined
21:26 ph88^ joined
21:28 leat joined
21:29 epsilonhalbe joined
21:30 emmanuel_erc joined
21:32 eschnett joined
21:33 marfoldi joined
21:35 rando6100 joined
21:35 rgc joined
21:38 peterbec` joined
21:38 peterbecich joined
21:39 <srhb> EvanR: getInput is a parser that just consumes everything,
21:39 wtetzner joined
21:40 <srhb> EvanR: (You could use setInput to continue with something else)
21:41 <EvanR> interesting
21:41 unK_ joined
21:41 <EvanR> though would be nicer to have that in the external interface than in the DSL
21:42 user1872 joined
21:42 fnurglewitz joined
21:44 shayan_ joined
21:44 <user1872> Hey! I've been using haskell for a while, but I've only just heard people throw "strict haskell" around. The only thing I can find on the topic is the strict pragma, but I feel like they're talking about something more than just the pragma
21:45 <user1872> do you all know of any good tutorials or descriptions of strict haskell and how to structure your code so that it's not lazy?
21:45 Foras joined
21:45 <monochrom> It is just the pragmas (there are two) and reading the GHC user's guide.
21:45 prohobo joined
21:47 <user1872> Great! I wasn't sure if I was missing something. thanks
21:49 TxmszLou joined
21:50 srbaker_ joined
21:50 wraithm joined
21:51 e14 joined
21:52 ramzifu joined
21:52 hiratara joined
21:52 danthemy_ joined
21:54 Koterpillar joined
21:54 hiThisIsMe joined
21:56 fendor joined
21:57 Rainb joined
22:00 leat joined
22:00 cyborg-one joined
22:03 Luke joined
22:04 fendoer joined
22:04 emmanuel_erc joined
22:07 FullyFunctional left
22:07 <EvanR> is a thread doing a ByteString copy interruptible
22:08 Snircle joined
22:09 <dolio> Doubt it.
22:10 sigmundv joined
22:11 <dmwit> EvanR: If it exists in the DSL, you can implement the out-of-DSL function on top. But not vice versa.
22:11 <dmwit> EvanR: (re: the question about getting the rest of input after a successful parse)
22:12 <dolio> Yeah, bytestring imports memcpy as an unsafe ccall, and uses that for copying things.
22:12 <dolio> So I think it can't be interrupted.
22:15 alexknvl joined
22:15 argent0 joined
22:16 pasukon joined
22:20 kosorith joined
22:20 fracting joined
22:21 rando6100 joined
22:31 hiratara joined
22:32 louispan joined
22:34 _Mzungu_ joined
22:34 orbifx joined
22:35 fre joined
22:36 mtjmullen joined
22:36 path[l] joined
22:38 coot joined
22:39 JuanDaugherty joined
22:40 <mtjmullen> Does a Free Monad have a valid Semigroup instance?
22:40 <mtjmullen> The free package doesn't have an instance for it
22:42 <fresheyeball> I have a simple task, take two lists and make a list of tuples with a book for matches
22:42 <fresheyeball> something like this
22:42 <fresheyeball> tagMatches :: [a] -> [a] -> [(a, Bool)]
22:42 <fresheyeball> such that
22:43 <glguy> mtjmullen: Free has an Alternative instance, so you can wrap it with Data.Monoid.Alt and get a Semigroup instance of that
22:43 <fresheyeball> tagMatches [1,2,3] [2,4] = [(1,False),(2,True),(3,False)]
22:43 codesoup joined
22:43 <glguy> or if we had the Data.Monoid.App (Applicative instead of Alternative) you could use that
22:43 <fresheyeball> what I want to avoid is inefficient code
22:44 Voldenet joined
22:44 Voldenet joined
22:45 mheinzel joined
22:45 <Cale> mtjmullen: An arbitrary monad applied to a semigroup can be given a semigroup instance with (<>) = liftM2 (<>)
22:45 <mtjmullen> glguy: I should be more specific: I would like to lift a semigroup instance to Free
22:45 <glguy> mtjmullen: I don't know what that means
22:45 <Cale> (but the way type classes work, you have to do this for each monad)
22:45 <mtjmullen> So if I have a (Free f a), and a forms a semigroup, can I have (Free f a) be a semigroup by deferring to the semigroup on a
22:46 jedws joined
22:46 <glguy> mtjmullen: That's the hypothetical Data.Monoid.App case I mentioned above
22:46 <Cale> instance Semigroup a => Semigroup (Free f a) where (<>) = liftM2 (<>)
22:46 <glguy> You don't need a Monad for that, an Applicative will do
22:46 <Cale> Sure
22:46 <mtjmullen> That's what I thought, I was surprised the free package didn't have it
22:47 <mtjmullen> I guess they want you to use the Alt instance
22:47 oisdk joined
22:48 <mtjmullen> sorry, Data.Monoid.App instance
22:49 jncunha joined
22:52 ramzifu joined
22:52 eschnett joined
22:52 mda1 joined
22:53 dfeuer joined
22:54 epsilonhalbe left
22:55 kthnnlg joined
22:55 max3 joined
22:57 rekahsoft joined
22:58 fDev2179 joined
23:07 markholmes joined
23:07 <markholmes> is there a way to stop an infinite list from printing
23:07 <markholmes> in ghci
23:07 <markholmes> ... :)
23:07 <dmwit> fresheyeball: Make a `Set` and use `Data.Set.member` or `Data.Set.elem` or whatever it's called.
23:07 <markholmes> ctrl + c and ctrl + z do not work
23:08 <dmwit> markholmes: Hm. They work here.
23:08 <dmwit> markholmes: Perhaps you will like to become acquainted with `kill`. =)
23:08 <markholmes> i'm assuming it's an issue with git bash on windows
23:08 <markholmes> :/
23:09 <markholmes> thanks
23:10 <dmwit> fresheyeball: What have you tried so far?
23:12 oisdk_ joined
23:13 <dmwit> markholmes: You could also try ctrl+q
23:13 <dmwit> Whoops, ctrl+q is resume. I meant ctrl+s
23:13 <mauke> on windows?
23:13 <glguy> When I have a run-away GHCi, I use Ctrl+Z and then kill -9 %1
23:13 <dmwit> Well, if he's in bash...
23:14 <dmwit> Presumably he has some kind of terminal emulation.
23:14 <mauke> ^S/^Q is a terminal thing, not shell
23:14 <dmwit> I am aware.
23:14 <mauke> ah
23:14 <markholmes> yeah, it's git bash
23:15 <markholmes> ctrl + s pauses it
23:15 <dmwit> Right. That should give you enough time to use some other tool to do something to ghci.
23:15 <markholmes> and then ctrl + z exits ghci
23:15 <markholmes> cool, thanks
23:17 <markholmes> oops, they were still running in the background. each one (i did it twice) was taking up 30% of my cpu
23:17 <markholmes> according to task manager
23:17 <dmwit> Yes, you can't forget the second half of glguy's workflow. =)
23:20 mcorpgc joined
23:24 igniting joined
23:24 <geekosaur> on windows I'd expect c-z to exit, on unix it means suspend and will still be running
23:24 tromp joined
23:24 elperdut joined
23:24 <Koterpillar> On Windows, Ctrl-Z is EOF
23:25 indi_ joined
23:25 augur joined
23:25 oisdk joined
23:25 MP2E joined
23:25 conal joined
23:26 anuxivm joined
23:26 <marvin2> my windows ghci must be special.. it exists on C-d
23:26 <marvin2> exits
23:27 <AndreasK> In what shell
23:27 <marvin2> just tried in both cmd.exe and powershell
23:28 <AndreasK> actually it does for me as well
23:29 <geekosaur> that doesn't surprise me, haskeline likely supports both on windows
23:29 <geekosaur> what I would *not* expect is c-z on windows somehow suspending the ghci
23:30 sigmundv joined
23:30 <geekosaur> the way glguy described for unix
23:31 oisdk_ joined
23:32 ezyang joined
23:33 <ezyang> Haskell, I am braining right now. If A <: B, and A <: C, and it's the "best" choice, is that a greatest upper bound or a lowest upper bound
23:33 <ezyang> erm, greatest lower bound, I mean
23:33 <lyxia> looks like a glb
23:34 <lyxia> A is "lower" than B and C
23:34 SwashBuckla joined
23:34 <ezyang> ok thanks
23:34 SwashBuckla left
23:34 coltfred joined
23:35 peterbecich joined
23:36 haennar joined
23:38 buglebudabey joined
23:40 Edith joined
23:41 wraithm joined
23:48 lep-delete joined
23:49 <Squarism> Ive isolated an "interface" from my threading code that isolates all interaction with the actual game. It looks as if i could make this interface "generic" as of 2 type parameters. Its just that i dont really know what is the best/easiest approach? Using generics? Using type classes? In this ( http://lpaste.net/353114 ) ive marked the 2 types that i want to parameterize with "a" and "b" and. Basically "a" == To game message, "b" == to client message.
23:50 <ezyang> generics are definitely not what you want
23:50 <ezyang> type classes could work, assuming that it is always obvious what the type parameter is
23:50 <Squarism> oh ok?
23:50 <ezyang> you might also consider using an associated type, to reduce the number of type parameters you need
23:51 <ezyang> if it is always the case that to game message uniquely determines to client message
23:51 alexbiehl joined
23:51 sykora joined
23:51 texasmynsted joined
23:51 <Squarism> ezyang, well its completely deterimined by the createGameSetupAdapter call
23:52 <ezyang> this produces some adapter type?
23:52 <Squarism> yep
23:52 ramzifu joined
23:52 eschnett joined
23:52 <Squarism> that is parameterized by the type
23:52 <Squarism> (for that particular game)
23:52 <ezyang> so you could, say, define a separate adapter type per game
23:52 cschneid_ joined
23:52 <ezyang> and then have associated types declaring the game and client message types
23:53 kiltzman joined
23:53 <Squarism> would that work even if above code would be "3rd" party?
23:54 kiltzman joined
23:54 <Squarism> in a lib of its own
23:54 <ezyang> yes
23:54 <ezyang> the third party defines the adapter type, and then writes an instance for it
23:54 <ezyang> btw, the biggest problem you might run into with this scheme is convincing GHC to specialize the dictionaries away
23:54 kiltzman joined
23:54 <ezyang> if it can't manage it, you might pay perf tax
23:54 YongJoon joined
23:55 Apocalisp joined
23:56 kiltzman joined
23:56 <Squarism> ezyang, im not very experianced in haskell. Im not sure i really understand what you mean by "define a separate adapter type per game , and then have associated types declaring the game and client message types"
23:56 <Squarism> is its something you could just sketch in lpaste?
23:56 ludat joined
23:57 <Squarism> ive written 1 type class
23:57 dario` left
23:57 kiltzman joined
23:59 <ezyang> maybe https://www.schoolofhaskell.com/school/to-infinity-and-beyond/pick-of-the-week/type-families-and-pokemon will help
23:59 markh joined
23:59 <ezyang> (haven't read)