<    June 2018     >
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 _2_3  
24 25 26 27 28 29 30
00:03 conal_ joined
00:04 freeman42x]NixOS joined
00:04 jtcs joined
00:04 abhiroop joined
00:05 dramforever joined
00:07 eschnett joined
00:08 <dramforever> Random announcement: vscode-ghc-simple: Simple GHC integration for VSCode, using only GHCi (experimental) https://github.com/dramforever/vscode-ghc-simple
00:09 jpgarcia_ joined
00:09 <suzu> instance (FromJSValue a, JsTypeable s b) => JsTypeable s (a -> b) where
00:10 <suzu> does this have GHC match the `s`-es on both sides of the `=>`?
00:10 ammazza joined
00:10 <dramforever> ( PS: Please don't tell me to join haskell-ide-engine here. Come over to https://www.reddit.com/r/haskell/comments/8ryjan/_/e0vbh2u/ )
00:10 twandy joined
00:11 <dramforever> suzu: yes. It's like instance forall s a b. (FromJSValue a, JSTypeable s b) => JSTypeable s (a -> b)
00:11 <suzu> i'm trying to use a function underneath `JsTypeable s b` in the body of `JsTypeable s (a -> b)` here and it's claiming it can't deduce (JsTypeable s1 b)
00:11 <zachk> how do I get websockets to error out on abnormal client disconnection, use the haskell websocket library for the server and warp/scotty, the connections aren't dying correctly when I shutoff the webbrowser, (sometimes)
00:12 <dramforever> suzu: Does it say anything about ambiguous types?
00:12 abhiroop joined
00:12 <suzu> yes. 's1' is ambiguous
00:12 <dramforever> Also code paste would be great, but now that lpaste is down... What do you use now?
00:13 <geekosaur> suzu, that's the application/use that is failing to typecheck, not the signature
00:13 <suzu> how do i annotate it to tell it what i mean?
00:13 <* geekosaur> would reocmmend gist.github.com tbh
00:14 mizu_no_oto_work joined
00:15 <geekosaur> that depends. asTypeOf (which iirc is not in base but is easy to make from const) works if you already have something of the right type
00:15 <suzu> a typeapplication seemed to have made it go away!
00:15 <suzu> "@s"
00:15 <suzu> failing that i was going to annotate the full type of the expression
00:15 <suzu> failing THAT i was gonna add a proxy i guess :/
00:16 <dramforever> I don't think in cases like that, -XTypeApplication can really fail...
00:16 abhiroop joined
00:17 dogweather joined
00:18 ImRatedX joined
00:19 <suzu> it can't?
00:19 HUNTER joined
00:20 <dramforever> I mean, you're *literally* directly telling GHC which 's' to use
00:20 <suzu> lol i suppose so
00:20 <suzu> i didn't get the effect i wanted though :(
00:20 <dramforever> :(
00:20 <suzu> i'm trying to make an environment similar to runST, with the ranktype preventing you from leaking some things
00:21 <suzu> but you can also lift IO actions into this environment
00:21 stavross joined
00:21 <suzu> and it is possible to write the unleakable thing to a ioref and use it in an invalid place
00:21 <dramforever> Ah
00:21 <suzu> is this unpreventable?
00:22 <dramforever> wait
00:22 <dramforever> isn't it prevented already?
00:22 <suzu> no?
00:22 <dramforever> I mean
00:22 <dramforever> maybe you can wrap the unleakable thing in a existential type and try to use it later on
00:23 <dramforever> but when you try, the type variable s would be different (or rather, not known to be the same)
00:23 <dramforever> like, you can't return a STRef from runST
00:23 <suzu> right. but i have an IORef here
00:24 <suzu> so you can write the value there and read it later
00:24 <dramforever> but the types won't match up
00:24 kwantam joined
00:24 <* dramforever> is still pretty sure
00:25 <suzu> they do :(
00:25 <suzu> well, perhaps i'm doing something wrong
00:25 <dramforever> suzu: wait, do your unleakable things have 's' in the types?
00:25 <dramforever> Remember 'STRef s a'
00:25 <suzu> yes
00:25 <suzu> they do
00:26 <dramforever> That's weird
00:26 kvda joined
00:26 <dramforever> Care to share the code?
00:26 DSM joined
00:26 <suzu> well, if you are writing the body of `Unleakable s a -> IO ()`
00:26 dogweather joined
00:26 <suzu> you can write it to an ioref
00:27 <suzu> and then in a different environment you can read it out
00:27 <dramforever> 'different environment' shouldn't that have a different 's'?
00:27 <suzu> it's be a type of `Env s a)
00:27 conal joined
00:27 <suzu> (Env s a)
00:28 <suzu> and yes the s would be different
00:28 jmcarthur joined
00:28 <* hackage> alex-tools 0.4 - A set of functions for a common use case of Alex. http://hackage.haskell.org/package/alex-tools-0.4 (IavorDiatchki)
00:28 <suzu> or at least, no guarantee they are the same
00:28 <dramforever> And so you aren't supposed to be use them
00:28 <dramforever> Did I get that right?
00:28 <suzu> i thought so too but that's false
00:29 <dramforever> That's like, really, really weird...
00:29 <dramforever> Like, how could you even have the IORef in the first place?
00:29 <dramforever> What's its type?
00:29 <* hackage> panic - A convenient way to panic. http://hackage.haskell.org/package/panic- (IavorDiatchki)
00:29 <suzu> lemme put together a small example
00:30 <suzu> maybe i'm misunderstanding something
00:30 MomusInvictus joined
00:30 <dramforever> Ah, ues
00:30 <dramforever> *yes, panic
00:31 hph^ joined
00:31 hph^ joined
00:31 AfC joined
00:31 hph^ joined
00:32 <* AfC> waves
00:32 hph^ joined
00:32 hph^ joined
00:32 hph^ joined
00:33 vurtz joined
00:33 abhiroop joined
00:34 <* dramforever> waves back
00:34 andyhuzhill joined
00:34 <dramforever> welcome :)
00:35 twandy joined
00:35 plugin joined
00:35 MomusInvictus joined
00:37 Mutter joined
00:38 abhiroop joined
00:38 amirpro joined
00:39 silver_ joined
00:41 ctag1 joined
00:41 Kundry_Wag joined
00:42 iakritas joined
00:42 abhiroop joined
00:42 <suzu> ok i wrote it and it appears you are correct
00:42 <suzu> lol
00:42 <suzu> so i must have made a mistake somewhere
00:43 Cthalupa joined
00:43 ozataman joined
00:44 <suzu> i must be using s in some place where it shouldnt be visible
00:44 <suzu> dramforever
00:44 w1n5t0n joined
00:45 iakritas joined
00:45 xcmw joined
00:46 <dramforever> yay
00:47 lazyinitialized joined
00:48 lazyinitialized joined
00:49 vurtz joined
00:50 <w1n5t0n> hi, I have a function "t :: Reader Double Double" which simply returns the context, how can I make it an instance of num so I can do something like "aFunc :: Reader Double Double; aFunc = 2 + t" which will return a reader that adds 2 to the context?
00:50 connrs joined
00:51 comerijn joined
00:51 <w1n5t0n> sorry, not sure if "function" is the proper term for t
00:53 <suzu> you can use `ask` which is `Reader a a`
00:53 <suzu> so it will give you whatever you put in the reader, out
00:53 <dramforever> 1. You probably want to wrap your Reader into a newtype. In fact, (->) is basically the same but easier to use.
00:53 <dramforever> From now on I assume you have newtype Fn a = Fn (Double -> a) with Functor, Applicative, Monad instances.
00:54 <suzu> you cannot make a reader that adds to the context. you aren't allowed to modify the context
00:54 <dramforever> 2. Then just do it :) instance Num a => Num (Fn a) where ...
00:54 <suzu> but you can instead run a different reader with a new context that is the old context, plus two
00:54 conal joined
00:54 <dramforever> Oh hey
00:54 ericsagn1 joined
00:55 <zachk> w1n5t0n, you probably want State instead of Reader
00:55 <dramforever> w1n5t0n: wait, t is (Reader id), and you want (2 + t) to be (Reader (\x -> 2 + x)), right?
00:55 <dramforever> I'm pretty sure w1n5t0n is talking about my thing
00:55 nighty- joined
00:55 <dramforever> considering that t probably means a parameter
00:56 <dramforever> 'independent variable'. Is that what it's called?
00:56 <w1n5t0n> dramforever: I think that's what I mean, what I want is to be able to map a single-argument function over a domain, and for "t" to return each input from that domain
00:57 <dramforever> yay
00:57 andreabedini joined
00:57 <dramforever> then what's stopping you? Just write your instance
00:58 <dramforever> like, you need to define fromInteger :: Integer -> Fn a, and you have (Num a), so you can use fromInteger :: Integer -> a, so fromInteger = pure . fromInteger
00:58 <dramforever> and (+) :: Fn a -> Fn a -> Fn a from (+) :: a -> a -> a, which is from (Num a), so (+) = liftA2 (+)
00:59 <* dramforever> regrets throwing like millions of combinators there... but that's literally what it's for
01:00 kvda joined
01:03 <w1n5t0n> dramforever: ok that makes more sense but it'll take some time to work through it, thanks!
01:03 chao-tic joined
01:03 <dramforever> I mean
01:04 antsanto joined
01:04 <dramforever> you *can* write it out more explicitly...
01:04 <dramforever> w1n5t0n: do you actually know liftA2?
01:05 andyhoang joined
01:06 <suzu> ok dramforever i found an example where it fails
01:06 <w1n5t0n> dramforever: yes I understand its concept, I'm just having some trouble piecing it all together in my head
01:09 <suzu> dramforever: https://lpaste.net/6170621948440084480
01:10 <dramforever> how were you able to post to lpaste??? It's completely not working for me
01:10 <Axman6> w1n5t0n: instance Num a => Num (Reader a a) where fromIntegral x = pure (fromIntegral x); (+) = liftA2 (+); (*) = liftA2 (*); etc.
01:10 johnvonneumann joined
01:11 <suzu> i don't know? it is working here
01:11 nuncanada joined
01:11 <suzu> try the ip directly dramforever ?
01:11 vurtz joined
01:12 <dramforever> suzu: same, try https://gist.github.com maybe?
01:12 twandy joined
01:13 <w1n5t0n> Axman6: I get an "Illegal instance declaration... (All instance types must be of the form (T t1 ... tn), where T is not a synonym)" when I try that
01:14 <geekosaur> right, it's duplicating a type variable, needs FlexibleContexts iirc
01:14 <dramforever> Put {-# LANGUAGE FlexibleInstances #-} (or FlexibleContexts, whatever the compiler said) at the beginning of the file
01:15 <suzu> dramforever: https://pastebin.com/4fK02Fbw
01:15 <dramforever> w1n5t0n: Or listen to me and newtype Fn a = Fn { runFn :: a -> a }
01:15 louispan joined
01:16 <dramforever> suzu: uhh, ever considered this? runEnv :: (forall s. Env s a) -> IO a
01:17 <dramforever> I mean,
01:17 <dramforever> :t runST
01:17 <lambdabot> (forall s. ST s a) -> a
01:17 Nik05 joined
01:18 nuncanada2 joined
01:20 <suzu> dramforever: this example, as it is, does not compile (which is correct)
01:21 <dramforever> uhh
01:21 <suzu> but if i comment that one impl of runAction and uncomment the other one
01:21 <dramforever> wat
01:21 <suzu> it will compile, and i don't want it to
01:22 <suzu> dramforever: this doesn't compile. uncomment 38-43 and comment 30-35 and it will compile
01:22 <dramforever> Do you have to use the commented out one...?
01:22 <suzu> yes
01:22 <suzu> that's how my program works
01:22 <suzu> it'll accept functions that match a typeclass like this
01:24 sektor joined
01:24 <dramforever> So!
01:25 <dramforever> have you considered runEnv :: (forall s. Env s a) -> IO a
01:25 <suzu> yes. i tried that ,it doesn't change anything
01:25 danso joined
01:25 <suzu> you can compile the code
01:26 <dramforever> Ah, I see, it's the problem with 's'
01:26 <dramforever> runAction is polymorphic in 's'...
01:27 <suzu> well, both are
01:27 <suzu> so that isn't it
01:28 <hololeap> i read a lot about how haskell (ghc) isn't very good for running a 3d game engine on because of the hiccups related to the GC. how would it fare as a realtime (as much as possible anyway, some latency is ok) audio synthesis engine?
01:29 <dramforever> So my idea is that you need something like (forall s. Unleakable s -> Env s a) -> IO a
01:29 <dramforever> That's really unleakable (I hope!)
01:29 sdothum joined
01:29 <ammar2> hololeap: sounds like the same problem, GC doesn't add latency, it adds intermittent pauses
01:29 <ammar2> so the same problem of game engines would apply
01:30 louispan joined
01:30 <suzu> dramforever: that works but i can't do that
01:30 <dramforever> This gets weird
01:30 <dramforever> like, really weird
01:30 <suzu> i need this typeclass
01:30 <monochrom> Haskell (generally GC) would be OK for 3D game engines for turn-based strategy games such as Civ 6. >:)
01:31 <dramforever> suzu: and really do you know anything about a?
01:31 <dramforever> In line 32
01:31 <suzu> i know that it is an instance of a different typeclass, in practice
01:31 <suzu> but that doesnt help
01:31 <monochrom> As for real-time strategy games, you know what, AoE2 had noticeable pauses too every time the computer player planned an attack against me. And I was actually thankful!
01:31 dodong joined
01:32 <dramforever> suzu: You probably want to add s to the other typeclass...
01:32 <dramforever> Oh wait
01:32 <dramforever> IsAction (IO ()) is like not helping
01:32 <dramforever> You need something like IsAction (Action s ())
01:33 <dramforever> Like, IsAction s (Action s ())
01:33 <dramforever> and instance (IsAction s tail, SomeOtherThing s a) => IsAction s (a -> tail)
01:33 <suzu> sure, i can newtype wrap IO with a new type Action but that doesn't help
01:33 <dramforever> Perhaps with a fundep class IsAction s a | s -> a
01:33 <suzu> and adding s to IsAction doesn't help
01:33 <dramforever> You need to add s to the other typeclass
01:33 <suzu> ohh a fundep
01:34 <dramforever> otherwise this isn't even a implementable typeclass
01:34 <dramforever> (how are you supposed to give any a)
01:34 <suzu> suppose that a must always be numeric
01:34 dogweather joined
01:34 <dramforever> I know what confused me now. You literally pulled an Unleakable s out of nowhere
01:34 <suzu> so it is a variadic function that takes any number of Num-s and then returns IO ()
01:35 <dramforever> and it's bad
01:35 <suzu> i dont understand
01:35 <dramforever> because it needs to return Action s ()
01:35 <dramforever> ah
01:35 <dramforever> wait
01:35 byorgey_ joined
01:35 <dramforever> wait wait wait
01:35 <dramforever> runAction is the 'super liftIO' part
01:35 <suzu> yes
01:35 <dramforever> ah
01:35 twandy joined
01:36 <suzu> so i still don't know how to get the compiling version to fail
01:36 <dramforever> suzu: 'any number of Num-s and then returns IO ()' but 'write' isn't that
01:36 <suzu> this is an example
01:36 <dramforever> you need to pass the 's' down to Unleakable somehow
01:36 halogena1dtoast joined
01:37 <dramforever> This is necessary
01:37 <suzu> oh ok let me implement that
01:37 Suk joined
01:38 <suzu> dramforever: https://lpaste.net/6830822786215182336
01:39 <dramforever> well, lpaste, nope :p
01:39 <suzu> functions may be variadic in numeric values, or can take an unleakable value
01:39 <suzu> argh one sec
01:39 sword865 joined
01:39 <dramforever> I mean, someone really need to look into this...
01:39 <suzu> https://pastebin.com/jJmjZULi
01:40 <suzu> dramforever ^
01:40 <dramforever> Ok
01:40 <* dramforever> rolls up sleeves
01:41 <suzu> ty for your help btw :)
01:41 tangmou joined
01:42 tzemanovic joined
01:43 Johannes13 joined
01:45 diwo joined
01:46 FreeBirdLjj joined
01:47 gsingh93 joined
01:47 chao-tic joined
01:48 <dmwit> suzu: For that to work, `newIORef Nothing` would have to give you an `IORef (Maybe (forall s. Unleakable s))`, but it doesn't, it gives you an `forall s. IORef (Maybe (Unleakable s))`.
01:48 <dramforever> https://pastebin.com/LNr2qPQx
01:48 <dramforever> suzu ^
01:49 <dramforever> I can't put in the fundep because Integer -> IO a isn't going to be related to s in any way...
01:49 <dmwit> Hm. I should maybe leave this one alone, since it seems I'm missing a bunch of context.
01:50 dogweather joined
01:50 ashirase joined
01:50 <dramforever> This is like
01:50 <dramforever> three problems mixed together
01:50 <dramforever> I think I mixed it well
01:53 <suzu> ahmm i tried this before
01:53 <suzu> and it would work when it shouldn't
01:54 <dramforever> did you have the 'forall' here? runEnv :: (forall s. Env s a) -> IO a
01:55 <suzu> no. that doesn't do anything afaict
01:55 HUNTER joined
01:56 ddellacosta joined
01:56 <suzu> i feel like this doenst work for a.. different reason
01:57 mud joined
01:58 <suzu> ok nope that's legit
01:58 <suzu> it can't infer that there's an (IsAction s (Unleakable s -> x)) given just the s in the Unleakable
01:59 MoarSpaceFi joined
01:59 louispan joined
02:00 hucksy_ joined
02:01 <dramforever> I mean, not even infer
02:01 <dramforever> s1 is fundamentally different from s
02:01 ashirase joined
02:04 Suk joined
02:06 pera joined
02:06 Suk joined
02:06 andyhoang joined
02:08 Suk joined
02:08 abhiroop joined
02:10 tabemann joined
02:13 Lynxium joined
02:14 Suk joined
02:14 dodong joined
02:15 Kundry_Wag joined
02:15 Linter joined
02:16 <* hackage> pandoc-crossref - Pandoc filter for cross-references http://hackage.haskell.org/package/pandoc-crossref- (lierdakil)
02:16 plugin joined
02:17 banc joined
02:18 dogweather joined
02:19 brocoli joined
02:22 __bo joined
02:28 dogweather joined
02:32 lagothri1 joined
02:33 fishythefish joined
02:34 dogweather joined
02:34 patlv joined
02:34 amirpro joined
02:34 andyhoang joined
02:36 <suzu> yeah
02:36 <suzu> ok
02:36 <suzu> hmm
02:36 <suzu> this error message makes this very unclear though
02:36 twandy joined
02:36 oisdk joined
02:36 <suzu> if i wanted to be abl eto create iorefs to store this value -- but restrict them only to work inside Env, how woudld i do it?
02:37 <* hackage> apecs - A fast ECS for game engine programming http://hackage.haskell.org/package/apecs- (jonascarpay)
02:37 Unhammer joined
02:40 louispan joined
02:43 andyhoang joined
02:43 <hololeap> just a question on people's opinion: can using a Reader monad be easier to read at times compared to nested clauses like `where`, `let`, `case`?
02:44 mizu_no_oto_work joined
02:44 <hololeap> or `do`
02:44 <geekosaur> I would not usually use one in place of any of those
02:44 <glguy> I don't know what those all have to do with each other
02:46 <mniip> I don't think I can conceive a case where I'd use a Reader monad do-block outside of a larger monadic transformer stack
02:46 <mniip> provided, I do use the Reader monad operations themselves often (bind, ap, join)
02:49 juhp joined
02:51 plutoniix joined
02:51 connrs joined
02:54 <hololeap> it seems like even ReaderT can be replaced with an extra parameter in the function. `func r = action >>= (\a -> actionF r)` vs. `func = action >>= (\a -> (ask >>= (\r -> actionF r))`
02:55 ddellaco_ joined
02:55 <lukelau> Is it possible to get a more detailed version from System.Info’s compilerVersion?
02:55 <glguy> hololeap: That's all the Reader is
02:55 <lukelau> It’s just returning 8.4 for me, I’d like to get the .3 as well
02:56 <geekosaur> hololeap, that's what Reader / ReaderT *is*
02:56 <mniip> hololeap, sure, all monad operations can be inlined because they are defined using haskell code
02:57 conal joined
02:57 juhp joined
02:57 lektrik joined
02:57 <hololeap> right, it's just a newtype of (r -> a) or (r -> m a). but my question is, when does it make sense to use Reader/ReaderT instead of doing the whole nested parameters thing.
02:57 <geekosaur> lukelau, no. I think you can use CPP to get it. https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/phases.html#standard-cpp-macros
02:57 <mniip> when you have other transformers already
02:57 <mniip> so a ReaderT on top adds no additional cost
02:57 mizu_no_oto_work joined
02:58 <mniip> notably when you are passing some sort of environment
02:58 <mniip> that you may wish to "locally override" in some bounded block
02:58 <mniip> cf 'local'
02:58 rasusto_ joined
02:59 <hololeap> ok, i could see how that would come in handy sometimes
03:00 <mniip> last time I properly used Reader when I was writing a (to-) brainfuck compiler
03:00 <mniip> the environment would contain the assignments of the tape to variables that are local to blocks
03:00 <lukelau> geekosaur: thanks!
03:01 <hololeap> uh
03:01 <mniip> well, local variables are syntactically local, right?
03:01 dogweather joined
03:01 <hololeap> first of all, what are "blocks"?
03:02 <mniip> well consider this
03:02 diwo joined
03:02 <mniip> do local f $ foo; bar
03:02 <mniip> versus
03:02 <geekosaur> regions with lexical scopes attached
03:02 <mniip> do modify f; foo; bar
03:02 theDon joined
03:02 <mniip> the former "reverts" the environment for 'bar'
03:02 <geekosaur> which probably doesn't help, but this may not make sense at all in that case :)
03:03 <mniip> the latter (StateT) doesn't
03:03 AetherWind joined
03:05 <hololeap> ok, i'm mostly with you
03:05 <hololeap> i would need an example of a block to understand that part
03:05 acertain joined
03:05 bbrodriguez joined
03:05 <hololeap> but you can have nested environments that "disappear" when the inner action is completed
03:06 orion joined
03:07 <mniip> yes
03:07 <mniip> it's a neat thing
03:07 Zipheir` joined
03:08 <hololeap> that helps me understand its purpose other than an educational tool. thanks
03:08 louispan joined
03:08 <mniip> GHC uses ReaderT all over the place
03:09 otto_s_ joined
03:10 <hololeap> :t local
03:10 <lambdabot> MonadReader r m => (r -> r) -> m a -> m a
03:12 chao-tic joined
03:12 <mniip> on a second thought, HscEnv is a StateT-type variable
03:13 <mniip> the Session you see in reifyGhc/reflectGhc is just an IORef...
03:13 <mniip> so I suppose GHC really just emulates StateT with ReaderT IORef
03:14 <mniip> I wonder if there's a good reason
03:14 <hololeap> some performance tweak?
03:14 <mniip> probably because StateT s IO a ~ s -> IO (s, a)
03:14 <mniip> in case the IO throws the s is not retained in any way whatsoever
03:15 <hololeap> oh, sure... IO is a tricky one
03:16 dogweather joined
03:20 ImRatedX joined
03:20 pera joined
03:21 reggie_ joined
03:21 kapil___ joined
03:27 lassulus_ joined
03:28 <dmwit> :t maybe (:) id
03:28 <lambdabot> Maybe (a -> [a] -> [a]) -> a -> [a] -> [a]
03:28 <dmwit> :t maybe id (:)
03:28 <lambdabot> Maybe a -> [a] -> [a]
03:28 nano__ joined
03:29 lastmanstanding joined
03:30 <mniip> :t mappend . maybeToList
03:30 <lambdabot> Maybe a -> [a] -> [a]
03:30 <dmwit> :t (++) . toList
03:30 <lambdabot> error:
03:30 <lambdabot> Ambiguous occurrence ‘toList’
03:30 <lambdabot> It could refer to either ‘F.toList’,
03:30 <dmwit> There's another toList?
03:31 <mniip> @more
03:31 <lambdabot> Plugin `more' failed with: Prelude.init: empty list
03:31 oisdk joined
03:31 <dmwit> :t Lambdabot.Plugin.Haskell.Eval.Trusted.toList
03:31 <lambdabot> IsList l => l -> [Item l]
03:32 <dmwit> :t (++) . F.toList
03:32 <lambdabot> Foldable t => t a -> [a] -> [a]
03:32 <mniip> hmm check this out
03:32 <mniip> :t (F.toList .) . (:*:)
03:32 <lambdabot> error:
03:32 <lambdabot> Data constructor not in scope: (:*:) :: a -> a1 -> [a2]
03:32 <mniip> :t (F.toList .) . (GHC.Generics.:*:)
03:32 <lambdabot> (Foldable g, Foldable f) => f a -> g a -> [a]
03:33 <dmwit> neat
03:34 <dmwit> `maybe id (:)` requires less magic from both reader and compiler. I'm going to stick with it.
03:35 bahamas joined
03:36 <mniip> :t \x -> lift x >>= tell
03:36 <lambdabot> (MonadWriter w (t m), Monad m, MonadTrans t) => m w -> t m ()
03:36 dogweather joined
03:36 <mniip> no wait that goes on the other end
03:37 twandy joined
03:38 pally joined
03:38 <pally> "zipWith is right-lazy"
03:38 <pally> What does right-lazy mean?
03:39 <mniip> > zipWith (error "f") (error "l") []
03:39 <lambdabot> *Exception: l
03:39 <mniip> > zipWith (error "f") [] (error "r")
03:39 <lambdabot> []
03:39 <mniip> basically this
03:41 <dmwit> Exercise: use `unamb` to create a `zipWith` which is both left-lazy and right-lazy.
03:42 louispan joined
03:44 <mniip> unsafeIsEvaluated = const False
03:44 <mniip> sounds fully functional
03:46 <dmwit> :t flip . zipWith . flip
03:46 <lambdabot> (b -> a -> c) -> [b] -> [a] -> [c]
03:46 wotan_ joined
03:47 <pally> > const (3+4) (div 1 0)
03:47 <lambdabot> 7
03:48 <pally> also right-lazy
03:49 <dmwit> It's harder to make that one left-lazy, though. =)
03:49 dogweather joined
03:50 <mniip> flip seq
03:52 <dmwit> ...is also not left-lazy.
03:54 <mniip> right-strict though :p
03:55 <dmwit> yes =)
03:55 tzemanovic joined
03:57 dogweather joined
03:58 anon136 joined
03:58 <pally> "right-strict though :p" I wish I knew what the amusement is about. lol
03:59 <dmwit> I asked him to make it lazier in the first argument. Instead he made it stricter in the second argument.
03:59 <dmwit> It's... I don't know. Perverse. =)
03:59 pykello joined
04:00 AetherWind_GJ joined
04:00 dan_f joined
04:01 <mniip> strictness is relative
04:01 Mrd1 joined
04:02 Linter joined
04:03 <mniip> bottoms requiring infinite time to evaluate is a result of time dilation :p
04:04 taumuon joined
04:04 pfurla joined
04:05 hphuoc25 joined
04:06 NiceTry5 joined
04:06 youtmon joined
04:07 tzemanovic joined
04:08 twandy joined
04:08 dtoma joined
04:09 halogenandtoast joined
04:09 youtmon joined
04:10 NiceTry5 joined
04:13 vmandela joined
04:13 Scip__ joined
04:15 scottschmidt1 joined
04:17 sebastianrkg joined
04:20 eruditass joined
04:21 keepLearning512 joined
04:25 scottschmidt1 joined
04:25 blankhart joined
04:25 altjsus joined
04:25 dogweather joined
04:26 language_agnosti joined
04:28 <jared-w> lol
04:28 <jared-w> "bottoms are merely finite values traveling at lightspeed"
04:28 halogenandtoast joined
04:29 <rotaerk> my bottom is pretty stationary
04:30 fmixing joined
04:31 <geekosaur> jared-w, or with infinite mass. >.>
04:31 <jared-w> is that just because it hasn't been observed yet, rotaerk? /s
04:33 <rotaerk> lol
04:35 codesoup joined
04:37 scottschmidt1 joined
04:38 osa1 joined
04:39 halogenandtoast joined
04:39 NiceTry5 left
04:40 hphuoc25_ joined
04:40 language_agnosti joined
04:41 j2j joined
04:41 twandy joined
04:41 danvet joined
04:43 tangmou joined
04:47 <* hackage> boolector - Haskell bindings for the Boolector SMT solver http://hackage.haskell.org/package/boolector- (DeianStefan)
04:47 halogenandtoast joined
04:47 Ariakenom joined
04:48 ImR4t3dX joined
04:49 language_agnosti joined
04:49 ImR4t3dX left
04:50 howdoi joined
04:53 xtreak joined
04:54 HUNTER joined
04:54 kvda joined
04:56 tangmou joined
04:56 Destol joined
04:56 sakalli_ joined
05:01 JanBessai joined
05:01 wchresta joined
05:02 woodson joined
05:02 SeMas joined
05:03 tsaka__ joined
05:04 Scip joined
05:05 language_agnosti joined
05:06 pfurla joined
05:06 dogweather joined
05:09 pfurla joined
05:11 <Orbstheorem> Hi, so I'm studing actors (notabbly akka), I'm wondering if there's an “actor” monad: I guess it's signature would be something like `Msg a, Actor b => a -> ([a], [b])` where `become` would be returning multiple a and sending messages would be returning multiple b
05:12 Cthalupa joined
05:13 twandy joined
05:13 pykello joined
05:16 <Ariakenom> Orbstheorem: I believe there's cloud haskell and their Process monad
05:17 enterprisey joined
05:19 Mrd1 joined
05:19 slomo joined
05:20 <Mrd1> Hei.....
05:21 <Ariakenom> Orbstheorem: I don't know if you're interested but for running on one machine I'd guess the Async and STM libraries is a good bet.
05:23 <Orbstheorem> I'm looking at Cloud haskell, and process looks very close to what I had in mind!
05:23 <Orbstheorem> Thanks!
05:25 ctag1 joined
05:26 lykrysh joined
05:27 SenasOzys joined
05:27 obi_jan_kenobi__ joined
05:28 dogweather joined
05:28 scottschmidt1 joined
05:30 jackdk joined
05:33 sakalli_ joined
05:34 Cthalupa joined
05:37 dogweather joined
05:37 sakalli_ joined
05:38 twandy joined
05:38 danso joined
05:39 <simon> I'm modelling an AST for an assembler language with instructions DUP1-DUP32, but having all those as constructors seems tedious.
05:39 kvda joined
05:40 <simon> it also has PUSH1-PUSH32, but those are identified by a constant the size of that number of bytes, so I made one single PUSHN [Word8] constructor. for DUPN I can't because it doesn't have an argument of size N.
05:41 <simon> (ideally I'd want at most 32 bytes, but [Word8] is perhaps sufficient.)
05:42 <simon> I'll just go with 'DUP Int'.
05:43 fmixing joined
05:43 camsbury joined
05:43 sakalli_ joined
05:44 Linter joined
05:45 Gurkenglas joined
05:45 halogena1dtoast joined
05:47 sakalli_ joined
05:47 keepLearning512 joined
05:49 raingloom joined
05:49 mariatsji joined
05:56 mariatsji joined
05:57 vlatkoB joined
05:57 sakalli_ joined
05:58 tangmou joined
05:59 louispan joined
06:00 halogenandtoast joined
06:00 zdenal joined
06:11 bahamas joined
06:11 scottschmidt1 joined
06:12 twandy joined
06:13 darjeeling_ joined
06:14 mariatsji joined
06:14 andyo joined
06:15 connrs joined
06:16 language_agnosti joined
06:19 louispan joined
06:20 robstr joined
06:23 thaumavorio joined
06:23 znack joined
06:23 mariatsji joined
06:24 orion joined
06:24 orion joined
06:25 mariatsji joined
06:25 ozzymcduff joined
06:27 scottschmidt1 joined
06:27 hphuoc25 joined
06:28 <* hackage> elf 0.29 - An Elf parser http://hackage.haskell.org/package/elf-0.29 (wangbj)
06:32 <jle`> acme-elf should just be quotes from the movie
06:32 Mrd1 joined
06:32 Mrd1 left
06:33 Mrd1 joined
06:33 language_agnosti joined
06:33 Mrd1 left
06:34 Ariakenom joined
06:36 dogweather joined
06:37 merijn joined
06:37 <mupf> Hello guys, for some reason I can't see my input in ghci anymore
06:37 <mupf> any idea why this might be?
06:38 <mupf> I can enter expressions etc but I simply can't see them
06:38 <dminuoso> mupf: Perhaps your tty is messed up?
06:38 twandy joined
06:39 <mupf> I use urxvt_unicode
06:39 <* hackage> potoki 2.0.1 - Simple streaming in IO http://hackage.haskell.org/package/potoki-2.0.1 (IrinaArtemeva)
06:39 <mupf> I try something
06:40 <mupf> Okay, it works when I delete my .ghci configuration
06:40 <infty> Does one ever get used to the prefix notation of function composition?
06:40 lortabac_ joined
06:40 <cocreature> infty: sure, I find it quite intuitive at this point
06:41 <dminuoso> infty: what's that? Do you mean `(.) f g`?
06:41 philippD joined
06:41 <cocreature> if you think about the fact that (f . g) x = f (g x) the order makes a lot more sense
06:41 <mupf> okay, it was misconfiguration. fixed it
06:41 ove__ joined
06:41 <cocreature> oh I think I might have misunderstood the question
06:42 <infty> When writing a composite function, I tend to imagine a process starting from the innermost argument (e.g.
06:42 louispan joined
06:42 <infty> "take a string, then reverse it, then truncate it"
06:43 <Ariakenom> :t (&)
06:43 <lambdabot> a -> (a -> b) -> b
06:43 <infty> ) but the syntax starts with the outermost process
06:44 <dminuoso> infty: What exactly do you mean by "prefix notation of function composition"
06:44 <Ariakenom> > let (%) = flip (.) in "Hello" & reverse % take 2
06:44 <lambdabot> "ol"
06:44 hamishmack joined
06:44 benjamin-l joined
06:44 <cocreature> dminuoso: I think they mean the fact that f . g first applies g and then f to the result of that instead of the other way around
06:44 <infty> dminuoso: I mean that f followed by g is written g.f, and not f.g
06:45 <dminuoso> cocreature: So curious.. how the heck did you understood him right based on that!
06:45 <Ariakenom> dminuoso: I dunno. it's wrong!
06:45 <dminuoso> :D
06:45 <cocreature> dminuoso: because it’s a common complaint :)
06:45 <dminuoso> Ah I suppose.
06:45 <infty> Sorry I was imprecise
06:46 <cocreature> infty: fwiw if you prefer the other style there are libraries that make that easy, e.g., https://hackage.haskell.org/package/flow-1.0.12/docs/Flow.html
06:46 <cocreature> there is also (&) for flipped function application in "base"
06:46 <Ariakenom> prefix is as dminuoso said (.) f g
06:47 <monochrom> Consider f >>> g
06:47 <infty> cocreature: Thanks, I was not aware of those
06:48 grastello joined
06:48 <cocreature> infty: but if you want to write Haskell you should at least be able to read code that uses (.) easily as well. otherwise you’ll have a hard time given that this is what most of the ecosystem uses
06:48 hphuoc25 joined
06:49 <infty> Ariakenom: I borrowed the terminology from https://en.wikipedia.org/wiki/Function_composition#Alternative_notations but perhaps I mistakenly took "prefix" to mean the reverse of "postfix"
06:51 <monochrom> Unfortunately "g . f" is postfix in "f" but infix in "." so it's infix too.
06:51 <infty> cocreature: That's a valid concern. I'm mostly wondering how people write their code: do you actually think of the outermost process first? The alternative seems to require a lot of cursor movement and parenthesis insertion.
06:52 <cocreature> infty: it depends™. (.) encourages a top-down approach where you start with what you want to return and then construct step-by-step how you get there
06:52 merijn joined
06:52 <cocreature> flip (.) encourages a more bottom-up approach where you start with your inputs and then move towards the output
06:53 <cocreature> which approach is preferable depends on preference and the problem at hand
06:53 <dminuoso> Is it possible that (>=>) is far more common than (<=<) though?
06:53 SenasOzys joined
06:53 benjamin-l joined
06:53 <Ariakenom> that use of postfix refers to f x instead being x f there. And technically not composition
06:53 thehivemind5 joined
06:53 <dminuoso> If that was the case I'd expcet it to be because of >>=
06:53 language_agnosti joined
06:53 <monochrom> Oh! Maybe I meant prefix.
06:53 <cocreature> yeah it’s kind of weird that for Monad we default to composing the other way around
06:53 <cocreature> although personally I use =<< and <=< more often
06:54 <cocreature> infty: often I introduce (.) when refactoring code that previously wasn’t point free, e.g., refactoring f (g x) into f . g and then the order is quite convenient
06:55 <dminuoso> Quick bikeshedding: https://hackage.haskell.org/package/base- does anyone else think it's bad to call (>=>) "composition of monads"?
06:55 <dminuoso> It's composition of kleisli arrows. The monad itself is *certainly not composed*
06:55 <dminuoso> Or is my pedantry setting too high?
06:56 <infty> cocreature: Thanks for providing some context, I'll try to get used to both.
06:57 <dminuoso> Or does "composition of monads"
06:57 benjamin-l joined
06:57 <dminuoso> mean "composition in the world of monads"
06:57 <cocreature> infty: also just to be clear, there is nothing wrong with taking a bottom-up approach and therefore using a flipped version of (.). all I’m saying is that (.) is quite common so you should familiarize yourself with that as well
06:57 bo joined
06:57 <jesyspa> dminuoso: I agree, "composition of monads" has a pretty clear meaning that's taken. "composition of monadic actions" or something would be okay-ish.
06:58 <cocreature> it does say “Kleisli composition of monads” rather than just “composition of monads” but yeah that’s still somewhat confusing
06:59 <cocreature> on the other hand I can’t be bothered to care :)
06:59 tangmou joined
06:59 <dminuoso> cocreature: Oh was just asking for feedback to see if there's any traction. Might make it a small doc fix pr.
06:59 scottschmidt1 joined
07:00 dogweather joined
07:01 tangmou joined
07:02 pwestling joined
07:02 pwestling joined
07:03 language_agnosti joined
07:04 reactormonk joined
07:04 <* hackage> potoki-hasql 1.6 - Integration of "potoki" and "hasql". http://hackage.haskell.org/package/potoki-hasql-1.6 (IrinaArtemeva)
07:05 mikeplus64 joined
07:06 ozzymcduff joined
07:06 fujiy joined
07:07 Kirk_ joined
07:08 pwestling joined
07:08 pipahask joined
07:08 capJKirk joined
07:10 revprez_atlanta joined
07:10 revprez joined
07:11 hphuoc25 joined
07:12 phenoble joined
07:12 remyhr joined
07:13 dogweather joined
07:13 jackdk joined
07:13 <dminuoso> Would "composition of Kleisli arrows" be a better fit?
07:14 revprez_stg joined
07:15 revprez_anz joined
07:16 mariatsji joined
07:17 zariuq joined
07:18 language_agnosti joined
07:19 cur8or joined
07:19 AetherWind left
07:20 language_agnosti joined
07:21 encod3 joined
07:21 Nussi joined
07:22 dddddd joined
07:22 khilan joined
07:23 zakora joined
07:24 raichoo joined
07:26 <osa1> anyone know what's going wrong here with cabal https://lpaste.net/2220164879879241728 ?
07:27 <osa1> ohh I need --enable-tests in the second command
07:28 language_agnosti joined
07:28 refold joined
07:28 Linter joined
07:30 dexhunter joined
07:30 connrs joined
07:31 <capJKirk> OverloadedStrings doesn't seem to work properly... https://lpaste.net/8970223116785549312
07:32 <capJKirk> I'm getting an error in the last line with mconcat
07:32 pwestling joined
07:32 <capJKirk> https://lpaste.net/1334972433706254336
07:32 <capJKirk> ^^^ the error
07:33 language_agnosti joined
07:34 <osa1> capJKirk: use <> instead of ++
07:34 <capJKirk> osa1: hmm let me check
07:35 <Ariakenom> Hm it maeks sense to classify bottom as a side effect, right?
07:35 merijn joined
07:35 agander joined
07:35 <capJKirk> osa1: man it worked... what was the problem?
07:35 <dminuoso> Ariakenom: What effect does it have?
07:36 <dminuoso> Ariakenom: Or perhaps more importantly how do you define "effects"?
07:36 <capJKirk> osa1: oh wait...
07:36 <osa1> capJKirk: see types of <> and ++. ++ is for concatenating lists (remember that String is [Char]) but you're concatenting Texts
07:36 Frodo1337 joined
07:37 <capJKirk> osa1: Ok, thanks :)
07:37 <osa1> yw
07:37 <Ariakenom> dminuoso: Well what is an effect is definitely part of my question :)
07:38 thc202 joined
07:38 <Ariakenom> But putStrLn (x :: String) not working for x=undefined seems like an effect
07:38 idupree joined
07:38 lesstat joined
07:39 lesstat left
07:39 twandy joined
07:40 <Ariakenom> Partiality being an effect seem intuitive
07:41 pwestling joined
07:41 tromp joined
07:42 sanitypassing joined
07:42 __monty__ joined
07:42 ackthet joined
07:44 tzemanovic joined
07:44 mnoonan joined
07:44 fmixing joined
07:44 scottschmidt1 joined
07:45 zariuq joined
07:47 <dminuoso> Well the term "effect" is so frequently being used with a lot of hand waving.
07:47 <simon> if I want an integral type bounded to 32 bytes, how do I define that?
07:47 <dminuoso> simon: Data.Int.Int32
07:47 <simon> dminuoso, bytes, not bits.
07:48 Cthalupa joined
07:48 <dminuoso> simon: Do you need to use this in arithmetic?
07:49 <simon> dminuoso, in practice I would probably only need to do that on smaller numbers.
07:49 <Ariakenom> You can newtype Integer and truncate on operations. A bit of typing though
07:50 <mniip> data Word256 = W256# Word64# Word64# Word64# Word64#
07:50 sighingnow joined
07:50 <simon> mniip, funny, I was just looking at finite-typelits. :)
07:50 chele joined
07:50 <simon> (for something related)
07:51 <mniip> for finite vectors?
07:51 <simon> mniip, can I make that Word256 an instance of Integral?
07:51 <simon> yes.
07:52 <mniip> vector-sized?
07:52 <simon> I have an AST definition with a PUSHN Integer, but really only N in [1,32] is supported.
07:52 <mniip> sure you can make that an instance of Integral if you implement the arithmetic yourself
07:52 ThomasLocke joined
07:53 <Ariakenom> Word256 is more typing than going via Integer. Word256 probably uses less memory but will likely have slower ops.
07:53 <simon> and an auxiliary push :: Integral i => i -> Opcode with a boundary check built in.
07:55 yeevy joined
07:55 <mniip> Ariakenom, questionable
07:55 <simon> someone on #haskell-beginners (I forgot who, unfortunately) suggested that my Integer was suspect.
07:56 <Ariakenom> which part? runtime speculation yes very
07:56 ZeuPiark joined
07:56 <mniip> if you implement it with Word# using primitive operations it might be faster than FFI to libgmp
07:56 <mniip> with its variable limb size arithmetic
07:57 <mniip> not saying it will be but it has potential to be
07:57 <ZeuPiark> hello
07:58 <Ariakenom> mniip: Are there primitives for carry-handling? That will somehow use the flag
07:59 ogrady joined
07:59 <Ariakenom> (on x86)
07:59 bahamas joined
08:00 ozzymcduff joined
08:00 andyhuzhill joined
08:00 <simon> mniip, so there are no shortcuts to making this Word256 an instance of Integral?
08:00 <mniip> no
08:01 <mniip> Ariakenom, there are
08:01 ogrady_ joined
08:01 ogrady__ joined
08:01 boj joined
08:01 <mniip> % :t plusWord2#
08:01 <yahb> mniip: Word# -> Word# -> (# Word#, Word# #)
08:01 <mniip> % :t timesWord2#
08:01 <yahb> mniip: Word# -> Word# -> (# Word#, Word# #)
08:02 <simon> mniip, do you by chance do any Haskell stuff on Ethereum?
08:03 sgraf812 joined
08:03 <mniip> no
08:03 andyhuzhill joined
08:04 tomphp joined
08:04 <simon> okay, just checking. :)
08:04 zero_byte joined
08:05 kuribas joined
08:05 jibby joined
08:05 Cthalupa joined
08:05 acidjnk joined
08:07 scottschmidt1 joined
08:08 dhil joined
08:11 phenoble joined
08:12 slaznick joined
08:15 amar joined
08:16 lyriclaw joined
08:17 beauby joined
08:19 jibby joined
08:20 Sampuka joined
08:23 errst joined
08:23 errst_ joined
08:25 _bo joined
08:25 mariatsji joined
08:29 agander_ joined
08:29 mariatsj_ joined
08:31 mreh joined
08:33 saep joined
08:34 refold joined
08:36 <quicksilver> if you implement Word256 with hardware level vector ops it would be way faster than libgmp
08:37 <quicksilver> not saying that's easy to do, mind you.
08:37 <quicksilver> fortunately if you just want it to work, someone else has done the work for you
08:37 curious_corn joined
08:37 <quicksilver> http://hackage.haskell.org/package/largeword-1.2.5/docs/Data-LargeWord.html
08:38 Lynxium[] joined
08:40 twandy joined
08:41 xtreak joined
08:41 dxld joined
08:42 <Ariakenom> quicksilver: does it have benchmarks?
08:44 louispan joined
08:45 ziyourenxiang joined
08:45 language_agnosti joined
08:46 <Ariakenom> relevant https://gmplib.org/manual/Assembly-SIMD-Instructions.html
08:46 Scip_ joined
08:46 <quicksilver> the package I linked above is pure haskell. No SIMD.
08:47 <quicksilver> that's an interesting link but given than SSE2 is now 17 years old I wonder if that is a fully current assessment of the vector ops on modern CPUs? :)
08:48 rprije joined
08:49 <quicksilver> I really know nothing about this so I'm just guessing. But given the important of integer math in encryption algorithm and the existence of hardware acclerated AES256, I am guessing that integer support is a bit better now.
08:49 language_agnosti joined
08:49 <pacak> "type Foo a = Bool -> a" can be written as "type Foo = (->) Bool" so type signature "x :: Foo Int" is valid, how do I get rid of a in "type Pred a = a -> Bool"?
08:50 jfredett joined
08:50 <Ariakenom> Indeed. But it's worth noting that gmp does aim at being fast at all sizes, not just huge. It's not impossible to beat in this case ofc. But probably not easy.
08:51 tomphp joined
08:51 <quicksilver> pacak: you can't
08:51 <dminuoso> pacak: You cant in general.
08:51 <pacak> Thought so :(
08:51 <dminuoso> quicksilver: Is there a reason for that? It would be kind of cool to be able to write `type Predicate = (-> Bool)` (type sections would be nice)
08:52 jeltsch joined
08:52 cur8or joined
08:52 <cocreature> would be kind of confusing once you start trying to make instances for those
08:53 <quicksilver> there is an incoherence problem with arbitrarily partially applied types and instances
08:53 <quicksilver> but I can't remember how to show the example
08:53 AndreasPK_ joined
08:54 <quicksilver> newtypes keep us sane because they provide a syntactic cue the type inference algorithm can use to pick the right instance
08:54 <cocreature> even if incoherence wasn’t a problem (no idea if it is) type inference would be shitty
08:54 <dminuoso> Ah right, I forgot about type inference
08:55 <dminuoso> pacak: you could take the Op route
08:55 <dminuoso> @let type Predicate = Op Bool
08:55 <lambdabot> .L.hs:158:18: error: Not in scope: type constructor or class ‘Op’
08:55 <lambdabot> |
08:55 <lambdabot> 158 | type Predicate = Op Bool
08:55 <dminuoso> @let import Data.Functor.Contravariant
08:55 <lambdabot> Defined.
08:55 <dminuoso> @let type Predicate = Op Bool
08:55 <lambdabot> Defined.
08:56 <dminuoso> Although I suppose at that point you already have Predicate.. heh
08:56 <pacak> dminuoso: That's what I did, just with my own data type.
08:58 _vaibhavingale_ joined
08:59 ogrady joined
09:03 mnoonan joined
09:03 oish joined
09:03 agander joined
09:04 curious_corn joined
09:05 sdothum joined
09:05 Folkol joined
09:06 cloudhead joined
09:06 Scip joined
09:07 tzemanovic joined
09:08 WhatisRT joined
09:09 Boomerang joined
09:09 reactormonk joined
09:10 dpn` joined
09:12 jollygood2 joined
09:12 <jollygood2> hi. is there a pdf reading library from haskell? I just need to extract plain text out of a pdf, don't need formatting, etc
09:13 chichou joined
09:13 <jollygood2> s/from/for
09:14 <dminuoso> "I just need to extract plain text out of a pdf"
09:14 <* dminuoso> smiles regarding the choice of the word "just"
09:14 Wuzzy joined
09:15 hphuoc25 joined
09:16 <pavonia> Yes, that's a highly non-trivial task
09:17 PLPD-Bot joined
09:17 <lieven> a simple matter of programming
09:17 ddellacosta joined
09:17 cur8or_ joined
09:18 bergle joined
09:19 <dminuoso> We've had scenarios where the simplest course of action was rasterizing the image, and shoving it into OCR.
09:19 <dminuoso> That's how we had to "just extract plain text ouf of a pdf"
09:19 <lieven> yeah. these days, I would probably use calibre's ebook-convert foo.pdf foo.txt as a first stab
09:20 <jollygood2> dminuoso, PDF contains text, not a scanned image, so I think you may be exaggerating the complexity of the problem. but regardless of complexity, is there a haskell lib that does it?
09:21 <dminuoso> jollygood2: PDF has the notion of text streams yes. But without knowing more about your PDF its impossible to give a generalized solution.
09:22 <dminuoso> jollygood2: I've had to deal with PDFs using bogus charsets/font faces, overlapping text streams and so much nonsense. the most reliable general way is OCR.
09:22 RegEchse joined
09:23 tzemanovic joined
09:24 <dminuoso> PDF was not designed with extraction in mind.
09:24 <jollygood2> select-all/copy in adobe reader does good enough job extracting the text that i can further parse with regular text parser. is there a haskell library that can approximate that?
09:24 <cocreature> there are various pdf to text tools that might or might not work for your usecase. I would just shell out to one of those
09:24 <lieven> about the best that can be said about it is that it is not Turing complete like PostScript
09:25 <jollygood2> let me rephrase my question, is there *any* haskell library that can extract any type of text from pdf?
09:25 tomphp joined
09:25 <__monty__> lieven: Are you sure about that?
09:26 <Ariakenom> lieven: https://www.adobe.com/content/dam/acom/en/devnet/acrobat/pdfs/js_api_reference.pdf
09:26 <cocreature> jollygood2: just pick your favorite command line tool that extracts text from pdf and call that from your Haskell app
09:26 <quicksilver> jollygood2: you can take a look at http://hackage.haskell.org/package/pdf2line and https://hackage.haskell.org/package/pdf-toolbox-core
09:27 <lieven> Ariakenom: yeah before they added a whole fucking language to it
09:27 <quicksilver> but I have no experience of either
09:27 <cocreature> pdf2line doesn’t have an API either afaict so it’s not different from shelling out to some other tool
09:28 <dminuoso> pdf-toolbox might work, but you have to figure out how to piece text together
09:28 gawen joined
09:34 louispan joined
09:35 tomphp joined
09:37 <* hackage> servant 0.14, servant-server 0.14, servant-client-core 0.14 (phadej): https://qbin.io/diff-diet-5kln
09:37 hphuoc25 joined
09:37 catsup joined
09:38 Boreeas joined
09:38 <* hackage> servant-client 0.14 - automatical derivation of querying functions for servant webservices http://hackage.haskell.org/package/servant-client-0.14 (phadej)
09:38 youtmon joined
09:38 catsup joined
09:39 <Boreeas> Hi, how do I express infinite iteration over monads? More specifically, I want to draw random numbers until I find a suitable candidate
09:39 dpyro joined
09:39 louispan joined
09:39 <Boreeas> I thought maybe `forever $ randomRIO (lo, hi)` is what I want, but apparently this can't be evaluated lazily?
09:40 falafel joined
09:40 twandy joined
09:41 curious_corn joined
09:42 <Ariakenom> :t \x -> sequence . cycle [x]
09:42 <lambdabot> error:
09:42 <lambdabot> • Couldn't match expected type ‘a1 -> t (m a2)’
09:42 <lambdabot> with actual type ‘[a]’
09:43 <Ariakenom> :t \x -> sequence $ cycle [x]
09:43 <lambdabot> Monad m => m a -> m [a]
09:43 <dminuoso> Boreeas: Mmm something like untilM' from monad-loops?
09:44 simukis joined
09:44 fishythefish joined
09:44 <dminuoso> oh wait no more like iterateUntil
09:44 <dminuoso> @import Control.Monad.Loops
09:44 <lambdabot> Unknown command, try @list
09:44 <dminuoso> @let import Control.Monad.Loops
09:44 <lambdabot> Defined.
09:44 theelous3_ joined
09:44 <dminuoso> :t iterateUntil
09:44 <lambdabot> Monad m => (a -> Bool) -> m a -> m a
09:46 <Boomerang> Boreeas: How about using `randomRs` instead? `do gen <- getStdGen; return (randomRs (lo, hi) gen)`
09:47 <Boreeas> Does that help me? I don't mind using the global rng.
09:47 perspectival joined
09:47 sgflt joined
09:48 louispan joined
09:48 language_agnosti joined
09:48 <Boreeas> dminuoso: Thanks, that looks good
09:48 <Ariakenom> :t forever -- this doesnt return anything
09:48 <lambdabot> Applicative f => f a -> f b
09:49 pally joined
09:49 <dminuoso> Boreeas: You could trivially write this yourself though iterateUntil p m = do { a <- m; if p a then pure a else iterateUntil p m }
09:49 amar_ joined
09:49 language_agnosti joined
09:50 <Boomerang> I think it helps because `randomRs` already gives you an infinite list, so then it's just a matter of filtering it :)
09:51 <Boreeas> Oh, true, didn't think of that
09:52 <pally> @let cities = ["Hong Kong", "Tokyo", "Hamburg", "Munchen"]
09:52 <lambdabot> Defined.
09:53 <pally> > delete "Hamburg" cities
09:53 <lambdabot> ["Hong Kong","Tokyo","Munchen"]
09:53 fmixing joined
09:53 <pally> > cities
09:53 <lambdabot> ["Hong Kong","Tokyo","Hamburg","Munchen"]
09:53 <* quicksilver> <3 immutability
09:54 rzp joined
09:55 tzemanovic joined
09:56 hphuoc25 joined
09:57 pbgc joined
09:57 Linter joined
09:59 beauby joined
09:59 curious_corn joined
10:00 fmixing joined
10:00 <pally> quicksilver, I need to maintain a graph using something like [(String, [String])] -- or something like that b/c I am only interested in out-going flights
10:01 <* hackage> expressions 0.1.8 - Expressions and Formulae a la carte http://hackage.haskell.org/package/expressions-0.1.8 (jakubdaniel)
10:01 vonfry joined
10:01 <pally> quicksilver, how can I reasonably maintain it if it is immutable?
10:02 machinedgod joined
10:04 danvet joined
10:06 <pally> anyone else have a suggestion?
10:07 mimi_vx joined
10:10 zdenal joined
10:11 zdenal joined
10:11 hphuoc25 joined
10:11 <pavonia> Perhaps you are looking for mutables variables like MVar or IORef?
10:11 sakalli_ joined
10:12 <Boomerang> The simplest way without getting into state monads, or IO refs, is to just retun the graph everytime you want to modify it
10:12 <pally> Boomerang, yes, I don't want into state monads.
10:13 <pally> *don't want to get into...
10:13 <Boomerang> If your logic is already heavy on IO, an IORef/MVar is not the worst thing. But in general it's better if you can separate the pure logic of your application from the IO you need to do
10:15 <Boomerang> The same way `delete` returns "updated" version of the list. All your logic function can do the same. `filterByPopulation :: Int -> CityGraph -> CityGraph`
10:15 curious_corn joined
10:15 <quicksilver> pally: I would answer it at a different level
10:16 dogweather joined
10:16 <quicksilver> pally: your functions calculate new versions of data structures from old ones
10:16 <pally> Boomerang, for what I want to do, is maintaining a graph of cities (and out-bound flights) a hairy matter?
10:16 <quicksilver> just get used to storing the new versions that get returned from your functions
10:16 <quicksilver> it's a clearer way to think about data flow
10:16 <quicksilver> once you're comfortable about the approach, then the state monad is just a different syntax for that
10:17 <quicksilver> which reduces the syntactical burden sometimes and makes some useful combinators available.
10:17 <quicksilver> "I don't want to get into state monads" is an interesting assertion. Why not?
10:17 <Boomerang> pally: Not at all, immutability is just something you have to get used to. :) Once you get used to it, you'll see it can "compose" pretty well
10:17 danso joined
10:17 <quicksilver> I would step one is get used to the idea that functions (s -> s) or (a,s -> s) or (a,s -> b,s) are really natural composable ways to work
10:17 <pally> Boomerang, gets a lot of newcomers churning, me included ^^;
10:18 <quicksilver> step two is seeing that the state monad is just a set of combinators to make it easy to combine functions of those forms
10:19 <Boomerang> @let removeMunchenAndStartingByH = filter ((/= 'H') . head) . delete "Munchen"
10:19 earthy joined
10:19 <lambdabot> Defined.
10:20 <Boomerang> > removeMunchenAndStartingByH cities
10:20 <lambdabot> ["Tokyo"]
10:21 louispan joined
10:21 <Boomerang> @let addCity = (:)
10:21 <lambdabot> Defined.
10:21 jollygood2 joined
10:21 language_agnosti joined
10:22 <Boomerang> > foldr ($) cities [delete "Munchen", addCity "Brussels", addCity "London", delete "Brussels"]
10:22 <lambdabot> ["Brussels","London","Hong Kong","Tokyo","Hamburg"]
10:22 <Boomerang> hehe
10:22 <Boomerang> foldl would be better for this example
10:22 <pally> what is /= ?
10:23 <Boomerang> The Haskell version of !=
10:23 <jollygood2> quicksilver thanks! it was pretty simple to extract text from pdf with pdf-toolbox. output isn't very pretty as far as human readability goes, but it is good enough to run through a parsec
10:23 <jollygood2> s/a//
10:23 <__monty__> Anyone know if there's a way to get the closure of all dhall files needed to evaluate an expression?
10:23 <quicksilver> jollygood2: yay :)
10:24 <dminuoso> jollygood2: glad it worked for you:)
10:24 <Boomerang> __monty__ strace and grep? :D
10:25 knupfer joined
10:25 <pally> Boomerang, If I am not mistaken, your "removeMunchenAndStartingByH" is in what's called eta reduced form, right?
10:25 <__monty__> Boomerang: Ideally without having to evaluate the expression >.<
10:26 <* hackage> haskell-src-meta - Parse source to template-haskell abstract syntax. http://hackage.haskell.org/package/haskell-src-meta- (JonasDuregard)
10:27 alexad joined
10:28 hphuoc25 joined
10:28 <Boomerang> __monty__: I think dhall has a resolve command line option to resolve the imports without evaluating the expression. I don't think it would be too difficult to modify it so that it prints out all the imports
10:29 zdenal joined
10:31 <__monty__> Boomerang: Thank you, all I get from the dhall-to-text --help is --explain.
10:31 <Boomerang> pally: Yes this is eta reduction, it is pretty common in Haskell. I do often forget it's not the most straight forward thing for newcomers :/
10:31 keepLearning512 joined
10:31 <pally> Boomerang, `filter` expects a boolean-valued function as its first argument.
10:32 <pally> ((/= 'H') . head) . delete "Munchen"
10:32 <Boomerang> :t filter
10:32 <lambdabot> (a -> Bool) -> [a] -> [a]
10:32 <pally> : ((/= 'H') . head) . delete "Munchen"
10:32 <Boomerang> It acts as a selecting function
10:32 <pally> :t ((/= 'H') . head) . delete "Munchen"
10:32 <lambdabot> error:
10:32 <lambdabot> • Couldn't match type ‘[Char]’ with ‘Char’
10:32 <lambdabot> Expected type: [[Char]] -> [Char]
10:33 <Boomerang> :t ((/= 'H') . head) -- sorry I didn't mean to give you a confusing example
10:33 <lambdabot> [Char] -> Bool
10:33 <Boomerang> @let doesntStartWithH = (/= 'H') . head
10:33 <lambdabot> Defined.
10:34 <pally> Haskell is really a whole different beast
10:34 <Boomerang> > doesntStartWithH "Tokio"
10:34 <lambdabot> True
10:34 thblt joined
10:34 <Boomerang> > doesntStartWithH "Hamburg"
10:34 <lambdabot> False
10:35 <* hackage> composition-prelude - Higher-order function combinators http://hackage.haskell.org/package/composition-prelude- (vmchale)
10:36 language_agnosti joined
10:37 <pally> Boomerang, maybe it has to do with me not knowing what the `.` (dot) does. I need that doesntStartWithH accepts a String as argument
10:38 <pally> and `head` will return the first letter
10:38 <Boomerang> :t (.)
10:38 danvet joined
10:38 <dminuoso> @src (.)
10:38 <lambdabot> (f . g) x = f (g x)
10:38 <lambdabot> (b -> c) -> (a -> b) -> a -> c
10:38 <pally> s/need/see/
10:39 <Boomerang> @let f str = head str /= 'H' -- This is probably a simpler version of the same function :-)
10:39 <lambdabot> Defined.
10:39 tsaka__ joined
10:39 <Boomerang> > f "Hello"
10:39 <lambdabot> error:
10:39 <lambdabot> Ambiguous occurrence ‘f’
10:39 <lambdabot> It could refer to either ‘Debug.SimpleReflect.f’,
10:40 freyr joined
10:40 ijks joined
10:41 twandy joined
10:41 <jollygood2> :t not . isPrefixOf "h"
10:41 <lambdabot> [Char] -> Bool
10:42 <jollygood2> let f = not . isPrefixOf "H" in f "Hamburg"
10:42 <jollygood2> > let f = not . isPrefixOf "H" in f "Hamburg"
10:42 <lambdabot> False
10:43 sdothum joined
10:44 scottschmidt1 joined
10:46 <* hackage> hasbolt-extras - Extras for hasbolt library http://hackage.haskell.org/package/hasbolt-extras- (ozzzzz)
10:47 <Boomerang> > isPrefixOf "h" "" -- Is this function total? Just curious
10:47 <lambdabot> False
10:48 matsurago joined
10:48 <jollygood2> > isPrefixOf "" ""
10:48 <lambdabot> True
10:49 Mrd1 joined
10:50 youtmon joined
10:50 <quicksilver> > zipWith isPrefixOf ["H","S","M"] ["High","School","Musical"]
10:50 <lambdabot> [True,True,True]
10:50 <jollygood2> I guess it kind of makes sense for that to return true
10:50 <jollygood2> empty string being prefix of any string, including an empty one
10:51 Mrd1 left
10:51 HarveyPwca joined
10:51 zdenal joined
10:51 marvin2 joined
10:52 marvin2 left
10:52 marvin2 joined
10:52 zdenal_ joined
10:52 sighingnow_ joined
10:53 zdenal_ joined
10:54 sighingnow__ joined
10:56 <* hackage> require 0.3.1 - Scrap your qualified import clutter http://hackage.haskell.org/package/require-0.3.1 (NickSeagull)
10:56 alexteves joined
10:59 language_agnosti joined
11:00 stavross joined
11:03 language_agnosti joined
11:04 emilypi joined
11:05 alexteves joined
11:06 SenasOzys joined
11:12 philippD joined
11:12 encod3 joined
11:13 <simon> quicksilver, thanks for pointing to Data.LargeWord!
11:13 louispan joined
11:13 language_agnosti joined
11:15 ammazza joined
11:15 sdothum joined
11:15 isovector joined
11:16 <alexad> What's a nice simple clean way to define multiple entry points to a program in haskell, as type safely as possible? I was thinking of simply defining multiple main functions, but that seems obnoxious.
11:16 jchia_ joined
11:16 forell joined
11:16 <pally> can someone write the eta expanded version of `let f = not . isPrefixOf "H" in f "Hamburg"`?
11:16 <pally> > let f x = not . isPrefixOf "H" x in f "Hamburg"
11:16 <lambdabot> error:
11:16 <lambdabot> • Couldn't match expected type ‘a1 -> Bool’ with actual type ‘Bool’
11:16 <lambdabot> • Possible cause: ‘isPrefixOf’ is applied to too many arguments
11:16 language_agnosti joined
11:17 <isovector> i have a type family `Component a b` and my usage of it completely ignores `b`. however GHC complains that due to noninjectivity, it can't solve what `b` at the use-site. is there some way i can mark it as "who cares?"
11:17 <cocreature> pally: f x = not (isPrefixOf "H" x)
11:17 <alexad> I suppose I'm likely stuck with command line args though? What I want is to be able to run the application in "Prod, Dev, or Staging" 'mode' for which I have an ADT
11:17 <philippD> alexad: you can have the core of the project as a library and create multiple executable entries in your cabal file
11:17 <alexad> philippD, aaah, right of course
11:17 Lynxium joined
11:17 psychicist__ joined
11:17 alexteves joined
11:17 <alexad> sort of an app/ dir and a src/ dir defined both in the cabal file right?
11:17 <cocreature> for things like switching between prod,dev and staging a cli arg seems like a better solution tbh
11:18 <cocreature> is there a specific reason why you are trying to avoid that?
11:18 <isovector> like the instantiation of `b` doesn't change anything, so it seems like i should be able to mark it as incoherent or something?
11:18 sighingnow joined
11:18 logzet joined
11:18 <pally> this leads me to ask: why do you use '.' and when can you stick to just parenthesis?
11:19 <cocreature> pally: it’s a matter of taste. you can always stick to parenthesis. (.) just happens to be more convenient/readable in some cases
11:19 hphuoc25 joined
11:20 dmiles joined
11:20 jchia_ joined
11:20 drbrule joined
11:21 <dminuoso> pally: (.) focuses more about what your program is, whereas applying things by hand is more focused about data shuffling.
11:21 bahamas joined
11:21 glguy joined
11:21 <alexad> cocreature, REAFY ALL THE TYPES
11:21 dexhunter joined
11:22 ices joined
11:22 <cocreature> alexad: just make an ADT "data Environment = Dev | Prod | …" and then you have your type safety
11:22 <* hackage> servant-lucid 0.8.1 - Servant support for lucid http://hackage.haskell.org/package/servant-lucid-0.8.1 (phadej)
11:22 <dminuoso> `(f . g . h) x` tells you something about a processing pipeline you put `x` into, where as f (g (h (x))) requires extra mental effort to see whats going on. You have to track parens, see what argument is being applied to what..
11:22 <alexad> cocreature, this is exactly what I have
11:23 <cocreature> alexad: ofc you need to deal with parsing the string into that but a) optparse-applicative helps a lot with that and b) mistyping the cli arg is not that different from mistyping the executable name imho
11:23 <cocreature> alexad: then I’m not sure what exactly you dislike about this approach?
11:23 <alexad> cocreature, I concede the second point.
11:23 <alexad> cocreature, nothing really, I just like trying to think about things in new ways. Hackathon at work, best time to experiment with things I haven't done
11:23 <cocreature> in fact you could get a better error message from a misspelled cli arg than from a missing executable
11:25 nuncanada joined
11:25 sakalli_ joined
11:25 language_agnosti joined
11:26 henriksod joined
11:28 curious_corn joined
11:29 <quicksilver> alexad: launch the right but based on the value of $0
11:29 <quicksilver> and use symlinks
11:29 MRd1 joined
11:29 <quicksilver> that's the unix way :)
11:30 <MRd1> Hello
11:30 <quicksilver> simon: glad it was useful
11:30 <isovector> can i refine a `forall s. SomeTypeFamily s` so that it is `s of [S1, S2]. SomeTypeFamily s`?
11:31 sdothum joined
11:31 scottschmidt1 joined
11:32 language_agnosti joined
11:32 <dmwit> isovector: not really
11:33 <dmwit> isovector: You can write `data SRepr a where S1 :: SRepr S1; S2 :: SRepr S2` and then use `(SRepr s, SomeTypeFamily s)`.
11:34 pulse joined
11:35 Solonarv joined
11:35 <MRd1> ....
11:35 <dmwit> (That's for positive position. For negative position you can use `(SomeTypeFamily S1, SomeTypeFamily S2)`.)
11:35 vurtz joined
11:36 <isovector> dmwit: hmmmm. the real problem is i have a noninjective parameter in my type family that GHC is trying to instantiate, but it doesn't actually have any effect
11:36 encod3 joined
11:37 <dmwit> Can you leave it out?
11:38 <alexad> cocreature, quicksilver thanks guys, I changed my mind anyway cause I don't want to complicate the docker shit later anyway XD
11:39 <isovector> nope. i haev a type family `TF s t`, and when `s in [S1, S2]`, `t` is unused, but used for `S3`. i am trying to write a function that keeps `s` polymorphic but only instantiates it at `S1` and `S2`
11:39 siraben joined
11:39 <isovector> "keeps `s` polymorphic -> uses `s` as rank 2"
11:39 encod3 joined
11:41 amar_ joined
11:41 dhil joined
11:42 twandy joined
11:43 ericsagn1 joined
11:45 <veverak> hi folks
11:46 <veverak> any tips for haskell bug that focuses on practice coding?
11:46 <veverak> ;)
11:46 <cocreature> veverak: do you mean a Haskell _book_ rather than a _bug_? otherwise I don’t understand the question :)
11:47 silver joined
11:49 xtreak joined
11:49 <alexad> is there a safe Read somewhere?
11:49 <cocreature> :t readMay
11:49 <lambdabot> error: Variable not in scope: readMay
11:49 <cocreature> :t readMaybe
11:49 <lambdabot> error: Variable not in scope: readMaybe
11:49 fmixing joined
11:49 <cocreature> :t Text.Read.readMaybe
11:49 <lambdabot> Read a => String -> Maybe a
11:50 <cocreature> there we go :)
11:50 <alexad> ty
11:50 <alexad> I really need to use the new hoogle, god damn
11:51 <veverak> cocreature: book
11:51 <cocreature> veverak: haskell programming from first principles has a lot of exercises afaik
11:52 <cocreature> I think hutton’s book also has exercises
11:52 AfC_ joined
11:53 isovector joined
11:54 agander joined
11:55 <veverak> cool
11:55 <bahamas> anyone know why I'm seeing this https://lpaste.net/6695940141443186688?
11:56 wrengr joined
11:58 <hpc> because you're looking at it :P
11:59 <cocreature> bahamas: I would guess that the warnings in gcc or clang or whatever is trying to include that header might have changed since GHC 7.10 was released
11:59 <cocreature> you might also want to consider using a more recent version of GHC. 7.10 is quite old by now
11:59 <hpc> ah, yeah
11:59 <__monty__> Can you used a method from an instance of a typeclass that's not exported in an importing module?
11:59 <hpc> you're on mac, i think ghc has had issues with clang in the past?
11:59 scottschmidt1 joined
12:00 beauby joined
12:01 andyhoang joined
12:02 <bahamas> cocreature: this project is a template from the haskell book https://github.com/haskellbook/hello
12:02 <cocreature> bahamas: that doesn’t really change my recommendation :)
12:02 louispan joined
12:04 <hpc> bahamas: since you're using stack, it should be really easy to upgrade your ghc
12:05 ZeuPiark joined
12:05 <bahamas> ok, I changed stack.yaml to use lts-11.13
12:06 <hpc> btw 11.14 came out yesterday :P
12:06 <bahamas> I'm just learning how to build projects in Haskell, so I don't think I'm missing anything important
12:06 <hpc> yeah
12:07 fmixing joined
12:08 <DigitalKiwi> I thought stack was supposed to just work and solve all problems
12:08 fmixing joined
12:08 <hpc> stack is a reproducible build system
12:08 <cocreature> for some definition of reproducible :)
12:09 <hpc> if your problem is you can't make a build environment, stack definitely helps
12:09 <DigitalKiwi> it seems to reproducibly cause inconvenience
12:09 <hpc> but if your build environment has an issue, it'll be wrong all day long :D
12:09 <hpc> fixing most things is just a few lines of config though, instead of doing a bunch of environment-modifying cabal installs
12:10 patlv joined
12:10 cur8or joined
12:11 jpgarcia__ joined
12:12 tomphp joined
12:12 vukasink joined
12:12 carlomagno joined
12:12 <alexad> aah, my brain just broke. I cannot for the life of me think of what the following is...
12:12 <alexad> f a -> f b -> f (a, b)
12:13 <cocreature> :t liftA2 (,)
12:13 <lambdabot> Applicative f => f a -> f b -> f (a, b)
12:13 <alexad> cocreature, <3
12:13 connrs joined
12:13 lumm joined
12:14 andreabedini joined
12:15 <rzmt> i cant figure out how to get this to work lazily. I think i need to replace "sequence" with something else but i'm not sure what. https://lpaste.net/230380392195031040
12:16 danthemyth joined
12:17 slomo joined
12:17 slomo joined
12:17 <cocreature> rzmt: what do you mean by “making it work lazily”. do you want to start returning list elements from "main" before all requests have been performed?
12:18 <rzmt> yes
12:18 <cocreature> you probably want to look at some streaming library for that, e.g. "streaming", "conduit" or "pipes"
12:18 <rzmt> i'm using rate-limit module for the requests but i left it out from the example
12:20 youtmon joined
12:24 tsaka__ joined
12:26 osa1 joined
12:28 Linter joined
12:28 sakalli_ joined
12:31 fendor joined
12:33 keepLearning512 joined
12:34 ozzymcduff joined
12:35 OnkelTem joined
12:36 jchia_ joined
12:37 ericsagn1 joined
12:38 jao joined
12:38 reactormonk joined
12:38 remyhr joined
12:39 <alexad> is there an already defined style for what is essentially "flip <$>"
12:39 <alexad> ?
12:39 scottschmidt1 joined
12:40 <cocreature> :t (<&>)
12:40 <lambdabot> Functor f => f a -> (a -> b) -> f b
12:40 <alexad> perfect thanks
12:41 <cocreature> also the typesearch in the new hoogle is apparently shittier than I thought. even for an exact match lik "Functor f => f a -> (a -> b) -> f b" the first result is fmap and not (<&>)
12:41 <bahamas> for some reason running stack exec -- hello. anyone know what's wrong and how I can fix it?
12:42 cloudhead joined
12:42 <bahamas> I forgot one word: running the above command hangs
12:42 <cocreature> bahamas: maybe it’s just your "hello" executable that hangs?
12:43 <pally> > let removeMunchenAndStartingByH = filter ((/= 'H') . head) . delete "Munchen"
12:43 <lambdabot> <no location info>: error:
12:43 <lambdabot> not an expression: ‘let removeMunchenAndStartingByH = filter ((/= 'H') ....
12:43 paolino joined
12:43 cur8or joined
12:43 <pally> > @let removeMunchenAndStartingByH = filter ((/= 'H') . head) . delete "Munchen"
12:43 <lambdabot> <hint>:1:1: error: parse error on input ‘@’
12:43 <bahamas> cocreature: doh.
12:44 hphuoc25 joined
12:44 5EXAA7D68 joined
12:44 <Boomerang> @let x = 2 -- pally :-)
12:44 <lambdabot> Defined.
12:44 dogweather joined
12:44 <pally> @let removeMunchenAndStartingByH = filter ((/= 'H') . head) . delete "Munchen"
12:44 <lambdabot> .L.hs:167:1: error:
12:44 <lambdabot> Multiple declarations of ‘removeMunchenAndStartingByH’
12:44 <lambdabot> Declared at: .L.hs:162:1
12:44 <paolino> hi, does it make sense to {#- INLINE c #-} where c = 16 , or the compiler does it already ?
12:45 <pally> vs.
12:45 <pally> @let removeMunchenAndStartingByH x = filter ((/= 'H') . head) (delete "Munchen" x)
12:45 <lambdabot> .L.hs:173:1: error:
12:45 <lambdabot> Multiple declarations of ‘removeMunchenAndStartingByH’
12:45 <lambdabot> Declared at: .L.hs:162:1
12:45 <paolino> @unlet
12:45 <lambdabot> Define what?
12:45 dodong joined
12:45 <Hjulle> Is there any way to put type signatures on binds in do notation? e.g. something like "do { x :: Int; x <- return 5; return x}"
12:46 <pally> anyway, I wanted to say the second version is much more natural for me, and that I am still having trouble reading definitions of the first form
12:46 <Boomerang> Hjulle: ScopedTypeVariables I think :)
12:46 <paolino> Hjulle: x :: Int <- ...
12:46 <Hjulle> Thx
12:46 <Boomerang> But you might need parenthesis
12:46 <paolino> with ScopedType...
12:46 <Boomerang> (x :: Int) <- ...
12:47 <dminuoso> Hjulle: I certainly hope you're not going to do `x <- return 5` anywhere in your code.
12:47 <Hjulle> dminuoso: Of course not. It was just the simplest example I could come up with. :)
12:47 <dminuoso> Okay :)
12:48 <paolino> yeah 5 is wrong, return 42
12:48 <dminuoso> Hjulle: Additional things you can keep in your bag of tools are: TypeApplications and inline annotations: do { x <- return (5 :: Int); return x }
12:49 <dminuoso> Not explicitly recommending them, just making you aware of their existence. :)
12:50 <rzmt> cocreature: you think this would work without library? Those look nice but a bit complicated for my use
12:50 <Hjulle> paolino: You see, it's a slightly more obscure Hitchhiker reference: http://refspace.com/quotes/Douglas_Adams/Q927
12:50 <pally> Boomerang, and I'll explain why. When you specify `((/= 'H') . head) . delete "Munchen"` it almost seems like you are saying this whole thing is predicate. I get this impression from the `. delete "Munchen"` being drag into it. In the second (more explicit) version, the reader can clearly the two pieces.
12:50 <pally> Boomerang, not really, complaining, but I am having trouble reading it.
12:51 <dminuoso> pally: you just dropped the filter function there.
12:51 p0lyph3m joined
12:51 bak1an joined
12:51 Ninja3047 joined
12:51 <Hjulle> paolino: But you are still correct that 5 is wrong. :)
12:52 <pally> dminuoso, what do you mean?
12:52 nowhere_man joined
12:52 <nowhere_man> Hey all
12:52 <Boomerang> pally: I think what might help is understanding how the precendence of different infix functions work. How would you understand `f x + y` ? `(f x) + y` or `f (x + y)`?
12:52 <cocreature> rzmt: not really or at least not without reimplementing parts of the library. IO is not lazy (technically there is lazy IO but it’s a can of worms) so you can’t just rely on lazyness
12:52 <pally> dminuoso, oh... I am just highlighting the part that got me confused.
12:52 alex`` joined
12:53 <dminuoso> pally: The fact that you dropped it shows where the problem is. :-)
12:53 <nowhere_man> I don't understand something with $
12:53 <dminuoso> pally: rule #1 in Haskell: function application has highest precedence.
12:53 <Boomerang> pally: In my example the first one is correct `(f x) + y`, it's the same thing for the `.` infix operator :)
12:53 <nowhere_man> Shouldn't map ((+) 1) $ take 5 [1..1000] be the same as map $ (+) 1 $ take 5 [1..1000]
12:54 malorie joined
12:54 <dminuoso> nowhere_man: No
12:55 <dstolfa> nowhere_man: definitely not
12:55 <dminuoso> nowhere_man: You can, roughly, think that $ acts as an opening paren with a closing paren to as far right as possible.
12:55 <nowhere_man> OK
12:55 jwynn6 joined
12:55 <dminuoso> nowhere_man: so the last can be rewritten as: map ((+1) (take 5 [1..1000]))
12:55 <dstolfa> which doesn't typecheck
12:56 <paolino> Hjulle: I think x <- return 5 is not so bad and iirc you might use it taking apart existentials where let will fail
12:56 <jollygood2> > map ((+1) (take 5 [1..1000]))
12:56 <lambdabot> error:
12:56 <lambdabot> • Couldn't match expected type ‘a -> b’
12:56 <lambdabot> with actual type ‘[Integer]’
12:57 <jollygood2> you mean t(map (+1)) (take 5 [1..1000]) ?
12:57 <Hjulle> paolino: I was referring to the quote I linked. ;)
12:57 tomphp joined
12:57 <dminuoso> pally: lets pretend for a moment this was written simpler: filter predicate . delete "München"
12:58 keepLearning512 joined
12:58 <dminuoso> this associates as: (filter predicate) . (delete "München")
12:58 <pally> dminuoso, that helps :-)
12:58 kuttifunk joined
12:58 curious_corn joined
12:59 <pally> I think it has to do with me working with parens all my life
12:59 <dminuoso> LISP developer?
12:59 <pally> w/o them I have a hard time parsing.
12:59 xkapastel joined
12:59 <Hjulle> paolino: But yes, there are cases where x <- return y might be useful.
12:59 <pally> dminuoso, yes, Racket/Scheme was the immediate section before Haskell
13:00 <pally> in my course I am doing, that is
13:00 <dminuoso> Yeah Haskell folks have the opposite mentality - we prefer less parens not more. :)
13:00 stargrass1 joined
13:01 <paolino> dminuoso: that's what I thought for a long time but it's not so
13:02 <paolino> my coworker is confused by ($) and prefer parens, in the end.
13:03 <dminuoso> pally: things get a bit quirker when you use multiple operators and rely on their fixity. For example this might be a common idiom to some: f . g . h . i $ x
13:03 <dminuoso> paolino: At the very least I recommend getting used to ($) so you can read other peoples code.
13:04 <dminuoso> pally: while others might rather write that as `(f . g . h . i) x`, or perhaps just refactor it into a seperate binding
13:05 <paolino> I agree completely, I was referring to the evidence of the non-parens syntax being the best for everyone
13:05 <* hackage> wild-bind, wild-bind-x11 (debugito): https://qbin.io/gun-locked-q0m3
13:05 wc211 joined
13:06 <dminuoso> Oh I didn't suggest it was a good idea - just implied it was a common mentality. :)
13:06 <Hjulle> paolino: It's mostly a question of how used you are with it. In my exprerience $ and "." becomes intuitive fairly quickly.
13:06 <paolino> well I cannot stand lines with unbalanced parens
13:07 <quicksilver> all mixing of infix operators is a burden - you have to have a mental model of how the precedence works. On the other hand if you have a good mental model it can be faster to read than balancing parens in your head
13:07 <pally> So I am not a lonely newbie, it seems like this is a common area where ppl have trouble with.
13:07 <quicksilver> therefore it's a tradeoff
13:08 <dminuoso> pally: that topic could be expanded to: how to write code that is easy to read
13:08 mizu_no_oto joined
13:08 <dminuoso> And that's always going to be a tradeoff
13:09 keepLearning512 joined
13:09 m1dnight1 joined
13:10 <nowhere_man> Hjulle: I concur, as a Lisper fond of parens, I still quickly got used to reading and writing with $ and .
13:11 <alexad> I'm slowly going mad, can anyone spot my idiocy in here? https://pastebin.com/LMJR6qj4
13:12 tomphp joined
13:12 <cocreature> alexad: what’s the type of slKeyText?
13:12 <* hackage> funflow 1.0.1 - Workflows with arrows http://hackage.haskell.org/package/funflow-1.0.1 (nclarke)
13:12 <DigitalKiwi> alexad that you posted it as haskell but it is actually an error message
13:13 dogweather joined
13:13 <alexad> cocreature, ByteString
13:13 <cocreature> alexad: you sure about that? the error message strongly suggests that it is of type Jwk
13:14 tomphp joined
13:14 <alexad> slKeyText <- C.lookup conf "IdentityKeys.Speedledger" :: IO (Maybe ByteString)
13:15 <dminuoso> alexad: Are you building with intero?
13:15 <cocreature> can you just show us the full code or at least a bit more context?
13:15 <alexad> cocreature, sure
13:15 vks_ joined
13:15 pzp joined
13:15 <pzp> Why do we need for and forM and traverse and mapM?
13:16 keepLearning512 joined
13:16 <cocreature> pzp: we don’t, we only have them for historic reasons
13:16 <alexad> huh, I deleted some test stuff further up and the error disappeared
13:16 alex``` joined
13:16 bo joined
13:17 <pzp> cocreature: because applicative came after monad?
13:17 <dminuoso> alexad: You're not using intero, are you? =)
13:17 <cocreature> pzp: yeah
13:17 <alexad> dminuoso, sorry, went to respond to that... I believe intero requires stack? This is a plain cabal project.-
13:18 <nowhere_man> cocreature: what are they replaced with in Applicative?
13:19 <cocreature> nowhere_man: traverse is the Applicative version of mapM and for is the applicative version of forM
13:19 jchia_ joined
13:19 camsbury joined
13:19 <Hjulle> Is there any proposal yet for introducing total pattern matching binds for do-notation in Haskell similar to that in Agda or Idris? http://docs.idris-lang.org/en/latest/tutorial/interfaces.html#pattern-matching-bind
13:19 <dminuoso> pzp: also the flipped versions exist just for convenience. Sometimes `for` looks a bit nicer than `traverse`
13:20 <dminuoso> pzp: especially when using with a lambda. e.g.: for [1,2,3,4] $ \n -> ...
13:20 avn joined
13:22 <vks_> I am a beginner in Haskell and reading "http://learnyouahaskell.com/syntax-in-functions". In the first example given for pattern matching, I get error on GHCI console. Has functional declaration changed in 8.4?
13:22 <vks_> Prelude> lucky :: (Integral a) => a -> String <interactive>:1:1: error: Variable not in scope: lucky :: a1 -> String Prelude>
13:22 alex```` joined
13:22 <dminuoso> vks_: Use :{ ... :} for multiline definitions in GHCi.
13:22 <dminuoso> vks_: Alternatively you can use a semicolon and put everything on a single line.
13:23 jchia_ joined
13:23 <Taneb> vks_: if you wrote what you were going to write in a file and then loaded it in, that would have worked fine.
13:23 <vks_> Let me try in a min
13:23 <Taneb> vks_: this is because GHCi likes things to be inputted all at once, which in GHCi normally means on one line
13:24 <Taneb> So it gets upset that you've given a type signature for something that doesn't exist
13:24 <Taneb> And if you did it the other way round it would get upset that you've given a type signature for something that already has a type, I think
13:24 fmixing joined
13:24 <jollygood2> was 'x = 10' always legal in ghci? I think I was getting error in earlier versions
13:25 <cocreature> jollygood2: I think it was added in 8.0?
13:25 <cocreature> it definitely wasn’t always supported
13:25 <edwardk> jollygood2: they figured out how to make it parse more common-looking definitions like that a few releases ago
13:25 <vks_> Taneb_: Thank You. I loaded it in file and ghci did not complain.
13:26 <Taneb> vks_: :)
13:26 <Taneb> vks_: hope you enjoy Haskell!
13:27 agander joined
13:27 jchia_ joined
13:27 <rzmt> cocreature: any tips how to fix this? I get compile error "Couldn't match type ‘ConduitT i0 String m0’ with ‘IO’" at 11:3 https://lpaste.net/3435208602476871680
13:28 <cocreature> rzmt: you can use liftIO to get from IO a to ConduitT i o IO r
13:28 <cocreature> *ConduitT i o IO a
13:29 aweinstock joined
13:30 bahamas joined
13:30 bahamas joined
13:30 dfeuer joined
13:30 mreh joined
13:32 ystael joined
13:32 emilypi joined
13:33 jchia_ joined
13:34 jchia_ joined
13:36 jchia_ joined
13:36 <vks_> Integral, Int and Integer - What is the difference between these type classes ? I wanted to use a factorial function and wanted to restrict to Int but compiler did not allow. Code : https://lpaste.net/8964721401118326784
13:37 <dminuoso> vks_: two of them are not typeclasses but types.
13:37 <rzmt> cocreature: nice, it works now. How about getting requestSource to work recursively? `yieldMany requestSource` isn't enough
13:37 <dminuoso> vks_: Int is machine sized and bounded, Integer is unbounded but boxed and slower.
13:37 amirpro joined
13:38 <dminuoso> vks_: You tried to use `Int` as a typeclass which doesn't work.
13:38 <p0lyph3m> factorial :: Int -> Int || factorial :: Num x => x -> x
13:39 <vks_> dminuosa_: Got it. Is this hierarichal relationship documented in haskell docs?
13:39 <dminuoso> vks_: You can use tab completion to save yourself some typing and mistyping names. dmin<TAB> or something along those lines. :)
13:40 <vks_> dminuoso: New to IRC. Thanks !
13:41 jchia_ joined
13:41 halogenandtoast joined
13:42 amirpro joined
13:42 vks__ joined
13:43 danso joined
13:43 lastmanstanding joined
13:44 <dminuoso> vks__: http://academic.udayton.edu/saverioperugini/courses/cps343/lecture_notes/images/typeclass.png
13:44 <dminuoso> The typo in Integral aside that appears to show the hierarchy of some of the haskell typeclasses
13:47 fendor joined
13:47 <vks__> dminuoso: Thank You. This is helpful.
13:48 dogweather joined
13:49 tomphp joined
13:49 dogweath_ joined
13:53 ijks joined
13:54 carlomagno joined
13:56 <* hackage> tar-conduit - Extract and create tar files using conduit for streaming http://hackage.haskell.org/package/tar-conduit- (MichaelSnoyman)
13:56 <pally> +
13:57 dbmikus joined
13:59 keepLearning512 joined
14:00 antsanto joined
14:00 pfurla joined
14:01 beauby joined
14:02 keepLearning512 joined
14:03 antsanto joined
14:03 <alexad> cocreature, what are the chances you can instantly tell me the name of this: (b -> b -> c) -> Either a b -> Either a b -> Either a c
14:04 <nowhere_man> I can't find it in the doc: how can I debug in GHCi a program working on its standard input?
14:04 <Taneb> :t liftA2
14:04 <lambdabot> Applicative f => (a -> b -> c) -> f a -> f b -> f c
14:05 <Taneb> :t liftA2 :: (b -> b -> c) -> Either a b -> Either a b -> Either a c
14:05 <* hackage> servant-generic - Specify Servant APIs with records. http://hackage.haskell.org/package/servant-generic- (PatrickChilton)
14:05 <lambdabot> (b -> b -> c) -> Either a b -> Either a b -> Either a c
14:05 <Taneb> alexad: ^
14:05 <alexad> oh right it's a special case of liftA2
14:05 <alexad> ty
14:06 ozzymcduff joined
14:07 <alexad> <3
14:07 sakalli_ joined
14:08 <cocreature> rzmt: just have requestSource call itself?
14:08 ddellacosta joined
14:10 codesoup joined
14:10 <alexad> Spend an hour trying to fix my types to all use Either with aeson so I can figure out where the parse is failing...
14:10 <alexad> Keyring could not be loaded, reason: Error in $: Failed reading: satisfy
14:10 <alexad> ... -_-
14:11 webstrand joined
14:11 lassulus_ joined
14:12 <butterthebuddha> "Yeah, I know, I know: the function returns a value representing an IO effect, which inverts the control: now the caller has explicit control over the effect (in imperative programming, it’s the callee that has control, which makes reasoning harder)."
14:12 <butterthebuddha> I don't really understand that statement
14:13 <nowhere_man> butterthebuddha: I would guess that when something returns an IO value, you as a caller can choose to execute it or not
14:13 <nowhere_man> in typical imperative programming, you call a function and it doesn't return an effectful function you might call, it does something
14:15 zariuq joined
14:15 <butterthebuddha> nowhere_man: Uhh, you can choose to not execute a IO effect? Can you give me an example?
14:15 plugin joined
14:15 curious_corn joined
14:15 <mnoonan> @let butter = print "HI!"
14:15 <lambdabot> Defined.
14:15 <mnoonan> ^ I didn't see "HI!" printed :)
14:16 <Ariakenom> > length [butter, butter, print "bye"]
14:16 <Taneb> > length [print 1, print 2, print 3]
14:16 <lambdabot> 3
14:16 <lambdabot> 3
14:16 SpinTensor joined
14:16 <dminuoso> butterthebuddha: Haskell has no effects in the evaluation. That's kind of the point of IO.
14:16 ozataman joined
14:16 <Ariakenom> :p
14:16 <dminuoso> butterthebuddha: `IO Int` is a *description* of an effect that, when executed, would produce an Int.
14:16 <nowhere_man> blew my mind when I got that, BTW
14:17 <butterthebuddha> mnoonan: but that's due to laziness right?
14:17 <dminuoso> butterthebuddha: And the trick to Haskell is, that something like `execute :: IO a -> a` does not exist. (Well it does, but we should not talking about that)
14:17 <butterthebuddha> You didn't call the function butter
14:17 <dminuoso> butterthebuddha: No.
14:17 <butterthebuddha> So Haskell didn't evaluate the definition
14:17 <dminuoso> You can evaluate it just fine.
14:17 taktoa joined
14:17 <dminuoso> > let (!a) = print "1" in ()
14:17 <lambdabot> ()
14:17 <mnoonan> butterthebuddha: yeah, Ariakenom and Taneb's examples are better
14:18 kapil___ joined
14:18 <dminuoso> mnoonan: in all fairness length doesn't need to evaluate the content of the list, just the spine.
14:18 <dminuoso> so lazyness could explain it.
14:19 <mnoonan> true
14:19 <dminuoso> butterthebuddha: You can experiment with the `pseq` primitive to force evaluation in GHCi.
14:19 <nowhere_man> in GHCi, I changed stdin to be a handle to a file, but getLine still reads from the terminal…
14:20 <dminuoso> butterthebuddha: `putStrLn "foo"` is an object that describes the effect of printing something. Evaluating that description does nothing.
14:20 <butterthebuddha> Right, you'd have to put it in the context of main
14:20 <Ariakenom> :t many getLine
14:20 <lambdabot> IO [String]
14:20 <butterthebuddha> But isn't that the same as calling printf from a function in C that doesn't get called by main?
14:20 hackebeilchen joined
14:21 <nowhere_man> butterthebuddha: main is just another IO
14:21 <dminuoso> butterthebuddha: No it's more analogous to passing the "name of the function" around.
14:21 <nowhere_man> Haskell's *runtime* takes the IO description in main and executes it
14:21 <butterthebuddha> nowhere_man: but with special compiler magic that actually causes the effects to happen?
14:22 <dminuoso> butterthebuddha: not compiler magic, its just the rts.
14:22 <butterthebuddha> dminuoso: I'm sorry, I'm confused :(
14:22 <nowhere_man> You can think of the core of your program's binary as an interpreter for IO
14:22 <dminuoso> butterthebuddha: getLine is not a function. It's a piece of paper that reads "Note to the RTS: When you see me, please get some input from stdin"
14:23 adkron_ joined
14:23 <dstolfa> butterthebuddha: IO is really just a "recipe" that is implemented using unboxed types in GHC and exposed as a monad to the programmer. somewhere deeper in the compiler (as is usually the case with programming languages), you implement a runtime that actually has effects
14:23 <dminuoso> butterthebuddha: Obviously you can duplicate that thing many times - but when that piece of paper ends up being thrown in the garbage can the RTS will be none the wiser.
14:23 abs-zero[m] joined
14:24 reactormonk joined
14:24 language_agnosti joined
14:24 <butterthebuddha> I understand all of this; here's where I'm getting confused - this might have been misinterpretation on my part but it seems you're implying that I can make a call to a function that returns an IO because of a call to some effectful computation
14:24 leonardys joined
14:24 dogweather joined
14:24 <mnoonan> there is some blog post that builds up a kind of mini-IO by hand that might help understand what is going on
14:24 <dstolfa> butterthebuddha: if you're familiar with erlang's BIFs, that's basically what you end up doing in the end, but in a bit of a different way
14:24 <butterthebuddha> and choose to have that effectful computation not produce any effects?
14:24 <mnoonan> can't find it right now :|
14:25 <dminuoso> The SPJ paper should be great
14:25 mrBen2k2k2k joined
14:25 <dstolfa> butterthebuddha: haskell is CBN, so yes, you might end up with just a bunch of IOs that haven't been executed yet and are dispatched to the RTS all at once
14:25 <dstolfa> just as you might end up with a bunch of functions being composed, and if none of them is strict w.r.t. their arguments, you'll just do CBN all the way through
14:25 <butterthebuddha> dstolfa: but in what sense as the programmer do I have control over the effects?
14:26 <dminuoso> butterthebuddha: You can choose to throw the effects away, sequence them with other things..
14:26 plugin joined
14:26 <butterthebuddha> Also, what does CBN stand for?
14:26 <dstolfa> butterthebuddha: call by name, lazy eval
14:27 <butterthebuddha> dminuoso: Can you be more explicit about what "throw the effects away" means? Sorry, I'm just trying to make sure I don't misunderstand anythign
14:27 <pally> > applyArg :: a -> (a -> b) -> b
14:27 <lambdabot> error:
14:27 <lambdabot> Variable not in scope: applyArg :: a1 -> (a1 -> b1) -> b1
14:27 <hexagoxel> but if you have an IO Int, and you want to get at that Int, you don't have much of a choice really. There is no way to get that Int without executing whatever the IO part does.
14:27 <dminuoso> butterthebuddha: So let's say you have a function: f :: Int -> (IO (), Char)
14:27 <pally> oops. (nvm this one)
14:27 <dstolfa> > f :: Int -> (IO (), Char)
14:27 leonardys joined
14:27 <dminuoso> butterthebuddha: You can apply that to an integer, use pattern matching to get the Char out - and disregard the IO () effect.
14:27 <lambdabot> error:
14:27 <lambdabot> Ambiguous occurrence ‘f’
14:27 <lambdabot> It could refer to either ‘Debug.SimpleReflect.f’,
14:27 <dstolfa> argh
14:27 <dstolfa> what was it again
14:27 mariatsji joined
14:27 <dstolfa> not this again
14:28 <dstolfa> > foo :: Int -> (IO (), Char)
14:28 <lambdabot> error:
14:28 <lambdabot> • Variable not in scope: foo :: Int -> (IO (), Char)
14:28 <lambdabot> • Perhaps you meant ‘for’ (imported from Data.Traversable)
14:28 <dstolfa> i give up
14:28 <dstolfa> i suck at lambdabot
14:28 <butterthebuddha> dminuoso: but if the IO () was due to a call to putStrLn for example, that will still print something right?
14:28 <dminuoso> butterthebuddha: No because the `IO ()` is the *description* of that printing action
14:28 <dminuoso> butterthebuddha: putStrLn is not a function you call and it prints things.
14:29 <jollygood2> butterthebuddha, here's an example of a difference. int x = puts("hi"); <- at the moment you called puts side effect of printing to stdout has been made. not so in haskell. let x = putStrLn "hello, world". x contains the action that prints to the screen. the act of calling putStrLn "hello, world" did not print to the screen, it just returned instructions in the form of IO () to do so. and this is not related to laziness, which
14:29 <dmwit> > let f :: Int -> (IO (), Char); f n = (print n, toEnum n) in snd (f 32) -- does not print 32
14:29 <lambdabot> ' '
14:30 <butterthebuddha> Oh. So given an IO, what must I explicitly do to it to execute it?
14:30 <dminuoso> butterthebuddha: fiddle it into `main`
14:30 <dmwit> butterthebuddha: Only `main` is ever executed. Any other `IO` actions you construct, but which do not figure into the chain of binds that makes up `main`, are not executed.
14:30 <pally> actually I do need help with this
14:31 epsilonhalbe joined
14:31 <pally> @let applyArg :: a -> (a -> b) -> b
14:31 <lambdabot> .L.hs:169:1: error:
14:31 <lambdabot> The type signature for ‘applyArg’ lacks an accompanying binding
14:31 <lambdabot> |
14:31 <pally> > applyArg :: a -> (a -> b) -> b
14:31 <lambdabot> error:
14:31 <lambdabot> Variable not in scope: applyArg :: a1 -> (a1 -> b1) -> b1
14:31 epsilonhalbe left
14:31 bahamas joined
14:31 <dmwit> pally: You have to give an implementation, not just a type.
14:31 <dmwit> pally: Do you know how to implement it? (Do you want spoilers?)
14:32 <dmwit> ?let example :: Int -> Int; example x = 3*x + 5
14:32 <lambdabot> Defined.
14:32 <dmwit> > example 70
14:32 <lambdabot> 215
14:32 <pally> yes it's `applyArg :: a -> (a -> b) -> b`
14:32 <pally> applyArg x = ($ x)
14:32 <pally> from https://stackoverflow.com/questions/19521246/what-does-mean-do-in-haskell
14:32 <dmwit> pally: See above for the syntax to use.
14:33 <dminuoso> butterthebuddha: so let's say your program was: `main = getLine` when you run that program the RTS will execute the getLine action and carry out the actual effect.
14:35 <dminuoso> butterthebuddha: Next up you might have: `main :: IO (); main = getLine >>= putStrLn` -- first we build a single IO () effect by taking the `getLine :: IO String` and plumbing it into `putStrLn :: String -> IO ()` - the result being a larger effect. If this program is ran, it execute the first action, place the result into the next function, determine that effect and run it too.
14:37 sqrt2 joined
14:38 ian_andrich joined
14:40 cloudhead joined
14:41 <alexad> butterthebuddha, I can recommend if you want a collection of programming exercises that really help one to grok various FP concepts
14:41 <pally> example taken from the above SOF answer
14:42 <pally> ?let applyArg :: a -> (a -> b) -> b ; applyArg x = ($ x)
14:42 <lambdabot> Defined.
14:42 <pally> > applyArg 3
14:42 <lambdabot> error:
14:42 <lambdabot> • No instance for (Typeable b0)
14:42 <lambdabot> arising from a use of ‘show_M688882654012430906026151’
14:42 <shapr> alexad: ooh, which collection?
14:43 codesoup joined
14:44 zdenal joined
14:44 FF6 joined
14:45 plugin joined
14:46 abhiroop joined
14:46 dodong joined
14:47 FreeBirdLjj joined
14:47 <maerwald> how do you evaluate IO to NF? :>
14:47 urodna joined
14:48 FF6 left
14:50 enterprisey joined
14:51 <Boomerang> > applyArg 3 even
14:51 <lambdabot> False
14:51 <Boomerang> > applyArg 3 odd
14:51 <lambdabot> True
14:53 <pally> Boomerang, by now, i understand type signature, but since the body it's trying to match pattern `applyArg x` and that's why I invoke it as such
14:53 <pally> > applyArg 3
14:53 <lambdabot> error:
14:53 <lambdabot> • No instance for (Typeable b0)
14:53 <lambdabot> arising from a use of ‘show_M559030206662384635026217’
14:54 paolino joined
14:54 keepLearning512 joined
14:54 <Boomerang> The issue is you can't show a function :)
14:54 <Boomerang> :t applyArg 3
14:54 <lambdabot> Num a => (a -> b) -> b
14:55 fmixing joined
14:55 <pally> Boomerang, the next example in that SOF answer is also interesting
14:55 <pally> > map ($ 10) [(+1), (+2), (+3)]
14:55 <lambdabot> [11,12,13]
14:55 <pally> :t map
14:55 <lambdabot> (a -> b) -> [a] -> [b]
14:55 <pally> my friend, `10` is not a function
14:56 <Boomerang> :t ($ 10)
14:56 <lambdabot> Num a => (a -> b) -> b
14:56 <alexad> shapr, Tony's https://github.com/data61/fp-course
14:56 <abs-zero[m]> :t fold
14:56 <lambdabot> (Monoid m, Foldable t) => t m -> m
14:56 merijn joined
14:56 <dmwit> pally: `10` is also not the argument given to `map`.
14:56 <shapr> alexad: oh that's cool
14:57 <pally> dmwit, it's not?
14:57 <dmwit> pally: no
14:57 <dmwit> `($10)` is
14:57 <dmwit> > map (applyArg 10) [(+1), (+2), (+3)] -- in your notation from above
14:57 <lambdabot> [11,12,13]
14:58 Linter joined
14:58 ozzymcduff joined
14:59 HarveyPwca joined
15:00 lykrysh joined
15:01 tax joined
15:01 beauby joined
15:03 <marvin2> butterthebuddha this might help with your undertanding. it builds a mini IO-like datatype on top of haskell's IO. http://web.archive.org/web/20171213122129/http://chris-taylor.github.io/blog/2013/02/09/io-is-not-a-side-effect/
15:03 hphuoc25 joined
15:05 dbmikus_ joined
15:06 bertschneider joined
15:07 malorie joined
15:09 eschnett joined
15:09 thunderrd joined
15:10 language_agnosti joined
15:10 HarveyPwca joined
15:12 <vks__> alexad: Thank you for sharing fp-course
15:12 DSM joined
15:12 <alexad> vks__, no worries
15:12 <dminuoso> butterthebuddha: Incidentally this is what makes debugging Haskell code somewhat tricky. Luckily there are primitives that can do `IO a -> a`, but they are unsafe to use and generally exist for debugging and a few other things.
15:13 bbrodriguez joined
15:14 reactormonk joined
15:16 UnChallengeD joined
15:17 amirpro joined
15:18 Boomerang joined
15:18 tomphp joined
15:18 __monty__ joined
15:19 Noldorin joined
15:19 danvet joined
15:20 <marvin2> dminuoso in what way is Debug.Trace unsafe?
15:20 <pally> :t $
15:20 <marvin2> I know it uses unsafePerofrmIO under the hood, but I'm not sure how their use is unsafe in practice
15:20 <lambdabot> error:
15:20 <lambdabot> parse error on input ‘$’
15:20 <lambdabot> Perhaps you intended to use TemplateHaskell
15:20 <pally> :t ($)
15:20 <lambdabot> (a -> b) -> a -> b
15:21 <dminuoso> marvin2: well `trace` itself is not a big issue, but unsafePerformIO is as it allows you to circumvent the type syste
15:21 <marvin2> sure
15:22 <pally> Is it true to say even those parens are for better readibility?
15:22 <philippD> pally which ones?
15:22 <pally> :t ($)
15:22 <lambdabot> (a -> b) -> a -> b
15:22 <marvin2> btw I wish there was a native support for something like Debug.Trace in ghci, that doesn't require adding temporary Show contrains everywhere
15:23 <philippD> pally: the ones arount ($) or the ones in the type (a -> b) -> a -> b
15:23 <philippD> pally: the answer would be no for both though :D
15:23 <pally> the ones in the type
15:23 slaznick left
15:24 <pally> I'll explain why I am asking this
15:24 <philippD> a -> b -> a -> b is the same as a -> b -> (a -> b) but not the same as (a -> b) -> a -> b
15:25 camsbury joined
15:25 raichoo joined
15:25 fendor joined
15:25 hphuoc25 joined
15:26 lainon joined
15:26 DSM joined
15:26 lambda-11235 joined
15:27 <dminuoso> marvin2: we have :print at least which is pretty cxool =)
15:28 <pally> okay let's try this again. so this is what `:t ($)` tells us
15:28 <pally> :t ($)
15:28 <lambdabot> (a -> b) -> a -> b
15:28 <pally> and I do:
15:28 <pally> > $ abs 3
15:28 <lambdabot> <hint>:1:1: error:
15:28 <lambdabot> parse error on input ‘$’
15:28 <lambdabot> Perhaps you intended to use TemplateHaskell
15:29 <pally> > ($ abs 3)
15:29 <lambdabot> error:
15:29 <lambdabot> • No instance for (Typeable b0)
15:29 <lambdabot> arising from a use of ‘show_M385346935543881866226393’
15:29 <dminuoso> pally: to use operators in prefix position you have to wrap them in ()
15:29 <dminuoso> > ($) abs 3
15:29 <lambdabot> 3
15:29 lethe25 joined
15:30 <philippD> yeah but what you just did is apply abs to ($)
15:30 <philippD> :t (($) abs)
15:30 <lambdabot> Num b => b -> b
15:30 djbeau joined
15:30 <dminuoso> philippD: wrong way around.
15:30 <dminuoso> philippD: I applied ($) to abs
15:30 <nshepperd> it would be cool if ghc had some kind of debug compilation mode which makes everything printable
15:30 <dminuoso> `f x` means f is applied to x
15:30 <shapr> my abs are rich
15:30 <* shapr> does more Haskell exercise
15:31 <philippD> dminuoso yeah you're right
15:31 <nshepperd> propagating Show constraints everywhere out of some polymorphic function i'm trying to debug, then removing them again when done, gets really tedious
15:31 <philippD> the brackets in the type still matter
15:31 curious_corn joined
15:31 <* hackage> rio-orphans - Orphan instances for the RIO type in the rio package http://hackage.haskell.org/package/rio-orphans- (MichaelSnoyman)
15:32 owiecc joined
15:32 pera joined
15:32 <philippD> :t ($ 3)
15:32 <lambdabot> Num a => (a -> b) -> b
15:33 elfets joined
15:33 camsbury joined
15:33 dhil joined
15:34 <* hackage> rio - A standard library for Haskell http://hackage.haskell.org/package/rio- (MichaelSnoyman)
15:34 avn joined
15:34 ozataman joined
15:34 <quicksilver> nshepperd: yes, it would.
15:35 lumm joined
15:35 suk joined
15:35 hvr joined
15:36 <nowhere_man> is it OK to post a StackOverflow question here?
15:36 cschneid joined
15:37 language_agnosti joined
15:37 <mitchellsalad__> yeah
15:37 <dminuoso> nowhere_man: Probably yes. Though some people are not happy if you immediately repost questions all over the place, so its better to wait a bit until you are convinced you are not getting a response. =)
15:38 <pally> let's see the difference,
15:38 <pally> :t ($) 3
15:38 <lambdabot> Num (a -> b) => a -> b
15:38 FreeBirdLjj joined
15:39 <dminuoso> pally: the difference is basically: (\x -> x $ 3) vs (\x -> 3 $ x)
15:39 suk joined
15:42 <* hackage> servant-multipart 0.11.2 - multipart/form-data (e.g file upload) support for servant http://hackage.haskell.org/package/servant-multipart-0.11.2 (phadej)
15:44 seveg joined
15:45 Khisanth joined
15:45 <quicksilver> nowhere_man: it's fine IMO
15:45 <quicksilver> we like having interesting discussions about haskell and we like helping people
15:46 patlv joined
15:47 <* hackage> servant-swagger-ui-core 0.3.1 - Servant swagger ui core components http://hackage.haskell.org/package/servant-swagger-ui-core-0.3.1 (phadej)
15:48 christin joined
15:48 khilan joined
15:49 cur8or joined
15:49 remyhr joined
15:49 borkr joined
15:50 cloudhea1 joined
15:51 obi_jan_kenobi__ joined
15:51 remyhr joined
15:52 comerijn joined
15:52 <* hackage> butter - Monad Transformer for Asyncronous Message Passing http://hackage.haskell.org/package/butter- (mpahrens)
15:52 scottschmidt1 joined
15:54 <* hackage> forkable-monad - An implementation of forkIO for monad stacks. http://hackage.haskell.org/package/forkable-monad- (mpahrens)
15:54 ian_andrich_ joined
15:57 brandly joined
15:58 iAmerikan joined
15:59 _noblegas joined
15:59 <pally> I actually don't understand the second one.
15:59 <pally> :t ($) 3
15:59 <lambdabot> Num (a -> b) => a -> b
15:59 <pally> perhaps an usage example will help
16:00 <nowhere_man> https://stackoverflow.com/questions/50931355/how-can-i-test-a-program-reading-from-stdin-in-ghci/50932360
16:00 <pally> the type parameter (a->b) is for which entity?
16:01 cloudhea1 joined
16:01 Gurkenglas joined
16:02 pio_ joined
16:02 <geekosaur> you told it to apply 3 as a function, so now it wants a Num instance for a function so it knows how to apply 3
16:02 keepLearning512 joined
16:03 <pally> geekosaur, but 3 is not a function, 3 is just 3 (a numeric literal).
16:03 <geekosaur> numeric literals are polymorphic
16:03 <geekosaur> internally it's (fromInteger (3# :: Integer)), where (3#) represents an internal representation
16:04 <geekosaur> ghc does not know that "numbers are just numbers". it knows that
16:04 <geekosaur> :t 3
16:04 <lambdabot> Num p => p
16:04 <geekosaur> so it looks for a Num instance for functions
16:05 humanoyd joined
16:05 fmixing joined
16:05 <geekosaur> and being able to create that instance is sometimes even useful
16:06 fendor joined
16:06 UnChallengeD joined
16:06 <pally> geekosaur, as it stands, simply put, `$) 3` is really not what a person want
16:07 <pally> wants*
16:07 <geekosaur> it's not what you want
16:08 gabcoh joined
16:08 <* [exa]> thinking about Num (-> a) instance and matiyasevich theorem
16:08 <geekosaur> partial application is "not what a person wants". lazy evaluation is "not what a person wants". functional programming is "not what someone who knows OOP wants". etc.
16:08 son0p_ joined
16:09 lastmanstanding joined
16:09 deepfire` joined
16:09 bbrodriguez joined
16:10 fmixing joined
16:10 abhiroop joined
16:11 rihards joined
16:11 <Cale> If we had an instance of Num for functions, then it would be possible to make sense of ($) 3
16:12 <Cale> and that's what the type is telling you
16:12 <nowhere_man> geekosaur: reminds me of an interesting talk, "From Dependency injection to Dependency Rejection", where Mark Seemann shows how just partial application in an impure fonctional language is a way of doing OOP dependency injection
16:12 <[exa]> gödel numbers yay
16:12 <Cale> 3 needs to be a function in order for that to make sense -- and it could be, were an appropriate instance of Num to exist
16:13 <pally> Cale, yes, and that concept is really foreign to me.
16:13 <Cale> Well, here let's make one
16:13 <geekosaur> which is the poont of what I said
16:13 <geekosaur> it's foreign to you. it's not nonsense.
16:13 <geekosaur> it has its uses
16:13 gabcoh joined
16:13 vks_ joined
16:13 <geekosaur> (granted, not many. so you just don't define that instance)
16:13 vurtz joined
16:14 <Cale> @let instance Num b => Num (a -> b) where { (f + g) x = f x + g x; (f * g) x = f x * g x; negate f x = negate (f x); fromInteger n x = fromInteger n; signum f x = signum (f x); abs f x = abs (f x) }
16:14 <lambdabot> Defined.
16:15 <Cale> > (sin^2 + cos^2) 4.6
16:15 <lambdabot> 1.0
16:15 <[exa]> <3
16:15 <Cale> > (sin + 1) 1
16:15 <lambdabot> 1.8414709848078965
16:16 alx741 joined
16:16 asheshambasta joined
16:17 stavross joined
16:17 Jeanne-Kamikaze joined
16:18 gabcoh joined
16:19 vilu joined
16:19 <[exa]> > (negate negate) 5
16:19 <lambdabot> 5
16:20 <[exa]> ok this is cool.
16:20 DSM joined
16:21 <electrocat> :O
16:21 halogenandtoast joined
16:21 <electrocat> cool :D
16:21 <Cale> > ($) 3 7
16:21 <lambdabot> 3
16:22 <wz1000> @let x = id
16:22 <lambdabot> .L.hs:183:1: error:
16:22 <lambdabot> Multiple declarations of ‘x’
16:22 <lambdabot> Declared at: .L.hs:166:1
16:22 <maerwald> is there a haskell alternative to lambda-paste?
16:23 <geekosaur> wz1000, all the single-letter names are taken by simple-reflect
16:23 <geekosaur> :t x
16:23 <wz1000> > let x = id in (x^3 + 3*x^2 + 3) 10
16:23 <lambdabot> error:
16:23 <lambdabot> Ambiguous occurrence ‘x’
16:23 <lambdabot> It could refer to either ‘Debug.SimpleReflect.x’,
16:23 <lambdabot> 1303
16:23 GladBoi left
16:23 gabcoh joined
16:24 language_agnosti joined
16:24 Azel joined
16:24 oisdk joined
16:25 dbmikus_ joined
16:25 curious_corn joined
16:26 amar_ joined
16:27 <pally> > (abs + abs) - 3
16:27 <lambdabot> <Integer -> Integer>
16:27 <pally> > (abs + abs) -3
16:27 <lambdabot> <Integer -> Integer>
16:27 jao joined
16:27 Linter joined
16:27 al-damiri joined
16:28 amar__ joined
16:28 slomo joined
16:28 slomo joined
16:29 gabcoh joined
16:30 reactormonk joined
16:30 valentinbuza joined
16:30 <pally> Cale, can you briefly explain which entity the type parameter (a->b) constrains in your definition above?
16:30 pykello joined
16:31 <Cale> pally: hm?
16:31 <Cale> I don't understand your question
16:31 altjsus joined
16:31 dpyro joined
16:31 <Cale> I wrote an instance of Num for functions of type (a -> b)
16:32 <Cale> on the basis that we have an instance of Num for the type b
16:32 <* hackage> steeloverseer - A file watcher and development tool. http://hackage.haskell.org/package/steeloverseer- (SchellScivally)
16:32 <Cale> So, this allows us to do a few things: it defines the arithmetic operations like (+) and (*) for functions
16:33 <Cale> and it gives us the ability to interpret integer literals such as 3 as functions
16:33 dbmikus joined
16:33 <Cale> (in particular, they get interpreted as constant functions)
16:34 <pally> > (abs + abs) -3
16:34 <lambdabot> <Integer -> Integer>
16:34 <Solonarv> there's actually a more general version of that instance: you can do the same thing for any Applicative, not just (->) a
16:34 gabcoh joined
16:34 Ariakenom joined
16:35 <__monty__> Could someone take a look at this bit of the implementation of dhall? I don't understand how `zoom stack State.get` results in all of the imports recursively for an expression? (If that's even what happens.) https://github.com/dhall-lang/dhall-haskell/blob/master/src/Dhall/Import.hs#L657
16:36 <c_wraith> __monty__: are you familiar with zoom ?
16:37 camsbury joined
16:37 <Solonarv> Cale: https://lpaste.net/4069994667062591488
16:37 diwo joined
16:38 <__monty__> c_wraith: No, and not with State or monad transformers either. As I understand it the get gets the `Status` and the zoom stack extracts a list of Imports from that Status.
16:38 alexteves joined
16:39 <c_wraith> __monty__: zoom is part of the lens library. It works with MonadState to "focus" the state on a smaller part of the total state within an expression
16:39 connrs joined
16:39 webstrand joined
16:39 gabcoh joined
16:39 <c_wraith> :t zoom
16:39 <lambdabot> Zoom m n s t => LensLike' (Zoomed m c) t s -> m c -> n c
16:39 <__monty__> c_wraith: So it projects out the `_stack`?
16:40 WhatisRT joined
16:40 <c_wraith> __monty__: within the context of MonadState, yes
16:40 <Cale> Solonarv: That instance is schematically okay, but won't be very useful in practice, due to overlapping with other instances.
16:40 <c_wraith> __monty__: of course, the only thing it's doing in the subcomputation is just returning the current state.
16:40 <c_wraith> __monty__: so the end result is yes, it's projecting out the stack component of the current state.
16:41 <Solonarv> yeah, that instance should probably be for a newtype. I was just pointing out that your (->) instance is a specialization of this one.
16:42 <__monty__> c_wraith: And how come that has all the imports? I figured the evalStateT in loadWithContext would pass in an emptyStatus and therefor imports would be empty?
16:42 Psybur joined
16:43 sakalli_ joined
16:43 WhatisRT_ joined
16:44 <c_wraith> __monty__: note that that's only the first pattern for loadStaticWith
16:44 <c_wraith> __monty__: there's also https://www.cs.ox.ac.uk/jeremy.gibbons/publications/iterator.pdf
16:44 <c_wraith> __monty__: err, sorry, C&P error
16:44 gabcoh joined
16:44 <c_wraith> __monty__: there's also https://github.com/dhall-lang/dhall-haskell/blob/master/src/Dhall/Import.hs#L721
16:45 <mreh> could I make this type more generic with typeclasses?=? :: [a] -> RandT StdGen [] a
16:45 <alexad> does ! denote something as being strict?
16:45 <mreh> There's MonadRand, but nothing for list
16:46 <c_wraith> __monty__: I would expect that case will alter the list of imports in the current state.
16:46 <glguy> alexad: It can in some contexts if you're using bang patterns extension
16:46 <c_wraith> alexad: in some cases, to WHNF only
16:46 <c_wraith> glguy: you don't need an extension to use it in data types
16:46 pipahask joined
16:46 <alexad> data JwtContent = Unsecured !ByteString | Jws !Jws | Jwe !Jwe deriving (Show, Eq)
16:46 <alexad> is what I'm looking at
16:47 <c_wraith> Yeah, that indicates the field is evaluated to WHNF when the constructor is.
16:47 dodong joined
16:47 <c_wraith> (It's a very operational view, but strictness is mostly an operational concern anyway)
16:47 slomo joined
16:47 slomo joined
16:48 oisdk joined
16:48 <pally> With Cale's Num instance for functions created, I thought (abs + abs) -7 would yield 14
16:49 <c_wraith> pally: you need parens around (-7), otherwise it will parse it as subtraction
16:49 merijn joined
16:50 gabcoh joined
16:52 cloudhead joined
16:52 vks_ joined
16:55 danthemyth joined
16:56 osa1 joined
16:57 <geekosaur> that's a known wart in the language (negative literals)
16:57 serendependy joined
16:58 zdenal joined
16:59 gefeo joined
17:00 HarveyPwca joined
17:00 gabcoh joined
17:01 <mreh> subtract 7
17:01 <mreh> oh
17:01 gefeo left
17:01 <domenkozar> need a bit of help with optparse-applicative. I have a subparser with commands that consume a sum type. I'd also like to add --version handling to result into Version term for the sum type. I've tried using alternative, but I can't use switch and probably need to just fail on case of no flag?
17:01 vks_ joined
17:02 <reactormonk> I'm debugging some typelevel programming with nested instances. From what I understand, there's no way besides digging through dump-tc-trace to figure out why a typeclass is required?
17:02 gefeo joined
17:02 language_agnosti joined
17:02 beauby joined
17:03 amar_ joined
17:05 <* hackage> language-lua 0.11.0 - Lua parser and pretty-printer http://hackage.haskell.org/package/language-lua-0.11.0 (EricMertens)
17:05 davr0s joined
17:05 chat_ joined
17:06 gabcoh joined
17:06 <maerwald> what is typelevel programming?
17:06 kritzefitz joined
17:06 <johnw> I usually think of it as meta programming
17:07 sdressel joined
17:07 <maerwald> except meta programming is a widely used term
17:07 <johnw> yep
17:07 sdothum joined
17:08 <__monty__> But you're not programmatically creating a program are you? You're just doing some calculations at typecheck time instead of at run time.
17:08 oisdk joined
17:08 <__monty__> Not sure my use of just is justified ; )
17:08 <johnw> what is the result of those calculations?
17:09 <__monty__> Ah type.
17:09 <__monty__> *a
17:09 <johnw> yeah, at compile time, your writing code that produces a value needed by the compiler
17:09 <__monty__> Hmm, I see what you did there.
17:09 <glguy> I think "type-level programming" is just a more specific term than meta-programming, which could encompass something like Template Haskell
17:10 <johnw> yes, agreed glguy
17:10 <maerwald> yeah, any macro sytem is meta programming
17:10 valentinbuza joined
17:10 Arcaelyx joined
17:10 <johnw> i'd even further specialize this case to "type class meta programming"
17:10 <johnw> where you game the instance resolution mechanism to do some work for you
17:10 eruditass joined
17:11 <glguy> For me "type-level programming" suggests you're making a mess of things with type families
17:11 <johnw> instance lookup can be a cheap way to reflect on nested type structures
17:11 gabcoh joined
17:11 <dstolfa> maerwald: i don't think that's a very precise way to describe anything. if by type-level programming you meant the fact that types can depend on terms, types and are polymorphic, we may be talking about the calculus of constructions for example
17:12 woodson joined
17:12 <maerwald> I didn't mean anything
17:12 <johnw> we're just being pedantic because it's early somewhere and not everyone has had their coffee?
17:12 <dstolfa> maerwald: oh i see, i missed the part above
17:13 <dstolfa> maerwald: sorry :)
17:13 <dstolfa> johnw: i'm not being pedantic because i want to be a pain in the arse, i'm being pedantic because i want to understand the question fully before i can start answering it
17:14 <maerwald> I was just wondering if "type level programming" is just a fancy way of saying "I do haskell"
17:14 <johnw> dstolfa: admirable
17:16 tsaka__ joined
17:16 gabcoh joined
17:17 <domenkozar> ah I was looking for flag' :)
17:17 <__monty__> maerwald: No, haskell's not even the most suitable language for type-level programming.
17:17 phenoble joined
17:21 gefeo joined
17:23 t7 joined
17:23 <c_wraith> maerwald: type-level programming is broad. It means any case where type resolution is used to do computation. Sometimes it's useless. Sometimes it's a cute toy. Sometimes it improves type-safety. Sometimes it improves usability.
17:24 conal joined
17:24 <maerwald> https://github.com/seliopou/typo
17:24 <dstolfa> c_wraith: sometimes it proves theorems, sometimes it finds isomorphisms :)
17:25 Gurkenglas joined
17:26 louispan joined
17:26 gienah joined
17:27 <reactormonk> Yeah, I'm using a mix of typeclasses and type families to improve usability (I hope)
17:27 detrumi joined
17:27 dfeuer joined
17:28 pipahask joined
17:29 <quicksilver> some people, when seeing a problem, select typeclasses... now they have Problem n => n problems.
17:29 t8 joined
17:29 <c_wraith> > show (1, [(True, "hello", ()), (False, "goodbye", ())]) -- Haskell98 type-level programming. Instance resolution is used to generate the code for show.
17:29 <lambdabot> "(1,[(True,\"hello\",()),(False,\"goodbye\",())])"
17:30 encod3 joined
17:30 <c_wraith> Haskell98 is very limited at the type level. That's about as interesting as it gets.
17:30 <c_wraith> But there are very many more things that fit the definition.
17:31 <quicksilver> haskell98 does typeclass-polymorphic recursion, I think?
17:31 <quicksilver> that's a powerful tool in the wrong hands.
17:31 connrs joined
17:31 <c_wraith> That's true. It's a bit more complex
17:31 paidnode joined
17:32 <c_wraith> > let f :: (Show a) => Int -> a -> String ; f 0 x = show x ; f n x = show (x, x) in f 3 ()
17:32 <lambdabot> "((),())"
17:32 <maerwald> has anyone deployed lambda-paste? There appears to be zero documentation
17:33 <c_wraith> err, wow, I messed that up
17:33 <c_wraith> > let f :: (Show a) => Int -> a -> String ; f 0 x = show x ; f n x = show (f (n - 1)x, f (n - 1) x) in f 3 ()
17:33 <lambdabot> "(\"(\\\"(\\\\\\\"()\\\\\\\",\\\\\\\"()\\\\\\\")\\\",\\\"(\\\\\\\"()\\\\\\\"...
17:33 enterprisey joined
17:33 <c_wraith> yeah, that looks right/wrong. :)
17:33 tomphp joined
17:34 <dmwit> > let f :: Show a => Int -> a -> String; f 0 x = show x; f n x = f (n-1) (x,x) in f 3 ()
17:35 <lambdabot> "((((),()),((),())),(((),()),((),())))"
17:35 t7 joined
17:35 <dmwit> Yours only ever uses `Show ()` and `Show (String, String)`.
17:35 <c_wraith> Ah, right
17:36 <dfeuer> quicksilver: wrong hands?
17:36 klugez joined
17:36 <* hackage> butter - Monad Transformer for Asyncronous Message Passing http://hackage.haskell.org/package/butter- (mpahrens)
17:37 <quicksilver> exercise for the reader: f :: (Show a) => Int -> a -> String to show (^)N copies of a in the sense of knuth up-arrow notation
17:38 jaspervdj joined
17:40 dpyro joined
17:40 danso joined
17:40 camsbury joined
17:41 klugez joined
17:42 zdenal joined
17:43 Deide joined
17:43 encod3 joined
17:45 darjeeling_ joined
17:46 Wrex joined
17:48 diwo joined
17:50 matt__ joined
17:52 Xal joined
17:53 <* hackage> streamly 0.3.0 - Beautiful Streaming, Concurrent and Reactive Composition http://hackage.haskell.org/package/streamly-0.3.0 (harendra)
17:53 merijn joined
17:53 tzemanovic joined
17:54 <Gurkenglas> quicksilver, but up-arrow notation, besides the number N of arrows which you seem to have provided, requires two values.
17:55 <quicksilver> a very good point
17:55 <quicksilver> still, it wasn't my most serious suggestion :)
17:55 <suzu> hmm
17:55 <suzu> so i can't do this
17:57 <suzu> class Foo s a where
17:57 tylerdmace joined
17:57 <suzu> foo :: s -> a
17:57 <suzu> err
17:57 <suzu> foo :: a -> x
17:57 <suzu> for some concrete x
17:57 <suzu> because ghc can't tell what the s would be from just using `foo` somewhere
17:58 twandy joined
17:58 <suzu> is there any way "around" this? i want s to be "anything" like the forall used in ST
17:58 <Tuplanolla> @let class Foo s a | a -> s where foo :: a -> ()
17:58 <lambdabot> Defined.
17:58 <cocreature> having a functional dependency for an unused type parameter seems weird
17:58 <cocreature> why not just remove the type parameter in that case
17:58 <suzu> i need to instantiate it to the value of a different type parameter which is not allowed to leak
17:59 <suzu> to prevent values of this typeclass from leaking
17:59 reactormonk joined
17:59 <cocreature> you can add a Proxy argument to foo
17:59 bahamas joined
17:59 <suzu> y..eah but that's gross :(
17:59 <cocreature> or probably AllowAmbigousTypes + type applications work as well
17:59 <glguy> Maybe make it work the gross way first
18:00 <suzu> i'm afraid of AllowAmbiguousTypes
18:00 <glguy> and then we'll be able to see what you're doing and help from there
18:00 <glguy> This doesn't sound like a job for typeclasses
18:00 <suzu> i have an example put together that i can paste
18:01 FreeBirdLjj joined
18:01 <cocreature> yeah you seem to be trying to create multiple typeclass instances for a single type but your solution is not to just give up on trying to use a typeclass for this but instead you add another type parameter
18:01 noipmups joined
18:02 <quicksilver> the ST trick requires you to tag each value you want to keep safe/consistent with the s
18:02 <suzu> https://pastebin.com/XHFNPZwT
18:02 <quicksilver> note that every value calculated "inside" the ST monad has a type like 'ST s a'
18:02 <quicksilver> you need that s in the type to do the safety.
18:02 <suzu> i am trying to use the ST trick in a monad where it will accept varidaic-arity actions and execute them
18:03 <pally> > map ($ 10) [(+1), (+2), (+3)]
18:03 <lambdabot> [11,12,13]
18:03 <pally> :t ($ 10)
18:03 <lambdabot> Num a => (a -> b) -> b
18:03 <glguy> suzu: The "ST trick" comes from the run function having a rank-2 type
18:03 <pally> are `(+1)`, `(+2)` functions?
18:04 <glguy> :t (+1)
18:04 <lambdabot> Num a => a -> a
18:04 <glguy> yup, it has the shape: _ -> _, so it's a function
18:04 <suzu> so how do i get 'runAction' here to have a rank2 type
18:04 <suzu> runAction :: (forall s. IsAction s a) => a -> Env s a
18:05 theelous3 joined
18:05 davr0s joined
18:05 <suzu> this doesn't work
18:05 lainon joined
18:05 <suzu> nor does moving the a inside or moving both s and a outside
18:05 <cocreature> how is that supposed to work? IsAction constrains the thing to some kind of function but then you try to convert it to Env which is a wrapper around IO?
18:05 <cocreature> where do the funciton arguments come from?
18:06 <glguy> suzu: I don't know how to fix that class because I don't see what it's supposed to do
18:06 <suzu> they're passed in by runAction but that stuff isn't important here
18:06 <cocreature> I feel like you are mixing up the runST trick with a printf like trick for no good reason
18:06 RegEchse joined
18:07 Destol joined
18:07 lortabac_ joined
18:07 <cocreature> but I agree with glguy. too much of this code is just stubs so it’s hard to tell what it’s actually supposed to do
18:08 <suzu> so, what i want to do is be able to transform a function that takes any number of Unleakable arguments or numeric arguments and wrap it and execute it in this environment
18:08 lykrysh joined
18:08 <suzu> so i have a printf-like typeclass to capture functions like that, and it is encoded in the IsAction typeclass
18:09 <suzu> the problem is that these functions return an action at the very end in IO
18:09 <cocreature> how about you write the ugly implementation with a Proxy and then we look at how we can improve upon that?
18:09 Wrex joined
18:10 chessai joined
18:10 <suzu> and so they can take those unleakable values and write them to an ioref living outside the env and use them elsewhere
18:10 Big_G joined
18:11 <suzu> ok, let me work on this example a bit more and then present it again
18:12 XMunkki joined
18:13 huxing joined
18:14 twandy joined
18:15 replay joined
18:15 klugez joined
18:16 Tspoon_ joined
18:17 XMunkki joined
18:18 pykello joined
18:19 language_agnosti joined
18:19 <orion> I'm trying to explain to a co-worker the difference between evaluation and execution. Does anyone know of a good article detailing the difference?
18:19 ozzymcduff joined
18:20 <dstolfa> orion: how do you define evaluation and how do you define execution?
18:20 philippD joined
18:21 twandy joined
18:22 <orion> dstolfa: My understanding is that when a program is compiled, it is evaluated to be single value of type IO () (named "main"). That value is pure.
18:22 <orion> Execution is a separate step that takes place.
18:23 enterprisey joined
18:24 <dstolfa> orion: ah, in that sense. sure, you could evaluate something without ever executing it if your separation is between compile time and run time. i don't think it's a very good separation to think of it as "evaluation" and "execution", but instead should be thought of at what happens at compile-time and what happens at run-time
18:24 <[exa]> orion: that's a good semantic explanation, yes
18:24 <cocreature> dstolfa: evaluation still happens at runtime
18:25 <dstolfa> cocreature: not necessarily.
18:25 <dstolfa> cocreature: compilers can evaluate things at compile-time, especially when they use powerful enough of a type theory
18:25 <cocreature> sure but evaluation can be dependent on user input and then the best compiler is not going to be able to evaluate it at compile-time
18:25 <cocreature> so labeling evaluation as “compile-time” doesn’t describe it particularly well
18:26 bahamas joined
18:26 <dstolfa> cocreature: yeah, but that doesn't mean it always happens there. that's why i said it's a bad way to think about it and instead thinking of it as compile-time vs run-time is easier to understand
18:26 <cocreature> what? my whole point here is that compile-time vs run-time is wrong
18:27 twandy joined
18:27 zachk joined
18:27 zachk joined
18:27 <cocreature> thinking about it as compile-time vs run-time when the things that fall into the “compile-time” category very often _have_ to happen at run-time is just confusing
18:27 <dstolfa> cocreature: i think you're misunderstanding what i'm trying to say (possibly through my fault as well). i'm saying that thinking of evaluation and execution isn't as easy to understand as it is to understand as to what happens at runtime and what happens at compile time in a particular program (i'm not making an analogy to the former, i'm saying the former is probably not the best way to think about it)
18:28 <cocreature> ah, sry then I completely misunderstood you. I think we then actually agree :)
18:28 <dstolfa> cocreature: yeah, i didn't point out the thing i was trying to say as clearly as i should have :)
18:29 <glguy> A common way to distinguish "evaluation" from "execution" when explaining how IO works in Haskell is that evaluation is what happens to determine what Haskell value an expression has through reducing function applications, performing pattern matches, branching on conditionals, etc
18:29 bbrodriguez joined
18:30 <glguy> execution is the process of running the various effects of IO: writing and reading files, updating references
18:30 DSM joined
18:30 twopoint718 joined
18:31 abhiroop joined
18:32 <glguy> these processes interleave
18:32 patlv joined
18:32 <EvanR> or happen in parallel?
18:33 <p0lyph3m> orion: think like this : you evaluate expressions to a value ; a common type of expression is your haskell program. it evaluates to a value main :: IO that when run in a RTS gets executed.
18:33 zdenal joined
18:33 joelb joined
18:33 beauby joined
18:33 ijks joined
18:35 <maerwald> how do you evaluate IO to NF?
18:35 mizu_no_oto_work joined
18:35 <EvanR> :t rnf
18:35 <lambdabot> error: Variable not in scope: rnf
18:35 plugin joined
18:36 Cale joined
18:36 <maerwald> EvanR: IO is not of NFData
18:36 <EvanR> i see that now
18:36 <maerwald> maybe we need to execute it :>
18:36 <glguy> IO itself is abstract, so the process of evaluating it to figure out what primitives to run are the RTS's problem
18:36 osa1 joined
18:37 vks_ joined
18:37 <maerwald> can we say that "main" forces NF evaluation of "dependent" IO and as such execution?
18:38 u__ joined
18:38 <dfeuer> maerwald: does what?
18:38 <maerwald> does what?
18:38 whaletechno joined
18:39 <u__> so i realize this is a pretty lazy and shortsighted thing i want to do but: is there any way to un-escape strings within Show output?
18:39 <dfeuer> What do you mean by "forces NF evaluation of 'dependent' IO and as such execution?"
18:39 <p0lyph3m> maerwald: main :: IO yields a value that is an action when its ever performed by the RTS
18:39 <maerwald> p0lyph3m: I am aware
18:39 <dfeuer> u__: like you said, this is a pretty lazy and shortsighted thing to do. So ... don't.
18:39 bor0 joined
18:39 <maerwald> but that is very fuzzy terminology
18:40 <cocreature> u__: newtype and write the Show instance you want?
18:40 <maerwald> so isn't the actual thing just that 1. IO is not of NFData and there is no function to evaluate to NF and 2. this is basically done by execution of main?
18:40 <EvanR> > read (show "wahahaha\\")
18:40 <lambdabot> *Exception: Prelude.read: no parse
18:40 <u__> cocreature: oh duh
18:40 <dfeuer> It's best to imagine IO as an operational monad, or if you prefer as the AST for a limited imperative language.
18:40 <u__> thanks
18:41 <u__> well
18:41 <maerwald> I'm not talking about imagination currently
18:41 <cocreature> u__: ofc that comes with problems if you have some weird characters in your Show instance
18:42 <maerwald> EvanR: what do you think of that proposal?
18:42 <glguy> maerwald: Yes, evaluation of IO actions is driven by execution by the runtime
18:42 ratsch joined
18:42 <u__> dfeuer: i just need to make this output legible before lunch, i know its a hack
18:42 <EvanR> maerwald: having trouble following. dependent IO ?
18:43 <maerwald> evaluation chain
18:43 <EvanR> whats the proposal
18:43 <dfeuer> u__: well, you can drop 1 to remove the leading paren. To remove the trailing paren, dropEnd n xs = zipWith const xs (drop n xs).
18:44 <maerwald> EvanR: to say that there is no function to evaluate IO to NF (because it's not an instance of NFData) and that this evaluation happens by main
18:44 ratschance joined
18:44 <maerwald> so execution, like glguy said
18:45 <maerwald> maybe that's not useful for beginners
18:45 <dmwit> maerwald: No, evaluating an IO action to NF does not execute the IO.
18:45 <maerwald> dmwit: but how do you evaluate it to NF?
18:45 <dmwit> maerwald: No, execution of main does not force it to NF.
18:45 <dmwit> maerwald: You don't. Why do you ask?
18:46 <EvanR> since you cant see IO actions, like, as expression primitives, not sure what NF would mean
18:46 <maerwald> mh
18:46 <EvanR> the question of what main "does" is valid, but i would think the answer involves the literal effects exhibited in the code
18:46 <EvanR> rather than evaluation
18:46 <dmwit> > read "\"\SOH\"" -- u__
18:46 <lambdabot> *Exception: Prelude.read: no parse
18:47 <dmwit> > read "\"\SOH\"" :: String -- u__
18:47 <lambdabot> "\SOH"
18:47 <dmwit> Oh, that didn't even show what I wanted it to show.
18:47 <dmwit> Yikes, my Haskell isn't so hot today.
18:47 <u__> lol
18:47 <dmwit> > read "\"\\SOH\"" :: String -- u__
18:47 <u__> fun with escaping
18:47 <lambdabot> "\SOH"
18:47 <dmwit> There. That did show what I want.
18:47 lainon joined
18:48 <glguy> That works for top-level strings being shown
18:48 <glguy> but it won't work for strings nested in some larger show output
18:48 <EvanR> escaping is funny because every "just understands it", but not really. when it comes to reverse it rather than comprehend it, gotta rewrire your brain
18:48 dodong joined
18:48 taktoa joined
18:48 <EvanR> language games
18:49 <dmwit> > reads "\"\\SOH\"foo" :: [(String, String)] -- glguy
18:49 <lambdabot> [("\SOH","foo")]
18:49 <u__> speaking of dumb Show hacks, groom is pretty convenient
18:49 conal joined
18:49 <glguy> > show ("an","example")
18:49 <lambdabot> "(\"an\",\"example\")"
18:49 <dmwit> In case of empty lists, `dropWhile (/='"')`.
18:50 <glguy> anyway, lunch!
18:50 pykello joined
18:51 emilypi joined
18:52 <dmwit> > let unescapeLol [] = []; unescapeLol s = case (reads s, break (=='"') s) of ([(here, later)], _) -> here ++ unescapeLol later; (_, (earlier, here)) -> earlier ++ unescapeLol here in unescapeLol (show ("an","example")) -- glguy
18:52 twanvl joined
18:52 <lambdabot> "(an,example)"
18:52 ahihi joined
18:53 dented42 joined
18:54 comerijn joined
18:54 <suzu> glguy cocreature https://pastebin.com/76ujHWFw
18:54 <suzu> i've implemented most of the stubs and added some more detail
18:54 <u__> dmwit: thanks
18:54 <u__> i will actually use this for a few hours, because the newtyping idea doesn't give me the right indentation when combined with groom
18:54 <u__> lol
18:55 <suzu> this sample doesn't compile. i don't know why the types won't unify
18:56 <suzu> any help is appreciated
18:57 connrs joined
18:57 <cocreature> suzu: you haven’t enabled ScopedTypeVariables
18:57 <suzu> oh i am an idiot lol.
18:57 <suzu> thought i thought ranktypes enables that
18:57 <suzu> though *
18:58 <suzu> ok i enabled that and it changed nothing
18:58 Linter joined
18:58 <cocreature> it should help with the instance
18:58 <cocreature> you need an explicit forall for it to take effect in "runAction"
18:58 <suzu> i spoke too soon, you are correct
18:58 <cocreature> but in the instance you also don’t need it, you can just pass on the proxy instead of trying to construct a new one
18:59 <suzu> ok yup that works
18:59 <suzu> 79-81 have errors though
18:59 <electrocat> oh, split sections is nice, much better results than split objs :)
18:59 <suzu> 80-81 should be illegal. 79 should work
18:59 <cocreature> it looks like you are missing a do block?
19:00 <suzu> >.< yes
19:00 <suzu> ok. last issue now is that first `runAction` invocation doesn't unify
19:01 Wrex joined
19:01 skeet70 joined
19:01 Urdnot_Wrex joined
19:01 camsbury joined
19:01 <suzu> no instance for IsAction s0 (Unleakable s1 -> Unleakable s1 -> IO ())
19:02 <cocreature> it seems like you are trying to rely on typeclass resolution to force unification and that’s just not how typeclass resolution works
19:02 abhiroop joined
19:04 <cocreature> I’m not sure I get what the arguments that are being passed to the function are supposed to be.
19:04 <suzu> it's just going to be a series of `MkUnleakable 0`
19:04 <cocreature> right but what’s the point of this? what’s the underlying goal here?
19:04 <suzu> i want to execute functions with variadic arguments, inside the environment
19:05 agander joined
19:05 <cocreature> but what’s the point of having a function that accepts a variadic number of identical constants?
19:05 <suzu> the underlying reason is i'm working on bindings for a javascript vm. i wish to take "regular" hs functions and transform them into functions that i can pass to C to expose them to the javascript vm
19:06 <suzu> a variadic number of identical constants is used just as an example
19:06 <cocreature> so where would the arguments come from if they are not all identical constants?
19:07 ahihi joined
19:07 <suzu> they come from some external source of data
19:08 <cocreature> how are you going to access the external source of data from your typeclass instance?
19:08 <suzu> the environment will source data from someplace and pass it to these functions
19:08 <cocreature> I am not trying to troll you here, I honestly don’t understand what you are hoping to gain from these variadic functions
19:08 <suzu> yes, i understand
19:09 <suzu> so suppose i wrote a function `Int -> Int -> IO Int`, which has the implementation `liftM (+)`
19:10 <cocreature> that doesn’t typecheck
19:10 amar joined
19:10 <cocreature> :t liftM (+)
19:10 <lambdabot> (Num a, Monad m) => m a -> m (a -> a)
19:10 <suzu> uh whoops
19:10 <suzu> `\a b -> return $ a + b`
19:11 <suzu> so i then need to take this hs function and create a C function to expose to the bindings
19:12 <suzu> there are rules ot this: each type must have a js analog
19:12 noipmups joined
19:12 <suzu> so i have this implemented under a typeclass
19:12 vks_ joined
19:12 <suzu> and this works. but now i want them to also be able to take some special values that i would like to be unleakable
19:13 ozataman joined
19:15 herr_jth joined
19:17 Arcaelyx joined
19:17 agander joined
19:18 lumm joined
19:19 patlv joined
19:19 andyhoang joined
19:20 camsbury joined
19:20 vukasink joined
19:20 agander_ joined
19:21 oisdk joined
19:22 altjsus joined
19:22 <cocreature> it feels like you want something more like this https://gist.github.com/cocreature/1acd71b309d83bc9b5b07777fdb719b1
19:23 <cocreature> however, that doesn’t work because you can’t use a polymorphic type in the instance
19:24 ozzymcduff joined
19:24 oisdk joined
19:24 <suzu> you mean the `forall s.` in the type?
19:24 <suzu> hmm i see
19:24 <cocreature> yep
19:25 <cocreature> so you probably need to manage to move the forall in the signature of runAction somehow
19:25 pfurla joined
19:25 <cocreature> so something like "runAction :: (forall s. f s) -> Env" (which is fairly close to runST
19:25 <cocreature> )
19:26 <cocreature> but then you can’t make it work when f is a function
19:26 danthemyth joined
19:27 acertain joined
19:27 mariatsji joined
19:27 worch joined
19:27 <suzu> okay i got it to compile
19:27 <suzu> except the illegal functions compile too
19:28 <suzu> by rewriting my typeclass instance: instance (IsAction s tail, s ~ s1) => IsAction s (Unleakable s1 -> tail) where
19:29 <cocreature> nothing forces the "s" to be polymorphic
19:29 troydm joined
19:30 epsilonhalbe joined
19:31 lumm_ joined
19:32 epsilonhalbe left
19:33 <suzu> ok i got this to work just the way i want
19:33 abhiroop joined
19:34 kapil___ joined
19:35 acidjnk joined
19:35 <suzu> so i changed the typeclass instance as above
19:36 raingloom joined
19:36 <suzu> and then rewrote runEnv's signature to runEnv :: (forall s. Env s a) -> IO a
19:36 <suzu> otherwise it is not rank2
19:39 dogweather joined
19:39 <suzu> cocreature
19:40 lumm joined
19:40 mounty joined
19:40 <zachk> has anyone worked with websocket servers in haskell here? my connections aren't properly dying after an abnormal client disconnect
19:40 ozzymcduff joined
19:40 oisdk joined
19:40 <cocreature> suzu: nice!
19:41 darjeeling_ joined
19:41 tomboy64 joined
19:42 zdenal joined
19:42 <Ariakenom> I haven't been paying attention. Is it different people asking about websockets every other day? Is it popular and|or full of issues?
19:42 abhiroop joined
19:45 dpyro joined
19:45 mounty joined
19:46 scottschmidt1 joined
19:46 ian_andrich_ joined
19:47 <geekosaur> same person in this case. and from what I've seen, most questions about websockets are people who don't understand websockets
19:48 <geekosaur> (this one… websockets are faked on top of normal http. what exactly is supposed to tell the server the client went away?)
19:50 Ariakenom joined
19:51 lumm joined
19:54 merijn joined
19:54 <zachk> Ariakenom, I asked yesterday, I have them working these days for the most part, I have asked how to get them working on and off over the past year or so, now I just have "hang up" problems with them
19:54 diwo joined
19:55 <zachk> geekosaur, I am relying on an exception to kill an execution thread and relying on the thread dying to finish cleanup, I looked at the websocket code and it seems to throw an exception most of the time, for the parts I could understand/follow
19:55 <geekosaur> the problem is deeper than that
19:56 <geekosaur> websockets are not actual sockets. they're tagged data on HTTP connections, which may not be persistent
19:56 <geekosaur> which means the only way to find out something went away *unexpectedly* is a timeout, which may need to be long because it might otherwise trigger on a slow network link
19:56 <zachk> isn't there an underlying persistent socket, that should raise a read/send error when it's closed ?
19:57 <geekosaur> "HTTP connections, which may not be persistent"
19:57 <zachk> yea I just got the bright idea to modify forkPingThread, lets see if it works
19:57 <zachk> oh
19:57 crestfallen joined
19:57 <geekosaur> IOW no, there is no underlying persistent anything except in the browser. if the browser dies unexpectedly, no state anywhere
19:58 stavross joined
19:58 <rihards> hey, anyone here familiar with Streamly? i was wondering whether there is an easy way to generalise my existing functions which work on lists to also work on Streamly streams. as an example - for stuff that depends on using `map` i think i should be able to switch my type signatures like :: Num a => [a] -> [a] to :: (Functor f, Num a) => f a -> f a (Streamly streams have functor instances). but how about stuff that depends on `take`, `siz
19:58 <rihards> e`, `minimum` and others?
19:58 lumm joined
19:59 <zachk> i thought they upgraded the http connection to a "permanent" tcp connection that used a messaging protocol
19:59 <zachk> well thats what I thought websockets did
19:59 lumm joined
20:00 mizu_no_oto_work joined
20:01 <rihards> i started thinking something like this could be possible after reading the awesome "Functor design patter" blog post on haskellforall http://www.haskellforall.com/2012/09/the-functor-design-pattern.html there at the end the author mentions monad morphisms which seemed to do something similar that i'm trying to do but i'm not sure that they apply here
20:02 <rihards> or should i just better forget about supporting plain lists and convert everything straight to Streamly streams and to use functions from Streamly.Prelude?
20:03 tsoernes joined
20:03 <geekosaur> there's a bunch of things websockets was supposed to do… and then there's what actually happens, which as usual for web stuff isn't quite the same thing
20:04 <jared-w> "quite"
20:04 <jared-w> Pretty sure websockets were gonna cure cancer at one point?
20:06 <Rembane> Sounds good. Did they?
20:06 davr0s joined
20:06 <cocreature> rihards: once you step outside of what Functor and Monoid provide (those are probably the only two relevant instances that [] and streamly’s types have in common), you can’t really do anything to support both short of coming up with your own typeclass that provides the operations you use (or try to make the types in Streamly an instance of some other class that provides these functions)
20:07 <DigitalKiwi> I still don't have cancer so it must have worked
20:09 mreh joined
20:09 zephyz joined
20:09 lambda-11235 joined
20:11 <rihards> concreature: that's what i was beginning to suspect when looking at Streamly instances. thanks. any idea why Streamly doesn't have an instance for Foldable? this wouldn't quite be enough for what i want but still..
20:12 <cocreature> rihards: probably because you can’t make one. Foldable requires you (among other things) to provide a pure toList function. however, for streamly you probably only get something that gives you an m [a] where m can be something like IO
20:12 vks_ joined
20:12 dogweather joined
20:13 <cocreature> also why are people suddenly misspelling my nick half of the time … this didn’t use to happen :)
20:13 borkr joined
20:13 <rihards> oh, sorry about that :)
20:14 abhiroop joined
20:14 <rihards> but on the other side of things - is there something that generalises `take`? or is it realy list-specific?
20:16 <rihards> looking at what hoogle gives me, i guess it's the later
20:16 <EvanR> the word take is used in several sequential-like APIs
20:16 <geekosaur> suppose you could say the generalization is lens :p
20:17 <EvanR> but since none of these data structures are really interchangable, they dont have a common type
20:17 brocoli joined
20:18 scottschmidt1 joined
20:18 sdothum joined
20:19 cybai joined
20:19 striapach joined
20:21 tomphp joined
20:22 ZeuPiark joined
20:22 jaspervdj joined
20:23 Ariakenom joined
20:23 scottschmidt1 joined
20:23 sdothum joined
20:23 halogenandtoast joined
20:24 vilu joined
20:26 p0lyph3m joined
20:26 vks_ joined
20:27 <jared-w> This is something that I've struggled with in general. I see a lot of shortcomings in the way we currently write and think about languages and libbraries in genera; but unfortunately, I'm not sure if a solution is even really possible
20:28 ijks joined
20:28 <jared-w> There seem to be two conflicting ways to think about types and functions that are really common. One is that you'd want a function that's the most general possible, overloaded, polymorphic, etc. Those functions are all about highly generalized building blocks of manipulating data structures (idk if I'd even call them data structures). 'take', 'head', 'zip', 'map', etc., are all great examples. I can think of
20:28 <jared-w> sane ways to do those on just about any data structure imaginable
20:28 wchresta joined
20:29 <EvanR> there are many sane ways to "take" a tree from a tree
20:29 <EvanR> or a matrix from a matrix
20:29 <jared-w> Right, there definitely are, which is a lot of the problem
20:29 <Tuplanolla> Usable first-class Futamura projections, when?
20:29 <jared-w> But even if we restricted take to 'linear data structures' there's still a lot of those
20:30 <jared-w> It'd be nice to have a "take" that worked on vectors, sequences, lists, every type of stream, etc., without throwing type inference out the window or making it super fucking ugly to write it
20:30 <EvanR> you want 1 way to implement take on all of them?
20:31 <jared-w> It's one idea "take the first n items from a linear data structure"
20:31 iAmerikan joined
20:31 <EvanR> we can already make a type class to make the operation polymorphic, it just has no laws so its not standard
20:31 <jared-w> it'd be nice if I could use one function for that. I'd even be willing to go down the typeclass route for some of those things
20:32 amar joined
20:32 <EvanR> for an experiment where they thought every "linear" structure should have the same interface, see clojure
20:32 <jared-w> (although a part of me wonders if we're abusing type classes for this sort of thing and if there's a better way to split typeclasses-with-laws and typeclasses-for-polymorphic-convenience out into two things where each can explore their strengths. I'm not sure the polymorphic convenience needs global coherence, for example, but ytpeclasses sure as hell do)
20:32 <EvanR> unfortunately, the actual intersection of all these APIs is pretty small in comparison to the full APIs, and the full APIs are what you need to exploit the performance differences
20:33 <EvanR> and avoid issues with semantic differences
20:33 <EvanR> its like "there should really be a class for things which can lookup by key"
20:33 <jared-w> like snoc being useless on streams and head being partial on some data structures and total on others?
20:33 <EvanR> since all these wildly different structures happen to have a lookup by key function in common
20:34 <EvanR> but almost nothing else
20:34 <Ariakenom> fromList . take 5 . toList -- add some rewrite rules
20:34 <EvanR> yes like snoc
20:34 beauby joined
20:34 Xal joined
20:35 tomku joined
20:35 <Ariakenom> jared-w: That split sounds like Idris' ad-hoc overloading
20:35 <jared-w> I'm not convinced the tolist-> f -> fromlist is a super great solution, honestly. Rewrite rules are hilariously fragile and you end up shoving exponential complexity on the maintainers for very little benefit on the author side of things
20:36 <jared-w> But yeah, there's this general feeling of "I feel like I can write _far_ more general code that really gets to the heart of what I'm doing at a foundational level, if only there was... something..."
20:36 <EvanR> before solving this i want to know that there is a well defined problem to solve
20:36 <EvanR> all these data structures are actually similar? in what way
20:36 drewr joined
20:36 <EvanR> or do they just happen to have a couple of the same operations, not necessarily efficient
20:37 <jared-w> Lenses give me that feeling too, like they're closer to the 'perfect' than accessor functions and feel like a really nice to think about data in a more abstract and uniform manner... But I can't help but feel there's just one level higher where everything clicks perfectly
20:37 <maerwald> lol
20:37 byorgey joined
20:37 byorgey joined
20:37 <jared-w> nice way to think about**
20:37 Thra11 joined
20:37 <EvanR> mapping to and from a list is one nice way
20:37 <EvanR> then you really are sure this is a list in disguise
20:38 <EvanR> but its not efficient
20:38 <jared-w> EvanR: unfortunately, I don't know the answer to that one. I feel like it's potentially possible that a language of the future might not really have any other data structures; merely data representations that are transiently created by an intermediate language representation in order to make an operation you want more efficient.
20:39 <jared-w> Of course, that doesn't seem really right to me, given that a lot of data structures are inescapable in their differences (eg non linear structures vs linear ones)
20:39 <Ariakenom> It's not exponential a rewrite rule per type and function. Like the typeclass approach. It's not a good idea but for it's the straightforward list-like thing to do
20:39 <EvanR> one true data structure? one true number type?
20:39 <jared-w> Right? It feels like, poetically, it might be possible, but I'm not sure the reality is so rosy :)
20:39 <maerwald> meanwhile, other people write actual code :D
20:39 detrumi left
20:40 <* jared-w> philosophizes grumpily in maerwald's general direction
20:40 <EvanR> i dont see fox, frog, gator anymore just tetrapods
20:40 <EvanR> dont worry about hexapods, out of scope
20:41 <jared-w> lol
20:41 <dmwit> am i a tetrapod
20:41 danthemy_ joined
20:41 <jared-w> But yeah, the other side of things is that often it's very useful to have things which are very very domain specific, so that the types help make sure you don't do anything wrong
20:42 vurtz joined
20:42 <jared-w> I might want 6 different newtypes of the same thing, for example, but do I want all of those super general functions to work on those newtypes? Maybe? Maybe not? Maybe only sometimes?
20:43 <EvanR> "hello " + "world" + 2
20:43 <Ariakenom> Why do you call them the same thing?
20:44 <Ariakenom> If they're new types they should """"ideally"""" not be. If we're philosophizing
20:44 <crestfallen> hello why is the seed value set to True using foldr in this case? : https://ptpb.pw/ngsq
20:44 pykello joined
20:44 <dmwit> What do you think it should be set to?
20:44 <dmwit> (And why?)
20:44 <mitchellsalad__> and [True] should return what? ;)
20:45 <EvanR> newtypes that act exactly the same but arent compatible with each other can be useful to avoid mixing up argument order
20:45 <jared-w> Ariakenom: right, but for another example, I might want to have a linear structure in a program where, in one section, it's very important to make sure the length of items is correct
20:45 abhiroop joined
20:45 <EvanR> but theys kind of a strech because no one does that
20:45 <jared-w> EvanR: I end up doing that sort of thing quite frequently in one off things like homework assignments
20:46 <jared-w> If I have like 3 matrices I'm passing in and things get fucked up, you best believe I don't want to do that book keeping by hand lol
20:46 <dmwit> If you were a mathematician, my answer would be "because True is the unit of (&&)" and be done with it. (You might also ponder what it has in common with the base cases for `product = foldr (*) 1` and `sum = foldr (+) 0`.)
20:46 bas080 joined
20:46 fishythefish joined
20:46 <jared-w> and in another section, I don't care about the length, but I do care about some other property, so I'd probably want to convert that type to one that tracks that property and throws away the length
20:47 brocoli joined
20:47 <ZeuPiark> bye
20:47 <crestfallen> dmwit: thanks, working on that
20:47 amirpro joined
20:47 <jared-w> but in all cases, being able to use a general `length` function on the list would probably be pretty useful and taking the head of a non-empty list should always be fine, even if that list is embued with additional (yet locally temporary) structure
20:48 <EvanR> philosophizing about these things is a lot easier than dealing with the code after putting mass quantities of types in hehe
20:48 <jared-w> Basically :p
20:48 sdothum joined
20:48 <jared-w> It'd be great if there /wasn't/ a cost to putting all those types in, though
20:48 amirpro joined
20:48 <crestfallen> dmwit: pls elaborate on 'the unit'
20:48 <EvanR> just install the AI java IDE plugin
20:49 <EvanR> equipped to not only detect mistakes but pass moral judgment on your ideas
20:49 dodong joined
20:49 <Ariakenom> We also have liquid haskell types. Which fit into these issues
20:50 <glguy> It's nice to be able to think about: and (xs ++ ys) === and xs && and ys, and similarly: or (xs ++ ys) === or xs || or ys
20:51 <crestfallen> do you mean unit in a way similar to identity dmwit ?
20:51 <* Ariakenom> disappears into the clouds
20:51 <glguy> xs == [] ++ xs or xs == or ([] ++ xs) == or [] || or xs == False || or xs == or xs
20:52 mreh joined
20:52 <wchresta> crestfallen: Yes, unit in the sense of identity. In the sense of "the element that when applied to another one does nothing; i.e. 0+2==2, 1*5==5, True&&a==a
20:52 <jared-w> The unit for lists and concatenation is [], the unit for addition is 0, the unit for multiplication is 1, the unit for... etc :)
20:52 Solonarv joined
20:52 kaictl joined
20:53 <jared-w> (can't think of any number types that doesn't hold for, tbh, but usually people use the Integers as the number type of choice when talking about units)
20:54 <crestfallen> wait a cotton pickin' minute :)
20:54 comerijn joined
20:55 lainon joined
20:55 <* jared-w> suddenly realizes how weird that phrase sounds outside of the southern US
20:56 <crestfallen> I know sorry its a bit backwater
20:56 <jared-w> hah it's fine, I just read it in a southern accent and got confused why my brain picked that one
20:56 <DigitalKiwi> how long is a cotton pickin' minute compared to regular minutes
20:57 <dysfun> not sure, but it's twice as long as a corn pickin' minute
20:57 <crestfallen> some colloquialisms, even those related to bad times, should be remembered perhaps.
20:58 <suzu> hmmmm
20:58 <suzu> why won't these instances overlap?
20:58 <suzu> instance (JsTypeable s b, s1 ~ s) => JsTypeable s (JsCallback s1 -> b) where
20:58 <DigitalKiwi> mhr so if I wait a cotton pickin' minute and you wait a corn pickin' minute, who will be done waiting first?
20:58 <suzu> instance (FromJSValue a, JsTypeable s b, s ~ s1) => JsTypeable s1 (a -> b) where
20:58 <suzu> they did overlap before i added this `s` parameter to JsTypeable
20:59 <EvanR> (but then why is monadplus's unit called zero, which acts like multiplicative zero)
20:59 amirpro joined
21:00 <glguy> mzero is the unit for mplus, not >>
21:00 <fishythefish> EvanR: at the risk of missing the joke, because zero is the identity for plus?
21:00 <EvanR> oh
21:00 <EvanR> right
21:00 <glguy> MonadPlus's interaction with >> is optimistically documented but not necessarily satisfied by its instances
21:01 <crestfallen> so it returns the seed value regardless, but you are saying that the empty list has a logical value with (||) and (&&) ?
21:01 <glguy> and the more modern Alternative class doesn't mention that interaction at all
21:01 abhiroop joined
21:02 <crestfallen> each empty list has a bool value based on the logical operator? now I'm not sure I get the (||) case either....
21:02 mstruebing1 joined
21:03 jdemler joined
21:04 DSM joined
21:05 lagothri1 joined
21:05 <geekosaur> every monoid comes with two things: an associative operator, and an identity specific to that operator
21:05 <crestfallen> foldr (#) v [] = v
21:06 <glguy> > foldr (Debug.SimpleReflect.op Debug.SimpleReflect.InfixR 2 " || ") (var "False") [a,b,c]
21:06 <lambdabot> a || b || c || False
21:07 <crestfallen> geekosaur: ok in straight logic (&&) has the identity of True
21:07 UnChallengeD joined
21:08 <crestfallen> so this leads me to ask a difficult-to-form question...
21:08 <glguy> > foldr (⊕) z [a,b,c]
21:08 <lambdabot> a ⊕ (b ⊕ (c ⊕ z))
21:09 <shapr> silly question, any good ways to golf [n | n <- (2^) <$> [1..], not . or $ elem <$> "1248" <*> [show n]] ?
21:09 <dmwit> I also like glguy's "because we want `and (xs ++ ys) = and xs && and ys`" answer. It is another way of talking about the same points.
21:09 <shapr> The question on work slack was, what's the shortest way to find all powers of two that do not contain numbers 1,2,4,8 powers of two
21:09 <shapr> I feel like my first attempt at golfing that was subpar
21:10 <crestfallen> pondering that: and (xs ++ ys) = and xs && and ys
21:10 <dmwit> > [n | n <- iterate (2*) 1, all (`elem`"356790") (show n)]
21:11 <lambdabot> mueval-core: Time limit exceeded
21:11 <shapr> dmwit: oooh
21:11 <shapr> > take 1 [n | n <- iterate (2*) 1, all (`elem`"356790") (show n)]
21:11 <lambdabot> [65536]
21:11 <shapr> niice
21:12 <dmwit> Optimized for beauty, not golfed.
21:13 <crestfallen> so in other words the empty list takes on the logical implications of the operators (&&), (||)
21:13 <dmwit> I don't know what the logical implications of (&&) are.
21:13 <dmwit> What do you mean by that?
21:14 freyr joined
21:14 maerwald joined
21:15 <crestfallen> because we are folding over an empty list with operators that have identity values, I guess
21:16 <suzu> nvm got my thing to work ^ grr polykinds were on
21:19 seizo joined
21:19 mreh joined
21:20 <maerwald> so stack doesn't have a 'run' command, great
21:20 tomphp joined
21:21 <maerwald> how do you run the project
21:21 <exio4> stack exec <project_name>
21:21 <exio4> executable name actually :p
21:21 <maerwald> exactly
21:21 <maerwald> stack-run exists, but the stack resolver fails
21:21 <maerwald> so I cannot build it
21:22 pfurla joined
21:22 Thra11 joined
21:23 osa1 joined
21:25 kunz joined
21:26 sdothum_ joined
21:27 abhiroop joined
21:27 Linter joined
21:29 replay joined
21:31 keith2 joined
21:33 sdothum joined
21:34 hphuoc25 joined
21:36 danso joined
21:36 mpahrens joined
21:43 codesoup joined
21:44 rzp joined
21:44 dented42 joined
21:44 tomku joined
21:45 louispan joined
21:47 vks_ joined
21:48 conal joined
21:50 tzemanovic joined
21:52 edmundnoble joined
21:52 fmixing joined
21:53 dan_f joined
21:53 mpahrens joined
21:54 merijn joined
21:56 tomphp joined
21:57 tsaka__ joined
21:57 danso joined
22:00 mpahrens joined
22:02 bergle2 joined
22:02 lainon joined
22:05 striapach_ joined
22:06 tdjones joined
22:07 mpahrens joined
22:07 tdjones joined
22:07 lortabac_ joined
22:09 taktoa joined
22:11 keith2 left
22:12 Psybur joined
22:12 MissingNoIOI joined
22:13 lumm joined
22:14 rasusto_ joined
22:14 bbrodr joined
22:15 abhiroop joined
22:16 pykello joined
22:16 aarvar joined
22:18 boj joined
22:19 codesoup joined
22:20 beauby joined
22:21 lainon joined
22:24 Solonarv joined
22:25 KeyJoo joined
22:25 pie_ joined
22:25 <mjoldfield> Suppose I have: data Foo = FA | FB deriving (Bounded, Enum), data Bar = BA | BB deriving (Bounded, Enum), data Baz = Baz Foo Bar. I can get all the Bazs with Baz <$> [minBound..maxBount] <*> [minBound..maxBound], but is there a way to derive the Enum instance ?
22:25 <pie_> emoji as haskell operators
22:26 sid2k joined
22:26 <geekosaur> mjoldfield, it won't derive Enum for constructors with parameters. You can make one yourself, but consider e.g. how it interacts with Ord.
22:27 MRd1 joined
22:27 brocoli joined
22:27 <geekosaur> (more to the point, does succ or prev make sense on a boundary of one of the components?)
22:28 <mjoldfield> geekosaur: Thanks. I think you could define an Ord couldn't you ? Just treat it as a multi-digit number.
22:29 <jared-w> does data Baz = Baz Foo Bar deriving (Bounded, Enum) not do what you want?
22:29 <geekosaur> you can derive Ord, I meant that doing an Enum that behaves differently from the Ord instance may confuse you or users of the type
22:29 <geekosaur> also the issue that it has to be something Ord makes sense on: consider why Complex Double has no Ord instance
22:30 <zachk> so it seems my server problem with websockets, isn't related to websockets at all, its multithread web telnet client server, and the problem seems to be a "race" condition with closing a regular socket whilee another thread is waiting a read form that socket, and it just hangs sometimes
22:30 <geekosaur> (quick, is 3+4i greater or less than 4+3i?)
22:30 <mjoldfield> geekosaur: True.
22:31 <mjoldfield> geekosaur: Though I think I'd say you can't put an ordering on the real complex numbers, but could put a silly ordering on Complex Doubles
22:32 hamishmack joined
22:32 <jared-w> You can just start pulling numbers out of a hat, but that doesn't make it a total ordering :)
22:32 <geekosaur> You can create something, yes, just not a proper ordering because Enum and Ord both assume you can meaningfully flatten a type onto the integers
22:32 <geekosaur> (or reals, as the case may be)
22:33 <jared-w> (1,2,3,... ... 0, -1, -2, -3, -4 ...) isn't a valid ordering for integers, for example, in the mathematical sense of the word
22:33 carlomagno joined
22:34 <jared-w> Its useful to think of 'ordering', in a loose handwavy way, as "a way of arranging numbers to assure that you can get to any single number in a finite amount of steps"
22:34 WhatisRT joined
22:35 <jared-w> which immediately shows why 3+4i and 4+3i is so confounding. How do you "arrange" things so that you can hit both without having to count to infinity first?
22:35 <mjoldfield> jared-w: But I could do that with your odd ordering of the integers. It's just that Succ wouldn't be the same as +1
22:35 <mjoldfield> jared-w: Quite, which is why I think you could order Complex Double which only has a finite number of them
22:36 <jared-w> you can't get to -1 in a finite amount of time with my odd ordering of the integers is the problem. You'd have to run out of naturals and then start at zero and walk down
22:36 <mjoldfield> Oh I see, you mean the infinite set of integers, not some bounded thing. I agree then.
22:37 <jared-w> Right, should've clarified I meant the proper math integers ;)
22:38 <mjoldfield> jared-w: Isn't it hard to write a Bounded instance for those ?
22:38 <jared-w> For the real integers?
22:38 tzemanovic joined
22:38 <mjoldfield> Yes
22:38 cschnei__ joined
22:38 deepfire` joined
22:39 mpahrens joined
22:39 lamdev joined
22:39 <geekosaur> indeed
22:39 <jared-w> All bounded is is minBound and maxBound. If I had to define bounded for the "real integers", I'd be a bit cheaky and define negative and positive infinity ad use those :) but the real answer is that I probably wouldn't define it at all
22:39 <geekosaur> and in Haskell Integer doesn't have an instance of Bounded; technically it is bounded, by available memory, but you can't encode that usefully
22:40 <lamdev> hello! i'm trying to do basic IO (reading lines from a file) and somehow i can't find any safe IO function that wouldn't raise exceptions in case something wrong happens. is there a module using Maybe or Either instead to implement error handling?
22:40 <mjoldfield> Quite, which is why I wondered if I could derive the Enum type given that my Foo and Bar were Bounded
22:40 astrofog joined
22:40 alx741 joined
22:40 <geekosaur> per spec it wont even try since the constructor takes 2 parameters
22:40 <zachk> lamdev, you can wrap the function in a catch to handle exceptions
22:40 <mjoldfield> geekosaur: Fair enough :)
22:41 <geekosaur> you can write one yourself, but the compiler isnt going to force meaning on you by assuming how they should fit together to make an Enum instance.
22:41 <jared-w> I'm not sure if you can automatically derive it, but you can certainly write an enum that does "the right thing"
22:41 <geekosaur> also because I suspect it's harder for the deriving machinery to determine which types are finite and which aren't
22:41 <jared-w> That being said, this does sound suspiciously like subtyping of some sort
22:42 <lamdev> zachk: well maybe i'll eventually have to do that yes but i would have hoped it already existed. i don't know anything about catching exceptions in haskell, so i'd hoped i wouldn't need to do so myself.
22:42 <jared-w> geekosaur: I'd imagine it's harder still because all* types are lifted in Haskell :)
22:43 <zachk> lamdev, usually I just want my program/current thread of execution to die , somewhat gracefully, on errors from IO functions
22:43 <mjoldfield> Anyway, thanks for your help.
22:43 <geekosaur> well. the real problem is Enum already has some special behavior with respect to Bounded; but they wanted to avoid too much, and I just told a slight lie because Bounded is a reasonable proxy for "finite" here (since Enum requires that things map to Integer)
22:45 abhiroop joined
22:47 <crestfallen> glguy: I'm almost with you: xs == [] ++ xs or xs == or ([] ++ xs) == or [] || or xs == False || or xs == or xs
22:48 abhiroop joined
22:48 marvin2 joined
22:49 deepfire` joined
22:50 darjeeling_ joined
22:50 dodong joined
22:51 mpahrens joined
22:55 comerijn joined
22:56 youtmon joined
22:57 zero_byte joined
22:59 dogweather joined
23:00 lainon joined
23:00 mpahrens joined
23:00 camsbury joined
23:01 christopher_ joined
23:01 brocoli joined
23:04 Linter joined
23:05 nyberg joined
23:09 prof_xavier96[m] joined
23:12 nyberg joined
23:13 dogweather joined
23:13 fmixing joined
23:14 diwo joined
23:20 rprije joined
23:20 woodson joined
23:21 mpahrens joined
23:22 MRd1 joined
23:25 abhiroop joined
23:26 dogweather joined
23:27 iAmerikan joined
23:27 philippD joined
23:33 vks_ joined
23:35 patlv joined
23:36 _zap_ joined
23:38 xpoqp joined
23:43 pfurla joined
23:44 patlv joined
23:44 dogweather joined
23:44 tabemann joined
23:45 <maerwald> https://github.com/yesodweb/yesod/wiki/Setting-up-PostgreSQL
23:45 <maerwald> are there instructions that are not 20 years old?
23:47 kokobo joined
23:47 blankhart joined
23:48 chao-tic joined
23:48 jcarpenter2 joined
23:48 dysoco joined
23:49 xlei joined
23:49 <philippD> everything besides the last two steps seem to be not yesode specific. So you could use any other postresql tutorial
23:49 <philippD> or am I reading this wrong
23:49 YongJoon joined
23:50 oisdk joined
23:50 <maerwald> it doesn't say anything about how I tell yesod how to use postgres
23:50 louispan joined
23:51 <dysoco> Hello, I'm trying to determine if there are repeated elements on an infinite list, I have the following code: https://lpaste.net/4100693315177938944 which worked fine because in my test cases I had the 1st element repeating... but if that's not the one that repeats then the function never returns
23:51 <dysoco> because it can never check if the head is on repeated in the tail or not
23:51 <philippD> maerwald I guess it uses the default port and localhost
23:52 <hpc> dysoco: you're trying to detect infinite lists?
23:52 <glguy> dysoco: You'll never be able to confirm that an infinite list doesn't have a repeated element like this
23:52 <hpc> oh, i see
23:52 <hpc> yeah
23:52 pykello joined
23:52 <dysoco> hpc, I know it's probably infinite, I know that sounds like the Halting Problem
23:53 <glguy> It's not the halting problem, it's just that Haskell doesn't give you the tools to observe if a list is infinite or not
23:53 <hpc> it's not possible to observe if a list is infinite
23:53 <dysoco> yeah it makes sense
23:53 <hpc> consider collatz :: Int -> [Int] showing all the steps until it reaches 1
23:53 <glguy> You can handle more cases if you accumulate a set of all the elements you've seen so far adding to it as you go while checking for membership along the way
23:54 plutoniix joined
23:54 <fishythefish> dysoco: also, what is the expected behavior if I call your function on an infinite list with no repeated elements?
23:55 merijn joined
23:55 <dysoco> fishythefish, if there are no repeated elements then the list is finite
23:55 <dysoco> it's infinite iff there is at least one repeated element
23:55 <fishythefish> dysoco: why?
23:55 <hpc> another way is to sort the list, group it, then see if any groups are larger than 1
23:55 <fishythefish> dysoco: consider [1..] :: [Integer]
23:55 <glguy> "iff" means if and only if, so that's not right, either
23:56 <hpc> dysoco: are you only using this on lists generated from some particular other function?
23:56 <dysoco> yes
23:56 <philippD> dysoco: `repeat undefined`
23:56 <hpc> hmm, sorting won't work then
23:56 <maerwald> philippD: well, guessing doesn't help here, since I need to configure.
23:57 <hpc> dysoco: do you know the length of the longest terminating list?
23:57 <dysoco> glguy, In my code, the only way a list can be infinite is that if any two elements are the same at least once
23:57 <hpc> you can use a similar trick to solving the halting problem with BB()
23:57 <fishythefish> dysoco: you say it's infinite iff there's a repeated element, but then why is determining if an infinite list has a repeated element even a problem?
23:57 <dysoco> hpc, no, it can be pretty large, I can assume it's not going to be exaggeratedly large like >50 but then my code wouldn't be correct because someone might come with a counterexample
23:58 <dysoco> OK let me explain a bit better
23:58 <hpc> i think you're stuck then
23:58 <dysoco> each element on the list is a position, so a list is a list of positions, if I step on the same position twice then I'm stuck in a loop
23:58 <glguy> dysoco: If you're trying to solve a much narrower problem than the original question it would help to see that instead
23:59 <hpc> dysoco: you need an upper limit to force your function to terminate, or you need to use some other property of the generated lists
23:59 <dysoco> yeah that's what I thought