{"id":25482443,"url":"https://github.com/Confidenceman02/scion-tools","last_synced_at":"2025-11-07T00:31:08.230Z","repository":{"id":242149464,"uuid":"808814329","full_name":"Confidenceman02/scion-tools","owner":"Confidenceman02","description":"Elm inspired functional programming in Go","archived":false,"fork":false,"pushed_at":"2024-10-25T09:09:26.000Z","size":62,"stargazers_count":0,"open_issues_count":118,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2024-10-25T13:16:39.257Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Confidenceman02.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":"2024-05-31T22:03:22.000Z","updated_at":"2024-10-25T02:24:34.000Z","dependencies_parsed_at":"2024-10-26T21:52:11.966Z","dependency_job_id":null,"html_url":"https://github.com/Confidenceman02/scion-tools","commit_stats":null,"previous_names":["confidenceman02/scion-tools"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Confidenceman02%2Fscion-tools","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Confidenceman02%2Fscion-tools/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Confidenceman02%2Fscion-tools/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Confidenceman02%2Fscion-tools/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Confidenceman02","download_url":"https://codeload.github.com/Confidenceman02/scion-tools/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":239513373,"owners_count":19651323,"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","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":"2025-02-18T17:00:52.944Z","updated_at":"2025-11-07T00:31:08.175Z","avatar_url":"https://github.com/Confidenceman02.png","language":"Go","funding_links":[],"categories":["Go"],"sub_categories":[],"readme":"# scion-tools\n\n[![Actions status](https://Confidenceman02.github.io/djelm/workflows/CI/badge.svg)](https://github.com/Confidenceman02/scion-tools/actions)\n[![](https://img.shields.io/badge/license-MIT-blue)](https://github.com/Confidenceman02/scion-tools/blob/main/LICENSE)\n\n\u003e [!NOTE]\n\u003e There are some packages and functions from the Elm core library that are yet to be implemented. You can see a list of these\n\u003e in the [issues](https://github.com/Confidenceman02/scion-tools/issues).\n\n# Elm inspired functional programing in Go\n\n---\n\n## Table of Content\n\n\u003e [!NOTE]\n\u003e For brevity we will use `[]` to signify a `List[T]` and `(,)` to signify a `Tuple[A,B]`.\n\u003e\n\u003e You can use the `FromSlice` utility to create a `List[T]` from a slice.\n\n```\n// example\n\n[1,2,3] =\u003e list.FromSlice([]int{1,2,3})\n(true,1) =\u003e tuple.Pair(true,1)\n```\n\n- [The why](#the-why)\n- [The when](#the-when)\n- \u003cdetails\u003e\n    \u003csummary\u003e\u003ca href=\"#basics\"\u003eBasics\u003c/a\u003e\u003c/summary\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#int\"\u003eInt\u003c/a\u003e\n        \u003c/li\u003e\n        \u003cli\u003e\n            \u003ca href=\"#float\"\u003eFloat\u003c/a\u003e\n        \u003c/li\u003e\n        \u003cli\u003e\n            \u003ca href=\"#number\"\u003eNumber\u003c/a\u003e\n        \u003c/li\u003e\n        \u003cli\u003e\n            \u003ca href=\"#comparable\"\u003eComparable\u003c/a\u003e\n        \u003c/li\u003e\n        \u003cli\u003e\n            \u003ca href=\"#add\"\u003eAdd\u003c/a\u003e\n        \u003c/li\u003e\n        \u003cli\u003e\n            \u003ca href=\"#sub\"\u003eSub\u003c/a\u003e\n        \u003c/li\u003e\n        \u003cli\u003e\n            \u003ca href=\"#fdiv\"\u003eFdiv\u003c/a\u003e\n        \u003c/li\u003e\n        \u003cli\u003e\n            \u003ca href=\"#mul\"\u003eMul\u003c/a\u003e\n        \u003c/li\u003e\n        \u003cli\u003e\n            \u003ca href=\"#tofloat\"\u003eToFloat\u003c/a\u003e\n        \u003c/li\u003e\n        \u003cli\u003e\n            \u003ca href=\"#round\"\u003eRound\u003c/a\u003e\n        \u003c/li\u003e\n        \u003cli\u003e\n            \u003ca href=\"#floor\"\u003eFloor\u003c/a\u003e\n        \u003c/li\u003e\n        \u003cli\u003e\n            \u003ca href=\"#ceiling\"\u003eCeiling\u003c/a\u003e\n        \u003c/li\u003e\n        \u003cli\u003e\n            \u003ca href=\"#truncate\"\u003eTruncate\u003c/a\u003e\n        \u003c/li\u003e\n        \u003cli\u003e\n            \u003ca href=\"#lt\"\u003eLt\u003c/a\u003e\n        \u003c/li\u003e\n        \u003cli\u003e\n            \u003ca href=\"#gt\"\u003eGt\u003c/a\u003e\n        \u003c/li\u003e\n        \u003cli\u003e\n            \u003ca href=\"#le\"\u003eLe\u003c/a\u003e\n        \u003c/li\u003e\n        \u003cli\u003e\n            \u003ca href=\"#ge\"\u003eGe\u003c/a\u003e\n        \u003c/li\u003e\n        \u003cli\u003e\n            \u003ca href=\"#max\"\u003eMax\u003c/a\u003e\n        \u003c/li\u003e\n        \u003cli\u003e\n            \u003ca href=\"#min\"\u003eMin\u003c/a\u003e\n        \u003c/li\u003e\n        \u003cli\u003e\n            \u003ca href=\"#compare\"\u003eCompare\u003c/a\u003e\n        \u003c/li\u003e\n        \u003cli\u003e\n            \u003ca href=\"#order\"\u003eOrder\u003c/a\u003e\n        \u003c/li\u003e\n        \u003cli\u003e\n            \u003ca href=\"#not\"\u003eNot\u003c/a\u003e\n        \u003c/li\u003e\n        \u003cli\u003e\n            \u003ca href=\"#append\"\u003eAppend\u003c/a\u003e\n        \u003c/li\u003e\n        \u003cli\u003e\n            \u003ca href=\"#modby\"\u003eModBy\u003c/a\u003e\n        \u003c/li\u003e\n        \u003cli\u003e\n            \u003ca href=\"#negate\"\u003eNegate\u003c/a\u003e\n        \u003c/li\u003e\n        \u003cli\u003e\n            \u003ca href=\"#sqrt\"\u003eSqrt\u003c/a\u003e\n        \u003c/li\u003e\n        \u003cli\u003e\n            \u003ca href=\"#identity\"\u003eIdentity\u003c/a\u003e\n        \u003c/li\u003e\n        \u003cli\u003e\n            \u003ca href=\"#composel\"\u003eComposeL\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n  \u003c/details\u003e\n- \u003cdetails\u003e\n    \u003csummary\u003e\u003ca href=\"#bitwise\"\u003eBitwise\u003c/a\u003e\u003c/summary\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#and\"\u003eAnd\u003c/a\u003e\n        \u003c/li\u003e\n        \u003cli\u003e\n            \u003ca href=\"#shiftrightby\"\u003eShiftRightBy\u003c/a\u003e\n        \u003c/li\u003e\n        \u003cli\u003e\n            \u003ca href=\"#shiftleftby\"\u003eShiftLeftBy\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n  \u003c/details\u003e\n- \u003cdetails\u003e\n    \u003csummary\u003e\u003ca href=\"#char\"\u003eChar\u003c/a\u003e\u003c/summary\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#isdigit\"\u003eIsDigit\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n  \u003c/details\u003e\n- \u003cdetails\u003e\n    \u003csummary\u003e\u003ca href=\"#dict\"\u003eDict\u003c/a\u003e\u003c/summary\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#empty\"\u003eEmpty\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#singletondict\"\u003eSingleton\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#insert\"\u003eInsert\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#update\"\u003eUpdate\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#remove\"\u003eRemove\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#isEmpty\"\u003eIsEmpty\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#memberdict\"\u003eMember\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#get\"\u003eGet\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#size\"\u003eSize\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#keys\"\u003eKeys\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#values\"\u003eValues\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#toList\"\u003eToList\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#fromList\"\u003eFromList\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#mapdict\"\u003eMap\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#foldldict\"\u003eFoldl\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#foldrdict\"\u003eFoldr\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#filter\"\u003eFilter\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#partitiondict\"\u003ePartition\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#union\"\u003eUnion\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#intersect\"\u003eIntersect\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#diff\"\u003eDiff\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#merge\"\u003eMerge\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n  \u003c/details\u003e\n- \u003cdetails\u003e\n    \u003csummary\u003e\u003ca href=\"#list\"\u003eList\u003c/a\u003e\u003c/summary\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#fromSlice\"\u003eFromSlice\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#fromSliceMap\"\u003eFromSliceMap\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#toSlice\"\u003eToSlice\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#toSliceMap\"\u003eToSliceMap\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#emptylist\"\u003eEmpty\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#Singletonlist\"\u003eSingleton\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#repeat\"\u003eRepeat\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#range\"\u003eRange\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#cons\"\u003eCons\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#maplist\"\u003eMap\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#foldl\"\u003eFoldl\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#foldr\"\u003eFoldr\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#filter\"\u003eFilter\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#filtermap\"\u003eFilterMap\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#length\"\u003eLength\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#reverselist\"\u003eReverse\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#memberlist\"\u003eMember\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#all\"\u003eAll\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#any\"\u003eAny\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#maximum\"\u003eMaximum\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#minimum\"\u003eMinimum\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#sum\"\u003eSum\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#product\"\u003eProduct\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#append\"\u003eAppend\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#concat\"\u003eConcat\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#concatmap\"\u003eConcatMap\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#intersperse\"\u003eIntersperse\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#map2\"\u003eMap2\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#map3\"\u003eMap3\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#map4\"\u003eMap4\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#map5\"\u003eMap5\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#sort\"\u003eSort\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#sortby\"\u003eSortBy\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#sortwith\"\u003eSortWith\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#isempty\"\u003eIsEmpty\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#head\"\u003eHead\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#tail\"\u003eTail\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#take\"\u003eTake\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#drop\"\u003eDrop\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#partition\"\u003ePartition\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#unzip\"\u003eUnzip\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#listwith\"\u003eListWith\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n  \u003c/details\u003e\n- \u003cdetails\u003e\n    \u003csummary\u003e\u003ca href=\"#maybe\"\u003eMaybe\u003c/a\u003e\u003c/summary\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#withdefault\"\u003eWithDefault\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#mapmaybe\"\u003eMap\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#map2\"\u003eMap2\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#map3\"\u003eMap3\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#map4\"\u003eMap4\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#map5\"\u003eMap5\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#andthen\"\u003eAndThen\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#maybewith\"\u003eMaybeWith\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n  \u003c/details\u003e\n- \u003cdetails\u003e\n    \u003csummary\u003e\u003ca href=\"#result\"\u003eResult\u003c/a\u003e\u003c/summary\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#mapresult\"\u003eMap\u003c/a\u003e\n        \u003c/li\u003e\n        \u003cli\u003e\n            \u003ca href=\"#map2result\"\u003eMap2\u003c/a\u003e\n        \u003c/li\u003e\n        \u003cli\u003e\n            \u003ca href=\"#map3result\"\u003eMap3\u003c/a\u003e\n        \u003c/li\u003e\n        \u003cli\u003e\n            \u003ca href=\"#map4result\"\u003eMap4\u003c/a\u003e\n        \u003c/li\u003e\n        \u003cli\u003e\n            \u003ca href=\"#map5result\"\u003eMap5\u003c/a\u003e\n        \u003c/li\u003e\n        \u003cli\u003e\n            \u003ca href=\"#andthenResult\"\u003eAndThen\u003c/a\u003e\n        \u003c/li\u003e\n        \u003cli\u003e\n            \u003ca href=\"#withDefault\"\u003eWithDefault\u003c/a\u003e\n        \u003c/li\u003e\n        \u003cli\u003e\n            \u003ca href=\"#tomaybe\"\u003eToMaybe\u003c/a\u003e\n        \u003c/li\u003e\n        \u003cli\u003e\n            \u003ca href=\"#frommaybe\"\u003eFromMaybe\u003c/a\u003e\n        \u003c/li\u003e\n        \u003cli\u003e\n            \u003ca href=\"#maperror\"\u003eMapError\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n  \u003c/details\u003e\n- \u003cdetails\u003e\n    \u003csummary\u003e\u003ca href=\"#set\"\u003eSet\u003c/a\u003e\u003c/summary\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#emptyset\"\u003eEmpty\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#singletonset\"\u003eSingleton\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#insertset\"\u003eInsert\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#removeset\"\u003eRemove\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#isEmptyset\"\u003eIsEmpty\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#memberset\"\u003eMember\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#sizeset\"\u003eSize\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#unionset\"\u003eUnion\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#intersectset\"\u003eIntersect\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#diffset\"\u003eDiff\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#toListset\"\u003eToList\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#fromList\"\u003eFromList\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#mapset\"\u003eMap\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#foldlset\"\u003eFoldl\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#foldrset\"\u003eFoldr\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#filterset\"\u003eFilter\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#partitionset\"\u003ePartition\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n  \u003c/details\u003e\n\n- \u003cdetails\u003e\n    \u003csummary\u003e\u003ca href=\"#string\"\u003eString\u003c/a\u003e\u003c/summary\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#isemptystring\"\u003eIsEmpty\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#lengthstring\"\u003eLength\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#reverse\"\u003eReverse\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#repeat\"\u003eRepeat\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#replace\"\u003eReplace\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#appendstring\"\u003eAppend\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#concat\"\u003eConcat\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#split\"\u003eSplit\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#join\"\u003eJoin\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#words\"\u003eWords\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#lines\"\u003eLines\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#slice\"\u003eSlice\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#left\"\u003eLeft\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#right\"\u003eRight\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#dropleft\"\u003eDropLeft\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#dropright\"\u003eDropRight\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#contains\"\u003eContains\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#startswith\"\u003eStartsWith\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#endswith\"\u003eEndsWith\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#indexes\"\u003eIndexes\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#indices\"\u003eIndices\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#toint\"\u003eToInt\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#fromint\"\u003eFromInt\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#tofloat\"\u003eToFloat\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#fromfloat\"\u003eFromFloat\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#fromchar\"\u003eFromChar\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#consstring\"\u003eCons\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#uncons\"\u003eUncons\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#tolist\"\u003eToList\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#fromlist\"\u003eFromList\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#toupper\"\u003eToUpper\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#tolower\"\u003eToLower\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#pad\"\u003ePad\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#padleft\"\u003ePadLeft\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#padright\"\u003ePadRight\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#trim\"\u003eTrim\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#trimleft\"\u003eTrimLeft\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#trimright\"\u003eTrimRight\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#mapstring\"\u003eMap\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#filter\"\u003eFilter\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#foldl\"\u003eFoldl\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#foldr\"\u003eFoldr\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#any\"\u003eAny\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#allstring\"\u003eAll\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n  \u003c/details\u003e\n- \u003cdetails\u003e\n    \u003csummary\u003e\u003ca href=\"#tuple\"\u003eTuple\u003c/a\u003e\u003c/summary\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#pair\"\u003ePair\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#first\"\u003eFirst\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#second\"\u003eSecond\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#mapfirst\"\u003eMapFirst\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#mapsecond\"\u003eMapSecond\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003cul\u003e\n        \u003cli\u003e\n            \u003ca href=\"#mapboth\"\u003eMapBoth\u003c/a\u003e\n        \u003c/li\u003e\n    \u003c/ul\u003e\n  \u003c/details\u003e\n\n## The Why\n\nGo is an incredibly powerful and performant language that promotes quality and maintainability through its\nextensive standard library and emphasis on simplicity. Sometimes however, it can be tricky to express certain\nfunctional patterns in an immutable and reusable fashion that is both concise and elegant.\n\nElm is a statically and strongly typed language with an approachable syntax that provides exceptional programming ergonomics.\nElm programs are delightful to write and maintain, largely due to the expressiveness one can harness from its functional\nprogramming style.\n\nThe scion-tools goal is to give Gophers an expressive functional approach by providing pure Go analogues of Elm's\ncore library, including its immutable data structures.\n\nIt's just Go that looks a little bit like Elm.\n\n[Back to top](#table-of-content)\n\n## The when\n\nWith scion-tools, Gophers have the ability to leverage functional programming techniques that harmonize with Go's idiomatic\npatterns that we all know and love. It's encouraged you dip in and out of this functional approach when it makes sense to.\n\nThe following scenarios provide some good uses cases where you may benefit from using scion-tools\nor other functional programming packages that are similar:\n\n- Function composition\n- Tail-Call Optimization\n- Immutability and persistence\n- Sorted maps\n- Error handling\n- Code reusability\n\n[Back to top](#table-of-content)\n\n# Basics\n\n```go\nimport \"github.com/Confidenceman02/scion-tools/pkg/basics\"\n```\n\nTons of useful functions.\n\n## Int\n\nA wrapped Go `int`.\n\n```go\ntype Int int\n```\n\n[Back to top](#table-of-content)\n\n## Float\n\nA wrapped Go `float32`.\n\n```go\ntype Float float32\n```\n\n[Back to top](#table-of-content)\n\n## Number\n\nA type alias for [Int](#int) and [Float](#float)\n\n```go\ntype Number interface {\n  Int | Float\n}\n```\n\n[Back to top](#table-of-content)\n\n## Comparable\n\nA special type that represents all types that can be compared:\n\n- [Number](#number)\n- [String](#string)\n- [Char](#char)\n- [List](#list) of Comparable\n- [Tuple](#tuple) of Comparable\n\n[Back to top](#table-of-content)\n\n## Add\n\n`func Add[T Number](a, b T) T`\n\nAdd two numbers. The number type variable means this operation can be specialized to any [Number](#number) type.\n\n```go\nvar n1 Int = 20\nvar n2 Int = 11\n\nAdd(n1, n2) // 31\n```\n\n[Back to top](#table-of-content)\n\n## Sub\n\n`func Sub[T Number](a, b T) T`\n\nSubtract numbers.\n\n```go\nvar n1 Int = 4\nvar n2 Int = 3\n\nSub(n1, n2) // 1\n```\n\n[Back to top](#table-of-content)\n\n## Fdiv\n\n`func Fdiv(a Float, b Float) Float`\n\nFloating-point division:\n\n```go\nvar n1 Float = 10\nvar n2 Float = 4\nvar n3 Float = -1\n\nFdiv(n1, n2) // 2.5\nFdiv(n3, n2) // -0.25\n```\n\n[Back to top](#table-of-content)\n\n## Mul\n\n`func Mul[T Number](a, b T) T`\n\nMultiply numbers.\n\n```go\nvar n1 Int = 2\nvar n2 Int = 6\n\nMul(n1, n2) // 6\n```\n\n[Back to top](#table-of-content)\n\n## ToFloat\n\n`func ToFloat[T Int](x T) Float`\n\nToFloat - Convert an integer into a float. Useful when mixing Int and Float values.\n\n```go\n\nfunc halfOf(num Int) Float {\n  return ToFloat(number / 2)\n}\n```\n\n[Back to top](#table-of-content)\n\n## Round\n\n`func Round(x Float) Int`\n\nRound a number to the nearest integer.\n\n```go\n\nRound(1.0) // 1\nRound(1.2) // 1\nRound(1.5) // 2\nRound(1.8) // 2\nRound(-1.2) // -1\nRound(-1.5) // -1\nRound(-1.8) // -2\n```\n\n[Back to top](#table-of-content)\n\n## Floor\n\n`func Floor(x Float) Int`\n\nFloor function, rounding down.\n\n```go\n\nFloor(1.0) // 1\nFloor(1.2) // 1\nFloor(1.5) // 1\nFloor(1.8) // 1\nFloor(-1.2) // -2\nFloor(-1.5) // -2\nFloor(-1.8) // -2\n```\n\n[Back to top](#table-of-content)\n\n## Ceiling\n\n`func Ceiling(x Float) Int`\n\nCeiling function, rounding up.\n\n```go\n\nCeiling(1.0) // 1\nCeiling(1.2) // 2\nCeiling(1.5) // 2\nCeiling(1.8) // 2\nCeiling(-1.2) // -1\nCeiling(-1.5) // -1\nCeiling(-1.8) // -1\n```\n\n[Back to top](#table-of-content)\n\n## Truncate\n\n`func Truncate(x Float) Int`\n\nTruncate a number, rounding towards zero\n\n```go\n\nTruncate(1.0) // 1\nTruncate(1.2) // 1\nTruncate(1.5) // 1\nTruncate(1.8) // 1\nTruncate(-1.2) // -1\nTruncate(-1.5) // -1\nTruncate(-1.8) // -1\n```\n\n[Back to top](#table-of-content)\n\n## Eq\n\n`func Eq[T any](x, y T) bool`\n\nCheck if values are structurally \u0026ldquo;the same\u0026rdquo;.\n\n```go\nvar arg1 List[string] = FromSlice([]string{\"a\", \"b\"}))\nvar arg2 List[string] = FromSlice([]string{\"a\", \"b\"}))\n\nEq(arg1, arg2) // true\n```\n\n[Back to top](#table-of-content)\n\n## Lt\n\n`func Lt[T Comparable[T]](x T, y T) bool`\n\n(\u003c)\n\n```go\nvar arg1 String = String(\"123\")\nvar arg2 String = String(\"456\")\n\nLt(arg1, arg2) // true\n```\n\n## Gt\n\n`func Gt[T Comparable[T]](x T, y T) bool`\n\n(\u003e)\n\n```go\nvar arg1 String = String(\"123\")\nvar arg2 String = String(\"456\")\n\nGt(arg1, arg2) // false\n```\n\n[Back to top](#table-of-content)\n\n## Le\n\n`func Le[T Comparable[T]](x T, y T) bool`\n\n(\u003c=)\n\n```go\nvar arg1 String = String(\"123\")\nvar arg2 String = String(\"456\")\n\nLe(arg1, arg2) // True\n```\n\n[Back to top](#table-of-content)\n\n## Ge\n\n`func Ge[T Comparable[T]](x T, y T) bool`\n\n(\u003e=)\n\n```go\nvar arg1 String = String(\"123\")\nvar arg2 String = String(\"456\")\n\nGe(arg1, arg2) // False\n```\n\n[Back to top](#table-of-content)\n\n## Max\n\n`func Max[T Comparable[T]](x T, y T) T`\n\nFind the larger of two comparables.\n\n```go\nMax(42,12345678) // 12345678\nMax(\"abc\",\"xyz\") // \"xyz\"\n```\n\n[Back to top](#table-of-content)\n\n## Min\n\n`func Min[T Comparable[T]](x T, y T) T`\n\nFind the smaller of two comparables.\n\n```go\nMin(42,12345678) // 42\nMin(\"abc\",\"xyz\") // \"abc\"\n```\n\n[Back to top](#table-of-content)\n\n## Compare\n\n`func Compare[T Comparable[T]](x T, y T) Order`\n\nCompare any two comparable values. Comparable values include String, Char,\nInt, Float, or a list or tuple containing comparable values. These are also the\nonly values that work as Dict keys or Set members.\n\n```go\n\nCompare (3,4) // LT\nCompare(4,4) // EQ\nCompare(5,4) // GT\n```\n\n[Back to top](#table-of-content)\n\n## Order\n\nRepresents the relative ordering of two things. The relations are less than, equal to,\nand greater than.\n\n```go\nLT{}\nEQ{}\nGT{}\n```\n\n[Back to top](#table-of-content)\n\n## Not\n\n`func Not(pred bool) bool`\n\nNegate a boolean value.\n\n```go\nnot(true) // false\nnot(false) // true\n```\n\n[Back to top](#table-of-content)\n\n## Append\n\n`func Append[T any](a Appendable[T], b Appendable[T]) Appendable[T]`\n\nPut two appendable things together. This includes strings and lists.\n\n```go\nAppend(String(\"hello\"), String(\"world\")) // \"helloworld\"\n```\n\n[Back to top](#table-of-content)\n\n## ModBy\n\n`func ModBy(modulus Int, x Int) Int`\n\nPerform arithmetic.\nA common trick is to use (n mod 2) to detect even and odd numbers:\n\n```go\nModBy(2,0) // 0\nModBy(2,1) // 1\nModBy(2,2) // 0\nModBy(2,3) // 1\n```\n\n[Back to top](#table-of-content)\n\n## Negate\n\n`func Negate[A Number](n A) A`\n\nNegate a number.\n\n```go\nNegate(42) // -42\nNegate(-42) // 42\nNegate(0) // 0\n```\n\n[Back to top](#table-of-content)\n\n## Sqrt\n\n`func Sqrt(n Float) Float`\n\nTake the square root of a number.\n\n```go\nSqrt(4) // 2\nSqrt(9) // 3\nSqrt(16) // 4\nSqrt(25) // 5\n```\n\n[Back to top](#table-of-content)\n\n## Identity\n\n`func Identity[A any](x A) A`\n\nGiven a value, returns exactly the same value. This is called the identity function.\n\n[Back to top](#table-of-content)\n\n## ComposeL\n\n`func ComposeL[A any, B any, C any](g func(B) C, f func(A) B) func(A) C`\n\nFunction composition, passing results along to the left direction.\n\n```go\nisEven := func(i Float) bool { return ModBy(2, Int(i)) == 0 }\ncomposed := ComposeL(isEven, Sqrt)\n\n\ncomposed(4) // true\ncomposed(3) // false\n```\n\n[Back to top](#table-of-content)\n\n# Bitwise\n\n```go\nimport \"github.com/Confidenceman02/scion-tools/pkg/bitwise\"\n```\n\nPackage for bitwise operations.\n\n## And\n\n`func And(a, b Int) Int`\n\nBitwise AND\n\n[Back to top](#table-of-content)\n\n## ShiftRightBy\n\n`func ShiftRightBy(offset Int, a Int) Int`\n\nShift bits to the right by a given offset, filling new bits with whatever is the topmost bit.\nThis can be used to divide numbers by powers of two.\n\n```go\nShiftRightBy(1,32) // 16\nShiftRightBy(2,32) // 8\nShiftRightBy(1,-32) // -16\n```\n\n[Back to top](#table-of-content)\n\n## ShiftLeftBy\n\n`func ShiftLeftBy(offset Int, a Int) Int`\n\nShift bits to the left by a given offset, filling new bits with zeros.\nThis can be used to multiply numbers by powers of two.\n\n```go\nShiftLeftBy(1, 5) // 10\nShiftLeftBy(5, 1) // 32\n```\n\n[Back to top](#table-of-content)\n\n# Char\n\n```go\nimport \"github.com/Confidenceman02/scion-tools/pkg/char\"\n```\n\nFunctions for working with runes. Rune literals are enclosed in 'a' pair of single quotes.\n\n## IsDigit\n\n`func IsDigit(c Char) bool`\n\nDetect digits 0123456789\n\n```go\nisDigit('0') // True\nisDigit('1') // True\nisDigit('9') // True\nisDigit('a') // False\nisDigit('b') // False\nisDigit('A') // False\n```\n\n[Back to top](#table-of-content)\n\n# Dict\n\n```go\nimport \"github.com/Confidenceman02/scion-tools/pkg/dict\"\n```\n\nA dictionary mapping unique keys to values. The keys can be any [Comparable](#comparable) type.\nThis includes Int, Float, Char, String, and tuples or lists of comparable types.\nInsert, remove, and query operations all take O(log n) time.\n\n## Empty\n\n`func Empty[K Comparable[K], V any]() Dict[K, V]`\n\nCreate an empty dictionary.\n\n```go\nEmpty()\n```\n\n[Back to top](#table-of-content)\n\n## Singleton(Dict)\n\n`func Singleton[K Comparable[K], V any](key K, value V) Dict[K, V]`\n\nCreate a dictionary with one key-value pair.\n\n```go\nSingleton(\"hello\", \"world\") // Dict[String,string]\n```\n\n[Back to top](#table-of-content)\n\n## Insert\n\n`func Insert[K Comparable[K], V any](key K, v V, d Dict[K, V]) Dict[K, V]`\n\nInsert a key-value pair into a dictionary. Replaces value when there is a collision.\n\n```go\nInsert(2, \"two\", Singleton(1,\"one\"))\n```\n\n[Back to top](#table-of-content)\n\n## Update\n\n`func Update[K Comparable[K], V any](targetKey K, f func(maybe.Maybe[V]) maybe.Maybe[V], d Dict[K, V]) Dict[K, V]`\n\nUpdate the value of a dictionary for a specific key with a given function.\n\n[Back to top](#table-of-content)\n\n## Remove\n\n`func Remove[K Comparable[K], V any](key K, d Dict[K, V]) Dict[K, V]`\n\nRemove a key-value pair from a dictionary. If the key is not found, no changes are made.\n\n```go\nRemove(1, Singleton(1,\"one\"))\n```\n\n[Back to top](#table-of-content)\n\n## IsEmpty\n\n`func IsEmpty[K Comparable[K], V any](d Dict[K, V]) bool`\n\nDetermine if a dictionary is empty.\n\n```go\nIsEmpty(Empty()) // true\n```\n\n[Back to top](#table-of-content)\n\n## Member(Dict)\n\n`func Member[K Comparable[K], V any](k K, d Dict[K, V]) bool`\n\nDetermine if a key is in a dictionary.\n\n```go\nMember(1, Singleton(1, \"one\")) // true\n```\n\n[Back to top](#table-of-content)\n\n## Get\n\n`func Get[K Comparable[K], V any](targetKey K, d Dict[K, V]) maybe.Maybe[V]`\n\nGet the value associated with a key.\nIf the key is not found, return [Nothing].\nThis is useful when you are not sure if a key will be in the dictionary.\n\n```go\nGet(1, Singleton(1, \"one\")) // Just \"one\"\n```\n\n[Back to top](#table-of-content)\n\n## Size\n\n`func Size[K Comparable[K], V any](d Dict[K, V]) Int`\n\nDetermine the number of key-value pairs in the dictionary.\n\n[Back to top](#table-of-content)\n\n## Keys\n\n`func Keys[K Comparable[K], V any](d Dict[K, V]) list.List[K]`\n\nGet all of the keys in a dictionary, sorted from lowest to highest.\n\n```go\nKeys(fromList([(0,\"Alice\"),(1,\"Bob\")])) == [0,1]\n```\n\n[Back to top](#table-of-content)\n\n## Values\n\n`func Values[K Comparable[K], V any](d Dict[K, V]) list.List[V]`\n\nGet all of the values in a dictionary, in the order of their keys.\n\n```go\nValues(fromList([(0,\"Alice\"),(1,\"Bob\")])) == [\"Alice\",\"Bob\"]\n```\n\n[Back to top](#table-of-content)\n\n## ToList\n\n`func ToList[K Comparable[K], V any](d Dict[K, V]) list.List[tuple.Tuple2[K, V]]`\n\nConvert a dictionary into an association list of key-value pairs, sorted by keys.\n\n[Back to top](#table-of-content)\n\n## FromList\n\n`func FromList[K Comparable[K], V any](l list.List[tuple.Tuple2[K, V]]) Dict[K, V]`\n\nConvert an association list into a dictionary.\n\n[Back to top](#table-of-content)\n\n## Map(Dict)\n\n`func Map[K Comparable[K], V, B any](f func(key K, value V) B, d Dict[K, V]) Dict[K, B]`\n\nApply a function to all values in a dictionary.\n\n[Back to top](#table-of-content)\n\n## Foldl(Dict)\n\n`func Foldl[K Comparable[K], V, B any](f func(K, V, B) B, acc B, d Dict[K, V]) B`\n\nFold over the key-value pairs in a dictionary from lowest key to highest key.\n\n[Back to top](#table-of-content)\n\n## Foldr(Dict)\n\n`func Foldr[K Comparable[K], V, B any](f func(K, V, B) B, acc B, d Dict[K, V]) B`\n\nFold over the key-value pairs in a dictionary from highest key to lowest key.\n\n[Back to top](#table-of-content)\n\n## Filter\n\n`func Filter[K Comparable[K], V any](isGood func(K, V) bool, d Dict[K, V]) Dict[K, V]`\n\nKeep only the key-value pairs that pass the given test.\n\n[Back to top](#table-of-content)\n\n## Partition\n\n`func Partition[K Comparable[K], V any](isGood func(K, V) bool, d Dict[K, V]) tuple.Tuple2[Dict[K, V], Dict[K, V]]`\n\nPartition a dictionary according to some test. The first dictionary\ncontains all key-value pairs which passed the test, and the second contains\nthe pairs that did not.\n\n[Back to top](#table-of-content)\n\n## Union\n\n`func Union[K Comparable[K], V any](t1 Dict[K, V], t2 Dict[K, V]) Dict[K, V]`\n\nCombine two dictionaries. If there is a collision, preference is given\nto the first dictionary.\n\n[Back to top](#table-of-content)\n\n## Intersect\n\n`func Intersect[K Comparable[K], V any](t1 Dict[K, V], t2 Dict[K, V]) Dict[K, V]`\n\nKeep a key-value pair when its key appears in the second dictionary.\nPreference is given to values in the first dictionary.\n\n[Back to top](#table-of-content)\n\n## Diff\n\n`func Diff[K Comparable[K], V any](t1 Dict[K, V], t2 Dict[K, V]) Dict[K, V]`\n\nKeep a key-value pair when its key does not appear in the second dictionary.\n\n[Back to top](#table-of-content)\n\n## Merge\n\n`func Merge[K Comparable[K], A, B, R any](\n\tleftStep func(K, A, R) R,\n\tbothStep func(K, A, B, R) R,\n\trightStep func(K, B, R) R,\n\tleftDict Dict[K, A],\n\trightDict Dict[K, B],\n\tinitialResult R,\n) R`\n\nThe most general way of combining two dictionaries. You provide three\naccumulators for when a given key appears:\n\n1. Only in the left dictionary.\n2. In both dictionaries.\n3. Only in the right dictionary.\n\nYou then traverse all the keys from lowest to highest, building up whatever\nyou want.\n\n[Back to top](#table-of-content)\n\n# List\n\n```go\nimport \"github.com/Confidenceman02/scion-tools/pkg/list\"\n```\n\nYou can create a `List` from any Go slice with the `FromSlice` function. This module has a bunch of functions to help you work with them!\n\n## FromSlice\n\n`func FromSlice[T any](arr []T) List[T]`\n\nCreate a [List](#list) from a Go slice.\n\n```go\nFromSlice([]int{1,2,3,4}) // [1,2,3,4]\n```\n\n[Back to top](#table-of-content)\n\n## FromSliceMap\n\n`func FromSliceMap[A any, B any](f func(A) B, arr []A) List[B]`\n\nCreate a [List](#list) from a Go slice applying a function to every element of the slice.\n\n```go\nFromSliceMap(func(i int) Int { return Int(i) },[]int{1,2,3,4}) // [1,2,3,4]\n```\n\n[Back to top](#table-of-content)\n\n## ToSlice\n\n`func ToSlice[T any](xs List[T]) []T`\n\nCreate a Go slice from a [List](#list).\n\n```go\nToSlice([1,2,3,4]) // []int{1,2,3,4}\n```\n\n[Back to top](#table-of-content)\n\n## ToSliceMap\n\n`func ToSliceMap[A any, B any](f func(A) B, xs List[A]) []B`\n\nCreate a Go slice from a [List](#list) applying a function to every element of the list.\n\n```go\nToSliceMap(func(i Int) int { return i.T() },[1,2,3,4]) // []int{1,2,3,4}\n```\n\n[Back to top](#table-of-content)\n\n## Empty\n\n`func Empty[T any]() List[T]`\n\nCreate a list with no elements.\n\n```go\nEmpty[int]() // []\n```\n\n[Back to top](#table-of-content)\n\n## Singleton(List)\n\n`func Singleton[T any](val T) List[T]`\n\nCreate a list with only one element.\n\n```go\nSingleton(1234) // [1234]\n```\n\n[Back to top](#table-of-content)\n\n## Repeat\n\n`func Repeat[T any](n basics.Int, val T) List[T]`\n\nCreate a list with _n_ copies of a value.\n\n```go\nRepeat(3,1) // [1,1,1]\n```\n\n[Back to top](#table-of-content)\n\n## Range\n\n`func Range(low basics.Int, hi basics.Int) List[basics.Int]`\n\nCreate a list of numbers, every element increasing by one. You give the lowest and highest number that should be in the list.\n\n```go\nRange(3,6) // [3, 4, 5, 6]\nRange(3,3) // [3]\nRange(6,3) // []\n```\n\n[Back to top](#table-of-content)\n\n## Cons\n\n`func Cons[T any](val T, l List[T]) List[T]`\n\nAdd an element to the front of a list.\n\n```go\nCons(1,Singleton(2)) // [1,2]\nCons(1,Empty())      // [1]\n```\n\n[Back to top](#table-of-content)\n\n## Map(List)\n\n`func Map[A, B any](f func(A) B, xs List[A]) List[B]`\n\nApply a function to every element of a list.\n\n```go\nMap(Sqrt, [1,4,9])          // [1,2,3]\nMap(Not, [true,false,true]) // [false,true,false]\n```\n\n[Back to top](#table-of-content)\n\n## IndexedMap\n\n`func IndexedMap[A, B any](f func(basics.Int, A) B, xs List[A]) List[B]`\n\nSame as map but the function is also applied to the index of each element (starting at zero).\n\n```go\nIndexedMap(tuple.Pair, [\"Tom\",\"Sue\",\"Bob\"]) // [(0,\"Tom\"),(1,\"Sue\"),(2,\"Bob\")]\n```\n\n[Back to top](#table-of-content)\n\n## Foldl\n\n`func Foldl[A, B any](f func(A, B) B, acc B, ls List[A]) B`\n\nReduce a list from the left.\n\n```go\nFoldl(Cons,Empty[int](), [1,2,3]) // [3,2,1]\n```\n\n[Back to top](#table-of-content)\n\n## Foldr\n\n`func Foldr[A, B any](fn func(A, B) B, acc B, ls List[A]) B`\n\nReduce a list from the right.\n\n```go\nFoldr(Cons,Empty(),[1,2,3]) == [1,2,3]\n```\n\n[Back to top](#table-of-content)\n\n## Filter\n\n`func Filter[T any](isGood func(T) bool, list List[T]) List[T]`\n\nKeep elements that satisfy the test.\n\n```go\nFilter(isEven, [1,2,3,4,5,6]) // [2,4,6]\n```\n\n[Back to top](#table-of-content)\n\n## FilterMap\n\n`func FilterMap[A, B any](f func(A) maybe.Maybe[B], xs List[A]) List[B]`\n\nFilter out certain values. For example, maybe you have a bunch of strings from an\nuntrusted source and you want to turn them into numbers:\n\n```go\nfunc numbers() List[Int] {\n  return FilterMap(ToInt, [\"3\",\"hi\",\"12\",\"4th\",\"May\"])\n}\n\n// numbers == [3, 12]\n```\n\n[Back to top](#table-of-content)\n\n## Length\n\n`func Length[T any](ls List[T]) basics.Int`\n\nDetermine the length of a list.\n\n```go\nLength([1,2,3]) // 3\n```\n\n[Back to top](#table-of-content)\n\n## Reverse(List)\n\n`func Reverse[T any](ls List[T]) List[T]`\n\nReverse a list.\n\n```go\nReverse([1,2,3,4]) // [4,3,2,1]\n```\n\n[Back to top](#table-of-content)\n\n## Member(List)\n\n`func Member[T any](val T, l List[T]) bool`\n\nFigure out whether a list contains a value.\n\n```go\nMember(9, [1,2,3,4]) // false\n```\n\n[Back to top](#table-of-content)\n\n## All\n\n`func All[T any](isOkay func(T) bool, l List[T]) bool`\n\nDetermine if all elements satisfy some test.\n\n```go\nAll(isEven, [2,4]) // true\n```\n\n[Back to top](#table-of-content)\n\n## Any\n\n`func Any[T any](isOkay func(T) bool, l List[T]) bool`\n\nDetermine if any elements satisfy some test.\n\n```go\nAny(isEven, [2,3]) // true\n```\n\n[Back to top](#table-of-content)\n\n## Maximum\n\n`func Maximum[T basics.Comparable[T]](xs List[T]) maybe.Maybe[T]`\n\nFind the maximum element in a non-empty list.\n\n```go\nMaximum([1,4,2]) == Just 4\n```\n\n[Back to top](#table-of-content)\n\n## Minimum\n\n`func Minimum[T basics.Comparable[T]](xs List[T]) maybe.Maybe[T]`\n\nFind the minimum element in a non-empty list.\n\n```go\nMinimum([1,4,2]) == Just 1\n```\n\n[Back to top](#table-of-content)\n\n## Sum\n\n`func Sum[T basics.Number](xs List[T]) T`\n\nGet the sum of the list elements.\n\n```go\nSum([1,2,3]) // 6\n```\n\n[Back to top](#table-of-content)\n\n## Product\n\n`func Product[T basics.Number](xs List[T]) T`\n\nGet the product of the list elements.\n\n```go\nProduct([2,2,2]) == 8\n```\n\n[Back to top](#table-of-content)\n\n## Append\n\n`func Append[T any](xs List[T], ys List[T]) List[T]`\n\nPut two lists together.\n\n```go\nAppend(['a','b'], ['c']) // ['a','b','c']\n```\n\n[Back to top](#table-of-content)\n\n## Concat\n\n`func Concat[T any](lists List[List[T]]) List[T]`\n\nConcatenate a bunch of lists into a single list:\n\n```go\nConcat([[1,2], [3], [4,5]]) // [1,2,3,4,5]\n```\n\n[Back to top](#table-of-content)\n\n## Intersperse\n\n`func Intersperse[T any](sep T, xs List[T]) List[T]`\n\nPlaces the given value between all members of the given list.\n\n```go\nIntersperse(\"on\",[\"turtles\",\"turtles\",\"turtles\"]) // [\"turtles\",\"on\",\"turtles\",\"on\",\"turtles\"]\n```\n\n[Back to top](#table-of-content)\n\n## Map2\n\n`func Map2[A, B, result any](f func(A, B) result, xs List[A], ys List[B]) List[result]`\n\nCombine two lists, combining them with the given function.\nIf one list is longer, the extra elements are dropped.\n\n[Back to top](#table-of-content)\n\n## Map3\n\n`func Map3[A, B, C, result any](f func(A, B, C) result, xs List[A], ys List[B], zs List[C]) List[result]`\n\n[Back to top](#table-of-content)\n\n## Map4\n\n`func Map4[A, B, C, D, result any](f func(A, B, C, D) result, xs List[A], ys List[B], zs List[C], ws List[D]) List[result]`\n\n[Back to top](#table-of-content)\n\n## Map5\n\n`func Map5[A, B, C, D, E, result any](f func(A, B, C, D, E) result, vs List[A], ws List[B], xs List[C], ys List[D], zs List[E]) List[result]`\n\n[Back to top](#table-of-content)\n\n## Sort\n\n`func Sort[T any](xs List[basics.Comparable[T]]) List[basics.Comparable[T]]`\n\nSort values from lowest to highest.\n\n```go\nSort([3,1,5]) == [1,3,5]\n```\n\n[Back to top](#table-of-content)\n\n## SortBy\n\n`func SortBy[A any](f func(A) basics.Comparable[A], xs List[A]) List[A]`\n\nSort values by a derived property.\n\n```go\nSortBy(String.length,[\"mouse\",\"cat\"]) // [\"cat\",\"mouse\"]\n```\n\n[Back to top](#table-of-content)\n\n## SortWith\n\n`func SortWith[A any](f func(a A, b A) basics.Order, xs List[A]) List[A]`\n\nSort values with a custom comparison function.\n\n[Back to top](#table-of-content)\n\n## IsEmpty\n\n`func IsEmpty[T any](l List[T]) bool`\n\nDetermine if a list is empty.\n\n```go\nIsEmpty([]) // True\n```\n\n[Back to top](#table-of-content)\n\n## Head\n\n`func Head[T any](l List[T]) maybe.Maybe[T]`\n\nExtract the first element of a list.\n\n```go\nHead([1,2,3]) // Just 1\n```\n\n[Back to top](#table-of-content)\n\n## Tail\n\n`func Tail[T any](l List[T]) maybe.Maybe[List[T]]`\n\nExtract the rest of the list.\n\n```go\nTail([1,2,3]) // Just [2,3]\n```\n\n[Back to top](#table-of-content)\n\n## Take\n\n`func Take[T any](n basics.Int, list List[T]) List[T]`\n\nTake the first n members of a list.\n\n```go\nTake(2,[1,2,3,4]) == [1,2]\n```\n\n[Back to top](#table-of-content)\n\n## Drop\n\n`func Drop[T any](n basics.Int, list List[T]) List[T]`\n\nDrop the first n members of a list.\n\n```go\nDrop(2,[1,2,3,4]) == [3,4]\n```\n\n[Back to top](#table-of-content)\n\n## Partition\n\n`func Partition[A any](pred func(A) bool, list List[A]) Tuple2[List[A], List[A]]`\n\n// Partition a list based on some test. The first list contains all values\n// that satisfy the test, and the second list contains all the value that do not.\n\n```go\nPartition(isEven,[0,1,2,3,4,5]) // ([0,2,4], [1,3,5])\n```\n\n[Back to top](#table-of-content)\n\n## Unzip\n\n`func Unzip[A, B any](pairs List[Tuple2[A, B]]) Tuple2[List[A], List[B]]`\n\nDecompose a list of tuples into a tuple of lists.\n\n```go\nUnzip([(0, true),(17,false),(1337,true)]) // ([0,17,1337], [true,false,true])\n```\n\n[Back to top](#table-of-content)\n\n# Maybe\n\n```go\nimport \"github.com/Confidenceman02/scion-tools/pkg/maybe\"\n```\n\nRepresent values that may or may not exist. It can be useful if you have a record field\nthat is only filled in sometimes. Or if a function takes a value sometimes, but does\nnot absolutely need it.\n\n```go\ntype Just[A any]\ntype Nothing\n```\n\n## WithDefault\n\n`func WithDefault[A any](a A, m Maybe[A]) A`\n\nProvide a default value, turning an optional value into a normal value.\nThis comes in handy when paired with functions like [Dict.Get](#get) which gives back a Maybe.\n\n```go\nWithDefault(100,Just[int]{42}) // 42\n```\n\n[Back to top](#table-of-content)\n\n## Map(Maybe)\n\n`func Map[A, B any](f func(A) B, m Maybe[A]) Maybe[B]`\n\nTransform a Maybe value with a given function:\n\n```go\nMap(Sqrt,(Just[Int]{9})) // Just 3\n```\n\n[Back to top](#table-of-content)\n\n## Map2\n\n`func Map2[A, B, value any](f func(a A, b B) value, m1 Maybe[A], m2 Maybe[B]) Maybe[value]`\n\nApply a function if all the arguments are Just a value.\n\n```go\nMap2(Add,Just[Int]{3}, Just[Int]{4}) // Just 7\n```\n\n[Back to top](#table-of-content)\n\n## Map3\n\n`func Map3[A, B, C, value any](f func(a A, b B, c C) value, m1 Maybe[A], m2 Maybe[B], m3 Maybe[C]) Maybe[value]`\n\n[Back to top](#table-of-content)\n\n## Map4\n\n`func Map4[A, B, C, D, value any](f func(a A, b B, c C, d D) value, m1 Maybe[A], m2 Maybe[B], m3 Maybe[C], m4 Maybe[D]) Maybe[value]`\n\n[Back to top](#table-of-content)\n\n## Map5\n\n`func Map5[A, B, C, D, E, value any](f func(a A, b B, c C, d D, e E) value, m1 Maybe[A], m2 Maybe[B], m3 Maybe[C], m4 Maybe[D], m5 Maybe[E]) Maybe[value]`\n\n[Back to top](#table-of-content)\n\n## AndThen\n\n`func AndThen[A, B any](f func(A) Maybe[B], m Maybe[A]) Maybe[B]`\n\nChain together many computations that may fail.\n\n[Back to top](#table-of-content)\n\n## MaybeWith\n\n`func MaybeWith[V, R any](m Maybe[V],j func(Just[V]) R,n func(Nothing) R) R`\n\nProvide functions for a Maybe's Just and Nothing variants\n\n[Back to top](#table-of-content)\n\n# Set\n\n```go\nimport \"github.com/Confidenceman02/scion-tools/pkg/set\"\n```\n\nA set of unique values. The values can be any comparable type.\nThis includes Int, Float, Char, String, and tuples or lists of comparable types.\nInsert, remove, and query operations all take O(log n) time.\n\n## Empty(Set)\n\n`func Empty[K Comparable[K]]() Set[K]`\n\nCreate an empty set.\n\n[Back to top](#table-of-content)\n\n## Singleton(Set)\n\n`func Singleton[K Comparable[K]](v K) Set[K]`\n\nCreate a set with one value.\n\n[Back to top](#table-of-content)\n\n## Insert(Set)\n\n`func Insert[K Comparable[K]](k K, s Set[K]) Set[K]`\n\nInsert a value into a set.\n\n[Back to top](#table-of-content)\n\n## Remove(Set)\n\n`func Remove[K Comparable[K]](k K, s Set[K]) Set[K]`\n\nRemove a value from a set. If the value is not found, no changes are made.\n\n[Back to top](#table-of-content)\n\n## IsEmpty(Set)\n\n`func IsEmpty[K Comparable[K]](s Set[K]) bool`\n\nDetermine if a set is empty.\n\n[Back to top](#table-of-content)\n\n## Member(Set)\n\n`func Member[K Comparable[K]](k K, s Set[K]) bool`\n\nDetermine if a value is in a set.\n\n[Back to top](#table-of-content)\n\n## Size(Set)\n\n`func Size[K Comparable[K]](s Set[K]) Int`\n\nDetermine the number of elements in a set.\n\n[Back to top](#table-of-content)\n\n## Union(Set)\n\n`func Union[K Comparable[K]](s1 Set[K], s2 Set[K]) Set[K]`\n\nGet the union of two sets. Keep all values.\n\n[Back to top](#table-of-content)\n\n## Intersect(Set)\n\n`func Intersect[K Comparable[K]](s1 Set[K], s2 Set[K]) Set[K]`\n\nGet the intersection of two sets. Keeps values that appear in both sets.\n\n[Back to top](#table-of-content)\n\n## Diff(Set)\n\n`func Diff[K Comparable[K]](s1 Set[K], s2 Set[K]) Set[K]`\n\nGet the difference between the first set and the second. Keeps values that do not appear in the second set.\n\n[Back to top](#table-of-content)\n\n## ToList(Set)\n\n`func ToList[K Comparable[K]](s Set[K]) list.List[K]`\n\nConvert a set into a list, sorted from lowest to highest.\n\n[Back to top](#table-of-content)\n\n## FromList(Set)\n\n`func FromList[K Comparable[K]](xs list.List[K]) Set[K]`\n\nConvert a list into a set, removing any duplicates.\n\n[Back to top](#table-of-content)\n\n## Map(Set)\n\n`func Map[A Comparable[A], B Comparable[B]](f func(A) B, s Set[A]) Set[B]`\n\nMap a function onto a set, creating a new set with no duplicates.\n\n[Back to top](#table-of-content)\n\n## Foldl(Set)\n\n`func Foldl[A Comparable[A], B any](f func(A, B) B, initialState B, s Set[A]) B`\n\nFold over the values in a set, in order from lowest to highest.\n\n[Back to top](#table-of-content)\n\n## Foldr(Set)\n\n`func Foldr[A Comparable[A], B any](f func(A, B) B, initialState B, s Set[A]) B`\n\nFold over the values in a set, in order from highest to lowest.\n\n[Back to top](#table-of-content)\n\n## Filter(Set)\n\n`func Filter[A Comparable[A]](isGood func(A) bool, s Set[A]) Set[A]`\n\nOnly keep elements that pass the given test.\n\n[Back to top](#table-of-content)\n\n## Partition(Set)\n\n`func Partition[A Comparable[A]](isGood func(A) bool, s Set[A]) tuple.Tuple2[Set[A], Set[A]]`\n\nCreate two new sets. The first contains all the elements that passed the\ngiven test, and the second contains all the elements that did not.\n\n[Back to top](#table-of-content)\n\n# Result\n\n```go\nimport \"github.com/Confidenceman02/scion-tools/pkg/result\"\n```\n\nA Result is the result of a computation that may fail. This is a great way to manage errors.\n\n## ResultWith\n\n`func ResultWith[E, V, R any](\n\tr Result[E, V],\n\terr func(Err[E, V]) R,\n\tok func(Ok[E, V]) R) R`\n\n## Map(Result)\n\n`func Map[X, A, V any](f func(A) V, ra Result[X, A]) Result[X, V]`\n\nApply a function to a result. If the result is Ok, it will be converted. If the result is an Err, the same error value will propagate through.\n\n```go\nMap(sqrt, (Ok[String, Float]{Val: 4.0}))          // Ok 2.0\nMap(sqrt, (Err[String, Float]{Err: \"bad input\"})) // Err \"bad input\"\n```\n\n[Back to top](#table-of-content)\n\n## Map2(Result)\n\n`func Map2[X, A, B, value any](f func(A, B) value, ra Result[X, A], rb Result[X, B]) Result[X, value]`\n\nApply a function if both results are Ok. If not, the first Err will propagate through.\n\n```go\nMap2(max, Ok[String, Int]{42}, Ok[String, Int]{13})   // Ok 42\nMap2(max, Err[String, Int]{\"x\"} Ok[String, Int]{13})  // Err \"x\"\nMap2(max, Ok[String, Int]{42} Err[String, Int]{\"y\"})  // Err \"y\"\nMap2(max, Err[String, Int]{\"x\"} Err[String, Int]{\"y\"} // Err \"x\"\n```\n\n[Back to top](#table-of-content)\n\n## Map3(Result)\n\n`func Map3[X, A, B, C, value any](\n\tf func(A, B, C) value,\n\tra Result[X, A],\n\trb Result[X, B],\n\trc Result[X, C],\n) Result[X, value]`\n\n[Back to top](#table-of-content)\n\n## Map4(Result)\n\n`func Map4[X, A, B, C, D, value any](\n\tf func(A, B, C, D) value,\n\tra Result[X, A],\n\trb Result[X, B],\n\trc Result[X, C],\n\trd Result[X, D],\n) Result[X, value]`\n\n[Back to top](#table-of-content)\n\n## Map5(Result)\n\n`func Map5[X, A, B, C, D, E, value any](\n\tf func(A, B, C, D, E) value,\n\tra Result[X, A],\n\trb Result[X, B],\n\trc Result[X, C],\n\trd Result[X, D],\n\tre Result[X, E],\n) Result[X, value]`\n\n[Back to top](#table-of-content)\n\n## AndThen(Result)\n\n`func AndThen[X, A, B any](f func(A) Result[X, B], r Result[X, A]) Result[X, B]`\n\nChain together a sequence of computations that may fail.\n\n[Back to top](#table-of-content)\n\n## WithDefault\n\n`func WithDefault[E, V any](r Result[E, V], defaultValue V) V`\n\nIf the result is Ok return the value, but if the result is an Err then return a given default value.\n\n[Back to top](#table-of-content)\n\n## ToMaybe\n\n`func ToMaybe[E, V any](r Result[E, V]) maybe.Maybe[V]`\n\nConvert to a simpler Maybe if the actual error message is not needed or you need to interact with some code that primarily uses maybes.\n\n[Back to top](#table-of-content)\n\n## FromMaybe\n\n`func FromMaybe[X, V any](e X, m maybe.Maybe[V]) Result[X, V]`\n\nConvert from a simple Maybe to interact with some code that primarily uses Results.\n\n[Back to top](#table-of-content)\n\n## MapError\n\n`func MapError[X, Y, V any](f func(X) Y, r Result[X, V]) Result[Y, V]`\n\nTransform an Err value. For example, say the errors we get have too much information:\n\n[Back to top](#table-of-content)\n\n# String\n\n```go\nimport \"github.com/Confidenceman02/scion-tools/pkg/string\"\n```\n\nA built-in representation for efficient string manipulation.\nThe String type is a wrapper for Go's `string`.\n\n```go\ntype String string\n```\n\n## IsEmpty(String)\n\n`func IsEmpty(x String) bool`\n\nDetermine if a string is empty.\n\n```go\nIsEmpty(\"\") // true\n```\n\n[Back to top](#table-of-content)\n\n## Length(String)\n\n`func Length(x String) basics.Int`\n\nGet the length of a string.\n\n```go\nLength(\"innumerable\") // 11\n```\n\n[Back to top](#table-of-content)\n\n## Reverse(String)\n\n`func Reverse(x String) String`\n\nReverse a string.\n\n```go\nReverse(\"stressed\") // \"desserts\"\n```\n\n[Back to top](#table-of-content)\n\n## Repeat(String)\n\n`func Repeat(n basics.Int, chunk String) String`\n\nRepeat a string n times.\n\n```go\nRepeat(3,\"ha\") // \"hahaha\"\n```\n\n[Back to top](#table-of-content)\n\n## Replace\n\n`func Replace(before String, after String, str String) String`\n\nReplace all occurrences of some substring.\n\n```go\nReplace(\",\",\"/\",\"a,b,c,d,e\")           == \"a/b/c/d/e\"\n```\n\n[Back to top](#table-of-content)\n\n## Append\n\n`func Append(x String, y String) String`\n\nAppend two strings. You can also use basics.Append to do this.\n\n```go\nAppend(\"butter\",\"fly\") // \"butterfly\"\n```\n\n[Back to top](#table-of-content)\n\n## Concat\n\n`func Concat(chunks list.List[String]) String`\n\nConcatenate many strings into one.\n\n```go\nConcat([\"never\",\"the\",\"less\"] ) // \"nevertheless\"\n```\n\n[Back to top](#table-of-content)\n\n## ConcatMap\n\n`func ConcatMap[A, B any](f func(A) List[B], list List[A]) List[B]`\n\nMap a given function onto a list and flatten the resulting lists.\n\n[Back to top](#table-of-content)\n\n## Split\n\n`func Split(sep String, s String) list.List[String]`\n\nSplit a string using a given separator.\n\n```go\nSplit(\",\",\"cat,dog,cow\") // [\"cat\",\"dog\",\"cow\"]\n```\n\n[Back to top](#table-of-content)\n\n## Join\n\n`func Join(sep String, chunks list.List[String]) String`\n\nPut many strings together with a given separator.\n\n```go\nJoin(\"a\",[\"H\",\"w\",\"ii\",\"n\"]) // \"Hawaiian\"\n```\n\n[Back to top](#table-of-content)\n\n## Words\n\n`func Words(str String) list.List[String]`\n\nBreak a string into words, splitting on chunks of whitespace.\n\n```go\nWords(\"How are \\t you? \\n Good?\") // [\"How\",\"are\",\"you?\",\"Good?\"]\n```\n\n[Back to top](#table-of-content)\n\n## Lines\n\n`func Lines(str String) list.List[String]`\n\nBreak a string into lines, splitting on newlines.\n\n```go\nLines(\"How are you?\\nGood?\") // [\"How are you?\", \"Good?\"]\n```\n\n[Back to top](#table-of-content)\n\n## Slice\n\n`func Slice(start basics.Int, end basics.Int, str String) String`\n\nTake a substring given a start and end index. Negative indexes are taken starting from the end of the list.\n\n```go\nSlice(7,9,\"snakes on a plane!\") // \"on\"\n```\n\n[Back to top](#table-of-content)\n\n## Left\n\n`func Left(n basics.Int, str String) String`\n\nTake _n_ characters from the left side of a string.\n\n```go\nLeft(2,\"Mulder\") // \"Mu\"\n```\n\n[Back to top](#table-of-content)\n\n## Right\n\n`func Right(n basics.Int, str String) String`\n\nTake _n_ characters from the right side of a string.\n\n```go\nRight(2,\"Scully\") // \"ly\"\n```\n\n[Back to top](#table-of-content)\n\n## DropLeft\n\n`func DropLeft(n basics.Int, str String) String`\n\nDrop _n_ characters from the left side of a string.\n\n```go\nDropLeft(2,\"The Lone Gunmen\") // \"e Lone Gunmen\"\n```\n\n[Back to top](#table-of-content)\n\n## DropRight\n\n`func DropRight(n basics.Int, str String) String`\n\nDrop _n_ characters from the right side of a string.\n\n```go\nDropRight(2,\"Cigarette Smoking Man\") // \"Cigarette Smoking M\"\n```\n\n[Back to top](#table-of-content)\n\n## Contains\n\n`func Contains(sub String, str String) bool`\n\nSee if the second string contains the first one.\n\n```go\nContains(\"the\",\"theory\") // true\n```\n\n[Back to top](#table-of-content)\n\n## StartsWith\n\n`func StartsWith(sub String, str String) bool`\n\nSee if the second string starts with the first one.\n\n```go\nStartsWith(\"the\",\"theory\") // true\n```\n\n[Back to top](#table-of-content)\n\n## EndsWith\n\n`func EndsWith(sub String, str String) bool`\n\nSee if the second string ends with the first one.\n\n```go\nEndsWith(\"the\",\"theory\") // false\n```\n\n[Back to top](#table-of-content)\n\n## Indexes\n\n`func Indexes(sub String, str String) list.List[basics.Int]`\n\nGet all of the indexes for a substring in another string.\n\n```go\nIndexes(\"i\",\"Mississippi\") // [1,4,7,10]\n```\n\n[Back to top](#table-of-content)\n\n## Indices\n\n`func Indices(sub String, str String) list.List[basics.Int]`\n\nAlias for `indexes`.\n\n```go\nIndexes(\"i\",\"Mississippi\") // [1,4,7,10]\n```\n\n[Back to top](#table-of-content)\n\n## ToInt\n\n`func ToInt(x String) maybe.Maybe[basics.Int]`\n\nTry to convert a string into an int, failing on improperly formatted strings.\n\n```go\nToInt(\"123\") // Just 123\n```\n\n[Back to top](#table-of-content)\n\n## FromInt\n\n`func FromInt(x basics.Int) String`\n\nConvert an Int to a String.\n\n```go\nFromInt(123) // \"123\"\n```\n\n[Back to top](#table-of-content)\n\n## ToFloat\n\n`func ToFloat(x String) maybe.Maybe[basics.Float]`\n\nTry to convert a string into a float, failing on improperly formatted strings.\n\n```go\nToFloat(\"123\") // Just 123.0\n```\n\n[Back to top](#table-of-content)\n\n## FromFloat\n\n`func FromFloat(x basics.Float) String`\n\nConvert a Float to a String.\n\n```go\nFromFloat(123) // \"123\"\n```\n\n[Back to top](#table-of-content)\n\n## FromChar\n\n`func FromChar(char char.Char) String`\n\nCreate a string from a given character.\n\n```go\nFromFloat(123) // \"123\"\n```\n\n[Back to top](#table-of-content)\n\n## Cons(String)\n\n`func Cons(char char.Char, str String) String`\n\nAdd a character to the beginning of a string.\n\n```go\nCons('T',\"he truth is out there\") // \"The truth is out there\"\n```\n\n[Back to top](#table-of-content)\n\n## Uncons\n\n`func Uncons(str String) maybe.Maybe[tuple.Tuple2[char.Char, String]]`\n\nSplit a non-empty string into its head and tail. This lets you pattern match on strings exactly as you would with lists.\n\n```go\nUncons(\"abc\") // Just ('a',\"bc\")\n```\n\n[Back to top](#table-of-content)\n\n## ToList\n\n`func ToList(str String) list.List[char.Char]`\n\nConvert a string to a list of characters.\n\n```go\nToList(\"abc\") // ['a','b','c']\n```\n\n[Back to top](#table-of-content)\n\n## FromList\n\n`func FromList(chars list.List[char.Char]) String`\n\nConvert a list of characters into a String. Can be useful if you want to create a string primarily by consing, perhaps for decoding something.\n\n```go\nFromList(['a','b','c']) // \"abc\"\n```\n\n[Back to top](#table-of-content)\n\n## ToUpper\n\n`func ToUpper(str String) String`\n\nConvert a string to all upper case. Useful for case-insensitive comparisons and VIRTUAL YELLING.\n\n```go\nToUpper(\"skinner\") // \"SKINNER\"\n```\n\n[Back to top](#table-of-content)\n\n## ToLower\n\n`func ToLower(str String) String {`\n\nConvert a string to all lower case. Useful for case-insensitive comparisons.\n\n```go\nToLower(\"X-FILES\") // \"x-files\"\n```\n\n[Back to top](#table-of-content)\n\n## Pad\n\n`func Pad(n basics.Int, char char.Char, str String) String`\n\nPad a string on both sides until it has a given length.\n\n```go\nPad(5,' ',\"1\" ) == \"  1  \"\n```\n\n[Back to top](#table-of-content)\n\n## PadLeft\n\n`func PadLeft(n basics.Int, char char.Char, str String) String {`\n\nPad a string on the left until it has a given length.\n\n```go\nPadLeft(5,'.',\"1\") == \"....1\"\n```\n\n[Back to top](#table-of-content)\n\n## PadRight\n\n`func PadRight(n basics.Int, char char.Char, str String) String`\n\nPad a string on the right until it has a given length.\n\n```go\nPadRight(5,'.',\"1\") // \"1....\"\n```\n\n[Back to top](#table-of-content)\n\n## Trim\n\n`func Trim(str String) String`\n\nGet rid of whitespace on both sides of a string.\n\n```go\nTrim(\"  hats  \\n\") // \"hats\"\n```\n\n[Back to top](#table-of-content)\n\n## TrimLeft\n\n`func TrimLeft(str String) String`\n\nGet rid of whitespace on the left of a string.\n\n```go\nTrimLeft(\"  hats  \\n\") // \"hats  \\n\"\n```\n\n[Back to top](#table-of-content)\n\n## TrimRight\n\n`func TrimRight(str String) String`\n\nGet rid of whitespace on the right of a string.\n\n```go\nTrimRight(\"  hats  \\n\") // \"  hats\"\n```\n\n[Back to top](#table-of-content)\n\n## Map(String)\n\n`func Map(f func(char.Char) char.Char, str String) String`\n\nTransform every character in a string\n\n[Back to top](#table-of-content)\n\n## Filter\n\n`func Filter(isGood func(char.Char) bool, str String) String`\n\nKeep only the characters that pass the test.\n\n```go\nFilter(IsDigit,\"R2-D2\") // \"22\"\n```\n\n[Back to top](#table-of-content)\n\n## Foldl(String)\n\n`func Foldl[B any](f func(char.Char, B) B, state B, str String) B`\n\nReduce a string from the left.\n\n```go\nFoldl(Cons,\"\",\"time\") // \"emit\"\n```\n\n[Back to top](#table-of-content)\n\n## Foldr(String)\n\n`func Foldr[B any](f func(char.Char, B) B, state B, str String) B`\n\nReduce a string from the right.\n\n```go\nFoldr(cons,\"\",\"time\") // \"time\"\n```\n\n[Back to top](#table-of-content)\n\n## Any(String)\n\n`func Any(isGood func(char.Char) bool, str String) bool`\n\nDetermine whether any characters pass the test.\n\n```go\nAny(IsDigit,\"90210\") // true\n```\n\n[Back to top](#table-of-content)\n\n## All(String)\n\n`func All(isGood func(char.Char) bool, str String) bool`\n\nDetermine whether all characters pass the test.\n\n```go\nAll(IsDigit,\"90210\") == true\n```\n\n[Back to top](#table-of-content)\n\n# Tuple\n\n```go\nimport \"github.com/Confidenceman02/scion-tools/pkg/tuple\"\n```\n\nThis package is a bunch of helpers for working with 2-tuples.\n\n## Pair\n\n`func Pair[A, B any](a A, b B) Tuple2[A, B]`\n\nCreate a 2-tuple.\n\n```go\nPair(3,4) // (3,4)\n```\n\n[Back to top](#table-of-content)\n\n## First\n\n`func First[A, B any](t Tuple2[A, B]) A`\n\nExtract the first value from a tuple.\n\n```go\nFirst((3,4)) // 3\n```\n\n[Back to top](#table-of-content)\n\n## Second\n\n`func Second[A, B any](t Tuple2[A, B]) B`\n\nExtract the second value from a tuple.\n\n```go\nSecond((3, 4)) // 4\n```\n\n[Back to top](#table-of-content)\n\n## MapFirst\n\n`func MapFirst[A, B, C any](f func(A) B, t Tuple2[A, C]) Tuple2[B, C]`\n\nTransform the first value in a tuple.\n\n```go\nMapFirst(string.reverse,(\"stressed\", 16)) // (\"desserts\", 16)\n```\n\n[Back to top](#table-of-content)\n\n## MapSecond\n\n`func MapSecond[A, B, C any](f func(B) A, t Tuple2[C, B]) Tuple2[C, A]`\n\nTransform the second value in a tuple.\n\n```go\nMapSecond(Sqrt,(\"stressed\", 16)) // (\"stressed\", 4)\n```\n\n[Back to top](#table-of-content)\n\n## MapBoth\n\n`func MapBoth[A, B, C, D any](f func(A) C, g func(B) D, t Tuple2[A, B]) Tuple2[C, D]`\n\nTransform both parts of a tuple.\n\n```go\nMapBoth(string.reverse,Sqrt,(\"stressed\", 16)) // (\"desserts\", 4)\n```\n\n[Back to top](#table-of-content)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FConfidenceman02%2Fscion-tools","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FConfidenceman02%2Fscion-tools","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FConfidenceman02%2Fscion-tools/lists"}