learnxinyminutes-docs/purescript.html.markdown

213 lines
5.8 KiB
Markdown
Raw Normal View History

2014-09-01 01:26:56 +04:00
---
language: purescript
2017-08-25 11:16:44 +03:00
filename: purescript.purs
2014-09-01 01:26:56 +04:00
contributors:
- ["Fredrik Dyrkell", "http://www.lexicallyscoped.com"]
- ["Thimoteus", "https://github.com/Thimoteus"]
2014-09-01 01:26:56 +04:00
---
PureScript is a small strongly, statically typed language compiling to Javascript.
* Learn more at [http://www.purescript.org/](http://www.purescript.org/)
* Documentation: [http://pursuit.purescript.org/](http://pursuit.purescript.org/)
2014-09-01 01:26:56 +04:00
* Book: Purescript by Example, [https://leanpub.com/purescript/](https://leanpub.com/purescript/)
All the noncommented lines of code can be run in the PSCI REPL, though some will
require the `--multi-line-mode` flag.
```haskell
2014-09-01 01:26:56 +04:00
--
-- 1. Primitive datatypes that corresponds to their Javascript
-- equivalents at runtime.
import Prelude
2014-09-01 01:26:56 +04:00
-- Numbers
1.0 + 7.2*5.5 :: Number -- 40.6
-- Ints
1 + 2*5 :: Int -- 11
2014-09-01 01:26:56 +04:00
-- Types are inferred, so the following works fine
9.0/2.5 + 4.4 -- 8.0
-- But Ints and Numbers don't mix, so the following won't
5/2 + 2.5 -- Expression 2.5 does not have type Int
2014-09-01 01:26:56 +04:00
-- Hexadecimal literals
0xff + 1 -- 256
2014-09-01 01:26:56 +04:00
-- Unary negation
6 * -3 -- -18
6 * negate 3 -- -18
-- Modulus, from purescript-math (Math)
3.0 % 2.0 -- 1.0
4.0 % 2.0 -- 0.0
2014-09-01 01:26:56 +04:00
-- Inspect the type of an expression in psci
:t 9.5/2.5 + 4.4 -- Prim.Number
2014-09-01 01:26:56 +04:00
-- Booleans
true :: Boolean -- true
false :: Boolean -- false
2014-09-01 01:26:56 +04:00
-- Negation
not true -- false
23 == 23 -- true
1 /= 4 -- true
1 >= 4 -- false
-- Comparisons < <= > >=
2014-09-01 01:26:56 +04:00
-- are defined in terms of compare
compare 1 2 -- LT
compare 2 2 -- EQ
compare 3 2 -- GT
2014-09-01 01:26:56 +04:00
-- Conjunction and Disjunction
true && (9 >= 19 || 1 < 2) -- true
2014-09-01 01:26:56 +04:00
-- Strings
"Hellow" :: String -- "Hellow"
-- Multiline string without newlines, to run in psci use the --multi-line-mode flag
"Hellow\
2014-09-01 01:26:56 +04:00
\orld" -- "Helloworld"
-- Multiline string with newlines
"""Hello
world""" -- "Hello\nworld"
2014-09-01 01:26:56 +04:00
-- Concatenate
"such " <> "amaze" -- "such amaze"
2014-09-01 01:26:56 +04:00
--
-- 2. Arrays are Javascript arrays, but must be homogeneous
[1,1,2,3,5,8] :: Array Int -- [1,1,2,3,5,8]
[1.2,2.0,3.14] :: Array Number -- [1.2,2.0,3.14]
[true, true, false] :: Array Boolean -- [true,true,false]
2014-09-01 01:26:56 +04:00
-- [1,2, true, "false"] won't work
-- `Cannot unify Prim.Int with Prim.Boolean`
2014-09-01 01:26:56 +04:00
-- Cons (prepend)
1 : [2,4,3] -- [1,2,4,3]
2014-09-01 01:26:56 +04:00
-- Requires purescript-arrays (Data.Array)
-- and purescript-maybe (Data.Maybe)
-- Safe access return Maybe a
head [1,2,3] -- Just (1)
tail [3,2,1] -- Just ([2,1])
init [1,2,3] -- Just ([1,2])
last [3,2,1] -- Just (1)
2016-12-14 21:59:16 +03:00
-- Array access - indexing
[3,4,5,6,7] !! 2 -- Just (5)
2015-10-08 06:11:24 +03:00
-- Range
1..5 -- [1,2,3,4,5]
length [2,2,2] -- 3
drop 3 [5,4,3,2,1] -- [2,1]
take 3 [5,4,3,2,1] -- [5,4,3]
append [1,2,3] [4,5,6] -- [1,2,3,4,5,6]
2014-09-01 01:26:56 +04:00
--
-- 3. Records are Javascript objects, with zero or more fields, which
-- can have different types.
-- In psci you have to write `let` in front of the function to get a
-- top level binding.
let book = {title: "Foucault's pendulum", author: "Umberto Eco"}
2014-09-01 01:26:56 +04:00
-- Access properties
book.title -- "Foucault's pendulum"
2014-09-01 01:26:56 +04:00
let getTitle b = b.title
2014-09-01 01:26:56 +04:00
-- Works on all records with a title (but doesn't require any other field)
getTitle book -- "Foucault's pendulum"
getTitle {title: "Weekend in Monaco", artist: "The Rippingtons"} -- "Weekend in Monaco"
-- Can use underscores as shorthand
_.title book -- "Foucault's pendulum"
2014-09-01 01:26:56 +04:00
-- Update a record
let changeTitle b t = b {title = t}
getTitle (changeTitle book "Ill nome della rosa") -- "Ill nome della rosa"
2014-09-01 01:26:56 +04:00
--
-- 4. Functions
-- In psci's multiline mode
let sumOfSquares :: Int -> Int -> Int
sumOfSquares x y = x*x + y*y
sumOfSquares 3 4 -- 25
let myMod x y = x % y
myMod 3.0 2.0 -- 1.0
2014-09-01 01:26:56 +04:00
-- Infix application of function
3 `mod` 2 -- 1
2014-09-01 01:26:56 +04:00
-- function application has higher precedence than all other
2014-09-01 01:26:56 +04:00
-- operators
sumOfSquares 3 4 * sumOfSquares 4 5 -- 1025
2014-09-01 01:26:56 +04:00
-- Conditional
let abs' n = if n>=0 then n else -n
abs' (-3) -- 3
2014-09-01 01:26:56 +04:00
-- Guarded equations
let abs'' n | n >= 0 = n
| otherwise = -n
2014-09-01 01:26:56 +04:00
-- Pattern matching
-- Note the type signature, input is a list of numbers. The pattern matching
-- destructures and binds the list into parts.
-- Requires purescript-lists (Data.List)
let first :: forall a. List a -> a
first (Cons x _) = x
first (toList [3,4,5]) -- 3
let second :: forall a. List a -> a
second (Cons _ (Cons y _)) = y
second (toList [3,4,5]) -- 4
let sumTwo :: List Int -> List Int
sumTwo (Cons x (Cons y rest)) = x + y : rest
fromList (sumTwo (toList [2,3,4,5,6])) :: Array Int -- [5,4,5,6]
-- sumTwo doesn't handle when the list is empty or there's only one element in
-- which case you get an error.
2014-09-01 01:26:56 +04:00
sumTwo [1] -- Failed pattern match
-- Complementing patterns to match
-- Good ol' Fibonacci
let fib 1 = 1
fib 2 = 2
fib x = fib (x-1) + fib (x-2)
fib 10 -- 89
2014-09-01 01:26:56 +04:00
-- Use underscore to match any, where you don't care about the binding name
let isZero 0 = true
isZero _ = false
2014-09-01 01:26:56 +04:00
-- Pattern matching on records
let ecoTitle {author = "Umberto Eco", title = t} = Just t
ecoTitle _ = Nothing
2014-09-01 01:26:56 +04:00
ecoTitle book -- Just ("Foucault's pendulum")
ecoTitle {title: "The Quantum Thief", author: "Hannu Rajaniemi"} -- Nothing
2014-09-01 01:26:56 +04:00
-- ecoTitle requires both field to type check:
ecoTitle {title: "The Quantum Thief"} -- Object lacks required property "author"
2014-09-01 01:26:56 +04:00
-- Lambda expressions
(\x -> x*x) 3 -- 9
(\x y -> x*x + y*y) 4 5 -- 41
let sqr = \x -> x*x
2014-09-01 01:26:56 +04:00
-- Currying
let myAdd x y = x + y -- is equivalent with
let myAdd' = \x -> \y -> x + y
let add3 = myAdd 3
:t add3 -- Prim.Int -> Prim.Int
2014-09-01 01:26:56 +04:00
-- Forward and backward function composition
-- drop 3 followed by taking 5
(drop 3 >>> take 5) (1..20) -- [4,5,6,7,8]
2014-09-01 01:26:56 +04:00
-- take 5 followed by dropping 3
(drop 3 <<< take 5) (1..20) -- [4,5]
2014-09-01 01:26:56 +04:00
-- Operations using higher order functions
let even x = x `mod` 2 == 0
filter even (1..10) -- [2,4,6,8,10]
map (\x -> x + 11) (1..5) -- [12,13,14,15,16]
2014-09-01 01:26:56 +04:00
2016-02-26 01:30:35 +03:00
-- Requires purescript-foldable-traversable (Data.Foldable)
2014-09-01 01:26:56 +04:00
foldr (+) 0 (1..10) -- 55
sum (1..10) -- 55
product (1..10) -- 3628800
2014-09-01 01:26:56 +04:00
2015-10-08 06:11:24 +03:00
-- Testing with predicate
any even [1,2,3] -- true
all even [1,2,3] -- false
2014-09-01 01:26:56 +04:00
```