{"action":"created","comment":{"url":"https://api.github.com/repos/ekmett/machines/pulls/comments/89555107","pull_request_review_id":10100841,"id":89555107,"diff_hunk":"@@ -0,0 +1,114 @@\n+{-# LANGUAGE TupleSections #-}\n+\n+-----------------------------------------------------------------------------\n+-- |\n+-- Module      :  Data.Machine.Mealy\n+-- License     :  BSD-style (see the file LICENSE)\n+--\n+-- <http://en.wikipedia.org/wiki/Mealy_machine>\n+-- <https://github.com/ivanperez-keera/dunai/blob/develop/src/Data/MonadicStreamFunction/Core.hs#L35>\n+-- <https://hackage.haskell.org/package/auto-0.4.3.0/docs/Control-Auto.html>\n+-- <https://hackage.haskell.org/package/varying-0.6.0.0/docs/Control-Varying-Core.html>\n+----------------------------------------------------------------------------\n+module Data.Machine.MealyT\n+  ( MealyT(..)\n+  , arrPure\n+  , arrM\n+  , upgrade\n+  , scanMealyT\n+  , scanMealyTM\n+  , embedMealyT\n+  , autoMealyT\n+  ) where\n+\n+import Data.Machine\n+import Control.Arrow\n+import Control.Applicative\n+import Data.Pointed\n+import Control.Monad.Trans\n+import Control.Monad.Identity\n+import qualified Control.Category as C\n+\n+-- | 'Mealy' machine, with monadic effects\n+newtype MealyT m a b = MealyT { runMealyT :: a -> m (b, MealyT m a b) }\n+\n+instance Functor m => Functor (MealyT m a) where\n+  {-# INLINE fmap #-}\n+  fmap f (MealyT m) = MealyT $ \\a ->\n+    fmap (\\(x,y) -> (f x, fmap f y)) (m a)\n+\n+instance Pointed m => Pointed (MealyT m a) where\n+  {-# INLINE point #-}\n+  point b = r where r = MealyT (const (point (b, r)))\n+\n+instance Applicative m => Applicative (MealyT m a) where\n+  {-# INLINE pure #-}\n+  pure b = r where r = MealyT (const (pure (b, r))) -- Stolen from Pointed\n+  MealyT m <*> MealyT n = MealyT $ \\a -> (\\(mb, mm) (nb, nm) -> (mb nb, mm <*> nm)) <$> m a <*> n a\n+\n+instance Monad m => Monad (MealyT m a) where\n+  {-# INLINE return #-}\n+  return = pure\n+  MealyT g >>= f = MealyT $ \\a ->\n+    do (b, MealyT _h) <- g a\n+       runMealyT (f b) a\n+\n+instance Monad m => C.Category (MealyT m) where\n+  {-# INLINE id #-}\n+  id = MealyT $ \\a -> return (a, C.id)\n+  MealyT bc . MealyT ab = MealyT $ \\a ->\n+    do (b, nab) <- ab a\n+       (c, nbc) <- bc b\n+       return (c, nbc C.. nab)\n+\n+instance Monad m => Arrow (MealyT m) where\n+  {-# INLINE arr #-}\n+  arr f = r where r = MealyT (\\a -> return (f a, r))\n+  first (MealyT m) = MealyT $ \\(a,c) ->\n+    do (b, n) <- m a\n+       return ((b, c), (first n))\n+\n+arrPure :: (a -> b) -> MealyT Identity a b\n+arrPure = arr\n+\n+arrM :: Functor m => (a -> m b) -> MealyT m a b\n+arrM f = r where r = MealyT $ \\a -> fmap (,r) (f a)\n+\n+upgrade :: Monad m => Mealy a b -> MealyT m a b\n+upgrade (Mealy f) = MealyT $ \\a ->\n+  do let (r, g) = f a\n+     return (r, upgrade g)\n+\n+scanMealyT :: Monad m => (a -> b -> a) -> a -> MealyT m b a\n+scanMealyT f a = MealyT (\\b -> return (a, scanMealyT f (f a b)))\n+\n+scanMealyTM :: Functor m => (a -> b -> m a) -> a -> MealyT m b a\n+scanMealyTM f a = MealyT $ \\b -> (\\x -> (a, scanMealyTM f x)) <$> f a b\n+\n+autoMealyTImpl :: Monad m => MealyT m a b -> ProcessT m a b\n+autoMealyTImpl = construct . go\n+  where\n+  go (MealyT f) = do\n+    a      <- await\n+    (b, m) <- lift $ f a\n+    yield b\n+    go m\n+\n+-- | embedMealyT Example:\n+--\n+-- >>> embedMealyT (arr (+1)) [1,2,3]\n+-- [2,3,4]\n+--\n+embedMealyT :: Monad m => MealyT m a b -> [a] -> m [b]\n+embedMealyT _  []     = return []\n+embedMealyT sf (a:as) = do\n+  (b, sf') <- runMealyT sf a\n+  bs       <- embedMealyT sf' as\n+  return (b:bs)\n+\n+class AutomatonM x where\n+  autoMealyT :: Monad m => x m a b -> ProcessT m a b","path":"src/Data/Machine/MealyT.hs","position":110,"original_position":110,"commit_id":"9f0d34ece9e1c46e7c4dacd5eab6f19bedded593","original_commit_id":"0ee93cd88b5386603424a353df847e3947a92d98","user":{"login":"sordina","id":92299,"avatar_url":"https://avatars.githubusercontent.com/u/92299?v=3","gravatar_id":"","url":"https://api.github.com/users/sordina","html_url":"https://github.com/sordina","followers_url":"https://api.github.com/users/sordina/followers","following_url":"https://api.github.com/users/sordina/following{/other_user}","gists_url":"https://api.github.com/users/sordina/gists{/gist_id}","starred_url":"https://api.github.com/users/sordina/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sordina/subscriptions","organizations_url":"https://api.github.com/users/sordina/orgs","repos_url":"https://api.github.com/users/sordina/repos","events_url":"https://api.github.com/users/sordina/events{/privacy}","received_events_url":"https://api.github.com/users/sordina/received_events","type":"User","site_admin":false},"body":"Haha good point!","created_at":"2016-11-25T01:07:16Z","updated_at":"2016-11-25T01:07:16Z","html_url":"https://github.com/ekmett/machines/pull/85#discussion_r89555107","pull_request_url":"https://api.github.com/repos/ekmett/machines/pulls/85","_links":{"self":{"href":"https://api.github.com/repos/ekmett/machines/pulls/comments/89555107"},"html":{"href":"https://github.com/ekmett/machines/pull/85#discussion_r89555107"},"pull_request":{"href":"https://api.github.com/repos/ekmett/machines/pulls/85"}}},"pull_request":{"url":"https://api.github.com/repos/ekmett/machines/pulls/85","id":94926591,"html_url":"https://github.com/ekmett/machines/pull/85","diff_url":"https://github.com/ekmett/machines/pull/85.diff","patch_url":"https://github.com/ekmett/machines/pull/85.patch","issue_url":"https://api.github.com/repos/ekmett/machines/issues/85","number":85,"state":"open","locked":false,"title":"MealyM","user":{"login":"sordina","id":92299,"avatar_url":"https://avatars.githubusercontent.com/u/92299?v=3","gravatar_id":"","url":"https://api.github.com/users/sordina","html_url":"https://github.com/sordina","followers_url":"https://api.github.com/users/sordina/followers","following_url":"https://api.github.com/users/sordina/following{/other_user}","gists_url":"https://api.github.com/users/sordina/gists{/gist_id}","starred_url":"https://api.github.com/users/sordina/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sordina/subscriptions","organizations_url":"https://api.github.com/users/sordina/orgs","repos_url":"https://api.github.com/users/sordina/repos","events_url":"https://api.github.com/users/sordina/events{/privacy}","received_events_url":"https://api.github.com/users/sordina/received_events","type":"User","site_admin":false},"body":"Hi Machines Makers and Maintainers,\r\n\r\nI've added a MealyM newtype to address the Mealy part of [#51](https://github.com/ekmett/machines/issues/51).\r\n\r\nI know that there are some missing instances and specialised definitions, but I was hoping that it could provide a starting point to figure out what needed to be done before something like this could be merged into Machines. I'm happy to attempt undertaking the work to get this up to scratch. Just let me know what needs to be done!\r\n\r\nThere was talk about potentially creating a MealyT transformer, but I'm not sure how to get started on that, and if that has to happen instead of a simpler contribution like MealyM.\r\n\r\nLet me know your thoughts.","created_at":"2016-11-23T00:36:57Z","updated_at":"2016-11-25T01:07:16Z","closed_at":null,"merged_at":null,"merge_commit_sha":"68cff2173b4fb692f1f4ead085a05c38ab8389b7","assignee":null,"assignees":[],"milestone":null,"commits_url":"https://api.github.com/repos/ekmett/machines/pulls/85/commits","review_comments_url":"https://api.github.com/repos/ekmett/machines/pulls/85/comments","review_comment_url":"https://api.github.com/repos/ekmett/machines/pulls/comments{/number}","comments_url":"https://api.github.com/repos/ekmett/machines/issues/85/comments","statuses_url":"https://api.github.com/repos/ekmett/machines/statuses/9f0d34ece9e1c46e7c4dacd5eab6f19bedded593","head":{"label":"sordina:master","ref":"master","sha":"9f0d34ece9e1c46e7c4dacd5eab6f19bedded593","user":{"login":"sordina","id":92299,"avatar_url":"https://avatars.githubusercontent.com/u/92299?v=3","gravatar_id":"","url":"https://api.github.com/users/sordina","html_url":"https://github.com/sordina","followers_url":"https://api.github.com/users/sordina/followers","following_url":"https://api.github.com/users/sordina/following{/other_user}","gists_url":"https://api.github.com/users/sordina/gists{/gist_id}","starred_url":"https://api.github.com/users/sordina/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sordina/subscriptions","organizations_url":"https://api.github.com/users/sordina/orgs","repos_url":"https://api.github.com/users/sordina/repos","events_url":"https://api.github.com/users/sordina/events{/privacy}","received_events_url":"https://api.github.com/users/sordina/received_events","type":"User","site_admin":false},"repo":{"id":74415384,"name":"machines","full_name":"sordina/machines","owner":{"login":"sordina","id":92299,"avatar_url":"https://avatars.githubusercontent.com/u/92299?v=3","gravatar_id":"","url":"https://api.github.com/users/sordina","html_url":"https://github.com/sordina","followers_url":"https://api.github.com/users/sordina/followers","following_url":"https://api.github.com/users/sordina/following{/other_user}","gists_url":"https://api.github.com/users/sordina/gists{/gist_id}","starred_url":"https://api.github.com/users/sordina/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sordina/subscriptions","organizations_url":"https://api.github.com/users/sordina/orgs","repos_url":"https://api.github.com/users/sordina/repos","events_url":"https://api.github.com/users/sordina/events{/privacy}","received_events_url":"https://api.github.com/users/sordina/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/sordina/machines","description":"Networks of composable stream transducers","fork":true,"url":"https://api.github.com/repos/sordina/machines","forks_url":"https://api.github.com/repos/sordina/machines/forks","keys_url":"https://api.github.com/repos/sordina/machines/keys{/key_id}","collaborators_url":"https://api.github.com/repos/sordina/machines/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/sordina/machines/teams","hooks_url":"https://api.github.com/repos/sordina/machines/hooks","issue_events_url":"https://api.github.com/repos/sordina/machines/issues/events{/number}","events_url":"https://api.github.com/repos/sordina/machines/events","assignees_url":"https://api.github.com/repos/sordina/machines/assignees{/user}","branches_url":"https://api.github.com/repos/sordina/machines/branches{/branch}","tags_url":"https://api.github.com/repos/sordina/machines/tags","blobs_url":"https://api.github.com/repos/sordina/machines/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/sordina/machines/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/sordina/machines/git/refs{/sha}","trees_url":"https://api.github.com/repos/sordina/machines/git/trees{/sha}","statuses_url":"https://api.github.com/repos/sordina/machines/statuses/{sha}","languages_url":"https://api.github.com/repos/sordina/machines/languages","stargazers_url":"https://api.github.com/repos/sordina/machines/stargazers","contributors_url":"https://api.github.com/repos/sordina/machines/contributors","subscribers_url":"https://api.github.com/repos/sordina/machines/subscribers","subscription_url":"https://api.github.com/repos/sordina/machines/subscription","commits_url":"https://api.github.com/repos/sordina/machines/commits{/sha}","git_commits_url":"https://api.github.com/repos/sordina/machines/git/commits{/sha}","comments_url":"https://api.github.com/repos/sordina/machines/comments{/number}","issue_comment_url":"https://api.github.com/repos/sordina/machines/issues/comments{/number}","contents_url":"https://api.github.com/repos/sordina/machines/contents/{+path}","compare_url":"https://api.github.com/repos/sordina/machines/compare/{base}...{head}","merges_url":"https://api.github.com/repos/sordina/machines/merges","archive_url":"https://api.github.com/repos/sordina/machines/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/sordina/machines/downloads","issues_url":"https://api.github.com/repos/sordina/machines/issues{/number}","pulls_url":"https://api.github.com/repos/sordina/machines/pulls{/number}","milestones_url":"https://api.github.com/repos/sordina/machines/milestones{/number}","notifications_url":"https://api.github.com/repos/sordina/machines/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/sordina/machines/labels{/name}","releases_url":"https://api.github.com/repos/sordina/machines/releases{/id}","deployments_url":"https://api.github.com/repos/sordina/machines/deployments","created_at":"2016-11-21T23:34:37Z","updated_at":"2016-11-21T23:34:38Z","pushed_at":"2016-11-24T06:43:43Z","git_url":"git://github.com/sordina/machines.git","ssh_url":"git@github.com:sordina/machines.git","clone_url":"https://github.com/sordina/machines.git","svn_url":"https://github.com/sordina/machines","homepage":"","size":419,"stargazers_count":0,"watchers_count":0,"language":"Haskell","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"ekmett:master","ref":"master","sha":"a620a1b837425647258a20fad8afe17e32fd94ba","user":{"login":"ekmett","id":304657,"avatar_url":"https://avatars.githubusercontent.com/u/304657?v=3","gravatar_id":"","url":"https://api.github.com/users/ekmett","html_url":"https://github.com/ekmett","followers_url":"https://api.github.com/users/ekmett/followers","following_url":"https://api.github.com/users/ekmett/following{/other_user}","gists_url":"https://api.github.com/users/ekmett/gists{/gist_id}","starred_url":"https://api.github.com/users/ekmett/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ekmett/subscriptions","organizations_url":"https://api.github.com/users/ekmett/orgs","repos_url":"https://api.github.com/users/ekmett/repos","events_url":"https://api.github.com/users/ekmett/events{/privacy}","received_events_url":"https://api.github.com/users/ekmett/received_events","type":"User","site_admin":false},"repo":{"id":5445365,"name":"machines","full_name":"ekmett/machines","owner":{"login":"ekmett","id":304657,"avatar_url":"https://avatars.githubusercontent.com/u/304657?v=3","gravatar_id":"","url":"https://api.github.com/users/ekmett","html_url":"https://github.com/ekmett","followers_url":"https://api.github.com/users/ekmett/followers","following_url":"https://api.github.com/users/ekmett/following{/other_user}","gists_url":"https://api.github.com/users/ekmett/gists{/gist_id}","starred_url":"https://api.github.com/users/ekmett/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ekmett/subscriptions","organizations_url":"https://api.github.com/users/ekmett/orgs","repos_url":"https://api.github.com/users/ekmett/repos","events_url":"https://api.github.com/users/ekmett/events{/privacy}","received_events_url":"https://api.github.com/users/ekmett/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/ekmett/machines","description":"Networks of composable stream transducers","fork":false,"url":"https://api.github.com/repos/ekmett/machines","forks_url":"https://api.github.com/repos/ekmett/machines/forks","keys_url":"https://api.github.com/repos/ekmett/machines/keys{/key_id}","collaborators_url":"https://api.github.com/repos/ekmett/machines/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/ekmett/machines/teams","hooks_url":"https://api.github.com/repos/ekmett/machines/hooks","issue_events_url":"https://api.github.com/repos/ekmett/machines/issues/events{/number}","events_url":"https://api.github.com/repos/ekmett/machines/events","assignees_url":"https://api.github.com/repos/ekmett/machines/assignees{/user}","branches_url":"https://api.github.com/repos/ekmett/machines/branches{/branch}","tags_url":"https://api.github.com/repos/ekmett/machines/tags","blobs_url":"https://api.github.com/repos/ekmett/machines/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/ekmett/machines/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/ekmett/machines/git/refs{/sha}","trees_url":"https://api.github.com/repos/ekmett/machines/git/trees{/sha}","statuses_url":"https://api.github.com/repos/ekmett/machines/statuses/{sha}","languages_url":"https://api.github.com/repos/ekmett/machines/languages","stargazers_url":"https://api.github.com/repos/ekmett/machines/stargazers","contributors_url":"https://api.github.com/repos/ekmett/machines/contributors","subscribers_url":"https://api.github.com/repos/ekmett/machines/subscribers","subscription_url":"https://api.github.com/repos/ekmett/machines/subscription","commits_url":"https://api.github.com/repos/ekmett/machines/commits{/sha}","git_commits_url":"https://api.github.com/repos/ekmett/machines/git/commits{/sha}","comments_url":"https://api.github.com/repos/ekmett/machines/comments{/number}","issue_comment_url":"https://api.github.com/repos/ekmett/machines/issues/comments{/number}","contents_url":"https://api.github.com/repos/ekmett/machines/contents/{+path}","compare_url":"https://api.github.com/repos/ekmett/machines/compare/{base}...{head}","merges_url":"https://api.github.com/repos/ekmett/machines/merges","archive_url":"https://api.github.com/repos/ekmett/machines/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/ekmett/machines/downloads","issues_url":"https://api.github.com/repos/ekmett/machines/issues{/number}","pulls_url":"https://api.github.com/repos/ekmett/machines/pulls{/number}","milestones_url":"https://api.github.com/repos/ekmett/machines/milestones{/number}","notifications_url":"https://api.github.com/repos/ekmett/machines/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/ekmett/machines/labels{/name}","releases_url":"https://api.github.com/repos/ekmett/machines/releases{/id}","deployments_url":"https://api.github.com/repos/ekmett/machines/deployments","created_at":"2012-08-16T22:31:42Z","updated_at":"2016-11-22T13:53:46Z","pushed_at":"2016-11-24T06:43:43Z","git_url":"git://github.com/ekmett/machines.git","ssh_url":"git@github.com:ekmett/machines.git","clone_url":"https://github.com/ekmett/machines.git","svn_url":"https://github.com/ekmett/machines","homepage":"","size":470,"stargazers_count":211,"watchers_count":211,"language":"Haskell","has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":true,"forks_count":40,"mirror_url":null,"open_issues_count":19,"forks":40,"open_issues":19,"watchers":211,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/ekmett/machines/pulls/85"},"html":{"href":"https://github.com/ekmett/machines/pull/85"},"issue":{"href":"https://api.github.com/repos/ekmett/machines/issues/85"},"comments":{"href":"https://api.github.com/repos/ekmett/machines/issues/85/comments"},"review_comments":{"href":"https://api.github.com/repos/ekmett/machines/pulls/85/comments"},"review_comment":{"href":"https://api.github.com/repos/ekmett/machines/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/ekmett/machines/pulls/85/commits"},"statuses":{"href":"https://api.github.com/repos/ekmett/machines/statuses/9f0d34ece9e1c46e7c4dacd5eab6f19bedded593"}}}}
{"actor":{"display_login":"sordina"}}