{"id":15362789,"url":"https://github.com/hemanth/haskell-rascal","last_synced_at":"2025-08-18T20:34:52.287Z","repository":{"id":15333112,"uuid":"18063524","full_name":"hemanth/haskell-rascal","owner":"hemanth","description":"Learning haskell with a rascal!","archived":false,"fork":false,"pushed_at":"2019-01-09T05:05:19.000Z","size":2114,"stargazers_count":13,"open_issues_count":0,"forks_count":2,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-03-28T18:50:51.449Z","etag":null,"topics":["haskell","programming-language"],"latest_commit_sha":null,"homepage":"https://git.io/haskell-rascal","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hemanth.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-03-24T13:32:20.000Z","updated_at":"2024-07-28T11:05:20.000Z","dependencies_parsed_at":"2022-08-30T12:11:25.464Z","dependency_job_id":null,"html_url":"https://github.com/hemanth/haskell-rascal","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hemanth%2Fhaskell-rascal","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hemanth%2Fhaskell-rascal/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hemanth%2Fhaskell-rascal/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hemanth%2Fhaskell-rascal/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hemanth","download_url":"https://codeload.github.com/hemanth/haskell-rascal/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249040181,"owners_count":21202830,"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":["haskell","programming-language"],"created_at":"2024-10-01T13:03:49.888Z","updated_at":"2025-04-15T09:21:22.448Z","avatar_url":"https://github.com/hemanth.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"![](https://raw.githubusercontent.com/hemanth/haskell-rascal/master/imgs/swahili.png)\n\n\u003e Learning Haskell with a rascal!\n\n__What the hell is haskell-rascal?__\n\nFirst of all, let me define rascal:\n\n\u003e a mischievous or cheeky person, especially a child or man (typically used in an affectionate way). \"a lovable rascal\"\n\nOk, now that you know what rascal means, let's learn some haskell!\n\n\u003eHaskell is an advanced purely-functional programming language. An open-source product of more than twenty years of cutting-edge research, it allows rapid development of robust, concise, correct software. With strong support for integration with other languages, built-in concurrency and parallelism, debuggers, profilers, rich libraries and an active community, Haskell makes it easier to produce flexible, maintainable, high-quality software. \n\n![](http://upload.wikimedia.org/wikipedia/commons/f/fd/Frank_Oppenheimer.jpg)\n\n__\"The best way to learn is to teach\" -- Frank Oppenheirmer__\n\n\nThis repo will remains W.I.P as a rascal learns haskell by teaching it!\n\n\n__Installation:__\n\nEasy way is to hit [haskell-platfrom](http://www.haskell.org/platform/), download the required binary, install it! \n\nP.S: If want to build from source paw [here](https://ghc.haskell.org/trac/ghc/wiki/Building/GettingTheSources)\n\n__CLI FTW:__\n\n```sh\n$ ghci\nGHCi, version 7.6.3: http://www.haskell.org/ghc/  :? for help\nLoading package ghc-prim ... linking ... done.\nLoading package integer-gmp ... linking ... done.\nLoading package base ... linking ... done.\nPrelude\u003e :set prompt \"haskell-rascal\u003e \"\nhaskell-rascal\u003e \n```\nP.S: You can as well add `:set prompt \"haskell-racal\u003e \"` to your `~/.ghci` file.\n\nIf you want to try it online, you must looks at [ghc.io](ghc.io) or [codeworld](http://codeworld.info/)\n\nNow you are all set to do some haskell with a rascal!\n\n---\n\n# Defining Haskell in a line\n\n\"It's a pure functional programming language which is statically typed and lazily evaluated!\"\n\nLet's break it down.\n\n__Pure functions:__ \n\nPure implies idempotency and functional programming is a one in which functions are first-class. \n\n__Statically typed:__\n\nA programming language is said to use static typing when type checking is performed during compile-time as opposed to run-time. \n\n__Lazy evaluation:__\n\nLazy evaluation is an evaluation strategy which delays the evaluation of an expression until its value is needed and which also avoids repeated evaluations.\n\n# Abstract syntactic and semantic structure.\n\n* Set of modules make a Haskell program at the top most level.\n\n* The top level of a module consists of a collection of declarations.\n\n* The the next lower level are expressions.\n\n* The bottom level is Haskell 's lexical structure.\n\nWe shall paw at each of them as we move on the next units of Haskell.\n\n# Simple Arithmetic and Boolean Algebra\n\n![](http://upload.wikimedia.org/wikipedia/commons/d/d8/Bring_radicals_cartoon.PNG)\n\nREPL is your friend :)\n\n```\nhaskell-rascal\u003e 0/0\nNaN\nhaskell-rascal\u003e 1/0\nInfinity\nhaskell-rascal\u003e 22 / 7\n3.142857142857143\nhaskell-rascal\u003e pi\n3.141592653589793\nhaskell-rascal\u003e ( 43 * 1 ) - 1\n42\n```\n\n`\u0026\u0026` =\u003e boolean and `||` =\u003e boolean or. `not` =\u003e negatation\n\n```\nhaskell-rascal\u003e not True \nFalse\nhaskell-rascal\u003e True || False\nTrue\nhaskell-rascal\u003e True \u0026\u0026 ( False \u0026\u0026 True )\nFalse\nhaskell-rascal\u003e not (True \u0026\u0026 ( False \u0026\u0026 True ))\nTrue\n```\n\n# Types and Type-classes\n\n`:type` aka `:t` is at your help.\n\n```\nhaskell-rascal\u003e :type True\nTrue :: Bool\nhaskell-rascal\u003e :t 1\n1 :: Num a =\u003e a\nhaskell-rascal\u003e :t 'H'\n'H' :: Char\nhaskell-rascal\u003e :t \"H\"\n\"H\" :: [Char]\nhaskell-rascal\u003e :t []\n[] :: [a]\n```\n---\n\n# Lists and tuples\n\nLists are a **homogenous** data structure, i.e it stores several elements of the same type.\n\nLet's see few examples:\n\n```\nhaskell-rascal\u003e [\"hemanth\",1,2]\n\n\u003cinteractive\u003e:5:12:\n    No instance for (Num [Char]) arising from the literal `1'\n    Possible fix: add an instance declaration for (Num [Char])\n    In the expression: 1\n    In the expression: [\"hemanth\", 1, 2]\n    In an equation for `it': it = [\"hemanth\", 1, 2]\n    \nhaskell-rascal\u003e [\"hemanth\",'h']\n\n\u003cinteractive\u003e:7:12:\n    Couldn't match expected type `[Char]' with actual type `Char'\n    In the expression: 'h'\n    In the expression: [\"hemanth\", 'h']\n    In an equation for `it': it = [\"hemanth\", 'h']\n\nhaskell-rascal\u003e ['h','e']\n\"he\"\n\nhaskell-rascal\u003e [1,2,3]\n[1,2,3]\n\nhaskell-rascal\u003e \"heman\" == ['h','m','a','n']\nFalse\n\nhaskell-rascal\u003e \"he\" == ['h','e']\nTrue\n```\n---\n\n__List functions:__\n\nList processing:\n  * (:) (list constructor)\n  * ++\n  * head\n  * last\n  * tail\n  * init\n  * length\n  * !! (list index)\n\nArithmetic Operations:\n  * div\n  * mod\n  * gcd\n  * lcm\n  * even\n  * odd\n  * sum\n  * product\n\nExtended list processing:\n  * maximum\n  * minimum\n  * reverse\n  * elem\n  * notElem\n  * concat\n  * take\n  * drop\n  * takeWhile\n  * dropWhile\n  * words\n  * unwords\n   \n```\nhaskell-rascal\u003e let nums = [1,3,3,7]\n\nhaskell-rascal\u003e length nums\n4\n\nhaskell-rascal\u003e reverse nums\n[7,3,3,1]\n\nhaskell-rascal\u003e head nums\n1\n\nhaskell-rascal\u003e last nums\n7\n\nhaskell-rascal\u003e init nums\n[1,3,3]\n\nhaskell-rascal\u003e nums !! 3 -- Get the element at the given index.\n7\n\nhaskell-rascal\u003e minimum nums\n1\n\nhaskell-rascal\u003e maximum nums \n7\n\nhaskell-rascal\u003e 0 : nums\n[0,1,3,3,7]\n\nhaskell-rascal\u003e nums ++ [-1]\n[1,3,3,7,-1]\n\nhaskell-rascal\u003e [1,3] ++ [3,7] \n[1,3,3,7]  \n\nhaskell-rascal\u003e take 3 nums\n[1,3,3]\n\nhaskell-rascal\u003e drop 1 nums\n[3,3,7]\n\nhaskell-rascal\u003e sum nums\n14\n\nhaskell-rascal\u003e product nums\n63\n\nhaskell-rascal\u003e 7 `elem` nums\nTrue\n\nhaskell-rascal\u003e 0 `elem` nums\nFalse\n\nhaskell-rascal\u003e ['a'..'z']\n\"abcdefghijklmnopqrstuvwxyz\"\n\nhaskell-rascal\u003e words \"May the force be with you\"\n[\"May\",\"the\",\"force\",\"be\",\"with\",\"you\"]\n\nhaskell-rascal\u003e unwords [\"haskell\",\"-\",\"rascal\"]\n\"haskell - rascal\"\n\nhaskell-rascal\u003e takeWhile (\u003c=7) [1..10]\n[1,2,3,4,5,6,7]\n\nhaskell-rascal\u003e dropWhile (\u003c=7) [1..10]\n[8,9,10]\n\n```\n---\n\nTuples unlike lists have a __fixed__ number of elements (immutable) and are heterogenous data structures. \n\n__Example:__\n\n```\nhaskell-rascal\u003e let co-ordinates = (70.1,80.1,\"L33t Area\")\n```\n\n__Tuple functions:__\n\n* fst\n* snd\n* curry\n* uncurry \n* swap \n\n```\nhaskell-rascal\u003e fst (True,\"1\")\nTrue\n\nhaskell-rascal\u003e snd (True,\"1\")\n\"1\"\n\nhaskell-rascal\u003e zip \"leet\" [1,3,3,7]\n[('l',1),('e',3),('e',3),('t',7)]\n\nhaskell-rascal\u003e unzip [('l',1),('e',3),('e',3),('t',7)]\n(\"leet\",[1,3,3,7])\n```\n---\n\n# Functions!\n\nBefore we dive into functions, it's worth to know the below:\n\n```\n-- By default:\nf g h x \u003c=\u003e (((f g) h) x)\n\n-- $ replace parenthesis.\nf g $ h x       \u003c=\u003e   f g (h x) ⇔ (f g) (h x)\nf $ g h x       \u003c=\u003e   f (g h x) ⇔ f ((g h) x)\nf $ g $ h x     \u003c=\u003e   f (g (h x))\n\n-- (.) composition.\n(f . g) x       \u003c=\u003e   f (g x)\n(f . g . h) x   \u003c=\u003e   f (g (h x))\n```\n\nLet's take a `fib` function as an example and try to understand function!\n\n```\nhaskell-rascal\u003e let fib = 0 : 1 : zipWith (+) fib (tail fib)\n\nhaskell-rascal\u003e take 10 fib\n[0,1,1,2,3,5,8,13,21,34]\n```\n\nBefore we procede further understanding the fib function, we must understand what [Thunks](http://en.wikipedia.org/wiki/Thunk_%28functional_programming%29)\nare.\n\nIn most of the programming langauges that supports tuples, saying `(4+2,7)` would be stored as `(6,7)` but in Haskell it gets stored as `(_,7)` where the `_` is the thunk value.\n\nLets explore the same in ghci:\n\n```haskell\nhaskell-rascal\u003e let x = (4+2,7)\n\nhaskell-rascal\u003e :print x\nx = ((_t1::Integer),7)\n```\n\nNotice that `_t1` is the thunk value here, now if we fetch the second element of that tuple, it will be 7, but the first element we **not** be evaluated yet!\n\n```haskell\nhaskell-racal\u003e snd x\n7\n\nhaskell-racal\u003e :print x\nx = ((_t2::Integer),7)\n```\n\nBut as soon as we fetch the first or just evaluate `x`, the first value will be evaluated.\n\n```\nhaskell-racal\u003e fst x\n6\n\nhaskell-racal\u003e x\n(6,7)\n```\n\nSo, a thunk is basically a value that has not yet been computed yet. \nAs per the need it can evaluate or partly-evaluated to a real value.\nPartial evaluation of a thunk will resulting in a value with more thunks in it.\n\nNow the above function can be expanded as:\n\n```haskell\nfibs                        = 0 : 1 : \u003cthunk\u003e\ntail fib                    = 1 : \u003cthunk\u003e\nzipWith (+) fib (tail fib)  = \u003cthunk\u003e\n```\n\nThe first row left shifted is the second row and the third row is the sum of \nthe first and the second rows and all of them are **sharing** the same thunk.\n\n`take 2 fibs` will give use `[0, 1]` which is direct and does not need further evaluation.\n\nNow if we say `take 3 fib` Haskell will directly get the 0 and 1, and then it will have to partly evaluate the thunk, so that it can fully evaluate `zipWith (+) fib (tail fib)`, by getting the sum of the first two rows but it can't fully do that, it can begin to sum the first two rows:\n\n```haskell\nfibs                         = 0 : 1 : 1: \u003cthunk\u003e\ntail fibs                    = 1 : 1 : \u003cthunk\u003e\nzipWith (+) fibs (tail fibs) = 1 : \u003cthunk\u003e\n```\n\nLikewise it keeps on going creating `\u003cthunk's\u003e` and eval them as and when the need arrives.\n\nP.S: If you says `fib n` and then `fib n-m` where `m\u003c=n` the expresion will not be re-evaled but will just take the first `n-m` numbers from the list it has already evaled!\n\n\nNow that we could eat and digest thunks, let start with simple functions ;)\n\n```haskell\nhaskell-rascal\u003e let square n = n * n;\nhaskell-rascal\u003e square 3\n9\n```\n\n```haskell\nhaskell-rascal\u003e :t square\nsquare :: Num a =\u003e a -\u003e a\n```\n\n^ Is the signature of a function.\n\nWondering what does `square :: Num a =\u003e a -\u003e a` means?\n\nLet us see few more example of the functions we have used already:\n\n```haskell\nhaskell-rascal\u003e :t fst\nfst :: (a, b) -\u003e a\n\nhaskell-rascal\u003e :t snd\nsnd :: (a, b) -\u003e b\n\nhaskell-rascal\u003e :t map\nmap :: (a -\u003e b) -\u003e [a] -\u003e [b]\n```\n\nThe combination of :: and the type after it is called a type signature. Say we did a `:t \"haskell\"` we would get `\"haskell\" :: [Char]` in this case it's indicating that `\"haskell\"` is of `[Char]` type.\n\nGeneralising: x :: y  =\u003e \"the expression x has the type y\".\n\n\n__Recurison:__\n\n[Recursion](https://encrypted.google.com/search?hl=en\u0026q=recursion) simply defined: A function invoking itself for a finite number of times before returning the result of computation. \n\nAs we had noticed in the above example of `fibs` here is a simple example of `factorial`\n\n```haskell\nhaskell-rascal\u003e let factorial n = if n \u003e 0 then n * factorial (n-1) else 1\n\nhaskell-rascal\u003e factorial (10)\n3628800\n```\n\n__λ abstraction A.K.A Anonymous function:__\n\nFunction without a name?! \n\nHow would I call it?\n\nLet's see a simple example to understand how they work and why are they important. \n\n```haskell\nhaskell-rascal\u003e let list = [0..4]\nhaskell-rascal\u003e let odds x = x + 1 \nhaskell-rascal\u003e map odds list\n[1,2,3,4,5]\n```\n\nThe above steps adds `1` to every element to the list, that's why the function is named `odds`, but why must even bother creating a function, naming it, after all it's just by map?\n\nWouldn't be useful if we could condense them all to one single line!?\n\nYes, that's where lamda abstractions are very useful, so with the help of it, we can rewrite the above code as below and yet get the same effect.\n\n```haskell\nhaskell-rascal\u003e map (\\x-\u003ex+1) list \n[1,2,3,4,5]\n```\n\n__Curring!__\n\n![](https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTBSYQprd6BTkERQcBQeQ45vGDalsAcneivFH-cYfnBnVUGZ5BA)\n\nNo, this has nothing to do with the above curry ;)\n\nCurrying here is the process of transforming a function which accepts multiple arguments into a function that takes just accepts a single argument and returns another function if any arguments are still needed.\n\n`f :: a -\u003e b -\u003e c` curried -\u003e `g :: (a, b) -\u003e c` \n\nAs a matter of fact, `currying` was of the gifts from [Haskell Brooks Curry\n](http://en.wikipedia.org/wiki/Haskell_Curry) while the initial concept of combinatory logic was based on a single paper by `Moses Schönfinkel`, much of the development was done by Curry.\n\n\n__Example:__\n\n```haskell\nhaskell-rascal\u003e let add n1 n2 = n1 + n2\n\nhaskell-rascal\u003e add 2 3\n\nhaskell-rascal\u003e (add 2) 3\n```\n\n__Function composition:__\n\nFunction composition is a mechanism of combining two or more functions to a single function.\n\nThe closest analogy to this would be pipes in shells piping.\n\n```sh\ncat fubar.txt | sort -n | less\n```\nHere the output of `cat` is feed to `sort` and it's output is feed to `less`.\n\nIn Mathametical terms: `(f ◦ g)(x) = f (g(x))`\n\n__Example:__\n\n```haskell\nhaskell-rascal\u003e let last = head . reverse\nhaskell-rascal\u003e last [1,2,42]\n42\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhemanth%2Fhaskell-rascal","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhemanth%2Fhaskell-rascal","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhemanth%2Fhaskell-rascal/lists"}