{"id":20372831,"url":"https://github.com/sidmishraw/muunads","last_synced_at":"2026-07-09T19:31:49.973Z","repository":{"id":86400612,"uuid":"115216814","full_name":"sidmishraw/muunads","owner":"sidmishraw","description":"Monadic Java","archived":false,"fork":false,"pushed_at":"2018-01-08T23:52:57.000Z","size":113,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-04T20:43:21.740Z","etag":null,"topics":["java8","monad","monads"],"latest_commit_sha":null,"homepage":null,"language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sidmishraw.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-12-23T19:21:03.000Z","updated_at":"2018-01-08T23:52:58.000Z","dependencies_parsed_at":null,"dependency_job_id":"0bac0927-accd-4feb-af02-cd594120bdc5","html_url":"https://github.com/sidmishraw/muunads","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/sidmishraw/muunads","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sidmishraw%2Fmuunads","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sidmishraw%2Fmuunads/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sidmishraw%2Fmuunads/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sidmishraw%2Fmuunads/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sidmishraw","download_url":"https://codeload.github.com/sidmishraw/muunads/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sidmishraw%2Fmuunads/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":280943385,"owners_count":26417746,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-25T02:00:06.499Z","response_time":81,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["java8","monad","monads"],"created_at":"2024-11-15T01:15:11.222Z","updated_at":"2025-10-25T10:36:32.132Z","avatar_url":"https://github.com/sidmishraw.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Muunads\n\nAuthor: Sidharth Mishra\n\n\n## Description\n\nMuunads are Monads for Java. These *monads* are inspired by Haskell's monads.\n\nMy IO and STM actions are designed to be lazy. They are performed with call to `unwrap()`.\n\n## Usage Examples as of v0.2\n\n```java\n\n    /**\n     * \u003cp\u003e\n     * Uses Muunads `Do` utility method.\n     * \u003c/p\u003e\n     */\n    private static void usingMuunadsDo() {\n        String msg = Muunads.Do(Muunads.readLn);\n        Muunads.Do(Muunads.putStrLn.apply(\"Sample using `Muunads.Do()` :: \\n \" + msg));\n    }\n\n    /**\n     * \u003cp\u003e\n     * Uses the {@link Monad#unwrap()} instead of {@link Muunads#Do(actions.io.IO)}.\n     * \u003c/p\u003e\n     */\n    private static void usingUnwrap() {\n        String msg = Muunads.readLn.unwrap();\n        Muunads.putStrLn.apply(\"Sample using `unwrap` :: \\n \" + msg).unwrap();\n    }\n    \n    ...\n    \n\t/**\n     * @param args\n     */\n    public static void main(String[] args) {\n        usingMuunadsDo();\n        Muunads.putStrLn.apply(\"---------\").unwrap(); // Action is not performed immediately without a call to unwrap()\n        usingUnwrap();\n    }\n    \n```\n\n\n## IO Actions are Muunads\n\n## Changelog v0.2\n\n* The Monad interface has dropped `wrap()` and added `unwrap()`. `unwrap()` performs the action and returns the contents of the Monad or action.\n\n* This also eliminates the need for a `perform()` in the `IO\u003cA\u003e` Monad.\n\n* Also, this version includes the `Muunads` utility class. It has examples for Haskell's `readLn` and `putStrLn` functions.\n\n```java\n    public static final IO\u003cString\u003e readLn = new IO\u003cString\u003e(() -\u003e {\n        String input = null;\n        try (BufferedReader br = new BufferedReader(new InputStreamReader(System.in) {\n            /**\n             * do nothing, this will prevent\n             * the try with resources from closing\n             * the STDIN stream.\n             * \n             * @throws IOException\n             */\n            @Override\n            public void close() throws IOException {}\n        })) {\n            input = br.readLine();\n        } catch (Exception e) {\n            logger.error(e.getMessage(), e);\n        }\n        return input;\n    });\n```\n\n* `readLn` in Muunads is defined as an `IO\u003cString\u003e` action. When performed using the `unwrap()`, it will read a line from the `STDIN` and return the `String`.\n\n\u003e Note: Because `try-with-resources` block closes the `System.in` stream if the `close()` of `InputStreamReader` class is not overridden, I have overridden the close() to do nothing.\n\n* Similarly, `putStrLn` in Muunads is defined as a `Function\u003cString, IO\u003cVoid\u003e\u003e` that takes in a String and produces an `IO\u003cVoid\u003e` action, which when performed will put the applied String on the `STDOUT`.\n\n```java\n    public static final Function\u003cString, IO\u003cVoid\u003e\u003e putStrLn = (String str) -\u003e new IO\u003cVoid\u003e(() -\u003e {\n        System.out.println(str);\n        return null;\n    });\n```\n\n## Changelog v0.1\n\nConsider the following IO action in Haskell:\n\n```haskell\nmain :: IO ()\nmain = putStrLn \"Hello World!\"\n```\n\nThe `IO ()` action performs an IO action which prints `\"Hello World!\"` to the `STDOUT` and returns `()` unit or `Void`.\nSimilarly, Muunads also defines an IO action for Java. It too is a Monad.\n\n```java\nIO\u003cVoid\u003e ioAction = new IO\u003cVoid\u003e(() -\u003e {\n    System.out.println(\"IO Action in action!\");\n    return null;\n});\n\nioAction.perform(); // prints `IO Action in action!` to STDOUT and returns nothing or null (Void).\n```\n\nThe problem at first glance is the verbosity. Second, Haskell's IO system was built from a monadic point of view but, Java's was not. \nUsing this library, the consumer is able to get the power of Haskell like monadic IO actions but, they need to design the actions themselves.\n\nThe following example demonstrates a possible usage of the IO action in Java to emulate `putStrLn` in Haskell.\n\n```java\n/**\n * Returns an IO action that prints the string onto STDOUT.\n * \n * @param str\n *            the string to be printed to STDOUT.\n * @return the IO action.\n */\npublic static IO\u003cVoid\u003e putStrLn(String str) {\n    return new IO\u003cVoid\u003e(() -\u003e {\n        System.out.println(str);\n        return null;\n    });\n}\n\n/**\n * Performs the IO\u003cVoid\u003e actions sequentially.\n * \n * @param actions\n *            the IO\u003cVoid\u003e actions to perform\n */\n@SafeVarargs\npublic static void perform(IO\u003cVoid\u003e... actions) {\n    Arrays.asList(actions).forEach(act -\u003e {\n        act.perform();\n    });\n}\n\n...\n\n// somewhere inside main()\nperform(putStrLn(\"Hello\"), \n\tputStrLn(\"World!\"), \n\tputStrLn(\"I'm Sid\"),\n\tputStrLn(\"Trying to make Munnadic Java real!\"));\n```\n\nIn Haskell this would be as simple as:\n\n```haskell\nmain :: IO()\nmain = do\n  putStrLn \"Hello\"\n  putStrLn \"World!\"\n  putStrLn \"I'm Sid\"\n  putStrLn \"Trying to make Munnadic Java real!\"\n```\n\nBut, this syntactically this sweet-sugary form comes from Haskell's library and language syntax. However, this is easily emulated by my `putStrLn()` and `perform()` methods.\n\n## Requirements\n\n* Java 8+ for LAMBDAS --- since lambdas are supported from Java8+\n\n* Project Lombok for boilerplate reduction\n\n* Gradle for builds\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsidmishraw%2Fmuunads","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsidmishraw%2Fmuunads","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsidmishraw%2Fmuunads/lists"}