<    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:13 mthek joined
00:13 morphit_ joined
00:16 acarrico joined
00:25 aarvar joined
00:26 vaibhavsagar joined
00:31 <mengu> hi all
00:31 <mengu> do i have to know the structure of json, the fields in the json, etc?
00:32 <benzrf> mengu: for what
00:32 <mengu> can i make it some how generic?
00:32 <mengu> benzrf: i'd like to be able to parse a json without knowing it's keys, etc.
00:32 <mengu> should i just use map?
00:32 <geekosaur> think you can just ask for something of type Object?
00:35 <mengu> geekosaur: Data.Aeson.Object?
00:36 <geekosaur> actually it looks like you want Value
00:36 <geekosaur> perhaps you should read the documentation: http://hackage.haskell.org/package/aeson-
00:45 <mengu> geekosaur: thanks
00:45 <mengu> i went with Object
00:50 peterbec` joined
00:52 watersoul joined
00:54 sclv joined
00:55 dni- joined
00:55 mac10688 joined
00:56 Purlox joined
00:58 sshine joined
00:58 geekosaur joined
00:59 vaibhavsagar joined
01:02 emmanuel_erc joined
01:18 NoCreativity joined
01:38 vaibhavsagar joined
01:42 pancro joined
01:44 eacameron joined
01:47 Youmu joined
01:48 baweaver left
01:49 malaclyps joined
01:52 peterbec` joined
01:57 acarrico joined
02:00 takle joined
02:07 takle joined
02:20 takle joined
02:32 Dietr1ch joined
02:43 dni- joined
02:49 takle joined
02:53 peterbec` joined
02:56 exferenceBot joined
02:57 meandi_2 joined
03:00 hexagoxel joined
03:00 takle joined
03:04 aarvar joined
03:11 takle joined
03:17 vaibhavsagar joined
03:19 takle joined
03:32 takle joined
03:34 HazyPurple joined
03:34 peterbec` joined
03:36 gibbers joined
03:40 takle joined
03:41 hexagoxel joined
03:43 hazyPurple_ joined
03:55 takle joined
04:02 vaibhavsagar joined
04:07 hazyPurple_ joined
04:10 bkboggy joined
04:21 takle joined
04:28 holygun joined
04:32 dni- joined
04:42 Gurkenglas joined
04:47 takle joined
04:56 takle joined
05:01 vaibhavsagar joined
05:03 azahi joined
05:04 takle joined
05:12 takle joined
05:13 howdoi joined
05:13 Mutter_ joined
05:21 takle joined
05:23 nobodyzxc joined
05:34 kritzcreek joined
05:39 eacameron joined
05:40 takle joined
05:43 eacamero_ joined
05:46 ThomasLocke joined
05:49 eacameron joined
05:49 takle joined
05:51 vaibhavsagar joined
05:53 eacamero_ joined
05:54 takle joined
05:57 eacameron joined
05:58 bvad joined
05:59 takle joined
06:02 eacameron joined
06:04 peterbec` joined
06:07 takle joined
06:09 eacameron joined
06:10 dr_robot joined
06:20 takle joined
06:21 dni- joined
06:31 takle joined
06:41 dmi3y joined
06:44 takle joined
06:45 harfangk joined
06:52 yellowj joined
06:55 aphorisme joined
06:55 takle joined
07:04 galderz joined
07:07 thc202 joined
07:07 lithie joined
07:08 takle joined
07:08 vaibhavsagar joined
07:09 vaibhavsagar joined
07:16 takle joined
07:16 dni- joined
07:18 Pupnik joined
07:27 galderz joined
07:35 takle joined
07:35 eatman joined
07:39 vaibhavsagar joined
07:43 mthek joined
07:46 takle joined
08:00 MVQq joined
08:04 srnty joined
08:05 peterbec` joined
08:15 eacameron joined
08:20 vaibhavsagar joined
08:23 govg joined
08:26 vaibhavsagar joined
08:33 grdryn joined
08:35 mounty joined
08:38 zero_byte joined
08:44 tusj joined
08:48 salva joined
08:52 bkboggy joined
09:04 vaibhavsagar joined
09:06 takle_ joined
09:07 peterbec` joined
09:08 pungi-man joined
09:12 takle joined
09:24 dni- joined
09:24 <eatman> Hi there.
09:24 <eatman> Small question about this code: http://ix.io/r7q/hs
09:25 <eatman> I've the felling that either version is wrong somehow.
09:25 hiratara joined
09:25 <vaibhavsagar> they're both right
09:25 slomo joined
09:25 <vaibhavsagar> one is the State monad and the other is the reverse State monad
09:25 <eatman> Well, that was unexpected.
09:25 <eatman> Didn't now the reverse state.
09:25 <vaibhavsagar> https://lukepalmer.wordpress.com/2008/08/10/mindfuck-the-reverse-state-monad/
09:26 <vaibhavsagar> it's pretty trippy
09:26 <eatman> Thx, will read asap.
09:26 <vaibhavsagar> https://github.com/DanBurton/tardis
09:26 <eatman> And, what about throwing the s' and reuse the s?
09:28 <vaibhavsagar> hmm, that's more interesting
09:28 takle joined
09:28 <vaibhavsagar> I can't think of a good use for that
09:29 <eatman> Me neither, BUT, it typechecks so I wonder.
09:29 <vaibhavsagar> it's not automatically right if it typechecks :)
09:29 <vaibhavsagar> map f xs = []
09:29 <eatman> Yep yep.
09:29 <eatman> I know that.
09:30 <eatman> Anyway, jjust a troll.
09:30 <eatman> Lunch time, back in an hour.
09:30 <vaibhavsagar> your handle is appropriate
09:42 <Iceland_jack> :)
09:46 netheranthem joined
09:59 uglyfigurine joined
10:07 slomo joined
10:07 slomo joined
10:08 Gloomy joined
10:39 Mutter joined
10:42 <eatman> Back.
10:53 <eatman> Hum, i'd like to double check my understanding : here (http://ix.io/r7q/hs), Foo is the reverse state and Bar is the "vanilla" state?
11:09 peterbec` joined
11:11 mengu joined
11:17 jokester joined
11:21 nacon joined
11:21 nacon joined
11:39 colt44 joined
11:41 NoCreativity joined
11:49 netheranthem joined
11:56 Gloomy joined
12:10 peterbec` joined
12:14 carlomagno1 joined
12:17 acarrico joined
12:20 ederign joined
12:20 WarmCookie_ joined
12:24 vaibhavsagar joined
12:38 pbrant joined
12:51 ultalbot joined
13:00 Gurkenglas_ joined
13:09 jship joined
13:32 jathan joined
13:32 yellowj joined
13:43 jrajav joined
13:44 NoCreativity joined
13:45 mizu_no_oto_work joined
14:03 m3tti joined
14:04 chlong joined
14:04 dmi3y_ joined
14:05 nobodyzxc joined
14:07 pungi-man joined
14:16 earldouglas joined
14:17 earldoug1as joined
14:24 pungi-man joined
14:27 crave joined
14:27 <crave> Hey fellow humans!
14:27 <Akii> /r/totallynotrobots?
14:28 <crave> Haha, no I am a human and I have a question.
14:28 <Akii> just go ahead and ask
14:29 <crave> I have this expression: pure 1 >> print
14:29 <crave> I have this expression: pure 1 >>= print
14:30 <crave> I wish to know the exact type the sub-expression (pure 1 >>=) yields when "bound" to print like in the above
14:30 <Ferdirand> i think that the monad laws require this to be equivalent to "print 1"
14:30 <Ferdirand> :t (pure 1 >>=)
14:30 <lambdabot> (Num a, Monad m) => (a -> m b) -> m b
14:30 takle joined
14:30 <crave> I want to know what type `1` collapses down to
14:30 <Ferdirand> oh
14:30 <crave> is it an Int?
14:30 <Ferdirand> Num a => a
14:31 <crave> does it become an IO Int?
14:31 <crave> but `Num a` is not an instance of `Show`, right?
14:31 <crave> which is required for `print`
14:32 <Ferdirand> :t print
14:32 <lambdabot> Show a => a -> IO ()
14:32 <Ferdirand> yes, but for the subexpression (pure 1 >>=) the constraint on Show is not there
14:33 <Ferdirand> so when you apply the print to this
14:33 <Ferdirand> you are unifying (a -> m b) with (Show a => a -> IO)
14:34 <Ferdirand> IO () sorry
14:34 <crave> :t (>>=)
14:34 <lambdabot> Monad m => m a -> (a -> m b) -> m b
14:34 douglascorrea joined
14:35 <Ferdirand> :t (pure 1 >>= print)
14:35 <lambdabot> IO ()
14:35 <glguy> crave: the 1 "defaults" to an Integer by default (it's configurable)
14:35 <crave> So it's a `IO (Num t)`? How does Haskell decide if it should make the `Num t` an `Int` or an `Integer`?
14:36 <Ferdirand> defaulting rules kick in then
14:38 <crave> glguy, how do I configure it?
14:39 <Ferdirand> you could use a proxy, if you wanted to write a polymorphic expression where you could choose the type you want
14:39 <glguy> see section 4.3.4 https://www.haskell.org/onlinereport/haskell2010/haskellch4.html#x10-750004.3
14:40 peterbec` joined
14:42 nobodyzxc joined
14:42 <Ferdirand> but the default declaration only applies to Num, right ?
14:44 evilmaid joined
14:44 carlomagno joined
14:44 <crave> Looks like it
14:44 <crave> "Defaults are limited to Prelude numeric classes." - https://prime.haskell.org/wiki/Defaulting
14:45 <crave> I don't really see how I can configure it but I guess I shouldn't meddle with default defaulting rules anyway
15:04 <eatman> Heya! My state monad and I are back. http://ix.io/r8Q/hs (Forget about the Reader).
15:05 <eatman> The function : (\n -> state (replicateM_ n stateFib) $ Fib (0, 1))
15:05 <eatman> gives me both a list of fibonacci numbers AND the last state.
15:06 <eatman> I could use `last . fst` to extract the las number for example.
15:07 <eatman> But is there a way to have a (Next, (Previous, Current)) instead of a ([Next], (Previous, Current)) ?
15:07 Gloomy joined
15:07 <eatman> (Not quite sure to grasp the whole *monad* awesomeness yet.
15:09 dmi3y joined
15:15 nicknovitski joined
15:17 GreySunshine joined
15:18 <mengu> hi all
15:18 <mengu> is anyone using wai?
15:20 <mengu> i have a very simple file https://pastebin.com/Huk86zkd
15:21 <mengu> in there line 21 is causing an error: https://pastebin.com/jLcZSAY8
15:21 <Akii> try `liftIO $ getDbFileKeys "db.json"`
15:22 <mengu> what does it do Akii?
15:22 <Akii> lifts the IO action into the IO monad
15:22 <Akii> assuming this is some sort of Monad Transformer stack
15:23 bvad joined
15:23 <mengu> yeah my getDbKeyFiles returns an IO
15:24 <Akii> you could also define it like this: `getDbKeyFiles :: MonadIO m => Text -> m a0`
15:24 <Akii> not sure what your return type is ^^
15:25 <Akii> that just moves the liftIO however
15:29 <mengu> Akii: it's IO [Text]
15:30 <Akii> oh well, Request is not a Monad Stack
15:30 <Akii> no surprises there
15:31 <Akii> s/Request/Response
15:31 <Akii> mengu: you'll probably need to read those keys in main then pass it to your application
15:31 uglyfigurine joined
15:32 <mengu> Akii: it looks like i can't even putStrLn over there
15:32 <mengu> or liftIO $ putStrLn
15:32 <Akii> ye, doesn't work like that in this case
15:32 <Akii> fetch the keys in main, then pass them
15:32 <Akii> unless you need that for each response, in which case Application should offer some sort of IO handling
15:33 <Akii> not soo much into the details there
15:33 <mengu> depending on the route
15:33 <mengu> for example if it's the root path / i send the keys
15:33 <mengu> if it's /something - i send another thing
15:34 <Akii> yup, fetch the keys in main then pass them :D
15:34 <Akii> gtg now though, back later
15:34 <glguy> crave: Section 4.3.4 linked above describes how to configure numeric defaulting
15:41 Mutter joined
15:41 peterbec` joined
15:44 <mengu> Akii: aight
15:44 <mengu> fixed it
15:44 <mengu> @Akii https://pastebin.com/uF4Hyv6a
15:44 <lambdabot> Unknown command, try @list
15:46 <Geekingfrog> eatman: runState (fmap last $ replicateM 3 fib) (0,1) will give you the last element of the resulting list
15:46 crave_ joined
15:47 <Geekingfrog> in your case it's probably more like (\n -> state (fmap last $ replicateM n stateFib) $ Fib (0, 1))
15:47 baweaver joined
15:47 abhiroop joined
15:47 conal joined
15:48 <abhiroop> I am using the Data.graph package https://hackage.haskell.org/package/containers-
15:49 <abhiroop> Looking at the method graphFromEdges'
15:49 <abhiroop> @hoogle graphFromEdges'
15:49 <lambdabot> Data.Graph graphFromEdges' :: Ord key => [(node, key, [key])] -> (Graph, Vertex -> (node, key, [key]))
15:49 <abhiroop> I was wondering what purpose does the `node` type variable serve?
15:50 <abhiroop> i have some vertices like type Vertex = Text
15:50 <abhiroop> I was just wondering what should the node variable look like?
15:53 delexi joined
15:55 peterbecich joined
15:56 abhiroop joined
15:56 slomo joined
16:01 abhiroop joined
16:10 malaclyps joined
16:10 malaclyps joined
16:18 danny_ joined
16:19 mizu_no_oto_work joined
16:21 abhiroop joined
16:27 cmos joined
16:27 <cmos> any idea why Crypto.Hash.MD2's `hash` would be returning weird values on OS X?
16:28 <cmos> e.g. `unpack.hash.pack$""` -> "\131P\229\163\226L\NAK=\242'\\\159\128i's"
16:28 <cmos> whereas the hash of an empty string ought to be (see Wikipedia) "8350e5a3e24c153df2275c9f80692773"
16:29 <cmos> actually, looking, i see that those are the same, so my issue is elsewhere: any idea why Text.Regex.Posix would be having weird issues with that?
16:31 <cmos> …and, after wrestling with it for twenty minutes, I figured it out two minutes after posting. ignore the above
16:32 <qu1j0t3> cmos: :)
16:33 <srhb> cmos: Don't leave us hanging, what was it? :D
16:33 des_ joined
16:34 <cmos> silly mistake on my end. I needed to convert the string to a string of corresponding hex values before passing it to the regex.a
16:36 aarvar joined
16:39 Robin_Jadoul joined
16:42 earldouglas joined
16:42 danny_ joined
16:43 peterbec` joined
16:51 aaaaaaaaaaah joined
16:52 abhiroop joined
16:53 conal joined
16:57 des_ joined
16:58 abhiroop joined
17:03 ralu joined
17:06 xmonader joined
17:08 pilne joined
17:10 <crave_> Why exactly would I want mapM_ to "ignore results"?
17:10 <crave_> Is there a performance benefit to it? I don't really comprehend the use-case.
17:11 bvad joined
17:12 <Akii> crave_: I use it for side-effects where the return type is ()
17:12 <Akii> can't do much with [()]
17:17 chbatey joined
17:17 <geekosaur> there is a small space benefit when mapping over a large list, since mapM_ knows it doesn;t need to collect the useless list of ()
17:26 chlong joined
17:27 slomo joined
17:27 slomo joined
17:35 xmonader joined
17:36 <qu1j0t3> plus a slightly more precise statement of intent.
17:44 peterbec` joined
17:47 abhiroop joined
17:53 <evilmaid> hi, i have two aeson questions. a sample of the json in question, and data structes to unmarshal into here: https://pastebin.com/tMETsYVk first off, is this a plausible way of implementing the nested json, or are there.. for lack of a better phrasing.. less convoluted ways (in terms of mapping {"_embedded": {"events": [{"_embedded": {"entry": {"_embedded": {"question": {"question": "..."}}]}})?
18:00 <Akii> am I the only one questioning "question": {"question": .. }
18:01 <Akii> sry, couldn't resist
18:01 abhiroop joined
18:01 <evilmaid> hehe, the json format is insane, but out of my control
18:03 <Akii> this looks almost recursive
18:03 <Akii> not quite
18:03 <evilmaid> with some heavy use of <|> it might could be
18:04 <Akii> I'm just looking at the JSON now
18:04 <Akii> hm
18:04 <evilmaid> but the snippit pasted is the only part i'm interested in, so i've just mapped that out
18:05 <evilmaid> (ignore the "breaks here" comment, i forgot to use .:? on my Maybe's)
18:05 mizu_no_oto_work joined
18:05 <Akii> so basically you've key "events" and then _embedded.entry
18:06 <Akii> and whatever is in there is something you'd want to use
18:06 <evilmaid> yes
18:06 <Akii> ah, nice
18:07 <evilmaid> wondering if it'd be smarter to use a parseJSON lambda to skip the intermediate types (_embedded)
18:07 <Akii> so this EventE can be multiple things then, right?
18:07 <Akii> question, "content"
18:07 <evilmaid> Entry, yes, EntryE is just a "wrapper"
18:08 <evilmaid> (due to the form {"entry": ENTRY}
18:08 uglyfigurine joined
18:08 <Akii> line 36 is so bad
18:08 <Akii> 36/37
18:13 abhiroop joined
18:14 galderz joined
18:15 <evilmaid> https://artyom.me/aeson#extended-records i was considering trying parseJSON in parseJSON to avoid making data types for _embedded, but not sure if that's possible?
18:15 <evilmaid> or am i going about this the wrong way?
18:15 <Akii> evilmaid: so what I of was `data Entry = Content String | FAQ Answer Question`
18:16 <Akii> I thought of*
18:18 <evilmaid> as a datatype, i agree, but i'm not sure how to combine that with unmarshalling. the problem is twofold, 1. the intermediary "_embedded" that are just in the way, and 2. pulling the Question up as it's not on the same level as Content or Answer
18:19 <Akii> I think both is possible
18:19 <Akii> well obviously
18:19 nschoe_ joined
18:19 <Akii> JSON Object in Aeson is just a HashMap
18:20 <Akii> and then deciding what Entry type to use depends on whether the key "answer" is there or "content"
18:20 <Akii> let me fiddle around with it
18:21 <Akii> I assume your JSON doc is invalid because you cut out a lot
18:21 <Akii> otherwise that will likely result in errors too.. or at least I'd assume so
18:22 <evilmaid> let me just put up the data.json so i don't make it even more impossible for you to help :)
18:22 <evilmaid> https://pastebin.com/5qTVSN2Z
18:23 <evilmaid> as to "answer" or "content" i'd hope to do an IO with either <|> (if answer or content is there) or taking each optional and do if/else manually
18:29 <* Akii> is working on a solution :D please stand by!
18:29 <evilmaid> hacking on it aswel. i really appreciate it :)
18:30 yellowj joined
18:32 mizu_no_oto_work joined
18:34 danny_ joined
18:43 <Akii> oh I'm getting somewhere
18:43 <Akii> them parser tutorials finally paying off
18:45 simendsjo joined
18:45 chlong joined
18:46 Boarders joined
18:51 <evilmaid> something along the lines of https://pastebin.com/NGftDYz8 RE: the _embedded/intermediate types ?
18:51 <evilmaid> (focus on FromJSON) hehe
18:52 <Akii> almost there
18:52 <Akii> :D
18:55 <Akii> it compiles
19:03 abhiroop joined
19:05 dmi3y joined
19:06 <Akii> evilmaid: you got ClassyPrelude or do I have to convert it all :D
19:07 <evilmaid> in 10 sec i do, so no, hehe
19:07 <Akii> nvm, converted it
19:08 <Akii> wasn't that bad
19:08 <Akii> http://lpaste.net/354737
19:08 <Akii> that _almost_ works
19:09 <Akii> it's just a matter of getting the `parseAnswer` to work now
19:09 <Akii> and there only the question part
19:10 WarmCookie joined
19:11 <Akii> got it
19:11 <Akii> http://lpaste.net/354737
19:13 <evilmaid> i like it, especially your Entry parseJSON
19:14 <WarmCookie> return Document {..}
19:14 <WarmCookie> Very clever use of RecordWildcards
19:14 <Akii> haha
19:14 <Akii> ^^
19:14 <Akii> it saves parenthesis or a $
19:14 <Akii> take that
19:14 <Akii> but yes, now one would want to refactor
19:16 <WarmCookie> I think people normally use `do`-style from a monadic context like yours, or applicative-style like Document <$> ... <*> ... for these instances.
19:16 <Akii> since nothing really depends on eachother I'd go for applicative
19:17 <Akii> no reason for monadic style here
19:17 <Akii> other than maybe readability
19:17 <WarmCookie> You should be able to do:
19:17 <WarmCookie> o .: extractEntry <=< extractEmbedded
19:17 <WarmCookie> Monadic composition.
19:18 <Akii> don't even know the type of (.:)
19:18 <WarmCookie> (.:) :: FromJSON a => Object -> Text -> Parser a
19:18 <evilmaid> hopefully one day that'll be the kind of struggles, not "how to even do proper types and simple json parsing" :)
19:19 <evilmaid> Akii: thanks a million. one other key insight you gave was that it's akin to parsec, so when handling "content" or "faq" there's a similar pattern with <|> and fail
19:20 <WarmCookie> Akii: JSON object on the left, some key :: Text on the right, and it produces a json parser for the chosen type `FromJSON a => a`.
19:20 <Akii> np :D
19:20 <evilmaid> i'll go study your solution some more, but very happy :)
19:20 <Akii> glad to help ^.^
19:21 <WarmCookie> Akii: http://i.imgur.com/KNDRR6L.jpg
19:22 <Akii> :D
19:22 <Akii> long time no see btw, nitrix
19:22 <Akii> (=
19:23 nitrix joined
19:23 nitrix joined
19:23 nschoe_ joined
19:24 <nitrix> I've found people to be much nicer around WarmCookie than nitrix. It was an interesting experiment.
19:24 <Akii> ppl probably thought of warm cookies
19:24 <pungi-man> I am trying to validate whether a file is present or not. What is the way to do it? I tried using readFile but it directly errors out. openFile on the other end doesn't error out but errors when I run hGetContents I am from a C background and just started with haskell
19:24 <evilmaid> intresting, 'cus i remember you as nitrix and you helped me out last time i was here :)
19:25 <evilmaid> so.. hi
19:25 <nitrix> evilmaid: Welcome back :]
19:25 <Akii> this would be the first candidate for refactoring for me btw: extractKey "question" =<< extractKey "question" =<< extractEmbedded o
19:25 <Akii> that's a simple hash map traversal
19:25 <Akii> or so
19:26 <geekosaur> pungi-man, generally one uses readFile and catches the exception if needed; race conditions can lead to security holes, so checking beforehand is not necessarily the way to go
19:26 <geekosaur> but, http://hackage.haskell.org/package/directory/docs/System-Directory.html#v:doesFileExist
19:28 <pungi-man> geekosaur: The code I am trying to contribute to already uses this package. I think it would be better I use the existing method. Thanks a lot for your help! :)
19:34 <jle`> pungi-man: the problem with checking first and reading it is that the file might be deleted between the time you check and when you start reading
19:34 <jle`> so checking if a file exists and tehn erading it is considered a bad idea in almost every language
19:34 <jle`> since it's effectively meaningless
19:35 xificurC joined
19:37 <pungi-man> jle`: I am not trying to first check and then read it. What I want to do is that if the file exists already then before writing, I want the user prompt for rewriting.
19:37 <pungi-man> Otherwise directly write it out
19:38 <jle`> ah i see :)
19:39 <geekosaur> so, use doesFileExist. it's not in base but it is shipped with ghc
19:46 holygun joined
19:46 peterbec` joined
19:53 dmi3y joined
19:55 moei joined
20:08 uglyfigurine joined
20:11 uglyfigurine joined
20:16 uglyfigurine joined
20:18 uglyfigurine joined
20:19 uglyfigu_ joined
20:32 takle joined
20:34 takle joined
20:38 prophile joined
20:39 abhiroop joined
20:40 uglyfigurine joined
20:47 peterbec` joined
20:48 sigmundv_ joined
20:56 abhiroop joined
20:58 <xificurC> I have this definition of "die" - https://gitlab.com/xificurC/cis194/blob/master/src/L12/Risk.hs . If I call it in ghci all I see is die :: Rand StdGen DieValue
20:58 <xificurC> how can I see the value I get back?
20:58 <jle`> xificurC: 'die' is a description of a computation that generates a random DieValue
20:59 <jle`> you can use evalRand to run that computation on a given input seed
20:59 <jle`> evalRand :: g -> Rand g a -> a
20:59 uglyfigurine joined
20:59 <jle`> you can get a seed from IO, using newStdGen, or make one by hand, `mkStdGen 94234` or something
21:00 <jle`> there's also a convenience function, evalRandIO :: Rand g a -> IO a
21:01 <xificurC> jle`: the type has no arrows so it seems like a value, not a function, or a "computation"
21:01 <jle`> xificurC: it's an abstract data type
21:02 <jle`> how it implements the description is abstracted away
21:02 <jle`> but it has an API
21:02 <jle`> and, it *is* a value
21:02 <jle`> the value is a description of that computation
21:02 <jle`> it's implemented abstarctly, so you don't have direct access to how the computation is stored internally
21:02 <jle`> but there is an abstract API
21:03 <jle`> it's evalRand :: g -> Rand g a -> a
21:03 <jle`> and evalRandIO :: Rand g a -> IO a, etc.
21:03 <jle`> it's also not really relevant how it is implemented/represented, internally :)
21:03 <jle`> all you need to know is its API
21:05 <jle`> 'Rand g a' doesn't contain a random 'a', it's a description on how to generate a random a given some initial seed
21:05 <jle`> and it is a value. the value is that description
21:05 <xificurC> jle`: that'll take a while to *get*
21:06 <xificurC> jle`: I mean I understand what you're saying, thank you. Just a bit too abstract to grasp so easily
21:06 <jle`> no problem :) all you really need to know is how to use the API
21:06 <jle`> and yeah, this is a bit different than how other languages would describe random values
21:07 <jle`> if you want, you can just think of 'Rand g a' as an opaque box that you can use with evalRand :: g -> Rand g a -> a
21:07 <xificurC> jle`: OK, so `evalRandIO die` will give me a DieValue. Now I'm struggling with finding a function that would do:
21:08 <xificurC> given an Int n get a list of n times `evalRandIO die`
21:08 <jle`> you can turn any Rand g a into a Rand g [a]
21:08 <jle`> using replicateM
21:08 <jle`> replicateM :: Int -> Rand g a -> Rand g [a]
21:09 <jle`> and then you evalRandIO (replicateM 10 die)
21:09 <jle`> replicateM takes advantage of the fact that the Rand type exports a monadic interface, so it's 'sequencable' like that
21:10 <jle`> `replicateM n act` is "sequence act n times, and collect the results"
21:12 <xificurC> jle`: I see, I was going at it from the wrong perspective
21:13 <jle`> you can think of replicateM as a way of manipulating instructions/descriptions of computations
21:13 <jle`> xificurC: replicate n takes a description on how to produce 1 random thing, and turns it into a description of how to produce n random things :)
21:13 <jle`> replicateM n :: Rand g a -> Rand g [a], take one description and return another one
21:15 <jle`> working with Rand, what you'll basically be doing is building fancy Rand's out of simple Rand primitives, most of the time
21:15 <jle`> by using combinators like replicateM
21:18 <xificurC> jle`: I like this stuff, just takes a while to get into it
21:18 <xificurC> looking at the type of replicateM I understand what it does but I'm missing the hands-on practice to know when and how to apply it :)
21:20 <jle`> yeah, i agree that it takes a bit of adjustment to get used to it :)
21:21 <jle`> this is precisely why the Monad abstraction is so useful, btw
21:22 <jle`> if you know that a type is a monad, you have a whole API you can use with it, and a bunch of useful combinators
21:22 <jle`> and you can (carefully) port some of your intuition from working with others
21:22 <jle`> emphasis on carefully
21:25 <Cale> xificurC: You can think of replicateM n x as basically just running x in a loop n times (and collecting the results in a list).
21:29 ederign left
21:33 <xificurC> Cale: within some monadic context
21:40 madjestic joined
21:45 conal joined
21:45 abhiroop joined
21:53 hiratara joined
21:53 jacopo_belbo joined
21:55 jacopo_belbo left
21:59 abhiroop joined
22:08 nicknovitski joined
22:11 tractatus joined
22:13 ubsan joined
22:19 <tractatus> Hello! I've a noob question: I'm trying to write a function that, given a list of integers, returns the sum of the even ones. Here's my code:
22:19 <tractatus> evenSum :: [Integer] -> Integer
22:19 <geekosaur> @paste
22:19 <lambdabot> Haskell pastebin: http://lpaste.net/
22:19 <geekosaur> ^ generally easier on everyone
22:20 <jle`> tractatus: what have you tried?
22:20 <Cale> I'm just waiting for the rest of the code :)
22:20 <tractatus> Yep thank you but I've just understood what the mistake is ahahah
22:20 <tractatus> Thank you all xD
22:20 <Cale> nice
22:21 peterbec` joined
22:22 <geekosaur> rubber duck debugging at its finest
22:27 <xificurC> is `length (somethingThatOutputsAList)` fully realizing the list while holding on to its head? Or is it calculating it as it goes without keeping the whole list in memory
22:28 <xificurC> I'm baffled by the performance and memory characteristics of my code for now :)
22:29 <jle`> by itself, it does not keep the whole list in memory
22:29 <jle`> garbace collection does its job if possible
22:29 <geekosaur> it only forces the spine, not the elements
22:29 begriffs joined
22:29 <xificurC> e.g. Rust has iterators which is what they call a zero cost abstraction - it looks like a list of things but it is kind of identical to for (int i = 0; i < 1000; i++)
22:30 <jle`> most list operations in ghc end up being like this
22:30 <xificurC> jle`: being like what
22:30 <geekosaur> in this case the spine is a chain of (_ : (_ : (_ : ... (_ : []) ... ) ) )
22:30 <jle`> compiled to a tight loop
22:30 <geekosaur> the _s are the actual list values; that are not evaluated
22:30 <jle`> in constant space
22:31 <xificurC> geekosaur: ah, I was not lazy enough in my thoughts
22:31 hiratara joined
22:31 <geekosaur> and what jle` is saying is a result of this, since it doesn't need to look at the elements but only the (:) chain, it can do a tight loop
22:31 <jle`> the nice thing is that the list functions exported by Prelude compose well with prelude, so things like map (*2) . filter p ... will compile to one tight loop
22:31 zero_byte joined
22:31 <jle`> but that's a GHC thing, admittedly
22:31 <xificurC> jle`: so if there was a line of code like above (just that line) compiled it would compile to a tight loop with no allocations?
22:31 jarshwah_ joined
22:32 <jle`> which line are you talking about?
22:33 <xificurC> length (someComputation)
22:33 <xificurC> braces because lisp is too much ingrained -_-
22:34 sigmundv__ joined
22:34 <jle`> i believe so, depending on if anything else uses someComputation elsewhere in the program
22:34 <xificurC> what about `length . filter id . map somethingToBool $ someComputation` ?
22:34 <jle`> that should be one loop
22:35 <xificurC> jle`: again with no actual allocation?
22:35 conal joined
22:35 <xificurC> (for the whole list)
22:35 <jle`> it should be constant-space
22:35 <xificurC> jle`: constant for the size of 1 element?
22:36 <xificurC> if yes, it's dark magic and I'm leaving
22:36 <jle`> it doesn't need to evaluate any elements
22:36 <xificurC> I just want to get an intuition what is the overhead of the abstractions haskell wants me to use
22:37 <jle`> the constant space would be the Int that it is calculating
22:37 <jle`> and also the pointer to the next list cell
22:37 <xificurC> jle`: of course it does, in order to filter stuff it needs to map the function and get a Bool
22:37 <jle`> ah, yes, sorry
22:37 EduardoBautista joined
22:38 <xificurC> jle`: thank God I was right on that one or I would have no idea what alternate universe did I just enter
22:38 <xificurC> jle`: so, what constant space?
22:38 <jle`> for the most part, haskellers use lists as "zero-cost" iterators
22:38 <jle`> that are composable
22:39 <jle`> probably the elements and the Bool, then. but it's worth testing :)
22:39 <xificurC> jle`: ok, so I should use them as iterators
22:39 <xificurC> and stop worrying about performance
22:39 <jle`> yes, that's pretty much the only proper usage of lists
22:40 <jle`> that's what they were made for :)
22:40 <xificurC> in common lisp (some-computation) would create 1 list, (map something-to-bool) another, filter another ...
22:40 <jle`> lists in haskell are pretty much designed and optimized for this specific usage
22:40 <jle`> they are used as control flow, effectively
22:41 <xificurC> I'm not familiar with SBCL's JIT to tell what would it decide to do with the code but I think it would need to allocate a lot either way
22:41 <xificurC> jle`: cool, that makes writing code simpler
22:41 <xificurC> writing clean and effective code
22:42 <jle`> yup, it's the role of list in the haskell ecosystem :)
22:42 <xificurC> so I'm done with cis194, on to data61 I guess
22:43 yellowj joined
22:43 <jle`> just checked the compiled code
22:44 <jle`> for main = print . length . filter id . map even $ [1.1000000]
22:45 <xificurC> jle`: I hope that was meant to be [1..1000000]
22:45 <jle`> it is indieed a tight loop
22:45 <jle`> yes :)
22:47 <xificurC> thank you for your help and tips. I'll hit the bed now, good night
22:48 <jle`> night!
22:55 netheranthem joined
22:57 Iceland_jack joined
23:01 dni- joined
23:07 abhiroop joined
23:08 netheranthem joined
23:17 eacameron joined
23:19 conal joined
23:22 conal_ joined
23:29 jmiven joined
23:47 texasmynsted joined
23:53 acarrico joined