<    April 2017    >
Su Mo Tu We Th Fr Sa  
 2  3  4  5  6  7  8  
 9 10 11 12 13 14 15  
16 17 18 19 20 21 22  
23 24 25 26 27 28 29  
00:02 <hpc> i always thought free breakfast was more satisfying
00:04 <monochrom> Haha neat, this coincides with how you can grow array size and still get amortized O(1) time. You need one more bit for your IDs right when you need to double your array size. How neat is that.
00:05 <monochrom> I want free steak dinner.
00:07 {emptyset} joined
00:08 <julianleviston> I have a few questions about dynamic context “introspection”: is there a way I can determine a list of the available declarations and their types within a particular point in the source? I’ve done a fair bit of research into this area in that I’ve looked at and used hint, Language.Haskell.Exts and Control.Lens quite a bit, and had a look into Dynamic. So I know I can get a list of the exports of a module with
00:08 <julianleviston> for example. This ends up being [String], and I could coerce that to [Dynamic], but I’m not sure how I’d get *local* (this-module/this-file/within-this-function) declarations, also this brings me to my subsequent question… (which I’ll provide after this one)
00:10 Avogadro joined
00:10 iqubic joined
00:11 <iqubic> Hello everyone.
00:12 filterfish joined
00:13 vaibhavsagar joined
00:14 biglambda joined
00:15 raynold joined
00:15 takle joined
00:16 acarrico joined
00:17 <julianleviston> Once I have these declarations, I’d like to filter them to determine which ones *could* be put into a lensed focus, which is where things get *really* tricky, because a) I don’t know how to filter [Dynamic] based on type, and b) I’d have to match on the *return* type, so I can’t do this statically with AST (AFAIK). Also I have the issue that things would have to be an instance of Typeable, so no polymorphic
00:17 <julianleviston> declarations… so that stickies things up a lot.
00:17 <julianleviston> I might put this up on stack overflow...
00:23 MrRicecake joined
00:24 <Gurkenglas> julianleviston, Dynamic is internally just a runtime representation of a type and a magic Any value that allows coercion. A function type's TypeRep contains its argument and result type's TypeReps like any other datatype does it.
00:24 <julianleviston> Gurkenglas: Ooh… I’ve never even *heard* of TypeRep before.
00:25 <julianleviston> Is there also such a thing for non-function values?
00:26 <c_wraith> see Data.Typeable
00:26 <julianleviston> Ah it’s part of Data.Typeable
00:26 <julianleviston> Ok so that’s why it won’t work with non-concrete types.
00:26 <Gurkenglas> "data Dynamic = Dynamic TypeRep Obj" "splitTyConApp :: TypeRep -> (TyCon, [TypeRep])"
00:26 <julianleviston> very cool… (:~:)
00:27 <geekosaur> also note that this is changing in 8.2.1 (try rc1 which is out now) in a way you might like
00:27 <c_wraith> if you need to represent a polymorphic type, wrap it in a monomorphic newtype
00:28 <julianleviston> yeah I knew I could do that, thanks :)
00:28 kylepotts joined
00:28 indi_ joined
00:28 <julianleviston> ^ c_wraith sorry that was directed at you.
00:30 <julianleviston> Any answer to my actual first question tho? As in… How I could possibly get *local* declarations? Is the answer just to wrote it to a module and import it then get the exports using hint like that? I think that’d work, actually.
00:30 <julianleviston> also really not sure how to do this *inside* a function, but possibly that might be able to be done via traversing the AST and evaluating inner declarations with a new scope in hint… mmm
00:30 dijonmustard joined
00:32 <Gurkenglas> "data S = forall a. S { worker :: a -> M (); jobs :: [a] }" <- I want to allow the user to supply code for a new worker (b -> M ()) and a morphism (a -> b) at runtime, and check whether the types match. What eval library should I use, and can this existential approach work?
00:34 takle joined
00:34 <dijonmustard> So I'm wondering if my solution to generalizing access to a field was the right way to go about it. Can anyone chime in? It's pretty simple. https://pastebin.com/xySV6bKi
00:34 fermi_ joined
00:35 <Gurkenglas> (And is it just me or does System.Eval.Haskell not work at all, instead crashing at runtime complaining about GHC_PACKAGE_PATH when you try to use its eval?)
00:35 xcmw joined
00:36 darjeeling_ joined
00:38 <julianleviston> Gurkenglas: I’ve only used hint, I think.
00:38 <julianleviston> Gurkenglas: works really well.
00:38 <Gurkenglas> dijonmustard, lens solves this problem. http://lpaste.net/3683558570902683648
00:39 nicknovitski joined
00:40 Welkin joined
00:41 hexfive joined
00:41 <iqubic> Gurkenglas: Shouldn't that read MakeLens?
00:42 mjhoy joined
00:42 <iqubic> And what is the type of HasPosition?
00:42 <Gurkenglas> iqubic, makeLenses doesn't make typeclasses for it, so doesn't allow multiple both Person and Enemy to use position
00:43 <iqubic> So what does MakeField do?
00:43 <dijonmustard> wait, so does makeFields automatically generator typeclasses or something?
00:43 <iqubic> dijonmustard: You need to use the language pragma TemplateHaskell for that to work I think.
00:44 <dijonmustard> right, so is this just essentially generating my original code at compile time?
00:44 <iqubic> Yes.
00:44 <iqubic> It it is.
00:44 <iqubic> It is also making it easier to read.
00:45 <julianleviston> dijonmustard: it’s template haskell. It uses haskell to write boilerplate for building lenses for field access.
00:45 <iqubic> Gurkenglas: What the heck does makeFields do?
00:45 <dijonmustard> So lenses aside, my solution was correct?
00:45 <iqubic> Yeah, I think so.
00:45 <iqubic> Not too sure though.
00:45 <julianleviston> dijonmustard: looked good to me.
00:45 splanch joined
00:46 <iqubic> Gurkenglas: What does it mean for something to of type hasPosition?
00:46 <julianleviston> dijonmustard: typeclasses are pretty powerful, though, so might not wanna reach for them all the time straight away
00:47 bhiliyam joined
00:47 takle joined
00:47 <julianleviston> lenses are really nice because they compose (you can focus deeper on things when you have complex structure), and by making something a lens, you get all the general functions within the lens library (getters, setters, “over” which runs a function on the focussed thing, and many other things like `+=` etc)
00:48 <Gurkenglas> Oh shoot, makeFields makes "HasPosition Person Position" and "HasPosition Enemy Position". Is there a way to do that without the addition Position argument everywhere?
00:48 <julianleviston> dijonmustard: anytime you say “generalized access”, most Haskellers are going to say “lens”.
00:48 <iqubic> I still don't understand the difference between makeLenses and makeFields.
00:49 <Gurkenglas> iqubic, http://hackage.haskell.org/package/lens-4.15.1/docs/Control-Lens-TH.html
00:50 <dijonmustard> Okay cool. template haskell will be my next step.
00:50 <puregreen> iqubic: docs for microlens have longer explanations for makeLenses and makeFields so you could try reading those: http://hackage.haskell.org/package/microlens-th-, http://hackage.haskell.org/package/microlens-th-
00:50 <puregreen> in a nutshell, `makeFields` generates a class for each field name
00:50 <iqubic> What does makeClassy do?
00:51 umib0zu joined
00:51 <Gurkenglas> hint seems to require a witness of the type I want to create. Can I get out of the "data S = forall a. S { worker :: a -> M (); jobs :: [a] }"?
00:51 <Gurkenglas> *that
00:52 sanett joined
00:52 <puregreen> iqubic: makeClassy generates a class for each record type, not each name, and lets you do a kind of subtyping
00:52 <puregreen> it's the most complicated one to explain
00:53 <iqubic> What does that mean? If i have a record with 7 fields of different types, I get 7 different type classes?
00:53 morphit joined
00:53 <puregreen> with makeFields you get 7 different type classes even if all fields have the same type
00:53 <puregreen> with makeClassy you get one type class with 7 methods
00:53 Jeanne-Kamikaze joined
00:54 <iqubic> I don't understand, but that's fine
00:54 <puregreen> okay, another example: if you have “Foo {fooX, fooY :: Int}” and “Bar {barY, barZ :: Int}”, you'll get three type classes with makeFields: “HasX”, “HasY”, “HasZ”
00:55 <puregreen> because there are three different names after you throw away prefixes
00:55 <puregreen> Foo will be an instance of HasX and HasY, Bar will be an instance of HasY and HasZ
00:55 <puregreen> is this clear so far?
00:59 <iqubic> Yeah, I got it.
01:00 <iqubic> I see why people say Haskell is the best imperative language.
01:00 ChaiTRex joined
01:01 <julianleviston> Gurkenglas: sounds pretty tricky… have you tried TH?
01:02 <Gurkenglas> How'd that help?
01:02 <julianleviston> Gurkenglas: I’m not sure why hint’s interpreter woudln’t work with what you’re trying to do, though.
01:03 umib0zu left
01:03 <Gurkenglas> How does hint know what type to read "flip replicateM someaction :: Int -> M ()" as?
01:04 halogenandtoast joined
01:04 <dijonmustard> So trying to get Gurkenglas example of lenses to compile and as they said earlier 'makeFields makes "HasPosition Person Position"'. Can someone explain this to me?
01:04 splanch joined
01:05 <Gurkenglas> Well, it's going to work with http://lpaste.net/3683558570902683648#a354599 but that's ugly so the question remains
01:05 <Gurkenglas> (And you could do type Positional a = HasPosition a Position, but still)
01:06 <dijonmustard> what does that even mean to pass a type into a function?
01:06 takle joined
01:06 <dijonmustard> is it someone specifying some polymorphic type?
01:06 <julianleviston> dijonmustard: where are you passing a type into a function?
01:06 eacameron joined
01:07 <dijonmustard> oh nevermind, I just got it
01:07 <geekosaur> dijonmustard, thats a typeclass
01:07 <julianleviston> Gurkenglas: I haven’t really used hint like that. I build an expression as a string and then have it evaluate it and grab the result I’m after out and use that elsewhere. I guess it depends where the lines you’d like to draw in terms of evaluation are.
01:07 <geekosaur> instance
01:07 <dijonmustard> HasPosition Person Position is the typeclass with specified types
01:08 <julianleviston> dijonmustard: `HasPosition Person Position` is a type, isn’t it?
01:08 Khisanth joined
01:08 <dijonmustard> yeah
01:08 <dijonmustard> makes sense
01:09 <mniip> constraindkinds!
01:09 <julianleviston> dijonmustard: oh sorry, I’m not sure what I’m talking about - I didn’t check what HasPosition was.
01:13 pera joined
01:13 ericmathison joined
01:13 takle joined
01:24 michbad joined
01:26 sleffy joined
01:28 eacameron joined
01:29 gcross_ joined
01:30 cmsmcq joined
01:33 kylepotts joined
01:38 seekr_ joined
01:38 lambda-11235 joined
01:41 texasmynsted joined
01:43 wroathe joined
01:43 mjhoy joined
01:44 Guest10946 joined
01:44 revprez_atlanta joined
01:44 Guest10946 left
01:44 Supersonic112_ joined
01:45 heurist joined
01:48 bhiliyam joined
01:50 <seekr_> I'm trying to get GHC working in Windows 10, but the recently released Windows 10 Creators Update broke GHC. issue: https://ghc.haskell.org/trac/ghc/ticket/13411 . The link mentions a patched GHC, but I don't see where I can get it.
01:54 watabou joined
01:56 minn joined
01:56 Sgeo__ joined
01:57 Goplat joined
02:00 hucksy_ joined
02:00 ExcelTronic joined
02:01 filterfish joined
02:01 filterfish_ joined
02:05 cow_2001 left
02:06 halogenandtoast joined
02:08 harfangk joined
02:08 <geekosaur> http://downloads.haskell.org/~ghc/8.0.2/ghc-8.0.2-x86_64-unknown-mingw32-win10.tar.xz but it's still experimental I think
02:08 <geekosaur> (name may change so don't save a link to anything but that dir... they were still hashing this out within the past day)
02:11 ebzzry joined
02:12 e14 joined
02:14 ghc joined
02:15 ghc left
02:16 maxirater joined
02:16 <halogenandtoast> Could not deduce (Ord a0) arising from a use of ‘sortOn’
02:16 <halogenandtoast> from the context: RandomGen g
02:17 <halogenandtoast> is there a way to say that the values from RandomGen should be in Ord?
02:17 kylepotts joined
02:17 takle joined
02:20 sleffy joined
02:20 <geekosaur> you can't poke an additional constraint into RandomGen but you can add your own constraints (RandomGen g, Ord g ) => ...
02:20 <halogenandtoast> related code: shuffle xs = (fmap (map snd . sortOn fst) . zip <$> getRandoms) <*> pure xs
02:20 e14 joined
02:20 <halogenandtoast> I think the problem is that I'm not in some other monad m
02:21 <halogenandtoast> getRandoms :: Random a => m [a]
02:21 <halogenandtoast> it works in GHCI because I'm in IO
02:21 <geekosaur> what is the type signature for shuffle?
02:21 <halogenandtoast> but it doesn't work in my code because I'm not
02:21 uuplusu joined
02:21 <geekosaur> this likely has nothing to do with IO, but with defaulting in ghci
02:21 <geekosaur> which has to be done per line instead of per file, so it likely inferred Integer early
02:21 <halogenandtoast> shuffle :: MonadRandom f => [b] -> f [b]
02:22 wroathe joined
02:22 infinity0_ joined
02:22 infinity0_ joined
02:22 <geekosaur> actually that didn't help me as there appear to be several
02:23 <geekosaur> (and IO *is* relevant for one of them, it turns out)
02:23 <geekosaur> oh
02:23 <geekosaur> shuffle :: (MonadRandom f, Ord b) => [b] -> f [b]
02:23 jao joined
02:24 <geekosaur> and, again, ghci will have been forced to figure out b early and picked Integer, so there's no problem with the Ord constraint.
02:24 <geekosaur> but in a file, MonadRandom likely blocks normal defaulting so you need to give more information. you'll run into even more of this later I suspect
02:25 infinity0 joined
02:26 <halogenandtoast> geekosaur: sortOn is being called on the result of getRandoms, not on b
02:27 <geekosaur> ok, then you need to force that type to something with an Ord instance.
02:27 <geekosaur> you cannot use defaulting here, unless you want to switch on {-# LANGUAGE ExtendedDefaultRules #-} like ghci uses
02:28 infinity0 joined
02:28 <halogenandtoast> It looks like I have only 2 instances of MonadRandom to work with
02:28 <halogenandtoast> IO and RandT
02:28 <halogenandtoast> but Rand should work hmm
02:28 <geekosaur> IO has nothing to do with sorting'
02:28 <geekosaur> IO is *not* the problem
02:30 <halogenandtoast> geekosaur: I wasnt claiming it was, but I might be addressing the wrong problem anyways
02:30 <halogenandtoast> I was trying to type case getRandoms
02:30 <halogenandtoast> getRandoms :: (Random a, MonadRandom m) => m [a]
02:30 <geekosaur> constrain it afterward
02:30 <halogenandtoast> so I needed some value for m
02:30 <halogenandtoast> :i MonadRandom
02:30 <halogenandtoast> instance [safe] MonadRandom IO
02:30 <halogenandtoast> instance (RandomGen g, Monad m) => MonadRandom (RandT g m)
02:30 <halogenandtoast> are the only instances
02:30 infinity0 joined
02:30 <geekosaur> yes, I already said you can;t do it there
02:31 <halogenandtoast> Okay then I guess I misunderstood
02:31 <halogenandtoast> I was trying to do something derpy like: shuffle xs = (fmap (map snd . sortOn fst) . zip <$> (getRandoms :: m [Int])) <*> pure xs
02:31 indi_ joined
02:32 <geekosaur> I think you need something like: shuffle xs = (fmap (map snd . sortOn (fst :: (b,Int) -> Int)) . zip <$> getRandoms) <*> pure xs -- with ScopedTypeVariables and 'forall b.' in the signature
02:32 <geekosaur> unless you rearrange so you have something of the type to be sorted without other types involved
02:33 infinity0 joined
02:34 <halogenandtoast> This seems not worth the trouble :\
02:34 <halogenandtoast> I just wanted to get away from passing around StdGen
02:34 <geekosaur> this is one of the downsides of being clever with pointfree, the points are where you can inject type annotations sanely
02:34 <halogenandtoast> I didn't think I was being pointfree
02:34 <halogenandtoast> I pass in xs
02:35 <halogenandtoast> Or are you referring to internals
02:35 <geekosaur> internally, yes
02:35 <geekosaur> you pipeline the random stream through without ever exposing a point that could be used to type it
02:35 <geekosaur> without dragging in some other type, either that of xs or that of the monad
02:36 takle joined
02:36 infinity0 joined
02:37 <geekosaur> :t (^)
02:37 <lambdabot> (Num a, Integral b) => a -> b -> a
02:38 <geekosaur> this is another (albeit simpler) example, one constantly gets warnings about defaulting for b because it's almost never used in a way that gives it an explicit type
02:39 <geekosaur> anyway you could try just turning on ExtendedDefaultRules for that file so it'll work more like ghci does
02:40 <geekosaur> I don't normally recommend that because it means things suddenly typecheck that wouldn't have before, by defaulting uselessly to ()
02:41 <halogenandtoast> Yeah I think I'll just pass StdGen around
02:42 jao joined
02:42 <halogenandtoast> I was just trying to play with MonadRandom and shuffle a deck
02:43 takle joined
02:44 mjhoy joined
02:45 <lpaste> halogenandtoast pasted “Main.hs” at http://lpaste.net/4255346991493545984
02:45 <halogenandtoast> for reference ^^
02:45 sanett joined
02:45 cpennington joined
02:45 <halogenandtoast> I had a more complex example in another program, so I wanted to try with something rather isolated.
02:46 <halogenandtoast> The fact that initialDeck has to accept StdGen, but doesn't use it, made me feel like I wanted a Monad Transformer
02:46 <halogenandtoast> (in my actual program the StdGen gets passed down even more levels)
02:47 <* geekosaur> would have used the other MonadRandom (the package by that name), btw --- the parameter is the random type so it's easy to add an annotation, and it's just a state monad with methods that delegate to the actual RNG
02:48 <geekosaur> you're still "passing StdGen around" but it's done transparently
02:48 ebsen joined
02:48 <geekosaur> instead of using a hidden IORef somewhere
02:48 bhiliyam joined
02:51 <halogenandtoast> geekosaur: I "think" that was what I was trying to do
02:51 <halogenandtoast> I'm fine with passing it "transparently"
02:52 <halogenandtoast> MonadRandom comes from Control.Monad.Random right?
02:52 <geekosaur> which package?
02:52 <halogenandtoast> MonadRandom
02:52 <halogenandtoast> build-depends: base >= 4.7 && < 5
02:52 <halogenandtoast> , random
02:52 <halogenandtoast> , MonadRandom
02:52 <geekosaur> that sounds wrong, unless they decided to complicate things at some point :/
02:53 <geekosaur> ok, yes, at one point that was just a glorified state monad, now it's annoying :/
02:54 <geekosaur> sad
02:55 jayshua joined
02:55 <halogenandtoast> lol
02:56 <geekosaur> I mean, really all that's needed is a state monad with some helpers
02:59 nous1024 joined
02:59 <geekosaur> ok, guess the path is official now for the Creators Update-compatible ghc
03:01 aglorei joined
03:01 exferenceBot joined
03:02 takle joined
03:02 ricebox23 joined
03:03 zero_byte joined
03:03 PennyNeko joined
03:05 hexagoxel joined
03:08 wroathe joined
03:09 nous1024 left
03:09 freddys6 joined
03:11 freddys6 left
03:11 ricebox23 left
03:12 kylepotts joined
03:15 systemfault joined
03:15 hamishmack joined
03:15 seagreen joined
03:16 felixsch__ joined
03:16 nighty-- joined
03:17 kylepotts joined
03:19 nighty-- joined
03:21 frankg joined
03:21 hybrid joined
03:24 Chameleon joined
03:25 wroathe joined
03:28 ublubu joined
03:29 dunx_ joined
03:30 cmsmcq joined
03:30 takle joined
03:32 otto_s_ joined
03:32 ExcelTronic joined
03:33 raycoll joined
03:34 ExcelTronic joined
03:34 ebsen joined
03:35 meba joined
03:37 xcmw joined
03:38 takle joined
03:39 mzf joined
03:45 mjhoy joined
03:45 takle joined
03:47 pinkythepig joined
03:49 xall joined
03:49 bhiliyam joined
03:51 hamishmack joined
03:52 dunx joined
03:53 raycoll joined
03:56 raycoll joined
03:58 codygman joined
03:59 takle joined
03:59 <codygman> Does anyone know how I can wait for an interactive haskell repl in haskell-mode to load before trying to insert stuff into it?
03:59 <codygman> I'm browsing through the source but can't find it
04:00 <codygman> I think maybe I can use haskell-interactive-at-prompt
04:06 raycoll joined
04:06 takle joined
04:07 kylepotts joined
04:08 <ertes> geekosaur: at one point i completely removed any dependency on MonadRandom from all of my packages, precisely because it used StateT and had StateT-based instances of MonadRandom
04:09 <geekosaur> that's orthogonal, it should _behave like_ state, it doesn't have to take up a StateT
04:09 <geekosaur> requiring a monad it can hide a ref inside is better??
04:10 thunderrd_ joined
04:10 <ertes> geekosaur: oh, then i don't understand what you mean… RandT is just a newtype around StateT
04:11 wroathe joined
04:12 kylepotts joined
04:12 haoformayor joined
04:12 <ertes> not sure why its constructor is hidden though (for god's sake, stop doing that OOP bullshit already!)
04:13 zar joined
04:13 obruT1 joined
04:14 <seekr_> geekosaur: Thanks a lot for the link, I got GHC working.
04:15 <geekosaur> ertes, copy around a seed like a state monad, but the methods it provides are those for randomness, not those of MonadState
04:16 <geekosaur> no MonadState instance, no get/put (might provide renames as backdoors but I suspect there's more api appropriate stuff)
04:16 <ertes> geekosaur: yeah, for some reason it really tries hard not to look like StateT
04:16 baldrick1 joined
04:17 <ertes> highly inspired by java i take it
04:17 zar joined
04:17 revprez_atlanta joined
04:17 <ertes> anyway, just use StateT and dispense with the extra library dependency =)
04:18 <ertes> MonadRandom doesn't seem to provide any real benefit
04:19 halogenandtoast joined
04:21 mjhoy joined
04:22 wroathe joined
04:24 eklavya joined
04:25 MarioBranco joined
04:26 Xanather joined
04:27 takle joined
04:28 mac10688 joined
04:32 baldrick1 joined
04:36 indi_ joined
04:36 atomi joined
04:36 xormor joined
04:40 djapo_ joined
04:41 brynedwardz joined
04:42 xcmw joined
04:44 takle joined
04:46 wroathe joined
04:46 brynedwards joined
04:47 <iqubic> WHat is the best way to get random numbers in Haskell??
04:47 <iqubic> Like if I want N random integers X and Y, what do I do?
04:49 ysahil joined
04:49 <iqubic> Also, when using Lenses, when would I ever need a traversal?
04:50 bhiliyam joined
04:51 sleffy joined
04:51 jayshua joined
04:51 takle joined
04:52 <Cale> iqubic: Probably the easiest way is just replicateM n (randomRIO (x,y))
04:52 systemfault joined
04:53 <Cale> Depending on how heavily you're using random number generation though, there might be better options.
04:54 <iqubic> What's randomRIO?
04:55 <iqubic> :t randomRIO
04:55 <lambdabot> Random a => (a, a) -> IO a
04:55 freebrew81 joined
04:55 <iqubic> Why is that returning something of type IO a?
04:55 <iqubic> Also, when using Lenses, when would I ever need a traversal?
04:56 <iqubic> Trying to understand traversals here. I can look at the log to learn about random number generation.
04:56 <iqubic> I know what lenses are, well enough. I just need to know why a travesal would ever be helpful ever.
04:56 wroathe joined
04:58 freebrew81 joined
04:58 <jle`> iqubic: it returns an IO computation that produces a random 'a'
04:58 <iqubic> And while we're at it, what the heck is a prism???
04:58 <jle`> i use traversals more often than i use lenses
04:58 <ertes> iqubic: a lens points to exactly one value, whereas a traversal can point to arbitrarily many values
04:59 <ertes> iqubic: i use them much more often than lenses
04:59 <iqubic> ertes: So if I have [a], I can have a traversal that points to all 'a' in the list
04:59 <ertes> iqubic: a prism is a traversal that points to up to one element, and it has enough information to *construct* that element
04:59 <jle`> yup
04:59 <Cale> iqubic: Well first of all, are you familiar with "traverse"?
04:59 <jle`> iqubic: it's actually included in 'base'
05:00 <jle`> called traverse :: Traversal [a] [b] a b
05:00 <Cale> Traversals in general are things which behave much like traverse does.
05:00 <iqubic> Not too well Cale. What does travers do?
05:00 <Cale> :t traverse
05:00 <lambdabot> (Applicative f, Traversable t) => (a -> f b) -> t a -> f (t b)
05:00 <ertes> _Just is a prism
05:00 <ertes> > _Just # 5
05:00 <lambdabot> Just 5
05:00 <iqubic> That is too complex for me to handle.
05:00 <jle`> iqubic: traverse is like an "effectful" map
05:00 <Cale> So t a here is some data structure filled with values of type a
05:00 <iqubic> The type signature for traverse.
05:00 <jle`> map :: (a -> b) -> [a] -> [b]
05:00 <jle`> traverse :: (a -> f b) -> [a] -> f [b]
05:00 systemfault joined
05:00 <Cale> and a -> f b is a function describing something to be done for each value of type a
05:01 <jle`> it's like map, but your mapping function can be 'effectful'
05:01 <Cale> i.e. given some value of type a, you get an f-computation whose result will have type b
05:01 <jle`> if you're familiar with mapM, it's the same thing
05:01 <ertes> iqubic: have you implemented a lens by yourself?
05:01 <Cale> e.g. f might be IO
05:01 soLucien joined
05:01 <ertes> iqubic: without using any of the automations of the lens library
05:01 <iqubic> traverse putStr ["H", "E", "L", "L", "O"]
05:02 <iqubic> Does that work?
05:02 <jle`> yes, exactly
05:02 <jle`> that returns an IO [()]
05:02 kylepotts joined
05:02 <iqubic> Why is it that type???
05:02 <jle`> it's basically putStr "H" >> putStr "E" >> putStr "L" >> putStr "O", but also collects the results
05:02 <jle`> iqubic: look at the type signature of traverse
05:02 <iqubic> I see now.
05:02 <jle`> yes
05:02 <jle`> let the power flow through you
05:03 <iqubic> ertes: I have never constructed a lens by myself. I always use TemplateHaskell.
05:03 <ertes> iqubic: then do that
05:03 <jle`> map applies an (a -> b) over all the a's in a struture, and collects the results back
05:03 osa1 joined
05:03 osa1 joined
05:03 baldrick1 joined
05:03 <jle`> traverse applies an (a -> f b) over all of the a's in a sturcture, sequences the effects, collects the results
05:03 <ertes> iqubic: here is an exercise: write the following lens: traverseFst :: (Functor f) => (a -> f b) -> (a, c) -> f (b, c)
05:04 <jle`> iqubic: another common thing people traverse, besides lists, is Map's
05:04 <codygman> Is there a pointfree lens way of doing this: fmap (<> "!") (bs ^? key "filepath" . _String)
05:04 <jle`> a `Map k a` is a map of keys of type k and values of type a
05:05 <jle`> codygman: that's already pointfree
05:05 <iqubic> ertes: traverseFst f (a, b) = (f a, b)
05:05 <iqubic> Is that correct?
05:05 <codygman> jle`: I would like something like: bs ^? key "filepath" . _String . someFunctionLikeFmap (<> "!")
05:05 <ertes> iqubic: ask GHC whether it's correct
05:06 <ertes> iqubic: there is only one way to write this function
05:06 wroathe joined
05:06 <iqubic> I'll see what GHC thinks
05:07 <ertes> (i could tell you, but then i would encourage you to guess instead of think) =)
05:07 ysahil joined
05:07 <iqubic> Looks like that's not the correct implementation.
05:08 <ertes> your result needs to be of type (f (b, c)), but you are returning something of type (f b, c)
05:08 <jle`> iqubic: traverse for maps is (a -> f b) -> Map k a -> f (Map k b) -- apply the (a -> f b) to all of the a's in the map, and sequences the effects and collects them all into a new map
05:09 xall joined
05:09 <iqubic> ertes: I'm not sure of the correct way to write traverse first.
05:10 <ertes> iqubic: there is a way to get an (f b), and you have a value of type 'c' from the second argument
05:10 <ertes> iqubic: do you see a way to combine them into an (f (b, c)) with the hint that 'f' is a functor?
05:11 <iqubic> I'll try.
05:12 <iqubic> I think I need to use fmap or <$> somewhere.
05:12 <ertes> that's right
05:12 <iqubic> Not sure where though.
05:12 <ertes> iqubic: if you had a 'b', do you see how to turn it into a (b, c)?
05:12 <iqubic> No.
05:13 <iqubic> I think I'd need to apply a data constructor of (,) some how.
05:13 <ertes> yes
05:13 <ertes> let's say that (x :: b), and (y :: c)
05:13 <iqubic> But I don't know where
05:13 <ertes> can you give me a value of type (b, c)?
05:13 <iqubic> sure: (x, y)
05:13 <iqubic> done.
05:13 <iqubic> That was simple
05:13 <ertes> correct
05:14 <iqubic> traverseFst :: (Functor f) => (a -> f b) -> (a, c) -> f (b, c)
05:14 <iqubic> That's what I'm aming for
05:14 <ertes> now you have only (y :: c), can you write a *function* that, given a value of type 'b', returns a (b, c)?
05:14 <iqubic> Yes.
05:14 <jle`> codygman: you can probably use 'to'
05:15 <iqubic> makeFst b = (b, c)
05:15 <iqubic> provided that the second argument has the right type
05:15 <ertes> iqubic: correct, but let's use the lambda form: (\b -> (b, c))
05:15 <ertes> uhm
05:15 nicknovitski joined
05:15 <iqubic> What now?
05:15 <ertes> let's use this instead in order not to mix up values and types: (\x -> (x, y))
05:16 <iqubic> Sure.
05:16 <ertes> this function is of type (b -> (b, c))
05:16 <iqubic> correct.
05:16 <ertes> now given a function of type (b -> (b, c)), do you see a way to turn it into a function of type (f b -> f (b, c)), given that 'f' is a functor?
05:16 wroathe joined
05:17 <iqubic> Using fmap or <$>?
05:17 baldrick1 joined
05:17 <jle`> codygman: probably 'to (<> "!")'
05:17 takle joined
05:17 <ertes> iqubic: how exactly? you can use the lambda now
05:18 <jle`> codygman: bs ^? key "filepath" . _String . mapped . to (<> "!")
05:18 <iqubic> Not sure.
05:18 <iqubic> Don't we need a function in order to use fmap?
05:19 <ertes> iqubic: you have a function
05:19 <iqubic> I just realized that.
05:19 <jle`> iqubic: "now given a function..."
05:19 <iqubic> \x -> x <$> (\x -> (x, y))
05:19 <iqubic> Done.
05:19 <iqubic> I think that works
05:19 <jle`> ask ghc :)
05:19 <ertes> nope
05:20 <iqubic> That's wrong? how??
05:20 <ertes> and yes, sorry… you should ask GHC =)
05:20 <jle`> the best part about haskell is that you can always ask ghc if what you wrote is correct
05:20 <jle`> that's the best advantage of haskell over other languges :)
05:20 <ertes> however, GHC will not actually complain about that one, as far as i see
05:20 <iqubic> It won't?
05:21 <ertes> iqubic: (\x -> (x, y)) :: b -> (b, c) -- assuming (y :: c)
05:21 <iqubic> Sure.
05:21 <ertes> fmap :: (u -> v) -> (f u -> f v)
05:21 shane joined
05:21 eacameron joined
05:21 <ertes> do you see a way to turn a (b -> (b, c)) into an (f b -> f (b, c))?
05:22 <iqubic> Yes. I do.
05:22 <ertes> ok, give me an (f b -> f (b, c))
05:22 <iqubic> fmap (\x -> (x, y)
05:22 <ertes> apart from the missing bracket, exactly
05:23 <iqubic> Right, sorry.
05:23 <iqubic> Now, how does this help use with: traverseFst :: (Functor f) => (a -> f b) -> (a, c) -> f (b, c)?
05:23 <iqubic> Wait, let me try it on my own.
05:23 <ertes> fmap (\x -> (x, y)) :: f b -> f (b, c) -- this function returns a result of exactly the right type you need for traverseFst… all you need now is an (f b) you can apply it to
05:24 <iqubic> And how do I get that (f b)?
05:24 <ertes> traverseFst f (x, y) = _ -- for _ there is (f :: a -> f b) in scope
05:25 <ertes> if you could apply f to something, you would get an (f b), right?
05:25 <iqubic> yeah. I would.
05:25 <iqubic> What do I apply it to?
05:25 <ertes> well, do you have a value of type 'a'?
05:25 <iqubic> I do.
05:25 <ertes> ok, now try it =)
05:26 uelen joined
05:26 wroathe joined
05:27 <iqubic> traverseFst f (x, y) = fmap (\x -> (x, y)) x
05:28 <iqubic> I think that's right.
05:28 <ertes> try it
05:28 <iqubic> GHC tells me it's right, I think.
05:28 lordcirth joined
05:28 <ertes> then you forgot to write a type signature for traverseFst
05:28 <iqubic> Not quite.
05:28 <iqubic> I did.
05:28 <ertes> then GHC will not agree
05:28 <iqubic> Why is this so hard???
05:29 <ertes> symbolic/logical reasoning takes some getting used to, but you're really close
05:29 <Cale> iqubic: You just forgot to make use of f
05:29 <iqubic> Cale: I did nothing with f?
05:29 <iqubic> f is a function right??
05:29 <Cale> yeah
05:29 <ertes> you did not use f anywhere, but you need to use f to get the (f b)
05:30 <iqubic> got it.
05:30 Tharbakim joined
05:30 Tharbakim joined
05:30 <iqubic> traverseFst f (x, y) = fmap (\x -> (x, y)) (f x)
05:30 <iqubic> done.
05:30 <iqubic> That works.
05:30 <ertes> correct
05:30 <iqubic> GHC agrees.
05:30 <Cale> That is actually not just a traversal, it's a lens
05:30 <ertes> congratulations, you have just written your first lens
05:30 <iqubic> That's just a lens??
05:30 <ertes> yes
05:30 <iqubic> Let me guess
05:31 <ertes> you can replace the type signature by: traverseFst :: Lens (a, c) (b, c) a b
05:31 linelevel joined
05:31 <Cale> Lenses are the special case of traversals which only traverse one element
05:31 baldrick1 joined
05:31 <ertes> if you look up the definition of the Lens type alias, you will find that it matches your type exactly
05:31 sanett joined
05:31 <Cale> and which as such, don't need the full Applicative structure, just Functor
05:31 <iqubic> traverseSnd f (x, y) = fmap (\y -> (x, y)) (f y)
05:31 uelen joined
05:31 <Cale> (you only needed fmap)
05:31 <Cale> yeah
05:31 <iqubic> Is that right?
05:31 <iqubic> Did I get traverseSnd?
05:31 <iqubic> So what is a lens, then?
05:32 <iqubic> a single element traversal?
05:32 <ertes> iqubic: you can now import Control.Lens and use traverseFst to access/modify the first element of tuples
05:32 <Cale> yeah
05:32 <iqubic> What's a traversal then?
05:32 eacameron joined
05:32 <Cale> Now if you look at what you've done here
05:32 <ertes> iqubic: before we get to traversals, do you understand *why* this function is a lens?
05:32 <Cale> You've split the structure into two parts:
05:32 <iqubic> Do?
05:32 <iqubic> NO. I have no idea why that is a lens at all.
05:32 <Cale> the part which you're applying f to, the bit that the traversal/lens is focusing on
05:33 <Cale> and a function which replaces that part in the whole structure
05:33 <ertes> there are quite a few ways you can use traverseFst… the obvious way is to use it with f = Identity to map over the first element
05:33 <ertes> @let traverseFst f (x', y) = fmap (\x -> (x, y)) (f x')
05:33 <Cale> you can think of (\y -> (x, y)) as being like a pair with a hole punched in it by the lambda
05:33 <lambdabot> Defined.
05:33 <Cale> i.e. the second component is a blank which still needs filling in
05:33 <ertes> > runIdentity (traverseFst (\x -> Identity (x + 5)) (10, 20))
05:33 <lambdabot> (15,20)
05:33 <iqubic> Can I try writing another lens?
05:34 <iqubic> Can someone give me another lens to try writing?
05:34 <ertes> iqubic: sure… try writing a lens into the real part of a Complex from Data.Complex
05:34 <Cale> This is a general pattern with lenses: you're splitting the structure into a function which acts like the original structure with a hole punched in the appropriate place, and the part that you punched out of there
05:34 <Cale> and then you're applying your arbitrary function to the part that you punched out and fmapping the function over it
05:34 <iqubic> I'll try that.
05:34 <glguy> a lens for the least significant bit in an Int
05:35 <ertes> iqubic: glguy's exercise is better, because it's less similar to the tuple exercise
05:35 <iqubic> ertes: traverseReal f (x :+ y) = fmap (\x -> (x :+ y)) (f x)
05:35 <ertes> yeah, exactly
05:36 nirvinm joined
05:36 Tharbakim joined
05:36 Tharbakim joined
05:36 meba joined
05:37 wroathe joined
05:37 gcross_ joined
05:37 N0F4C3_47 joined
05:38 <iqubic> Now, how do I work with bits in an interger?
05:38 <ertes> Data.Bits
05:38 <Cale> Math
05:39 <iqubic> And I can use Data.Bits to make a lens for the least significant bit of an int?
05:39 <ertes> (you could also use 'mod', 'even' and (+))
05:39 <ertes> yeah
05:39 <iqubic> Cool. Let me try that.
05:39 uuplusu joined
05:39 <ertes> here is a similar exercise: write a lens into the absolute value of an Integer
05:39 <iqubic> What does that even mean?
05:40 <ertes> (-50) ^. traverseAbs = 50
05:40 <ertes> (-50) & traverseAbs +~ 10 = -60
05:40 <iqubic> Oh, I see.
05:40 <iqubic> ertes: I don't know what those infix functions are doing.
05:41 <Cale> +~ is silly, just use over :P
05:41 wei2912 joined
05:41 <ertes> over traverseAbs (+ 10) (-50) = -60
05:41 <N0F4C3_47> this is chaenel h4cker or math hehe :P
05:41 <iqubic> I see.
05:41 yellowj joined
05:41 <iqubic> So I don't know where to begin with that?
05:41 <Cale> iqubic: Did you read my general description of how a lens works?
05:42 <iqubic> Can I see the type signature of traverseAbs?
05:42 <Cale> Several people were talking about that time
05:42 <ertes> revisit traverseFst: you had a way to split the data into two parts: the focus part (fst) and the remainder part (snd)
05:42 uelen joined
05:42 <Cale> traverseAbs :: (Integer -> f Integer) -> Integer -> f Integer
05:42 <ertes> you used pattern-matching to do it, but you could just as well have used 'fst' and 'snd'
05:42 takle joined
05:42 <iqubic> I know. I know.
05:42 <Cale> (With the guarantee that the Integers involved in the function argument are nonnegative)
05:42 <ertes> traverseFst f xy' = fmap (\x -> (,) x (snd xy')) (f (fst xy'))
05:43 <ertes> fst/snd are splitting, (,) is reassembly
05:43 <iqubic> Right.
05:43 <iqubic> I know that.
05:43 <ertes> Integer splits into two parts: a sign and an absolute value
05:43 <iqubic> How do I get the sign?
05:43 <ertes> 'signum' and 'abs' will be helpful for that
05:43 <iqubic> :t signum
05:43 <lambdabot> Num a => a -> a
05:43 <ertes> and reassembly is just (*)
05:44 <ertes> > signum (-5) * abs (-5)
05:44 <iqubic> What does signum do?
05:44 <lambdabot> -5
05:44 <ertes> > map signum [-3..3]
05:44 <lambdabot> [-1,-1,-1,0,1,1,1]
05:44 <jle`> iqubic: check out the docs :)
05:44 baldrick1 joined
05:44 <iqubic> I ss how that works.
05:44 <jle`> http://hackage.haskell.org/package/base-
05:45 uglyfigurine joined
05:45 <Cale> @let onesDigit f n = let (q,r) = quotRem n 10 in (\r' -> 10*q + r') <$> f r
05:45 <lambdabot> Defined.
05:46 <Cale> > view onesDigit 47837
05:46 <lambdabot> 7
05:46 <Cale> > set onesDigit 2 47837
05:46 <lambdabot> 47832
05:47 wroathe joined
05:47 <iqubic> traverseAbs f x = (\x' -> x' * signum x) <$> (f $ abs x)
05:47 falafel joined
05:47 <iqubic> Not sure that will work.
05:47 <ertes> iqubic: not quite
05:47 <ertes> oh, wait
05:47 <ertes> yes, it should
05:47 falafel_ joined
05:47 <Cale> yeah, looks fine to me
05:48 <iqubic> Cool. I did a thing.
05:48 <iqubic> @let traverseAbs f x = (\x' -> x' * signum x) <$> (f $ abs x)
05:48 <lambdabot> Defined.
05:48 uelen joined
05:48 Tharbakim joined
05:48 Tharbakim joined
05:48 <iqubic> > over traverseAbs (+ 10) (-50)
05:48 <lambdabot> -60
05:48 <iqubic> It works.
05:48 <ertes> iqubic: now the important question is: how is traverseAbs an actual lens? using f = Identity we can *change* the value, but a lens also features *extraction*
05:49 <iqubic> How do I extract something from a lens like traverseFst?
05:49 <ertes> traverseFst :: (Functor f) => (a -> f b) -> (a, c) -> f (b, c)
05:49 <ertes> can you think of an 'f' that would return an 'a'?
05:50 <iqubic> id?
05:50 <ertes> i mean the type 'f'
05:50 <iqubic> Identity?
05:50 <ertes> nope: Identity (b, c) ≃ (b, c)
05:50 <ertes> you need an f such that: f (b, c) ≃ a
05:50 bhiliyam joined
05:50 <iqubic> Not sure how to do that.
05:51 <ertes> well, think about it… it's an 'f' that ignores its argument type (which is (b, c)), and just returns an 'a'
05:51 <ertes> a function that ignores its argument… does that sound familiar?
05:51 <ertes> (in this case a type-level function of course)
05:52 <iqubic> I have no idea.
05:52 <iqubic> Is it const?
05:52 <ertes> yeah, exactly!
05:52 <ertes> it's the constant functor
05:52 <iqubic> I was just making an educated guess.
05:52 <ertes> :k Const
05:52 <lambdabot> * -> k -> *
05:52 <iqubic> Oh. I see
05:52 <ertes> your guess was correct =)
05:52 <iqubic> So how does that help with traverseAbs?
05:53 <ertes> traverseFst :: (a -> Const a b) -> (a, c) -> Const a (b, c)
05:53 <iqubic> And extraction
05:53 <iqubic> > over traverseAbs (const 1) (-60)
05:53 <lambdabot> -1
05:53 <ertes> Const has a constructor, also named Const… it has type: Const :: a -> Const a b
05:53 <iqubic> Darn it.
05:54 <iqubic> > over traverseAbs (\x -> Const x) (-60)
05:54 <lambdabot> error:
05:54 <lambdabot> • Occurs check: cannot construct the infinite type: a ~ Const a b0
05:54 <lambdabot> • In the expression: Const x
05:54 <ertes> can you think of a function 'f' you can use with traverseFst when the type f = Const a?
05:54 nilg joined
05:54 <iqubic> is it id?
05:54 <iqubic> Just guessing here.
05:54 baldrick1 joined
05:54 <ertes> nope… the argument you need is of type: a -> Const a b
05:55 <ertes> can you think of a function of that type?
05:55 Tharbakim joined
05:55 Tharbakim joined
05:55 <iqubic> That's not the function, but the argument.
05:55 codesoup joined
05:55 insitu joined
05:55 <ertes> once again the type signature instantiated with f = Const a: traverseFst :: (a -> Const a b) -> (a, c) -> Const a (b, c)
05:56 <iqubic> What function can I use?
05:56 <iqubic> Is that the question?
05:56 <ertes> can you think of an argument of type (a -> Const a b) you can apply this function to? if not, read the last few lines i wrote carefully
05:56 <iqubic> \x -> Const x y
05:56 kylepotts joined
05:56 <iqubic> Does that work?
05:56 <ertes> that's a type error: Const takes only one argument
05:56 <jle`> :t Const
05:56 <lambdabot> forall k (b :: k) a. a -> Const a b
05:57 <iqubic> \x -> Const x
05:57 <iqubic> Does that work
05:57 <ertes> yeah… or simply Const
05:57 kellytk joined
05:57 <ertes> > traverseFst Const (3, 5)
05:57 <lambdabot> Const 3
05:57 wroathe joined
05:57 <iqubic> > traverseAbs Const (-60)
05:57 <lambdabot> Const 60
05:57 <iqubic> oh, that works.
05:58 <iqubic> That's how my function was a lens.
05:58 <kellytk> Hi, how well suited to making trading bots is Haskell?
05:58 <ertes> that's exactly what 'view' or (^.) does
05:58 <iqubic> Oh, is it.
05:58 _sg joined
05:58 <ertes> except that it also gets rid of the Const wrapper
05:58 <Cale> kellytk: I think some people actually do that, but I don't know what sort of libraries or techniques they use.
05:58 <iqubic> traverseAbs^.(-60)
05:58 <ertes> kellytk: you may have to write some support code first, like machine learning libraries
05:58 <jle`> kellytk: it depends on how important hard real-time is for you
05:58 <iqubic> >traverseAbs^.(-60)
05:59 <iqubic> > traverseAbs^.(-60)
05:59 tinkywinky joined
05:59 <lambdabot> error:
05:59 <lambdabot> • Could not deduce (Num t0)
05:59 <lambdabot> from the context: (Num (Getting a ((t -> f t) -> t -> f t) a),
05:59 fakenerd joined
05:59 <iqubic> Why doesn't that work?
05:59 <iqubic> > traverseAbs ^. (-60)
05:59 <jle`> > (-60) ^. traverseAbs
05:59 <lambdabot> 60
05:59 <lambdabot> error:
05:59 <lambdabot> • Could not deduce (Num t0)
05:59 <lambdabot> from the context: (Num (Getting a ((t -> f t) -> t -> f t) a),
05:59 bhiliyam joined
05:59 <Cale> jle`: I would expect something like a Haskell EDSL to be pretty good approach to writing one-shot compilers for trading bots
05:59 <kellytk> jle`: Soft is fine, I'd be coming from Node.js/TypeScript. ertes: ML for the trading strategies?
05:59 <Cale> (for HFT)
05:59 <jle`> iqubic: (you flipped the arguments for ^.)
05:59 <ertes> kellytk: i would assume that you use ML for automated trading
06:00 <iqubic> I did?
06:00 uelen joined
06:00 <iqubic> (-60) ^. traverseAbs
06:00 <iqubic> > (-60) ^. traverseAbs
06:00 <lambdabot> 60
06:00 <iqubic> so I did.
06:00 <kellytk> ertes: I'm getting started so they'd be static strategies and quite simple ala buy low sell high :-)
06:00 <jle`> mhm.
06:00 <Cale> ertes: Just because Jane Street?
06:00 <ertes> iqubic: does everything make sense so far?
06:00 <iqubic> Yes.
06:00 takle joined
06:00 <iqubic> What more do you want to teach me?
06:01 <jle`> kellytk: for something like that, haskell-the-language is kind of great for that
06:01 <iqubic> I get that a lens is a single element traversal
06:01 <ertes> kellytk: ah, then i see no problem in that regard… you may still need support libraries like bindings to your broker's API, for example
06:01 <jle`> it's just that the ecosystem is kind of lacking compared to for other languages
06:01 <ertes> kellytk: as for how much haskell as a language is suitable: very suitable =)
06:01 <kellytk> ertes: Also basic networking such as hitting a JSON HTTP endpoint once every x seconds
06:02 <ertes> kellytk: the basic stuff is all there
06:02 <kellytk> jle`: How fast can gaps be filled with Haskell?
06:02 <iqubic> ertes: What more is there to learn about lenses?
06:02 <ertes> including JSON/XML/HTTP/…
06:02 <ertes> iqubic: a *lot* =)
06:02 <dysfun> lenses go on forever and ever
06:02 eazar001 joined
06:02 <iqubic> How does the makeLens TemplateHaskell thing work with records?
06:02 <kellytk> ertes: That's pretty high-level IMHO but I suppose not coming from JS which also offers a lot
06:03 <ertes> iqubic: here is a challenge: can you write a lens into *both* components of a tuple?
06:03 <iqubic> What does that mean?
06:03 <ertes> iqubic: traverseBoth :: (Functor f) => (a -> f b) -> (a, a) -> f (b, b)
06:03 <iqubic> ertes: Won't that be a travesal for realsie this time?
06:03 <iqubic> or not yet?
06:03 <ertes> iqubic: note: i'm calling this a challenge, not an exercise
06:03 <iqubic> I'll try it.
06:03 <kellytk> ertes: Does Haskell offer anything helpful for parallel code?
06:03 <iqubic> Is it hard to do?
06:04 <jle`> kellytk: haskell gaps can be usually be easy to fill in
06:04 <ertes> kellytk: so much that there is a whole book about it
06:04 <ertes> kellytk: http://chimera.labs.oreilly.com/books/1230000000929/
06:04 <iqubic> Or is it just confusing to write that lens?
06:04 <Cale> also note: it won't be a lens, just a traversal
06:04 <ertes> iqubic: try it first, before i answer that
06:04 <iqubic> I will.
06:04 <iqubic> Cale: this will be a traversal?
06:04 <Cale> Yeah
06:05 <Cale> You will need Applicative
06:05 <iqubic> Why is that?
06:05 <ertes> iqubic: the actual exercise is, as soon as you hit the road-block, to explain *why* you can't do it =)
06:05 <ertes> but Cale already spoiled it
06:05 <Cale> With only fmap, you can only replace one thing
06:06 <ertes> you may still want to try though
06:06 <iqubic> It's like trying to apply (+) to two Maybe Ints without an applicative.
06:06 <iqubic> It can't be done.
06:06 <iqubic> ertes: I'll try.
06:07 splanch joined
06:07 <iqubic> So first I need a function that takes something of type a, and makes a tuple of (a, a). Let's use (,) for that.
06:07 <dysfun> what useful libraries make use of Applicative but *not* Monad?
06:07 <rotaerk> cereal package ... downloads: 158452. votes: 1.
06:07 <cocreature> dysfun: validation
06:07 <ertes> iqubic: it's impossible to do, but try to come up with an idea of what you *would* need to write it
06:07 descender joined
06:07 wroathe joined
06:07 <dysfun> aha
06:07 <Cale> dysfun: Traversable
06:07 <iqubic> dysfun: Apparently Traversals do.
06:07 <ertes> iqubic: i.e. why Functor is not enough
06:07 <cocreature> dysfun: or more accurately AccValidation
06:08 <tinkywinky> poll: what software are you writing with Haskell, or are you just gazing into the navel of category theory?
06:08 <dysfun> okay, thanks folks :)
06:08 <iqubic> I'm learning about lenses. They're teaching me.
06:08 <Cale> tinkywinky: The company I work for, Obsidian Systems, builds web and mobile applications for various clients entirely in Haskell.
06:08 sleffy joined
06:08 <* dysfun> is building a compiler in haskell, which is a bit of a cliche
06:08 <cocreature> tinkywinky: I’ve written web backends, (toy) compilers, small tools that help me with other things and more, …
06:08 <tinkywinky> Cale , that sounds cool are you using purescript perhaps?
06:09 <ertes> dysfun: since we're talking about it: lenses use proper Applicative a lot =)
06:09 <Cale> tinkywinky: We use GHCJS to build Haskell -> Javascript to run on the web, and GHC to turn the same Haskell into ARM code to run on mobile devices.
06:09 <Cale> Haskell only, no purescript
06:09 <dysfun> ertes: i really only use lenses at the highest level, i never did bother to try and understand the monster underneath
06:09 <jle`> dysfun: lens is a good example
06:09 <Cale> tinkywinky: (We also use GHC to build our application backends of course)
06:09 <jle`> oh someone already brought it up
06:09 CurryWurst joined
06:10 <iqubic> traverseBoth f xy' = (,) <$> f (fst xy') <*> (snd xy')
06:10 <iqubic> I think that works.
06:10 <jle`> dysfun: lens is a nice library that explicitly takes advantage of the difference between Applicative and Monad to make stornger guaruntees about code
06:10 uelen joined
06:10 <ertes> dysfun: if you've ever used traversals, you have used the Applicative part of lens
06:10 <dysfun> i have used traversals
06:10 <iqubic> I know I used an applicative, but I see no way to apply (,) to two values without an applicative.
06:10 <tinkywinky> dysfun adit.io has the best explanation of lenses ive seen yet. I'm putting you down for navel-gazing :P
06:10 <ertes> iqubic: it does work, but it has another type
06:10 <iqubic> ertes: traverseBoth f xy' = (,) <$> f (fst xy') <*> (snd xy')
06:11 <ertes> iqubic: a less generic one
06:11 <iqubic> What does that mean?
06:11 <dysfun> tinkywinky: i'm not navel-gazing. i said i'm writing a compiler
06:11 <ertes> iqubic: this happens to be a proper traversal
06:11 <ertes> iqubic: proper in the sense of "not a lens"
06:11 <iqubic> I wrote a proper traversal?
06:11 <ertes> iqubic: yeah
06:11 <tinkywinky> dysfun: sorry I withdraw my statement
06:11 <iqubic> Wow. I didn't think that code would actually work.
06:12 <Cale> I've also used traversals in production code... though not too commonly.
06:12 <jle`> welcome to haskell
06:12 <ertes> ah, you have one error there
06:12 <dysfun> that said, periodically i have curiosities that #haskell is very good at solving
06:12 <iqubic> You need an applicative, because you can't apply (,) to two valuse with just functors.
06:12 <ertes> iqubic: ^
06:12 <iqubic> ertes: What's the error?
06:12 <dysfun> i am not convinced anyone is ever 'done' learning haskell
06:12 <jle`> i mostly use traversals as a design pattern and not as a literal lens Traversal
06:12 <ertes> iqubic: you actually need to apply 'f' twice
06:13 <iqubic> ertes: traverseBoth f xy' = (,) <$> f (fst xy') <*> f (snd xy')
06:13 <jle`> when i want to create both a 'mapper' and a 'replacer' for my data types
06:13 <iqubic> Right, like that.
06:13 <jle`> and i don't want to define two different functions
06:13 <ertes> iqubic: yeah, exactly
06:13 <iqubic> I just fixed it.
06:13 <jle`> i can define a traversal and get both for free
06:13 <Cale> dysfun: I'm kinda 'done', in some sense, though I guess there are always new features being added to GHC.
06:13 <ertes> @let traverseBoth f xy' = (,) <$> f (fst xy') <*> f (snd xy')
06:13 <lambdabot> Defined.
06:13 <ertes> > (traverseBoth +~ 5) (3, 8)
06:13 <lambdabot> (8,13)
06:13 <iqubic> what does +~ do?
06:13 <Cale> dysfun: Of course, if you count the new libraries that people are building, then sure, can't ever be done :)
06:13 biglambda joined
06:13 <dysfun> yes!
06:14 <iqubic> wait I see that.
06:14 <ertes> iqubic: l +~ dx = over l (+ dx)
06:14 <iqubic> I got that now.
06:14 <* dysfun> is looking forward to when 'freer' has sane error messages
06:14 <iqubic> ertes: What other traversal should I try to write next?
06:14 <ertes> iqubic: easy or difficult?
06:15 <jle`> try writing one over lists ;)
06:15 <iqubic> easy for now. I'm still learning.
06:15 <iqubic> jle`: is that simple?
06:15 <ertes> iqubic: then what jle` said
06:15 <iqubic> How is that simple??
06:15 <jle`> it's simple, but there's one conceptual jump
06:15 <iqubic> Seems like it'd need recursion.
06:15 <jle`> but it illustrates a common pattern for writing traversals
06:15 <Cale> It does.
06:15 <ertes> iqubic: it's less simple than traverseBoth, because you need recursion, but still simple enough
06:15 <jle`> which is pattern match on all of the constructors
06:15 <jle`> and re-assembple them using <$>/<*>
06:16 <jle`> so traverseList f [] = ...; traverseList f (x:x) = ...
06:16 <jle`> *x:xs
06:16 <ertes> iqubic: traverseListElems :: (Applicative f) => (a -> f b) -> [a] -> f [b]
06:16 uelen joined
06:16 <Cale> hint: you've probably already seen this thing
06:16 <iqubic> I have.
06:16 <ertes> iqubic: oh, and don't cheat… you're not allowed to use 'traverse' or 'mapM' or any of their siblings =)
06:16 <iqubic> I know what it's called.
06:16 <jle`> you can use this same pattern to write a traversal for Maybe, Either e, etc.
06:17 <iqubic> ertes: I will write the implementation of traverse.
06:17 <jle`> just match on all of the constructors
06:17 <iqubic> How does that sound
06:17 <ertes> iqubic: that's exactly what this is
06:17 <ertes> iqubic: in fact 'traverse' is itself a proper traversal
06:17 <ertes> > (traverse +~ 5) [10,20,30]
06:17 <lambdabot> [15,25,35]
06:17 nomicflux joined
06:17 wroathe joined
06:19 <jle`> > traverse (\x -> Const [x]) [10,20,30]
06:19 <lambdabot> Const [10,20,30]
06:19 <iqubic> traverseListElems f [] = f []; traverseListElems f [x:xs] = f x : traverseListElems f xs
06:19 takle joined
06:19 <iqubic> I don't think that works at all.
06:19 <jle`> ask ghc :)
06:19 <ertes> > ["hel", "lo ", "wor", "ld"] ^. traverse
06:19 <lambdabot> "hello world"
06:19 <ertes> iqubic: ignore that =)
06:19 <ertes> i'll explain how/why this works later
06:19 <iqubic> That's just applying <> to all the elements
06:20 <iqubic> Isn't it?
06:20 <ertes> yes, but where does the (<>) come from?
06:20 <ertes> xs ^. traverse = getConst (traverse Const xs)
06:20 <iqubic> Instance Monoid [Char] where...
06:20 tmtwd joined
06:21 <iqubic> It's a monoid thing.
06:21 <iqubic> I know about monoids.
06:21 <ertes> it is, but how did it get there?
06:21 baldrick1 joined
06:21 teggi joined
06:21 <iqubic> I don't know.
06:21 Sh4rPEYE joined
06:21 <ertes> the trick is: instance (Monoid a) => Applicative (Const a)
06:21 <iqubic> How does one write a travesal for a list?
06:22 <iqubic> I have no idea how to do that.
06:22 <ertes> iqubic: jle` gave you a template
06:22 <iqubic> That template is just the pattern matching.
06:22 <iqubic> It doesn't actually help me.
06:22 <ertes> iqubic: traverse f [] = _ -- this one is easy
06:22 <ertes> _ = ?
06:22 <iqubic> Is it?
06:22 hurkan joined
06:23 <Cale> iqubic: Have you seen mapM?
06:23 <ggVGc> man, haven't written any haskell in months
06:23 <ggVGc> kind of miss it
06:23 crobbins joined
06:23 <Cale> iqubic: I don't know exactly how new you are :)
06:23 <ertes> iqubic: there is nothing you can apply 'f' to, so your only option to construct an (f [b]) is something that doesn't rely on 'f'
06:23 <iqubic> Cale: I know what mapM is.
06:23 <jle`> iqubic: look at the type
06:23 <jle`> traverse f [] should return f [b]
06:23 <ggVGc> has anyone here used haskell with children?
06:23 <ertes> iqubic: now 'f' might include effects… what do you call something that does *not* include effects?
06:24 <iqubic> f [] = pure
06:24 <iqubic> traverseList f [] = pure
06:24 <jle`> pure is a function
06:24 <jle`> pure...what?
06:24 <iqubic> traverseList f [] = pure []
06:24 <iqubic> I think.
06:24 <jle`> hooray
06:24 <ertes> iqubic: there you go
06:24 <ertes> iqubic: now: traverseList f (x : xs) = …
06:25 <ertes> the argument list has a head and a tail, so the resulting list also has a head and a tail
06:25 <ertes> traverseList f (x : xs) = _a <$> _b <*> _c
06:25 <ertes> so this is the template
06:25 <Cale> ggVGc: I have. Back in 2004 or so, when I was working for a summer as a research assistant at McMaster University, there was an experimental program going on which involved teaching a bunch of Haskell and basic math to kids in grade 6 or so.
06:25 <Sh4rPEYE> I'm sorry to interrupt the conversation. Does anyone know why this doesn't work? Please note that (:>) is a "Stream", or infinite list, data constructor...
06:25 <Sh4rPEYE> fibS = 0 :> 1 :> zipWithS (+) fibS (tailS fibS)
06:26 <ertes> iqubic: if _b gives the head, and _c gives the tail, what should _a be?
06:26 <jle`> Sh4rPEYE: what is the error?
06:26 <jle`> and what is the implementation of zipWithS ?
06:26 <jle`> and tailS ?
06:26 <iqubic> traverseList f (x:xs) = : <$> f x <*> traverseList f xs
06:26 <Sh4rPEYE> Also the "...S" functions are simply the analogies of the list counterparts
06:26 <jle`> and what do you mean by 'doesn't work'?
06:26 <jle`> does it compile and give the wrong answer?
06:26 <jle`> does it not compile?
06:26 <ertes> iqubic: right thought process, wrong syntax
06:26 sanett joined
06:26 <Sh4rPEYE> Does not typechceck
06:26 <jle`> does it compile and give the write answer, but not terminate?
06:26 <jle`> alright
06:26 <Cale> ggVGc: It seemed to go pretty well. I wasn't strongly involved in it, but I was around, and would sometimes help explain something or answer questions.
06:27 <Sh4rPEYE> zipWithS :: (a -> b -> c) -> Stream a -> Stream b -> Stream c
06:27 <Sh4rPEYE> zipWithS f (x :> xs) (y :> ys) = f x y :> zipWithS f xs ys
06:27 <jle`> Sh4rPEYE: post your code and the error message
06:27 <iqubic> ertes: how is that the wrong syntax?
06:27 forgottenone joined
06:27 <Sh4rPEYE> Ok, I'm on it.
06:27 <jle`> Sh4rPEYE: then we can reasonably begin to start
06:27 <ertes> iqubic: in prefix form it's written like this: (:)
06:27 <iqubic> Ah.
06:28 <ertes> iqubic: and that's pretty much it
06:28 wroathe joined
06:28 <ggVGc> Cale: what age groups was that?
06:28 <ggVGc> and do you know in which way haskell was used?
06:28 <jle`> iqubic: but yeah, that's the general pattern for writing traversals for ADT's
06:28 <ertes> @let traverseList f [] = pure []; traverseList f (x : xs) = (:) <$> f x <*> traverseList f xs
06:28 <lambdabot> Defined.
06:28 <Cale> I guess they'd have been around 11 years old.
06:28 <ertes> > (traverseList +~ 5) [10,20,30]
06:28 <lambdabot> [15,25,35]
06:29 <ertes> iqubic: your code at work =)
06:29 <jle`> traverseFoo f (SomeConstructor x y z) = SomeConstructor <$> (something f) x <*> (something f) y <*> (something f) z
06:29 <ggVGc> Cale: I'm about to get involved with teaching children programming through a project my coworker is running. We're currently using lisp within a tool he's written, which is basically a REPL and a drawing area, and a small library for drawing. They seem to really get it
06:29 <Cale> ggVGc: I believe they worked through the book called "The Haskell Road to Logic, Maths and Programming"
06:29 <ggVGc> but I've been wondering if haskell would be a good candidate too
06:29 <iqubic> [1..10]^..traverseList
06:29 <iqubic> > [1..10]^..traverseList
06:29 <lambdabot> [1,2,3,4,5,6,7,8,9,10]
06:30 <Cale> Which is not the best Haskell book, and not the best math book, but it has an interesting combination of them.
06:30 <ggVGc> ah
06:30 <ertes> iqubic: want a more challenging exercise?
06:30 <ggVGc> this sounds like older ages
06:30 <iqubic> ertes: yes please.
06:30 <ggVGc> I'm talking 9-11 year olds
06:30 <ggVGc> even 8
06:30 <Cale> Well, they were that young, but they were reasonably bright.
06:30 <ertes> iqubic: write a traversal into the bits of a Word64
06:30 insitu joined
06:30 <ggVGc> oh
06:30 <Sh4rPEYE> Code: https://gist.github.com/EugLion/c8e34bf0335d824788eadda8678c101f
06:30 <ggVGc> that's cool
06:30 simukis_ joined
06:30 <iqubic> ertes: How do I access the bits of a Word64?
06:31 <ertes> iqubic: Data.Bits
06:31 <iqubic> I'm not too familiar with working with bits, or what a Word64 is.
06:31 <Sh4rPEYE> And it has some type problems with "Stream a0" and "Integer"
06:31 <ertes> iqubic: a Word64 is an unsigned 64 bits integer
06:31 <iqubic> Is it a seperate type?
06:32 <cocreature> Sh4rPEYE: please add the error message to your gist
06:32 <Cale> I think some might've been 9 or 10, I'm not sure any were younger than that
06:32 <ertes> iqubic: yeah, you need to import Data.Word
06:32 <iqubic> Alright.
06:32 <Cale> So I can say I taught a bunch of 10 year olds about monads and they got it.
06:32 <Cale> lol
06:33 <ertes> iqubic: one way to do it is to use testBit, setBit and clearBit from here: https://hackage.haskell.org/package/base-
06:33 <cocreature> Cale: how many burritos were involved in that? :P
06:33 <iqubic> How many bits in Word64?
06:33 <iqubic> And does that matter?
06:33 <Cale> cocreature: none
06:33 <cocreature> iqubic: 64, that’s why it’s called Word64
06:33 <ertes> iqubic: the type is: bitsWord64 :: (Applicative f) => (Bool -> f Bool) -> Word64 -> f Word64
06:33 <iqubic> LOL
06:33 <iqubic> and will I use recursion for that?
06:34 <iqubic> or what?
06:34 <Sh4rPEYE> cocreature: Done.
06:34 <iqubic> How will I apply an operation 64 times?
06:34 <ertes> feel free to write this instead: bitsWord64 :: Traversal' Word64 Bool
06:34 __bluebell__ joined
06:34 <ertes> iqubic: strictly speaking you don't need recursion, but you should use it anyway
06:34 <jle`> iqubic: well, you applied an operation 2 times, with traverseBoth
06:34 <cocreature> Sh4rPEYE: try declaring :> as infixr
06:35 kody joined
06:35 <ertes> iqubic: if you're wondering how exactly to use the recursion, try to write your own replicateM_
06:35 <iqubic> What does replicateM_ do?
06:35 <kellytk> Is https://github.com/jameysharp/corrode/blob/master/Main.md an example of Haskell code? Including the comments
06:35 <ertes> iqubic: replicateM_ 5 c = c *> c *> c *> c *> c *> pure ()
06:36 <ertes> :t replicateM_
06:36 <lambdabot> Applicative m => Int -> m a -> m ()
06:36 <cocreature> kellytk: it’s a markdown file with Haskell code blocks in it
06:36 <kellytk> Oh
06:36 __bluebell__ joined
06:36 baldrick1 joined
06:36 <kellytk> What do comments look like?
06:36 <geekosaur> -- something here
06:36 <cocreature> or {- comments -}
06:36 <geekosaur> or: {- something here -} thois is outside the comment
06:37 <Sh4rPEYE> infixr
06:37 <cocreature> in particular the latter allows for multiline comments
06:37 <iqubic> So replicateM_ is running the function s to itself n times?
06:37 <kellytk> Thanks
06:37 <geekosaur> also beware of {-# #-} which is a pragma
06:37 <Sh4rPEYE> cocreature: reat, that worked! thanks
06:37 <cocreature> Sh4rPEYE: "infixr :>" should be sufficient
06:37 <cocreature> Sh4rPEYE: the problem is that by default you’ll get (1 :> 2) :> … instead of 1 :> (2 :> …)
06:37 <ertes> iqubic: let me write that differently:
06:37 <Sh4rPEYE> cocreature: Yes, it now typechecks :-)
06:38 <kellytk> How would you distribute the categories of Haskell's use across client apps, server code, and a wildcard I don't even know about?
06:38 <ertes> iqubic: replicateM_ 5 c = c *> (c *> (c *> (c *> (c *> pure ()))))
06:38 wroathe joined
06:38 <iqubic> do I need guards for this?
06:38 <ertes> iqubic: happen to know a shorter way to write c *> (c *> (c *> (c *> pure ())))?
06:38 <iqubic> I do.
06:38 <ertes> tell me
06:39 <iqubic> Wait, I actually don't know how to do that.
06:39 <ertes> iqubic: given replicateM_ …
06:39 <iqubic> replicateM_ 5 c
06:39 <Cale> kellytk: At the company I work for, we use Haskell to develop web and mobile applications, and use it both for the frontend and backend.
06:40 <ertes> iqubic: let me use a different example: fac 5 = 5 * (4 * (3 * (2 * 1)))
06:40 <Cale> kellytk: It's really nice being able to share a bunch of types and code between those
06:40 <ertes> iqubic: the factorial function… happen to know a shorter way to write (4 * (3 * (2 * 1)))?
06:40 <kellytk> Cale: How do you use it for the frontend? Is there a good translator to iOS/Android?
06:40 <iqubic> I know how the factorial function works.
06:40 indi_ joined
06:41 ubsan_ joined
06:41 <Cale> kellytk: We use GHCJS to compile to Javascript for the web, and GHC's ARM support to compile the same code for iOS and Android (and we're using JSaddle right now to make that work)
06:41 <ertes> iqubic: i don't doubt that… i'm using these examples to reinforce a pattern =)
06:41 <iqubic> I don't know the pattern.
06:41 safe joined
06:41 <ertes> fac 5 = 5 * _shorterWayToWriteTheRest
06:41 <ertes> fill this in
06:42 <iqubic> fac ( 5 -1
06:42 <Cale> kellytk: Well, specifically, the jsaddle branch of reflex-platform
06:42 <ertes> yeah
06:42 <Cale> https://github.com/reflex-frp/reflex-platform
06:42 Destol joined
06:42 <kellytk> Cale: That sounds quite interesting. Is there a large and active enough community that you see it not only continuing development but growing?
06:42 <ertes> iqubic: now use the same logic for replicateM_
06:42 <kellytk> I found that earlier it looks good
06:42 <iqubic> fac 0 = 1; fac n = fac (n - 1)
06:42 <Cale> Well, we're sort of in the middle of it :)
06:42 govg joined
06:42 <ertes> iqubic: replicateM_ 5 c = c *> _shorterWayToWriteTheRest
06:43 <Cale> It would probably continue if we vanished, but it would probably take some time before anyone was as well equipped as Ryan Trinkle to really work on it.
06:43 <Cale> (On reflex and reflex-dom anyway)
06:43 baldrick2 joined
06:44 <kellytk> Cale: That's an obvious concern, can you think of a tradeoff that makes it worth it?
06:44 connrs joined
06:44 <Cale> Well, it's just ridiculously more productive than anything else
06:44 <iqubic> replicateM_ 0 f = pure (); replicateM_ n f = f *> replicateM_ (n - 1) f
06:44 <iqubic> got that.
06:44 takuan joined
06:44 <ertes> iqubic: exactly
06:44 <kellytk> Cale: Have you written web front/backends and mobile apps natively before?
06:44 xcmw joined
06:44 <Cale> kellytk: Some
06:44 <iqubic> Now, how does that help use write a traversal into the bits of a Word64?
06:44 <ertes> iqubic: now here is how you print "hello world" 64 times: replicateM_ 64 (putStrLn "Hello world!")
06:45 <ertes> iqubic: emphasis is on "64"
06:45 <iqubic> Alright then.
06:45 <iqubic> Is see.
06:45 <iqubic> Now what it the signature for the traversal?
06:45 <ertes> bitsWord64 :: (Applicative f) => (Bool -> f Bool) -> Word64 -> f Word64
06:46 <iqubic> Cool.
06:46 <kellytk> Cale: How is it better than that?
06:46 <kellytk> I should say, more productive which were you words
06:46 <iqubic> Now how do I run the function 64 times on 64 *different* bits?
06:46 <Cale> kellytk: Well, a bunch of things come together. The main thing though I'd have to say is that Haskell's type system makes refactoring a lot simpler.
06:47 <Cale> kellytk: I can start changing something on the backend, and the type errors will bleed through to the frontend and tell me everything I need to update.
06:47 <iqubic> ertes: I know how to get a bit, and set a bit again.
06:47 <kellytk> Cale: Could the same not be experienced with TypeScript?
06:47 uuplusu joined
06:48 <ertes> iqubic: here is a variant of replicateM_ that communicates the current counter value: constructM_ 0 _ = pure (); constructM_ n f = f n *> constructM_ (n - 1) f
06:48 <Cale> kellytk: I don't know TypeScript all that well, but somehow I doubt that its type system is anywhere close to as expressive as Haskell's
06:48 wroathe joined
06:48 <jle`> Sh4rPEYE: not sure if you already solved your problem, but try adding parentheses to see what's wrong
06:48 <iqubic> :t constructM_
06:48 <lambdabot> error: Variable not in scope: constructM_
06:48 <jle`> oh wait you already got it, nvm
06:48 <iqubic> why is that not in scope?
06:48 <ertes> iqubic: and here is a program that prints the numbers [64,63..1]: constructM_ 64 print
06:48 <Cale> kellytk: I'm sure it would get you a little of that though.
06:48 <ertes> iqubic: because i invented it =)
06:49 <iqubic> Oh.
06:49 <ertes> iqubic: in practice you would just use 'traverse_' from Data.Foldable
06:49 <iqubic> what does that do?
06:49 <Cale> kellytk: The type system is a lot more meaningful in Haskell than in most other industrially-viable languages
06:49 <ertes> :t traverse_
06:49 <lambdabot> (Applicative f, Foldable t) => (a -> f b) -> t a -> f ()
06:49 xinming joined
06:49 <ertes> :t traverse_ print [64,63..1]
06:49 <lambdabot> IO ()
06:49 <iqubic> That's a traversal that throws out the result
06:49 <ertes> *results, yeah
06:50 <iqubic> Alright.
06:50 <iqubic> But don't we want the results when working with a travesal?
06:50 <kellytk> Cale: Can it do usual things like connect to a PostgreSQL/SQLite instance or process command-line input?
06:50 <Cale> kellytk: As an example, on one of our client projects, a chat application which is kind of slack-like but with a bunch of other features, such as integration with email (you can send an email from a channel and the replies will come back there), task management and other organisational features
06:50 vaibhavsagar joined
06:50 <ertes> iqubic: yes, this is just conceptual to give you an idea on how to implement the traversal
06:51 <kellytk> Very real-worldy there
06:51 kylepotts joined
06:51 <Cale> We'd been working on it about a year, and a coworker and I took 2-3 days to turn it into a multi-tenant app
06:51 <iqubic> I have no idea how to implement that traversal
06:51 <Cale> with one backend serving multiple database schemas on subdomains
06:51 <iqubic> I'm sorry.
06:51 <Cale> that are kept secure from one another
06:52 <iqubic> ertes: Can you help me with that?
06:52 <Cale> I think in just about anything else, that change easily might've taken weeks
06:52 <iqubic> traverseList f (x:xs) = : <$> f x <*> traverseList f xs
06:52 <Cale> kellytk: and yeah, it connects to postgresql
06:52 <iqubic> So there we're appending the results into a new list.
06:52 <ertes> iqubic: it's not that different from the list traversal: bitsWord64 f x = combineBits <$> bitWord64 0 f x <*> bitWord64 1 f x <*> … <*> bitWord64 63 f x
06:53 <kellytk> Cale: https://github.com/search?utf8=%E2%9C%93&q=haskell+graphql&type=Repositories it even has GraphQL implementations. Is the JS generation good enough to write a web client that gets data via a GraphQL API?
06:53 takle joined
06:53 <ertes> iqubic: bitWord64 :: (Functor f) => Int -> (Bool -> f Bool) -> Word64 -> f Word64
06:53 <kellytk> (and build the GraphQL server of course but I infer that's possible)
06:53 <iqubic> ertes: I need to right my own combineBits function though.
06:54 <iqubic> That doesn't exist.
06:54 <ertes> iqubic: not really… again, this is conceptual
06:54 <iqubic> Oh.
06:54 revprez_atlanta joined
06:54 <iqubic> So what should I do?
06:54 <Cale> kellytk: I'm sure all the parsing stuff would compile. The network I/O probably wouldn't make sense directly.
06:54 xcmw joined
06:54 <Cale> kellytk: You'd have to replace that bit with some XHR or something.
06:55 <Cale> But I'm sure it wouldn't be too hard.
06:55 <kellytk> Cale: When going outside the paved, is it much trouble?
06:55 <ertes> iqubic: let me think of an example i can write for you that doesn't spoil this exercise, but gives you a good clue
06:56 <Cale> kellytk: Well, Haskell is almost as nice a language as you could ask for as a baseline.
06:56 vlatkoB joined
06:56 kylepotts joined
06:56 <Cale> kellytk: and of course, there's FFI in cases where you really don't want to rebuild something in Haskell
06:57 <Cale> e.g. we use Javascript FFI to do stuff with Google Maps in a couple of our apps
06:57 <ertes> iqubic: are you familiar with the 'vector' library?
06:57 <iqubic> Yes. I am
06:57 <iqubic> This exercise is quite hard.
06:57 <Cale> and of course, there's FFI on the backend which binds the Postgres C library.
06:57 <ertes> iqubic: i'll write a horribly inefficient traversal into the elements of a vector, and i'll deliberately use indexing
06:57 <Cale> (we didn't have to write that of course, but someone did)
06:57 <ertes> iqubic: yes, it is
06:58 <iqubic> I like trying this.
06:58 indi_ joined
06:58 wroathe joined
06:59 <kellytk> So Haskell can call out to other code, such as a JS package from NPM?
07:00 <Cale> Well, the stuff compiled with GHCJS can call out to other Javascript code
07:00 <iqubic> ertes: you got that example using the vector library?
07:01 <Cale> (and the stuff using JSaddle can run Javascript code as well, though that bit works a little different)
07:02 <Cale> kellytk: this is quite a good talk given by Ryan about reflex and reflex-dom https://www.youtube.com/watch?v=dOy7zIk3IUI
07:02 <Cale> He builds a little twitter client as an example
07:02 eazar001 joined
07:02 <kellytk> Cale: Thank you for your time you've been generous with it. My last question for now, what are the 2 primary downsides to writing and running Haskell other than gaps in existing libraries
07:02 Sh4rPEYE joined
07:03 <kellytk> Thank you I look forward to watching it
07:03 <ertes> iqubic: i'm writing it
07:03 <iqubic> Got it. I'll wait.
07:04 <Cale> kellytk: 1) Compile times on large projects can be long -- there's stuff which can be done to mitigate that effect while developing, but for a real optimised build, our compile times are often pretty crazy. I think a full deployment on our largest project (including building the mobile apps, as well as the backend and web frontend) takes us about an hour now.
07:05 <Cale> The lion's share of that is due to our use of Template Haskell -- TH in GHCJS is quite slow, since it spins up a node instance to execute Javascript at compile time.
07:07 <ertes> iqubic: http://lpaste.net/354605
07:07 orbifx joined
07:07 <ertes> iqubic: unlike the list traversal this one does not use recursion on the vector itself, but on a running index
07:08 <iqubic> I see.
07:08 <iqubic> I was thinking I'd do that too.
07:08 <Cale> 2) I dunno -- maybe the general fact that Haskell is pretty different, and so if you're new to it, you're going to need to relearn stuff like how to spot and deal with various performance issues, even once you have a good handle on the language.
07:08 wroathe joined
07:08 <iqubic> ertes: I don't know what I'd do for the pure part at the end though.
07:09 <ertes> iqubic: look how i'm building a vector from scratch starting with the empty one
07:09 <iqubic> Why are you doing that? Isn't that bad??
07:09 <ertes> iqubic: look at the title of that paste =)
07:10 <Cale> I suppose an alternative to #2 is that the stuff in this particular area is all quite new and moving fast, and so the documentation is not as good as one would really hope in various places.
07:10 <iqubic> Ah.
07:10 <ertes> iqubic: it's bad for vectors, but it will be good for Word64 bits
07:10 <Cale> You will end up grepping source code more often than you might care to do.
07:10 <iqubic> I see.
07:11 crobbins joined
07:11 <Cale> kellytk: We are hoping to work on that soon though, and there are some people starting to write reflex-dom documentation for us :)
07:11 <iqubic> I have just a little bit more of an idea how to do this traversal.
07:11 vlatkoB_ joined
07:12 boombanana joined
07:12 <ertes> iqubic: take your time… this one is quite challenging
07:12 <iqubic> I will take my time.
07:12 augur joined
07:12 <Cale> http://reflex-frp.readthedocs.io/en/latest/ -- Divam wrote some user contrib docs... I haven't even had the time to really read them, but it's good that people are getting into it. I feel a bit guilty for not actually doing this myself. :)
07:13 <iqubic> What is the type signature again?
07:13 <ertes> iqubic: if you can write this one, you can write any traversal you want =)
07:13 <iqubic> Really?
07:13 <ertes> bitsWord64 :: (Applicative f) => (Bool -> f Bool) -> Word64 -> f Word64
07:13 SimpleL joined
07:13 <iqubic> Do I import Data.Word?
07:13 <ertes> yeah, you need it for Word64
07:14 <iqubic> Cool
07:14 <iqubic> And do I need ot import Data.Bits?
07:14 <iqubic> *to
07:14 <ertes> if you want to write it in terms of clearBit/setBit/testBit, then yes
07:15 puregreen joined
07:15 locallycompact joined
07:15 <iqubic> I will do that
07:15 <kellytk> Cale: Oh is Reflex your project? You said Haskell can generate JS, can it also generate TypeScript?
07:16 <Cale> kellytk: I don't believe there's a typescript backend for GHC -- at least I haven't heard about one
07:16 <iqubic> Cale, did you help make Reflex
07:16 <iqubic> ??
07:17 <ertes> iqubic: one challenging aspect of this is that the compiler will not help you as much as it did with traverseFst… there is in fact an enormous number of functions that fit this signature, only one of which is correct
07:17 <Cale> iqubic: only a very small amount -- basically I worked with Ryan on some earlier FRP systems (an arrowized system that we used on a gamedev project back in 2011-2012), and we figured out a lot of things about how we wanted our FRP system to work
07:17 raichoo joined
07:17 <ertes> @djinn (Functor f) => (a -> f b) -> (a, c) -> f (b, c)
07:17 <lambdabot> Error: Class not found: Functor
07:17 <ertes> really?
07:17 <iqubic> ertes: I will try to get something that will work
07:18 richi235 joined
07:18 <Cale> iqubic: and then a few years later, Ryan started working on a new FRP system (which eventually became Reflex), and it has a bunch of features of the design of our earlier system
07:18 <ertes> @djinn (forall a b. (a -> b) -> f a -> f b) -> (a -> f b) -> (a, c) -> f (b, c)
07:18 <lambdabot> -- f cannot be realized.
07:18 <MarcelineVQ> ertes: exferenceBot can write that for you if you wanted it to be shown
07:18 <ertes> lambdabot: come on…
07:18 <Cale> iqubic: I've contributed a very very small amount of code to reflex and reflex-dom
07:18 <Cale> iqubic: Mostly my job just involves using those. :)
07:18 takle joined
07:18 <ertes> MarcelineVQ: how do i talk to it?
07:18 <MarcelineVQ> :exf (Functor f) => (a -> f b) -> (a, c) -> f (b, c)
07:18 <exferenceBot> \ f1 b -> let ((,) d e) = b in fmap (\ h -> (h, e)) (f1 d)
07:18 <ertes> ah
07:18 wroathe joined
07:19 <iqubic> what does exferenceBot do?
07:19 <kellytk> Cale: Thanks for your help
07:19 <ertes> it does what djinn is supposed to do =)
07:19 <ertes> :exf a -> b -> a
07:19 <exferenceBot> parse error: more than one input
07:19 <iqubic> LOL.
07:19 <Cale> kellytk: no problem, if you end up getting interested in playing with reflex, there's a #reflex-frp on this IRC network
07:19 <ertes> the bots don't like me today
07:19 <MarcelineVQ> bad luck tonight
07:19 <iqubic> Nope
07:20 <iqubic> :exf a -> b -> a
07:20 <exferenceBot> parse error: more than one input
07:20 _paul0 joined
07:20 <ertes> @djinn a -> b -> a
07:20 <lambdabot> f a _ = a
07:20 <iqubic> :exf a -> b -> (a -> b)
07:20 <exferenceBot> parse error: more than one input
07:21 <ertes> iqubic: given a type, @djinn writes a function of that type, if possible
07:21 <Myrl-saki> @djinn Int -> Int
07:21 <lambdabot> Error: Undefined type Int
07:21 <Myrl-saki> Oh.
07:21 <iqubic> Oh. I see.
07:21 <ertes> @djinn ((a -> b) -> f a -> f b) -> (a -> f b) -> (a, c) -> f (b, c)
07:21 <lambdabot> -- f cannot be realized.
07:22 <ertes> lambdabot: come on… that one is easy!
07:22 <ertes> ah, no
07:22 <Myrl-saki> @djinn Functor f => (a -> b) -> f a -> f b
07:22 <lambdabot> Error: Class not found: Functor
07:22 <ertes> @djinn ((a -> (b, c)) -> f a -> f (b, c)) -> (a -> f b) -> (a, c) -> f (b, c)
07:22 <lambdabot> -- f cannot be realized.
07:22 <ertes> @djinn ((b -> (b, c)) -> f b -> f (b, c)) -> (a -> f b) -> (a, c) -> f (b, c)
07:22 <lambdabot> f a b (c, d) = a (\ e -> (e, d)) (b c)
07:22 <ertes> there we go
07:22 <ertes> a = fmap
07:23 <ertes> djinn can't handle higher-rank types?
07:23 <iqubic> I am having a lot of trouble witht the traversal into the Bits of a Word64
07:23 <ertes> @djinn (forall x y. (x -> y) -> f x -> f y) -> (a -> f b) -> (a, c) -> f (b, c)
07:23 <lambdabot> -- f cannot be realized.
07:23 <ertes> apparently not
07:24 <iqubic> I can't seem to get this traversal to work correctly.
07:24 <ertes> iqubic: if you can't figure it out, take a break
07:24 <ertes> let everything sink in for a while
07:24 <iqubic> I will try it again later.
07:25 <iqubic> Is it super hard???
07:25 bjz joined
07:25 <ertes> iqubic: not super-hard, but it's definitely challenging
07:25 <Myrl-saki> Would it be smart to have 2 compilations? Compile everything except main, then have a specialized compilation for main, which links the function calls?
07:25 <ertes> iqubic: i can give you super-hard ones, after you solved this one =)
07:25 <iqubic> No.
07:25 <Myrl-saki> Not smart.
07:25 <Myrl-saki> I mean, would it be a good idea.
07:25 <iqubic> ertes: I want to solvle this first.
07:26 eacameron joined
07:26 connrs joined
07:27 halogenandtoast joined
07:27 <MarcelineVQ> what sig are we implementing?
07:27 <iqubic> @let x = traverse setBit [1..10]
07:27 <lambdabot> Defined.
07:27 <iqubic> > x 0
07:27 <lambdabot> error:
07:27 <lambdabot> Ambiguous occurrence ‘x’
07:27 <lambdabot> It could refer to either ‘Debug.SimpleReflect.x’,
07:27 <ertes> MarcelineVQ: bitsWord64 :: (Applicative f) => (Bool -> f Bool) -> Word64 -> f Word64
07:27 <ertes> MarcelineVQ: a traversal into the individual bits of Word64
07:28 <iqubic> > (traverse setBit [1..10]) 0
07:28 <lambdabot> [1,3,3,5,5,7,7,9,9,11]
07:28 <iqubic> > (traverse setBit [1..10]) 1
07:28 bhiliyam joined
07:28 <lambdabot> [3,2,3,6,7,6,7,10,11,10]
07:28 <iqubic> What is that doing?
07:28 <iqubic> > (traverse setBit [1..10]) 2
07:28 <lambdabot> [5,6,7,4,5,6,7,12,13,14]
07:28 <iqubic> I don't understand that at all.
07:28 <Myrl-saki> :t traverse
07:28 <lambdabot> (Applicative f, Traversable t) => (a -> f b) -> t a -> f (t b)
07:28 <iqubic> :t setBit
07:28 <lambdabot> Bits a => a -> Int -> a
07:28 <ertes> iqubic: you're using the following Applicative instance: instance Applicative ((->) a)
07:29 <iqubic> Sure am.
07:29 <iqubic> So what is it doing
07:29 wroathe joined
07:29 albertus1 joined
07:29 <iqubic> :t x
07:29 <lambdabot> error:
07:29 <lambdabot> Ambiguous occurrence ‘x’
07:29 <lambdabot> It could refer to either ‘Debug.SimpleReflect.x’,
07:29 ggVGc_ joined
07:29 <ertes> > (f <*> g) x = f x (g x)
07:29 <lambdabot> <hint>:1:13: error:
07:29 <lambdabot> parse error on input ‘=’
07:29 <lambdabot> Perhaps you need a 'let' in a 'do' block?
07:29 <ertes> whoops
07:29 <ertes> (f <*> g) x = f x (g x)
07:29 <ertes> iqubic: that's the semantics of this particular instance
07:29 <iqubic> Oh, I see.
07:30 <Myrl-saki> Ah. Reader.
07:30 <ertes> liftA2 (+) sin cos x = sin x + cos x
07:30 t0by joined
07:30 t0by joined
07:30 <ertes> iqubic: we call these reader monads =)
07:30 <iqubic> I see.
07:30 <iqubic> That's cool
07:30 <Myrl-saki> (Also called as the "please don't use this monad")
07:30 albertus1 joined
07:31 <ertes> or at least: don't abuse this monad for point-free style
07:31 <iqubic> I just figured out how to do this thing.
07:31 <Myrl-saki> ertes: I love the applicative instance though!
07:31 <iqubic> I think I figured out how to do the thing.
07:31 <iqubic> does the number 0 count as a word64?
07:31 <ertes> iqubic: sure
07:32 <ertes> it's 64 bits of 0
07:32 <iqubic> Cool.
07:32 <iqubic> That helps me.
07:32 <kellytk> Cale: What do you use to run Haskell apps on iOS?
07:33 <iqubic> > pure 0
07:33 <lambdabot> error:
07:33 <lambdabot> • Ambiguous type variables ‘f0’, ‘a0’ arising from a use of ‘show_M73440...
07:33 <lambdabot> prevents the constraint ‘(Show (f0 a0))’ from being solved.
07:33 <iqubic> I don't think that's right.
07:33 <ertes> > pure 0 :: [Integer]
07:33 <iqubic> > pure 0 :: Int
07:33 jgt joined
07:33 <lambdabot> [0]
07:33 <lambdabot> error:
07:33 <lambdabot> • Couldn't match expected type ‘Int’ with actual type ‘f0 Integer’
07:33 <lambdabot> • In the expression: pure 0 :: Int
07:34 <iqubic> > pure 0 :: [Int]
07:34 <lambdabot> [0]
07:34 plutoniix joined
07:34 <iqubic> Does Word64 have a pure function?
07:34 <Myrl-saki> No.
07:34 <Myrl-saki> It's not a Functor.
07:34 <ertes> 'pure' is unrelated to Word64 here
07:35 <iqubic> but how does our traversal return an f Word64?
07:35 <ertes> iqubic: but Identity and (Const a) have 'pure'
07:35 plutoniix joined
07:35 <Myrl-saki> :k Functor
07:35 <lambdabot> (* -> *) -> Constraint
07:35 <ertes> iqubic: using 'pure'
07:35 <ertes> you do need it, but it has nothing to do with Word64
07:35 <iqubic> but Word64 is not a functor?
07:35 <iqubic> What the heck is going on here???
07:36 <ertes> f is a functor
07:36 <ertes> look at the type signature again
07:36 <iqubic> yes, but of what type??
07:36 <iqubic> What kind of functor do I use here?
07:36 <ertes> f *is* a type
07:36 <ertes> you don't get to choose the functor
07:36 <iqubic> I don't
07:36 <ertes> all you know is that f is Applicative
07:36 <iqubic> right.
07:36 <iqubic> So I can use pure and have it work??
07:36 <ertes> that means you can use 'pure'
07:38 <iqubic> How do I create a Word64?
07:38 <Myrl-saki> > 0 :: Word64
07:38 <ertes> > 0 :: Word64
07:38 <lambdabot> 0
07:38 <lambdabot> 0
07:38 <ertes> hehe
07:38 <Myrl-saki> ertes: :D
07:38 <ertes> iqubic: Word64 is a Num and a Bits
07:38 OscarZ joined
07:38 CoderPuppy joined
07:38 <iqubic> LOL.
07:38 dan_f joined
07:38 <iqubic> I see now.
07:39 wroathe joined
07:40 zeroed joined
07:40 <iqubic> This is hard. Can you just give me the solution?
07:41 eacameron joined
07:41 Denthir joined
07:41 <iqubic> Actually, don't do that. I like the challenge
07:42 <Myrl-saki> > me when trying to understand monads
07:42 <lambdabot> error:
07:42 <lambdabot> Ambiguous occurrence ‘trying’
07:42 <lambdabot> It could refer to either ‘Control.Exception.Lens.trying’,
07:42 <iqubic> Myrl-saki: Do you understand monads?
07:42 <Myrl-saki> > does it trigger with a space before it?
07:42 <Myrl-saki> Phew.
07:42 <Myrl-saki> iqubic: Now I do.
07:42 <MarcelineVQ> ​> space
07:43 connrs joined
07:43 <Myrl-saki> MarcelineVQ: H o w
07:43 <Myrl-saki> MarcelineVQ: NBSP?
07:43 <iqubic> I don't understand traversals at all.
07:43 <Myrl-saki> MarcelineVQ: Unprintable unicode?
07:43 forgottenone joined
07:43 <ertes> iqubic: i'm gonna give you the solution, but it will not help you, because i write it the ertes way =)
07:43 eklavya joined
07:44 <ertes> :t foldr (\i go -> (\b y -> (if b then setBit else clearBit) y i) <$> f (testBit x i) <*> go) (pure 0) [0..63]
07:44 <lambdabot> error:
07:44 <lambdabot> Ambiguous occurrence ‘x’
07:44 <lambdabot> It could refer to either ‘Debug.SimpleReflect.x’,
07:44 <ertes> :t \f x -> foldr (\i go -> (\b y -> (if b then setBit else clearBit) y i) <$> f (testBit x i) <*> go) (pure 0) [0..63]
07:44 <iqubic> Is that the solution??
07:44 <lambdabot> (Num b, Bits a, Bits b, Applicative f) => (Bool -> f Bool) -> a -> f b
07:44 <ertes> that's my solution =)
07:44 <Myrl-saki> ertes: lmao
07:44 <iqubic> But it doesn't have the right type.
07:44 <ertes> it does =)
07:44 <ertes> @let bitsWord64 :: (Applicative f) => (Bool -> f Bool) -> Word64 -> f Word64; bitsWord64 f x = foldr (\i go -> (\b y -> (if b then setBit else clearBit) y i) <$> f (testBit x i) <*> go) (pure 0) [0..63]
07:44 <iqubic> so a is the same type as b?
07:44 <lambdabot> Defined.
07:45 <Myrl-saki> lambdabot: Can I try it out myself?
07:45 <ertes> :t bitsWord64
07:45 <lambdabot> Applicative f => (Bool -> f Bool) -> Word64 -> f Word64
07:45 <ertes> iqubic: ^
07:45 <Myrl-saki> ertes: Can I try it out myself?
07:45 <iqubic> How does that work?
07:45 <iqubic> How does that function work?
07:45 <ertes> Myrl-saki: what?
07:45 <Myrl-saki> ertes: What is being defined?
07:46 kylepotts joined
07:46 <ertes> iqubic: instead of using recursion on an index, i fold a list of indices
07:46 <ertes> iqubic: the result is the same… it's just shorter to write
07:46 <iqubic> You do? why do you do that?
07:47 <iqubic> when do you apply the function f?
07:47 <ertes> look closely
07:47 <iqubic> I see it there.
07:47 <ertes> Myrl-saki: not sure what you mean
07:48 <iqubic> How does this let me right any traversal I want?
07:48 <Myrl-saki> ertes: I read the types. I understand now.
07:48 emmanuel_erc left
07:48 <ertes> > showHex ((bitsWord64 %~ not) 0xFFFFFFFF00000000) ""
07:48 <lambdabot> "ffffffff"
07:48 <ertes> > showHex ((bitsWord64 %~ not) 0xFFFFFFFF) ""
07:48 <lambdabot> "ffffffff00000000"
07:49 <ertes> iqubic: as i said, my solution is not going to help you
07:49 <ertes> iqubic: i've written it this way *specifically* to not be helpful
07:49 <iqubic> Wait, that's not the solution you want me to write?
07:49 <iqubic> Gosh darn it.
07:49 <ertes> iqubic: correct =)
07:49 <iqubic> I don't even understand that function.
07:50 <ertes> iqubic: look at the vector code from earlier… that one i wrote to be helpful
07:50 <iqubic> I tried that. Couldn't get that to work.
07:51 kylepotts joined
07:51 <ertes> iqubic: then give it a break… eat something, watch a movie, listen to some music, then try again
07:51 <iqubic> http://termbin.com/8v0v
07:51 <iqubic> That doesn't work.
07:51 armyriad joined
07:51 <ertes> iqubic: allow your subconscious to work on it for a while… that helps a lot
07:52 <MarcelineVQ> it does as annoying as that can seem
07:52 <ertes> iqubic: 'bit' does not do what you expect it to do
07:52 <iqubic> It doesn't?
07:52 <iqubic> What does it do?
07:52 <ertes> > bit 0 :: Integer
07:52 <lambdabot> 1
07:52 <ertes> > bit 4 :: Integer
07:52 <lambdabot> 16
07:52 <MarcelineVQ> "bit i is a value with the ith bit set and all other bits clear."
07:53 <kellytk> What kinds of programs is Haskell the wrong choice for?
07:53 <iqubic> Oh, yeah it doesn't do what I want
07:53 wroathe joined
07:54 <ertes> iqubic: but you're on the right track with your template
07:54 <iqubic> Yeah, I know.
07:54 <iqubic> I copied the template from your vector example.
07:54 mrcrjs joined
07:55 <Myrl-saki> traverse = sequence . map
07:55 <Myrl-saki> fmap*
07:55 filterfish joined
07:55 takle joined
07:55 <Myrl-saki> Errr, I'm probably missing some parentheses there?
07:55 seveg joined
07:55 <Myrl-saki> traverse f = sequence . fmap f
07:56 <MarcelineVQ> (sequence .) . fmap if you're feeling adventurous
07:56 <MarcelineVQ> don't feel too adventurous
07:56 <iqubic> http://termbin.com/4sno
07:56 <iqubic> Not working either.
07:56 <iqubic> I think my combination function is wrong.
07:56 <mniip> traverse = ((.) . (.)) sequence fmap
07:57 eacameron joined
07:57 <iqubic> (.|.) is not the right combination function to use there.
07:58 <iqubic> I don't know what is though.
07:59 <tsahyt> mniip: that's an evil way of writing this
07:59 <MarcelineVQ> sometimes being bad feels pretty darn good
07:59 <Cale> :t fmap fmap fmap sequence fmap
07:59 <lambdabot> (Monad m, Traversable t) => (a1 -> m a) -> t a1 -> m (t a)
08:00 <ertes> @let bitsWord64' f x = foldr (\i -> liftA2 (fmap ($ i) . bool clearBit setBit) (f (testBit x i))) (pure 0) [0..63]
08:00 <lambdabot> Defined.
08:01 <tsahyt> :t \f -> sequence . fmap f
08:01 <lambdabot> (Monad m, Traversable t) => (a1 -> m a) -> t a1 -> m (t a)
08:01 <tsahyt> that's still not exactly traverse though
08:01 <tsahyt> :t \f -> sequenceA . fmap f
08:01 <Cale> :t fmap fmap fmap sequenceA fmap
08:01 <lambdabot> (Applicative f, Traversable t) => (a1 -> f a) -> t a1 -> f (t a)
08:01 <lambdabot> (Applicative f, Traversable t) => (a1 -> f a) -> t a1 -> f (t a)
08:01 <iqubic> ertes: I think I cracked the code.
08:01 <ertes> @let bits f x = foldr (\i -> liftA2 (fmap ($ i) . bool clearBit setBit) (f (testBit x i))) (pure 0) [0 .. finiteBitSize x - 1]
08:01 <lambdabot> Defined.
08:02 <ertes> > (15 :: Word8) ^.. bits
08:02 revprez_atlanta joined
08:02 <lambdabot> error:
08:02 <lambdabot> Ambiguous occurrence ‘bits’
08:02 <lambdabot> It could refer to either ‘Data.Bits.Lens.bits’,
08:02 <ertes> d'oh
08:02 <ertes> @let _bits f x = foldr (\i -> liftA2 (fmap ($ i) . bool clearBit setBit) (f (testBit x i))) (pure 0) [0 .. finiteBitSize x - 1]
08:02 <lambdabot> Defined.
08:02 <ertes> > (15 :: Word8) ^.. _bits
08:02 <lambdabot> [True,True,True,True,False,False,False,False]
08:02 <ertes> iqubic: great… show me
08:03 eacameron joined
08:04 wroathe joined
08:04 <Myrl-saki> lmao
08:05 <mniip> > set _bits True undefined :: Int64
08:05 <lambdabot> error:
08:05 <lambdabot> • Ambiguous type variable ‘b10’ arising from a use of ‘_bits’
08:05 <lambdabot> prevents the constraint ‘(FiniteBits b10)’ from being solved.
08:05 <mniip> > set _bits True (undefined :: Int64)
08:05 <lambdabot> 18446744073709551615
08:05 <mniip> wait... that's no Int
08:05 <ertes> huh?
08:06 <ertes> > finiteBitSize (0 :: Int64)
08:06 <lambdabot> 64
08:06 <ertes> that should be negative
08:06 <mniip> yes
08:06 <mniip> :t set _bits True (undefined :: Int64)
08:06 <lambdabot> (Bits t, Num t) => t
08:06 <mniip> that explaains it
08:06 <iqubic> Is there a way to get the number of bits a number has?
08:06 <mauke> define "has"
08:07 <ertes> > setBit 0 63 :: Int64
08:07 <lambdabot> -9223372036854775808
08:07 <iqubic> Like find out that 4 takes two bits two right.
08:07 <iqubic> *write
08:07 <iqubic> *to
08:07 <mauke> ah, position of the highest bit
08:07 fuzzy-id joined
08:07 <iqubic> yes that.
08:07 <iqubic> That is what I nee
08:07 <iqubic> *d
08:07 <mniip> ceil . logBase 2
08:07 <mniip> or something
08:08 <ertes> iqubic: finiteBitSize
08:08 <mniip> otherwise bitwise tricks
08:08 azahi joined
08:08 <mauke> :t finiteBitSize
08:08 <iqubic> thanks ertes
08:08 <lambdabot> FiniteBits b => b -> Int
08:08 <mauke> > finiteBitSize 4
08:08 <lambdabot> error:
08:08 <lambdabot> • Ambiguous type variable ‘b0’ arising from a use of ‘finiteBitSize’
08:08 <lambdabot> prevents the constraint ‘(FiniteBits b0)’ from being solved.
08:08 <mauke> > finiteBitSize (4 :: Integer)
08:08 <Myrl-saki> > bitSize (4 :: Integer)
08:08 <ertes> ah, wait
08:08 <lambdabot> error:
08:08 <lambdabot> • No instance for (FiniteBits Integer)
08:08 <lambdabot> arising from a use of ‘finiteBitSize’
08:08 <lambdabot> *Exception: Data.Bits.bitSize(Integer)
08:08 <mauke> > finiteBitSize (4 :: Int)
08:08 <Myrl-saki> Wait what
08:08 <lambdabot> 64
08:08 <ertes> iqubic: i think you're asking for something else
08:08 <mauke> yeah, no
08:08 <mauke> > finiteBitSize (undefined :: Int)
08:08 <lambdabot> 64
08:08 <Myrl-saki> Oh right.
08:08 <Myrl-saki> I had a gitlab.
08:08 <fuzzy-id> is there something shorthand to `h x = (>>= g) <$> f x`?
08:09 <ertes> not the position of the highest bit, but the position of the highest *set* bit
08:09 <ertes> fuzzy-id: unlikely
08:09 <mniip> :t \x -> (>>= ?g) <$> ?f x
08:09 <lambdabot> (Functor f, ?g::a -> m b, ?f::t -> f (m a), Monad m) => t -> f (m b)
08:09 <ertes> fuzzy-id: look if the 'free' library takes any shortcuts, but i doubt it
08:10 <Myrl-saki> I'm pretty sure I had some interesting bit twiddling hacks.
08:10 <Myrl-saki> In Haskell.
08:10 <ertes> still trying to figure out why my code fails
08:10 <Myrl-saki> https://gitlab.com/Myrl/mya/blob/master/lib/Primes/Testing.hs
08:11 <iqubic> ertes: What I want is the position of the highest set bit in a number.
08:11 <iqubic> Like for the number 15 that be 3
08:11 <Myrl-saki> > popCount (2^65 :: Integer)
08:11 <lambdabot> 1
08:11 <tsahyt> I had a fun bit hack to determine position of the highest (and only) set bit in a number 2^k.
08:11 <mniip> Myrl-saki, >bit twiddling >boxed types
08:11 <seequ_> Shift right until n == 0, the number of shifts is the position of the highest bit
08:11 <mniip> are you even
08:11 <Myrl-saki> mniip: :D
08:12 <Myrl-saki> mniip: I don't know man.
08:12 <tsahyt> > popCount (2^8 - 1 :: Word32)
08:12 <lambdabot> 8
08:12 <tsahyt> I think this was it
08:12 <Myrl-saki> mniip: It's still bit twiddling.
08:12 <geekosaur> that's number of set bits, I believe
08:12 <tsahyt> basically popCount (n - 1). only works for n = 2^k though, and should then return k
08:12 <Myrl-saki> geekosaur: Yep.
08:12 <Myrl-saki> tsahyt: Mhm.
08:12 <iqubic> I don't want the number of set bits.
08:12 <Myrl-saki> tsahyt: You can use bit twiddling hacks to still get the "next power of 2" though.
08:13 <iqubic> Let's take the number 6. the highest set bit is 3. That is what I want.
08:13 <ertes> iqubic: you have to search for it
08:13 <iqubic> I do?
08:13 <ertes> i'm not aware of any predefined function
08:13 connrs joined
08:13 <iqubic> Looks like I need to modify my template a bit to make this work better.
08:13 <Myrl-saki> Oh
08:13 <Myrl-saki> Found it.
08:14 <Myrl-saki> https://gitlab.com/Myrl/mya/blob/master/lib/Powers/Squares.hs#L40-48
08:14 wroathe joined
08:14 <Myrl-saki> tsahyt: ^
08:14 <iqubic> what did you fing?
08:14 lithie joined
08:14 <Myrl-saki> iqubic: Magic.
08:14 <Myrl-saki> I call it... Haskell C.
08:15 <* seequ_> sent a long message: seequ__2017-04-15_08:15:11.txt - https://matrix.org/_matrix/media/v1/download/matrix.org/NXhfHdrKCRqkNGaMXZSZVdgZ
08:15 <Myrl-saki> But mniip will hate me anyway for using Boxed types. ; ^ ;
08:15 <tsahyt> Myrl-saki: that's nice
08:16 <ertes> > (\x -> find (\i -> i <$ guard (testBit x i)) [finiteBitSize x - 1, finiteBitSize x - 2 .. 0]) (15 :: Word8)
08:16 <lambdabot> error:
08:16 <lambdabot> • Couldn't match expected type ‘Bool’ with actual type ‘f0 Int’
08:16 <lambdabot> • In the expression: i <$ guard (testBit x i)
08:16 <tsahyt> I should get in the habit of using state monads like this
08:16 <tsahyt> ad hoc I mean
08:16 <tsahyt> I usually just pass a parameter around
08:16 <ggVGc> I've never gound a good use of State
08:16 <ggVGc> I always end up just going with a fold
08:16 <ggVGc> State always ends up overly complicated for me
08:17 <ertes> :t find
08:17 <lambdabot> Foldable t => (a -> Bool) -> t a -> Maybe a
08:17 <ertes> > (\x -> find (testBit x) [finiteBitSize x - 1, finiteBitSize x - 2 .. 0]) (15 :: Word8)
08:17 <lambdabot> Just 3
08:17 <Myrl-saki> Oh what.
08:17 <ertes> iqubic: ^ like that
08:18 <seequ_> Seriously, that's wy overdoing it. :P
08:18 <seequ_> way*
08:18 <Myrl-saki> ggVGc: I needed to work on this like a tree.
08:18 <ertes> > (\x -> let i0 = finiteBitSize x - 1 in find (testBit x) [i0, i0 - 1 .. 0]) (15 :: Word8)
08:18 <lambdabot> Just 3
08:18 <iqubic> ertes: I think I can get this to work.
08:18 <ertes> or more like that
08:19 <iqubic> bit numbers are [0,1..63] right?
08:19 <ertes> [0, 1 .. finiteBitSize (undefined :: A)]
08:19 <ertes> in the case of Word64: [0..63]
08:19 <Sh4rPEYE> If I want to split String into [String] by upper-case letters, what's the best way to do that? Currently I'm using a weird fold with lambda... Is there a better way?
08:20 <Sh4rPEYE> Such that: "HelloMyWorld" -> ["Hello", "My", "World"]
08:20 <Myrl-saki> Also, I still think that the popCount is bad.
08:20 <Myrl-saki> I think it could have been done better.
08:20 <ertes> Sh4rPEYE: i'd use 'break'
08:20 <seequ> You are way ovethinking this..
08:20 <seequ> hbit_ 0 c = c
08:20 <seequ> hbit_ n c = hbit_ (shift n -1) (+ c 1)
08:20 <seequ> hbit n = hbit_ n 0
08:20 lep-delete joined
08:20 <tsahyt> > (\x -> listToMaybe . ($ reverse [0 .. finiteBitSize x]) . filter . testBit $ x) (16 :: Int)
08:20 <lambdabot> Just 4
08:20 <tsahyt> > (\x -> listToMaybe . ($ reverse [0 .. finiteBitSize x]) . filter . testBit $ x) (15 :: Int)
08:20 <Myrl-saki> seequ: Anything other than pointfree is pointless. :D
08:20 <lambdabot> Just 3
08:21 mmn80 joined
08:21 ericmathison joined
08:21 <tsahyt> arguably, using find is nicer though
08:21 <seequ> Myrl-saki: traversing lists for this is ridiculously inefficient :P
08:22 <Myrl-saki> @t unfolrd
08:22 <lambdabot> Maybe you meant: tell thank you thanks thesaurus thx tic-tac-toe ticker time todo todo-add todo-delete type v @ ? .
08:22 <Myrl-saki> :t unfoldr
08:22 <lambdabot> (b -> Maybe (a, b)) -> b -> [a]
08:22 <Myrl-saki> Maybe?
08:22 <Myrl-saki> Knew it.
08:23 <jle`> > unfoldr (\x -> if x < 4 then Just (x, x+1) else Nothing) 0
08:23 <lambdabot> [0,1,2,3]
08:24 <jle`> [a] is pretty much Maybe (a, [a]) anyway
08:24 wroathe joined
08:25 <jle`> > unfoldr (\case [] -> Nothing; x:xs -> Just (x,xs)) [1..5]
08:25 <lambdabot> [1,2,3,4,5]
08:25 <tsahyt> jle`: aka Maybe (NonEmpty a)
08:25 <Myrl-saki> jle`: Maybe (NonEmpty a) = [a]
08:25 <Myrl-saki> tsahyt: :D
08:25 <jle`> :D
08:25 <Myrl-saki> I feel like I'm one of the cool kids now.
08:26 <jle`> luckily `\case [] -> Nothing; x:xs -> Just (x,xs)` is already in base
08:26 <iqubic> Ug. I don't understand why this code doesn't compile.
08:26 <tsahyt> I should not have picked up this idris book
08:26 <jle`> > unfoldr uncons [1..5]
08:26 <lambdabot> [1,2,3,4,5]
08:26 <iqubic> http://termbin.com/tceo
08:26 <iqubic> Doesn't pass type checking.
08:27 <jle`> ejsy
08:27 <jle`> * what's the error
08:27 <tsahyt> I mean it's a good book, but it's also very good at showing you things that are currently very very hard to do in Haskell
08:27 connrs joined
08:27 <seequ> Yup.
08:27 <jle`> it's a book for dreamers
08:27 <tsahyt> but a decently sized chunk of the examples in the book can also be implemented very nicely in haskell
08:27 <lpaste> iqubic pasted “Type Checking Error” at http://lpaste.net/354607
08:28 <iqubic> I don't understand that.
08:28 eacameron joined
08:28 <jle`> iqubic: f (testBit i w) is 'f Bool', but it needs to be 'f Int'
08:28 <jle`> so you just need to fmap some (Bool -> Int) function over it
08:28 <iqubic> why does it need to be f Int?
08:28 bhiliyam joined
08:29 <tsahyt> jle`: I've skimmed richard eisenberg's thesis a bit, and on the surface, Dependent Haskell looks like it'd be very well capable of expressing all of the Idris tricks nicely
08:29 <jle`> iqubic: cause you're using the result in (\xs x -> shiftL 1 xs .|. x)
08:29 <tsahyt> so yeah, it's for dreamers. or for patient peopele.
08:29 <tsahyt> people*
08:29 <Cale> Or people who want to program in Idris
08:29 <tsahyt> Cale: oh yeah that too
08:29 <Cale> you know, what the book is about
08:29 <Cale> lol
08:30 <iqubic> why does it need to be type of (f Int)?
08:30 <jle`> iqubic: what's the type of shiftL
08:30 <iqubic> Oh. Right.
08:30 <ertes> @let camelSplit = unfoldr (\xs' -> case break isUpper xs' of ("", "") -> Nothing; ("", (y:ys)) -> Just $ Bi.first (y :) (break isUpper ys); r -> Just r)
08:30 <lambdabot> Defined.
08:30 <tsahyt> it's certainly a nice side effect to have another language at my disposal. but realistically I'd rather stick with Haskell. the compiler produces better code, the eco system is better, it's lazy by default (which is what turns me off most from idris), etc etc
08:30 takle joined
08:30 <Cale> Well, sure
08:31 <ertes> > map camelSplit ["HelloMyWorld", "elloMyWorld"]
08:31 <lambdabot> [["Hello","My","World"],["ello","My","World"]]
08:31 <jle`> tsahyt: we might be able to express it in haskell, but the real barrier is those nice proof building tools and automated proof generators
08:31 <iqubic> jle`: I had my arguments backwards.
08:31 <tsahyt> Cale: it'd be interesting to have good Haskell <-> Idris interop though
08:31 <iqubic> I just got another weird error.
08:32 <jle`> idris without its proof building tools and automated proof tools is also not very fun
08:32 <tsahyt> jle`: if you want a theorem prover, Haskell will never be the right choice. Dependent Haskell will not suddenly turn it into a total language
08:32 <jle`> well, it is some amount of fun
08:32 <Cale> I honestly think that it's pretty likely that at some point GHC gets a new frontend with a better language for dependently typed programming.
08:32 <jle`> tsahyt: we don't need a total language
08:32 <tsahyt> Cale: so it'd be the Glasgow Not-only-Haskell Compiler?
08:32 <Cale> yeah
08:32 <tsahyt> jle`: well technically you do. if you want to actually proof theorems with it, non-termination is a big issue for correctness
08:33 <jle`> just tools to make writing `(x + 0) :~: x` nicer
08:33 <iqubic> http://termbin.com/iilx
08:33 <jle`> x + Z
08:33 <iqubic> http://lpaste.net/354608
08:33 <jle`> or (x ++ []) :~: x
08:33 <tsahyt> jle`: there've been attempts to integrate SMT solvers as type checker plugins iirc
08:33 <iqubic> Errors are weird.
08:33 <iqubic> I don't understand them.
08:33 eacameron joined
08:33 <jle`> not just for type checking, but for actually writing proofs
08:34 <ertes> mniip: that's weird… my bits traversal works locally
08:34 <jle`> iqubic: the error here is very similar
08:34 <ertes> @let bitsAgain f x = foldr (\i -> liftA2 (fmap ($ i) . bool clearBit setBit) (f (testBit x i))) (pure 0) [0..finiteBitSize x - 1]
08:34 <lambdabot> Defined.
08:34 <jle`> iqubic: the function wants Word64, but you're giving it Bool
08:34 <Cale> We do need a termination checker, and a total language fragment, eventually.
08:34 <tsahyt> jle`: what's the difference really. for writing these proofs you mostly want a library of theorems like that available
08:34 <iqubic> Yeah, I got my argments backwards again.
08:34 <ertes> > set bitsAgain True undefined :: Int64
08:34 wroathe joined
08:34 <lambdabot> error:
08:34 <lambdabot> • Ambiguous type variable ‘b10’ arising from a use of ‘bitsAgain’
08:34 <lambdabot> prevents the constraint ‘(FiniteBits b10)’ from being solved.
08:34 <ertes> > set bitsAgain True (undefined :: Int64)
08:34 <jle`> iqubic: the error is actually pretty clear :)
08:34 <lambdabot> 18446744073709551615
08:35 balor joined
08:35 <tsahyt> the harder part in my experience is convincing the type checker that say n + k - k ~ n
08:35 <jle`> iqubic: "Expected type: ____, Actual type: ____"
08:35 <Cale> It's not the top priority for practical work, but it would be very nice to have
08:35 <tsahyt> and that's where the type checker plugins come in
08:35 <lpaste> iqubic pasted “Bool does not equal Word64” at http://lpaste.net/354609
08:35 <iqubic> http://termbin.com/mgly
08:35 <Cale> and it's essential if we start proving stuff
08:35 <jle`> iqubic: means that haskell wants something from the "expected" thing, but you are giving it something from the "actual" line
08:35 <tsahyt> Cale: for the time being, I resort to liquid haskell for termination checking. it's certainly not perfect either, but then again no termination checker ever is
08:35 <ertes> does anyone need the definitions so far?
08:35 <ertes> good
08:35 <ertes> @undef
08:35 <lambdabot> Undefined.
08:35 <iqubic> That last error doesn't say where the error comes from.
08:35 <jle`> iqubic: so if the error says "expected: Foo, actual: Bar", it means that you're giving it a FOo, but it wants a Bar
08:35 <ertes> @let bits' f x = foldr (\i -> liftA2 (fmap ($ i) . bool clearBit setBit) (f (testBit x i))) (pure 0) [0..finiteBitSize x - 1]
08:35 <lambdabot> Defined.
08:36 <Myrl-saki> You know what.
08:36 <ertes> > set bits' True (undefined :: Int64)
08:36 <Myrl-saki> I honestly have no idea what I wrote.
08:36 <lambdabot> 18446744073709551615
08:36 <Myrl-saki> :D
08:36 <jle`> iqubic: it does, though
08:36 <Myrl-saki> Not anymore, at least.
08:36 <ertes> something is wrong with lambdabot… that definition works for me locally
08:36 <jle`> iqubic: "In the expression: go 64"
08:36 <iqubic> jle`: Where is the error coming from?
08:36 <jle`> iqubic: "in the expression: ____"
08:36 <jle`> that's where it tells you where the error is
08:36 <iqubic> Yeah, but that expression is really large.
08:36 <ertes> :t set
08:36 <jle`> no
08:36 <lambdabot> ASetter s t a b -> b -> s -> t
08:36 <jle`> the expression is 'go 64'
08:37 <jle`> "In the expression: go 64"
08:37 <jle`> are we reading the same error message?
08:37 <iqubic> yes.
08:37 <jle`> the expression is 'go 64'
08:37 <ertes> :t bits
08:37 <lambdabot> (Applicative f, Indexable Int p, Bits b, Num b) => p Bool (f Bool) -> b -> f b
08:37 <jle`> that's pretty small, as far as expressions go :)
08:37 <ertes> OH!
08:37 <jle`> only 5 characters
08:37 <ertes> stupid me
08:37 <ertes> @undef
08:37 <lambdabot> Undefined.
08:38 <iqubic> jle`: look at the where statement just below that.
08:38 <iqubic> That's the part that I can't seem to puzzle out
08:38 <ertes> @let bits' :: (Num a, FiniteBits a, Applicative f) => (Bool -> f Bool) -> a -> f a; bits' f x = foldr (\i -> liftA2 (fmap ($ i) . bool clearBit setBit) (f (testBit x i))) (pure 0) [0..finiteBitSize x - 1]
08:38 <lambdabot> Defined.
08:38 <jle`> iqubic: you don't have to look at that
08:38 <jle`> iqubic: you just need to fix the error
08:38 <iqubic> Why not?
08:38 <ertes> > set bits' True undefined :: Int64
08:38 <lambdabot> -1
08:38 <ertes> THERE we go
08:38 <iqubic> how do I fix the error?
08:38 <jle`> iqubic: the error is that 'go 64' is f Bool
08:38 <Cale> tsahyt: Well, we hope that e.g. Agda's is "perfect" in the sense of not admitting non-terminating programs. But there's always the question of whether it could perhaps admit more programs automatically.
08:38 <jle`> iqubic: but haskell wants it to be f Word64
08:39 <mniip> 1492245384 [11:36:24] <ertes> something is wrong with lambdabot… that definition works for me locally
08:39 <jle`> iqubic: what's what it means when it says "Expected XXX, Actual YYYY, in expression ZZZ"
08:39 <mniip> it monomorphizes to Integer
08:39 blender joined
08:39 <mniip> obviously
08:39 <jle`> iqubic: it means that ZZZ is type YYY, but haskell wants XXX
08:39 [exa]_ joined
08:39 <iqubic> yes. I know. jle` I can't change the type of the funxtion without chaning the the where expression below.
08:39 <jle`> you don't have to change the type of the function
08:39 <jle`> you just need to change the type of what you put for bitsWord64 f w = ????
08:40 <jle`> instead of putting 'go 64', put something else
08:40 <iqubic> How do I do that?
08:40 <jle`> type it in
08:40 <jle`> where the ???? is
08:40 <iqubic> Like what?
08:40 <iqubic> What do I type in there?
08:40 <ertes> mniip: i didn't realise that this function is actually more generic… the fact that the type signature on the result wasn't enough should have set off my alarm bells
08:40 chbatey joined
08:40 <blender> Hello, I have a small issue Applicative Maybe and Monad Transformers, can anyone help or tell me if I'm holding it wrong? http://stackoverflow.com/questions/43408620/monad-transformer-and-applicative-maybe
08:41 kylepotts joined
08:41 Argue joined
08:41 <ertes> i think it's just regular defaulting in this case
08:41 <Myrl-saki> What does expected type and actual type mean again?
08:41 <iqubic> jle`: How do I change the type of my function?
08:41 <Myrl-saki> > 1 :: String
08:41 <lambdabot> error:
08:41 <lambdabot> • No instance for (Num String) arising from the literal ‘1’
08:41 <lambdabot> • In the expression: 1 :: String
08:41 <[exa]_> Mmm guys. Anyone knowledgeable about how monad transformers and similar higher-kinded stuff are actually compiled? E.g.: I know how simple stuff like DataCon Int Int can be represented in STG. But how does one store e.g. the first parameter of MaybeT which is of kind (*->*) ? Or does it just get "optimized out"?
08:41 <ertes> @let genericBits f x = foldr (\i -> liftA2 (fmap ($ i) . bool clearBit setBit) (f (testBit x i))) (pure 0) [0..finiteBitSize x - 1]
08:41 <lambdabot> Defined.
08:41 <ertes> :t genericBits
08:41 <lambdabot> (Bits b, Applicative f, Num b, FiniteBits b1) => (Bool -> f Bool) -> b1 -> f b
08:42 <Myrl-saki> Okay.. that was not what I was looking for.
08:42 <ertes> mniip: yeah, just defaulting, no monomorphisation
08:42 <mniip> er
08:42 <mniip> yes
08:42 <mniip> defaulting
08:42 <Myrl-saki> I like how this has no answer. http://stackoverflow.com/questions/44965/what-is-a-monad?rq=1
08:42 <mniip> defaulting is a typee of monomorphisation I guess
08:42 <Myrl-saki> Accepted answer, I mean.
08:43 revprez_atlanta joined
08:43 <iqubic> Alright, I have no idea how to make a traversal over the bits of a word64.
08:43 <ertes> iqubic: you were really close
08:43 <iqubic> I was? How do I make this work?
08:44 <tsahyt> @mtl ReaderT Foo IO a
08:44 <lambdabot> Maybe you meant: url unmtl pl msg
08:44 <tsahyt> @unmtl ReaderT Foo IO a
08:44 <lambdabot> Foo -> IO a
08:44 <ertes> iqubic: go i | i < 64 = _combine <$> f (testBit w i) <*> go (i + 1)
08:44 nicknovitski joined
08:44 wroathe joined
08:44 <ertes> iqubic: _combine receives two arguments: a boolean for the current bit, and the word built so far
08:45 <tsahyt> [exa]_: since all (I think) the transformers are just newtypes, their constructors should be erased. so you end up with Foo -> IO a for a ReaderT Foo IO for example
08:45 <tsahyt> all the wrapping and unwrapping itself should be free
08:45 <tsahyt> however, the dictionary passing for MonadReader isn't
08:45 <iqubic> What do I put as combine?
08:45 <ertes> iqubic: (\b w' -> …)
08:46 <ertes> iqubic: if b is True, you want to set the corresponding bit in w'
08:46 Berra joined
08:47 piyush-kurur joined
08:47 kaichao[m] left
08:47 <iqubic> How do I know what bit to se?
08:48 <iqubic> I have the counter i
08:48 <ertes> iqubic: the bit at the current index
08:48 <ertes> what is the current index?
08:48 <[exa]_> tsahyt: so it gets evaluated out. Suspected that. Thanks!
08:48 <ertes> iqubic: hint: you are reading the bit at the current index in the same line
08:48 <tsahyt> [exa]_: kinda. due to the dictionaries at least you still end up with some overhead.
08:48 <iqubic> I know
08:49 <tsahyt> I'm not sure whether explicit lifting would be free either. I don't think it is. but in reality, this is hardly ever the bottleneck for performance.
08:50 fotonzade joined
08:50 splanch joined
08:50 <tsahyt> in any case, mtl outperforms any alternatives like extensible-effects afaik.
08:50 eacameron joined
08:51 descender joined
08:52 chichou joined
08:53 <Myrl-saki> unsafeReUnion sounds like dating your long lost sister.
08:54 <iqubic> I did a thing.
08:54 <iqubic> I GOT THE THING TO WORK.
08:54 <halogenandtoast> If I want to make a game with a GUI, is Cairo a good choice?
08:54 <Myrl-saki> iqubic: lmao
08:54 Kreest__ joined
08:54 <Myrl-saki> iqubic: Show us.
08:54 wroathe joined
08:55 <iqubic> http://termbin.com/cne7
08:55 <iqubic> I think that should work.
08:55 <iqubic> Type Signature check passes.
08:55 <ertes> iqubic: it looks correct, yeah
08:55 <iqubic> I did a thing.
08:55 <iqubic> That was super hard.
08:55 <ertes> congratulations =)
08:55 <Myrl-saki> `:D
08:56 <iqubic> Now, give me another traversal to write. I want to see if I can make another one.
08:56 eacameron joined
08:56 <Myrl-saki> iqubic: https://media.tenor.co/images/6863669abb7bb57c71886bc8cbfb274f/tenor.gif
08:56 <iqubic> Thank you.
08:57 Mon_Ouie joined
08:57 <ertes> iqubic: you want something harder, don't you…
08:57 <iqubic> Do I still need to use Template Haskell to generate lenses for records? Or is that not needed?
08:57 <Myrl-saki> I wonder how I'd do it.
08:58 <iqubic> ertes: I'd like to try something.
08:58 <Myrl-saki> Probably unfoldr + foldr?
08:58 <ertes> iqubic: TH is completely optional
08:58 xcmw joined
08:58 <iqubic> How do you write a lens for a record?
08:58 <Myrl-saki> :t foldr
08:58 <lambdabot> Foldable t => (a -> b -> b) -> b -> t a -> b
08:58 <iqubic> Is that hard to do?
08:58 <ertes> iqubic: tuples are records with two fields in a way
08:58 <iqubic> Or they?
08:58 <iqubic> How can you pattern match on a record?
08:59 <piyush-kurur> is there a way to run the example code given in the haddock documentation and check whether everything is fine?
08:59 <ertes> to write field lenses you generally don't pattern-match
08:59 <Lokathor> iqubic, (RecordName fieldA fieldB etc), like it was a normal data thing, the fields fall in order of their declaration
08:59 <iqubic> Ah.
09:00 <iqubic> ertes: You got a harder traversal for me to try writing?
09:00 plutoniix joined
09:00 <ertes> myField f x = (\a -> x { _myField = a }) f (_myField x)
09:00 <Lokathor> halogenandtoast, sdl2 is probably your best choice for a 2d game in Haskell
09:00 <ertes> iqubic: if you want, sure
09:01 <halogenandtoast> Lokathor: I'll check it out
09:01 <iqubic> Can I have something to make?
09:01 <halogenandtoast> it will be 2d
09:01 leifmetcalf joined
09:01 indi_ joined
09:02 <ertes> iqubic: as you wish: write a traversal into the result of a boolean function
09:02 <iqubic> What?
09:02 <ertes> iqubic: boolCodomain :: (Applicative f) => (a -> f b) -> (Bool -> a) -> f (Bool -> b)
09:02 takle joined
09:03 <iqubic> You can't control the output of a boolean function.
09:03 <ertes> iqubic: you can… take your time =)
09:04 <iqubic> How do you change the output of a Boolean Function??
09:04 <ertes> iqubic: for this one you need to think outside the box a little
09:04 <ertes> iqubic: you can't *change* it, but you can construct functions based on other functions
09:04 <iqubic> What does it mean for something to be a Boolean Function?
09:04 <ertes> actually the correct term is "function of Bool"
09:04 <iqubic> Ah.
09:04 <ertes> a boolean function is a function that would return a Bool… sorry
09:05 wroathe joined
09:05 <iqubic> So how do I change the outcome of a function??
09:05 <Myrl-saki> :t (\b -> if b then 1 else 0)
09:05 <lambdabot> Num t => Bool -> t
09:05 <ertes> iqubic: (not .)
09:05 <ertes> :t (not .)
09:05 <lambdabot> (a -> Bool) -> a -> Bool
09:06 <iqubic> wait, so it's a travesal over both possible outputs?
09:06 <ertes> this one takes a function f and returns a function that is the same as f, but with the result inverted
09:06 <ertes> yes
09:06 <iqubic> So this is simple?
09:06 <iqubic> Or is it?
09:06 eacameron joined
09:06 <ertes> it's simple, but a bit mind-bending, if you're not used to this =)
09:06 <Myrl-saki> ertes: Is there an actual use for this?
09:06 <iqubic> What would the (a -> f b) do?
09:07 <ertes> Myrl-saki: sure… think of functions as an abstraction for arrays
09:07 <ertes> then you have a traversal into the array elements
09:07 <Myrl-saki> ertes: Are you talking about x^n == n -> x?
09:07 <ertes> Myrl-saki: exactly =)
09:08 <ertes> iqubic: take your time and think… compare the type to other traversals you have written
09:08 <Myrl-saki> I'll be trying out this one. Been some time since I've done some weird stuff. :D
09:09 <iqubic> This is weird
09:10 <Myrl-saki> It's supposed to be weird. :D
09:10 <ertes> iqubic: you wanted a challenge =)
09:10 <iqubic> I have no idea what the (a -> f b) would do, other than operate on all the possible outcomes.
09:10 <ertes> iqubic: typically you would think of a value of type (Bool -> A) as "something that takes a Bool and returns an A"
09:11 <ertes> iqubic: can you think of any other interpretations for such a value?
09:11 <iqubic> No.
09:11 <Myrl-saki> ertes: Something that contains 2 As? :D
09:11 <ertes> iqubic: how many Bools are there?
09:11 <iqubic> Two.
09:11 <Myrl-saki> Rather, "contains"
09:11 <iqubic> It's like (Maybe -> a)
09:11 <ertes> iqubic: so if (f :: Bool -> A), how many possible results can f have?
09:12 <iqubic> two.
09:12 mtesseract joined
09:12 <ertes> iqubic: how do you get the first result?
09:12 <iqubic> you run the function.
09:12 <ertes> iqubic: give me code
09:12 <iqubic> f
09:12 ninjazoete joined
09:12 <iqubic> that is the first result
09:12 <ertes> give me the code for one of the As
09:13 <iqubic> is not just 'f'?
09:13 <ertes> nope, f is not of type A
09:13 fgaz joined
09:13 <iqubic> How do I extract the value?
09:13 <ertes> iqubic: you just told me
09:13 <iqubic> how do I run a function?
09:14 <ertes> you apply it
09:14 <iqubic> How do I apply it? I feel really stupid now.
09:14 <Myrl-saki> This sounds like it'd be way easier with a Monad instance. <.<
09:14 <ertes> iqubic: function application: f False, f True
09:14 augur joined
09:14 marr joined
09:14 <iqubic> oh, right.
09:15 wroathe joined
09:15 <ertes> iqubic: now, can you write a function that, given such a function, gives you the two results?
09:15 <ertes> toPair :: (Bool -> a) -> (a, a)
09:16 filterfish joined
09:16 eacameron joined
09:16 <iqubic> So what I do is this: toPair f b = (,) <$> f (b True) <*> f (b False)
09:16 <iqubic> Got it.
09:16 xall joined
09:16 <ertes> nope
09:16 <iqubic> Why not?
09:17 <ertes> toPair takes only one argument
09:17 <iqubic> how is that wrong???
09:17 descender joined
09:17 <ertes> (it's not anything lensy)
09:17 <iqubic> :t toPair
09:17 <lambdabot> error: Variable not in scope: toPair
09:17 <jle`> ask ghc :o
09:17 <iqubic> so what do I do then???
09:17 <iqubic> I'm a bit confused now.
09:17 <ertes> iqubic: write the function
09:18 <iqubic> what function am I trying to write? toPair?
09:18 <ertes> yeah
09:18 NextHendrix joined
09:18 Wedamm joined
09:18 <NextHendrix> just been reading this interesting tidbit from the monad reader https://imgur.com/jVq8hgV
09:18 <iqubic> toPair f = (,) <$> f True <*> f False
09:19 <ertes> iqubic: you're overthinking it
09:19 <NextHendrix> question is, what is happening in that last line lol
09:19 <iqubic> or toPair f = (f True, f False)
09:19 <ertes> iqubic: yeah, that's the one
09:19 Gurkenglas joined
09:19 <iqubic> is that all you wanted?
09:19 <iqubic> or what?
09:19 <ertes> iqubic: not yet
09:20 <iqubic> what do you want?
09:20 <NextHendrix> reverse = foldl (flip (:)) []
09:20 <ertes> iqubic: now, could you also write a function that goes from a pair to such a function?
09:20 <ertes> iqubic: fromPair :: (a, a) -> (Bool -> a)
09:20 <jle`> NextHendrix: easiest way to decipher it is to just manually apply out the definition of foldl
09:20 <jle`> @src foldl
09:20 <lambdabot> foldl f z [] = z
09:20 <lambdabot> foldl f z (x:xs) = foldl f (f z x) xs
09:20 <iqubic> I don't think you can do that.
09:20 <iqubic> ertes: you can't go back the other way.
09:20 <ertes> iqubic: try it
09:20 Xanather joined
09:21 <NextHendrix> oh wait (:) is just prefix cons isnt it
09:21 <geekosaur> yes
09:21 <NextHendrix> lol, that article is really good
09:21 <jle`> :t flip (:)
09:21 <lambdabot> [a] -> a -> [a]
09:21 <geekosaur> operator as a function you can pass to other things
09:21 <jle`> > flip (:) [1,2,3] 0
09:21 <lambdabot> [0,1,2,3]
09:21 <ertes> iqubic: remember currying: (a, a) -> (Bool -> a) = (a, a) -> Bool -> a
09:21 <NextHendrix> yeah gotcha
09:21 meandi joined
09:21 <iqubic> :t curry
09:21 <lambdabot> ((a, b) -> c) -> a -> b -> c
09:21 <iqubic> :t uncurry
09:21 <lambdabot> (a -> b -> c) -> (a, b) -> c
09:21 hexfive joined
09:21 <Myrl-saki> Can I use holes in ghci?
09:21 <Myrl-saki> Oh, I can.
09:21 <ertes> iqubic: it has nothing to do with curry/uncurry, just the way you read the type
09:21 <jle`> what happens when you try?
09:22 <iqubic> Ah.
09:22 <Myrl-saki> But not as a function argument..
09:22 <ertes> iqubic: the point is that fromPair actually takes two arguments
09:22 <jle`> as a function argument, it's not a typed hole
09:22 <jle`> it's just a wildcard pattern match
09:23 <iqubic> ertes: you want me to write fromPair??
09:23 eacameron joined
09:23 <ertes> iqubic: yeah
09:23 <NextHendrix> extremely terse pointfree haskrll might as well count as a form of encryption
09:23 <geekosaur> sometimes it is :)
09:23 <iqubic> How will that work?
09:23 <geekosaur> that was in fact the point of that page of the Monad.Reader
09:23 <Myrl-saki> I wanted to work with holes. :(
09:23 <NextHendrix> yeah
09:23 <geekosaur> there's also an "evolution of a haskell programmer" joke along those lines
09:24 <NextHendrix> heh
09:24 <jle`> Myrl-saki: ghci works with holes the same way as normal haskell files do
09:24 <Myrl-saki> jle`: I don't normally use holes.
09:24 <jle`> oh
09:24 <jle`> holes are pretty useful
09:24 <jle`> but what do you want to use them for?
09:24 <Myrl-saki> jle`: Exactly!
09:24 <Myrl-saki> jle`: I want to know the type of an argument.
09:24 <iqubic> what will fromPair do?
09:24 <Myrl-saki> jle`: I mean, sure, I can easily figure it out.
09:24 <geekosaur> oh, you want ScopedTypeVariables and (_ :: _)
09:25 <ertes> iqubic: given a pair constructed via toPair, reconstructs the original function
09:25 <geekosaur> and I think another extension to turn on the _ as type thing
09:25 <ertes> iqubic: such that (fromPair . toPair = id)
09:25 <jle`> i think it's on by default
09:25 <Myrl-saki> Let me try.
09:25 <iqubic> I cna't do that. I have no idea how to do that?
09:25 wroathe joined
09:26 <jle`> iqubic: just believe in your self ~
09:26 <ertes> iqubic: fromPair (x, y) True = _ -- this clause is supposed to return the component that the original function would have returned when given True
09:26 <ertes> iqubic: example: f b = if b then 3 else 5
09:26 HarveyPwca joined
09:26 <ertes> iqubic: toPair f = (3, 5)
09:27 <iqubic> fromPair (x, y) True = x; fromPair (x, y) False = y
09:27 <iqubic> got it.
09:27 <geekosaur> oh, the extension is to enable it to actually continue using the inferred type
09:27 <ertes> iqubic: correct
09:27 <geekosaur> instead of throwing it as an error
09:27 <iqubic> Now what do you want me to do?
09:27 bbear joined
09:27 <bbear> hello
09:27 <bbear> I have a little problem.
09:28 <Myrl-saki> `• Found type wildcard ‘_’ standing for ‘t’`
09:28 <ertes> iqubic: now there is a good reason why i made you write those functions: they are actually isomorphisms, meaning that they take a value of type (Bool -> a) to a value of type (a, a) and back without information loss, and vice versa
09:28 <Myrl-saki> :C
09:28 <ertes> iqubic: makes sense so far?
09:28 <Myrl-saki> I'm done. I'm sleepy.
09:28 <iqubic> I have fromPoint and toPoint.
09:28 <iqubic> Yes, ertes makes sense.
09:28 <iqubic> *pair.
09:28 <bbear> let say I partition the alphabet in three parts : [a..f] [g..u] [v..z]
09:28 HarveyPwca joined
09:28 augur joined
09:28 dan_f joined
09:28 raichoo joined
09:28 <ertes> iqubic: then would it be fair to say that those two types are really just representations of the same concept, namely "pair"?
09:29 <iqubic> yes.
09:29 <iqubic> I think that is correct.
09:29 <ertes> iqubic: does that give you an idea on how to approach that traversal?
09:29 <geekosaur> Myrl-saki, if it's inferred polymorphic then you need to put the wildcard at the use site
09:29 <iqubic> What traversal?
09:29 <bbear> How can I do a function that returns three list of letters according to the set in which the initial letter is.
09:29 <ertes> iqubic: boolCodomain
09:29 bhiliyam joined
09:29 <iqubic> What is the type signature.
09:29 <iqubic> ??
09:29 takle joined
09:29 gmhafiz joined
09:29 <bbear> :t boolCodomain
09:30 <lambdabot> error: Variable not in scope: boolCodomain
09:30 <ertes> iqubic: you really need to start taking notes =)
09:30 <iqubic> I'll start doing that.
09:30 yellowj joined
09:30 <ertes> boolCodomain :: (Applicative f) => (a -> f b) -> (Bool -> a) -> f (Bool -> b)
09:30 <Myrl-saki> geekosaur: Actually used the value. `• Found type wildcard ‘_’ standing for ‘Int’`
09:30 <Myrl-saki> geekosaur: the argument*
09:30 filterfish joined
09:30 <bbear> btw my question would
09:31 <bbear> how can I return
09:31 <bbear> ok I found out I think
09:31 <iqubic> ertes: And I need to traverse both values?
09:31 plutoniix joined
09:31 <ertes> iqubic: yes
09:31 <iqubic> Is there a way to traverse both parts of a tuple?
09:31 <iqubic> Do I have that at my disposal?
09:32 <jle`> you just did it earlier, heh
09:32 <ertes> iqubic: you have done that
09:32 <jle`> granted, it was about four or five hours ago
09:32 <jle`> so you'd be forgiven for not recalling :)
09:32 <geekosaur> iqubic, I think you want to use the log links in the /topic and review this whole discussion
09:32 <geekosaur> because yeh, it's drawn out a bit and you could be forgiven for forgetting where it started (I did!)
09:33 <blender> How do I combine something like a -> b > ReaderT (Bool) IO () with Maybe a
09:33 HarveyPwca joined
09:33 xormor joined
09:33 <iqubic> What did that look like again? This: traverseBoth f (x, y) = (,) <$> f x <*> f y
09:33 Uakh joined
09:33 <iqubic> is that the correct form of that?
09:33 <ertes> that's the one
09:33 descender joined
09:33 <Myrl-saki> &&& ?
09:33 <Myrl-saki> :t traverseBoth = join (&&&)
09:34 <lambdabot> error:
09:34 <lambdabot> parse error on input ‘=’
09:34 <lambdabot> Perhaps you need a 'let' in a 'do' block?
09:34 <Myrl-saki> :t join (&&&)
09:34 <lambdabot> Arrow a => a b c' -> a b (c', c')
09:34 <Myrl-saki> Oh. No.
09:34 <mniip> :t join (***)
09:34 <lambdabot> Arrow a => a b' c' -> a (b', b') (c', c')
09:35 robotroll joined
09:35 <Myrl-saki> mniip: Thanks. :C
09:35 kylepotts joined
09:35 wroathe joined
09:35 <iqubic> boolCodomain f b = fromPair (traverseBoth f (toPair b))
09:36 <iqubic> I don't think that quite works
09:36 <ertes> iqubic: not quite
09:36 <iqubic> what am I missing?
09:37 <iqubic> I don't understand what I am doing wrong there.
09:37 <ertes> the result of traverseBoth is not quite a pair
09:37 biglambda joined
09:37 <ertes> look at its type
09:37 <iqubic> No it isn't
09:37 <iqubic> it's f (a, b
09:37 Icewing joined
09:37 <iqubic> * f (a, b)
09:37 meba joined
09:38 Uakh joined
09:38 <iqubic> I don't know what to do from there.
09:38 <iqubic> I can't quite make this work
09:38 <ertes> you have an f X and an X -> Y, you want an f Y
09:38 <ertes> any idea?
09:38 <iqubic> So I use <*>
09:39 <ertes> nope
09:39 <iqubic> GRR
09:39 <iqubic> What do I use?
09:39 <ertes> (well, you can, but there is a more sensible choice)
09:39 nmattia joined
09:39 <ertes> if you had an f (X -> Y), then (<*>) would be the right choice
09:39 <ertes> but you have an X -> Y
09:40 <iqubic> So I use fmap.
09:40 t7 joined
09:40 krypton joined
09:40 <iqubic> That's how that works
09:41 <iqubic> boolCodomain f b = fromPair <$> (traverseBoth f (toPair b))
09:41 <iqubic> Just trying stuff out.
09:41 <ertes> that's correct
09:41 kolko_ joined
09:41 <iqubic> But where's the applicative??
09:41 <ertes> you're using it implicitly via traverseBoth
09:41 <iqubic> Ah. I see.
09:42 <iqubic> Anything else I need to know about traversals and lenses?
09:42 pytuger joined
09:42 takle joined
09:42 <iqubic> Or do I just need practice with this
09:42 <iqubic> >>
09:42 <iqubic> ???
09:42 eacameron joined
09:43 <ertes> practice is your first step now
09:43 beanbagu1 joined
09:43 <ertes> use lenses and traversals practically
09:43 kylepotts joined
09:43 <iqubic> Alright, what else can I learn about.
09:43 balor joined
09:43 <iqubic> I've heard about prisms. Are those related to lenses and travesals?
09:44 <ertes> let me answer that in the form of a comic
09:44 <ertes> https://ro-che.info/ccc/23
09:44 <iqubic> I've read that they are.
09:44 <iqubic> I'm sorry for opening another can of worms
09:44 <ertes> the lens library refers to all these as "optics"
09:44 <ertes> there are lots of them
09:44 <ertes> and they form a kind of hierarchy
09:44 <Gurkenglas> There's a nice segue here into isos by saying that "boolCodomain f b = fromPair <$> (traverseBoth f (toPair b))" can be rewritten as "boolCodomain = au (iso fromPair toPair) traverseBoth"
09:45 <ertes> https://hackage.haskell.org/package/lens
09:45 <ertes> look at the diagram
09:45 <iqubic> What the heck is and iso?
09:45 wroathe joined
09:45 <Gurkenglas> Every Iso is a Lens. It is a witness that two types are isomoprhic.
09:46 <iqubic> So fromPair . toPair = id?
09:46 <ertes> iqubic: i used the word isomorphism earlier… it means that one type is just another type in disguise, because you can convert between them without information loss
09:47 <Gurkenglas> Yes I assumed that
09:48 <MarcelineVQ> I ​have got to say, the ((->) r) instance for functor and applicative made working that problem out by looking at type errors very difficult
09:49 feynhat joined
09:50 seveg_ joined
09:50 taktoa joined
09:50 beanbagu1 joined
09:51 <iqubic> Are isos and prisms required for me to learn about?
09:52 <jle`> nothing here is really required. just useful :)
09:52 <iqubic> Are Isos and Prisms easy to teach. Are they easy to learn about?
09:53 NotAwal joined
09:55 Denthir joined
09:56 nmattia joined
09:56 <dibblego> iqubic: yes, are you going to lambdaconf?
09:57 <iqubic> No.
09:57 <iqubic> Not going to lambaconf
09:57 saep joined
09:57 <dibblego> or, if you are in .au the .au federal government occasionally runs free course on lens (iso, prism, etc)
09:58 <iqubic> I'm not in au
09:58 <iqubic> in USA
09:58 <dibblego> come to Boulder
09:58 <iqubic> I'm in the NW
09:58 puregreen joined
09:58 eacameron joined
10:00 nighty-- joined
10:00 <kellytk> What kinds of programs is Haskell the wrong choice for?
10:01 <ongy> low level embedded environments with memory constraints, or hard realtime. At least with current implementations.
10:01 NotAwal joined
10:02 <kellytk> I don't have projects of either kind in the works
10:02 <kellytk> Is there anything else?
10:03 silver joined
10:03 <ongy> those are exampls where haskell will fail. For all others I think it's gradual. I don't think we have a native gui library on hackage either. So if you need that, you will either have to figure something out, or at least mix languages in the project
10:05 <kellytk> I'll try making a bot to begin with to see how Haskell feels to me
10:05 <kellytk> Thanks ongy
10:05 <ongy> well, we have some bindings to gtk and wx I think. But I don't think they are considered complete or easy/intuitive to use.
10:05 eacameron joined
10:06 <puregreen> I don't think gtk is easy/intuitive to use in general
10:06 <ongy> For things like irc bot, haskell works pretty well. Since they fit the functional paradigm pretty well (you take one line in, process it and return a line (or list of lines)
10:06 [exa] joined
10:08 <iqubic> ongy: You can even use interact for that.
10:08 <iqubic> :t interact
10:08 <lambdabot> (String -> String) -> IO ()
10:08 mtesseract joined
10:08 <halogenandtoast> If I have a Text and I want to read it until a specific sequence of characters is there a function that lets me do that?
10:08 <ongy> does that line-buffer? If so, probably
10:09 connrs joined
10:09 <kellytk> How well can Haskell do what RxJS does, to allow composition of multiple event streams? After the basics of the bot work, I'd like to make it trade stocks for me
10:09 <kellytk> That would require intaking data continually via API queries and processing the flow
10:11 eacameron joined
10:11 <halogenandtoast> I think splitOn is what I wanted
10:12 rcat joined
10:12 filterfish joined
10:14 _sg joined
10:14 infinity0 joined
10:15 kody joined
10:15 sepp2k joined
10:16 Kreest_ joined
10:16 wroathe joined
10:17 bollu joined
10:18 eacameron joined
10:22 sssilver joined
10:22 <sssilver> Hey guys, anyone here knows Haskell?
10:22 <Sh4rPEYE> I stumbled upon Literate Haskell. Should I learn it/use it? I'm doing only fun little exercises, but there are some "organisation-ish" comments (like "this the task no. x, link: x), which could look better when put out of code.
10:22 <sssilver> I was having an interesting debate with my Clojure friend today. He was arguing that type systems are useless, because they're all deficient. And asked to model the following problem:
10:23 <Sh4rPEYE> Somewhere I read lhs is dead and one should use haddock... I've no idea what that is; should I use that instead?
10:24 <sssilver> imagine you have a function(m: hashmap, k: key), and it returns m[k]. Is it possible to model this in a way that the program won't compile if m[k] doesn't exist?
10:25 <sssilver> and I thought about it and realized that no I can't accomplish that using any language that I know
10:25 <sssilver> but then I remembered Haskell
10:25 NyanPasu joined
10:25 <sssilver> and here I am, asking for your input
10:25 <Gurkenglas> You'll have to know the key at compile-time, obviously, so you just make a record with a field for each k
10:25 balor joined
10:26 <sssilver> Gurkenglas: the set of possible hashables for k though, you can't define all of them
10:26 <sssilver> because there's infinite amount of them
10:26 <Gurkenglas> What decides whether m[k] exists?
10:27 <sssilver> the hashmap type I suppose
10:27 soLucien joined
10:28 filterfish joined
10:28 <Gurkenglas> Can infinitely many m[k] exist at a time, or are all m constructed by starting empty and filling up one by one?
10:28 <sssilver> my intuition was -- "do value types apply here"?
10:29 <sssilver> Gurkenglas: not sure I understand the question
10:29 <sssilver> OK let me rephrase the problem
10:29 eacameron joined
10:30 <sssilver> can you model a hashmap such that a program that uses it won't compile if you're accessing a nonexistent key on it
10:30 <sssilver> it seems that this would be theoretically impossible
10:30 bhiliyam joined
10:30 ixxie joined
10:30 <Maxdamantus> with dependent types you could have something like `get :: (map: Map k v) -> (key: k) -> hasKey map key -> v`
10:31 bollu joined
10:31 <Maxdamantus> but in Haskell you'd just produce a `Maybe v`
10:31 <bollu> bgamari: ping
10:31 <sssilver> Maybe you still need to unwrap runtime though
10:31 <Maxdamantus> ie, `get :: Map k v -> k -> Maybe v`
10:31 <sssilver> I mean yes Maybe is the closest you get
10:31 <Gurkenglas> Note that the dependent types one would require you to prove that the hashmap contains the key
10:31 <Maxdamantus> Yes, what Gurkenglas said.
10:32 <sssilver> guess I need to do some reading on dependent types
10:32 <Maxdamantus> but the proof (namely, the term of type `hasKey map key`) could be passed in by the caller.
10:32 <Gurkenglas> (Which he presumably got from putting it in the map, but then why not just lug around the value instead?)
10:33 <sssilver> aha, I think this is looking very much like it's possible!
10:33 <sssilver> makes a lot of sense
10:33 <Maxdamantus> so the caller could just check once that the key exists (checking existence of the key would give you something like `Either (hasKey map key) (not (hasKey map key))`) then multiple lookups can use the same proof.
10:34 <sssilver> so setting a key on the map gives you a type that says "that thing has been put"
10:34 <Gurkenglas> If you pass the proof to multiple lookups, why not pass the value to multiple sites that might want to look it up?
10:34 <sssilver> and then you only access the value on the map using that type
10:34 <Maxdamantus> Yes, you could also get that proof from the set operation.
10:34 <sssilver> Gurkenglas: because the value may be coming from an arbitrary place
10:34 <Gurkenglas> And if you only get a Maybe proof that's no better than the maybe value
10:34 <sssilver> that hasn't been set on the map
10:35 <Gurkenglas> sssilver, I mean if you get the proof from the map in order to give it to multiple sites, you could just get the value immediately and pass that to the multiple sites
10:35 epsilonhalbe joined
10:36 biglambda joined
10:36 <sssilver> Gurkenglas: I guess I'm confused by what you mean. To me the difference is that "the value" could be coming from anywhere, and the "proof" can only come from the map.set operation
10:36 <sssilver> I'm sorry I'm not an expert on this at all
10:36 <sssilver> just trying to keep my head above water at this point
10:36 wroathe joined
10:36 <Gurkenglas> If you can get the proof from the set operation, then you have the value, because you would need to pass it to the set operation
10:36 coec__ joined
10:37 <sssilver> ah, yes
10:37 <Gurkenglas> And if you can then pass the proof to whoever needs the value, then you have a way to pass things to them, and can pass the value instead
10:37 <sssilver> that is true
10:37 <sssilver> yes that makes sense
10:37 <sssilver> darn it
10:37 ragepandemic joined
10:38 <spion> Can something like TypeScript's "mapped types" be achieved Haskell? e.g. given a Vinyl record type, create a new record type with the same fields where for each field the original type is wrapped using `return`
10:39 <Gurkenglas> I think the usual way to achieve this is to start out with each value wrapped in an arbitrary m which is originally Identity
10:39 <Gurkenglas> See any of the monad transformers
10:40 exferenceBot joined
10:41 cpennington joined
10:42 eacameron joined
10:43 <sssilver> Gurkenglas: so just to continue the proof discussion, what type would this proof be?
10:43 <sssilver> sorry I know you could as well pass the value instead
10:43 <sssilver> but curious about the type system still
10:43 <Gurkenglas> I mean, the value would be a pretty good proof. jk
10:44 ragepandemic joined
10:45 filterfish joined
10:45 mohsen_ joined
10:46 Wizek_ joined
10:46 <ixxie> Has anybody tried shell scripting in Haskell using Turtle? I am considering that is a route to learn some Haskell....
10:46 cpape joined
10:46 coec__ left
10:47 wroathe joined
10:47 nirvinm joined
10:48 fuzzy-id` joined
10:49 wildlander joined
10:49 binaryplease joined
10:50 wildlander joined
10:51 <Gurkenglas> I mean, that's what Turtle does. Googling "haskell shell scripting turtle" finds https://hackage.haskell.org/package/turtle-1.3.2/docs/Turtle-Tutorial.html
10:51 wildlander joined
10:51 wildlander joined
10:51 jan-sipr joined
10:52 shwouchk joined
10:52 insitu joined
10:53 Avogadro joined
10:53 <ixxie> Gurkenglas: I get that, what I am wondering is if anybody has experience using this in practice
10:53 beeman joined
10:55 eacameron joined
10:55 filterfish joined
10:56 ziocroc joined
10:56 vaibhavsagar joined
10:56 Aruro joined
11:00 terrorjack left
11:00 terrorjack joined
11:02 Snircle joined
11:04 seveg_ joined
11:04 Yuras joined
11:06 indi_ joined
11:06 eacameron joined
11:07 <Athas> :t state
11:07 <lambdabot> MonadState s m => (s -> (a, s)) -> m a
11:07 wroathe joined
11:08 fragamus joined
11:11 detrumi joined
11:12 kritzcreek_ joined
11:13 mtesseract joined
11:13 epsilonhalbe left
11:15 Wizek_ joined
11:15 Itkovian joined
11:15 coot joined
11:16 melop joined
11:17 <dysfun> anyone know any good libraries for concurrent append-only logging?
11:17 <dysfun> the sort of logging that needs fsyncing to disk, that is
11:18 eacameron joined
11:19 BartAdv joined
11:20 dramforever joined
11:21 dramforever joined
11:21 dramforever joined
11:21 revprez_atlanta joined
11:21 <dramforever> Question: What are some use cases of ekmett
11:21 <dramforever> ekmett's ad
11:21 <dramforever> Stupid hands
11:22 mzf joined
11:23 <dramforever> Forward mode is relatively easy, everyone knows. Reverse mode as implemented in ad looks extremely complicated, involving various unsafe stuffs, and doesn't really look too efficient
11:24 eacameron joined
11:25 Sh4rPEYE joined
11:26 soLucien joined
11:26 <troydm> what are the options for interprocess communications in Haskell, for example I have two Haskell apps running on linux box and i want them to be able to communicate as quickly as possible
11:26 <troydm> ?
11:27 <terrorjack> mmap is your friend
11:27 wroathe joined
11:27 melop left
11:28 <troydm> terrorjack: u mean shared memory?
11:29 <terrorjack> yep
11:29 <troydm> terrorjack: ic, thx
11:29 oisdk joined
11:29 inr joined
11:29 <terrorjack> there's an mmap package on hackage, too
11:31 netheranthem joined
11:31 mtesseract joined
11:31 mmn80 joined
11:31 bhiliyam joined
11:32 <troydm> terrorjack: mmap I think can only working with memory-mapped files, not shared memory
11:33 Wizek joined
11:34 Argue_ joined
11:34 eacameron joined
11:35 mzf joined
11:35 <terrorjack> troydm: you need also to use shm_open call
11:36 <troydm> terrorjack: found this http://stackoverflow.com/questions/30446690/how-do-i-read-a-shared-memory-using-haskells-mmap-library
11:37 ziarkaen joined
11:38 wroathe joined
11:38 mzf joined
11:38 meba joined
11:39 JagaJaga joined
11:39 AndreasK joined
11:40 eacameron joined
11:42 mzf joined
11:42 xcmw joined
11:42 mzf joined
11:43 vydd joined
11:43 vydd joined
11:43 koitalel joined
11:45 sdothum joined
11:46 eacameron joined
11:47 mtesseract joined
11:48 blender joined
11:51 connrs joined
11:53 doomlord joined
11:53 fotonzade joined
11:55 beeman left
11:58 xcmw joined
11:58 blender joined
12:00 eklavya joined
12:00 Yuras joined
12:02 wroathe joined
12:02 plutoniix joined
12:08 LeCamarade joined
12:08 skeuomorf joined
12:11 ixxie joined
12:18 forgottenone joined
12:19 <Eduard_Munteanu> troydm, I'd use Unix-domain sockets. They are fast and easy to extend to TCP sockets if you need to.
12:19 <troydm> Eduard_Munteanu: not fast enough, shared memory is faster
12:22 wroathe joined
12:25 bollu joined
12:30 ysahil joined
12:30 vydd joined
12:30 vydd joined
12:31 mrcrjs joined
12:32 bhiliyam joined
12:32 blender joined
12:33 xcmw joined
12:33 a3Dman joined
12:38 fmmarques joined
12:38 augur joined
12:39 meba joined
12:41 pavonia joined
12:43 Fendor joined
12:43 wroathe joined
12:45 bollu joined
12:46 MrWoohoo joined
12:47 halogenandtoast joined
12:47 <Gurkenglas> Is there a way to get ":t x" to display the haddock type signature at least when x is a single token?
12:48 <Tuplanolla> Does it not, Gurkenglas?
12:48 wei2912 joined
12:48 <Gurkenglas> :t at
12:48 <lambdabot> (Functor f, At m) => Index m -> (Maybe (IxValue m) -> f (Maybe (IxValue m))) -> m -> f m
12:48 <Gurkenglas> http://hackage.haskell.org/package/lens-4.15.1/docs/Control-Lens-At.html#v:at
12:51 <Tuplanolla> :t emptyMap
12:51 <lambdabot> Ord keyAsGiven => M.Map keyAsGiven valueAsGivenToo
12:51 <Tuplanolla> That package must be doing something strange there.
12:51 a3Dman joined
12:51 a3Dman joined
12:52 <blender> is there any nicer way to plug in Maybe half way here https://pastebin.com/L9J5kQRc other than using MaybeT and a lambda ?
12:52 Denthir joined
12:53 wroathe joined
12:56 _sg2 joined
12:58 <Gurkenglas> blender, http://lpaste.net/320937101866565632
12:59 biglambda joined
12:59 <blender> Grunkenglas: oh wow, what is for ?
12:59 xmonader joined
12:59 <Gurkenglas> for is flip traverse
13:00 <blender> :t for
13:00 <Gurkenglas> (Oh wait you want for_ because you don't care for the results)
13:00 <lambdabot> (Applicative f, Traversable t) => t a -> (a -> f b) -> f (t b)
13:00 <Gurkenglas> :t for_
13:00 <lambdabot> (Applicative f, Foldable t) => t a -> (a -> f b) -> f ()
13:00 emc2 joined
13:00 <blender> amazing
13:00 <Gurkenglas> Note that lines 3 and 4 are interchangeable, and then one sees that saveVersionFileToLocalCache should have lCacheDir go as the last argument so you can eta-reduce the lambda away
13:00 oisdk joined
13:01 <blender> thanks, I will try. This might solve me quite a headache
13:01 splanch joined
13:02 meoblast001 joined
13:04 <blender> Gurkenglas: this was the original question but I am also very happy with for_ http://stackoverflow.com/questions/43408620/monad-transformer-and-applicative-maybe
13:05 forker joined
13:06 <Gurkenglas> Hint: Each use of for is a hint that there might be potential to refactor until you can replace for with a pointfree use of traverse
13:09 <blender> I understand. In the the case this was not my code and I could not change the oder of the arguments, do you suggest wrapping it?
13:10 <Gurkenglas> Nah, I'd let it stay ugly because it deserves to be and maybe write a pull request to the library
13:11 indi_ joined
13:12 Avogadro joined
13:13 twanvl joined
13:13 wroathe joined
13:15 oisdk joined
13:20 eacameron joined
13:21 fkurkowski joined
13:22 acarrico joined
13:23 nirvinm joined
13:23 mrcrjs joined
13:24 sepp2k1 joined
13:24 sz0 joined
13:24 wroathe joined
13:25 Yuras joined
13:27 gugah joined
13:28 Wizek_ joined
13:28 xormor joined
13:29 takle joined
13:31 BlueRavenGT joined
13:32 biglambda joined
13:32 nirvinm1 joined
13:32 bhiliyam joined
13:34 eacameron joined
13:34 cpup joined
13:35 nirvinm joined
13:36 bollu joined
13:36 AndreasK joined
13:36 fotonzade joined
13:38 connrs joined
13:43 connrs joined
13:44 biglambda joined
13:44 takle joined
13:45 <bollu> I can't have derivingAny and generalizedNewtypeDeriving on the same module?
13:45 a3Dman_ joined
13:48 Avogadro joined
13:51 Argue joined
13:52 takle joined
13:53 forgottenone joined
13:54 wroathe joined
13:57 <bollu> cocreature: ping
13:57 acarrico joined
13:59 gugah joined
14:00 <cocreature> bollu: pong
14:01 <bollu> cocreature: can I create new passes in haskell?
14:01 <bollu> cocreature: or will I need to do that in C++?
14:01 <cocreature> atm you need to do this in c++
14:01 <bollu> hm, I see
14:01 <bollu> unfortunate
14:02 <bollu> but "at the moment" is encouraging, I'm assuming you have a plan to bind this to haskell? :)
14:02 <cocreature> not really
14:02 <bollu> ah, OK
14:02 <fotonzade> fellas this is a horrible language
14:02 <bollu> cocreature: what files will I need to change? I assume I need to show the haskell PassManager the existence of my passes, for example?
14:02 <cocreature> bollu: the problem is that the AST exposed by llvm-hs-pure is not really meant to be processed by passes.
14:02 <bollu> ah
14:03 <cocreature> also the overhead of converting to the Haskell representation only to then convert to the C++ representation again is silly
14:04 <bollu> right
14:04 the_2nd joined
14:05 connrs joined
14:07 lordcirth joined
14:07 soLucien joined
14:10 SimpleL joined
14:12 takle joined
14:13 kamyar joined
14:13 <kamyar> hi all
14:13 <kamyar> please help mw with Scotty
14:13 electrostat joined
14:13 <kamyar> How can I use jsonData function?
14:14 <kamyar> parsing a post body
14:14 <kamyar> All samples use request itself
14:15 govg joined
14:17 harfangk joined
14:17 <Gurkenglas> kamyar, that question is hard to understand. If it's possible to restate it as a request for an expression of some type, that'd be better
14:17 sanett joined
14:17 <kamyar> Gurkenglas: I read Scotty samples for writing a JSON API: they used decode function from Aeson
14:17 bcremer1 joined
14:18 <kamyar> Gurkenglas: But I just want to use jsonData function which is inside SCotty
14:18 <kamyar> Gurkenglas: I just need to extract GPS info form a post body sent by client as JSON
14:20 wroathe joined
14:20 <Gurkenglas> Do you have a lens for the GPS info?
14:20 Itkovian joined
14:20 rcat joined
14:21 <kamyar> Gurkenglas: I have a Type for use with Aeson
14:22 <dgonyeo> I'm using the DuplicateRecordFields extension, and getting a bizarre error: https://gist.github.com/dgonyeo/ee28124518528db6dcd4f46f8e8ae1d1
14:22 <dgonyeo> has anyone seen that before?
14:22 <dgonyeo> the `Web.Mastodon.Lib.Types` function is coming from another package
14:22 <Gurkenglas> Let me rephrase. Do you have a function that'd give you the data you want given the value that corresponds to the JSON?
14:23 burtons joined
14:23 xcmw joined
14:23 <kamyar> Gurkenglas: I think it is simple: I just need to use Scotty to arse some request body given as JSON! Is it ambigious/
14:24 oisdk joined
14:24 <kamyar> Gurkenglas: *Parse
14:25 <kamyar> Gurkenglas: Now I guess using SCotty's internal function jsonData may help.
14:26 <Gurkenglas> kamyar, it doesn't seem to be internal http://hackage.haskell.org/package/scotty-0.11.0/docs/Web-Scotty.html#v:jsonData
14:28 <kamyar> Gurkenglas: It is defined within Scotty! Is'nt it?
14:28 <kamyar> Gurkenglas: As like reuqest and param
14:29 xcmw joined
14:30 eschnett joined
14:30 wroathe joined
14:31 sanett_ joined
14:31 coltfred joined
14:31 <kamyar> Gurkenglas: Why this phrase does not work: location <- jsonData :: (Maybe Location)
14:31 boombanana joined
14:32 niHiggim_ joined
14:32 <Gurkenglas> ActionM, not Maybe
14:33 takle joined
14:33 a3Dman joined
14:33 bhiliyam joined
14:33 <kamyar> Gurkenglas: But in the sample you see param "word"! See the signature: Text - > ActionM a
14:34 eacameron joined
14:34 SimpleL joined
14:34 <Gurkenglas> What function has that type? What sample do you mean?
14:34 Gredu joined
14:34 <kamyar> Gurkenglas: Just see the first sample
14:34 <kamyar> https://hackage.haskell.org/package/scotty
14:34 <Gurkenglas> The first sample from what list
14:35 <kamyar> Gurkenglas: on the top of the page
14:35 revprez_atlanta joined
14:36 beckyconning joined
14:36 <Gurkenglas> 'beam <- param "word"' <- This is in the ActionM monad. Using PartialTypeSignatures, 'beam <- param "word" :: ActionM _'
14:36 connrs joined
14:36 <Gurkenglas> "jsonData :: Maybe Location" this asserts that jsonData is in the Maybe monad, but it isn't
14:37 <kamyar> Gurkenglas: Now I just want to use jsonData like the way
14:37 <kamyar> Gurkenglas: Like the way it used param
14:37 insitu joined
14:37 <Gurkenglas> Why did you add ":: (Maybe Location)"?
14:37 <kamyar> Gurkenglas: I need a Location variable
14:38 <kamyar> Gurkenglas: PLease guide me
14:38 <kamyar> Gurkenglas: I have not used Haskell for about 6 months after my firts project and somewhat forgotten things
14:38 <Gurkenglas> Perhaps you want ":: ActionM Location" or ":: ActionM (Maybe Location)" there, and probably "" works as well
14:38 fnurglewitz joined
14:38 ebzzry joined
14:39 <kamyar> Gurkenglas: Yes empty works but how would I make GHC know how to parse json items and extract properties?
14:39 meba joined
14:40 wroathe joined
14:40 kylepotts joined
14:41 <kamyar> Gurkenglas: Does inference like "latitude location" work?
14:42 eacameron joined
14:42 <kamyar> Gurkenglas: I guess it worked! Thanks anyway!
14:43 takle joined
14:43 oisdk joined
14:47 RegEchse joined
14:48 <Gurkenglas> kamyar, you can have it show you the type it infers using ":: _" there
14:49 eacameron joined
14:50 xall joined
14:51 wroathe joined
14:52 noobineer joined
14:52 jmcarthur joined
14:53 Krymise joined
14:55 connrs joined
14:56 {emptyset} joined
14:56 Khisanth joined
14:58 sgflt joined
14:58 acarrico joined
14:58 zero_byte joined
14:59 ericmathison joined
14:59 nirvinm joined
15:00 connrs joined
15:01 wroathe joined
15:02 halogenandtoast joined
15:03 paulsh94 joined
15:04 SimpleL joined
15:04 <bollu> if I have a package compiled with stack in another location
15:04 <bollu> can I have it reuse that?
15:04 <bollu> I don't want to build it from scratch (LLVM, so it is quite large)
15:05 Krymise joined
15:07 <sbrg> bollu: yep, I think you can just point to the package
15:08 <sbrg> eh.. point to the package's directory in your other project's stack.yaml
15:09 <maerwald> why would stack build llvm
15:11 wroathe joined
15:12 nomicflux joined
15:15 sanett joined
15:15 indi_ joined
15:16 raycoll joined
15:16 a3Dman joined
15:18 bhiliyam joined
15:20 wroathe joined
15:24 Denthir joined
15:26 nicknovitski joined
15:26 connrs joined
15:27 cmsmcq joined
15:27 blender joined
15:28 jancc joined
15:29 richi238 joined
15:31 dhil joined
15:31 chbatey joined
15:32 codesoup joined
15:32 bhiliyam joined
15:34 pera_ joined
15:36 sanett joined
15:36 ublubu joined
15:38 <bollu> maerwald: because I'm using llvm-hs
15:38 bjz joined
15:38 texasmynsted joined
15:38 teggi joined
15:38 <maerwald> so you don't mean llvm, but llvm-hs?
15:39 dan_f joined
15:39 teggi joined
15:39 boombanana joined
15:39 forgottenone joined
15:42 urodna joined
15:44 kau joined
15:47 Itkovian joined
15:52 xall joined
15:53 Wuzzy joined
15:53 connrs joined
15:53 watabou joined
15:54 revprez_atlanta joined
15:56 cmsmcq joined
15:57 thunderrd joined
15:58 fotonzade joined
15:58 meoblast001 joined
15:58 insitu joined
16:00 darlan joined
16:01 boombanana joined
16:02 xmonader2 joined
16:05 wroathe joined
16:06 doomlord joined
16:07 connrs joined
16:07 <Gurkenglas> Is there a way to get ":t x" to display the haddock type signature at least when x is a single token?
16:08 <osa1> anyone here use language-c? I can't figure how to function arguments with types e.g. `(int x, int y)`. I'd love to see some examples
16:08 AndreasPK joined
16:08 bjz joined
16:08 <osa1> what is "haddock type signature" ?
16:09 <c_wraith> Gurkenglas: if x was defined with an explicit type signature, :t x should show that type signature.
16:09 portu joined
16:09 nirvinm joined
16:09 kamog joined
16:10 sanett joined
16:10 augur joined
16:11 portu joined
16:11 deciduously joined
16:12 allenj12 joined
16:12 sleffy joined
16:13 xall joined
16:14 connrs joined
16:14 <Gurkenglas> @let myat = at :: At m => Index m -> Lens' m (Maybe (IxValue m)) -- c_wraith
16:14 <lambdabot> Defined.
16:14 <Gurkenglas> :t myat
16:14 <lambdabot> (At m, Functor f) => Index m -> (Maybe (IxValue m) -> f (Maybe (IxValue m))) -> m -> f m
16:14 smwentum joined
16:14 ChaiTRex joined
16:15 wroathe joined
16:16 <Tuplanolla> It expands higher-rank type synonyms for some reason, c_wraith.
16:16 <c_wraith> so that really only impacts lens type signatures?
16:16 <Gurkenglas> :t over -- I think it's when they're in positive position
16:16 <lambdabot> ASetter s t a b -> (a -> b) -> s -> t
16:17 AndreasK joined
16:18 cmsmcq joined
16:20 eacameron joined
16:20 <Gurkenglas> @let negativelens = undefined :: Lens' s a -> s -> a -- Um.
16:20 <lambdabot> .L.hs:161:16: error:
16:20 <lambdabot> • Cannot instantiate unification variable ‘a0’
16:20 <lambdabot> with a type involving foralls: Lens' s1 a1 -> s1 -> a1
16:20 eacameron joined
16:21 <Sornaensis> negative lens?
16:21 <Gurkenglas> Something with a lens in negative position
16:22 <Gurkenglas> > let foo = view :: Lens' s a -> s -> a in foo -- UM.
16:22 <Sornaensis> what's a negative position
16:22 <lambdabot> error:
16:22 gugah joined
16:22 <lambdabot> • Couldn't match expected type ‘()’
16:22 <lambdabot> with actual type ‘Lens' s0 a0 -> s0 -> a0’
16:22 <Gurkenglas> the left side of an arrow
16:22 cyborg-one joined
16:22 <Sornaensis> why is it called negative?
16:22 <Gurkenglas> Coz you consume the value instead of producing it
16:22 gugah joined
16:22 <Sornaensis> ah
16:23 <Gurkenglas> So if you're in double negative position you're positive again: the a in (a -> x) -> x
16:23 portu joined
16:23 ixxie joined
16:23 AndreasPK joined
16:23 <Gurkenglas> (I mean, not sure whether it's called positive, but you're producing again.)
16:25 <Gurkenglas> :t let foo = view :: Lens' s a -> s -> a in foo -- why no error here, compared to the last one? :(
16:25 <lambdabot> Lens' s a -> s -> a
16:26 antky joined
16:27 <antky> @help
16:27 <lambdabot> help <command>. Ask for help for <command>. Try 'list' for all commands
16:27 <antky> hello
16:27 <antky> who is use lambdabot as hoogle
16:27 <antky> ?
16:27 <Theophane> *how you mean?
16:28 AndreasPK joined
16:28 <maerwald> @hoogle lens
16:28 <lambdabot> package lens
16:28 <lambdabot> Control.Lens.Lens lens :: (s -> a) -> (s -> b -> t) -> Lens s t a b
16:28 <lambdabot> Lens.Micro lens :: (s -> a) -> (s -> b -> t) -> Lens s t a b
16:28 kylepotts joined
16:29 <Sornaensis> @hoogle (a,b) -> c
16:29 <lambdabot> Prelude fst :: (a, b) -> a
16:29 <lambdabot> Data.Tuple fst :: (a, b) -> a
16:29 <lambdabot> CorePrelude fst :: (a, b) -> a
16:29 AndreasPK_ joined
16:29 <antky> @type map
16:29 <lambdabot> (a -> b) -> [a] -> [b]
16:30 <bbear> hi
16:30 <bbear> should I use fromJust ?
16:30 <bbear> no
16:30 <bbear> I shouldn't
16:31 <maerwald> bbear: ?
16:31 <bbear> I am struggling with monad composition : [] and Maybe
16:31 <c_wraith> bbear: there are rare occasions when it's ok, but even then it usually indicates a problem someplace else.
16:31 <bbear> yes
16:31 AndreasPK__ joined
16:31 <Sornaensis> > sequence [Just 5, Just 6]
16:31 <lambdabot> Just [5,6]
16:31 augur joined
16:31 <bbear> say I have a list of [Maybe
16:31 <bbear> ha yes
16:31 <bbear> but what is sequence exactly ?
16:31 <antky> hi eatman
16:31 <Sornaensis> :t sequence
16:31 <lambdabot> (Monad m, Traversable t) => t (m a) -> m (t a)
16:32 <c_wraith> > sequence [Just 5, Nothing]
16:32 <lambdabot> Nothing
16:32 <bbear> ha yes
16:32 <antky> how i see the man
16:32 <antky> hey
16:32 <Sornaensis> it moves the monad outside the traversable
16:32 <antky> anybody here me?
16:32 <maerwald> fromJust is fine if you know it's safe, but you should mark that spot, because next time you refactor it might not be safe anymore
16:32 <bbear> I was reading something related to that in RWH but I got lost.
16:32 <bbear> thanks.
16:32 <bbear> That was just what I looked for.
16:32 spectre joined
16:32 <fotonzade> fellows how do I define a type with a list of integers
16:33 <fotonzade> something like type Guy = Int [Int]
16:33 <fotonzade> I want to have a normal int with it too
16:33 <geekosaur> not with type, for starters
16:33 <fotonzade> ah
16:33 <Sornaensis> data Guy = Guy Int [Int] ?
16:33 <geekosaur> data Guy = Guy Int [Int]
16:33 <fotonzade> thank you very much
16:33 <bbear> how do I combine sequence with map
16:33 <bbear> is doing sequence.map ok ?
16:34 <bbear> it sounds kind of weird to me.
16:34 <geekosaur> :t sequenceA
16:34 <lambdabot> (Applicative f, Traversable t) => t (f a) -> f (t a)
16:34 <geekosaur> :t mapM
16:34 <lambdabot> (Monad m, Traversable t) => (a -> m b) -> t a -> m (t b)
16:34 <geekosaur> @src mapM
16:34 <lambdabot> mapM f as = sequence (map f as)
16:34 spectre left
16:34 <bbear> Is it ok to use Maybe in real code ?
16:34 <geekosaur> why wouldn't it be?
16:35 <ChaiTRex> bbear: Maybe.
16:35 <bbear> I mean I started to write some code and now I think using Maybe at some point is kind of the right thing to do.
16:35 blender joined
16:35 <bbear> I am still a noob so I wonder if effective use of Maybe may occur sometimes.
16:35 gcross_ joined
16:36 ziarkaen joined
16:36 <bbear> I mean at some point my goal is to keep my code reasonably straightforward before doing weird stuff.
16:37 splanch joined
16:37 jason85 joined
16:37 <bbear> problem is that it seems when you start to use Maybe somewhere, it kind of goes everywhere in your code like a plague.
16:37 <bbear> what do you think about this problem ?
16:38 <Sornaensis> sounds like your code might have encapsulation problems
16:38 <bbear> instead of Nothing, I could use empty list
16:38 <bbear> Sornaensis: possible.
16:38 grim_ joined
16:38 RoyalNightGuard joined
16:39 simukis_ joined
16:39 <fotonzade> I'm having trouble with this function
16:39 <fotonzade> http://paste2.org/eW09JLHG
16:39 AndreasPK_ joined
16:39 <fotonzade> the error is Couldn't match expected type ‘[a] -> Bool’ with actual type ‘Bool’
16:39 wroathe joined
16:40 <c_wraith> fotonzade: on line 5, you are passing 2 arguments to allEqual, but it only takes 1
16:40 <fotonzade> oh good lord thanks a lot c_wraith
16:40 <c_wraith> fotonzade: that error says it expects it to take another argument, given how you are using it
16:41 <glguy> fotonzade: How about: allEqual [] = True; allEqual (x:xs) = all (x==) xs
16:41 heurist` joined
16:41 <Sornaensis> :t all
16:41 <lambdabot> Foldable t => (a -> Bool) -> t a -> Bool
16:41 <glguy> fotonzade: generally if you find yourself using head and tail should should be using a pattern match instead
16:42 <Sornaensis> bbear: what are you trying to do that needs Maybe
16:42 <fotonzade> hmm
16:42 <fotonzade> thanks for the tip glguy
16:42 <bbear> I am trying to find the closest element of an argument in a list
16:43 Goplat joined
16:43 <bbear> minimumBy (on compare abs((-) x) mynumber
16:43 <bbear> something like that
16:43 <bbear> :t minimumBy (on compare abs((-) x)
16:43 <lambdabot> error:
16:43 <lambdabot> parse error (possibly incorrect indentation or mismatched brackets)
16:43 <bbear> :t minimumBy (on compare abs((-) x))
16:43 <lambdabot> error:
16:43 <lambdabot> • Couldn't match type ‘Ordering’ with ‘(Expr -> Expr) -> Ordering’
16:43 <lambdabot> Expected type: (Expr -> Expr) -> (Expr -> Expr) -> Ordering
16:44 <bbear> foo x= minimumBy (on compare abs((-) x))
16:44 <bbear> ha shit
16:44 <bbear> well I'm using minimumBy on a list
16:44 xkapastel joined
16:44 <bbear> the problem is : what do I do when the list is empty ?
16:45 <Sornaensis> :t minimumBy
16:45 <lambdabot> Foldable t => (a -> a -> Ordering) -> t a -> a
16:46 asmyers joined
16:46 <bbear> > let closestTo intList int = minimumBy (on compare abs((-) int)) intList in closestTo [1,2,3,4,8] 7
16:46 <lambdabot> error:
16:46 <lambdabot> • Couldn't match type ‘Ordering’ with ‘(a1 -> a1) -> Ordering’
16:46 <lambdabot> Expected type: (a1 -> a1) -> (a1 -> a1) -> Ordering
16:46 <bbear> >let closestTo intList int = minimumBy (on compare abs((-) int)) intList in closestTo [1,2,3,4,8] 7
16:46 <Sornaensis> it might be easier to avoid calling the function with an empty list
16:46 {emptyset} joined
16:47 sanett joined
16:47 <bbear> okay
16:47 <bbear> I'll try that. Youre right.
16:47 <bbear> thank you
16:50 wroathe joined
16:50 ph88 joined
16:51 kritzcreek_ joined
16:52 <ph88> hi guys, does anyone know what's the best way to serve static html from spock ? just read file ?
16:54 augur joined
16:55 oisdk joined
16:57 <ph88> lol searching for SpockM https://spockm.com/
16:59 NyanPasu joined
16:59 bkboggy joined
17:00 moth joined
17:00 <ph88> does anyone know how i can get hot code reloading with spock ? right now i open ghci and run main .. then when i change the code i have to abort :r and main again
17:01 blender joined
17:02 _sg joined
17:02 moth joined
17:03 ompaul joined
17:03 oisdk joined
17:03 binaryplease joined
17:03 iqubic joined
17:03 albertus1 joined
17:03 <ph88> is this not working because the code is using monad transformers and i have to use liftIO ? https://bpaste.net/show/ce86a34285a7
17:03 <iqubic> What do I have to import to be able to work with lenses in GHCi?
17:04 ericmathison joined
17:04 <ph88> iqubic, the lenses package .. there are several you can choose from
17:04 <iqubic> Like what?
17:04 <ph88> https://hackage.haskell.org/package/lens
17:04 Itkovian joined
17:04 <ph88> import Control.Lens & friends
17:05 <iqubic> ph88: Why am i getting an error in GHCi?
17:05 <ph88> iqubic, also pays off to google for "haskell lens tutorial"
17:05 <ph88> iqubic, dunno, what error on what code ?
17:05 <iqubic> Could not find module Control.Lens
17:05 <iqubic> trying to import Control.Lens, and I'm told that it couldn't find that module.
17:06 <geekosaur> you have to install it, probably
17:06 <monochrom> That will open a whole can of worms.
17:06 des_ joined
17:07 <iqubic> monochrom: What does that mean
17:07 <iqubic> Why do I have to install Control.Lens?
17:07 <geekosaur> because it's not part of a basic install
17:07 <geekosaur> very little is
17:07 <iqubic> Isn't that a part of core Haskell.
17:07 <iqubic> geekosaur: How do I install Control.Lens?
17:07 <geekosaur> no, the core contains only the things needed for the compiler to work
17:08 <iqubic> Oh.
17:08 <iqubic> What's provided in the Basic Install?
17:08 <iqubic> very little?
17:08 <geekosaur> ...and sticks to that because ghc has "interesting" version relationships, so anything shipped with it is effectively version-frozen. so we want it to be as small as possible to restrict versions as little as possible
17:08 <monochrom> The documentation that comes with GHC lists what's included.
17:09 <geekosaur> (cross-module inlining is great for speed and horrible for version management)
17:09 <iqubic> How do I install Control.Lens? With Stack?
17:09 <geekosaur> stack or cabal, yes
17:09 Denthir joined
17:09 cmsmcq joined
17:09 splanch joined
17:09 <Tuplanolla> You probably want to start with Microlens.
17:10 <iqubic> Why is that?
17:10 <geekosaur> also lens is specifically not in most distributions because it depends on half the ecosystem (so it can provide lenses for half the ecosystem...()
17:10 <Tuplanolla> It's a bit less overwhelming to the package manager and you.
17:10 <Tuplanolla> They're compatible anyway.
17:10 <iqubic> Tuplanolla: What the heck does that mean?
17:10 <geekosaur> what I just said
17:10 <glguy> If you start with lens you can figure out if you will mind losing what you lose when you drop down to microlens
17:11 xcmw joined
17:11 _sg joined
17:11 <iqubic> glguy: I was learning about lenses all last night. I think I know my way around the lens library.
17:11 <geekosaur> microlens gives you the lens machinery but very little in the way of predefined lenses for various data types
17:11 <iqubic> Oh. So I want to start with that?
17:11 <geekosaur> lens gives you a whole bunch of predefined lenses as well.. but that means it depends on every package that defiines data types for which it provides lenses
17:12 <geekosaur> so lens has a HUGE dependency list
17:12 <iqubic> I'll start with Microlens.
17:12 <iqubic> Does that contain prisms and isos too?
17:12 <iqubic> Or just lenses and traversals?
17:12 <glguy> It has lots of small dependencies and dependencies on things you'll likely depend on yourself anyway
17:13 mada joined
17:13 <iqubic> How do I install microlens in a place that I can always access the library?
17:13 <iqubic> Like how I can always import Data.Bits.
17:14 <geekosaur> ph88, you not only need to liftIO, you also need to deal with the fact that readFile is in IO but text is pure; you can't just use ($)
17:15 <fotonzade> Guys what if I wanted to sum a column in a matrix
17:15 <fotonzade> or wait
17:15 <fotonzade> no
17:15 <fotonzade> I want to check how many 1's there are in a matrix column
17:15 <fotonzade> [[Int]]
17:15 <monochrom> I might transpose the matrix and sum the row.
17:15 <monochrom> Likewise.
17:16 <monochrom> Not the only way but I would try it first.
17:16 <fotonzade> what would you do if you didnt know haskell
17:16 <monochrom> I would learn Haskell.
17:16 <fotonzade> nice
17:16 <iqubic> How do I install microlens in a place that I can always access the library?
17:16 <iqubic> Like how I can always import Data.Bits.
17:16 <iqubic> Is that possible to do?
17:17 <monochrom> It would be the same approach (transpose then work on row) in Scheme or SML or... as long as your matrix is [[Int]].
17:17 <iqubic> Isn't transposition kinda hard to do though??
17:17 <monochrom> I mean, you could also say "what about Java" but you wouldn't use [[Int]] for matrix in Java.
17:17 wroathe joined
17:17 systemfault joined
17:17 <fotonzade> I mean I'm working on stuff that is trivial with imperative programming
17:18 takle joined
17:18 <fotonzade> but I don't know how to do anything in haskell
17:18 <Tuplanolla> That's a linked list of linked lists, fotonzade.
17:18 <monochrom> Well yeah [[Int]] is not exactly an ideal matrix. You should use a real array. PEBKAC.
17:18 <fotonzade> right
17:18 <tsahyt> so I've now seen most of the new idris book.
17:18 <tsahyt> I have to agree that it's very good at making you jealous of dependent types
17:19 indi_ joined
17:19 <ph88> geekosaur, i don't understand why i can't use $, why doesn't liftIO take care of that ?
17:19 <tsahyt> and also of idris' ability to deduce code via proof search. but that should be possible to some degree in haskell too, right?
17:19 <tsahyt> I've found ghc-mod's auto command, but unfortunately ghcmod-vim doesn't implement it
17:19 <geekosaur> ph88, for the same reason show (readFile "foo") doesn't worl
17:19 <monochrom> So maybe my first instinct should have been "who the hell chose [[Int]]???!!!!"
17:19 <tsahyt> does anyone here use an editor with support for it?
17:19 <geekosaur> liftIO doesn't help there, >>= does
17:19 <iqubic> sumCol [] = 0; sumCol [[x:xs]:rest] = x + sumCol rest
17:19 <geekosaur> or fmap
17:20 <iqubic> that's a terrible way to do that. It uses no transposing at all.
17:20 takle joined
17:20 <ph88> iqubic, i would forget about the "can always access the library" right now, worry about that later
17:20 <iqubic> ph88, how would you install microlens?
17:21 <ph88> fotonzade, i think there are also special packages for dealing with matrices .. perhaps more efficient too than using list of list
17:21 <geekosaur> if you always use stack, you can install lens/microlens in the default project
17:21 <ph88> iqubic, stack install microlens
17:21 bab joined
17:21 <glguy> If you're using cabal you can: cabal install microlens
17:21 eacameron joined
17:21 <geekosaur> there is no "always availabel" because that tends to cause conflicts; you need to specify what versions of things you want
17:21 <ph88> tsahyt, can you link to the new idris book ?
17:21 <geekosaur> well, for just running ghc there is a global package space, but anything you install there WILL end up causing version conflicts and massive pain. DON'T.
17:22 <tsahyt> ph88: https://www.manning.com/books/type-driven-development-with-idris
17:22 <ph88> geekosaur, ok but since i was using liftIO i (maybe unreasonably) was expecting show (liftIO $ readFile "foo") to work .. how am i thinking about this the wrong way ?
17:22 <ph88> thank you tsahyt
17:22 <iqubic> geekosaur: is running "stack install microlens" a bad idea?
17:23 <ph88> iqubic, first you should start a new project with stack new myproject simple
17:23 <iqubic> Too Late. :)
17:24 <iqubic> I just ran "stack install microlens" in my home directory.
17:24 <ph88> iqubic, you can still do it and then use the generated files as doner files to your project i think
17:24 <iqubic> Where would the library have been installed?
17:24 <ph88> iqubic, that will install microlens in your global project .. which is ok .. but not really that maintainable in the long run .. better to start a new stack project
17:25 <ph88> iqubic, probably now it's installed somewhere in ~/.stack/global-project
17:25 <iqubic> And then reinstall?
17:25 <Tuplanolla> Skim this page, iqubic: https://docs.haskellstack.org/en/stable/yaml_configuration/
17:25 <ph88> you can leave it in the global project and just install it again in a project
17:25 <geekosaur> iqubic, the point of stack is to avoid those kinds iof problems
17:26 <geekosaur> but when you set up a new stack sandbox with stack init, you need to specify what you want to be visible inside it
17:26 <geekosaur> and stack will manage the rest
17:26 <iqubic> geekosaur: Can I remove it from my global project?
17:26 iomonad joined
17:26 <ph88> i never use stack init
17:26 <ph88> iqubic, you tied on disc space? :P
17:26 <iqubic> no.
17:26 <ph88> tight
17:26 <iqubic> I have plenty of disk space
17:26 <ph88> ok so leave it .. it doesn't harm for the moment
17:27 <geekosaur> well, or just have a stack.yaml somehow. stack init creates one for you if you don;t have obne
17:27 <monochrom> But perhaps it's recompilation time at stake.
17:27 <iqubic> Installing in my stack project told me that it just used the precompiled version.
17:27 wroathe joined
17:27 <iqubic> Is that bad
17:27 <iqubic> ??
17:28 <geekosaur> iqubic, I would not, no, but it will depend on what you are doing. I think at this point you would leave it unless you find it starts to cause version conflicts; then you'll want to sart using separate projects with their own stack.yaml files specifying what is to be visible
17:28 kylepotts joined
17:28 <ph88> no it's good, saves you time to use precompiled version
17:28 <ph88> it was already compiled by you another time
17:28 <iqubic> Yeah, just now when I installed it into the global project.
17:28 <iqubic> LOL
17:28 <ph88> geekosaur, do i need to use fmap for readFile ?
17:28 <geekosaur> ph88, if that still confuses you, you need to read http://www.vex.net/~trebla/haskell/IO.xhtml
17:28 <ph88> geekosaur, i've read that 2 days ago when you linked it for someone else
17:29 <geekosaur> liftIO does not mean "ohg go ahead and pretend you are in IO here"
17:29 <bbear> how do you concatMap ?
17:29 <bbear> : concat
17:29 <ph88> it doesn't cover liftIO
17:29 <bbear> :t concat
17:29 <lambdabot> Foldable t => t [a] -> [a]
17:29 <geekosaur> except in the sense where you are in a monad stack ewith IO at its botto
17:29 <ph88> i thought liftIO was a monad transformer thing
17:29 <geekosaur> it doers not help you in a pure context like show (some IO thing here)
17:29 <geekosaur> fmap will help you with that
17:29 <iqubic> So I have microlens installed.
17:30 <iqubic> How do I import it?
17:30 <ph88> nice one
17:30 zaquest joined
17:30 <ph88> import PACKAGENAME in your source file
17:30 <glguy> ?hackage microlens
17:30 <lambdabot> http://hackage.haskell.org/package/microlens
17:30 <ph88> in the documentation it says the name at the top
17:30 <glguy> You can review the documentation to find out what modules there are
17:30 <iqubic> What's the module name?
17:30 <glguy> and what's in those modules
17:30 <kellytk> iqubic: You were going strong with learning Haskell when I went to sleep, I just woke up, here you are you're relentless :-D
17:30 <iqubic> What is an ASetter?
17:31 <iqubic> Can I assume that is it is the same as a lens?
17:31 <bbear> is that something comparable to object inheritance in haskell ?
17:31 <iqubic> Looking at the type of over.
17:31 <iqubic> :t over
17:31 <lambdabot> ASetter s t a b -> (a -> b) -> s -> t
17:32 thc202 joined
17:32 <iqubic> What does the type synonym Lens s a expand to?
17:32 <rotaerk> hmm seems odd to me that pipes-cereal and pipes-binary haven't really been maintained
17:32 <ph88> iqubic, i would assume that you already read https://hackage.haskell.org/package/microlens-
17:33 <iqubic> Ah, ASetter is a lens with Identity as the Functor
17:34 diginet joined
17:34 <geekosaur> bbear, is what?
17:34 <geekosaur> but in general there is no inheritance, no
17:34 diginet left
17:34 <geekosaur> there's something that is sometimes described in a way that sounds like inheritance but isn't
17:34 <ph88> geekosaur, i'm confused what function am i suppose to fmap over IO action readFile ?
17:34 <iqubic> geekosaur: I said: "Can I assume that ASetter is the same as a Lens?"
17:35 <iqubic> That's what bbear thinks is inheritence
17:35 <Tuplanolla> The footer `div` in Haddock documentation is stuck in its initial position, overlapping the contents of the page. Is this a bug in Haddock's CSS or in Firefox's renderer?
17:35 <geekosaur> that's not inheritance, just specialization
17:35 <geekosaur> slotting in some or all of the types called for by type variables in another type
17:35 <iqubic> Right.
17:36 <geekosaur> ph88, in this case, it won;t help you. in the show case it would, since you would fmap show over it.
17:36 <iqubic> I just pointed out that ASetter is a Lens with Identity as Functor
17:36 <ph88> geekosaur, can i even use readFile together with Web.Spock.get or do i have to use another function here ?
17:36 <iqubic> good bye for now.
17:36 <iqubic> I have to go
17:36 <geekosaur> but for your case, you need something like: s <- liftIO $ readFile "whatever"; Web.Spock.get "/test" s
17:36 <ph88> bye iqubic
17:37 <ph88> oooh
17:37 <geekosaur> but I don;t know if liftIO is right there because I don;t know whether there is an IO directly accessible there
17:37 pbogdan joined
17:37 <ph88> let's find out :P
17:37 <geekosaur> I seem to recall you need to get at the Spock context or something like that
17:37 <ph88> oh you worked with spock ?
17:38 orbifx joined
17:38 <geekosaur> no, that's why I'm uncertain
17:38 <geekosaur> have run into its types before but have never sat down to understand what's going on with them, so.
17:38 <ph88> well good that you know about spock context then ^^
17:38 <ph88> ok
17:38 <ph88> well that code didn't type check
17:38 coltfred_ joined
17:40 ph88 joined
17:40 <ph88> geekosaur, i got it to type check now with Web.Spock.get "/test" (text s) .. i think text was some spock function to return an action
17:40 <ph88> it looks a bit stupid though ..
17:40 <geekosaur> the one I found was in Data,Text and just pcks a String to make a Text
17:41 <geekosaur> but, I suppose Spock might have its own just to confuse things
17:41 meba joined
17:41 <ph88> oh and also .. it serves up the html as text hahah
17:42 <ph88> ActionCtxT () (WebStateM SqlBackend MySession MyAppState) ()
17:42 <ph88> maybe i should use https://hackage.haskell.org/package/Spock-
17:46 wroathe joined
17:48 blender joined
17:50 cmsmcq joined
17:50 chbatey joined
17:51 <bbear> I'm stuck in my programming
17:51 <bbear> The architectural flaw in my program prevents me to go forward.
17:51 <bbear> What can I do ?
17:52 <rotaerk> refactor
17:52 <rotaerk> also don't prematurely engineer/abstract
17:53 <ph88> i'm trying to follow this blog about spock serving static files http://watchchrislearn.com/blog/2014/12/24/spock-basics/ it talks about SpockT but i can't find this in the package .. anyone know if there is a replacement for it ?
17:53 TheLemonMan joined
17:54 <ph88> bbear, what is the flaw ?
17:55 eazar001 joined
17:56 flump joined
17:56 portu_ joined
17:57 wroathe joined
17:57 <portu_> I dont know where is apropriate to ask such question, (newbie) it's related with nix-shell, emacs, and haskell development, I can not figure out how to use nix-shell via emacs by default, that flycheck and everything else can work out of the box
17:59 <bbear> It's ok I adde pattern matching to cover my track
17:59 Fendor joined
18:01 dan_f joined
18:01 <ph88> when i have [String] and i want Text, is it more efficient to go to [Text] first or String first ?
18:02 <ph88> i use pack and concat
18:03 <jle`> ph88: my intuition says concat then pack, but it's worth benchmarking
18:03 <ph88> ok :P
18:03 <jle`> this is the sort of question that can be easily answered by a few benchmarks
18:03 <jle`> :)
18:03 connrs joined
18:03 <ph88> in my case, simple benchmarks, but not easy :P
18:03 <jle`> actually i could see why pack then concat might be faster
18:04 <sbrg> we need criterion support in lambdabot!
18:04 pbogdan joined
18:04 <jle`> that'd be nice actually :o
18:04 <jle`> these questions are actually pretty popular on #haskell
18:04 <ph88> when i have F Char can i fmap [] to make it F String ?
18:04 <ph88> it looks weird
18:04 <jle`> fmap (:[]), if F has a Functor instance
18:04 <jle`> the robot monkey operator
18:05 <sbrg> fmap return works as well
18:05 <sbrg> or fmap pure
18:05 sedeki joined
18:05 doomlord joined
18:05 fkurkowski joined
18:05 hybrid joined
18:06 wroathe joined
18:07 <ph88> robot monkey ! :D
18:07 <texasmynsted> robot monkey?
18:07 <ph88> (:[])
18:09 <texasmynsted> Does anybody here have an opinion about the Category Theory "The Beginner's Introduction" videos from Dr. Martin J.M. Codrington?
18:09 <jle`> fmap (:[]) (Just 3)
18:09 NoCreativity joined
18:09 conal joined
18:09 <texasmynsted> I just watched the first one and so far I am liking it. I hope it will help me with the way that categories and types work in Haskell.
18:10 <ph88> > fmap (:[]) 'A'
18:10 <lambdabot> error:
18:10 <lambdabot> • Couldn't match expected type ‘f a’ with actual type ‘Char’
18:10 <lambdabot> • In the second argument of ‘fmap’, namely ‘'A'’
18:10 <ph88> > fmap (:[]) (Just 'A')
18:10 <lambdabot> Just "A"
18:10 <ph88> > :t fmap (:[]) (Just 'A')
18:10 <lambdabot> <hint>:1:1: error: parse error on input ‘:’
18:10 <ph88> texasmynsted, good tip, i will check them out too :P
18:10 revprez_atlanta joined
18:11 <ph88> are they on youtube ?
18:12 srbaker joined
18:12 ertesx joined
18:13 <ph88> is there a function in applicative that takes an input and returns () ? like void in purescript
18:13 <sbrg> yep, void
18:13 <sbrg> :t void
18:13 <lambdabot> Functor f => f a -> f ()
18:13 <sbrg> well, a functor
18:14 kamyar joined
18:14 <kamyar> Hello again
18:14 <ph88> hello kamyar
18:14 <kamyar> What is the equivalent of a void function in Haskell? I mean when declaration
18:14 <jle`> what is a 'void function' ?
18:14 <kamyar> For example, can I say MyFunc :: Int -> a
18:14 <ph88> kamyar, it's ()
18:14 <kamyar> I mean a function with interger argument and no return
18:14 <ph88> kamyar, MyFunc :: Int -> ()
18:15 <kamyar> ph88: Thanks!
18:15 <jle`> kamyar: all functions return something in haskell, by definition
18:15 <sbrg> () is the simplest type that we have, because it just contains one inhabitant: the value ()
18:15 <jle`> but () conveys no information, so it's like "returning nothing"
18:15 <sbrg> so it is commonly used to denote "i'm not really returning anything important"
18:15 <kamyar> jle`: I Guess Int -> () is equvalent of Int -> a
18:15 <sbrg> kamyar: no, because you can't write a function with the latter type
18:15 <jle`> kamyar: they are different
18:15 <ph88> kamyar, but this type signature is weird ... maybe better use :: Int -> IO () because why you want to put arguments in a function that returns nothing ?
18:16 <sbrg> except for "foo :: Int -> a; foo _ = undefined"
18:16 <jle`> kamyar: a function in haskell is described as some A -> B, that takes an A and returns a B. so a function that returns nothing is not a function, by definition
18:16 <M-kevinliao> Hi, I'm wondering how people feel is the best way to get started with GUI programming in Haskell?
18:16 <jle`> but yes, `foo :: Int -> a` is not possible to write without being an error or an infinite loop
18:16 wroathe joined
18:16 <jle`> try it and see why :)
18:17 <texasmynsted> Here is the link I found for the videos… https://www.youtube.com/playlist?list=PLm_IBvOSjN4zthQSQ_Xt6gyZJZZAPoQ6v
18:17 <sbrg> yeah, there are essentially two valid definitions: foo a = foo a and foo _ = _|_
18:17 <kamyar> Actually I need to write some wrapper functions for writing data into redis and can be called from anywhere in my program
18:17 <ph88> kamyar, when you use a lowercase letter or word like "a" it can have all types .. you can then constrain the types by using => .. but if you don't use => then "a" just means "everything" .. it then depends on the context where you use your function what is expected to be returned. But you can not create a function that takes an Int and can return every possible type i think
18:17 <sbrg> which are kind of equivalent really
18:17 <kamyar> What signature do u recommend?
18:17 jeltsch joined
18:17 <ph88> M-kevinliao, i feel electron :P
18:18 <ph88> thx texasmynsted
18:18 <jle`> kamyar: if you have something that writes to redis, it'll probably be IO (), or something similar
18:18 <jle`> kamyar: you'll be returning a computation, like IO () or Redis ()
18:18 <kamyar> jle`: Thanks!
18:18 <jle`> remember that haskell functions are pure, so foo :: Int -> () is kinda silly
18:18 <M-kevinliao> ph88: As in ditch Haskell altogether and just write an electron app?
18:18 <jle`> the only implementation is 'const ()'
18:19 <jle`> M-kevinliao: write an electron app in haskell
18:19 <sbrg> M-kevinliao: don't have to ditch Haskell. I think you could roll Haskell for the backend, for example. and you could use ghcjs
18:19 <ph88> M-kevinliao, no you stay with haskell, but then for frontend you can use ghcjs or purescript, and for backend you just use haskell ... it's just my opinion. Ask other opinions
18:19 <sbrg> I would personally probably just go the web route, and either just make a website, or make an electron application using Haskell and probably ClojureScript
18:20 <ph88> you can also use Qt with haskell or whatever .. i would just go for electron because i have affinity with web development
18:20 <ph88> it's what you want
18:20 <Tuplanolla> I would go with Brick, because text ought to be enough, M-kevinliao.
18:21 <sbrg> yeah brick is actually pretty cool.
18:21 <sbrg> very easy to get up and running
18:21 <ph88> he ask for gui :P
18:21 <M-kevinliao> Oooh Brick and GHCJS both look interesting... It seems like the current state of GUI programming is a bit of a mess...
18:21 <Tuplanolla> It may be half-g, but it's full-u and full-i.
18:22 <M-kevinliao> Anyone ever work with GTK on Haskell?
18:22 indi_ joined
18:22 eacameron joined
18:22 <sbrg> i tried a bit. it's a pain IMO
18:22 <Tuplanolla> I installed it once.
18:22 <glguy> M-kevinliao: I've made UIs with vty, gtk, and web-interfaces in Haskell
18:22 <sbrg> there's also FLTKHS
18:22 <glguy> M-kevinliao: which is better will depend on what you're building
18:23 <M-kevinliao> I don't know exactly what I'm building yet. I'm just playing around with all sorts of different things and exploring a final project for Richard Eisenberg's FP class at Bryn Mawr. :P
18:23 kylepotts joined
18:23 carlomagno joined
18:24 pbogdan joined
18:24 <ph88> glguy, what did you like the best ?
18:24 <glguy> M-kevinliao: Examples http://imgur.com/a/ISOxN http://imgur.com/a/yoUHm
18:25 Yuras joined
18:25 <sbrg> haha, cookie clicker
18:25 <glguy> example: https://www.youtube.com/watch?v=2NG4sqXLZlk lua debugger via webb interface
18:25 hamishmack joined
18:25 <ph88> Cookie Calculator looks like a very serious app
18:25 <glguy> ph88: I don't think one is best
18:26 safe joined
18:26 <ph88> glguy, just what you like the best ;)
18:26 <glguy> ph88: The cookies accumulation rate isn't going to accelerate itself :)
18:26 <Tuplanolla> I'd be very surprised if the answer was GTK+.
18:27 wroathe joined
18:27 <ph88> i'd go with Qt over GTK myself
18:27 <glguy> I really don't have a favorite. I wouldn't have wanted to do any of those three projects in a different UI environment than they were done in
18:28 <ph88> was the web-interface with electron ?
18:28 <glguy> snap-server and jQuery
18:28 <glguy> That lua debugger project distributes as a library you link into your actual program
18:29 <glguy> so that project can't take over the UI, it just opens an HTTP server
18:32 aarvar joined
18:32 <glguy> I can't speak to the merits of Qt vs Gtk from Haskell. I've only tried Gtk. As far as GTK goes I liked the gi-gtk package over the gtk package
18:34 srbaker_ joined
18:36 <srk> glguy: I can compare gtk and qt from before and qt was more stable and easier to work with
18:36 <srk> now I find qt kind-of hard to compile
18:36 <srk> I would like to try implementing gui in gl like https://github.com/ocornut/imgui
18:37 <srk> looks doable with e.g. gloss. there's also UISF which does similar thing
18:37 mac10688 joined
18:38 chbatey joined
18:39 srbaker_ joined
18:40 <glguy> Oh, I forgot about gloss, but I've made some stuff with gloss and it was nice, too.
18:41 <sbrg> M-kevinliao: https://maxow.github.io/posts/creating-a-desktop-application-with-threepenny-gui-and-cef3.html this may be relevant to your question
18:41 <M-kevinliao> Oooh I'll take a look at that. Thanks sbrg
18:43 <glguy> Yinsh game: http://imgur.com/a/25DGm
18:43 vaibhavsagar joined
18:44 <Cale> :D
18:44 <Cale> I haven't played Yinsh, but I played a bunch of the Gipf project games with a friend of mine in university.
18:45 aarvar left
18:45 splanch joined
18:46 srbaker joined
18:47 wroathe joined
18:48 bjz joined
18:49 kylepotts joined
18:49 biglambda joined
18:50 JagaJaga joined
18:50 <glguy> updated with circular slide rule and Hidden in Plain Sight knockoff: http://imgur.com/a/25DGm :)
18:51 augur joined
18:51 revprez_atlanta joined
18:51 <glguy> Just imagine the productivity improvements of using your computer as a sliderule to do computations instead of doing them directly with the computer !
18:52 dfeuer joined
18:52 oisdk joined
18:53 raichoo joined
18:53 cyborg-one joined
18:53 mou joined
18:56 <srk> cool
18:56 zv joined
18:56 emc2 joined
18:56 <srk> do you think it would be possible to compose gloss with another 3d GL framework?
18:58 chbatey joined
19:06 JagaJaga joined
19:07 maarhart joined
19:07 wroathe joined
19:07 <Tuplanolla> There's `not-gloss`, srk.
19:08 <Tuplanolla> I haven't used it yet though.
19:08 <srk> Tuplanolla: haha, nice
19:08 blender joined
19:09 <infinity0> is there a function to turn a State s a into a StateT s m a ?
19:09 orbifx joined
19:09 <hpc> whoever wrote not-gloss missed an amazing opportunity to name it matte
19:10 <srk> :))
19:12 <infinity0> oh i guess "hoist generalize" from mmorph does what i want
19:12 <pavonia> infinity0: mapStateT should also work
19:13 <sbrg> hpc: submit a bug report ;)
19:13 <infinity0> pavonia: ah thanks
19:13 des_ joined
19:15 initiumdoeslinux joined
19:15 ryantm joined
19:16 zeroed joined
19:16 zeroed joined
19:19 gawen joined
19:20 pera joined
19:20 sophiag joined
19:20 zv joined
19:21 <infinity0> on second thoughts "hoist generalize" is what i actually needed, i don't have anything to pass to mapStateT's first argument
19:22 ptvirgo joined
19:23 NoCreativity joined
19:23 halogenandtoast joined
19:23 <glguy> :t state . runState
19:23 <lambdabot> MonadState s m => State s a -> m a
19:23 dmwit_ joined
19:26 <glguy> or
19:26 <glguy> mapStateT (return . runIdentity) :: Monad m => State s a -> StateT s m a
19:26 alx741 joined
19:28 wroathe joined
19:28 <kellytk> Is PureScript and improvement upon Haskell?
19:29 <bbear> is there bug in GHC ?
19:29 <glguy> yes
19:30 <bbear> known bugs ?
19:30 <jle`> kellytk: they're different
19:30 <glguy> bbear: Yes, known and unknown
19:31 doomlord joined
19:31 <terrorjack> kellytk: A different approach. Some problems are addressed though (monolithic IO monad, etc)
19:33 <sbrg> @let isBugInSoftware = const True
19:33 <lambdabot> Defined.
19:33 eacameron joined
19:33 <jle`> isBugInSoftware :: Software -> Bool ...?
19:33 wroathe joined
19:34 <sbrg> i guess it's a bit too polymorphic
19:35 Fendor joined
19:37 chbatey joined
19:38 coltfred_ joined
19:38 vicfred joined
19:40 magneticduck joined
19:42 <bbear> ok
19:42 <bbear> was wondering
19:42 <bbear> you know this post on quora
19:43 <bbear> https://www.quora.com/Which-of-Haskell-and-OCaml-is-more-practical/answer/Jon-Harrop-2
19:43 Destol joined
19:43 <bbear> don't read this it will hurt you but basically it says that ghc is bogus.
19:43 <bbear> well was wondering if it was true to some extent.
19:43 <infinity0> glguy: oh, thanks
19:44 Denthir joined
19:44 <bbear> Don't take me wrong. I am sure that GHC is a fine piece of software. I am even more sure that it is kind of a masterpiece in the actual CS world.
19:44 leat joined
19:45 wroathe_ joined
19:45 <terrorjack> Before another Haskell versus OCaml flamewar starts...
19:46 <glguy> bbear: No need to be hurt by Jon Harrop's words
19:46 <terrorjack> Why not learn both
19:46 <glguy> starting flame wars is basically what he does
19:46 jeltsch joined
19:46 Wedamm joined
19:48 <glguy> Perhaps by the elevated profile of his regular posts drive more business to his consulting service. I like to think there's a point to it all
19:48 zv joined
19:50 systemfault joined
19:51 <jgt> how can I test if two lists have any common elements?
19:51 JoshS joined
19:51 <jgt> don't need the common elements, just a bool result
19:52 <bbear> map elem
19:52 <sbrg> > let (x, y) = ("foo", "boo") in any (`elem` x) y
19:52 <lambdabot> True
19:52 <jle`> map . elem, but that's pretty inefficient
19:52 <bbear> not sure
19:52 <jle`> > "foo" \\ "bar"
19:52 <lambdabot> "foo"
19:52 <jle`> oh
19:53 <jle`> > "foo" `intersect` "bar"
19:53 <lambdabot> ""
19:53 <bbear> yes
19:53 <jle`> > "foo" `intersect` "bara"
19:53 <bbear> intersect
19:53 <lambdabot> ""
19:53 <jle`> > "foo" `intersect` "barao"
19:53 <lambdabot> "oo"
19:53 <terrorjack> f = (null .) . intersect
19:53 <jgt> so maybe I'm going to have to convert the lists to sets, intersect them, and test the length of the result
19:53 <jle`> if your type is Ord, then yeah, you should use Set instead
19:53 <jle`> you do'nt need to test the length; just check if it's empty
19:54 <jgt> right
19:54 <bbear> :t elem
19:54 <lambdabot> (Eq a, Foldable t) => a -> t a -> Bool
19:54 the_2nd joined
19:54 <jgt> thanks :)
19:54 atomi joined
19:55 <the_2nd> I want to have a simple json api for my lib / program. What framework should I use?
19:55 <bbear> :t any(map (isIn foo) bar) where isIn b a=elem a b
19:55 <lambdabot> error: parse error on input ‘where’
19:55 nagyf joined
19:55 <bbear> let isIn b b = elem a b in any(map(isIn foo) bar)
19:56 <glguy> where isn't part of an expression
19:56 gibbers joined
19:56 <bbear> >let isIn b a = elem a b in any(map(isIn foo) bar)
19:56 sepp2k joined
19:57 <bbear> >let intersect foo bar = let isIn b a = elem a b in any(map(isIn foo) bar) in intersect [1,2] [2,3]
19:57 ixxie joined
19:57 <bbear> weird
19:57 jeltsch joined
19:58 <jgt> the_2nd: you can do a simple json api in Yesod. It's what I use for everything.
19:58 kylepotts joined
20:00 <geekosaur> the space is mandatory
20:00 <geekosaur> > 0
20:00 <lambdabot> 0
20:01 <bbear> > let (isIn a b = elem b a) in intersect foo bar = any (isIn foo) bar
20:01 fragamus joined
20:01 <lambdabot> <hint>:1:15: error:
20:01 <lambdabot> parse error on input ‘=’
20:01 <lambdabot> Perhaps you need a 'let' in a 'do' block?
20:01 <bbear> > let ((isIn a b) = (elem b a)) in intersect foo bar = any (isIn foo) bar
20:01 <lambdabot> <hint>:1:17: error:
20:01 <lambdabot> parse error on input ‘=’
20:01 <lambdabot> Perhaps you need a 'let' in a 'do' block?
20:01 <bbear> wow
20:01 <bbear> anyway
20:02 <bbear> it works
20:02 <jle`> bbear: you can always test it out in private chat too :)
20:02 <bbear> intersect foo bar = any (isIn foo) bar
20:02 <bbear> surpinsingly concise
20:02 <bbear> yes irc chan is not made to run cod
20:02 <bbear> ghci is
20:02 <geekosaur> you can't do definitions like that in lambdabot. it is NOT ghci
20:03 <* bbear> is wondering who is lambda bot
20:03 <geekosaur> "> " evaluates expressions. not definitions
20:03 <geekosaur> you can use @let for (some) definitions
20:03 <geekosaur> @version
20:03 <lambdabot> lambdabot
20:03 <lambdabot> git clone https://github.com/lambdabot/lambdabot
20:03 splanch joined
20:04 <the_2nd> jgt, already used happstack for some projects. scotty seems nice too
20:05 jeltsch joined
20:05 acarrico joined
20:06 dc0de joined
20:07 <infinity0> oh, looks like hoist is exactly mapStateT and generalize is exactly return . runIdentity
20:07 karchie joined
20:08 <jle`> except less polymorphic
20:08 <jle`> hoist only lets you lift a (forall a. m a -> n a)
20:12 ogelbukh joined
20:12 maarhart joined
20:14 <jgt> the_2nd: if that's what you're comfortable with, then go with that :)
20:15 Swizec joined
20:16 strykerkkd joined
20:17 des_ joined
20:17 snowalpaca joined
20:19 coot joined
20:19 <simukis_> a recent ghc on my new ryzen is taking 24 minutes now to compile release+profiling libraries of aeson. Is that expected?
20:20 revprez_atlanta joined
20:20 <simukis_> to be honest I haven’t built anything haskell for long time so I don’t know if its ghc, aeson change or anything else
20:20 jeltsch joined
20:20 <simukis_> (and by 24 minutes I mean that it has taken 24 minutes of cpu time already and is still going strong)
20:21 <Athas> Is that including all dependencies?
20:21 <Athas> If so, that might easily be the case. Especially if you didn't utter enough magic words to make it build in parallel.
20:22 gawen joined
20:23 <simukis_> Athas: no, it is stuck eating a single core for 25 minutes now
20:23 <simukis_> oh its done
20:23 <simukis_> so approx 25-26 minutes
20:24 zv joined
20:24 beckyconning joined
20:25 indi_ joined
20:26 richi235 joined
20:27 pbogdan joined
20:28 nomeata joined
20:28 <xcmw> Is there a way to use Maybe with freer-effects or extensible-effects?
20:28 <the_2nd> I have a function a -> IO (Either e a)
20:29 <the_2nd> and would like to apply that to many [a] in such a way
20:29 <the_2nd> that I get a IO (Either e [a])
20:29 xdelv joined
20:30 <the_2nd> I tried using mapM but end up with e.g. IO ([Either e a])
20:30 <xcmw> map then sequence
20:30 <xcmw> sequence twice
20:31 <xcmw> squence . sequence $ map function array
20:32 <Gurkenglas> :t alaf Compose traverse :: (a -> IO (Either e a)) -> [a] -> IO (Either e [a])
20:32 <lambdabot> (a -> IO (Either e a)) -> [a] -> IO (Either e [a])
20:34 <the_2nd> Gurkenglas, alaf?
20:34 <the_2nd> I mean the signature looks good, but no idea what to use there
20:35 <the_2nd> ??? f xs
20:36 <Gurkenglas> alaf Compose traverse f xs
20:36 <the_2nd> alaf from Control.Lens?
20:37 takle joined
20:37 <Gurkenglas> yep
20:38 <Tuplanolla> It's just `alaf Compose f = getCompose . f . Compose`, the_2nd.
20:38 <the_2nd> I guess I have to read up on lenses then :D
20:39 kamyar joined
20:39 <kamyar> Hello fellows
20:39 <Tuplanolla> You don't necessarily need it.
20:39 <xcmw> fmap sequence . sequence $ map function array works if you confused by alaf
20:39 <the_2nd> but Gurkenglas 's version seems to work fine, thanks
20:39 <Gurkenglas> no, alaf Compose f g = getCompose . f (Compose . g)
20:39 <kamyar> please help me use messagepack to serialize an object
20:39 <Tuplanolla> Ah, indeed, Gurkenglas.
20:39 <xcmw> I missed an fmap the first time
20:41 <the_2nd> xcmw, yeah it didn't work before
20:41 <the_2nd> that version does
20:41 <kamyar> Please give me a sample code for using MessagePack
20:41 <the_2nd> I'll go with xcmw's version then, so I won't hate myself in the future in case I still don't know much about lenses ;)
20:42 wroathe joined
20:42 Remavas__ joined
20:42 <the_2nd> fmap sequence . mapM f xs
20:45 <Gurkenglas> > (`runState` 0) $ alaf Compose traverse (maybe (return $ Left "Nothing encountered") $ \i -> modify (+i) *> gets Right) [Just 3, Just 2, Nothing, Just 4] -- the_2nd, it doesn't short-circuit though - EitherT does
20:45 <lambdabot> (Left "Nothing encountered",9)
20:46 <kamyar> PLease reply me
20:46 <Tuplanolla> :t getCompose .: traverse . fmap Compose :: (a -> IO (Either e a)) -> [a] -> IO (Either e [a]) -- You don't need lenses for this, the_2nd.
20:46 <lambdabot> (a -> IO (Either e a)) -> [a] -> IO (Either e [a])
20:46 <Gurkenglas> (ExceptT here I guess since that's imported by lens and technically does the same thing)
20:46 <Gurkenglas> :t alaf ExceptT traverse
20:46 <lambdabot> (Monad m', Traversable t) => (a -> m' (Either e' a')) -> t a -> m' (Either e' (t a'))
20:47 <Gurkenglas> > (`runState` 0) $ alaf ExceptT traverse (maybe (return $ Left "Nothing encountered") $ \i -> modify (+i) *> gets Right) [Just 3, Just 2, Nothing, Just 4] -- See, now it doesn't add the 4 after failing on the Nothing
20:47 <lambdabot> (Left "Nothing encountered",5)
20:47 insitu joined
20:48 Sampuka_ joined
20:50 raycoll joined
20:53 kylepotts joined
20:53 texasmynsted joined
20:54 MrRicecake joined
20:56 nakal_ joined
20:58 splanch joined
20:59 bjz joined
21:00 mac10688 joined
21:01 <the_2nd> thanks
21:01 insitu joined
21:04 insitu_ joined
21:04 boombanana joined
21:05 sedeki joined
21:06 jao joined
21:12 Sampuka joined
21:14 rockfordal joined
21:17 fragamus joined
21:19 ij joined
21:19 Deide joined
21:24 Sampuka joined
21:24 madsa joined
21:24 epsilonhalbe joined
21:24 Edith joined
21:24 markus1189 joined
21:25 markus1199 joined
21:26 robotrolll joined
21:26 ericmathison joined
21:30 biglambda joined
21:30 g0d355__ joined
21:31 <ij> Is stack docker's integration for only building or running too?
21:31 ericmathison joined
21:34 Itkovian joined
21:34 codesoup joined
21:34 silver joined
21:35 USBoss joined
21:35 Destol joined
21:35 Micamo joined
21:37 xcmw joined
21:42 <kellytk> I'm attempting to get started with Haskell. I've downloaded ghc 8.2.1-rc1 to my Mac and in the directory I type ./configure per the README. An error is generated "-bash: ./configure: No such file or directory"
21:42 meba joined
21:43 <ij> I think using homebrew should be easier than compiling ghc yourself.
21:43 dan_f joined
21:43 <kellytk> Can it be used to get 8.2.1?
21:43 <Tuplanolla> Can you explain why you need 8.2.1?
21:44 <kellytk> No reason really, I'm curious about Backpack
21:44 wroathe joined
21:44 <Tuplanolla> I'm quite sure you don't need 8.2.1.
21:45 <ij> You're starting with haskell, but curious about backpack? That's interesting.
21:45 <Tuplanolla> Besides installing another version is not a lifelong commitment.
21:45 <kellytk> Fair enough, I'll install whatever it has
21:46 conal joined
21:46 splanch joined
21:47 kylepotts joined
21:50 insitu joined
21:54 fotonzade joined
21:54 <fotonzade> how do I divide two integers and get a float result?
21:55 <geekosaur> > fromIntegral 5 / fromIntegral 2
21:55 <lambdabot> 2.5
21:55 hiratara joined
21:55 <fotonzade> ah so fromIntegral is a function?
21:55 <geekosaur> yes
21:55 wroathe_ joined
21:55 <Sornaensis> :t fromIntegral
21:55 <lambdabot> (Num b, Integral a) => a -> b
21:56 <fotonzade> you guys are the best
21:56 Taslem joined
21:56 hamishmack joined
21:56 coltfred_ joined
21:59 splanch joined
22:01 test234 joined
22:04 aarvar joined
22:04 simukis__ joined
22:05 gibbers joined
22:05 yellowj joined
22:08 Guest83 joined
22:08 manjaro-kde5- joined
22:09 <Lokathor> : iterate
22:09 <Lokathor> :t iterate
22:09 <lambdabot> (a -> a) -> a -> [a]
22:10 Krymise joined
22:11 Krymise joined
22:11 wroathe joined
22:11 Krymise joined
22:12 Krymise joined
22:12 Guest51282 joined
22:13 xcmw joined
22:14 splanch joined
22:17 maarhart joined
22:20 EvilMachine joined
22:21 Counterfeit joined
22:22 pera joined
22:22 Counterfeit left
22:22 miaumiau joined
22:22 <miaumiau> hello channel!
22:23 <miaumiau> I'm having several questions around the implicit extensions
22:23 <miaumiau> as I'm trying to port some Scala code that uses global implicits
22:23 <miaumiau> and reproducing it from GHCi is proving difficult
22:24 <miaumiau> along with parametrizing one of the implicit types
22:24 <miaumiau> getComponentForEntity:: (?r:: Reader EntityId (Component a)) => EntityId -> a
22:25 <miaumiau> Component a is not valid there
22:25 <lyxia> oh you meant ImplicitParams
22:25 <miaumiau> yeah, sorry, translation of nomenclature :D
22:25 <lyxia> what's the error
22:27 <miaumiau> expected a type but (Component a) was a constraint
22:27 <miaumiau> was a -> has a kind
22:28 indi_ joined
22:28 <lyxia> looks like Component is a typeclass
22:28 <miaumiau> yes!
22:29 <miaumiau> I'm trying to constraint a to only be a Component a
22:29 <lyxia> perhaps you meant (Component a, ?r:: EntityId -> a)
22:30 <miaumiau> getComponentForEntity:: (Component a, ?r:: Reader EntityId a) => EntityId -> a
22:30 <miaumiau> that worked, cheers
22:31 <miaumiau> now, for the next trick :D
22:31 <miaumiau> how do I materialize an implicit in ghci
22:31 <miaumiau> getImplicitComponent id = let ?r = reader (\id -> Health 3 id) in getComponentForEntity id
22:31 <miaumiau> that works as a function definition
22:31 <miaumiau> let ?r = reader (\id -> Health 3 id) in getComponentForEntity id
22:31 <miaumiau> that doesn't work on the REPL
22:32 <miaumiau> best guess the repl doesn't have implicis loaded, only my file?
22:32 <miaumiau> I start it using Intero in emacs
22:32 manjaro-kde5- left
22:33 ego joined
22:36 bhiliyam joined
22:36 forgottenone joined
22:37 Wuzzy2 joined
22:38 nathanic joined
22:39 splanch joined
22:39 soLucien joined
22:40 barryburd joined
22:41 beerdrop joined
22:42 wroathe joined
22:43 <barryburd> Hello. I’ve posted code at https://users.drew.edu/bburd//Main1.hs. I’m trying to create a Convertible class that works with different kinds of values with units (units of length, units of currency, units of whatever). As part of this, I’m trying to define fromUS in terms of toUS (the conversion functions) inside the class definition so I don’t have to define both individually for each instance of the class. If you
22:43 <barryburd> at my code, you’ll see that I awkwardly define a bunch of additional functions in order to make this happen. Is there a way to avoid defining all the additional functions (getNumber, newUS, newNonUS, and so on).
22:44 hybrid joined
22:45 hiratara joined
22:46 descender joined
22:47 lifter joined
22:47 gibbers joined
22:48 Sampuka joined
22:49 jeltsch left
22:49 revprez_atlanta joined
22:49 mmn80 joined
22:50 beanbagula joined
22:50 t0by joined
22:50 t0by joined
22:52 gawen joined
22:53 <biglambda> What is the right forum to ask cabal-install questions?
22:53 <Cale> Here's probably fine
22:54 <miaumiau> is there any way to declare global implicit parameters a la scala, that you can import and use in all functions in a module?
22:54 hexfive joined
22:54 <Cale> There are implicit parameters, but not global implicit parameters
22:55 <miaumiau> scoped implicit parameters?
22:55 <miaumiau> as it is right now they're indistinguishable from partially applied functions
22:55 <Cale> https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#implicit-parameters
22:55 <Cale> People don't really use them very much though
22:56 conal joined
22:56 <miaumiau> yep I checked that, the let ?bla in functionWithImplicit isn't much of an improvement
22:56 <miaumiau> okay, let me ask you this then
22:56 <miaumiau> I have a function that requires a reader instance
22:56 <miaumiau> for the same type as the return
22:56 <miaumiau> the function inside runs the reader and little else
22:57 <biglambda> I’m trying to cabal-install wxHaskell on a Mac and I’m getting a strange error: error: Unknown option "--sysconfdir=
22:57 <biglambda> Here’s the full output: https://pastebin.com/0VFh2rS1
22:57 <biglambda> Kind of stumped
22:57 <miaumiau> how do I pass the reader to the function without having to explicitly use the instance every time
22:58 snowalpaca joined
22:58 <miaumiau> biglambda probably a config issue in wxHaskell's side? haveyou tried a prior version
22:58 <ertes> (OT) is there a C++ equivalent for Maybe, perhaps in the STL?
22:58 Cotillion joined
22:58 <biglambda> Now sure how to do that with cabal
22:58 <Cale> biglambda: That's a rather old version of wxcore that you're trying to install
22:59 wroathe joined
22:59 <Cale> biglambda: Maybe try a newer version?
22:59 fnurglewitz joined
22:59 <biglambda> Do I need to do that outside of cabal
22:59 <MarcelineVQ> ertes: optional perhaps
22:59 <geekosaur> ertes, std::optional I think
23:00 <Cale> cabal install wx-
23:00 <Cale> try that
23:00 <ertes> oh, i tried that, but i tried "Optional" =)
23:00 ublubu joined
23:00 <MarcelineVQ> when it was part of boost is maybe have been Optional
23:00 <MarcelineVQ> *it may have
23:01 fnurglewitz joined
23:01 <Cale> ah, hm
23:02 <Cale> I can't get that to build either, due to a constraint that wxdirect places on the process package.
23:02 <Cale> My guess is that it's just in a bad state because nobody's bothered to maintain these packages in the last year
23:03 <Cale> It's probably possible to straighten everything out, but you might have to download the packages and relax some of the version constraints
23:04 <biglambda> Ok I can do that.
23:04 <biglambda> What is the cabal command to override your sandbox with a directory you cloned from github?
23:05 kellytk left
23:05 <glguy> cabal sandbox add-source
23:06 <biglambda> Cool thanks
23:06 <glguy> biglambda: check out 'cabal help sandbox' for more
23:08 markus1209 joined
23:08 markus1219 joined
23:09 maarhart joined
23:09 <Sornaensis> mmm big lambdas
23:09 raichoo joined
23:10 <biglambda> substitution…. burp.
23:10 codesoup joined
23:12 theDon_ joined
23:12 NoCreativity joined
23:14 wroathe joined
23:16 bhiliyam joined
23:17 fnur_ joined
23:19 silver joined
23:23 halogenandtoast joined
23:24 dan_f joined
23:26 martingale joined
23:26 coot joined
23:32 binaryplease joined
23:32 bjz joined
23:36 kylepotts joined
23:38 splanch joined
23:38 gibbers joined
23:42 patriknygren joined
23:47 dsh joined
23:47 twanvl joined
23:47 <patriknygren> http://lpaste.net/5557497396792918016
23:49 xiinotulp joined
23:55 aarvar joined
23:57 conal joined
23:58 revprez_atlanta joined
23:59 dfeuer joined