<     May 2017     >
Su Mo Tu We Th Fr Sa  
    1  2  3  4  5  6  
 7  8  9 10 11 12 13  
14 15 16 17 18 19 20  
21 22 23 24 _2_5 26 27  
28 29 30 31
00:00 crave joined
00:01 ddere joined
00:01 infinity0 joined
00:02 e14 joined
00:03 tromp joined
00:03 <ertes> type TicTacToe = (Ordering -> Ordering, Ordering -> Ordering, Either Bool (Bool -> Either Bool Ordering))
00:04 infinity0 joined
00:04 filterfish joined
00:06 oisdk joined
00:07 infinity0 joined
00:07 lgas joined
00:08 sleffy joined
00:08 plutoniix joined
00:09 a3Dman joined
00:10 infinity0 joined
00:11 shangxiao joined
00:11 louispan joined
00:11 flatmap13 joined
00:11 alx741 joined
00:12 alx741 joined
00:12 infinity0 joined
00:13 kadoban joined
00:14 flatmap1_ joined
00:14 flatmap13 joined
00:19 Koterpillar joined
00:20 amuck_ joined
00:20 e14 joined
00:23 jer1 joined
00:23 lgas joined
00:23 nighty-- joined
00:24 juanpaucar joined
00:26 chlong joined
00:26 juanpaucar joined
00:27 Natch joined
00:27 mjora7 joined
00:30 <Squarism> can one unload all modules in ghci ? Google only told me for single modules
00:30 <Squarism> when i run stack it keeps loading all exposed modules
00:30 <geekosaur> the whole point o 'stack ghci' is to build and load all modules, which is hard to do otherwise
00:30 <geekosaur> if you want a bare ghci in your stack project, try 'stack exec ghci'
00:31 <Squarism> thanks
00:31 <geekosaur> (this will however leave you missing e.g. any ffi objects needed, and no good way to load them)
00:31 wroathe joined
00:32 jer1 joined
00:32 <geekosaur> anyway I suspect something like ':m Prelude' will reset the module list
00:32 <geekosaur> seems to here
00:33 juanpaucar joined
00:34 dmwit_ joined
00:37 Eduard_Munteanu joined
00:38 {emptyset} joined
00:38 juanpaucar joined
00:40 <athan> Is there a concept in QuickCheck which is like Arbitrary, but for explicit collections of values (a Data.Set for instance, as the thing to choose values from, rather than a type)?
00:41 <lyxia> oneof ?
00:41 mkoenig joined
00:41 <lyxia> it's not very efficient, you'll have to write your own generator otherwise
00:41 <EvanR> elements :: [a] -> Gen a
00:43 juanpaucar joined
00:43 tromp joined
00:45 takle joined
00:46 augur joined
00:48 juanpaucar joined
00:48 cyborg-one joined
00:51 Hunter1 joined
00:52 bitf joined
00:52 <bitf> clear
00:52 juanpauc_ joined
00:53 takle joined
00:53 xcmw joined
00:53 ContessaTP joined
00:54 tosun joined
00:57 juanpaucar joined
00:57 Flechette joined
00:58 vaibhavsagar joined
00:58 jer1 joined
01:01 e14 joined
01:01 juanpaucar joined
01:03 connrs joined
01:03 <iqubic> How does QuickCheck work. Is there a guide anywhere. It's a testing suite right. I need on of those for Haskell.
01:04 n_blownapart joined
01:05 Supersonic112_ joined
01:06 juanpaucar joined
01:07 socrabot joined
01:07 augur joined
01:07 <peddie> iqubic: I googled 'quickcheck examples' and got https://www.schoolofhaskell.com/user/pbv/an-introduction-to-quickcheck-testing http://www.cse.chalmers.se/~rjmh/QuickCheck/manual.html
01:08 <peddie> @hackage QuickCheck -- iqubic
01:08 <lambdabot> http://hackage.haskell.org/package/QuickCheck -- iqubic
01:08 mmachenry joined
01:09 abroz joined
01:10 Scip joined
01:11 juanpauc_ joined
01:11 torgdor joined
01:11 saussure joined
01:12 Koterpillar joined
01:12 xcmw joined
01:13 jer1 joined
01:14 orion joined
01:14 orion joined
01:15 juanpaucar joined
01:17 socrabot left
01:20 mmachenry joined
01:20 juanpaucar joined
01:22 <vaibhavsagar> can anyone help me create a static executable with stack?
01:22 xcmw joined
01:22 <mjora7> Hey, could someone help me out with a quick question about stack? I'm trying to get a "Hello, world!" project for Scotty working, so I made a new stack project, `stack new hello-scotty; cd hello-scotty; stack setup; stack build;`, now I'm wondering how do I get it to include the scotty package?
01:23 <vaibhavsagar> mjora7: edit the hello-scotty.cabal file and add scotty to the "build-depends: "
01:23 cmn joined
01:23 raid joined
01:23 darlan joined
01:23 <mjora7> vaibhavsagar: Ok, there's no way to get a tool to automatically do that by some sort of command? Like in Node.js you can go `npm install scotty --save` and it will install that package and save it as a dependency.
01:24 <mjora7> vaibhavsagar: Also, I see three `build-depends:`, one under library, one under executable, and one under test-suite. I guess I put it under executable?
01:24 juanpaucar joined
01:25 <vaibhavsagar> no, library
01:25 <vaibhavsagar> my question has to do with statically linking libpq
01:26 <mjora7> vaibhavsagar: Ok. This indentation in the .cabal file is scaring me. Is it just for visual appearances or does it actually matter logically a la python?
01:27 jship joined
01:27 <vaibhavsagar> mjora7: I think it's just for show, but here is an example: https://github.com/vaibhavsagar/suppandi/blob/master/suppandi.cabal
01:27 jedws joined
01:27 <mjora7> vaibhavsagar: Ok cool. So I added my dependency, now I run `stack-build`?
01:27 <vaibhavsagar> yup
01:28 <vaibhavsagar> are you on #haskell-beginners? it's more active than this channel atm
01:28 <mjora7> vaibhavsagar: Nope, I should go there.
01:28 <mjora7> vaibhavsagar: I am now!
01:29 <vaibhavsagar> yay :)!
01:29 juanpauc_ joined
01:29 eacameron joined
01:29 <vaibhavsagar> just as long as you know it's there
01:30 <mjora7> vaibhavsagar: So I see that you can run your program with `stack exec hello-scotty-exe`, but where does it dump the exe?
01:31 LuckyRawApe joined
01:31 <clamchowder> hello
01:31 <clamchowder> I have a simple question: say I define a function:
01:31 <vaibhavsagar> it's under `.stack-work/install/<os>/<lts>
01:31 <clamchowder> f :: Monad m => a -> m a
01:31 <Koterpillar> stack path —local-install-root
01:32 <clamchowder> f x = return x
01:32 ianandrich joined
01:32 <clamchowder> how do I pass the type of m to f?
01:32 <mjora7> vaibhavsagar: Hey btw, the build-depends under library didn't work but it did under executable.
01:32 <Koterpillar> clamchowder: it will be inferred from the invocation
01:33 <vaibhavsagar> mjora7: I forgot to ask if you were using scotty in Main.hs or Lib.hs, you must be using it in Main.hs
01:33 Noldorin joined
01:33 <clamchowder> Koterpillar: say at one time I want m to be list, and at another time I want it to be Maybe
01:33 <clamchowder> Without any context
01:33 <vaibhavsagar> you can add a type annotation
01:33 <Koterpillar> clamchowder: annotate it with a type
01:34 juanpaucar joined
01:34 cschneid_ joined
01:35 <clamchowder> Koterpillar: how do I do that
01:35 <Koterpillar> either as f 0 :: [Int], or as f @[]; for latter, you'll have to enable an extension
01:35 peterbecich joined
01:35 lavalike joined
01:35 <Koterpillar> > return 0 :: [Int]
01:35 <lambdabot> [0]
01:35 <Koterpillar> > return 0 :: Maybe Int
01:35 <lambdabot> Just 0
01:35 systadmin joined
01:35 <jle`> @[] is "literally" passing the type, since it's called a type application
01:35 <lambdabot> Maybe you meant: wn v rc pl id do bf @ ? .
01:35 <jle`> sorry lambdabot
01:35 <Koterpillar> ah yes, TypeApplications
01:36 <jle`> it treats f as f :: forall m. Monad m => a -> m a
01:36 <jle`> and so like 'm' is an argument
01:36 Koterpillar joined
01:37 <clamchowder> Koterpillar, vaibhavsagar, jle`: thanks.
01:38 juanpauc_ joined
01:38 varuaa joined
01:41 <iqubic> But isn't ScopedTypes a pragma you'd need in order to do that?
01:41 <iqubic> > return 0
01:41 <lambdabot> error:
01:41 <lambdabot> • Ambiguous type variables ‘m0’, ‘a0’ arising from a use of ‘show_M36851...
01:41 <lambdabot> prevents the constraint ‘(Show (m0 a0))’ from being solved.
01:42 flatmap13 joined
01:42 <iqubic> > return 0 :: Either String Int
01:42 <lambdabot> Right 0
01:42 <iqubic> > join $ Right $ Left 50
01:42 <lambdabot> Left 50
01:42 <iqubic> > join $ Right $ Right $ Right 50
01:42 <lambdabot> Right (Right 50)
01:42 wroathe joined
01:42 <mjora7> vaibhavsagar: Ah yes, in Main.hs. What is the difference between Main.hs and Lib.hs? I guess Main.hs is an entry point that has the main function?
01:42 <clamchowder> that's weird. in my ghci return 0 gives me 0
01:43 <sleblanc> :t join
01:43 <lambdabot> Monad m => m (m a) -> m a
01:43 juanpaucar joined
01:43 <iqubic> > join $ join $ Right $ Right $ Right 50
01:43 <lambdabot> Right 50
01:44 <vaibhavsagar> mjora7: yup, and Main.hs is managed by the 'executable' section whereas Lib.hs is managed by the 'library' section
01:44 <Koterpillar> clamchowder: I think GHCi is trying to interpret it as IO Int, and runs the resulting action
01:44 <geekosaur> ^
01:44 <mjora7> Ok
01:44 <mjora7> So I guess this means that I should study Cabal in additional to Stack to understand how this all works.
01:44 <iqubic> Is there a way to take an m (m (m (m ... a))) and turn it into an m a? So a thing like join that takes an arbitrarily nested monad, an un-nests it?
01:44 <jle`> it is ill-typed
01:44 <jle`> what would its type be?
01:45 <iqubic> I don't know.
01:45 <geekosaur> ghc speculatively tries a type as IO x to see if it should run it and produce the result. since that typechecks, it's what ghci does
01:45 <jle`> there is no type it could be
01:45 <iqubic> I'm thinking that this is similar to lift.
01:45 <jle`> so it cannot exist
01:45 <Koterpillar> or, each one of those will be a different type
01:45 <geekosaur> ghc itself, or wrappers like mueval (what lambdabot uses), will not do that
01:45 <iqubic> :t lift
01:45 <lambdabot> (Monad m, MonadTrans t) => m a -> t m a
01:45 <clamchowder> Koterpillar: ah I see
01:46 <Koterpillar> iqubic: if you know how many layers there are, use that many joins
01:46 <iqubic> > lift Maybe 1 :: MaybeT IO Int
01:46 <lambdabot> error:
01:46 <lambdabot> Not in scope: type constructor or class ‘MaybeT’
01:46 <lambdabot> Perhaps you meant ‘Maybe’ (imported from Data.Maybe)
01:46 <Xnuk> @hoogle Network.OAuth.Http.Request
01:46 <lambdabot> Network.Wai data Request
01:46 <lambdabot> Network.Wai.Internal data Request
01:46 <lambdabot> Network.Wai.Internal Request :: Method -> HttpVersion -> ByteString -> ByteString -> RequestHeaders -> Bool -> SockAddr -> [Text] -> Query -> IO ByteString -> Vault -> RequestBodyLength -> Maybe
01:46 <lambdabot> ByteString -> Maybe ByteString -> Maybe ByteString -> Maybe ByteString -> Request
01:46 <jle`> Maybe is not a data constructor, heh
01:46 <geekosaur> er, "ghci speculatively..."
01:46 <jle`> iqubic: also 'lift' takes only one argument
01:46 <iqubic> > lift $ Maybe 1 :: MaybeT IO Int
01:46 <lambdabot> error:
01:46 <lambdabot> Not in scope: type constructor or class ‘MaybeT’
01:46 <lambdabot> Perhaps you meant ‘Maybe’ (imported from Data.Maybe)
01:46 <Koterpillar> iqubic: otherwise you can build _something_, but where did you ever get that type?
01:46 abroz joined
01:46 <jle`> iqubic: there is no data constructor 'Maybe'
01:46 <jle`> at least not in any standard library
01:46 <iqubic> Koterpillar: I'm just asking abstract questions.
01:46 <jle`> or non-standard ones
01:47 <iqubic> > lift $ Just 1 :: MaybeT IO Int
01:47 <lambdabot> error:
01:47 <lambdabot> Not in scope: type constructor or class ‘MaybeT’
01:47 <lambdabot> Perhaps you meant ‘Maybe’ (imported from Data.Maybe)
01:47 <jle`> check the type of lift
01:47 <iqubic> :t lift
01:47 <lambdabot> (Monad m, MonadTrans t) => m a -> t m a
01:47 <jle`> and see why that doesn't work
01:47 <Xnuk> Can I find package name with module name?
01:47 <iqubic> jle`: What am I doing wrong?
01:47 juanpauc_ joined
01:47 <jle`> you're using MaybeT IO Int as the result
01:47 <jle`> so the type of the input is ...?
01:48 e14 joined
01:48 castlelore joined
01:48 castlelore joined
01:48 <jle`> if 't m a' is MaybeT IO Int, what is t, what is m, and what is a ?
01:48 takle joined
01:48 <Xnuk> :t lift $ Maybe 1
01:48 brynedwards joined
01:48 <lambdabot> error:
01:48 <lambdabot> • Data constructor not in scope: Maybe :: Integer -> m a
01:48 <lambdabot> • Perhaps you meant variable ‘maybe’ (imported from Data.Maybe)
01:48 <jle`> Xnuk: you can use hoogle maybe if you want to search online
01:48 <Xnuk> :t lift $ Just 1
01:48 <lambdabot> (Num a, MonadTrans t) => t Maybe a
01:48 <geekosaur> Xnuk, for installed packages, ghc-pkg find-module
01:49 <geekosaur> Xnuk, for packages not installed, hoogle and hayoo can be used
01:49 <iqubic> t ~ MaybeT, m ~ IO, a ~ Int
01:49 <iqubic> > lift $ IO 1 :: MaybeT IO Int
01:49 <lambdabot> error:
01:49 <lambdabot> Not in scope: type constructor or class ‘MaybeT’
01:49 <lambdabot> Perhaps you meant ‘Maybe’ (imported from Data.Maybe)
01:49 <jle`> iqubic: yes, so what is the input 'm a' ?
01:49 <jle`> IO is not a data constructor
01:49 <jle`> IO is an abstract data type
01:49 <iqubic> > lift $ read getLine :: MaybeT IO Int
01:49 <lambdabot> error:
01:49 <lambdabot> Not in scope: type constructor or class ‘MaybeT’
01:49 <lambdabot> Perhaps you meant ‘Maybe’ (imported from Data.Maybe)
01:49 <Xnuk> geekosaur, jle`: thanks a lot
01:49 <iqubic> :t getLine
01:49 <lambdabot> IO String
01:50 <iqubic> :t read
01:50 <lambdabot> Read a => String -> a
01:50 <jle`> :t lift getLine
01:50 <lambdabot> MonadTrans t => t IO String
01:50 <Koterpillar> :i StateT
01:50 locallycompact joined
01:50 <Koterpillar> :t StateT
01:50 <jle`> lambdabot has no :i
01:50 <lambdabot> (s -> m (a, s)) -> StateT s m a
01:50 <jle`> @let import Control.Monad.Trans.Maybe
01:50 <lambdabot> Defined.
01:50 <iqubic> > lift $ read getLine :: MaybeT IO Int
01:50 <Koterpillar> iqubic: try StateT something as the result type, you're close… ah, that's better
01:50 <jle`> :t lift getLine :: MaybeT IO Int
01:50 <lambdabot> error:
01:50 <lambdabot> • Couldn't match type ‘[Char]’ with ‘Int’
01:50 <lambdabot> Expected type: MaybeT IO Int
01:50 <lambdabot> error:
01:50 <lambdabot> • Couldn't match type ‘IO String’ with ‘[Char]’
01:50 <lambdabot> Expected type: String
01:50 <jle`> heh sorry
01:50 <jle`> :t lift getLine :: MaybeT IO String
01:50 <lambdabot> MaybeT IO String
01:51 <jle`> but yeah, back to your original question, no, the thing you are talking about has no type
01:51 <iqubic> I just want to undserstand when lift is useful.
01:51 <jle`> so it cannot be done
01:51 mkoenig joined
01:51 <jle`> iqubic: well, like any typeclass instance, it's best understood as something useful for each instance
01:51 <jle`> it's not very frutiful to attempt to understand it first as a general concept
01:51 Goplat joined
01:52 <iqubic> Why would one need to use lift ever?
01:52 eacameron joined
01:52 <jle`> like i said, that's not too useful of a question
01:52 lambdamu_ joined
01:52 <jle`> you should undersatnd it for a specific instance
01:52 juanpaucar joined
01:52 <jle`> every instance uses 'lift' in its own way
01:52 <geekosaur> iqubic, to implement more specific lisfters
01:52 <iqubic> I have written lift for a MaybeT
01:53 dfordivam joined
01:53 qwertydvorak left
01:53 <jle`> 'MaybeT IO a' is an IO action that might return nothing. so lift :: IO a -> MaybeT IO a, it lets you use a normal IO action in a MaybeT IO action
01:53 <geekosaur> e.g. instance (MonadTrans m, MonadIO m) => MonadIO MyTransformer m where liftIO = lift . liftIO (which is what deriving MonadIO does, more or less)
01:53 <iqubic> In fact, I wrote myself a whole thing a while ago
01:54 <jle`> `lift :: IO a -> MaybeT IO a` just turns an IO action into a MaybeT IO a that always returns Just a. (without thinking about exceptions)
01:54 <jle`> so you can use an IO action in a MaybeT IO do block
01:54 <iqubic> http://termbin.com/3sfr
01:54 <iqubic> Yeah, see the last function in that file.
01:54 <iqubic> It's my version of MaybeT
01:55 <jle`> yes, it appears that you already see why 'lift' is useful for MaybeT
01:55 <iqubic> I know.
01:55 <iqubic> Lift is helpful
01:55 <iqubic> I have to use lift, because getNonEmpty line might return Nothing
01:55 takle joined
01:55 <jle`> that's not quite why you have to use lift
01:56 <jle`> you have to use lfit becase putStrLn "hello" :: IO ()
01:56 <jle`> but your do block is MaybeT IO ()
01:56 <iqubic> Right.
01:56 <iqubic> That TestMaybeT aborts if I type in an empty line ever.
01:56 mizu_no_oto joined
01:57 juanpauc_ joined
01:57 <jle`> mhm. that's because of the Monad instance fo r MaybeT and how it implements >>=
01:58 <iqubic> Yep. I wrote that myself with the help of glguy.
01:59 dan_f joined
02:00 wroathe joined
02:00 hucksy joined
02:00 abroz joined
02:01 darjeeli1 joined
02:01 juanpaucar joined
02:01 rkazak joined
02:01 drman joined
02:02 martinga_ joined
02:03 alasi joined
02:03 <iqubic> I just realized that my Monad instance was a little verbose
02:04 <iqubic> Or sorry, my Applicative was the verbose one.
02:04 <iqubic> http://termbin.com/l3564
02:04 <iqubic> That's better.
02:06 juanpauc_ joined
02:07 <EvanR> the dsp package seems to waffle between lists and Array... and i was thinking of doing dsp by passing immutable Vectors around... so...
02:07 <heath> :)
02:07 <EvanR> Array seems like the worst of both worlds
02:08 <heath> i have three general questions i'd like some feedback on from the channel: what are some methods you use to maintain a clean codebase? how does haskell help you to maintain a clean, decoupled codebase? what system design benefits do you receive from a statically typed, pure language such as haskell, that you wouldn't in a dynamically typed, but immutable language?
02:09 <dunx> heath: using git to keep track of changes usually keeps your code as clean as it would otherwise be.
02:09 <dunx> then you don't forget where you put rubbish
02:09 louispan joined
02:09 socrabot joined
02:09 <heath> i disagree :)
02:09 <c_wraith> heath: for the last question, the big answer is that when you change something, the compiler tells you everywhere to fix. No guessing, no hoping you remembered everything.
02:10 mimi_vx joined
02:10 <heath> c_wraith: that's fair
02:10 fbergmann joined
02:10 juanpaucar joined
02:11 <c_wraith> heath: it's a *slight* exaggeration. Not all refactorings catch the attention of the typechecker when done incompletely. But you can often write code in a way that makes it feel magical. (Keep everything as polymorphic as possible, use different type variables for everything, etc)
02:12 barrucadu joined
02:12 barrucadu joined
02:12 tel joined
02:12 locallycompact joined
02:13 filterfish joined
02:13 Guest10 joined
02:15 filterfish_ joined
02:15 <heath> c_wraith: have you written tightly coupled haskell code before?
02:15 kvda joined
02:15 juanpauc_ joined
02:17 <c_wraith> heath: yeah. It kind of was a necessity. When the project starts at 0 lines of code, the first line goes well, but the second line ends up pretty tightly coupled to the first.
02:18 <heath> :)
02:18 <c_wraith> heath: The project probably reached the minimum viable state around a couple thousand lines. After that, a couple years of constant maintenance and adding new features meant basically no original code or design survived.
02:19 <heath> tony morris had a nice response just now to the three questions: they all seem to be the same question to me. without static types, you never see any non-trivial level of generalisation. That's because it's humanly intractable. Dynamically-typed languages are simply compiler outputs and should never be handwritten. Those generalisations are what it means (afaic) to keep a code base clean, maintainable, and
02:19 <heath> decoupled.
02:19 <EvanR> i noticed trying to treat haskell like a dynamic language, or trying to usual corner cutting just fails early
02:20 <dibblego> hai
02:20 juanpaucar joined
02:20 <EvanR> it seems to reject any attempt to "just do it"
02:20 andyhuzhill joined
02:20 <EvanR> you are really encouraged to do it right
02:20 <c_wraith> heath: The overall opinion I formed on that project was that you can do things just as badly as in any other language - but when you decide to improve things, it works so much better.
02:20 tommd joined
02:20 <c_wraith> heath: and for what it's worth, dibblego chimed in up there because he's Tony Morris. :)
02:22 exferenceBot joined
02:23 flatmap1_ joined
02:24 juanpauc_ joined
02:25 <heath> the dynamic crowd points me to: https://valbonne-consulting.com/papers/classic/Liskov_72-Design_Methodology_for_Reliable_Software_Systems.pdf and https://mitpress.mit.edu/books/engineering-safer-world
02:26 <EvanR> im thinking a lot about reliability right now, since this program is supposed to run in an arcade cabinet with no real option to sit down in front of it and debug if it fails
02:26 <heath> dibblego: are you saying that decoupling ≡ generalization?
02:27 <EvanR> its really good that certain parts of the code (the "pure" parts) sort of obviously cant fail
02:27 <dibblego> generalisation (done well, principled, etc etc) leads to decoupling
02:27 louispan joined
02:27 hexagoxel joined
02:27 <dibblego> look at all the generalisations in e.g. lens. I use lens because it leads to decoupling, better maintenance, and other reasons
02:27 <monochrom> Decoupling also requires generalization.
02:28 <dibblego> when the "dynamic crowd" point me to sources like that, I like to debunk it in such a way that they will never propose such a sillu argument again.
02:28 pikachoo joined
02:29 <dibblego> seems a waste of time otherwise
02:29 <monochrom> I don't think Liskov would speak against types, actually.
02:29 juanpaucar joined
02:29 <heath> that same crowd also pointed me to: https://arxiv.org/ftp/arxiv/papers/1703/1703.10863.pdf
02:29 <dibblego> the best way to do that, is to first defer the argument, then teach your opponents the tools and vocabulary to debunk it, then ask, "so what now?"
02:30 <heath> dibblego: how do you debunk those first two sources?
02:31 <dibblego> well clearly, we have found the point of agreement: we both agree that "software reliability" is a worthwhile goal. Then I show that no, you didn't actually achieve that, not even close, and catch up. I do that by teaching the tools to understand just how far behind achieving that goal my opponents actually are.
02:31 takle joined
02:32 <pikachoo> Hello, is there a name for: c -> [a] -> (c -> a -> (c, b)) -> [b] ?
02:32 <dibblego> looks almost like traverse
02:32 mmachenry joined
02:32 andyhuzhill joined
02:33 <ezyang> @hoogle c -> [a] -> (c -> a -> (c, b)) -> [b]
02:33 <lambdabot> Data.List.HT mapAdjacent1 :: (a -> a -> b -> c) -> a -> [(a, b)] -> [c]
02:33 <lambdabot> GHC.OldList mapAccumL :: (acc -> x -> (acc, y)) -> acc -> [x] -> (acc, [y])
02:33 <lambdabot> GHC.OldList mapAccumR :: (acc -> x -> (acc, y)) -> acc -> [x] -> (acc, [y])
02:33 juanpaucar joined
02:33 <ezyang> mapAccum?
02:33 <heath> pikachoo: are you looking for a generic term?
02:34 <pikachoo> Yeah. Will look at mapAccum, thanks.
02:35 <pikachoo> I guess it's also scanl + zipWith?
02:38 juanpaucar joined
02:39 takle joined
02:41 <pikachoo> The definition of mapAccumL is totally crazy. Is there a way to simplify it for [a] instead of Traversable?
02:41 orhan89 joined
02:41 tromp joined
02:41 <pacak> :t mapAccum
02:41 <lambdabot> error:
02:41 <lambdabot> • Variable not in scope: mapAccum
02:41 <lambdabot> • Perhaps you meant one of these:
02:42 <pacak> :t mapAccumL
02:42 drewbert joined
02:42 socrabot left
02:42 <lambdabot> Traversable t => (a -> b -> (a, c)) -> a -> t b -> (a, t c)
02:42 <pacak> :t mapAccumL :: a -> b -> (a, c) -> a -> [b] -> (a, [c])
02:42 <lambdabot> error:
02:42 <lambdabot> • Couldn't match type ‘(b1, (a1, c0))’
02:42 <lambdabot> with ‘a1 -> [b1] -> (a1, [c1])’
02:42 <pacak> :t mapAccumL :: (a -> b -> (a, c)) -> a -> [b] -> (a, [c])
02:42 <lambdabot> (a -> b -> (a, c)) -> a -> [b] -> (a, [c])
02:43 juanpaucar joined
02:47 juanpaucar joined
02:47 Stratege joined
02:49 varuaa joined
02:49 Scip_ joined
02:50 arctictern joined
02:51 Hunter1 joined
02:51 chao-tic joined
02:52 juanpaucar joined
02:56 Argue joined
02:56 juanpauc_ joined
02:58 Argue joined
03:01 juanpaucar joined
03:02 geekosaur joined
03:02 sanitypassing joined
03:02 conal joined
03:02 takle joined
03:03 andyhuzhill joined
03:03 connrs joined
03:04 n_blownapart joined
03:06 juanpauc_ joined
03:07 pranitbauva1997 joined
03:07 conal joined
03:08 davr0s joined
03:08 <n_blownapart> hi anyone know if there are (still) issues running haskell on the atom ide ? I was learning haskell and had a tough time configuring Atom for stack et al.
03:10 takle joined
03:10 juanpaucar joined
03:12 saussure joined
03:12 andyhuzhill joined
03:14 connrs joined
03:15 juanpaucar joined
03:15 LuckyRawApe joined
03:16 sanitypassing joined
03:16 sanitypassing joined
03:17 Guest10 joined
03:17 ChaiTRex joined
03:17 slack1256 joined
03:18 CoderPuppy joined
03:19 Xanather joined
03:19 juanpaucar joined
03:20 wroathe joined
03:20 sellout- joined
03:20 flatmap13 joined
03:20 louispan joined
03:21 aarvar joined
03:21 <slack1256> why is important to check that laws are being respected to cases like (Just bottom)?
03:21 raibutera joined
03:21 <slack1256> wouldn't fast a loose reasoning be enough for the cases we actually care?
03:22 neror joined
03:23 <EvanR> yes
03:23 <EvanR> caring about stuff and not caring changes a lot
03:24 <EvanR> if bottom doesnt happen and laws work ignoring bottom, then last work
03:24 <EvanR> laws work
03:24 cschneid_ joined
03:24 juanpauc_ joined
03:24 cschneid_ joined
03:25 neror left
03:25 flatmap13 joined
03:26 lavalike joined
03:27 takle joined
03:28 flatmap13 joined
03:28 systemfault joined
03:29 juanpaucar joined
03:29 flatmap13 joined
03:31 sanitypassing joined
03:32 <slack1256> I worry that because making something completely law abiding, I incur in code that must use a lot of stack levels or is operationally not optimal
03:33 <EvanR> example?
03:33 <slack1256> I was thinking on the fmap instance for lazy state
03:33 juanpaucar joined
03:34 <slack1256> it lazy patterns on the tuple, nothing wrong with that. But references are being maintained instead of evaluated and collected
03:34 <slack1256> *it's
03:34 <EvanR> isnt that why youd choose lazy state, so it works in the presence of things that require extra laziness
03:34 <EvanR> maybe you want strict state
03:35 <slack1256> didn't strict state meet less laws?
03:36 <EvanR> like what, i have not heard of this
03:37 takle joined
03:38 juanpauc_ joined
03:38 <slack1256> I think it was the left identity one, let me check
03:40 jsgrant joined
03:40 louispan joined
03:40 <EvanR> o_O
03:40 wroathe joined
03:42 juanpaucar joined
03:43 tromp joined
03:43 <glguy> m >>= return = m
03:43 <glguy> but for State
03:43 <glguy> (undefined >>= return :: State a b) `seq` ()
03:43 <glguy> ()
03:45 <EvanR> how is that a consequence of strictness?
03:45 <glguy> That one's not different for Strict vs Lazy State, that's just it not following the monad laws
03:46 andyhuzhill joined
03:46 <EvanR> o_O
03:46 <slack1256> @info State
03:46 <lambdabot> State
03:46 <EvanR> is haskell a lie
03:46 <Clint> :-O
03:47 <glguy> same on the other side
03:47 <slack1256> (\s -> undefined) `seq` ()
03:47 <glguy> (return () >>= undefined :: State a b) `seq` ()
03:47 <glguy> ()
03:47 xall joined
03:47 <slack1256> basically what is happening
03:47 juanpauc_ joined
03:47 <glguy> return a >>= k = k a
03:47 takle joined
03:48 <slack1256> > (\s -> undefined :: State a b) `seq` ()
03:48 <lambdabot> ()
03:48 <slack1256> yet this is only related to my point. What if in trying to make instance abide by all the laws, I end up with code that is operationally not optimal
03:49 <glguy> Then don't do that?
03:49 felixsch_ joined
03:49 <slack1256> just for trying to handle cases like `undefined >> return = undefined` correctly
03:49 <EvanR> fast and loosely reasoning is precisely about this
03:49 <EvanR> if bottom isnt happening, then all the work youre doing to understand it isnt doing anything
03:50 <slack1256> usually is not clear to me at the writing moment. After pondering a while I get it
03:51 twomix joined
03:52 juanpaucar joined
03:52 obadz joined
03:53 Argue_ joined
03:54 primal joined
03:54 primal_ joined
03:55 <slack1256> Mmm the whole point of "fast & loose" is that if I say "bottom isn't happening", no other effect in the analysis happens at haskell level other than the lack of bottom right?
03:56 <primal_> Yop [REGEX] I get a format like TTTTXYUUUXYIIIXY and i just whant to replace the first XY some idea ?
03:56 <primal_> my problem, it'"s i what he replace only one occurence of XY
03:56 juanpaucar joined
03:56 drcode joined
03:57 <primal_> i can replace, but he will replace all of thream
03:57 <EvanR> lack of bottom cant make a program that worked with bottom not work... where work means _
03:57 takle joined
03:57 LuckyRawApe joined
03:57 mtg joined
03:57 <EvanR> not freeze up
03:57 <primal_> try stuff like {1} but still replace all
03:58 <slack1256> I wonder how many non esoteric programs work like that
03:58 <platz> I got the techempower blues, woa-ah-o-wah
03:58 <* slack1256> remember the fix definition
03:58 <slack1256> dman
03:58 conal joined
03:59 <primal_> i found Regex.Replace(input, replacement, count); but i need to send a count ? i can't solve the problem via only a regex ?
03:59 slack1256 left
03:59 louispan joined
04:01 <EvanR> platz: referring to web framework benchmarks or?
04:01 juanpaucar joined
04:06 juanpauc_ joined
04:10 takle joined
04:10 juanpaucar joined
04:11 saussure joined
04:12 systadmin joined
04:12 LuckyRawApe joined
04:13 <platz> EvanR: pretty much - bummed, though I'm fairly sure I lack the skills to contribute
04:14 infinity0 joined
04:15 juanpaucar joined
04:18 <EvanR> platz: well, i wonder what a non-framework web solution would look like
04:19 <EvanR> performance wise
04:19 louispan joined
04:19 <EvanR> or it doesnt matter because people would rather see a framework being fast and just use that, at whatever cost
04:19 juanpaucar joined
04:19 kvda joined
04:20 <EvanR> otoh, if its 5x slower and ur-web is 2x slower... this is sort of cutting hairs from a big-O perspective
04:20 <EvanR> (than the fastest)
04:21 <platz> i wonder what a pure wai/warp stripped down solution would look like too
04:21 <EvanR> i was thinking snap
04:21 Swizec joined
04:22 <platz> the discussion shows a real dollar cost difference in additional instances needed to support a given traffic volume relative to others
04:22 hybrid joined
04:22 wroathe joined
04:23 `Guest00000 joined
04:23 <platz> even so, if there is some badness in DB, or JSON parsing.. i mean those are common ops
04:23 <`Guest00000> why are exceptions not monoid?
04:23 <platz> the websocket shootout didn't end well either
04:23 <EvanR> your bands website traffic? medium to large name business traffic?
04:24 <pacak> `Guest00000: How would you combine two exceptions?
04:24 <platz> well, you got me there. no i don't have such requirements. thinking more as a selling point
04:24 juanpaucar joined
04:24 <EvanR> heh
04:24 kaychaks joined
04:24 <`Guest00000> the problem with the "finally" blocks, when there's an exception and control goes into the "finally" block and another exception happens there
04:24 <EvanR> "pay no attention to practical issues, see here the theoretical savings"
04:25 <`Guest00000> one of exceptions is dropped
04:25 <EvanR> platz: man i remember a great websockets lib... i think bitrotted way back
04:26 <EvanR> an exception during your finally block?
04:26 <glguy> `Guest00000: Being a monoid wouldn't help, the exceptions can be different types
04:26 <`Guest00000> sorry, this is sort of offtop, i don't mean in haskell specifically
04:27 eklavya joined
04:27 ortmage joined
04:27 <glguy> `Guest00000: My answer wasn't Haskell specific
04:28 <kaychaks> Is there some reference (other than the backtracking paper) / posts / tutorials on how Logic Monad can be used in Logic Programming ?
04:28 xcmw joined
04:28 juanpaucar joined
04:29 <jle`> how is the package documentation?
04:30 <kaychaks> jle` : package doc points to the paper
04:32 inad922 joined
04:32 <peddie> kaychaks: https://github.com/atzeus/reflectionwithoutremorse/blob/master/TicTacToe.hs https://github.com/atzeus/reflectionwithoutremorse/blob/master/MCPT.hs
04:33 <kaychaks> peddie : thanks I will go through them
04:33 juanpauc_ joined
04:35 kvda joined
04:36 systadmin joined
04:37 MP2E joined
04:38 juanpaucar joined
04:38 cpennington joined
04:40 RayNbow`TU joined
04:40 Argue__ joined
04:42 micmus joined
04:42 juanpauc_ joined
04:42 drewbert joined
04:43 wroathe joined
04:47 halogenandtoast joined
04:47 juanpaucar joined
04:47 abroz joined
04:47 JoelMcCracken joined
04:49 <`Guest00000> what is a portable way to redirect stdout to void (/dev/null, NUL, etc)?
04:50 mtg joined
04:51 juanpaucar joined
04:52 cschneid_ joined
04:53 jhrcek joined
04:53 filterfish joined
04:54 bkboggy joined
04:56 andyhuzhill joined
04:56 juanpauc_ joined
04:57 sanitypassing joined
04:58 torgdor joined
04:58 simukis_ joined
05:00 <EvanR> redirecting is part of your shell functionality
05:01 <EvanR> the thing that is spawning the process in the first place
05:01 juanpaucar joined
05:01 <EvanR> so you could write a portable shell...
05:03 jaziz joined
05:04 wroathe joined
05:04 ErinvanderVeen joined
05:05 juanpaucar joined
05:05 mjora7 joined
05:06 saussure joined
05:08 dec0n joined
05:09 sproingie joined
05:09 louispan joined
05:10 juanpaucar joined
05:13 dfeuer joined
05:13 abroz joined
05:13 jluttine joined
05:14 juanpaucar joined
05:15 saussure joined
05:18 saussure joined
05:19 juanpaucar joined
05:20 Kuros` joined
05:20 augur joined
05:21 mmachenry1 joined
05:21 anodium joined
05:22 lgas joined
05:22 jutaro joined
05:23 dec0n joined
05:23 xall joined
05:23 meandi_2 joined
05:24 juanpaucar joined
05:24 revprez joined
05:24 robotroll joined
05:25 wroathe joined
05:27 jykell joined
05:28 juanpauc_ joined
05:29 xcmw joined
05:30 connrs joined
05:31 kvda joined
05:32 dan_f joined
05:33 juanpaucar joined
05:34 vlatkoB joined
05:34 sanitypassing joined
05:35 benl23 joined
05:36 abroz joined
05:38 juanpaucar joined
05:38 jluttine joined
05:38 joakim` joined
05:38 joakim` joined
05:39 caumeslasal joined
05:41 danvet joined
05:41 xtreak joined
05:42 juanpauc_ joined
05:42 kaychaks joined
05:43 tromp joined
05:43 hexfive joined
05:43 leat joined
05:45 <hexfive> is it possible to use typeclasses in a type synonym declaration?
05:46 <glguy> What are you trying to do, there are a couple of answers.
05:46 <jle`> what do you mean
05:46 <jle`> typeclasses are just first-class things at the type level, so with ConstraintKinds you can use them as teh results of a typesynonym
05:46 <hexfive> something like (Integral i, [i])
05:47 juanpaucar joined
05:47 <glguy> hexfive: What would that mean?
05:47 <hexfive> essentially a point in multidim space
05:47 <glguy> I mean in Haskell...
05:47 <hexfive> ah, sorry
05:48 <hexfive> right now i have `type FT = (Int, [Int])`
05:48 <glguy> OK, you can do this: type FT i = (i, [i])
05:48 <glguy> the constraints will go on the things that use FT
05:49 <hexfive> ahh, okay. I was looking for the syntax in defining the constraints. thanks!
05:49 Xanather joined
05:51 shangxiao joined
05:51 juanpaucar joined
05:53 ThomasLocke joined
05:54 FjordPrefect joined
05:56 juanpauc_ joined
05:58 thang1 joined
05:59 <thang1> sup
05:59 hurkan joined
05:59 mrkgnao joined
06:00 <mrkgnao> are there any type-level extensible records libraries?
06:01 juanpaucar joined
06:03 bonz060 joined
06:03 <jle`> what is a type-level extensible record?
06:04 <glguy> It's like a value level extensible record (vinyl and friends) but for types instead of values
06:05 <glguy> (unfortunately we don't have a nice solution for non-extensible records at the type-level, either)
06:05 <jle`> we also don't even have a nice solution for value-level extensible records
06:05 <thang1> Does anyone?
06:05 juanpauc_ joined
06:05 <glguy> Such disappoint
06:06 <EvanR> the language infernu ?
06:06 <EvanR> theres also an extensible record library for idris that uses syntax sugar and dependent types
06:06 <jle`> (type-level) (extensible) records, pick 0
06:07 wroathe joined
06:07 <EvanR> and in idris, thatd work for values and types, or both at the same time
06:08 dan_f joined
06:08 sproingie joined
06:09 mbuf joined
06:10 juanpaucar joined
06:10 takle joined
06:12 connrs joined
06:14 Argue_ joined
06:14 juanpauc_ joined
06:15 Hunter1 joined
06:15 filterfish joined
06:15 Swizec joined
06:15 <mrkgnao> glguy: jle`: well, I'd be happy just being able to use a list of key-value pairs (normalized by sorting the keys), but I'm looking for a way to not have to repeat myself
06:16 <mrkgnao> Previously, I had ways of doing what I want where it'd be enough to be able to use a type family in an instance head, or promote a data family, but both of those are out.
06:17 Swizec_ joined
06:17 cpup joined
06:17 CoderPuppy joined
06:17 <mrkgnao> if I could just sort the list in instance heads (so I don't have to sort them myself when declaring the instances, which is error-prone), I'd be a happy camper
06:18 dm3 joined
06:18 <mrkgnao> There's a Sort type family which does the thing, but I can't write instance (Foo a, Foo b) => Bar (Sort ["b" := b, "a" := a])
06:18 nomotif joined
06:19 Yuras joined
06:19 juanpaucar joined
06:20 takuan joined
06:21 baldrick1 joined
06:21 castlelore joined
06:22 freusque joined
06:22 _sras_ joined
06:23 <_sras_> In Servant, is there an easy way to extract path from the type of an endpoint?
06:24 juanpaucar joined
06:24 sproingie joined
06:26 ChaiTRex joined
06:28 grizwako joined
06:28 juanpauc_ joined
06:29 isenmann joined
06:30 xcmw joined
06:33 juanpaucar joined
06:35 takle joined
06:36 jutaro1 joined
06:37 nshepperd joined
06:37 juanpaucar joined
06:37 andyhuzhill joined
06:38 Hunter1 joined
06:39 XorSwap joined
06:40 paolino joined
06:41 dm3 joined
06:41 abroz joined
06:41 yobohohoz joined
06:42 ertes-w joined
06:42 juanpauc_ joined
06:42 blym joined
06:43 yobohohoz joined
06:43 alfredo joined
06:43 sproingie joined
06:43 sproingie joined
06:43 louispan joined
06:44 yobohohoz joined
06:44 takle joined
06:46 torgdor joined
06:46 justanotheruser joined
06:46 juanpaucar joined
06:46 hurkan left
06:47 torgdor joined
06:47 JakePeralta joined
06:48 filterfish joined
06:48 wroathe joined
06:48 laplacian joined
06:49 filterfish_ joined
06:51 juanpauc_ joined
06:52 yobohohoz joined
06:53 blym joined
06:54 <ertes-w> Philonous: software design in a dependently typed language is a new and for the most part unexplored area, so i wouldn't expect there to be a blog post or tutorial that can give you any definitive directions
06:54 jgt3 joined
06:56 juanpaucar joined
07:00 <_sras_> In Servant, is there an easy way to extract path from the type of an endpoint?
07:00 sproingie joined
07:00 juanpaucar joined
07:01 tiny_test joined
07:02 osa1 joined
07:02 osa1 joined
07:02 iross joined
07:03 AlphaAtom joined
07:04 <Axman6> _sras_: I don't know of an existing method to do it, and it;s not completely clear what that would look like in the presence of things like captures and query params
07:04 <Axman6> it woiuldn't be difficult to make an appropriate type family though
07:04 guiben joined
07:04 torgdor joined
07:05 biglama joined
07:05 juanpaucar joined
07:06 <_sras_> Axman6: I am trying to implement a HasSwagger instance for some paths, where I want to add a description to all the endpoints in it. Is there any way this could be done with out actually getting the path from the type?
07:06 rafaelcgs10 joined
07:07 eacameron joined
07:07 torgdor joined
07:08 takle joined
07:09 juanpaucar joined
07:10 Itkovian joined
07:10 CurryWurst joined
07:10 wroathe joined
07:11 <Axman6> yeah that feels like the wrong way to do things, but it's been a while since I played with servant-swagger stuff. I would take a look around the package and see if the thing you're after already exists in the package asd a type class, which would allow you to modify parts of produced Swagger value
07:11 SenpaiSilver joined
07:12 takle joined
07:12 xtreak joined
07:13 freusque joined
07:14 juanpauc_ joined
07:15 vlatkoB_ joined
07:15 sproingie joined
07:15 sproingie joined
07:17 yoneda joined
07:19 <ph88^> hello
07:19 juanpaucar joined
07:19 dm3 joined
07:20 <ph88^> i have a conduit which processes Double's .. but in order to process them i need the average between the pairs of doubles first (basically (last double - first double) / amount of doubles) how can i split my conduit in 2 and do this calculation first and then use the outcome to continue the conduit as normal ?
07:20 cdepillabout joined
07:21 dalek_ joined
07:21 dalek__ joined
07:21 butterthebuddha joined
07:23 joakim` joined
07:23 <cocreature> ph88^: I’m not sure I understand your question. by last and first double you mean the very first double and the very last double in your stream? what do you do with the doubles in between?
07:23 tiny_test joined
07:23 juanpauc_ joined
07:28 juanpaucar joined
07:28 test174638 joined
07:30 refold joined
07:30 <halogenandtoast> Anyone familiar with the Spock framework know offhand if I can get the domain for the request?
07:30 wroathe joined
07:30 mattyw joined
07:31 xcmw joined
07:31 <ph88^> cocreature, yes i mean the very last and very first double .. with the doubles in between i just need to know that they happened (to get the total amount of doubles)
07:32 <ph88^> if i have 1000 doubles in stream and first double was 2 and last was 800 then i need to calculate (800 - 2) / 1000 to get the average time between 2 doubles
07:32 <cocreature> ph88^: I would write a fold that computes your expected result using https://hackage.haskell.org/package/foldl-1.2.5/docs/Control-Foldl.html and then use sinkFold https://hackage.haskell.org/package/conduit-extra-0.1.6/docs/Data-Conduit-Extra-Foldl.html to turn this into a consumer
07:32 juanpaucar joined
07:32 sproingie joined
07:33 <ph88^> halogenandtoast, they domain should be in the request .. maybe take a look at the request data type
07:33 <ph88^> thanks cocreature i will take a look at those functions
07:34 <cocreature> ph88^: the nice thing about the foldl library is that using the Applicative instance of Fold you can trivially compose folds to get a new fold that still only requires a single traversal
07:34 <cocreature> in your case you want the head, last and length fold
07:34 tiny_test joined
07:35 quchen joined
07:35 <cocreature> so you get something like liftA3 (\maybeFirst maybeLast num -> liftA2 (\first last -> (first - last) / fromIntegral num) maybeFirst maybeLast) head last length
07:35 <halogenandtoast> ph88^: Sounds simple, but not proving so, I have no idea how to get the request data type either.
07:36 connrs joined
07:36 <halogenandtoast> Oh well, I'll spend time reading the source until I find something.
07:37 juanpaucar joined
07:38 mekeor joined
07:38 Test182738 joined
07:39 sampuka joined
07:39 <cdepillabout> halogenandtoast: https://hackage.haskell.org/package/Spock-core-
07:39 <cdepillabout> This gets you the original wai Request.
07:39 <ph88^> cocreature, what is that maybeFirst ?
07:40 <cocreature> ph88^: if you take a look at the signature of the "head" fold it gives you a Maybe a because there might not be a first element
07:40 <halogenandtoast> cdepillabout: thanks that will probably do it.
07:40 pgiarrusso joined
07:40 <halogenandtoast> cdepillabout: How's Arow these days?
07:41 Wizek_ joined
07:41 <Test182738> Hi
07:41 Levex joined
07:42 juanpaucar joined
07:42 <cdepillabout> halogenandtoast: Doing well. We may start on a new project for a company here in Tokyo sometime soon, so I'm really looking forward to that.
07:42 <cdepillabout> Oh hey, I just googled your name and I realized who you were :-)
07:43 yobohohoz joined
07:43 <cdepillabout> Have you been doing much Haskell lately?
07:43 <halogenandtoast> cdepillabout: I've been trying, I think I finally found a "good" use for a Haskell app at my job.
07:43 <halogenandtoast> Or basically I found an internal tool I can force us to use Haskell with
07:44 tromp joined
07:44 <cdepillabout> Oh really?? Is that the first time that Haskell will be used at cookpad?
07:44 <halogenandtoast> Yeah
07:44 <cdepillabout> nice!
07:44 <halogenandtoast> Basically when we buy out other companies we need to redirect their old site to Cookpad, but we want to map recipes, users, and also we want categories to hit our search
07:45 <halogenandtoast> so I was thinking I could make a haskell app that just takes a "map" file
07:45 <halogenandtoast> We could probably use a proxy server to do this, but...
07:46 <cdepillabout> Sounds like a nice Haskell project.
07:46 <halogenandtoast> exactly :D
07:46 ph88 joined
07:46 <cdepillabout> Are any of your coworkers interested in Haskell? (or even functional programming?)
07:46 juanpaucar joined
07:46 <halogenandtoast> Yeah a few, but none of them are writing any except one.
07:46 bvad joined
07:46 <ph88> still broken :/ http://ircbrowse.net/browse/haskell
07:46 <halogenandtoast> Thinking of starting an after hours Haskell Hack Night internally
07:47 Wizek_ joined
07:47 <halogenandtoast> That might get more people interested
07:47 <halogenandtoast> One guy on the Japan side wrote this: https://github.com/taiki45/hs-vm
07:47 <halogenandtoast> which is pretty awesome
07:48 augur joined
07:49 <ph88> i'm writing a small app for work to do some DSP
07:49 merijn joined
07:49 <cdepillabout> If you opened it up to outside people (like the Tokyo Haskell meetup, or the Haskell Mokumoku-kai), I bet people would go. I know I would try to make it out. The cookpad office is pretty awesome.
07:50 <halogenandtoast> cdepillabout: I'll see what I can do and reach out if I get something running.
07:50 <james999> how does haskell solve that problem where you have a type that can be A or B, and functions that take in that type, and then you want to add an option C to the type?
07:51 <halogenandtoast> It would be awesome to have more people.
07:51 juanpaucar joined
07:51 wroathe joined
07:51 nshepperd joined
07:52 <halogenandtoast> james999: sounds like a Sum type, usually with pattern matching.
07:52 <halogenandtoast> Or specifically, I tend to solve that problem with pattern matching.
07:52 <cdepillabout> halogenandtoast: Awesome. I'd definitely be interested.
07:52 <james999> because normally you have to update each function that takes the type with a new case for possibility of C
07:52 <halogenandtoast> Yes, that's what you'd do james999
07:52 Mortomes|Work joined
07:53 <halogenandtoast> Add a new pattern to match against.
07:53 <ab9rf> i think you might need to be a bit more concrete in explaining what you're trying to accomplish
07:53 <james999> oh ok. i read theres a split where in OO you can easily add new types, and in functional languages you can easily add new functions.
07:53 <james999> and the opposite operations are hard
07:53 mlehmk joined
07:54 <merijn> james999: That distinction is commonly known as "the expression problem"
07:54 <james999> right, that
07:54 <mlehmk> hi
07:55 <Liskni_si> james999: it's worth mentioning that if you add C, you get warnings for each and every function that needs to be adapted
07:55 <merijn> james999: Lots of interesting things to read on that. And yes, different things are hard in OO and FP. There's several ways of doing things, but how much time/boilerplate you're willing to invest depends on how likely it is that people will want to add things
07:55 juanpauc_ joined
07:55 <james999> sure, predicting when people would want to add things is hard
07:55 <james999> but i presume there are scenarios where you want to make one or the other easier
07:56 <merijn> james999: Well, one trick you can use to make extending easier is what I like to call "OO Haskell" where you treat records as object that implement an interface
07:57 eklavya joined
07:57 jcjustjc joined
07:57 <merijn> james999: I'm using that approach in some benchmarks: https://github.com/merijn/broadcast-chan/blob/master/benchmarks/Channels.hs#L47-L59
07:57 <james999> merijn: ah ok. the visitor pattern in OO is a way of circumventing the expression problem temporarily
07:58 eacameron joined
07:58 <ab9rf> merijn: i've used that, it actually reminds me of how i used to OO in plain C way back when
07:58 <merijn> james999: You can see further in the file how I use those records to wrap Chan, TChan, and a bunch of others to give them a single interface I can use :)
07:58 <merijn> ab9rf: It works really well, especially combined with RecordWildCards :)
07:58 <james999> ab9rf: how, make a structure of function pointers or something?
07:58 <ab9rf> james999: yup
07:59 <ab9rf> james999: which is actually how C++ does it in ternally (vtables)
07:59 <ab9rf> you just have to make it explicit instead of relying on language sugar to abstract it away
08:00 juanpaucar joined
08:00 <james999> ab9rf: yeah you have more flexibility that way too to do what you want
08:00 <merijn> james999: Anyway, have a look at that github link, if there's anything you don't get I can explain it :)
08:01 Kreest__ joined
08:01 <ab9rf> james999: but the price of that flexibility is that yhour code is more complicated, has lots of boilerplate, and will break if you're not disciplined
08:01 WhereIsMySpoon left
08:02 <ab9rf> which is why we have so many different programming languages :)
08:02 <james999> merijn what is this broadcastChan about?
08:02 <torstein> I'm not sure how to structure sequential, related HSpec tests. For example, load contents of two directories, then check that the files in the two directories have the same file names, then check that they have the same contents. http://lpaste.net/355662
08:02 fizruk joined
08:02 ventonegro joined
08:03 <merijn> james999: Well, it was a simple hack to work around a problem I had with Chan, but I'm hoping to finish up some stuff and bump the version to 1.0 as strictly better version of Chan :)
08:03 <torstein> The structure of the test suite above is a bit awkward, since the asserts are in comments on in "it"'s
08:04 guardianx joined
08:04 <ventonegro> Can't build Idris on OS X uising Stack, I get linker errors related to iconv... Anybody seen that?
08:05 JagaJaga joined
08:05 juanpaucar joined
08:06 <quchen> Seems to be an OSX-specific problem, built it with Linux yesterday
08:06 thc202 joined
08:06 <ventonegro> Yeah, I can build on Linux at work
08:07 nickolay joined
08:08 <merijn> I like to call this graph "TMVar performs so shit under contentation that it is making my benchmarks useless" http://files.inconsistent.nl/TMVar.png
08:08 <merijn> s/contentation/contention
08:08 <merijn> typing is hard
08:09 juanpaucar joined
08:09 <merijn> Can I somehow make criterion split the graph into subgroups?
08:10 <merijn> Or I guess I should just eliminate TMVar entirely
08:10 guardianx left
08:11 marr joined
08:11 coot____ joined
08:12 <Philonous> Oh wow, I realized STM was prone to lifelock, but that's horrifying
08:12 wroathe joined
08:12 <merijn> Philonous: Well, note that the others do much better
08:12 sirreal joined
08:12 <merijn> It's specifically TMVar that's *really* awful
08:12 <merijn> But yeah, the thunder herd is real
08:12 abroz joined
08:13 <cocreature> why does TMVar perform so much worse than TVar?
08:13 <Philonous> Does TVar have to retry?
08:13 <merijn> Yes
08:14 <merijn> Code is here, if there's anything you think could make it faster, lemme know: https://github.com/merijn/broadcast-chan/blob/master/benchmarks/Sync.hs
08:14 juanpaucar joined
08:14 <quchen> TMVar a = TVar (Maybe a)
08:14 <merijn> Note that those are the unthreaded implementation numbers, the threaded implementation has much more variation
08:14 raichoo joined
08:14 <merijn> Unfortunately, criterion is producing some NaN's for those benchmarks, which wreck the JS plotting library, so it's not producing graphs for those :\
08:15 <merijn> I haven't figured out how to fix that yet
08:15 <merijn> If someone knows how I can feed filtered CSV from criterion back into criterion to produce graphs I can make those
08:16 <quchen> Criterion really ought to normalize benchmark groups
08:16 osa1 joined
08:18 <angerman> cocreature: I hope I can entertain you yet another day :)
08:18 <cocreature> angerman: :)
08:18 osa1_ joined
08:18 juanpaucar joined
08:19 <merijn> quchen: Well, I just got the message that my changes will be merged soon-ish, so that'll at least improve the benchmarking situation for IO :)
08:19 <quchen> merijn: Which changes?
08:19 <angerman> cocreature: that's going to be an exception though. I'll try to stick with three (Tue, Wed, Thu) though.
08:19 Zachoz1 joined
08:19 <cocreature> angerman: don’t let me stop you :)
08:20 <angerman> cocreature: lol, no. But, I need to get some work done... you know :-)
08:20 osa1__ joined
08:20 <merijn> quchen: https://github.com/bos/criterion/pull/136
08:21 <merijn> quchen: per benchmark and per batch environment setup and the ability to do cleanup after runs
08:21 <angerman> I usually write the drafts over the weekend. And then do minimal polish until release. That way I can work during the week :D
08:22 <quchen> merijn: Neat
08:22 osa1 joined
08:23 pie_ joined
08:23 juanpaucar joined
08:25 freusque joined
08:25 <cocreature> merijn: I’m slightly confused about the benchmarks. it seems like you are testing the performance of n threads running signal followed by wait so basically a barrier. but the syncTMVar code is weird. wait tries to take out the same mvar i times
08:25 <cocreature> oh wait is only run once
08:25 thunderrd joined
08:26 eacameron joined
08:26 <cocreature> well I’m not particularly surprised about the mvar performance then.
08:26 <cocreature> eh *tmvar
08:26 <merijn> cocreature: I'm not saying I expected it to be any good. It's honestly only in there for completeness
08:26 <merijn> I just didn't expect it to be *that* terrible
08:27 <merijn> Async actually does really well (in the threaded runtime, anyway)
08:27 <merijn> At the very least it's *very* consistent
08:27 biglama joined
08:28 osa1_ joined
08:28 juanpaucar joined
08:28 <merijn> With 10k threads in the threaded runtime Async is *consistently* at like 1.5-3 ms range, only AtomicCounter and IORef are remotely competitive, but they tend to produce really inconsistent and funky results
08:28 <merijn> i.e. ranging anywhere from a few hundred microseconds to 20 or so ms
08:29 <merijn> And in most of the other cases Async is like, top 3, so that's what I'm using now
08:29 <cocreature> I’m surprised MVar is so fast
08:29 <merijn> Haven't really looked at the non-threaded numbers yet
08:30 <cocreature> does GHC do some intelligent thread scheduling for MVars?
08:30 <merijn> cocreature: Well...so this graph is the non-threaded numbers. In the threaded case MVar does...pretty good
08:30 <merijn> Like, MVar is clearly slower than Async/AtomicCounter, but *way* better than I thought
08:30 <merijn> The non-threaded runtime seems to have even faster MVar operations
08:31 <merijn> cocreature: Yes. MVar's are fair and single-wakeup, so should be *much* better under contention than STM
08:31 <cocreature> ah yeah then it makes sense that it performs so much better
08:31 xcmw joined
08:32 barua joined
08:32 juanpaucar joined
08:33 wroathe joined
08:34 twanvl joined
08:35 <halogenandtoast> Is there a "correct" way to conver a Char to Word8?
08:36 <merijn> halogenandtoast: Yes. Don't
08:36 <halogenandtoast> for context: I'm trying to do: getDomain = BS.takeWhile (/= ':')
08:37 lep-delete joined
08:37 biglama joined
08:37 juanpaucar joined
08:37 <merijn> There's 'ord', but you better only use it on ascii, or you'll be doomed for eternity
08:37 <halogenandtoast> I really just want to take a ByteString in the format "foo:bar" and get back "foo"
08:37 Gurkenglas joined
08:37 <Philonous> halogenandtoast, You can use the functions from Data.ByteString.Char8
08:38 <Philonous> halogenandtoast, They accept chars and convert them to ASCII
08:38 <merijn> I propose we ban anyone who mentions that accursed module >.<
08:38 <cocreature> merijn: you can take Data.ByteString.Char8 from my cold dead hands
08:38 <merijn> cocreature: If I have to...
08:38 <Philonous> halogenandtoast, The correct way to do it is to convert your ByteString into Text and then you can work with chars properly
08:38 <halogenandtoast> fair enough, I'll do the correct way
08:39 <cocreature> it’s not always the correct way. if you are working with some ascii protocol then converting to Text is silly
08:40 <Philonous> cocreature, ASCII is a subset of UTF8, so you can use decodeUTF8
08:40 <cocreature> Philonous: I’m not saying it doesn’t work but it’s completely unnecessary overhead
08:41 quobo joined
08:41 <Philonous> Well, tbh I've been naughty and using Char8 a lot myself :>.
08:41 <Philonous> But using the right abstraction doesn't sound like unecessary overhead to me.
08:41 juanpauc_ joined
08:42 <cocreature> but it’s not the right abstraction if you’re working with ascii
08:45 takuan joined
08:45 uiop joined
08:45 xtreak joined
08:46 xtreak joined
08:46 juanpaucar joined
08:47 romank joined
08:48 xtreak joined
08:49 alexbiehl joined
08:51 juanpaucar joined
08:51 <halogenandtoast> If I wanted to read a value form the env with a default if it does not exists, kind of like how Yesod does it, what's the best way to handle that
08:51 <halogenandtoast> getEnv seems to raise if it doesn't exist
08:51 ridho joined
08:51 <merijn> cocreature: That's why I need to pick up https://hackage.haskell.org/package/validated-literals again soon :p
08:52 <merijn> cocreature: That way you could safely convert string literals to ByteString, rather than Char8's ridiculousness
08:52 <cocreature> merijn: if Char8 would throw an exception instead of truncating bytes, it would already be a lot better
08:53 abroz joined
08:53 butterthebuddha joined
08:54 <halogenandtoast> Is wrapping it in a try the best option?
08:55 <cocreature> halogenandtoast: the unix package contains getEnv that returns a Maybe
08:55 <cocreature> I have no idea why that is in the unix package and why the one in base does not return a Maybe
08:55 <cocreature> ah base has lookupEnv
08:55 juanpauc_ joined
08:55 <cocreature> yeah for consistencey …
08:55 comiccobe joined
08:55 baldrick1 joined
08:55 <halogenandtoast> ah
08:56 fotonzade joined
08:56 <merijn> Right
08:56 <merijn> For fans of benchmarks
08:56 <merijn> Non-threaded runtime: http://files.inconsistent.nl/sync.txt
08:56 <merijn> threaded runtime: http://files.inconsistent.nl/sync-threaded.txt
08:56 <merijn> Massive differences, surprisingly
08:57 <merijn> hmmm
08:57 <merijn> Looks like the server is fucking up the encoding
08:57 <cocreature> is that supposed to be microseconds?
08:57 <merijn> yeah
08:57 <merijn> It's just utf-8. not sure what the server is doing
08:58 <cocreature> tell your server to use utf-8 :)
08:58 <merijn> cocreature: It's not mine
08:58 <merijn> cocreature: Free webspace provided by my email host
08:59 osa1 joined
09:00 juanpaucar joined
09:00 <LiaoTao> merijn: lpaste? :D
09:00 <LiaoTao> Should work for regular texts too
09:01 <merijn> How do I get Chrome to show me the HTTP headers?
09:01 <cocreature> F12 and then find the network tab
09:02 <merijn> Got them, looks like they don't specify a Content-Encoding header at all
09:02 ed-ilyin-lv joined
09:02 <merijn> So the question is: Why is Chrome defaulting to non-UTF8 for unspecified encoding?
09:02 cretiq joined
09:03 <cocreature> probably that is specified somewhere™
09:03 <cocreature> firefox does the same
09:03 <cocreature> merijn: can you use htaccess files?
09:03 sfcg joined
09:03 <merijn> cocreature: No idea, tbh
09:03 <merijn> "Chrome will do auto-encoding detection " <- not very well, apparently >.>
09:05 juanpaucar joined
09:05 ixxie joined
09:05 <dario`> often such auto-detection only looks at the first 2^n bytes (typically 512, 1024 or 4k), so it might have missed that
09:06 <merijn> I'll just open a ticket and see what they say
09:07 <LiaoTao> merijn: "Won't fix"
09:07 <merijn> LiaoTao: I'm still optimistic :p
09:08 <LiaoTao> That is, if you get an answer at all
09:08 xtreak joined
09:08 <merijn> LiaoTao: See, the beauty of actually paying for hosting is getting a support response within 24 hours :)
09:08 <LiaoTao> merijn: I thought you meant Chrome
09:08 <LiaoTao> :D
09:09 takle joined
09:09 balor joined
09:09 juanpaucar joined
09:10 arctictern joined
09:12 bonz060 joined
09:12 ragepandemic joined
09:12 xtreak joined
09:13 <mutsig_> I'm performing some profiling of a program. In my heap profile, I have a significant portion of the heap being covered by "THUNK". Is there anything meaninful I can conclude from this, since it doesn't specify any particular funciton?
09:13 <merijn> Anyway, back to the data. The non-threaded runtime appears to be 2 orders of magnitude faster
09:14 abroz joined
09:14 juanpauc_ joined
09:14 <merijn> And async performs terible in the non-threaded case
09:14 <merijn> It's like bottom 3 in all cases
09:14 xtreak joined
09:15 wroathe joined
09:15 jgt3 joined
09:15 <mniip> hmm
09:16 <mniip> what is this property called, where a function can either be strict in certain argument, or it has to ignore it overall
09:16 ericsagnes joined
09:16 oish joined
09:17 <mniip> it's not monotonicity because 'const () :: Bool -> ()' is not monotonic wrt bottoms
09:17 <mniip> or is it
09:17 <mniip> oh it is
09:18 acidjnk22 joined
09:18 <mniip> but then this statement is stronger than monotonicity
09:18 takle joined
09:18 juanpaucar joined
09:19 lonokhov joined
09:20 pgiarrusso joined
09:21 Elhamer joined
09:22 birdgg joined
09:23 juanpaucar joined
09:23 osa1_ joined
09:24 andyhuzhill joined
09:25 ixxie joined
09:26 bjz joined
09:27 oish_ joined
09:27 mattyw joined
09:27 juanpauc_ joined
09:28 nglsr joined
09:30 xcmw joined
09:31 mmn80 joined
09:32 juanpaucar joined
09:33 <merijn> The only sad thing is that to plot partial results I need the JSON files, which I didn't produce, so I have to run the benchmarks again for like 12 hours >.>
09:34 ilyaigpetrov joined
09:35 niteria joined
09:36 wroathe joined
09:36 jutaro joined
09:37 juanpaucar joined
09:37 heurist joined
09:38 yogsototh joined
09:41 kareeeeem joined
09:41 <Gurkenglas> mniip, all functions you can define in Haskell are monotonic
09:41 <mniip> that is correct
09:41 juanpauc_ joined
09:41 <Gurkenglas> mniip, bottom maps to either a minimum or a maximum in definedness
09:41 <mniip> but \x -> case x of () -> True; _|_ -> False
09:41 <Gurkenglas> oh wait no, it might map to a nonmaximum but everything larger than it maps to that as well. hm.
09:41 <mniip> is monotonic
09:42 Elhamer_ joined
09:43 <Gurkenglas> Why do you think "bottom maps to bottom or everything maps to the same value" has a shorter description?
09:43 <Philonous> mniip, I don't think True and False are comparable
09:44 <Philonous> mniip, That would lead to True >= False and False >= True ==> True == False
09:44 <Gurkenglas> I dont think you can pattern match on undefined. Or was your point that not all monotonic functions can be defined in Haskell?
09:44 <mniip> Philonous, we're talking about partial order of bottoms
09:44 <mniip> Gurkenglas, yes, that
09:44 <Philonous> mniip, Yes, and the only elements of that relation are _|_ <= T for all T
09:44 <mniip> Philonous, no
09:44 <Gurkenglas> mniip, that function you gave isnt monotonic
09:45 <Gurkenglas> () >= _|_, but not True >= False
09:45 <mniip> True <=> False
09:45 <mniip> no?
09:45 <Gurkenglas> no
09:45 <Philonous> What does <=> mean?
09:45 <Gurkenglas> <= in both directions, I suppose.
09:46 <Philonous> That would imply equality
09:46 juanpaucar joined
09:46 <Gurkenglas> Only for some relations.
09:46 <mniip> yeah I avoided the = symbol
09:46 <Gurkenglas> (For the partial order of bottoms it would though.)
09:46 <mniip> Gurkenglas, maybe I'm misinterpreting the "partial order of bottoms" relation?
09:46 <Philonous> Gurkenglas, Yes, for example partial orderings, which by definition are antisymmetric
09:47 jutaro joined
09:47 mmhat joined
09:47 <mniip> does it only contain _|_ <= True, _|_ <= False and reflexive stuff?
09:47 <Gurkenglas> Yep.
09:47 <mniip> and for lazy data, (_|_, y) <= (x, y), but not (_|_, z) <= (x, y) ?
09:48 heurist` joined
09:48 <Gurkenglas> But also _|_ <= [_|_] and [2,_|_] <= [2,3] and [2,_|_] </=/> [_|_,2]
09:48 <Philonous> Unless < <= y
09:48 <pgiarrusso> mniip: that depends on z and y
09:48 <Philonous> z <= y
09:48 <mniip> right
09:48 oish_ joined
09:48 <pgiarrusso> Ints and all such *flat* data types are like Bool, but functions are trickier
09:48 <mniip> Gurkenglas, I understand [2,_|_] </=/> [_|_,2]
09:49 <mniip> but I thought True <=> False
09:49 <mniip> because they are on the same level of "definedness"
09:49 <Philonous> Your <=> really is ==
09:49 <Gurkenglas> No that would make that function you gave that cant be defined in haskell monotonic :P
09:49 sproingie joined
09:49 sproingie joined
09:49 <mniip> alright
09:49 <mniip> so then,
09:49 <mniip> are all haskell functions monotonic?
09:50 <Philonous> mniip, Yes, necessarily
09:50 <Gurkenglas> Ive got that statement cached but dont know how to prove it
09:50 <mniip> are all monotonic computable functions haskell?
09:50 <Gurkenglas> (Probably by induction on Haskell's syntax.)
09:50 juanpaucar joined
09:51 <pgiarrusso> mniip: that's much trickier, let's go with "no" — the keyword to google is "full abstraction" but it's high math
09:51 <pgiarrusso> Gurkenglas: "all functions are monotonic" is more a definition
09:51 <pgiarrusso> Gurkenglas: you define a model using monotonic function spaces
09:52 bonz060 joined
09:52 <pgiarrusso> and then you give a semantics for Haskell functions into this model
09:52 <merijn> Isn't the fact that all functions are monotonic the fact that gives "Fast and Loose Reasoning is Morrally Correct" it's point?
09:52 <Gurkenglas> pgiarrusso, or our definedness relation was defined as an extremum among those such that "all haskell functions are monotonic" is true?
09:53 <mniip> pgiarrusso, I am capable of high math...
09:53 <pgiarrusso> merijn: I think even strict functions are monotonic... so I'm not sure
09:53 <Gurkenglas> Sure, strict functions are monotonic.
09:53 <Gurkenglas> Strict functions are just those where _|_ maps to _|_
09:53 <pgiarrusso> mniip: no offense, was just a warning — I'd say I'm not
09:53 henriksod joined
09:54 <Gurkenglas> (For nonstrict functions, monotonicity thus forbids mapping to _|_ at all)
09:54 <pgiarrusso> Gurkenglas: not quite
09:54 <_sras_> How can I set description for parameters in a Swagger schema?
09:54 <pgiarrusso> I think your claim might be true on flat source and target domains
09:54 bennofs joined
09:55 <ertes-w> mniip: i think there is an uncountable number of monotonic computable functions, but only a countable number of haskell functions
09:55 heurist` joined
09:55 <Gurkenglas> Which part? My strictness definition or the reasoning that followed?
09:55 juanpaucar joined
09:55 <Gurkenglas> If the second one, wanna bet?
09:55 <Gurkenglas> ertes-w, there are countably many computable functions, for there are countably many turing machines
09:56 <pgiarrusso> Gurkenglas: I meant the second one — non strict functions can be partially strict
09:56 <mniip> ertes-w, but
09:56 <mniip> turing machines are countable
09:56 <pgiarrusso> Gurkenglas: the lambda-calculus - Turing machines isomorphism breaks down at higher orders, so I'm not sure that claim follows
09:56 <ertes-w> oh, right
09:56 <Gurkenglas> pgiarrusso, _|_ <= x for all x. Therefore f x >= f _|_ > _|_ for all monotonic f
09:57 ccomb joined
09:57 wroathe joined
09:57 Natch joined
09:57 primal joined
09:57 Boomerang joined
09:57 <pgiarrusso> Gurkenglas: f _|_ > _|_ does not follow from f is nonstrict — that's more like "f is const (f _|_)"
09:58 <Gurkenglas> (given, as we said, that f is not strict in the "_|_ maps to _|_" way I mentioned)
09:58 eyck joined
09:58 <pgiarrusso> Gurkenglas: Hm... well... you might be right in fact
09:59 <Gurkenglas> "<pgiarrusso> Gurkenglas: I meant the second one" <- therefore you admitted the first one, which was "strict means _|_ maps to _|_"
09:59 <pgiarrusso> ertes-w: I think what's uncountable is unrestricted functions, and monotonicity makes things countable
09:59 juanpauc_ joined
10:00 <Gurkenglas> there are uncountably many monotonic functions
10:01 <pgiarrusso> Gurkenglas: OK sorry, your statement is completely right. And a function like f xs = (0:xs) is both nonstrict and non-constant
10:02 <pgiarrusso> the part that confused me is that "strict functions" might map bottom to bottom but still be partially lazy if they don't examine all their input (example: tail)
10:03 <pgiarrusso> Gurkenglas, regarding countability: what I remember better was that the domain equation D = D -> D is unsolvable by cardinality reasons for an unrestricted function spaces
10:03 <mniip> tail is not strict
10:03 <mniip> not strict in all of the input
10:03 <mniip> only in the topmost spine
10:03 <pgiarrusso> mniip, yes but tail _|_ = _|_
10:03 <Gurkenglas> pgiarrusso, you're thinking of functions that map all nonmaximal values to bottom
10:03 <mniip> 1495188215 [13:03:35] <mniip> only in the topmost spine
10:04 <pgiarrusso> which is why it's at least strict according to Gurkenglas definition, which I think is the standard one
10:04 juanpaucar joined
10:04 <pgiarrusso> IIRC, restricting D -> D fixes the cardinality problems... ah but wait
10:04 <pgiarrusso> you need to restrict D -> D to continuous functions, need you not?
10:04 <pgiarrusso> Gurkenglas: do I recall correctly?
10:05 <pgiarrusso> (it's years since I last looked at domain theory)
10:05 <Gurkenglas> For the uncountability of monotonic functions: Here's an injection of f: N -> N (uncountably many values) into [()] -> [()] (montonic): g 0 = _|_; g n = replicate (f n) () ++ g (n-1)
10:05 takle joined
10:06 <pgiarrusso> g :: Int -> [()] right?
10:06 <pgiarrusso> not [()] -> [()]
10:06 <Gurkenglas> pgiarrusso, I don't follow. (I merely remember seeing the term D -> D somewhere for some D in that context, and what continous means)
10:06 <Gurkenglas> Whoops, lol
10:07 zariuq joined
10:09 juanpauc_ joined
10:09 <Gurkenglas> Okay, that makes it simpler: There are uncountably many permutations of the natural numbers, and each can be seen as a strict monotonic function on the flat naturals.
10:11 <Gurkenglas> mniip, here's a monotonic function that can't be defined in Haskell: f :: [()] -> (); f (repeat ()) = True; f _ = _|_
10:11 <Gurkenglas> mniip, I think the property that exactly describes haskell functions is "continous", which is monotonicity and limits map to limits.
10:11 <pgiarrusso> Gurkenglas, is that function continuous? IIUC not
10:12 <Gurkenglas> pgiarrusso, monotonic doesnt imply continuous
10:12 <pgiarrusso> sure
10:12 <pgiarrusso> that is
10:12 <pgiarrusso> I agree that monotonic does not imply continuous
10:12 <mniip> Gurkenglas, is that function computable
10:12 <mniip> ah yes, I see, this is where the church thesis breaks down
10:12 <Gurkenglas> mniip, no. Haskell happens to be turing complete? :P
10:13 <pgiarrusso> That function is neither continuous nor computable :-)
10:13 <pgiarrusso> also
10:13 juanpaucar joined
10:13 <pgiarrusso> "full abstraction" is about whether all continuous functions can be written in Haskell
10:14 primal_ joined
10:14 <Gurkenglas> I think no function that's not continuous is computable, if matching on a bottom crashes the turing machine.
10:15 <pgiarrusso> and IIRC (and don't trust me too much) already for PCF (a much simpler language) the answer is no — some continuous functions can't be written down in the language
10:15 nighty-- joined
10:15 <pgiarrusso> Gurkenglas: if by "crash" you mean bottom, that sounds right
10:16 augur joined
10:16 <pacak> bottom is not necessarily crash.
10:16 cretiq joined
10:16 Someguy123 joined
10:17 rafaelcgs10 joined
10:17 wroathe joined
10:17 <pacak> > length $ fix (:1)
10:17 <lambdabot> error:
10:17 <lambdabot> • Occurs check: cannot construct the infinite type: a0 ~ [a0]
10:17 <lambdabot> Expected type: [a0] -> [a0]
10:17 bjz joined
10:17 <quchen> 1:
10:17 <fizruk> _sras_: Swagger does not have descriptions for parameters
10:18 xcmw joined
10:18 juanpaucar joined
10:18 primal joined
10:19 <_sras_> fizruk: Is there anyway I can provide description to indivdual keys of a Json request?
10:20 prophile joined
10:20 oisdk joined
10:20 <fizruk> _sras_: yes, those are object schemas and can have descriptions
10:21 <fizruk> _sras_: request and response bodies (and their parts) are of type Schema which has description property
10:22 juanpaucar joined
10:23 <_sras_> fizruk: So I can access the name property of a schema using `(((toSchema (Proxy :: Proxy Config)) ^. properties) ^.at "Name")`. I can see the result of this is a Referenced Schema. But I am not able to access description inside it..
10:24 primal_ joined
10:24 <quchen> Is Richard Eisenberg here?
10:25 <quchen> goldfierere?
10:25 augur joined
10:26 takle joined
10:26 <fizruk> _sras_: schema ^. properties.at "name"._Inline.description
10:27 <fizruk> _sras_: that's assuming that property schema is inlined, not referenced
10:27 <_sras_> fizruk: Yes. Where is this stuff documented?
10:27 <_sras_> fizruk: Yes. It is inlined.
10:27 juanpaucar joined
10:28 <fizruk> _sras_: Referenced is a sum type, for sum types we have prisms to peak into constructors
10:28 <fizruk> _sras_: prisms are conventionally named just like constructors, but with a leading underscore
10:28 <fizruk> _sras_: so Inline constructor becomes _Inline prism
10:29 <tobiasBora> Hello,
10:29 <fizruk> _sras_: there's Lenses and prisms section in the documentation: http://hackage.haskell.org/package/swagger2-2.1.3/docs/Data-Swagger.html#g:3
10:31 <tobiasBora> I'd like to know, is there a library that would allow me to perform formal computation in Haskell ? I'd like to do some matrix computation on matrix that contains exp(i \theta) angles and \sqrt(2) values, and I don't want to approximate them using floating point complex number, I really want that when I do x1 = x2, then it's true if and only if x1 and x2 represents exactly the same number.
10:31 <fizruk> _sras_: it could probably have an extra paragraph on prisms specifically
10:32 juanpauc_ joined
10:32 takle joined
10:32 jaspervdj joined
10:33 takle joined
10:34 cpup joined
10:34 primal joined
10:34 CoderPuppy joined
10:35 abroz joined
10:36 juanpaucar joined
10:37 <_sras_> fizruk: Yes. Thankyou for your help since yesterday...
10:37 <_sras_> :)
10:38 osa1 joined
10:38 osa1 joined
10:39 mohsen_ joined
10:41 juanpauc_ joined
10:44 takle joined
10:44 primal_ joined
10:44 gawen joined
10:44 FreeBirdLjj joined
10:46 juanpaucar joined
10:47 Yuras joined
10:47 oisdk joined
10:47 tomphp joined
10:48 Wuzzy joined
10:49 <merijn> I wish I'd known I should make criterion output JSON for runs that can/are killed :\
10:49 netheranthem joined
10:49 bjz joined
10:50 juanpauc_ joined
10:51 fnurglewitz joined
10:52 osa1 joined
10:52 osa1 joined
10:53 osa1_ joined
10:54 tiny_test joined
10:55 juanpaucar joined
10:55 <merijn> Is there any documentation on how Hackage decides what file to display as readme?
10:56 oisdk joined
10:57 ziocroc joined
10:58 louispan joined
10:58 <fizruk> _sras_: you're welcome :)
10:58 <fizruk> _sras_: as are contributions such as documentation improvements or that NonEmpty instance :)
10:59 cpup joined
10:59 CoderPuppy joined
10:59 wroathe joined
10:59 takle_ joined
10:59 bvad joined
10:59 juanpauc_ joined
11:01 alibabzo joined
11:02 darlan joined
11:04 juanpaucar joined
11:04 tomphp_ joined
11:07 mattyw joined
11:08 Gloomy joined
11:08 juanpauc_ joined
11:11 balor joined
11:11 james9999 joined
11:11 petermw joined
11:12 benl23 joined
11:12 Elhamer__ joined
11:13 juanpaucar joined
11:15 <lyxia> merijn: how about this https://github.com/haskell/hackage-server/blob/d2008bcc9ec887c766497c77e206e62545c64bea/Distribution/Server/Packages/Readme.hs
11:16 ridho joined
11:16 xall joined
11:17 tomphp joined
11:17 Nicmavr joined
11:18 xcmw joined
11:18 juanpauc_ joined
11:19 petermw joined
11:20 wroathe joined
11:20 jutaro joined
11:22 <ertes-w> tobiasBora: number fields are easy enough to encode, if that's all you need
11:22 <ertes-w> tobiasBora: here i'm using a number field to compute the exact fibonacci formula: https://github.com/esoeylemez/snippets/blob/master/FibNF.hs
11:23 juanpaucar joined
11:24 butterthebuddha joined
11:24 <ertes-w> tobiasBora: the reflection stuff is nice-to-have, but if you hard-code the field extension, then all you need is a simple tuple type
11:24 <ertes-w> data NfSqrt2 a = NfSqrt2 !a !a
11:25 abroz joined
11:25 <ertes-w> (NfSqrt2 x y) represents the number x + y * sqrt 2
11:26 <ertes-w> in fact Data.Complex is such a special case, where (x :+ y) represents the number x + y * sqrt (-1)
11:27 mattyw joined
11:27 <ertes-w> > (1 :+ 2) * (3 :+ 4) :: Complex Integer
11:27 <lambdabot> error:
11:27 <lambdabot> • No instance for (RealFloat Integer) arising from a use of ‘*’
11:27 <lambdabot> • In the expression: (1 :+ 2) * (3 :+ 4) :: Complex Integer
11:27 <ertes-w> well, so much for that =)
11:27 juanpaucar joined
11:28 <_sras_> fizruk: Yes. Haven't added it yet....
11:28 <ertes-w> > abs (Complex 1 1)
11:28 <lambdabot> error:
11:28 <lambdabot> Data constructor not in scope: Complex :: Integer -> Integer -> a
11:28 <ertes-w> > abs (1 :+ 1)
11:28 <lambdabot> 1.4142135623730951 :+ 0.0
11:28 <ertes-w> ah, that's why
11:29 Gloomy joined
11:31 paolino_ joined
11:32 juanpaucar joined
11:33 kuribas joined
11:34 yqt joined
11:36 abroz joined
11:36 bennofs joined
11:36 xtreak joined
11:36 juanpaucar joined
11:37 xtreak_ joined
11:38 barua joined
11:39 tiny_test joined
11:40 tiny_test joined
11:41 Gloomy joined
11:41 juanpauc_ joined
11:41 wroathe joined
11:43 osa1 joined
11:43 bennofs joined
11:45 zariuq joined
11:45 Boomerang joined
11:45 Elhamer joined
11:45 tromp joined
11:46 juanpaucar joined
11:46 balor joined
11:46 cretiq joined
11:49 Hafydd joined
11:49 sproingie joined
11:49 pgiarrusso joined
11:50 asm_ joined
11:50 juanpauc_ joined
11:50 freusque joined
11:52 pie_ joined
11:55 juanpaucar joined
11:55 pgiarrusso joined
11:55 kaeluka joined
11:55 <quchen> What’s the module called again that allows reserving space for bytestrings in an executable?
11:56 <quchen> It allows allocating a number of bytes in an executable that can then be filled later, or something along those lines.
11:57 primal joined
11:58 oisdk joined
11:58 sdothum joined
11:59 juanpauc_ joined
11:59 <lyxia> file-embed
12:00 blym joined
12:04 <quchen> lyxia: Spot on, thanks!
12:04 juanpaucar joined
12:05 RayNbow`TU joined
12:08 blym_ joined
12:08 juanpaucar joined
12:11 tiny_test joined
12:11 phaji_ joined
12:13 juanpauc_ joined
12:15 BartAdv joined
12:15 <kuribas> Is there a better way to do "(\l -> if null l then Nothing else Just $ foldl1 max l) $ mapMaybe f l"?
12:16 <merijn> :t mapMaybe
12:16 <lambdabot> (a -> Maybe b) -> [a] -> [b]
12:16 cpup joined
12:16 jao joined
12:16 CoderPuppy joined
12:17 <kuribas> perhaps listToMaybe...
12:17 <kuribas> :t listToMaybe
12:17 <lambdabot> [a] -> Maybe a
12:17 <phadej> kuribas: foldMap with Option and Max from Data.Semigroup
12:17 <kuribas> :t foldMap
12:17 <lambdabot> (Monoid m, Foldable t) => (a -> m) -> t a -> m
12:17 jgt3 joined
12:17 <merijn> kuribas: Yes, monoid-extras Inf
12:18 <phadej> that's another option (I opted for `base` variant :)
12:18 xcmw joined
12:19 Argue_ joined
12:19 louispan joined
12:19 srcerer_ joined
12:19 <phadej> yet it might be less strict, so maybe you still want to foldl'
12:20 <merijn> Does anyone know what kind of markup is allowed in the Description field of a cabal file?
12:21 <ph88> how can i make LiftA3 with <$> and <*> ?
12:21 <phadej> merijn: haddock
12:21 <phadej> ph88: liftA3 f x y z = f <$> x <*> y <*> z
12:22 takle joined
12:22 <ph88> oki ty
12:22 ventonegro joined
12:22 wroathe joined
12:23 <ph88> cocreature, i don't understand how this code deals with the Nothing case (\maybeFirst maybeLast num -> liftA2 (\first last -> (first - last) / fromIntegral num) maybeFirst maybeLast)
12:23 takle joined
12:25 <cocreature> ph88: it will give you back a Maybe Double that is Nothing if first or last are not present. the inner liftA2 uses the Applicative instance of Maybe
12:25 comiccobe joined
12:26 <ph88> how does the applicative instance of Maybe work ?
12:27 <cocreature> it shortcircuits on Nothing
12:27 <cocreature> Nothing <$> Just True
12:27 <cocreature> > Nothing <*> Just True
12:27 <lambdabot> Nothing
12:27 eacameron joined
12:27 <cocreature> > Just (+1) <*> Nothing
12:27 <lambdabot> Nothing
12:27 <cocreature> > Just (+1) <*> Just 41
12:27 <lambdabot> Just 42
12:27 <ph88> but now you liftA2 with a function that takes 2 arguments
12:27 <ph88> ok lemme try
12:28 <cocreature> > liftA2 (+) Nothing (Just 1)
12:28 <ph88> > Just (+) <$> Just 1 <*> Just 2
12:28 <lambdabot> Nothing
12:28 flatmap13 joined
12:28 <lambdabot> error:
12:28 <lambdabot> • Couldn't match expected type ‘Integer -> Integer -> b’
12:28 <lambdabot> with actual type ‘Maybe (Integer -> Integer -> Integer)’
12:28 xanadu joined
12:28 <cocreature> ph88: remove the first Just
12:28 <ph88> > (+) <$> Just 1 <*> Just 2
12:28 <lambdabot> Just 3
12:28 <ph88> > (+) <$> Just 1 <*> Nothing
12:28 <lambdabot> Nothing
12:29 <ventonegro> > Just (+) <*> Just 1 <*> Just 2
12:29 <lambdabot> Just 3
12:29 <ventonegro> > Just (+) <*> Nothing <*> Just 2
12:30 <lambdabot> Nothing
12:30 <ph88> this avoid having to do a case pretty nice
12:30 <cocreature> ph88: that’s exactly what it is for :)
12:30 <ph88> but why do you have to do liftA3 and liftA2 here and you can not do it in 1 lift ?
12:31 <ph88> oh wait i think i know
12:31 <ph88> the A2 is for the maybe- context ?
12:31 <cocreature> ph88: the liftA3 is for the applicative instance of Fold. the liftA2 is for the applicative instance of Maybe
12:31 <ph88> ok
12:31 sellout- joined
12:32 <phadej> i'm confused, "liftA3 is for the applicative instance of Fold" ?
12:33 <ph88> https://hackage.haskell.org/package/foldl-1.2.5/docs/Control-Foldl.html
12:33 <cocreature> I should have said Fold Double
12:34 <cocreature> phadej: I was referring to the use of liftA3 in an example I had shown ph88 earlier
12:34 <phadej> ah
12:35 runforestrun joined
12:35 juanpaucar joined
12:36 ziocroc joined
12:36 danthemyth joined
12:37 runforestrun joined
12:37 jakub joined
12:37 takle joined
12:37 <ph88> cocreature, i can not find Data.Conduit.Extra.Foldl in the lastest version of conduit / conduit-extra
12:39 <jakub> Hi, I have: data X = A | B and data Y (x :: X) = Y and I want to write a function f :: forall x. Y x -> String such that f (y :: Y A) = "ya" and f (y :: Y B) = "yb" how would I go about it?
12:39 <ph88> i can also not find sinkFold on hoogle
12:40 earthy joined
12:41 <ph88> jakub, maybe use Proxy .. seems you don't make a distinction on the value level only on the type level
12:41 <jakub> ph88: what does proxy offer that Y itself does not?
12:42 kritzcreek joined
12:42 <ph88> jakub, the ability to match on a dummy value depending on the type
12:43 wroathe joined
12:43 <ph88> data Proxy (Y A) = Proxy let ya = Proxy (Y :: Y A) f (Proxy :: Y A) = "ya"
12:43 <jakub> ph88 but that I can do with Y, I asked because Y looks almost as synonym to Proxy to me
12:44 <ph88> i don't know enough about this stuff, have to step out for a moment anyway
12:44 <jakub> I could do: f (Y :: Y A) = "ya"
12:45 <merijn> cabal's description field doesn't allow heading/bold markup?
12:45 <jakub> but can I really write: let f :: forall x. Y x -> String; f (Y :: Y A) = "ya"; f (Y :: Y B) = "yb" ???
12:45 <merijn> That's annoying...
12:45 xcmw joined
12:46 <pgiarrusso> jakub, what language extension is that?
12:46 sproingie joined
12:46 sproingie joined
12:47 <mutsig_> I'm currently discovering Pipes. I have a case where I need to parse a large file, and the program will die when an error occurs somwhere during parsing. However, I will need the entire result loaded into memory if the parsing is succesfull in order to act on it in multiple ways. Is `toListM` suitable for this, or am I misunderstanding pipes in some regard, since toListM is said to not be an idiomatic
12:47 <mutsig_> use of pipes?
12:47 <jakub> pgiarrusso: I am trying to figure that out
12:47 abroz joined
12:47 <pgiarrusso> jakub, oh, seems DataKinds
12:47 <jakub> pgiarrusso: currently I have DataKinds KindSignatures
12:47 <pgiarrusso> yeah
12:47 <jakub> and ScopedTypeVariables
12:47 <merijn> mutsig_: Well, if you need to load the entire thing into memory, why bother using pipes?
12:47 <jakub> but the definition of "f" is not admissible under those
12:48 <jakub> I cannot case-split on the type
12:48 <kosmikus> jakub: proxy is not enough. you need a singleton type for kind X.
12:48 <lambdamu_> Can the Handle type from base be converted to a Ptr type suitable to be passed as FILE* argument via FFI?
12:49 wroathe joined
12:49 <jakub> kosmikus: I was afraid that was the case, however I really do not understand singletons, could you walk me through it, pretty please :)
12:49 <pgiarrusso> agree with kosmikus — either that or using Tapeable
12:49 <kosmikus> jakub: no time right now, sorry. in short: data SX :: X -> * where SA :: SX A; SB :: SX B
12:49 <jakub> kosmikus: thank you :)
12:50 <kosmikus> jakub: then have your function f take an SX value to do the distinction
12:50 <kosmikus> jakub: I'm sure you'll find someone else around here to give you a more detailed explanation
12:50 <jakub> kosmikus: the only problem is that I would have to know the type to know which of the constructors to invoke
12:50 <pgiarrusso> jakub: singleton means that for each x :: X, SX x has a *single* value (SA or SB), so that by matching on a value of SX x you encode a match on X
12:50 <kosmikus> jakub: you can also combine singletons with type classes
12:51 <pgiarrusso> jakub: the point is that case splitting on a type variable MUST be forbidden to preserve parametricity
12:51 <jakub> pgiarrusso: thanks, I was always confused with "singleton = one inhabitant... proceeds to define multiple constructors... ¯\_(ツ)_/¯"
12:52 <pgiarrusso> jakub: yes, hope I clarified that
12:52 <mutsig_> merijn: Because it makes sense to first parse the file and "being able to interact with IO" along the way.
12:52 <pgiarrusso> so, find the closest caller which *still* knows the concrete X, and pick the right value for SX there
12:52 <mutsig_> merijn: And also, i want to learn pipes
12:53 <merijn> mutsig_: Wouldn't it be easier to just load the entire file into memory and parse it in one go?
12:53 <sproingie> lambdamu_: i imagine the internal representation of Handles are platform-specific, so you'd probably have to see how the Handle is made and pull it apart appropriately
12:53 <sproingie> lambdamu_: i dunno about FILE*, but at least on unix, there'd be at least an integer fd you could fdopen
12:53 <pgiarrusso> jakub, you can also encode that via type classes I think (not sure the details), but the type class mechanism would just help doing a similar transformation
12:53 <jakub> pgiarrusso: so my data Y cannot be used to define f right? I would need to modify Y to be parametrised with the singleton instead
12:53 mtg joined
12:54 <pgiarrusso> jakub: yes, or just replace Y with the singleton
12:54 [[[[[ExTRa]]]]] joined
12:54 <jakub> pgiarrusso: actually you are right, parametrizing Y with singleton wouldnt solve anything
12:55 <mutsig_> merijn: Perhaps, but I thought that using pipes might be cleaner - but since I dont' know pipes yet, I might be wrong
12:55 <pgiarrusso> jakub: I was confused that f (Y :: Y A) = "ya" works, but that's not doing a pattern match, it just creates an f :: Y 'A -> String
12:55 fotonzade joined
12:55 <pgiarrusso> rather than f :: Y x -> String
12:55 cdepillabout joined
12:55 <jakub> pgiarrusso: yeah, exactly, that was why I did not believe it could work
12:55 <jakub> kosmikus, pgiarrusso: thanks a lot!
12:55 <merijn> mutsig_: Pipes is really designed for doing constant space streaming processing. So what you propose is possible, it's just the exact opposite of what it was designed for :)
12:55 Cerise joined
12:56 <mutsig_> merijn: Ok :)
12:57 <lambdamu_> sproingie: I just saw the unix package can convert between file descriptor and Handle, that should be enough
12:57 <merijn> lambdamu_: Word of warning: converting a Handle to a file descriptor *closes* the handle
12:58 <sproingie> but you'd still have an open fd, right?
12:58 <merijn> Yes
12:58 <ph88> jakub, maybe if you also cover the case of Y _
12:58 <merijn> You just gotta be careful that for example "handleToFd stdout" will *close* stdout and break lots of things :p
12:58 <mutsig_> merijn: I allways feel like parsing is most often used in combination with IO, for me at least, since most errors should kill the process with an error message. Isn't pipes the best way to accomplish this combination of a "list-like-result" and IO?
12:58 <sproingie> there ya go. don't even need a pointer then, it's just a plain old int
12:59 <merijn> mutsig_: Depends on the kind of parsing
12:59 <jakub> pgiarrusso: ok so I oversimplified my original problem :)... I actually have data X = A | B X X, I have no idea what the singleton would look like for that
12:59 <merijn> mutsig_: for, e.g., source code I try to parse as much as possible to report as many errors are I can in one go
13:00 <ph88> mutsig_, i'm also processing a large file but i use conduit, i use fromList to put it into a vector
13:00 <lambdamu_> merijn: good to know, thanks
13:00 <pgiarrusso> jakub, instead of data SX :: X -> * where SA :: SX A; SB :: SX B, you want data SX :: X -> * where SA :: SX A; SB :: SX x1 -> SX x2 -> SX (B x1 x2) I think
13:01 juanpauc_ joined
13:02 <ph88> mutsig_, i think conduit helps to make things more explicit, but you can also do lazy read without conduit
13:02 <mutsig_> merijn, ph88: Ok, I think I'll try out pipes for now, to see where it leads. This area is where I'm the least comfortable in haskell - lazily produce listlike parse-results and error out otherwise...
13:02 juanpaucar joined
13:03 primal_ joined
13:03 <sproingie> you could always slurp up the file to a list with a helper then produce from the list and not the file
13:03 <ph88> mutsig_, that error out otherwise was not trivial to me in conduit
13:03 <mutsig_> ph88: So you recommend it? Haven't used that one either. Can you compare it to pipes?
13:04 <mutsig_> ph88: ah *not* trivial :) Missed that one
13:04 <pgiarrusso> jakub: to confirm that's a singleton, you can try proving (pen-and-paper) that a function like inverseSingletonMap is injective let inverseSingletonMap :: SX x -> X ; inverseSingletonMap SA = A ; inverseSingletonMap (SB x1 x2) = B (f x1) (f x2)
13:04 <ph88> mutsig_, i haven't used pipes but it seems easier to use, snoyberg wrote a blog post about the tradeoffs between the two
13:05 <ph88> mutsig_, i just mention it since for me it was not easy to do, so maybe you will have the same problem with pipes
13:05 obadz joined
13:05 ericsagnes joined
13:06 <ph88> does anyone know what is the new version for this? https://hackage.haskell.org/package/conduit-extra-0.1.6/docs/Data-Conduit-Extra-Foldl.html
13:07 tsmish joined
13:07 abroz joined
13:07 <mutsig_> ph88: Ok, thanks. This is quite a wonky area for haskell, isn't it? I mean, bytestrings - strings - text - lazy text... Parsec, attoparsec, condouit, pipes. Would be really nice with some kind of consensus on how parsing generally should be used.
13:07 jwbuurlage joined
13:08 primal joined
13:08 exarkun joined
13:08 Boomerang joined
13:08 <sproingie> there's no real consensus in other languages either wrt parsing
13:08 fizruk joined
13:08 <ph88> mutsig_, you will find the same in C with bison, yacc, lex, lemon and so on (about parsers)
13:09 <ph88> mutsig_, about conduit and pipes .. they try to offer abstractions that other languages don't even have.
13:09 <sproingie> to say nothing of packrat parser generators now
13:09 stevenxl joined
13:10 <ph88> mutsig_, about data types you can stay on String most of the time .. but other types are better for performance
13:10 stevenxl joined
13:10 stevenxl joined
13:10 ADG_ joined
13:10 <mutsig_> ph88: Yeah, I dont mean that the solutions aren't good, and often superior to possible tools in other languages. And perhaps it's just that i'm not used to parsing yet. Just feels that there's so many holes one could drop down to.
13:10 <ADG_> why does "fmap chr . xor `on` ord" work but "map chr . xor `on` ord" not?
13:10 wroathe joined
13:10 <ph88> mutsig_, there is also an interesting post on how to handcraft parsers in haskell that outperform attoparsec even
13:10 Yuras joined
13:11 <jakub> pgiarrusso: thanks a lot really, I will try doing exactly that, do you happen to know about a good reference for all of this? is this covered in some document about dependent types? is there a good source that starts from the foundations and builds up to singletons and such?
13:11 <sproingie> the proliferation of string types ... well, [Char] was never a very efficient thing
13:11 <cocreature> ph88: I think you may just need to copy the source of those functions. it looks like there is no builtin way to use conduit with the foldl library (I use pipes myself and it integrates quite well with that). luckily it’s a one liner
13:11 <mutsig_> sproingie: exactly
13:11 <ph88> mutsig_, i tried re2c/lemon in C and this was also a big hole to drop down to .. even though the quality of those libraries suppose to be excellent .. it's just me i figure
13:12 <mutsig_> ph88: Yeah, well I guess I just have to find the right solution. But as i mentioned, this is a bit of a grey area as of now for me...
13:13 <ph88> cocreature, where is that extract coming from? i don't see it in the imports
13:13 <bartavelle> ph88: it is not hard to outperform attoparsec if you drop features, but then you get a very bare-bones parser
13:13 primal joined
13:13 <cocreature> ph88: it’s bound by the pattern match
13:13 <sproingie> ph88: the fact that the C solutions require a separately parsed language that generate impenetrable code ... bleh
13:13 <ertes-w> mutsig_: in principle consensus could be reached in some areas, but you have the NIH effect
13:13 <ph88> mutsig_, i find those libraries are mainly polished on the theoritical/performance side and not so much on the practical/features side
13:13 <sproingie> i'm always glad to have a language expressive enough to write a proper EDSL in
13:13 <sproingie> (or "with")
13:14 <ertes-w> mutsig_: i found myself reinventing libraries that already existed for minor reasons
13:14 <ph88> cocreature, oops ye :/
13:14 <ertes-w> mutsig_: and in one instance i even reinvented a library without knowing
13:14 <sproingie> i accidentally a parser
13:14 <ph88> sproingie, i did like it that lemon was able to exploit some particular gcc feature to get even more performance out of it :P
13:14 Levex joined
13:15 <mutsig_> ertes-w: Yeah, it's like a double edged sword in haskell. You have the tools to come up with good solutions, but when you do, you realise it already exist - but you didn't know before inventing it.
13:15 <ph88> i still believe that if you want max performance it's easier to do in C than haskell
13:15 <ph88> ertes-w, what did you reinvent? circular buffers? :P
13:15 <sproingie> depends. parallel performance in C is difficult.
13:16 <bartavelle> ph88: if you care about how fast your program can grant RCE, yeah ;)
13:16 <juanpaucar> use MPI o openMP for C
13:16 <juanpaucar> it's a breeze
13:16 <ph88> bartavelle, what's RCE ?
13:16 <sproingie> ph88: lemon is pretty decent, sure beats bison. i just don't like external parser generators. errors in the grammar tend to be baffling.
13:16 <bartavelle> ph88: remote code execution
13:16 <sproingie> juanpaucar: for problems that are easily expressed with message passing, sure
13:17 <bartavelle> ph88: but yeah, if you are very biased towards performance, haskell isn't a great choice
13:17 <pgiarrusso> jakub, I don't know good sources for this... I learned it from papers (and lots of practice with Agda)
13:17 spacecadetbrown joined
13:18 <jakub> pgiarrusso: I dont
13:18 abroz joined
13:18 <jakub> pgiarrusso: I dont want to bother you
13:18 <pgiarrusso> jakub: maybe the papers cited in https://hackage.haskell.org/package/singletons, or their references? If you're into papers
13:18 <bartavelle> ph88: however I found out that I could write very fast parsers in haskell (that would beat some C ones), whereas they are just horrible to write in C for like 20% speed gain ...
13:18 primal joined
13:18 <juanpaucar> sproingie: Yup.. but if it's forced to use C to max performance in parallelism, then at least make sure that there's a framework to help with that
13:18 <jakub> pgiarrusso: I actually like papers
13:18 iomonad joined
13:18 <ph88> sproingie, in C it's no good to do without parser generators
13:18 <jakub> pgiarrusso: especially FP / Cat / TT ones
13:19 <sproingie> ph88: oh yah i've ripped out a lot of C code in my time that was parsing by hand with strtok (or reinventing strtok)
13:19 <ph88> ya parsers are nice :D
13:19 <ph88> sproingie, i did the same in PHP ..
13:19 <jakub> pgiarrusso: not that I understood many, (functional pearl: data types ala carte, programming with bananas, ...)
13:19 <ph88> parsers everywhere
13:20 aweinstock joined
13:20 <shapr> mmm, parsers
13:20 <sproingie> i ended up replacing it with Spirit from boost. awful hacky syntax, but worked like a dream
13:20 <sproingie> replaced about 500 LOC with five
13:20 ErinvanderVeen joined
13:21 <sproingie> then decided it was insane for C++ to be doing any parsing and preprocessed everything to xml instead. yeah xml, it was a stupid time.
13:22 Elhamer joined
13:23 <ertes-w> ph88: heh, no… i reinvented clay, the DSL for CSS
13:24 <ertes-w> ph88: and since you didn't ask further, i assumed that you no longer needed… ok, ok… i forgot =)
13:24 earldouglas joined
13:24 <shapr> Hi Earl
13:24 hydraz joined
13:26 rcat joined
13:26 bennofs joined
13:26 primal_ joined
13:27 runforestrun joined
13:27 <mpickering> Say I have, data T = T { field = (forall a . [a]) } then is there a way to use lenses with fields like this?
13:27 sfcg joined
13:28 <mpickering> It seems that makeLenses derives a getter
13:28 abroz joined
13:28 <mpickering> I want to also allow modifications which change the order of the list
13:28 <tobiasBora> ertes-w: Well, I also need to be able to test equalities, and since I've sqrt, complex exponential... I need to code it very carefully to have only one possible "normal form".
13:28 eSVG joined
13:29 alfredo joined
13:30 <tobiasBora> I think it's possible to handle it manually, but I hoped that it would be possible to use something that already exists
13:30 marvin3 joined
13:30 Noldorin joined
13:31 carlomagno joined
13:31 ChaiTRex joined
13:31 wroathe joined
13:31 foo_ joined
13:31 fkurkowski joined
13:32 nuub joined
13:32 <ph88> ertes-w, i don't need it anymore, but i have a feeling that it will be a super useful general concept for a lot of projects !
13:32 <phadej> mpickering: good question. i'm not sure you can have anything lawful
13:33 <mpickering> I can get around it but something I hadn't thought about
13:34 <phadej> maybe if you have a Setter setting the "permutation"
13:34 <phadej> but you cannot extract it, obviously
13:34 jathan joined
13:34 oish joined
13:35 primal joined
13:35 ccomb joined
13:39 <mpickering> I can defined "(forall a . [a] -> [a]) -> T -> T" but not "Functor f => (forall a . [a] -> f [a]) -> T -> f T"
13:40 primal joined
13:41 Mon_Ouie joined
13:41 ystael joined
13:41 <foo_> Hello, am wondering about a concept in Haskell (not really a Haskell-programmer here). Just 3 creates a value of type Maybe a where a is a Num, and Nothing creates a value of type Maybe a; is it possible to create a value of e.g. type Maybe Int via the data constructor Nothing?
13:41 iAmerikan joined
13:42 <merijn> foo_: Sure, "Maybe a" means it's type "Maybe a" for all possible types 'a'
13:42 <merijn> :t Nothing :: Maybe Int
13:42 <lambdabot> Maybe Int
13:42 <merijn> :t Nothing :: Maybe Bool
13:42 <lambdabot> Maybe Bool
13:42 ozgura joined
13:43 <geekosaur> (Nothing :: Maybe Int) -- type ascription
13:43 <phadej> mpickering: exactly, the first one is what you need to define 'Setter', latter is the Lens (which AFAICS you cannot have)
13:43 locallycompact joined
13:43 quobo joined
13:44 <mpickering> But I can also get the value out.
13:44 <phadej> hmm, sorry, i completely missunderstood
13:44 <foo_> merijn: So one can create a Maybe with a concrete type via Nothing. Is the type parameter a a phantom type in Nothing or is that something different?
13:45 <phadej> I think you can write something which looks like Lens' T [Natural]
13:45 <merijn> foo_: Personally I dislike the term "concrete type" since no one can ever agree what it means
13:45 <phadej> mpickering: but the laws won't hold for get and set interactions
13:45 primal_ joined
13:45 <merijn> foo_: Do you know what unification means?
13:45 <mnoonan> All of the ghc download pages at haskell.org (e.g. https://www.haskell.org/ghc/download_ghc_8_0_2) give an internal server error (500). does anybody know what is up?
13:45 <mpickering> if the laws don't hold then it's pointless
13:45 <merijn> mnoonan: URL got changed, Google hasn't noticed
13:46 xcmw joined
13:46 <phadej> mpickering: yet forall a. [a] ~ Natural
13:46 <merijn> mnoonan: Goto /download.html instead of /download
13:46 <merijn> mnoonan: i.e. https://www.haskell.org/ghc/download.html
13:46 <foo_> merijn: Yes. Let's say a less-generic type then instead of concrete. :)
13:46 ChristopherBurg joined
13:46 cloudhead joined
13:46 <mpickering> I don't actually have [a], I have [ALens (a, a) a]
13:46 cpennington joined
13:47 <phadej> well, that have more information in it!
13:47 danza joined
13:47 <phadej> isn't ALens (a, a) a ~ Bool ?
13:47 <merijn> foo_: Basically if you GHC infers "Nothing :: Maybe a" and you say "Maybe Int", GHC then tries to "unify" those types (basically it computes a bunch of equations, in this case simply "a = Int" and sees if there's a contradiction
13:47 <mpickering> So instead it's isomorphic to [Bool] but less convenient to have that
13:48 <phadej> it is :)
13:48 <merijn> foo_: If the equations between type variables don't conflict, then GHC is happy since there is a legal solution
13:48 abroz joined
13:48 <phadej> but can't you have Lens' T [Bool] then?
13:48 `^_^v joined
13:48 <merijn> If you have "Just True :: Maybe Bool" and try to write "Just True :: Maybe Int" then GHC starts unifying, reaches "Int = Bool" and goes "nuhuh"
13:48 <nuub> Hello. What is the maximum size of Integer in practice? Amount of memory?
13:49 <mpickering> That sounds quite indirect to write
13:49 <mpickering> I can work around it easily
13:49 <merijn> nuub: basically, yes
13:49 <byorgey> foo_: I would not call the type parameter a phantom type. A phantom type parameter is one that is not used in *any* of the constructors.
13:49 <mpickering> but I want to know why GHC rejects the obvious version
13:50 <phadej> mpickering: because you'd need to have exists a. Lens' T [a]
13:50 <foo_> merijn: I see, thanks.
13:51 sfcg joined
13:52 <foo_> byorgey: I assume the compiler will always try to infer the most general unifier/type for such parameters if not given?
13:52 <mnoonan> merijn: ah, thanks!
13:52 <phadej> mpickering: I run into similar situations, where needed to have a lens to extract an existential type-variable; but I aborted that, I most likely missed somehing, but didn't get types to align
13:53 abroz joined
13:53 <foo_> byorgey: e.g. Data Foo a = Bar | Baz will always construct a Foo a (for all a).
13:53 yellowj joined
13:54 dm3 joined
13:55 primal joined
13:57 saussure joined
13:59 meba joined
13:59 takle joined
14:00 primal joined
14:01 takle_ joined
14:01 inad922 joined
14:02 <ClaudiusMaximus> nuub: i think libgmp's maximum integer is 2^((2^31-1)*64)-1 (mpz_t stores a 32bit signed count of 64bit limbs); however i think ghc's integer-gmp uses lower-level functions that might have even higher limits. in practice, available memory is the limiting factor
14:04 mmachenry joined
14:04 takle joined
14:05 <nuub> Thanks ClaudiusMaximus
14:06 <cocreature> can I link to things in packages that I don’t depend on in haddock?
14:06 geekg_000 joined
14:06 <cocreature> and to those packages themselves
14:06 <sproingie> every time i run stack, i have to "stty sane" to unscrew my terminal
14:06 <sproingie> among other things, ^D stops working
14:06 aarvar joined
14:06 dsh joined
14:06 jgt3 joined
14:07 ystael joined
14:07 <lyxia> cocreature: you can
14:07 foo_ left
14:08 <lyxia> or do you mean something other than just putting an url there
14:08 sfcg joined
14:08 <quchen> sproingie: Woah cool command!
14:08 <quchen> I usually close and reopen the terminal
14:08 <cocreature> lyxia: I was more hoping for something like '' but which allows me to specify the package
14:09 <sproingie> i think i might still have stty-insane.com
14:10 jcjustjc joined
14:10 eacameron joined
14:10 primal joined
14:13 <quchen> cocreature: I don’t thin you can do better than using fully qualified names
14:13 <sproingie> looks like stack isn't resetting icanon
14:13 <cocreature> quchen: url links it is then
14:14 <sproingie> stack or possibly ghc's IO system itself, but i always invoke via stack so dunno which
14:15 <sproingie> being that a failed stack build triggers it, ima blame stack
14:15 marvin2 joined
14:16 primal_ joined
14:17 <merijn> hmm
14:17 Punisher joined
14:17 <ph88> cocreature, i have this now https://bpaste.net/show/55a9f42029e7 i don't know what to do with that (Maybe Double) i already do runConduit on it .. but now i get a type error (basically it was expecting () )
14:17 oisdk joined
14:18 eschnett joined
14:18 jacereda joined
14:18 bvad joined
14:21 <cocreature> ph88: you need to give it a source of doubles
14:22 <ph88> i have a source blabla <- runStream $ src .| (readValue tcol) .| getAverageSampleInterval
14:22 <ph88> readValue :: MonadIO m => Int -> Conduit BSC.ByteString m Value where Value stands in for Double
14:22 takle joined
14:23 cschneid_ joined
14:23 <cocreature> connect your source to the sink and then call runConduit
14:24 eacameron joined
14:24 HarveyPwca joined
14:26 sternmull joined
14:26 primal joined
14:27 mmachenry joined
14:29 jgt3 joined
14:29 lknows joined
14:30 wroathe joined
14:33 jcjustjc joined
14:33 jedws joined
14:33 ertes joined
14:35 freusque joined
14:36 crobbins joined
14:36 tsmish joined
14:37 primal_ joined
14:37 flatmap13 joined
14:38 phaji joined
14:38 thimoteus joined
14:40 thimoteus left
14:42 Kreest_ joined
14:42 <mpickering> It seems that variables bound in do notation are subject to some kind of monomorphism restriction?
14:42 <quchen> ..?
14:42 <quchen> mpickering: … continue
14:43 <quchen> I don’t know of any DMR in do-notation
14:43 <glguy> the variables will have a monomorphic type
14:43 <merijn> mpickering: let variables?
14:43 <mpickering> no, not let variables
14:44 <quchen> Doesn’t the DMR apply only at the top level?
14:45 <merijn> Suppose I have a type Foo, what's a good naming scheme for various folds?
14:45 uglyfigurine joined
14:45 <merijn> foldMFoo, mapMFoo, etc.?
14:45 Iceland_jack joined
14:45 <merijn> The capital M feels awakward combined with the Foo
14:46 <merijn> Especially if you want a mapM_ variant, then you have to pick between "mapM_Foo" or "mapMFoo_" both are awkward
14:46 <quchen> > [ "fold" <> replicate n '\'' | n <- [0..] ]
14:46 <lambdabot> ["fold","fold'","fold''","fold'''","fold''''","fold'''''","fold''''''","fold...
14:46 <quchen> mapM, boo! traverseFoo
14:46 <quchen> traverseFoo_
14:46 <mpickering> Define a Traversal for it and then use the lens combinators
14:46 <merijn> Alternatively, I suppose I could make a special module so people can import that qualified and then simply shadow Prelude
14:46 alfredo joined
14:46 <merijn> mpickering: You can't define a Traversal for it
14:47 pavonia joined
14:47 xcmw joined
14:47 <merijn> If I could I'd just make a Foldable/Traversable instance and use the names from Prelude
14:47 <quchen> I think aliasing Prelude is a good idea.
14:47 <glguy> no, the MR is not restricted to top level, also in where
14:47 <mpickering> Not a Traversable instance, a Traversal
14:47 takle joined
14:48 <quchen> glguy: Oh, is that the key difference between where and let?
14:48 <merijn> mpickering: I know Traversal is not Traversable, but it's still not possible
14:48 <merijn> mpickering: Same way you can't make a Traversal for MVar
14:48 <merijn> Additionally, I'm not gonna add a lens dependency
14:49 <glguy> no should be in let, too
14:50 <ph88> cocreature, i thought was the sink because i put sinkFold in there
14:51 zariuq joined
14:51 Gurkenglas joined
14:51 <cocreature> ph88: what’s the type of "src .| readValue tcol .| getVerageSampleInterval"?
14:51 takle joined
14:52 harryblack joined
14:52 <ph88> cocreature, ConduitM BSC.ByteString a (StateT AdjustSampleState (ResourceT IO)) (Maybe Double)
14:53 <merijn> I guess I'll just steal Tekmo's "Pipes.Prelude" idea and add Foo.Prelude that shadows the ideal names from Prelude :)
14:53 ixxie joined
14:53 coltfred joined
14:53 <ph88> runStream pipe = runResourceT $ runStateT (sourceToList pipe) startAdjustSampleState
14:53 rcschm joined
14:54 primal joined
14:56 phaji joined
14:57 <merijn> Anyone know of a JSON pretty printer?
14:57 <cocreature> merijn: aeson-pretty
14:57 <Clint> merijn: like aeson-pretty?
14:58 <ph88> be back later
14:58 <merijn> I meant more like standalone tool for debugging
14:58 <cocreature> merijn: aeson-pretty
14:58 <Clint> aeson-pretty
14:59 <merijn> oh, it has an executable too, neat
14:59 primal_ joined
14:59 jgt3 joined
14:59 <Clint> you can also do it with jq and stuff
14:59 <Geekingfrog> merijn for json debugging jq is pretty neat as well (it's an executable only though)
14:59 takle joined
14:59 <clamchowder> Hello
15:00 <merijn> Unrelatedly: pasting several MB of json into an online form for formatting is a good way to kick AppleSpell into 100% CPU load
15:00 <clamchowder> A simple question: what is the use of ()?
15:00 <clamchowder> For example, in Control.Monad, there is a function called guard
15:00 <merijn> hmmm
15:01 <merijn> This might be too pretty for me...
15:01 <byorgey> clamchowder: () is the "unit type", which has only a single value (also called () )
15:01 <merijn> 95k line json file
15:01 Sonderblade joined
15:01 <clamchowder> guard :: Alternative f => Bool -> f ()
15:01 <clamchowder> guard True = pure ()
15:01 <clamchowder> guard False = empty
15:01 <merijn> Thanks...I guess...
15:01 <byorgey> clamchowder: so if you have a value of type () you have no information at all. It's similar-ish to 'void' in Java or C
15:02 Rodenbach joined
15:02 <byorgey> clamchowder: intuitively, something of type f () is like a "computation with no output"
15:03 <byorgey> that is, it outputs a value of type (), but since there is only one, that tells you nothing, so it might as well have no output at all
15:03 takle joined
15:03 <clamchowder> byorgey: OK thanks.
15:04 xall joined
15:04 fizruk joined
15:04 <clamchowder> byorgey: but what does guard do with pure () output?
15:04 theelous3 joined
15:05 <Iceland_jack> clamchowder: Succeeds
15:05 takle joined
15:05 <byorgey> clamchowder: pure () is a computation which has no effects and returns ().
15:05 <byorgey> clamchowder: guard produces either a computation which "does nothing and succeeds" (pure ()) or a computation that "fails" (empty)
15:05 <byorgey> what that specifically means depends on f, but that is the general idea
15:06 <byorgey> > guard (3 > 2) *> Just 6
15:06 <lambdabot> Just 6
15:06 <byorgey> > guard (3 > 6) *> Just 6
15:06 <lambdabot> Nothing
15:06 <Iceland_jack> > Just () *> Just 6
15:06 <lambdabot> Just 6
15:06 <Iceland_jack> > Nothing *> Just 6
15:06 <lambdabot> Nothing
15:06 primal joined
15:07 <clamchowder> byorgey, Iceland_jack: thanks.
15:09 <quchen> Black magic question incoming. Suppose I have a module that exports a type, but not its constructors. How can I access them anyway?
15:09 <glguy> quchen: th
15:09 <quchen> In other words, I’d like to inspect opaque data types in the least awful way.
15:09 <quchen> glguy: TH?
15:09 <quchen> How so?
15:09 takle joined
15:10 <byorgey> quchen: I seem to recall someone publishing a package to do exactly this.
15:10 <clamchowder> Hackage says (*>) disgard the value of the first argument, then how come Nothing *> Just 6 produces Nothing?
15:10 <quchen> So do I, but that’s all I remember.
15:10 <quchen> I tried unsafeCoercing to an identical type once but couldn’t make it work.
15:10 <quchen> I ventured deep into segfault land before giving up.
15:10 <Iceland_jack> clamchowder: It disgards the () value
15:10 <byorgey> clamchowder: it disregards the *output* value. It does not disregard the effects.
15:11 <Iceland_jack> > Just undefined *> Just 42
15:11 <lambdabot> Just 42
15:11 <byorgey> clamchowder: in this case the "effect" is that Nothing means the computation has failed
15:11 <clamchowder> :t undefined
15:11 <bartavelle> quchen: I suppose it doesn't implement stuff like Generic or ToJSON ?
15:11 <lambdabot> a
15:11 <lyxia> quchen: is it an instance of Generic or Data
15:11 <byorgey> clamchowder: have you read about Applicative?
15:11 primal_ joined
15:12 <quchen> bartavelle, lyxia: Nothing of the sort, no. I’m asking generally, but my solution should work first and foremost for the Doc type of ansi-wl-pprint.
15:12 <clamchowder> byorgey: not much. It seems less useful to me than functor, monoid or monad
15:12 wroathe joined
15:12 <byorgey> clamchowder: well, you are going to have a hard time understanding things like guard then =)
15:13 <byorgey> clamchowder: also, it is incredibly useful.
15:13 <byorgey> if it seems less useful to you, it's probably just because you don't understand it.
15:13 <glguy> quchen: template hask, reify
15:13 abroz joined
15:13 cschneid_ joined
15:14 <clamchowder> byorgey: Yeah I don't understand it
15:14 <clamchowder> byorgey: I saw the definition, but can't think of any natural examples
15:14 NeozbiljnOzbilja joined
15:14 <byorgey> clamchowder: there are tons of natural examples. For starters, every Monad is also Applicative.
15:15 <quchen> main = putStrLn "hello" *> putStrLn "world"
15:15 <Iceland_jack> clamchowder: Here is an unnatural example, wanting to add the numbers in (Just 10) and (Just 40)
15:15 <Iceland_jack> > liftA2 (+) (Just 10) (Just 40)
15:15 <lambdabot> Just 50
15:15 <Iceland_jack> > liftA2 (+) [10] [40]
15:15 <lambdabot> [50]
15:15 <Iceland_jack> > liftA2 (+) (Right 10) (Left "ERROR")
15:15 <lambdabot> Left "ERROR"
15:16 ystael joined
15:16 primal joined
15:17 <ab9rf> writing succinct and useful code is a lot harder without Applicative.
15:17 Elhamer_ joined
15:17 mtg joined
15:17 osa1 joined
15:17 osa1 joined
15:17 <clamchowder> byorgey: yeah every monad is also applicative, but then I may as well just use monad
15:17 <Iceland_jack> clamchowder: there are more Applicatives
15:18 <ab9rf> no, you really should not just use monad
15:18 <ab9rf> monads have more restrictive conditions than applicatives
15:18 <ab9rf> there's lots of things that are applicative that aren't monads
15:19 thimoteus joined
15:20 <clamchowder> Iceland_jack: I suppose. But any natural examples of non-monad applicative?
15:20 <Iceland_jack> You keep using this word, 'natural' :)
15:20 <glguy> clamchowder: I have an example of using a type that only supports an Applicative instance but not a Monad in order to generate documentation from a parser https://glguy.net/config-demo
15:21 <Iceland_jack> Look at http://blog.functorial.com/posts/2015-12-06-Counterexamples.html
15:21 <ab9rf> ziplists?
15:21 <quchen> glguy: reify can’t be used in GHCi ಠ_ಠ how do I debug this
15:21 <glguy> quchen: Yes it can
15:21 <Iceland_jack> "An Applicative which is not a Monad"
15:21 <glguy> What are you trying?
15:21 <Iceland_jack> ZipLists, Const m
15:21 <quchen> runQ (reify ''Doc)
15:21 <quchen> Template Haskell error: Can't do `reify' in the IO monad
15:21 <glguy> clamchowder: In that example "SectionSpecs" is only an Applicative
15:21 <quchen> in GHCi
15:21 <glguy> quchen: Yeah, you have to do reify in Q
15:22 <Iceland_jack> Validation is an Either that can't be a Monad
15:22 <glguy> try: $(stringE . show =<< reify ''Doc)
15:22 takle joined
15:22 <clamchowder> Iceland_jack, glguy, ab9rf, byorgey: thanks very much guys! Sorry I have to go now... I'll read the links
15:22 <Iceland_jack> good luck clamchowder
15:22 <quchen> glguy: Ah, I see.
15:23 <quchen> glguy: I tried »fmap show« but that didn’t help of course.
15:23 <clamchowder> Iceland_jack: thanks :)
15:23 <glguy> quchen: this is a nicer interface to reify : http://hackage.haskell.org/package/th-abstraction
15:23 psmmr joined
15:23 <glguy> quchen: It works across lots of versions of GHC so you can save the CPP effort
15:24 <glguy> and it normalizes out the syntax-focused nature of reify
15:24 <bartavelle> glguy: wow that's a nice package!
15:24 dcoutts joined
15:24 dcoutts joined
15:24 <ab9rf> it occurs to me that there's probably lots of applicatives that i use that are actually monads but i just don't care that they're monads :)
15:24 jao joined
15:25 <mniip> @where pristine
15:25 <lambdabot> I know nothing about pristine.
15:25 <mniip> @where Pristine
15:25 <lambdabot> I know nothing about pristine.
15:25 <mniip> hmm
15:25 sellout- joined
15:26 <mniip> there it is http://silicon.int-e.eu/lambdabot/State/Pristine.hs
15:27 ystael joined
15:28 dcoutts_ joined
15:31 sepp2k joined
15:32 robotroll joined
15:34 Cerise joined
15:34 Cerise joined
15:37 Luke joined
15:37 primal_ joined
15:38 <Tuplanolla> I just did the Haskell "if it compiles, it works" trick on a 10 k line C project.
15:38 <Tuplanolla> This place has clearly taught me some good habits.
15:38 <quchen> glguy: Is there an API function I’m overlooking to reify values, or do I have to do the plumbing myself in order to convert one from the old type to my own format?
15:39 <glguy> quchen: I'm not sure what you mean, you can't reify values
15:39 <quchen> glguy: I want to write a function »Foo -> Bar«, where I have full control of Bar, but Foo’s constructors are hidden.
15:40 urodna joined
15:40 <glguy> You'll have to use Template Haskell to generate a case statement, for example, that can consume a Foo
15:41 <quchen> I see. Looks like I have some TH exercise ahead of me. Thanks for the help!
15:41 <mrkgnao> someone tell me if wanting promoted record, uh, kinds to print in a recordish fashion in GHCi is intrinsically stupid
15:42 primal joined
15:42 trism joined
15:42 <mrkgnao> I mean, yeah, type-level record selectors obviously won't exist, but still
15:42 eazar001 joined
15:42 hackebeilchen joined
15:42 alx741 joined
15:43 <lyxia> no it would be quite useful for type-level programming
15:43 ozgura joined
15:44 <glguy> without some cleverness it would probably result it less readable types, record syntax is rather verbose to be printing inline in a larger type signature
15:44 jgt3 joined
15:44 <heath> anyone care to add to this? https://gist.github.com/heath/858a321b5fc96d3011d9b6ea4fca3cb9
15:44 Cerise joined
15:44 Cerise joined
15:44 sproingie joined
15:44 sproingie joined
15:45 <mrkgnao> that's definitely true. I almost blew GHCi up today by calling kind! on a broken type family that didn't reduce and made the buffer grow to ~5M, hah
15:46 bonz060 joined
15:47 tromp joined
15:47 primal_ joined
15:47 <Tuplanolla> I was going to answer, but then I realized I've never used a good dynamically typed language, heath.
15:47 <sproingie> clojure's pretty good
15:47 <Tuplanolla> Erlang would probably be nice as well.
15:47 xcmw joined
15:48 ertes joined
15:48 <c_wraith> Erlang is nice, but it's amazingly hard to switch between Erlang and Haskell. They use opposite conventions for lexing patterns!
15:48 pie_ joined
15:48 wroathe joined
15:50 <heath> someone messaged me this as well: """ in general, re tacl, a system that is highly reliable tend to be _less safe_ Because errors _will happen_ and they will be more catastrophic and you will be less prepared for them. """
15:51 <sproingie> that ... makes no sense
15:51 <sbrg> yeah...
15:51 <sproingie> at worst it's somewhat orthogonal
15:52 <maerwald> yeah, you want your program to crash on an airplane on errors?
15:52 <sproingie> to say nothing of the general safety of planes
15:53 <mrkgnao> maybe the idea is that it's good to move fast and break a couple airplanes in a while if it increases overall safety /s
15:53 <glguy> if people get to accustomed to not dying on airplanes they might keep using them
15:53 mohsen_ joined
15:54 <mrkgnao> but planes are safe enough already that that's stupid even assuming suspension of disbelief
15:54 <sproingie> they still experiment with planes. they generally don't stick people in them when they do.
15:54 <mrkgnao> glguy: "avoid success at all costs"
15:54 primal joined
15:54 ystael joined
15:54 <heath> this guy started out with an ML, and i know he understands the importance of type safety. i think his point was around unexpected failure similar to what is discussed at https://arxiv.org/ftp/arxiv/papers/1703/1703.10863.pdf
15:56 <sproingie> not impressed by the socratic dialogue in the papers
15:56 saussure joined
15:57 <sproingie> saying Y2K wouldn't have been helped by formal proofs. i dunno what formalisms are involved in "plug in a number > 99" but there's probably something
15:58 jutaro joined
15:58 <sproingie> we just need to cut those pesky humans out of the loop
15:59 louispan joined
15:59 primal joined
15:59 <heath> sproingie: i thought the same thing about ariane, but the software was built to spec. the spec was incorrect though: http://se.inf.ethz.ch/~meyer/publications/computer/ariane.pdf
16:00 <heath> there might be something to the study of "human factors" and "system design"
16:00 takle joined
16:00 <tobiasBora> Hello,
16:01 <tobiasBora> How could I use the HDBC postgresql backend to insert array ? I'm trying to play with that but I can't find a way to insert an array, since only SqlText type exists (no SqlArray type)
16:01 jaziz joined
16:01 <mrkgnao> SMH: "satisfiability modulo humans"
16:01 <heath> :)
16:01 <sproingie> yah, systems have to take human factors into account. security's a big one for example: the most secure systems are usually the ones no one wants to use
16:01 <EvanR> tobiasBora: arrays arent standard sql, so i would be surprised to see HDBC support it
16:02 <tobiasBora> I've still an error:
16:02 <heath> """reliability means doing what your specs says in a consistent way. it does not means doing things that are _safe_. safety is a _system level_ property"""
16:02 <maerwald> sproingie: why is that
16:02 Sonolin joined
16:02 <tobiasBora> execute: PGRES_FATAL_ERROR: ERREUR: array literal badly formated, the array must begin with...
16:02 Argue_ joined
16:03 <sproingie> tobiasBora: you might be looking for executeMany if you're trying to do several rows
16:03 cpennington joined
16:03 <maerwald> heath: I'd say that's rather compliance, not reliabilty
16:03 <EvanR> sproingie: talking about an array data type
16:03 <EvanR> in the database
16:04 <sproingie> maerwald: because the more you lock things down, the more cumbersome it is to use, and the more people will circumvent it
16:04 <maerwald> I don't see the connection
16:04 <sproingie> case in point, a password policy that forces new passwords every couple weeks. know what happens then? people write down their passwords.
16:05 ystael joined
16:05 <maerwald> ah well, I was more thinking about the technical software level
16:05 <sproingie> or security doors with an elaborate protocol. people prop them open.
16:05 <maerwald> as in: you have two ftp server implementations, one has a higher attack surface than the other... the end user still doesn't see any difference
16:05 ccomb joined
16:06 <sproingie> sure there's plenty that can protect software against itself, and more to be done there
16:06 <EvanR> i proped the security door open last night when the power went out, otherwise i wouldnt be able to get back in
16:06 <mniip> how would I bootstrap cabal with a custom installation directory??
16:06 marr joined
16:07 primal_ joined
16:07 zariuq joined
16:07 RegEchse joined
16:08 nomotif joined
16:09 wroathe joined
16:10 <sproingie> easiest probably would be to make a symlink
16:11 <mniip> what
16:11 <sproingie> cabal looks in /usr/local and ~/.cabal and afaik those are pretty hardwired
16:12 <merijn> mniip: Why wouldn't you use the ~/.cabal directory?
16:12 <mniip> it's a chroot of sorts
16:12 <merijn> mniip: You can try asking in #hackage where the cabal experts hang out
16:13 jsgrant joined
16:14 anodium joined
16:14 nick8325 joined
16:15 oisdk joined
16:15 ystael joined
16:17 primal joined
16:17 ralu joined
16:18 fragamus joined
16:18 e14 joined
16:19 LHoT10820 joined
16:20 abroz joined
16:20 robotroll joined
16:21 caumeslasal joined
16:24 mizu_no_oto joined
16:25 TheFuzzball joined
16:26 buttbutter joined
16:26 jsgrant left
16:26 takle joined
16:26 primal_ joined
16:27 dm3 joined
16:28 ozgura joined
16:29 Guest10 joined
16:30 jsgrant joined
16:35 tosun joined
16:35 Elhamer joined
16:35 tommd joined
16:37 primal joined
16:37 robertkennedy joined
16:38 <robertkennedy> Does anyone know if hlint has an "only errors" flag?
16:38 harryblack left
16:38 Guest7184 joined
16:38 oisdk joined
16:39 <merijn> robertkennedy: hlint never reports errors
16:39 <merijn> robertkennedy: It's a style hinter, not an error checker
16:39 <robertkennedy> In hlint's terminology "use concatMap" is an error
16:39 t7 joined
16:40 <robertkennedy> The three severity levels it has are Suggestion/Warning/Error
16:40 <tosun> How do I check if a `PrimTyCon` (constructor from `TyCon` from types/TyCon.lhs) is, for example, `intPrimTyCon` or `eqPrimTyCon`? I am looking at Eisenberg's Core specification from the GHC repo.
16:41 <tosun> When the constructors are not exported there usually are predicates, but this is not the case primitive type constructors
16:41 avi` joined
16:42 takle_ joined
16:43 <mniip> hmm
16:43 `Guest00000 joined
16:43 <mniip> I think I got the bootstrap script to work
16:43 <mniip> now comes the package mess associated with base-4.11
16:44 <merijn> base-4.11 o.O
16:44 <merijn> oh, I suppose 4.10 is 8.2
16:44 <mniip> oops
16:44 <mniip> one too many
16:44 <mniip> 4.10
16:44 <* sbrg> wonders when base will hit 4.20
16:44 <mniip> yes
16:44 mbuf joined
16:44 <sbrg> or will we bump it to 5 by then?
16:46 Boomerang joined
16:46 dm3 joined
16:47 sellout-1 joined
16:47 oisdk joined
16:47 <mniip> huh
16:47 <mniip> I have Cabal- installed but it's not on hackage?
16:48 <mniip> indeed it is not
16:48 xcmw joined
16:48 <glguy> mniip: Are you using a GHC release candidate?
16:49 dm3_ joined
16:49 <mniip> git head
16:49 argent0 joined
16:49 psychicist__ joined
16:50 albertus1 joined
16:50 primal joined
16:51 wroathe joined
16:53 <dredozubov> is there a type-directed way to find inhabitants for singleton types in haskell?
16:53 gillesmajor joined
16:53 baldrick1 joined
16:53 <mniip> ugh
16:54 <dredozubov> proof-searching makes me think of constraints library
16:54 <mniip> seems like I'll have to reinstall ghc
16:54 <dredozubov> but i honestly have no clue how to make something useful out of it
16:54 SkyPatrol joined
16:56 primal_ joined
16:56 eklavya joined
16:56 takle joined
16:57 drewbert joined
16:57 kritzcreek joined
16:57 <dredozubov> hm, `find` is not a correct term though
16:58 <dredozubov> `constructing` seems more precise in this context
16:58 <dredozubov> `construct`*
16:59 quinor joined
17:00 <quinor> Hey, a quick (maybe complicated) question from me: can I compose same monad transformer multiple times? ie. type Test a = ReaderT Int (Reader Bool) a
17:01 <quinor> If yes, how to use that construct? If no, what should I do instead?
17:01 <EvanR> Reader (Int,Bool) would be simpler
17:01 connrs joined
17:01 <EvanR> and (Int,Bool) -> a would be simpler
17:01 <EvanR> see also Int -> Bool -> a
17:02 <quinor> my question is not exactly about that example but what to do if I want to use monad transformer on a monad which already uses that particular one
17:02 <EvanR> you can do it
17:03 <sbrg> quinor: I don't think it's possible normally, but there are libraries that let you do it.
17:03 <EvanR> its possible
17:03 <EvanR> monad transformers take any monad, such as ReaderT r IO a, to another monad
17:04 <byorgey> it's absolutely possible. The only problem is that type-class based operations like 'ask' will work with one of the Readers but not the other.
17:04 <sbrg> sure, you can compose them. but you can't use them very easily.
17:04 <sbrg> ^
17:04 <EvanR> er, ReaderT IO r a
17:04 <byorgey> To get the other you have to do 'lift . ask' or something like that
17:04 Destol joined
17:04 <byorgey> sbrg: they're not *that* hard to use.
17:04 <sbrg> there was this nice library I don't remember the name of which seemed pretty elegant
17:04 <quinor> byorgey: I forgot about the lift
17:04 <EvanR> yes theres lift and hoist and MonadBaseControl and ...
17:04 primal joined
17:05 <EvanR> i try to avoid monad transformers unless im trying to make a specific kind of monad and then transformers can be used as the backend implementation only
17:05 abroz joined
17:05 muesli4 joined
17:05 <quinor> what should I use instead EvanR, function arguments?
17:06 <EvanR> which makes their presence at that point optional
17:06 <dredozubov> quinor: you can compose it, but the type inference will not work smoothly when you'll want to call `ask`
17:06 sfcg joined
17:06 <EvanR> quinor: for ReaderT over Reader... yes just use functions
17:07 <dredozubov> if you want to stick with mtl, push all your data in one reader and get the field with a getter
17:07 <quinor> dredozubov: that's my plan probably, thanks
17:07 AlphaAtom joined
17:07 Itkovian joined
17:07 <dredozubov> also you can try this https://hackage.haskell.org/package/hreader
17:07 oisdk joined
17:07 <dredozubov> it's lacking in documentation though
17:07 pylbrecht joined
17:08 <quinor> I'll stay with getters :)
17:08 locallycompact joined
17:08 <dredozubov> another way will be using an alternative library which features tagged transformers
17:09 ystael joined
17:09 primal_ joined
17:10 halogenandtoast joined
17:10 <quinor> the usecase is I'm writing an interpreter and wanna keep current namespace and stack trace with me
17:10 SkyPatrol joined
17:10 <quinor> I guess I'll just use functions
17:11 rkazak joined
17:11 Swizec joined
17:12 iAmerikan joined
17:12 <EvanR> if they arent modifiable, that sounds sane
17:12 <EvanR> if they are modifiable but you never return, thats still easy, just pass the modified version to the next iteration
17:13 <quinor> that's the point of reader monad, so yeah EvanR
17:13 <EvanR> im kind of not sure about the point of bare Reader monad ;)
17:15 alex__ joined
17:15 GGMethos joined
17:15 <dredozubov> hiding a lot of unnecessary details(arguments in that case)?
17:15 <EvanR> if its a whole record of things, no
17:15 <EvanR> its a single record
17:16 <quinor> EvanR: me neither, I was taught this way on classes
17:16 <quinor> still learing haskell
17:17 <dredozubov> Reader with a record is not very flexible solution
17:17 primal joined
17:17 <EvanR> eh?
17:17 <c_wraith> Reader by itself really isn't easier than just padding an argument in any way.
17:17 <dredozubov> you'll want to have a subset of that record in quite a few cases
17:17 <c_wraith> *passing and argument
17:17 <c_wraith> I give up.
17:17 <EvanR> that sounds like a niche case, but reader and functions can both do that
17:17 <dredozubov> but if you have a record, you'll have to instantiate the rest
17:18 <dredozubov> EvanR: it's all over my work codebase
17:18 <EvanR> reader loses one argument and adds sporatic uses of do notation and an oddball type
17:18 <dredozubov> which is >100KLOC
17:18 <EvanR> you should just pass the records around then
17:18 <dredozubov> i promise you it can be quite tiresome
17:20 <dredozubov> let's say you want to have terms of types A, B, C here and B, C, D there
17:20 <dredozubov> record can only be A, B, C, D in that case
17:21 <dredozubov> what do you do if instantiating D in the first case and instantiating A in the latter one don't make any sense?
17:21 <EvanR> D is coming from the global environment?
17:21 <EvanR> then its obviously in that global record
17:22 <dredozubov> what if doesn't make sense to instantiate it?
17:22 <EvanR> if you want strict access control, then you need to use (A,B,C) in one case (B,C,D) in the other, or use more types
17:22 Faucelme_ joined
17:22 <EvanR> i dont follow your question
17:23 clog joined
17:23 <dredozubov> ok, we have two cases
17:23 <dredozubov> now add another twenty
17:23 armyriad joined
17:23 <EvanR> strict access control is a bitch!
17:23 <dredozubov> i'm arguing there are better ways of doing that
17:23 <EvanR> if A B C and D are all in the global environment, then the simplest case is to put them all in one record and pass it around everywhere
17:24 <nshepperd> class HasA m where { askA :: m A }?
17:24 socrabot joined
17:24 <EvanR> thatll work if youre buried in transformers
17:24 <dredozubov> we've had two solutions for that problem
17:24 mada joined
17:24 <dredozubov> https://hackage.haskell.org/package/hreader-1.1.0/docs/Control-Monad-HReader.html first one
17:25 <dredozubov> https://hackage.haskell.org/package/ether second one
17:25 Luke joined
17:25 <EvanR> i dont understand "it doesnt make sense to instantiate one is one of the cases"
17:25 <EvanR> in one
17:25 <EvanR> if its in the global environment
17:26 <dredozubov> imagine you have two similar programs
17:26 <dredozubov> which share a lot of code
17:26 pie_ joined
17:26 <dredozubov> let's say you have two services
17:27 <dredozubov> one logs errors to file on file system
17:27 primal_ joined
17:27 <dredozubov> the other one logs it to an external log service(awkward example, i know)
17:27 codygman_ joined
17:27 raynold joined
17:27 Faucelme joined
17:27 <dredozubov> the rest of the configuration is shared
17:28 <dredozubov> it doesn't make any sense to provide a API token for a log service to the first one
17:28 <dredozubov> and it doesn't make any sense to provide a filename to the second one
17:28 <EvanR> yes so you have types Prog1Env and Prog2Env which look similar
17:28 <cocreature> I’m not sure that example is very good. your record can just have a field of type LoggingConfig which can be a sumtype representing the different choices
17:28 <nshepperd> but it makes perfect sense to provide the whole program configuration
17:29 <EvanR> and the two programs dont expect the same reader record
17:29 coltfred_ joined
17:29 <cocreature> or even just a "LogMsg -> IO ()" action and you capture the config implicitely
17:29 <nshepperd> if the first service wants to ignore the API token, that's its business?
17:29 <dredozubov> sure, that's a simple difference
17:29 <EvanR> cocreature: that doesnt sound very good actually, because if you are given the one that doesnt make sense, you crash?
17:29 <dredozubov> you add a type parameter and you're good to go
17:29 <EvanR> LogMsg -> IO () makes more sesne
17:29 <dredozubov> but tomorrow you'll have another one
17:29 <EvanR> that is what im using
17:29 sleffy joined
17:29 <dredozubov> and it'll go on
17:30 <cocreature> EvanR: I was assuming that the LoggingConfig field decides how you log
17:30 <dredozubov> it makes you refactor a whole bunch of code every time you do that
17:30 netheranthem joined
17:30 <EvanR> well, in this example *you* wanted to decide how to log
17:30 <cocreature> if you use the LogMsg -> IO () you shouldn’t need to refactor anything
17:30 <dredozubov> imagine having a constraint based resolution instead
17:30 <EvanR> so yeah we solved that one, but dredozubov is saying the next problem will be different yet also solved by hreader
17:30 afldcr joined
17:31 <nshepperd> dredozubov: why even bother removing the api token from the context, when the file based logger already isn't using it?
17:31 <dredozubov> MonadReaders '[A,B,C] m => m Foo
17:31 <EvanR> nshepperd: because to put it there in the first place in the other program you have to instantiate it for no reason, as an object
17:31 <EvanR> i guess you could put undefined...
17:32 <dredozubov> at some point you'll want to limit the environment
17:32 <cocreature> I completely agree that Reader (or rather ReaderT) can make my life easier. I’m not sure if hreader actually helps over standard reader + classy lenses
17:32 <dredozubov> which can be done with type families
17:32 <EvanR> dredozubov: in my code.. i would have written A -> B -> C -> IO Foo...
17:32 <EvanR> which is about as long
17:32 <dredozubov> now imagine having 40 arguments
17:32 wroathe joined
17:32 mohsen_ joined
17:33 <EvanR> and you use constraint synonyms?
17:33 <EvanR> or what
17:33 <dredozubov> cocreature: sure, there are lots of similar solutions
17:33 balor joined
17:33 mstruebing joined
17:33 <dredozubov> it happens i don't really like "just stuff it in the record" mentality
17:33 <dredozubov> it leads to overconstrained code
17:34 Itkovian_ joined
17:34 <dredozubov> every function that use at least some configuration suddenly depends on a bunch of other stuff
17:34 <nshepperd> ok, so in one case the api token doesn't exist
17:35 <EvanR> 40 arguments to HReader ?
17:35 <nshepperd> then the LogMsg -> IO () method seems superior
17:35 <cocreature> EvanR: the point is with Reader you only have a long type signature but if your function just passes those 40 arguments down to other functions you don’t have to specify the 40 arguments every time. if you pass arguments manually you have to do that
17:35 <dredozubov> EvanR: constraint synonym are ok for that matter
17:35 drcode joined
17:35 <EvanR> cocreature: so... record
17:35 crobbins joined
17:35 SeMas joined
17:35 psychicist__ joined
17:36 <dredozubov> EvanR: you'll get a heterogenous structure for free
17:36 leat joined
17:36 <cocreature> EvanR: then you can’t use arbitrary subsets of this record without creating a new record for each and every one of them
17:36 hybrid joined
17:36 <dredozubov> you can make subsets and stuff like that pretty easy with that approach
17:36 Bassetts joined
17:36 <dredozubov> cocreature: exactly
17:36 <EvanR> cocreature: if the subsets are small, youd just use arguments. if they are huge, just pass the whole thing
17:36 jaziz joined
17:37 <EvanR> im doing both in my program right now
17:37 <dredozubov> > if the subsets are small
17:37 primal joined
17:37 <lambdabot> <hint>:1:25: error:
17:37 <lambdabot> parse error (possibly incorrect indentation or mismatched brackets)
17:37 <EvanR> because "just dont use the stuff you dont use"
17:37 <dredozubov> oh lambdabot
17:37 <cocreature> EvanR: now you are passing more information to functions then they need which means the type signature is going to tell me less about what the function can do
17:37 th0br0 joined
17:37 <dredozubov> if you have 3 arguments, then it doesn't matter
17:37 <EvanR> yeah but i need to get the job done and stop over engineering ;)
17:37 <dredozubov> when you have 30, you'll feel pain
17:38 <EvanR> kind of skeptical about 30 argument subsets of a 900 field environment
17:38 <EvanR> which mix and match randomly
17:38 zero_byte joined
17:38 <EvanR> what in the world
17:38 dm3 joined
17:38 Tene left
17:38 <EvanR> types can become too much
17:38 <centril> dredozubov: 30 arguments to a function? how the...
17:39 <centril> tho... I get mad even with 1 argument and put in a Reader
17:39 <EvanR> :|
17:39 <cocreature> centril: yeah I’m just too lazy to pass things around when I can let ghc do it for me :)
17:40 <jle`> (?implicit :: Params) => ...
17:40 <centril> More so in the case of State ... manually passing state is no fun
17:40 <dredozubov> it's simple, you rewrite less code if you use mtl and Readers
17:40 <EvanR> i havent had that experience
17:40 <dredozubov> it's all about working in polymorphic monads
17:40 <EvanR> when i rewrite all my code to use a Reader, its the opposite experience
17:40 <cocreature> jle`: thou shalt not talk about the existence of implicit parameters
17:41 <dredozubov> if you pass arguments explicitly... you have a lot of free time on your hands!
17:41 <cocreature> different people prefer different coding styles :)
17:41 <EvanR> when i rewrite it back because the Reader is not helping
17:41 <EvanR> yes not spending time making these decisions would be nice
17:41 <centril> cocreature: ummh... use one Reader + Env + zoom with Lens ?
17:41 <centril> To tank about implicit parameters is to sin.
17:41 <centril> talk*
17:41 wroathe joined
17:42 <EvanR> i was going to mention that, glad jle` did it for me
17:42 ziocroc joined
17:42 <dredozubov> centril: i like that, when i have a bunch of nested readers/states
17:42 <jle`> it's a legitimate coding style ;_;
17:42 <jle`> i've been using it for years
17:42 <dredozubov> you zoom to the part of the structure and run another transformer
17:43 <centril> yep, its neat
17:43 <cocreature> jle`: heretic!
17:43 <centril> jle`: shame on you.
17:43 <jle`> you just need to understand the trade-offs
17:43 <jle`> MonadReader/Reader/reflections/etc. all have tradeoffs
17:43 oisdk joined
17:43 socrabot left
17:44 primal_ joined
17:44 takle joined
17:45 <hexagoxel> a data-type that'd i'd normally call "tree" really becomes a DAG due to sharing. Which term (tree vs DAG) should i prefer when describing values of such a type?
17:45 refold joined
17:45 <cocreature> jle`: sure but obviously the tradeoffs that I choose are the right ones and everyone else is wrong
17:45 <centril> dredozubov: tho... when you have lenses and traversals, you really dont need to zoom, you can just use "use / using" and your traversal/lens
17:45 <jle`> the curse of being right
17:45 Levex joined
17:45 <dredozubov> cocreature: that's a positive way of looking at things
17:45 <dredozubov> i should adopt that
17:45 sz0 joined
17:45 <th0br0> Currently wondering how I'd implement frame types for a protocol, e.g. (from cpp:) `enum FrameType { F1 = 0x01, F2 = 0x08, ... }` without writing the value twice for serialising/deserialising. Any pointers as to where I might look for what is a good pattern for this?
17:46 <cocreature> dredozubov: it makes life a lot simpler. the only downside is that everybody hates you
17:46 <dredozubov> cocreature: who cares if you're right. amirite?
17:46 <cocreature> :)
17:46 <Tuplanolla> Unleash your inner Henning.
17:47 <cocreature> please don’t
17:47 <centril> cocreature: thank you for putting my thoughts into words. I've always had this sensation that everything I do is just awesome.
17:47 <hexagoxel> @hackage multistate
17:47 <lambdabot> http://hackage.haskell.org/package/multistate
17:47 <hexagoxel> dredozubov: i have not read the whole discussion, but ^ might be relevant
17:47 <sbrg> th0br0: One way would be to use `data Foo = F1 | F2 .. deriving Enum` and then you can have a Map from the type to the values. this doesn't statically guarantee that you have assigned every frame type a value, though, but that could be caught using tests, or you can have the compiler warn you if you just use a function instead of a Map.
17:48 <hexagoxel> or you might all have already agreed that such approach is entirely ugly :D
17:48 <centril> "and all kinds of GHC extensions magic"
17:48 <centril> nice.
17:48 tromp joined
17:48 primal joined
17:49 <cocreature> hexagoxel: oh btw I recently stumbled upon your butcher library. if you are fine with GHC >= 8.0 you don’t need your evil monadic interface and can just use ApplicativeDo instead
17:49 xcmw joined
17:49 cpennington joined
17:50 osa1 joined
17:50 <cocreature> hexagoxel: and optparse-applicative had a hack even before that using Arrow to provide names https://hackage.haskell.org/package/optparse-applicative-
17:50 <th0br0> sbrg: thought about that and saw an approach that would make the compiler tell me if I forgot to map an enum - was just wondering whether there exists a more native way, esp. for reverse mapping (i.e. from number to type)
17:51 <hexagoxel> cocreature: yeah, i am aware. I did write attempt an Applicative-base interface at some point, too. There are two reasons that i stuck to the monadic version:
17:51 mbw joined
17:51 <hexagoxel> 1) ApplicativeDo still had some strange constraints to it (return $ ..) not being supported, plus kinda-confusing error messages when you mess up, although i have not checked if latest ghc versions have improved on that;
17:52 <cocreature> I think it doesn’t support pure. return is supported iirc
17:52 <centril> what is wrong with pure $ ...
17:52 <cocreature> which is even weirder
17:52 <sbrg> th0br0: if you use a Map, it is pretty simple to reverse the map. but that still doesn't get you the compile-time guarantee. I'm sure there are ways to do it with some fancy type magic
17:52 <hexagoxel> ah yes, i meant `pure $ ..`
17:52 <mbw> Hello, is it possible to define an Applicative instance for arrays that behaves like the one for ZipLists? Specifically, would "pure" have to return an infinite array...?
17:53 <glguy> No, you can't allocate an infinite array
17:53 <hexagoxel> 2) for supporting child-commands, you'd still need two "layers" instead of the one; one to gather the flags, one to define implementation/childcommands.
17:54 <mbw> Yeah I know that. The question is if a "zip-like" Applicative instance is possible without violating the laws.
17:54 <cocreature> hexagoxel: fair enough.
17:55 <cocreature> mbw: pure x = ZipList [x] doesn’t work because of the "pure id <*> v" law
17:55 <th0br0> sbrg: cheers.
17:55 coot____ joined
17:56 <cocreature> mbw: if you include the length of the array at the typelevel you should be able to write an instance but now you can’t combine arrays with different lengths anymore (whether you want to do that depends on your application)
17:56 <hexagoxel> to be fair, the two-layer solution probably would still be preferable; i spend too much time considering one-layer approaches and have not bothered to do the two-layer one yet.
17:56 <cocreature> eh "pure id <*> v = v". I forgot the important part
17:56 <hexagoxel> mistake on my part that i did not consider it sooner.
17:56 <hexagoxel> s/spend/spent/
17:56 primal_ joined
17:57 <cocreature> hexagoxel: it just felt weird that the readme talked a lot about the naming part which is mostly solved by ApplicativeDo.
17:57 <mbw> cocreature: If I only write expressions like (\x y z -> ...) <$> mx <*> my <*> mz, and not pure (\x y ....) <*> mx ..., I should be able to half-ass it and leave pure undefined.
17:58 <nshepperd> fixed size vectors have a zippy applicative instance. they're even monads
17:58 <mbw> Which is not a law-abiding applicative instance
17:58 <cocreature> mbw: sure but then you don’t really have an Applicative instance :)
17:58 coot_____ joined
17:58 <cocreature> mbw: you should be able to make an instance of Apply which is Applicative without pure https://hackage.haskell.org/package/semigroupoids-5.2/docs/Data-Functor-Bind.html#t:Apply
17:58 <mbw> It would be ideal if you could generalize Control.Monad.Zip to mzipWith3/4/... etc.
17:58 <mbw> Oh, that sounds interesting.
17:59 <cocreature> nobody really uses it afaik but it exists
17:59 moongazer joined
17:59 cdg joined
18:00 <nshepperd> you could also extend your array type with an additional point. data ZipArray a = Pure a | Array (Vector a)
18:00 <nshepperd> and do the obvious thing when combining
18:01 <cocreature> huh, would that really be lawful?
18:01 <cocreature> it seems weird
18:01 <mbw> If I used Vector instead of Array, I don't think I would have to reinvent the wheel in the first place.
18:02 wroathe joined
18:02 cpennington joined
18:02 <mbw> It's probably best to just stick with array/accumArray, since these functions are more or less omnipotent...
18:02 <cocreature> hm seems like the laws hold
18:02 <nshepperd> cocreature: yeah, it's basically adjoining a value for each constant infinite list
18:02 <jle`> hm yeah
18:03 <nshepperd> Array or Vector, whatever
18:03 <jle`> for data Pure f a = Pure a | Other (f a)
18:03 <jle`> you have instance Apply f => Applicative (Pure f)
18:03 <jle`> er
18:03 locallycompact joined
18:03 tomphp joined
18:03 <jle`> for data Lift f a = Pure a | Other (f a), you have Apply f => Applicative (Lift f)
18:04 <jle`> i suppose it's similar `Semigroup m => Monoid (Maybe m)`
18:04 <mbw> I need to use higher-dimensional arrays, so the difference does matter. (And a Vector of Vectors of Vectors of ... is just not the same.)
18:05 <jle`> interestingly enough, the Applicative instance for 'Lift' irl has an Applicative constraint since Apply isn't well used
18:05 <nshepperd> well, I think it works for higher dimension arrays too
18:05 sdothum joined
18:05 <jle`> just like how the Monoid instance for 'Maybe' irl has a Monoid constraint since Semigroup isn't well-used
18:05 <mbw> Also, Haskell's Arrays are way underrated. I really came to like them :)
18:05 replay joined
18:05 <nshepperd> except Pure represents I guess an infinite... hyper.. half-plane instead of an infinite list
18:06 <mbw> This might become complicated quickly.
18:06 <jle`> the last time i used Array was ... before I knew about Vector
18:08 <jle`> by the way, consider that the `f <$> xs <*> ys <*> zs` style of zipping arrays might not be as performant as just using array + indexing
18:08 exarkun joined
18:08 <jle`> unless you can somehow defer the allocation of the intermediate arrays
18:08 primal joined
18:08 ptvirgo joined
18:08 <shapr> jle`: is there a blog post describing the benefits of vector over array?
18:09 ystael joined
18:09 <mbw> Yeah but seriously, I have tried my way with all the major array libraries. Sure, for the one-dimensional case, Vector's got you covered. On the other hand, Repa and Accelerate are unwieldy. And clunky. Indexing via snoc-lists, reduced type-inference, etc. This doesn't help if you want to "quickly try something out". On the other hand, if you get to know arrays, there API is not so bad. It may be helpful to
18:09 <mbw> also have some experience in an imperative language, though.
18:10 flatmap13 joined
18:10 <jle`> shapr: api is a little more fully featured/user friendly
18:10 <shapr> mbw: you prefer Array for multidimensional?
18:10 <jle`> but also i'm not sure if array has any fusion
18:10 <nshepperd> ofc whether this is useful to you depends on what else you intend to do with the arrays... you can implement most of the array api for ZipArray, but (\\) won't work / will be partial
18:11 <mbw> jle`: Btw, I have not really considered the problem with intermediaries. On the other hand, it wouldn't work for Unboxed Arrays anyway.
18:11 cyborg-one joined
18:11 <cocreature> the fact that vector-algorithms is a thing while array-algorithms isn’t, can also often be a deciding factor
18:11 <jle`> i can't find any mention of stream fusion in the docs for arrays
18:11 <mbw> shapr: I really tried to come to like Repa/Accelerate. I really tried... Also, if you have anything not "inherently parallel", what are you gonna do?
18:12 <cocreature> I’m not going to implement tim sort myself
18:12 <EvanR> you got your Data-IVar, you got your ivar-simple, you got your data-ivar...
18:12 tomphp joined
18:12 <shapr> mbw: I really want to read your blog post or whatever about this, I don't think I have all the context
18:12 <mbw> jle`: I don't think they have that. Looking through the source, there are some rewrite rules for the second Functor law and stuff like that, but I think that's it
18:13 <jle`> yeah, so that's also probably a pbd
18:13 <EvanR> can edk please make a "once and for all" ivar package called ivar
18:13 wroathe joined
18:13 mstruebing joined
18:14 <jle`> cocreature: simple, just convert back and forth between vectors and arrays
18:14 <mbw> shapr: I don't have a blog. The thing that comes closest to it would be a reddit question I asked about Repa that became really long. Didn't get that much attention tho.
18:14 <shapr> got a link?
18:14 oisdk joined
18:14 <cocreature> jle`: who needs performance anyway
18:14 <jle`> avoid performance at all costs
18:14 <Tuplanolla> What is there to blog about, shapr? Our multidimensional array situation is a mess.
18:15 tzh joined
18:16 <mbw> shapr: https://www.reddit.com/r/haskell/comments/68pc7a/equational_reasoning_with_multidimensional_arrays/
18:16 <mbw> But it probably isn't really what you are looking for.
18:16 takle joined
18:16 primal_ joined
18:18 hackebeilchen1 joined
18:18 dual joined
18:20 takle joined
18:20 merijn joined
18:22 takle joined
18:22 cpennington joined
18:25 dddddd joined
18:25 <torstein> With Hspec, are "before_" actions run before every top level describe, or every nested describe also?
18:25 Kuros` joined
18:26 <torstein> How can I can I call a setup function which is only run once before some "describe"'s?
18:26 primal joined
18:29 pylbrecht joined
18:29 simukis_ joined
18:29 <LiaoTao> Is ghc smart enough to reduce two sequential maps over the same data with two different functions to a single map with the functions composed together?
18:30 dxtr joined
18:30 HarveyPwca joined
18:30 uglyfigurine joined
18:30 <glguy> LiaoTao: Yes, but because the authors of 'map' write RULES for it, not because of a general purpose optimiation
18:30 jgt3 joined
18:31 <LiaoTao> Right
18:31 <LiaoTao> glguy: Thanks!
18:31 simukis_ left
18:32 juanpaucar joined
18:33 phaji_ joined
18:33 simukis joined
18:34 <mbw> LiaoTao: Depending on what kind of data structures you use, this might be something that hlint can point you to as well.
18:34 dm3 joined
18:35 <LiaoTao> mbw: Haven't started using hlint yet! Maybe I should!
18:35 oisdk_ joined
18:35 <sbrg> LiaoTao: definitely. it's really nice.
18:35 <sbrg> also teaches you a lot of things if you're new to haskell.
18:35 <sbrg> or well, it can.
18:36 <torstein> In Hspec, is a spec item a "describe" or an "it" ?
18:36 <sbrg> LiaoTao: depending on your editor setup, you may be able to plug it in so that you get hlint suggestions on the fly, which is even nicer.
18:36 takle_ joined
18:36 <lyxia> torstein: it
18:36 tosun joined
18:37 <torstein> lyxia, is there a way to do a setup once for multiple "it"s ?
18:37 <LiaoTao> mbw sbrg Thanks for the recommendation
18:37 <LiaoTao> sbrg: I'll check out if there's vim support
18:37 <sbrg> LiaoTao: there is :)
18:37 <torstein> Like, load a database, then have different tests for checking different aspects of the database.
18:38 <sbrg> you can also get vim setup so that it shows you type errors on the fly as well.
18:38 <LiaoTao> That sounds nice
18:38 <torstein> Because according to the docs, a "before_" action is run before every Spec item, but I want multiple tests with a "before_" action that is only run once and that passes some parameter to the tests
18:40 connrs joined
18:41 primal joined
18:41 <mbw> LiaoTao: You might want to google Stephen Diel's vim setup guide.
18:42 <lyxia> torstein: runIO? https://hackage.haskell.org/package/hspec-core-2.4.3/docs/Test-Hspec-Core-Spec.html#v:runIO
18:42 <cocreature> can’t you use beforeAll for that?
18:42 tefter joined
18:43 <torstein> lyxia, thank you, that seems right
18:43 <lyxia> oh yes
18:43 <torstein> cocreature, I need the result from the IO action so beforeAll won't work
18:43 <cocreature> torstein: that’s what you get with beforeAll
18:44 <torstein> "f you do not need the result of the IO action to construct the spec tree, beforeAll may be more suitable for your use case."
18:44 sgflt joined
18:44 <torstein> I don't know the difference ...
18:44 <cocreature> “construct the spec tree” not “run your tests”
18:44 <cocreature> if I understood you correctly your spec tree, i.e., the tree of tests that you want to run is static
18:44 <cocreature> and you only want to pass dynamic data to each of those tests
18:45 <torstein> Yes that's right
18:45 <cocreature> then beforeAll seems like what you want
18:45 <torstein> it does i'll give it a try thank you
18:48 actualHuman_462 joined
18:49 oisdk joined
18:50 xcmw joined
18:51 takle joined
18:51 primal joined
18:52 coot____ joined
18:52 coltfred_ joined
18:53 gawen joined
18:55 zariuq joined
18:55 dm3 joined
18:56 primal_ joined
18:57 darjeeli1 joined
18:59 wroathe joined
18:59 dcoutts_ joined
18:59 xcmw joined
19:02 ragepanda joined
19:03 SkyPatrol_ joined
19:05 Herbstkind joined
19:05 texasmynsted joined
19:06 mstruebing joined
19:06 primal joined
19:07 jaziz joined
19:07 ziocroc joined
19:08 ragepanda joined
19:08 erisco joined
19:11 SpinTensor joined
19:12 mmachenry joined
19:14 primal_ joined
19:14 leshow joined
19:14 koserge joined
19:14 iAmerikan joined
19:15 hackebeilchen joined
19:15 <leshow> I'm looking at the definition for (!!) and can't quite figure it out
19:15 <leshow> http://lpaste.net/355682
19:15 <torstein> Is there any way to ignore the arguments from a beforeAll in Hspec when calling a spec? http://lpaste.net/355683
19:15 <leshow> how is it that foldr's lambda has 3 arguments, and foldr itself has 4
19:16 <Tuplanolla> :t foldr (.) id -- It's the same idea as in this, leshow.
19:16 <lambdabot> Foldable t => t (b -> b) -> b -> b
19:16 <byorgey> leshow: foldr is being used to compute a function
19:17 <leshow> Tuplanolla: I'm not sure I follow
19:17 CurryWurst joined
19:17 <byorgey> leshow: every function in Haskell has only one argument. But some return functions.
19:17 <leshow> with (const Nothing) as the arg for b i can see why foldr's lambda has an extra argument
19:17 <EvanR> data Rumsfeld a b = http://lpaste.net/355684
19:18 <erisco> I'll jump in and make it more confusing
19:19 primal joined
19:19 <erisco> leshow, lambdas have exactly one argument. they don't gain extra arguments or lose arguments
19:19 <leshow> I understand that f x y z is actually
19:19 ptvirgo joined
19:19 <leshow> f = \x -> \y -> \z ->
19:20 <leshow> but I still am not grasping how this specific thing works
19:20 <EvanR> f x y z is actually ((f x) y) z
19:20 <byorgey> leshow: right, and do you know that the expression g a b c is really ((g a) b) c ?
19:20 wroathe joined
19:20 <byorgey> leshow probably means f x y z = ... is f = \x -> \y -> \z -> ...
19:20 <erisco> wish that was true in all languages...
19:20 <leshow> byorgey: yeah sorry, forgot the equals
19:20 <byorgey> no worries
19:20 <leshow> let f x y z = ...
19:21 mmachenry joined
19:21 <lyxia> torstein: mapSpecTree
19:21 <byorgey> leshow: so do you know that g a b c is ((g a) b) c ?
19:21 <leshow> yes
19:21 <leshow> but how does that help
19:21 <byorgey> so if g a b c returns a function, then g a b c d is (((g a) b) c) d
19:21 <byorgey> it applies the function returned by g a b c to the argument d
19:22 <byorgey> leshow: in this case g = foldr
19:22 <erisco> well it sort of isn't in Haskell if you have multiple clauses
19:22 justanotheruser joined
19:22 <leshow> byorgey: oh are you saying in this case, foldr is producing a function, then n is being applied?
19:22 <byorgey> leshow: exactly
19:22 <leshow> ohhh
19:23 <erisco> :t id
19:23 <Tuplanolla> Look at the type signature again, leshow.
19:23 <lambdabot> a -> a
19:23 <erisco> :t id (+)
19:23 <lambdabot> Num a => a -> a -> a
19:23 <erisco> :t id (+) 1 2
19:23 <lambdabot> Num a => a
19:24 <erisco> :t id (+) `id` 1 `id` 2
19:24 <lambdabot> Num a => a
19:24 <leshow> it's still odd a bit to read I find
19:25 <erisco> specialising type variables to function types is not intuitive
19:25 <erisco> it takes some time to realise it
19:25 Oxit_ joined
19:26 <leshow> at a high level I get what we're saying. the play of (const Nothing) as the "argument" for b reads weird thouhg
19:26 tomphp joined
19:26 <leshow> I wouldn't come up with something like this myself
19:26 <EvanR> polymorphism begins simple until you take "any type" seriously
19:26 <Tuplanolla> You could've reinvented `ShowS` though, leshow.
19:27 <leshow> lol
19:27 <erisco> the simple way to understand foldr is just to look at how it expands
19:27 peterbecich joined
19:27 plutoniix joined
19:27 <erisco> > foldr f z [a,b,c]
19:27 <lambdabot> f a (f b (f c z))
19:27 grizwako joined
19:27 <erisco> you can literally view foldr as a builder of these expressions
19:27 <leshow> a regular foldr I don't find difficult, where the arguments are values
19:28 <leshow> when it's a partially applied function
19:28 <erisco> with that in mind, seeing how z might be itself a function is not as difficult
19:28 <Tuplanolla> > (shows 42 . (" * " ++) . shows 13) ""
19:28 <lambdabot> "42 * 13"
19:28 <erisco> leshow, functions are values
19:28 <Tuplanolla> > foldr (.) id [shows 42, (" * " ++), shows 13] ""
19:28 <lambdabot> "42 * 13"
19:29 <erisco> a big unlearning is how we're used to treating functions specially
19:29 primal joined
19:29 grizwako left
19:30 <lyxia> torstein: actually, I was looking at the low level interface again. aroundWith allows you to map Specs
19:30 <erisco> really they are completely ordinary in useful senses. for example they are values like any other, and the function type is like any other type constructor
19:30 <erisco> except extensions like RankNTypes and whatever
19:30 grizwako joined
19:31 <mniip> wut
19:31 <mniip> is it normal for cabal to spin at 100% cpu for a minute and consume 4G ram?
19:32 <monochrom> I think it is not normal. But I don't know.
19:32 <EvanR> you should not conflate forall with functions
19:32 flatmap13 joined
19:32 <mniip> correction, 9GB
19:32 <Tuplanolla> If you're installing Yesod, mniip.
19:32 <hexagoxel> mniip: during dependency resolution?
19:32 <erisco> I am just saying that it has a unique feature for functions, EvanR
19:32 <mniip> I don't know
19:32 <mniip> it seems like it doesn't matter what package I install
19:33 <mniip> oh huh
19:33 <mniip> it did finish
19:33 <mniip> after 10 GB of ram
19:33 <erisco> so, data types we construct with their data constructors and we deconstruct them by pattern matching
19:33 <monochrom> I'm OK with 100% CPU for a little while, but 9GB is too much (considering that I only have 3GB).
19:34 <mniip> I have 16 and a good swap hdd, but uh
19:34 <erisco> functions we construct with various syntaxes the language provides us and we're not allowed to pattern match them
19:34 flatmap1_ joined
19:34 <leshow> erisco: They may be equivalent in that sense, but evaluating mentally does become more complicated, at least for me, when many partially applied functions come into play. I feel like there's more to juggle with mentally when reading
19:34 robotroll joined
19:34 <erisco> but instead we have application, which still eliminates them but we don't get to look at the innards like we do data
19:35 peterbecich joined
19:35 <erisco> leshow, that is because when you see functions your mind goes into the mode that thinks about functions
19:35 <erisco> even though those details may not be relevant
19:35 codesoup joined
19:36 <erisco> I know this because, as you said, if this was some other type, such as Int, you'd have an easier time with it
19:36 mivael_ joined
19:36 primal_ joined
19:37 <erisco> well, the fact we're using functions doesn't actually make it any different
19:37 <leshow> Knowing that, at this stage, doesn't help that much though lol. I think it's just practice.
19:37 <erisco> how can I say that? because foldr didn't change
19:37 <EvanR> you can think of functions as taking arguments and holding onto an invisible context (the arguments already given, the lexical environment the lambda was in)
19:37 davr0s joined
19:37 <EvanR> thats pretty much like a data structure
19:38 <EvanR> an object
19:38 <monochrom> Yes, there is much practice involved when you try to change the way you think. For most people anyway.
19:39 <torstein> lyxia, That worked thank you. Had to do "aroundWith (\_ -> \_ -> return ()) myFunc"
19:40 wroathe joined
19:40 augur joined
19:41 dm3 joined
19:42 <byorgey> torstein: you can shorten that a bit by writing \_ _ -> return ()
19:42 cpup joined
19:42 <erisco> leshow, it's no problem. I have the same struggle... I suspect it is to do with Haskell not being my native PL, so to speak
19:42 CoderPuppy joined
19:42 dfeuer joined
19:42 Levex joined
19:43 <erisco> I have to wonder if people brought up on FP have the same difficulties in this area
19:43 <leshow> erisco, me too. I find they tend to do FP more on the euro side in school
19:43 <leshow> in NA it's all OO
19:43 <leshow> I'm in Canada, we did Java
19:44 <leshow> I had no idea how much bigger the PL spectrum was until I started learning on my own.
19:44 <erisco> when the back of your mind is thinking "functions do things" and your procedural and imperative intuitions begin to bubble...
19:44 <Tuplanolla> I don't have an issue with them, but only because I've spent so much time wrangling the various instances of `(a ->)`.
19:44 <erisco> it becomes difficult to see the picture where you're just constructing something
19:45 <erisco> we don't "lists do things", we just construct them
19:45 <Tuplanolla> They're my favorite simple thing in Haskell.
19:45 <erisco> we don't think*
19:46 <EvanR> functions are an immutable data structure with one operation, apply. simple!
19:47 primal joined
19:47 <leshow> Monads are just like burritos, simple!
19:47 <Tuplanolla> Like that thing torstein mentioned I would've written `pure (pure unit)`.
19:47 <erisco> and tasty
19:49 nickolay_ joined
19:49 tromp joined
19:50 <erisco> leshow, I am in Canada too and though there was an intro course that used Miranda the focus in later years was Java
19:50 Levex joined
19:50 <leshow> For what program? It seemed like all the software engineering programs in Ontario did Java, then a few years later switch to Python
19:51 <EvanR> my uni went from C to Java
19:51 <erisco> the program was Computer Science ;)
19:52 <erisco> on one hand I understand they want to be industry relevant
19:52 <torstein> there's no Haskell in Norway at least. The advanced programming course used Oz; a academic mix match language with imperative, functional, procedural and dataflow variables
19:52 <lyxia> torstein: uh I'm not sure you're supposed to throw away the first argument
19:52 xPaw1 joined
19:52 <erisco> on the other, if that were true, I have to wonder why half our classes weren't JavaScript and web dev
19:52 gehmehgeh joined
19:52 <EvanR> erisco: give it time
19:53 <erisco> by the time JavaScript is phased out, or the prevalence of web diminishes, that is when the Universities will switch over
19:53 <torstein> isn't JS here to stay forever?
19:53 <erisco> to keep up the tradition of 20 years lag time :
19:53 Levex joined
19:54 <EvanR> somebody needs to tell these chairpeople that computer science is not the same thing as "how to get a job 3.5 years ago"
19:54 <erisco> maybe it is unintentional revenge for the industry lagging 20 years behind research
19:55 soLucien joined
19:55 <ptvirgo> Is there an HUnit equivilant to 'python -m unittest discover,' or do you have to load the ghci every time you want to run your tests?
19:55 oish joined
19:56 grizwako joined
19:56 <leshow> It is kind of disappointing to me that uni's churn out CS and S.Eng students, myself included, that know almost nothing about PL theory
19:56 <leshow> or type theory
19:57 <erisco> the true problem with trying to be industry focused in uni is that, well, look at who is teaching
19:57 chaosmasttter joined
19:57 <erisco> researchers, not day job programmers
19:57 <EvanR> im ok with that
19:58 pookleblinky joined
19:58 <EvanR> i dont need handlebars or whatever latest js template language impressed upon me by the professor
19:58 <[exa]> what's wrong about day job researchers? :]
19:59 <leshow> If anything I'd like to see more research stuff be taught at schools, at least then you can learn the things that will be used over the next decade
19:59 mstruebing joined
19:59 <leshow> and not just learn things tha twill be obsolete when you graduate
20:00 <erisco> I just want them to teach what they're excellent at, and I'll learn the trade of programming from someone else
20:00 <torstein> lyxia, You're right, i think it might be "aroundWith (\a _ -> a ()) myFunc" instead
20:00 <EvanR> right, university CS vs trade school
20:00 <erisco> I dunno... I've just had embarrassingly poor "software engineering" courses
20:00 Levex joined
20:01 wroathe joined
20:02 <Tuplanolla> The best part about programming courses at the university was pointing out errors in C programs by citing N1570.
20:02 <sproingie> oz is a funky little language. did the course use CTM?
20:02 <DSM> Does anyone know of a library with good automated test coverage? I'm trying to figure out how I should setup and organize tests and an example would be useful
20:03 Lynxium joined
20:04 <torstein> sproingie, Yep. Course instructor said it was THE book on Oz, though it probably was the ONLY book
20:04 <sproingie> DSM: lens has a pretty good number of tests
20:04 <sproingie> torstein: pretty much. i'd definitely call it a "teaching language", tho there was some attempt at an industrial-strength thing on top of oz way back
20:05 <erisco> leshow, I didn't take grad school because all I wanted to focus on was PL theories and the offering was too dilute
20:05 <sproingie> called Alice I think, more ML-ish than mozart
20:05 psychicist__ joined
20:06 <leshow> erisco: I didn't even know that kind of thing existed, I just rushed out and got a job. Then started discovering all these wonderful languages over the last 3 or 4 years
20:06 <erisco> imagine it varies school by school just based on the faculty
20:06 <erisco> we had one prof who was deep in Haskell and as far as I could tell, or knew, the others were at most just interested in it
20:07 <erisco> well, not saying Haskell encompasses FP, but it is a hard language to miss
20:07 <leshow> it also tends to bleed into modern languages over time
20:07 <ggVGc> any sufficiently complete implementation of FP contains a full haskell compiler
20:08 <ggVGc> isn't that how the saying goes?
20:08 <[exa]> erisco: anyway, could you elaborate about what was embarrasingly poor on that S.Eng course? (kindof interested for I'm teaching too)
20:08 <EvanR> that would make ghc complete
20:08 <EvanR> or sufficiently complete
20:08 <sbrg> any FP implementation that doesn't contain a full haskell compiler is not sufficiently complete
20:08 <leshow> [exa]: I think he said he was in CS
20:09 <erisco> [exa], sure. We studied waterfall and agile methods out of a text book and were tested on what the text book said
20:09 <EvanR> can it be a adhoc informally specified bug ridden slow haskell compiler?
20:09 <leshow> sbrg: sounds like a no true scotsman lol
20:09 CurryWurst joined
20:09 <[exa]> erisco: oh so. So nothing in common with software engineering. :D
20:09 <leshow> erisco: I had one of those too
20:09 abroz joined
20:10 bendo joined
20:10 <leshow> It's all the same, I was just correcting lol.
20:10 <[exa]> best course about software engineering I had was called something like "recommended practices in programming"
20:10 <ph88> i need some help with conduit, i have a (Maybe Double) there in my type but i don't know what to do with it https://bpaste.net/show/9af835644e1d
20:10 <erisco> [exa], nadda. No practicum. Not even a group essay to write.
20:11 pranitbauva1997 joined
20:11 takle joined
20:11 <[exa]> the course was basically about doing reasonably one assignment, and then modifying several other people's assignment result for new functionality
20:11 phyrex1an joined
20:11 <[exa]> taught me about getting burnt
20:11 <erisco> haha, that's smart
20:11 <erisco> lets you experience the full range of coworkers you'll have in the future :P
20:12 <erisco> and instruct you brutally as to what kind of code you'll want to hand over to others
20:12 <[exa]> learning stuff from books is great for formal logic, not for agile tribesmanship
20:13 <[exa]> we also had a formal course about software testing
20:13 <[exa]> it was led by one of the smartest people from the faculty
20:13 geekg_000 joined
20:13 carlomagno joined
20:13 <erisco> leshow, UoW? Waterloo?
20:14 <leshow> when I think about school I barely even remember any of the actual on topic courses, I just remember the calculus, physics, stuff like that
20:14 <leshow> I'm in Ottawa, Carleton
20:14 <[exa]> started with gödel, and rest of the course were fun examples of what tests can't expect
20:14 <erisco> ah ha
20:14 Bassetts joined
20:15 <EvanR> classic
20:16 <erisco> job interview... "so are you familiar with unit testing?", "yeah", "what coverage did your last project have?", "well, none, but I formally proved all the tests I couldn't write"
20:17 sigmundv__ joined
20:17 wildlander joined
20:18 <leshow> https://aphyr.com/posts/342-typing-the-technical-interview
20:18 <leshow> this has to be one of my favorite blog posts
20:18 buglebudabey joined
20:19 ph88_ joined
20:19 oish joined
20:21 hexfive joined
20:22 wroathe joined
20:22 <erisco> I kinda like them when they're five miles over my head
20:22 <erisco> that one is a bit too understandable for me
20:23 <erisco> needs moar CT :P
20:23 ompaul joined
20:25 ccomb joined
20:26 fotonzade joined
20:26 pookleblinky joined
20:26 <leshow> ah well any further and I wouldn't get the jokes
20:26 peterbecich joined
20:27 primal_ joined
20:27 <erisco> you begin with a simple problem with an easily verifiable solution
20:28 baldrick1 joined
20:28 <erisco> in the middle you insert advanced and niche theory
20:28 <erisco> so it works as a magic show where the audience knows the premise and result but can't figure out what made it happen
20:28 sepp2k1 joined
20:29 takuan joined
20:29 <erisco> and also attractive is that you can learn and peel away the mysteries, if you want to
20:29 pera joined
20:33 <suzu> anybody have experience using snap without heist?
20:33 nilof joined
20:34 <dmj`> suzu: yea
20:35 <erisco> for example... the premise is user interaction with a program... the result is a GUI... I can't figure out the middle
20:37 <suzu> dmj` how can i use a splice without heist?
20:37 Waynes joined
20:37 mstruebing joined
20:38 <dmj`> suzu: I don’t think you can since type Splice n = HeistT n n Template
20:39 <suzu> hmm crap
20:39 <suzu> so using all of snap-extras is out of the question
20:39 <suzu> i'm currently using lucid. ive not used heist before
20:39 <suzu> is it worth switching everything oveR?
20:39 <suzu> over *
20:40 <dmj`> suzu: what are you trying to build?
20:40 fotonzade joined
20:40 abroz joined
20:40 jerbome_ joined
20:41 <suzu> i'm building a web application
20:41 <suzu> i was hoping to get csrfs and recaptcha and such for free
20:41 <shapr> What framework are you using?
20:41 <suzu> snap
20:42 <shapr> have you checked the #snapframework channel? ( I think that's the name )
20:42 <suzu> nope
20:42 <dmj`> suzu: just snap-core and snap-server? Or snap, which re-exports both.
20:42 <suzu> snap, with the re-exports, so i can get snaplets
20:43 dogweather joined
20:45 bennofs joined
20:45 <dogweather> Adding modules to the cabal file: best practice? I'm seeing that it's a lot of redundancy
20:45 user___ joined
20:45 <glguy> The best practice is to add them so that your package functions
20:45 anderson joined
20:45 <glguy> There shouldn't be any redundancy, you only need to add them once
20:46 <dogweather> glguy: I refactored some functions out to a new file, but didn't add it. I get a warning, but my tests still pass
20:46 <dmj`> suzu: it might be worth it
20:46 <suzu> hmm, yeah guess i need heist if i want to use splices.
20:46 <suzu> i was already so comfy with lucid
20:46 <glguy> dogweather: When you create a source tarball via 'cabal sdist', those modules will be missed
20:46 <suzu> :(
20:46 <dogweather> Ah hah!
20:47 <dogweather> I've been deploying by doing git clone ; stack build.
20:47 <dmj`> suzu: you could just use the session id as the csrf token though, if you’re already using snap’s auth, and embed that into the template. A little manual work.
20:47 <suzu> yeah so i could manually implement these things and avoid heist
20:48 <dmj`> suzu: right
20:48 <suzu> but then its a matter of which is less work: rolling my own extras, or porting heist?
20:48 <dmj`> suzu: how many templates do you have
20:48 <dogweather> This is application-level code; maybe it's not so necessary. FWIW, I'm finding that I need to add each filename (module) twice to the cabal file: `other-modules` in the executable and test-suite sections
20:48 <suzu> just two, so far
20:48 <suzu> so it might not be too much trouble
20:49 cpennington joined
20:49 GamboPango joined
20:49 <dmj`> suzu: alternatively, you could try servant.
20:49 darjeeli1 joined
20:49 fnurglewitz joined
20:50 <suzu> hmmm
20:50 <suzu> servant for a full-stack web application..?
20:50 tromp joined
20:50 <suzu> i had thought it was an api framework
20:51 <glguy> dogweather: If you're adding modules to multiple sections, that means you've misconfigured your source directories
20:52 <dogweather> glguy: !! Interesting - i'll look into that
20:52 <glguy> dogweather: each section should have its own hs-source-dirs:
20:52 <glguy> and those should be different
20:53 <actualHuman_462> The thing about full-stack web apps is that the stack is built from components.
20:53 dm3 joined
20:54 <suzu> right
20:54 <dmj`> suzu: no reason why servant can’t deliver html, handle sessions, auth, etc.
20:54 <dogweather> Huh, I have `app, src`, and `test, src` - orig. set up by Stack. https://github.com/dogweather/nv-statutes-haskell/blob/chapter-details/nv-statutes.cabal
20:54 <suzu> so you're saying i could just layer stuff on top of servant
20:54 <dogweather> I appreciate any advice!
20:54 justan0theruser joined
20:54 <suzu> i guess that'd work
20:54 sellout- joined
20:54 <suzu> but then i'd need to roll a lot more things myself than if i continue with snap without heist
20:55 <glguy> dogweather: the library's source directory should be separate from the executable
20:55 <glguy> dogweather: same for the test suite
20:55 <actualHuman_462> Note that rolling your own may or may not be more work depending on the scale of what you're trying to accomplish
20:55 pip joined
20:56 <actualHuman_462> Frameworks in general tend to save you effort if and only if what you're doing hits the scale that they're targeted at
20:56 <dogweather> ok, I'm never really building the library. Can I ignore it and just straighten out the executable and test-suite sections?
20:56 <suzu> hmm
20:56 <suzu> i see
20:56 <dmj`> suzu: it’s a double-edged sword, suppose you need to do something custom with your authentication, you’d have to fork snap’s auth package and modify it.
20:57 <glguy> dogweather: all of the interesting stuff should be in your library, the executable should be a shim that uses the library
20:57 <glguy> and the test suite should only test the library
20:57 primal joined
20:58 <dogweather> ah hah, yeah, that'd be good architecture. Currently I don't even have the executable code; i guess i've been doing lib dev but in the executable environment
20:58 twanvl joined
20:59 DanielMayz joined
21:01 <glguy> OK, well if you fix that then you'll have less redundancy
21:01 <glguy> and fewer recompiles
21:02 <ph88> i would like some help with conduit, i have a (Maybe Double) there in my type but i don't know what to do with it https://bpaste.net/show/9af835644e1d
21:02 abhiroop joined
21:02 <athan> Is forking a long-running process like `_ <- async $ forever $ ..` dangerous, because the thread could get GC'd?
21:03 <glguy> no
21:04 <dogweather> thanks glguy
21:04 <athan> hm. I read on EZYang's blog that "blocked indefinitely in an STM transaction" exceptions can be caused by threads getting collected, but I'm not exactly sure what I'm doing ._.
21:04 wroathe joined
21:05 ErinvanderVeen joined
21:06 <lyxia> ph88: use runConduit instead of sourceToList
21:07 <lyxia> ph88: $$ would be even shorter
21:07 <ph88> ah ye that was it !
21:07 <ph88> lyxia, i thought $$ was deprecated
21:08 <ph88> https://github.com/snoyberg/conduit#legacy-syntax The $$ operator is a combination of runConduit and .|
21:08 <ph88> that's why i stopped using it
21:09 <lyxia> oh, okay. Well there's still runConduit
21:10 buglebudabey joined
21:10 <ph88> lyxia, why was i getting (Maybe Double) there actually ? shouldn't the type be something with a list since i was using sourceList ?
21:10 halogenandtoast joined
21:12 <lyxia> ph88: you didn't have a Source, as the error indicates. Source m a = ConduitM () a m ()
21:12 quobo joined
21:12 bennofs joined
21:13 MarioBranco joined
21:13 <ph88> lyxia, src was on line 13 in paste .. what do you mean ?
21:13 <lyxia> ph88: apart from the type, getAverageSampleInterval doesn't send anything downstream, so blabla doesn't either
21:14 <lyxia> ph88: sourceToList is being applied to blabla, not src.
21:14 <ph88> getAverageSampleInterval is suppose to be the sink
21:14 <ph88> ooohh right
21:14 <ph88> anyway it type checks now ^^
21:15 <vimalloc> Hey guys :) I got some help from this lovely community a week or so ago about a bridges game solver I'm building (first thing I've really done in haskell). I refactored a bunch of stuff, and it now looks like this: https://gist.github.com/vimalloc/3e3ec5f37ca5a1d60ce474996b788c26
21:15 <vimalloc> would anyone want to give it a quick glance through, and let me know if anything looks bad right off hand?
21:16 <vimalloc> (bridge game in question is this: http://www.puzzle-bridges.com/)
21:16 sproingie joined
21:17 buglebudabey joined
21:17 <lyxia> ((...) == False) is not (...)
21:18 <vimalloc> thx
21:19 <lyxia> fromJust $ ... <|> Just ' ' is fromMaybe ' ' $ ...
21:19 <lyxia> Overall it looks good though
21:19 <vimalloc> doh! I was even looking at fromMaybe in an earlier iteration. Thanks!
21:20 e14 joined
21:20 <lyxia> it's nicely indented
21:20 <vimalloc> The joys of coming from a python background :P
21:21 abroz joined
21:21 cpup joined
21:21 CoderPuppy joined
21:21 mjora7 joined
21:21 <dmj`> vimalloc: you can take advantage of the fact you’re in the Maybe monad
21:22 <dmj`> and use the guard function, instead of guards, and maybe foldM, could be interesting
21:22 <dmj`> in bridgeAtPoint
21:22 <lyxia> line 125 is "asum" of something
21:23 <vimalloc> Ah, I just read about the guard function the other day, but didn't think about how they would apply here. I will refresh myself on that
21:24 <lyxia> vimalloc: you could define Point and Island as records
21:25 wroathe joined
21:25 <vimalloc> That's a good idea. Would clear out some of those 'get' functions
21:25 <dmj`> > Just 4 >>= \x -> do { guard (x > 4); pure x; }
21:26 <lambdabot> Nothing
21:26 koserge joined
21:27 abhiroop_ joined
21:28 refold joined
21:29 darjeeli1 joined
21:29 <vimalloc> This community is awesome. Thanks for all the suggestions :)
21:29 primal_ joined
21:29 juanpaucar joined
21:31 pie_ joined
21:31 malt3 joined
21:33 pie_ joined
21:33 augur joined
21:34 <Boomerang> vimalloc: Why don't you make Point and Island records? This would create all the getter functions for you. data Point = Point { getX :: Int, getY :: Int } deriving ...
21:34 Khisanth joined
21:35 <vimalloc> lyxia said the same thing. I'm going to change it to that.
21:35 saussure joined
21:37 abroz joined
21:37 <Boomerang> Oh yeah, missed that. Sorry :/
21:37 <vimalloc> Oh, no worries at all!
21:38 moth joined
21:39 primal joined
21:39 mr_sm1th joined
21:39 mjora7 joined
21:44 dcoutts_ joined
21:45 [[[[[ExTRa]]]]] joined
21:45 connrs joined
21:45 Heedypo[m] joined
21:46 wroathe joined
21:47 bjz joined
21:49 primal_ joined
21:49 {emptyset} joined
21:51 quobo joined
21:51 <lambdamu_> inline-c is really nice to beat awful c apis into submission
21:52 <lambdamu_> code looks abominal but that was to be expected
21:53 hiratara joined
21:53 Heedypo[m] left
21:57 baldrick1 joined
21:59 nuclx joined
22:00 saussure joined
22:01 ludat joined
22:03 epsilonhalbe joined
22:04 OnkelTem joined
22:04 bigos joined
22:06 asm_ joined
22:08 nandub joined
22:11 sproingie joined
22:11 ystael joined
22:14 <scav> Are there no feature complete JWT libraries for Haskell?
22:15 <sproingie> there's the JWT package. seems to be missing RSA, otherwise seems to have everything.
22:15 <sproingie> s/JWT/jwt/
22:16 <scav> thats web.jtw?
22:17 <sproingie> ew, it doesn't verify exp. easily enough done after the fact i guess.
22:17 <scav> yeah, it has a couple of limitations, which is why i was curious :)
22:17 <scav> but that should be quick to fix anyway
22:19 cpennington joined
22:20 spacecadetbrown joined
22:20 <ph88> hey guys a question about syntax https://bpaste.net/show/4ac98a1c8feb
22:20 justanotheruser joined
22:22 <ph88> i updated my paste a little https://bpaste.net/show/a97d9fead846
22:23 <reactormonk[m]> ph88: "Just tcol"
22:23 <ph88> where ?
22:23 <jle`> instead of tcol
22:23 crobbins joined
22:23 <reactormonk[m]> In the function declaration. You want to extract the value.
22:24 <reactormonk[m]> It's not just a syntax question, it's also a semantics one - you want to prove to the compiler the value will be there.
22:24 <jle`> convert (Options fin fout vcol (Just tcol) (Just st) rs p swv) =
22:24 <ph88> but then the case where one of the two is Nothing won't be covered ..
22:24 dan_f joined
22:24 <jle`> how would you want to handle that case?
22:24 <jle`> it's not clear
22:25 <reactormonk[m]> Yup.
22:25 <jle`> looks like an issue with your logic
22:25 <ph88> look at the case statement line 6 to 10
22:25 <ph88> :(
22:25 <jle`> ah, sorry, was looking at the first link
22:26 takle joined
22:27 safe joined
22:27 <threshold> recommended way of creating migrations in a sql database?
22:27 <ph88> here is the actual code as from my file https://bpaste.net/show/b2f202262216
22:27 jship joined
22:27 wroathe joined
22:28 <threshold> postgresql is the database being used
22:28 <ph88> threshold, i thought there was something about that in persistent
22:28 <jle`> you can just handle all of it in a single case, can't you?
22:28 albertus1 joined
22:28 <Boomerang> ph88: If you know a state is impossible tcol and st being both Nothing, try to model your data so it is impossible for you to represent it. You could make a custom data type of use something like These https://hackage.haskell.org/package/these-0.7.3/docs/Data-These.html
22:28 <threshold> ph88: i will look at it. thank you
22:28 <Boomerang> s/of/or
22:28 primal joined
22:29 spacecadetbrown joined
22:30 <Boomerang> Oh wait I didn't take into account the previous line that handle Nothing and Nothing, two Maybes may be an appropraite model
22:31 hiratara joined
22:32 <lpaste> jle` pasted “convert” at http://lpaste.net/355691
22:32 <lpaste> jle` pasted “convert” at http://lpaste.net/355692
22:32 <jle`> oops sorry
22:32 <jle`> ^ ph88
22:32 kamog joined
22:33 <ph88> thx
22:33 other_spacecadet joined
22:33 cloudhead joined
22:34 juanpaucar joined
22:34 <ph88> <|> is in maybe applicative context ?
22:35 <reactormonk[m]> <|> is Alternative
22:36 uglyfigurine joined
22:39 primal_ joined
22:40 wayne joined
22:40 ChaiTRex joined
22:41 byte512 joined
22:42 jerbome_ joined
22:44 flatmap13 joined
22:44 <mniip> int-e, you said it takes lambdabot a second to parse interface files?
22:44 <mniip> takes 8 seconds here...
22:45 <jle`> ph88: for <|>, it's "pick the first Just"
22:46 <jle`> for Maybe, i mean
22:46 mjora7 joined
22:46 epsilonhalbe left
22:49 wroathe joined
22:52 tromp joined
22:53 SeMas joined
22:57 juanpaucar joined
22:59 alveric2 joined
23:03 alveric3 joined
23:03 <threshold> is there an example of how to use persistent-postgresql?
23:03 Hunter1 joined
23:04 thimoteus joined
23:05 paulnoise joined
23:09 <nilof> The IO type has no constructor, is this compiler magic or are there more HKT's that behave like this?
23:10 <glguy> nilof: The IO type has a constructor, but that constructor is not exported. No magic
23:10 prkc joined
23:10 wroathe joined
23:10 <glguy> nilof: Also you can declare "empty data types" that actually have no constructors
23:12 abroz joined
23:13 meba joined
23:13 halogenandtoast joined
23:14 <nilof> Like for example GADT's with constructors that are specialized to specific types, so that the GADT type with some type parameters will be empty?
23:15 <pikajude> nilof: if you enter :i IO in ghci it'll even tell you what the constructor is called
23:16 Rotaerk joined
23:19 saussure joined
23:20 paulnoise left
23:20 ystael joined
23:21 iAmerikan joined
23:23 <hpc> nilof: /eventually/ there is magic (and if your perspective is strictly based on the spec any IO implementation is magic)
23:23 <hpc> nilof: the comments around the IO type and the stuff it's made up of have a good explanation of some of it
23:26 fotonzade joined
23:31 yrdz joined
23:33 theDon_ joined
23:34 markus1189 joined
23:34 markus1199 joined
23:35 wroathe joined
23:36 fragamus joined
23:42 nakal joined
23:43 uglyfigurine joined
23:43 jerbome_ joined
23:45 darjeeli1 joined
23:48 jacereda joined
23:49 nomotif joined
23:49 Gurkenglas joined
23:52 socrabot joined
23:58 Nicmavr joined
23:58 infinity0_ joined
23:59 infinity0_ joined