PureScript is a small strongly, statically typed language compiling to JavaScript.
- Learn more at https://www.purescript.org/
- Documentation: https://pursuit.purescript.org/
- Book: Purescript by Example, https://book.purescript.org/
All the noncommented lines of code can be run in the PSCi REPL, though some
will require «paste» mode (:paste
followed by multiple lines, terminated by
^D).
1--
2-- 1. Primitive datatypes that corresponds to their JavaScript
3-- equivalents at runtime.
4
5import Prelude
6-- Numbers
71.0 + 7.2*5.5 :: Number -- 40.6
8-- Ints
91 + 2*5 :: Int -- 11
10-- Types are inferred, so the following works fine
119.0/2.5 + 4.4 -- 8.0
12-- But Ints and Numbers don't mix, so the following won't
135/2 + 2.5 -- Expression 2.5 does not have type Int
14-- Hexadecimal literals
150xff + 1 -- 256
16-- Unary negation
176 * -3 -- -18
186 * negate 3 -- -18
19-- Modulus, from purescript-math (Math)
203.0 % 2.0 -- 1.0
214.0 % 2.0 -- 0.0
22-- Inspect the type of an expression in psci
23:t 9.5/2.5 + 4.4 -- Number
24
25-- Booleans
26true :: Boolean -- true
27false :: Boolean -- false
28-- Negation
29not true -- false
3023 == 23 -- true
311 /= 4 -- true
321 >= 4 -- false
33-- Comparisons < <= > >=
34-- are defined in terms of compare
35compare 1 2 -- LT
36compare 2 2 -- EQ
37compare 3 2 -- GT
38-- Conjunction and Disjunction
39true && (9 >= 19 || 1 < 2) -- true
40
41-- Strings
42"Hello" :: String -- "Hello"
43-- Multiline string without newlines, to run in PSCi use "paste" mode.
44"Hello\
45\orld" -- "Helloworld"
46-- Multiline string with newlines
47"""Hello
48world""" -- "Hello\nworld"
49-- Concatenate
50"such " <> "amaze" -- "such amaze"
51
52--
53-- 2. Arrays are JavaScript arrays, but must be homogeneous
54
55[1,1,2,3,5,8] :: Array Int -- [1,1,2,3,5,8]
56[1.2,2.0,3.14] :: Array Number -- [1.2,2.0,3.14]
57[true, true, false] :: Array Boolean -- [true,true,false]
58-- [1,2, true, "false"] won't work
59-- `Cannot unify Int with Boolean`
60
61-- Requires purescript-arrays (Data.Array)
62-- Cons (prepend)
631 : [2,4,3] -- [1,2,4,3]
64
65-- and purescript-maybe (Data.Maybe)
66-- Safe access return Maybe a
67head [1,2,3] -- (Just 1)
68tail [3,2,1] -- (Just [2,1])
69init [1,2,3] -- (Just [1,2])
70last [3,2,1] -- (Just 1)
71-- Array access - indexing
72[3,4,5,6,7] !! 2 -- (Just 5)
73-- Range
741..5 -- [1,2,3,4,5]
75length [2,2,2] -- 3
76drop 3 [5,4,3,2,1] -- [2,1]
77take 3 [5,4,3,2,1] -- [5,4,3]
78append [1,2,3] [4,5,6] -- [1,2,3,4,5,6]
79
80--
81-- 3. Records are JavaScript objects, with zero or more fields, which
82-- can have different types.
83book = {title: "Foucault's pendulum", author: "Umberto Eco"}
84-- Access properties
85book.title -- "Foucault's pendulum"
86
87getTitle b = b.title
88-- Works on all records with a title (but doesn't require any other field)
89getTitle book -- "Foucault's pendulum"
90getTitle {title: "Weekend in Monaco", artist: "The Rippingtons"} -- "Weekend in Monaco"
91-- Can use underscores as shorthand
92_.title book -- "Foucault's pendulum"
93-- Update a record
94changeTitle b t = b {title = t}
95getTitle (changeTitle book "Ill nome della rosa") -- "Ill nome della rosa"
96
97--
98-- 4. Functions
99-- In PSCi's paste mode
100sumOfSquares :: Int -> Int -> Int
101sumOfSquares x y = x*x + y*y
102sumOfSquares 3 4 -- 25
103
104myMod x y = x % y
105myMod 3.0 2.0 -- 1.0
106-- Infix application of function
1073 `mod` 2 -- 1
108
109-- function application has higher precedence than all other
110-- operators
111sumOfSquares 3 4 * sumOfSquares 4 5 -- 1025
112
113-- Conditional
114abs' n = if n>=0 then n else -n
115abs' (-3) -- 3
116
117-- Guarded equations
118-- In PSCi's paste mode
119abs'' n | n >= 0 = n
120 | otherwise = -n
121
122-- Pattern matching
123
124-- Note the type signature, input is a list of numbers. The pattern matching
125-- destructures and binds the list into parts.
126-- Requires purescript-lists (Data.List) and purescript-maybe (Data.Maybe)
127first :: forall a. List a -> Maybe a
128first (x : _) = Just x
129first Nil = Nothing
130first (fromFoldable [3,4,5]) -- (Just 3)
131
132second :: forall a. List a -> Maybe a
133second Nil = Nothing
134second (_ : Nil) = Nothing
135second (_ : (y : _)) = Just y
136second (fromFoldable [3,4,5]) -- (Just 4)
137
138-- Complementing patterns to match
139-- Good ol' Fibonacci
140fib 1 = 1
141fib 2 = 2
142fib x = fib (x-1) + fib (x-2)
143fib 10 -- 89
144
145-- Use underscore to match any, where you don't care about the binding name
146isZero 0 = true
147isZero _ = false
148isZero 9 -- false
149
150-- Pattern matching on records
151ecoTitle {author: "Umberto Eco", title: t} = Just t
152ecoTitle _ = Nothing
153
154ecoTitle {title: "Foucault's pendulum", author: "Umberto Eco"} -- (Just "Foucault's pendulum")
155ecoTitle {title: "The Quantum Thief", author: "Hannu Rajaniemi"} -- Nothing
156-- ecoTitle requires both field to type check:
157ecoTitle {title: "The Quantum Thief"} -- Object lacks required property "author"
158
159-- Lambda expressions
160(\x -> x*x) 3 -- 9
161(\x y -> x*x + y*y) 4 5 -- 41
162sqr = \x -> x*x
163
164-- Currying
165myAdd x y = x + y -- is equivalent with
166myAdd' = \x -> \y -> x + y
167add3 = myAdd 3
168:t add3 -- Int -> Int
169
170-- Forward and backward function composition
171-- drop 3 followed by taking 5
172(drop 3 >>> take 5) (1..20) -- [4,5,6,7,8]
173-- take 5 followed by dropping 3
174(drop 3 <<< take 5) (1..20) -- [4,5]
175
176-- Operations using higher order functions
177even x = x `mod` 2 == 0
178filter even (1..10) -- [2,4,6,8,10]
179map (\x -> x + 11) (1..5) -- [12,13,14,15,16]
180
181-- Requires purescript-foldable-traversable (Data.Foldable)
182
183foldr (+) 0 (1..10) -- 55
184sum (1..10) -- 55
185product (1..10) -- 3628800
186
187-- Testing with predicate
188any even [1,2,3] -- true
189all even [1,2,3] -- false