{"action":"created","issue":{"url":"https://api.github.com/repos/mikeizbicki/HLearn/issues/56","labels_url":"https://api.github.com/repos/mikeizbicki/HLearn/issues/56/labels{/name}","comments_url":"https://api.github.com/repos/mikeizbicki/HLearn/issues/56/comments","events_url":"https://api.github.com/repos/mikeizbicki/HLearn/issues/56/events","html_url":"https://github.com/mikeizbicki/HLearn/issues/56","id":87140739,"number":56,"title":"HLearn.History","user":{"login":"tonyday567","id":1622093,"avatar_url":"https://avatars.githubusercontent.com/u/1622093?v=3","gravatar_id":"","url":"https://api.github.com/users/tonyday567","html_url":"https://github.com/tonyday567","followers_url":"https://api.github.com/users/tonyday567/followers","following_url":"https://api.github.com/users/tonyday567/following{/other_user}","gists_url":"https://api.github.com/users/tonyday567/gists{/gist_id}","starred_url":"https://api.github.com/users/tonyday567/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tonyday567/subscriptions","organizations_url":"https://api.github.com/users/tonyday567/orgs","repos_url":"https://api.github.com/users/tonyday567/repos","events_url":"https://api.github.com/users/tonyday567/events{/privacy}","received_events_url":"https://api.github.com/users/tonyday567/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":2,"created_at":"2015-06-10T23:19:07Z","updated_at":"2015-06-11T22:56:02Z","closed_at":null,"body":"I was thinking of tackling a FIXME surrounding incorporation of History.Timing into the History modue.  Here's a few initial thoughts and ideas.\r\n\r\nAPI & HistoryT\r\n---\r\nreport is the main (and only) access to the History machinery.\r\n\r\nI'd like to include an ability to be selective in what's timed, and quickly turn an IO chunk say, into a History chunk (by adding report to a line and liftIOing other stuff). Say we have:\r\n\r\n    sumOrig = do\r\n     let s1 = P.foldr (P.+) 0 [1..10000]\r\n     threadDelay 1000000\r\n     return s1\r\n\r\nbecoming\r\n\r\n    liftIO' = History . liftIO\r\n\r\n    sumHist = do\r\n     s1 <- report $ P.foldr (P.+) 0 [1..10000]\r\n     liftIO' $ threadDelay 1000000\r\n     return s1\r\n\r\nWhich all seems doable and very cool.  At this point, however, I jump straight to thinking about a HistoryT, so the report api can handle an IO a etc, but I lack a MonadIO to throw in there.\r\n\r\nSo question number 1 is whether to give up on a HistoryT given no MonadIO etc, or whether that would be a simple compatability patch.\r\n\r\nRelationship to Criterion\r\n---\r\nI do a lot of benchmarking and the guts of criterion has the wrong types for stuff I often want to do (quickly annotate computations with debugging and timing information, rather than do statistical analytics of multiple runs without any continuation that criterion is based on) \r\n\r\nI often pick apart times into GC and Mutation via some criterion [functionality](https://hackage.haskell.org/package/criterion-1.1.0.0/docs/Criterion-Measurement.html).  I also think it would benefit the History monad if you could start and stop the timing within a report chunk, but still be able to report timings at higher levels.  The report API could morph to something like this:\r\n\r\n    report \"all of it\" $ do\r\n     s1 <- report \"the slow bit\" $ P.foldr (P.+) 0 [1..10000]\r\n     liftIO' $ threadDelay 1000000\r\n     return s1\r\n\r\nSubHask versus Control.Monad\r\n---\r\nBeing able to benchmark in the middle of a computation is a nice goal in the broader Haskell toolkit (there might be stuff out there that already does this, but I haven't come across it).\r\nI'm unsure whether to head for a more general History (or HistoryT) based on Control.Monad or stick to SubHask.\r\n\r\nMy use case, however, is pretty centered on HLearn, so targetting a boiler-plate monad may not get the job done.\r\n\r\nVery generally, to what extent can normal monads play nice with subhask?\r\n\r\nReportable versus Optimizable\r\n---\r\nHistory.Timing (one off reporting) is starting to drift away from the idea of reporting on optimization (or other) loopings.  There might be a case for clear separation of looping constructs like stopping criteria versus straight reporting constructs (like when to report timings).\r\nI haven't dug into how History is used in a looping context yet.\r\n\r\nI'm sure there's lots of other issues I haven't thought of yet.\r\n\r\nTony\r\n\r\n\r\n\r\n\r\n"},"comment":{"url":"https://api.github.com/repos/mikeizbicki/HLearn/issues/comments/111299193","html_url":"https://github.com/mikeizbicki/HLearn/issues/56#issuecomment-111299193","issue_url":"https://api.github.com/repos/mikeizbicki/HLearn/issues/56","id":111299193,"user":{"login":"tonyday567","id":1622093,"avatar_url":"https://avatars.githubusercontent.com/u/1622093?v=3","gravatar_id":"","url":"https://api.github.com/users/tonyday567","html_url":"https://github.com/tonyday567","followers_url":"https://api.github.com/users/tonyday567/followers","following_url":"https://api.github.com/users/tonyday567/following{/other_user}","gists_url":"https://api.github.com/users/tonyday567/gists{/gist_id}","starred_url":"https://api.github.com/users/tonyday567/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tonyday567/subscriptions","organizations_url":"https://api.github.com/users/tonyday567/orgs","repos_url":"https://api.github.com/users/tonyday567/repos","events_url":"https://api.github.com/users/tonyday567/events{/privacy}","received_events_url":"https://api.github.com/users/tonyday567/received_events","type":"User","site_admin":false},"created_at":"2015-06-11T22:56:02Z","updated_at":"2015-06-11T22:56:02Z","body":"My use case for History is pretty much yours, lol.  See https://github.com/tonyday567/digit-recognizer/blob/master/testing/BenchKnn.hs#L208.  I'd like to replace all the time and timeIOs with report and reportIOs (or similar), and include the info wrapped up in Criterion.Extended.\r\n\r\nwrt the ugly side, that sig is due to infoType.  If you gave up on automatically using the type as the report collection label, and accepted a hard coded label (of type s) eg\r\n\r\n    report :: s -> a -> History_ s a\r\n\r\nor you could go the whole hog, and use a String as the label as beginFunction does, making it:\r\n\r\n    History :: \r\n    report :: String -> a -> History_ a"}}