{"id":13687609,"url":"https://github.com/qfpl/applied-fp-course","last_synced_at":"2025-10-05T05:00:02.980Z","repository":{"id":38341090,"uuid":"106774466","full_name":"qfpl/applied-fp-course","owner":"qfpl","description":"Applied Functional Programming Course - Move from exercises to a working app!","archived":false,"fork":false,"pushed_at":"2023-11-20T13:29:36.000Z","size":643,"stargazers_count":632,"open_issues_count":8,"forks_count":180,"subscribers_count":37,"default_branch":"master","last_synced_at":"2025-05-01T13:50:53.195Z","etag":null,"topics":["fp-course","haskell","study"],"latest_commit_sha":null,"homepage":"http://qfpl.io/projects/professional-fp-courses/","language":"Haskell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/qfpl.png","metadata":{"files":{"readme":"README.md","changelog":"changelog.md","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-10-13T03:38:55.000Z","updated_at":"2025-04-29T16:18:01.000Z","dependencies_parsed_at":"2024-01-14T18:09:24.421Z","dependency_job_id":null,"html_url":"https://github.com/qfpl/applied-fp-course","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/qfpl/applied-fp-course","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/qfpl%2Fapplied-fp-course","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/qfpl%2Fapplied-fp-course/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/qfpl%2Fapplied-fp-course/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/qfpl%2Fapplied-fp-course/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/qfpl","download_url":"https://codeload.github.com/qfpl/applied-fp-course/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/qfpl%2Fapplied-fp-course/sbom","scorecard":{"id":753161,"data":{"date":"2025-08-11","repo":{"name":"github.com/qfpl/applied-fp-course","commit":"5cc757153a41f7efcd7fc047a7fee483a8b3bb9b"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3,"checks":[{"name":"Code-Review","score":0,"reason":"Found 0/11 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"License","score":9,"reason":"license file detected","details":["Info: project has a license file: LICENCE:0","Warn: project license file does not contain an FSF or OSI license."],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 23 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-22T20:52:45.985Z","repository_id":38341090,"created_at":"2025-08-22T20:52:45.986Z","updated_at":"2025-08-22T20:52:45.986Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278411248,"owners_count":25982368,"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-05T02:00:06.059Z","response_time":54,"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":["fp-course","haskell","study"],"created_at":"2024-08-02T15:00:57.444Z","updated_at":"2025-10-05T05:00:02.929Z","avatar_url":"https://github.com/qfpl.png","language":"Haskell","funding_links":[],"categories":["Haskell"],"sub_categories":[],"readme":"# Applied Functional Programming Course\n\n[![Build Status](https://travis-ci.org/qfpl/applied-fp-course.svg?branch=master)](https://travis-ci.org/qfpl/applied-fp-course)\n\n![CSIRO's Data61 Logo](https://raw.githubusercontent.com/qfpl/assets/master/data61-transparent-bg.png)\n\nThis is a new course, so there are going to be rough edges. We invite you to\nsubmit issues or pull requests if you find errors or have suggestions on how to\nimprove it.\n\nThis course is designed to be run in a class room with instructors, but we\nwould like to make it suitable for self-study as well. Although undertaking\nthis course outside of the workshops will increase the difficulty somewhat,\nwe do not discourage it and invite suggestions on how to make the course more\napproachable.\n\nIf you do attempt this on your own and find yourself completely lost,\nthen you may come find us on IRC on [libera.chat](https://web.libera.chat/)\nin `#qfpl` or `#fp-course`.\n\n### You:\n\n* Have completed, or are capable of completing, the [FP Course](https://github.com/system-f/fp-course).\n* Have a few months self-study to your name.\n* Want to know how to build larger applications with statically typed FP.\n* Are willing to accept that a web application is a sufficient choice.\n* Can write the canonical function of type: `Applicative f =\u003e [f a] -\u003e f [a]`\n\n### We:\n\n* Have constructed a sequence of goals of increasing difficulty.\n* Have provided a framework within which to apply these goals.\n* Have included relevant components of larger applications:\n  * Package dependencies\n  * Project configuration\n  * Application testing \u0026 building\n  * Encoding / Decoding messages (JSON \u0026 Binary)\n  * Persistent storage integration\n  * App state \u0026 configuration management\n  * Error handling \u0026 reporting\n* Will utilise both type \u0026 test driven development techniques.\n* Will explain architectural and design trade-offs when appropriate.\n\n### Setup build tools:\n\nEach level is a self-contained Haskell module, containing incomplete, or as yet\nundefined, data types and functions.\n\nWe recommend using `nix develop` or `nix-shell` to get a shell with\nthe necessary tools. You can also use `cabal` or `stack`.\n\n#### Cabal\n\nIf you're using version \u003e=3.0 of `cabal-install` (use `cabal\n--version` to find out), then you don't need to previx the commands\nwith `v2-`:\n\n```bash\n$ cd path/to/applied-fp-course\n$ cabal configure --enable-tests\n$ cabal build \u003clevelN\u003e-exe\n$ $EDITOR src/\u003cLevelN\u003e/README.md\n```\n\n#### Nix\n\nIf you would like to use a Nix Shell:\n\n```bash\n$ cd path/to/applied-fp-course\n$ nix-shell  # or `nix develop`, if you use flakes\n$ cabal build \u003clevelN\u003e-exe\n$ $EDITOR src/\u003cLevelN\u003e/README.md\n```\n\n#### ghcid\n\nIf you have `ghcid` installed, run `ghcid -c 'cabal repl'` to get a\nterminal with up-to-date type errors, which are refreshed on every\nsave.\n\n#### Stack\n\nA `stack.yaml` configuration is provided on a best-effort basis. The\nauthors do not use stack and cannot promise to be able to resolve\nstack-related issues. Though we will do our best. :)\n\n#### Please note...\n\nThese lessons are designed to be completed with an instructor as part of the\nData61 Applied Functional Programming Course. You are of course welcome to\nclone the repository and give it a try, but you may find the tasks more\ndifficult. If you have any questions we can be contacted in the\n[#qfpl IRC channel](https://libera.chat) on `libera.chat`.\n\n#### Subsequent lessons may contain spoilers, don't cheat yourself out of the experience!\n\nThere is a `README.md` file in each Level module folder that will provide\ninstructions about what the goal is for that specific level.\n\n* Level 01 : Simple hello world web app.\n* Level 02 : Define our application spec with types!\n* Level 03 : Testing \u0026 tools\n* Level 04 : Database layer (sqlite-simple)\n* Level 05 : Better error handling through ExceptT\n* Level 06 : Add some flexible configuration\n* Level 07 : `ReaderT` \u0026 refactoring\n\n-- In Development...\n* Level 08 : Lenses \u0026 \"classy mtl\" monad transformers\n\n-- Maybe...\n* Level 09 : Add session controls (login, logout) and a protected route. So we\n  can have something that resembles application state. For the purposes of\n  modelling the state machine and implementing some property based tests.\n\n### Bonus Content\n\nExtension material that doesn't feel like it belongs to the main progression\nlives in the [`bonus`](https://github.com/qfpl/applied-fp-course/tree/master/bonus)\nsubdirectory.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fqfpl%2Fapplied-fp-course","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fqfpl%2Fapplied-fp-course","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fqfpl%2Fapplied-fp-course/lists"}