{"id":15355203,"url":"https://github.com/sake92/fp4noobs","last_synced_at":"2026-07-10T08:31:48.114Z","repository":{"id":92664965,"uuid":"440255902","full_name":"sake92/fp4noobs","owner":"sake92","description":"FP for beginners","archived":false,"fork":false,"pushed_at":"2022-06-15T21:50:06.000Z","size":48,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-10-25T12:04:19.083Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Scala","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sake92.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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":"2021-12-20T17:37:11.000Z","updated_at":"2022-06-06T07:24:19.000Z","dependencies_parsed_at":"2023-03-10T02:32:03.625Z","dependency_job_id":null,"html_url":"https://github.com/sake92/fp4noobs","commit_stats":{"total_commits":23,"total_committers":2,"mean_commits":11.5,"dds":0.04347826086956519,"last_synced_commit":"d38a6092094896d2c9b4f32d4bd1937c40083d70"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/sake92/fp4noobs","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sake92%2Ffp4noobs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sake92%2Ffp4noobs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sake92%2Ffp4noobs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sake92%2Ffp4noobs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sake92","download_url":"https://codeload.github.com/sake92/fp4noobs/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sake92%2Ffp4noobs/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35326962,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-10T02:00:06.465Z","response_time":60,"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":[],"created_at":"2024-10-01T12:23:06.145Z","updated_at":"2026-07-10T08:31:48.097Z","avatar_url":"https://github.com/sake92.png","language":"Scala","funding_links":[],"categories":[],"sub_categories":[],"readme":"# FP for beginners, in Scala 3\n\n\u003e A change in perspective is worth 80 IQ points ~ Alan Kay\n\n\nDisclaimer:  \nThis is by no means a thorough introduction to FP concepts.  \nIt contains lots of my *personal* opinions/views.  \nBut it could help beginners to understand faster some of this mathy stuff.\n\nThe basics of FP are usually simple to understand:\n- immutability\n- tuples\n- ADTs: `case class`es and `enum`s\n- recursion\n- collections functions like `map`, `fold` etc\n\n\nWhere it gets challenging is the maths(category theory) terminology and advanced types (higher kinded types).  \nThis repo tries to simplify that learning path.  \nIt introduces minimal syntax and some examples of usage for each concept.  \nWe don't bother with *laws* here, we just consider the intuition and usage.  \n\nEach of these concepts is using the [typeclass pattern](https://docs.scala-lang.org/scala3/book/ca-type-classes.html) which you need to know already.\n\nOrder of reading:  \n1. [semigroup](https://github.com/sake92/fp4noobs/tree/main/fp/src/main/scala/fp/semigroup)\n1. [monoid](https://github.com/sake92/fp4noobs/tree/main/fp/src/main/scala/fp/monoid)\n1. [functor](https://github.com/sake92/fp4noobs/tree/main/fp/src/main/scala/fp/functor)\n1. [applicative](https://github.com/sake92/fp4noobs/tree/main/fp/src/main/scala/fp/applicative)\n1. [monad](https://github.com/sake92/fp4noobs/tree/main/fp/src/main/scala/fp/monad)\n1. [writer](https://github.com/sake92/fp4noobs/tree/main/fp/src/main/scala/fp/writer)\n1. [reader](https://github.com/sake92/fp4noobs/tree/main/fp/src/main/scala/fp/reader)\n1. [state](https://github.com/sake92/fp4noobs/tree/main/fp/src/main/scala/fp/state)\n\nResources:\n- https://www.youtube.com/playlist?list=PLFrwDVdSrYE6dy14XCmUtRAJuhCxuzJp0\n- https://www.scalawithcats.com/dist/scala-with-cats.html\n\nHighly recommended exercises:\n- https://www.scala-exercises.org/fp_in_scala\n- https://www.scala-exercises.org/cats\n\n## Running examples\n\n```bash\n.\\millw.bat fp.runMain fp.functor.functorMain\n```\n\n---\n## Nicer Syntax\nWe usually want a nice \"operator-ish\" syntax like `1 + 3`.  \nScala has *infix notation* for functions.  \nBut those have to be called on an object. \n\nIf we have:\n```scala\ndef f(a: Int, b: Int): Int = a + b\n\nf(1, 2)\n1 f 2   // does not compile\n```\nBut this works:\n```scala\nclass MyClass(x: Int):\n  def f(y: Int): Int = x + y\n\nval myCls = MyClass(1)\nmyCls.f(2)\nmyCls f 2   // works!\n```\n\nSo we fix the first example by extending the type using \"extension function\":\n```scala\nextension (x: Int)\n  def f(y: Int): Int = x + y\n\n1 f 2   // works, yay!\n```\n\n\n\n---\n\n## Advanced types\nThis is mostly a rewording of Adriaan's answer from SO: https://stackoverflow.com/a/6427289/4496364  \nHe uses an analogy with values:\n- a **proper value** is \"immediately usable\" and \"concrete\", like `1`, `true`, an object etc. \n- **value constructor**(function) is NOT \"immediately usable\", you need to give it a value first\nThis is \"first order\" value constructor, one level deep.\n- **value constructor constructor** is NOT \"immediately usable\". If you give it a value, it will return another value constructor. This is a **higher order** abstraction.   \n\"higher-order abstraction abstracts over something that abstracts over something\" - Adriaan   \nThis reminds me of OOP abstract factory design pattern (factory of factories). :)\n\n\nIf we have these:\n```scala\nclass String\nclass List[T]\nclass Functor[F[_]]\n```\n\nyou can refer to this table:\n| Syntax          | proper  | first-order         | higher-order                  |\n| --------------- | ------- | ------------------- |----------------------------   |\n| values          | 10      | (x: Int) =\u003e x       |(f: (Int =\u003e Int)) =\u003e f(10)     |\n| types (classes) | String  | List                |Functor                        |\n| types           | String  | type F = [X] =\u003e\u003e R  |type FF = [X] =\u003e\u003e [Y] =\u003e\u003e R    |\n\n\n![](https://i.stack.imgur.com/K0dwL.jpg)\n\n\nhttps://adriaanm.github.io/files/higher.pdf\n\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsake92%2Ffp4noobs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsake92%2Ffp4noobs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsake92%2Ffp4noobs/lists"}