{"action":"created","comment":{"url":"https://api.github.com/repos/ambiata/x/pulls/comments/67592231","id":67592231,"diff_hunk":"@@ -29,9 +44,71 @@ import           Data.Vector.Fusion.Stream.Monadic (Stream(..))\n import qualified Data.Vector.Fusion.Stream.Monadic as Stream\n \n import           Data.Vector.Generic as Generic\n+import qualified Data.Vector.Generic.Mutable as MGeneric\n+import qualified Data.Vector.Unboxed as Unboxed\n \n import           P hiding (mapMaybe)\n \n+-- | The 'transpose' function transposes the rows and columns of its argument.\n+--\n+--   For example:\n+--\n+--   > transpose [[1,2,3],[4,5,6]] == [[1,4],[2,5],[3,6]]\n+--\n+--   If some of the rows are shorter than the following rows, their elements are skipped:\n+--\n+--   > transpose [[10,11],[20],[],[30,31,32]] == [[10,20,30],[11,31],[32]]\n+--\n+transpose :: forall vv va a. (Vector va a, Vector vv (va a)) => vv (va a) -> vv (va a)\n+transpose xss =\n+  Generic.create $ do\n+    let\n+      xss_len :: Int\n+      xss_len =\n+        Generic.length xss\n+\n+      xss_lens :: Unboxed.Vector Int\n+      xss_lens =\n+        lengths xss\n+\n+      max_len :: Int\n+      max_len =\n+        Generic.foldl' max 0 xss_lens\n+\n+    yss <- MGeneric.unsafeNew max_len\n+    for_ [0..max_len-1] $ \\i ->\n+\n+      let\n+         loop :: Mutable va s a -> Int -> Int -> Int -> ST s Int\n+         loop ys0 !to from xs_len =\n+           if i < xs_len then do\n+             let\n+               xs = xss `Generic.unsafeIndex` from\n+               x  = xs  `Generic.unsafeIndex` i\n+\n+             MGeneric.unsafeWrite ys0 to x\n+             pure $! to + 1\n+           else\n+             pure to\n+\n+         ys :: va a\n+         ys =\n+           Generic.create $ do\n+             ys0 <- MGeneric.unsafeNew xss_len\n+             n <- Generic.ifoldM (loop ys0) 0 xss_lens\n+             pure $ MGeneric.unsafeSlice 0 n ys0\n+      in\n+        MGeneric.unsafeWrite yss i ys\n+\n+    pure yss\n+\n+lengths :: (Vector va a, Vector vv (va a), Vector vn Int) => vv (va a) -> vn Int\n+lengths =\n+  unstream .\n+  Bundle.map Generic.length .\n+  Bundle.reVector .\n+  stream","path":"x-vector/src/X/Data/Vector/Generic.hs","position":105,"original_position":105,"commit_id":"3cf40acc54e67a9e77f8ad5fa9e918677562c0e9","original_commit_id":"3cf40acc54e67a9e77f8ad5fa9e918677562c0e9","user":{"login":"jystic","id":134805,"avatar_url":"https://avatars.githubusercontent.com/u/134805?v=3","gravatar_id":"","url":"https://api.github.com/users/jystic","html_url":"https://github.com/jystic","followers_url":"https://api.github.com/users/jystic/followers","following_url":"https://api.github.com/users/jystic/following{/other_user}","gists_url":"https://api.github.com/users/jystic/gists{/gist_id}","starred_url":"https://api.github.com/users/jystic/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jystic/subscriptions","organizations_url":"https://api.github.com/users/jystic/orgs","repos_url":"https://api.github.com/users/jystic/repos","events_url":"https://api.github.com/users/jystic/events{/privacy}","received_events_url":"https://api.github.com/users/jystic/received_events","type":"User","site_admin":false},"body":"Yeah, so unfortunately `convert . fmap G.length` requires and extra constraint `Vector vv Int` on the `transpose` function above, where as this one does not.","created_at":"2016-06-18T01:03:58Z","updated_at":"2016-06-18T01:03:58Z","html_url":"https://github.com/ambiata/x/pull/84#discussion_r67592231","pull_request_url":"https://api.github.com/repos/ambiata/x/pulls/84","_links":{"self":{"href":"https://api.github.com/repos/ambiata/x/pulls/comments/67592231"},"html":{"href":"https://github.com/ambiata/x/pull/84#discussion_r67592231"},"pull_request":{"href":"https://api.github.com/repos/ambiata/x/pulls/84"}}},"pull_request":{"url":"https://api.github.com/repos/ambiata/x/pulls/84","id":74207501,"html_url":"https://github.com/ambiata/x/pull/84","diff_url":"https://github.com/ambiata/x/pull/84.diff","patch_url":"https://github.com/ambiata/x/pull/84.patch","issue_url":"https://api.github.com/repos/ambiata/x/issues/84","number":84,"state":"open","locked":false,"title":"x-vector: add transpose for vectors","user":{"login":"jystic","id":134805,"avatar_url":"https://avatars.githubusercontent.com/u/134805?v=3","gravatar_id":"","url":"https://api.github.com/users/jystic","html_url":"https://github.com/jystic","followers_url":"https://api.github.com/users/jystic/followers","following_url":"https://api.github.com/users/jystic/following{/other_user}","gists_url":"https://api.github.com/users/jystic/gists{/gist_id}","starred_url":"https://api.github.com/users/jystic/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jystic/subscriptions","organizations_url":"https://api.github.com/users/jystic/orgs","repos_url":"https://api.github.com/users/jystic/repos","events_url":"https://api.github.com/users/jystic/events{/privacy}","received_events_url":"https://api.github.com/users/jystic/received_events","type":"User","site_admin":false},"body":"This adds the `Data.List.transpose` function, but over vectors.\r\n\r\nThe main downside is that we pessimistically allocate the largest possible number of columns for each row and then trim it with `unsafeSlice` once we know how many columns that row will have. Not sure if there is a fast way we could determine the final layout up front, but this will only be sub-optimal in the case of jagged (non-rectangular) vectors.\r\n\r\n/cc @amosr ","created_at":"2016-06-17T08:42:03Z","updated_at":"2016-06-18T01:03:58Z","closed_at":null,"merged_at":null,"merge_commit_sha":"1530123aef825b87295b71c20f0b622256b4daa4","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/ambiata/x/pulls/84/commits","review_comments_url":"https://api.github.com/repos/ambiata/x/pulls/84/comments","review_comment_url":"https://api.github.com/repos/ambiata/x/pulls/comments{/number}","comments_url":"https://api.github.com/repos/ambiata/x/issues/84/comments","statuses_url":"https://api.github.com/repos/ambiata/x/statuses/3cf40acc54e67a9e77f8ad5fa9e918677562c0e9","head":{"label":"ambiata:topic/transpose","ref":"topic/transpose","sha":"3cf40acc54e67a9e77f8ad5fa9e918677562c0e9","user":{"login":"ambiata","id":1691023,"avatar_url":"https://avatars.githubusercontent.com/u/1691023?v=3","gravatar_id":"","url":"https://api.github.com/users/ambiata","html_url":"https://github.com/ambiata","followers_url":"https://api.github.com/users/ambiata/followers","following_url":"https://api.github.com/users/ambiata/following{/other_user}","gists_url":"https://api.github.com/users/ambiata/gists{/gist_id}","starred_url":"https://api.github.com/users/ambiata/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ambiata/subscriptions","organizations_url":"https://api.github.com/users/ambiata/orgs","repos_url":"https://api.github.com/users/ambiata/repos","events_url":"https://api.github.com/users/ambiata/events{/privacy}","received_events_url":"https://api.github.com/users/ambiata/received_events","type":"Organization","site_admin":false},"repo":{"id":33694347,"name":"x","full_name":"ambiata/x","owner":{"login":"ambiata","id":1691023,"avatar_url":"https://avatars.githubusercontent.com/u/1691023?v=3","gravatar_id":"","url":"https://api.github.com/users/ambiata","html_url":"https://github.com/ambiata","followers_url":"https://api.github.com/users/ambiata/followers","following_url":"https://api.github.com/users/ambiata/following{/other_user}","gists_url":"https://api.github.com/users/ambiata/gists{/gist_id}","starred_url":"https://api.github.com/users/ambiata/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ambiata/subscriptions","organizations_url":"https://api.github.com/users/ambiata/orgs","repos_url":"https://api.github.com/users/ambiata/repos","events_url":"https://api.github.com/users/ambiata/events{/privacy}","received_events_url":"https://api.github.com/users/ambiata/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/ambiata/x","description":"A collection of extra combinators for various projects.","fork":false,"url":"https://api.github.com/repos/ambiata/x","forks_url":"https://api.github.com/repos/ambiata/x/forks","keys_url":"https://api.github.com/repos/ambiata/x/keys{/key_id}","collaborators_url":"https://api.github.com/repos/ambiata/x/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/ambiata/x/teams","hooks_url":"https://api.github.com/repos/ambiata/x/hooks","issue_events_url":"https://api.github.com/repos/ambiata/x/issues/events{/number}","events_url":"https://api.github.com/repos/ambiata/x/events","assignees_url":"https://api.github.com/repos/ambiata/x/assignees{/user}","branches_url":"https://api.github.com/repos/ambiata/x/branches{/branch}","tags_url":"https://api.github.com/repos/ambiata/x/tags","blobs_url":"https://api.github.com/repos/ambiata/x/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/ambiata/x/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/ambiata/x/git/refs{/sha}","trees_url":"https://api.github.com/repos/ambiata/x/git/trees{/sha}","statuses_url":"https://api.github.com/repos/ambiata/x/statuses/{sha}","languages_url":"https://api.github.com/repos/ambiata/x/languages","stargazers_url":"https://api.github.com/repos/ambiata/x/stargazers","contributors_url":"https://api.github.com/repos/ambiata/x/contributors","subscribers_url":"https://api.github.com/repos/ambiata/x/subscribers","subscription_url":"https://api.github.com/repos/ambiata/x/subscription","commits_url":"https://api.github.com/repos/ambiata/x/commits{/sha}","git_commits_url":"https://api.github.com/repos/ambiata/x/git/commits{/sha}","comments_url":"https://api.github.com/repos/ambiata/x/comments{/number}","issue_comment_url":"https://api.github.com/repos/ambiata/x/issues/comments{/number}","contents_url":"https://api.github.com/repos/ambiata/x/contents/{+path}","compare_url":"https://api.github.com/repos/ambiata/x/compare/{base}...{head}","merges_url":"https://api.github.com/repos/ambiata/x/merges","archive_url":"https://api.github.com/repos/ambiata/x/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/ambiata/x/downloads","issues_url":"https://api.github.com/repos/ambiata/x/issues{/number}","pulls_url":"https://api.github.com/repos/ambiata/x/pulls{/number}","milestones_url":"https://api.github.com/repos/ambiata/x/milestones{/number}","notifications_url":"https://api.github.com/repos/ambiata/x/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/ambiata/x/labels{/name}","releases_url":"https://api.github.com/repos/ambiata/x/releases{/id}","deployments_url":"https://api.github.com/repos/ambiata/x/deployments","created_at":"2015-04-09T21:44:14Z","updated_at":"2016-01-13T04:22:31Z","pushed_at":"2016-06-17T08:42:03Z","git_url":"git://github.com/ambiata/x.git","ssh_url":"git@github.com:ambiata/x.git","clone_url":"https://github.com/ambiata/x.git","svn_url":"https://github.com/ambiata/x","homepage":null,"size":247,"stargazers_count":1,"watchers_count":1,"language":"Haskell","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":4,"forks":0,"open_issues":4,"watchers":1,"default_branch":"master"}},"base":{"label":"ambiata:master","ref":"master","sha":"2c622d87a3cf9b9781d85b84e46aeca8437bfed2","user":{"login":"ambiata","id":1691023,"avatar_url":"https://avatars.githubusercontent.com/u/1691023?v=3","gravatar_id":"","url":"https://api.github.com/users/ambiata","html_url":"https://github.com/ambiata","followers_url":"https://api.github.com/users/ambiata/followers","following_url":"https://api.github.com/users/ambiata/following{/other_user}","gists_url":"https://api.github.com/users/ambiata/gists{/gist_id}","starred_url":"https://api.github.com/users/ambiata/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ambiata/subscriptions","organizations_url":"https://api.github.com/users/ambiata/orgs","repos_url":"https://api.github.com/users/ambiata/repos","events_url":"https://api.github.com/users/ambiata/events{/privacy}","received_events_url":"https://api.github.com/users/ambiata/received_events","type":"Organization","site_admin":false},"repo":{"id":33694347,"name":"x","full_name":"ambiata/x","owner":{"login":"ambiata","id":1691023,"avatar_url":"https://avatars.githubusercontent.com/u/1691023?v=3","gravatar_id":"","url":"https://api.github.com/users/ambiata","html_url":"https://github.com/ambiata","followers_url":"https://api.github.com/users/ambiata/followers","following_url":"https://api.github.com/users/ambiata/following{/other_user}","gists_url":"https://api.github.com/users/ambiata/gists{/gist_id}","starred_url":"https://api.github.com/users/ambiata/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ambiata/subscriptions","organizations_url":"https://api.github.com/users/ambiata/orgs","repos_url":"https://api.github.com/users/ambiata/repos","events_url":"https://api.github.com/users/ambiata/events{/privacy}","received_events_url":"https://api.github.com/users/ambiata/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/ambiata/x","description":"A collection of extra combinators for various projects.","fork":false,"url":"https://api.github.com/repos/ambiata/x","forks_url":"https://api.github.com/repos/ambiata/x/forks","keys_url":"https://api.github.com/repos/ambiata/x/keys{/key_id}","collaborators_url":"https://api.github.com/repos/ambiata/x/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/ambiata/x/teams","hooks_url":"https://api.github.com/repos/ambiata/x/hooks","issue_events_url":"https://api.github.com/repos/ambiata/x/issues/events{/number}","events_url":"https://api.github.com/repos/ambiata/x/events","assignees_url":"https://api.github.com/repos/ambiata/x/assignees{/user}","branches_url":"https://api.github.com/repos/ambiata/x/branches{/branch}","tags_url":"https://api.github.com/repos/ambiata/x/tags","blobs_url":"https://api.github.com/repos/ambiata/x/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/ambiata/x/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/ambiata/x/git/refs{/sha}","trees_url":"https://api.github.com/repos/ambiata/x/git/trees{/sha}","statuses_url":"https://api.github.com/repos/ambiata/x/statuses/{sha}","languages_url":"https://api.github.com/repos/ambiata/x/languages","stargazers_url":"https://api.github.com/repos/ambiata/x/stargazers","contributors_url":"https://api.github.com/repos/ambiata/x/contributors","subscribers_url":"https://api.github.com/repos/ambiata/x/subscribers","subscription_url":"https://api.github.com/repos/ambiata/x/subscription","commits_url":"https://api.github.com/repos/ambiata/x/commits{/sha}","git_commits_url":"https://api.github.com/repos/ambiata/x/git/commits{/sha}","comments_url":"https://api.github.com/repos/ambiata/x/comments{/number}","issue_comment_url":"https://api.github.com/repos/ambiata/x/issues/comments{/number}","contents_url":"https://api.github.com/repos/ambiata/x/contents/{+path}","compare_url":"https://api.github.com/repos/ambiata/x/compare/{base}...{head}","merges_url":"https://api.github.com/repos/ambiata/x/merges","archive_url":"https://api.github.com/repos/ambiata/x/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/ambiata/x/downloads","issues_url":"https://api.github.com/repos/ambiata/x/issues{/number}","pulls_url":"https://api.github.com/repos/ambiata/x/pulls{/number}","milestones_url":"https://api.github.com/repos/ambiata/x/milestones{/number}","notifications_url":"https://api.github.com/repos/ambiata/x/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/ambiata/x/labels{/name}","releases_url":"https://api.github.com/repos/ambiata/x/releases{/id}","deployments_url":"https://api.github.com/repos/ambiata/x/deployments","created_at":"2015-04-09T21:44:14Z","updated_at":"2016-01-13T04:22:31Z","pushed_at":"2016-06-17T08:42:03Z","git_url":"git://github.com/ambiata/x.git","ssh_url":"git@github.com:ambiata/x.git","clone_url":"https://github.com/ambiata/x.git","svn_url":"https://github.com/ambiata/x","homepage":null,"size":247,"stargazers_count":1,"watchers_count":1,"language":"Haskell","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":4,"forks":0,"open_issues":4,"watchers":1,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/ambiata/x/pulls/84"},"html":{"href":"https://github.com/ambiata/x/pull/84"},"issue":{"href":"https://api.github.com/repos/ambiata/x/issues/84"},"comments":{"href":"https://api.github.com/repos/ambiata/x/issues/84/comments"},"review_comments":{"href":"https://api.github.com/repos/ambiata/x/pulls/84/comments"},"review_comment":{"href":"https://api.github.com/repos/ambiata/x/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/ambiata/x/pulls/84/commits"},"statuses":{"href":"https://api.github.com/repos/ambiata/x/statuses/3cf40acc54e67a9e77f8ad5fa9e918677562c0e9"}}}}
{"actor":{"display_login":"jystic"}}