title | author | patat | ||||||
---|---|---|---|---|---|---|---|---|
M02 - PureScript Foundations |
Walker Leite |
|
In this module we will introduce you to PureScript language, and we'll play in Try PureScript.
To run this presentation type (you will need nix):
../../slide README.md
- LovelaceAcademy Discord
- StackExchange (:bulb: use the tag lovelace-academy)
- Plutonomicon Discord
- A programming language
- Although not essential, being familiar with a language will be beneficial in understanding the in-depth content of this course;
- Knowing JavaScript and HTML will be beneficial;
- Functional programming paradigm
- Although not essential, it will help in the understanding of the in-depth content of this course;
- We need to build smart contracts
- We need to run smart contracts on the front-end
- We need to integrate with other tools (wallets, libraries, and more)
- Haskell (GHCJS)
- JavaScript
- TypeSCript
- Elm or Reason
- PureScript
- Compile to readable JavaScript
- Similar Haskell/Plutus syntax (learn once, use twice)
- Same Haskell purity
- purs-nix
- Cardano-Transaction-Lib
entity_name :: Optional Type Signature
entity_name = definition
💡 We use types to allow the compiler to test the function application (usage) and throw errors when something unexpected is being passed.
module Main where
import Prelude
import Effect.Console (log)
adult :: Int
adult = 18
age :: Int -> String
age n = if n >= adult then "you're an adult" else "you're a child"
main = log (age 19)
If we pass wrong parameters the compiler will throw:
main = log (age "18")
Could not match type
String
with type
Int
while checking that type String
is at least as general as type Int
while checking that expression "18"
has type Int
in value declaration main
💡 It helps to read this error message from bottom-up
module Main where
import Prelude
import Data.String (length)
import Effect.Console (log)
mkQuestion :: String -> Char -> String
mkQuestion "abcD" 'D' = "congrats, your answer is correct"
mkQuestion "abCd" 'C' = "congrats, your answer is correct"
mkQuestion "aBcd" 'B' = "congrats, your answer is correct"
mkQuestion "Abcd" 'A' = "congrats, your answer is correct"
mkQuestion s 'A' | length s > 4 = "your question should have 4 alternatives"
mkQuestion _ _ = "sorry, your answer is incorrect"
evaluateQ1 :: Char -> String
evaluateQ1 = mkQuestion "abCd"
evaluateQ2 :: Char -> String
evaluateQ2 = mkQuestion "aBcdf"
-- ignore do for a moment, we'll introduce it later
main = do
log (evaluateQ1 'C')
log (evaluateQ2 'A')
log (mkQuestion "Abcd" 'B')
How we create custom types?
module Main where
import Prelude
import Effect.Console (log)
-- read | as or
data Animal = Cat String | Dog String
-- append :: String -> String -> String
talk :: Animal -> String
talk (Dog name) = append "Hello, I am the dog " name
talk (Cat name) = append "Hello, I am the cat " name
dog :: Animal
dog = Dog "max"
main = do
log (talk dog)
log (talk (Cat "kitty"))
What if I need to identify animals by Char
or String
?
module Main where
import Prelude
import Effect.Console (log)
import Data.String.CodeUnits (singleton)
data ID = CharID Char | StringID String
data Animal a = Cat a | Dog a
-- singleton :: Char -> String
merge :: String -> ID -> String
merge str (CharID char) = append str (singleton char)
merge str (StringID str') = append str str'
talk :: Animal ID -> String
talk (Dog id) = merge "Hello, I am the dog " id
talk (Cat id) = merge "Hello, I am the cat " id
dog :: Animal ID
dog = Dog (StringID "max")
cat :: Animal ID
cat = Cat (CharID 'A')
main = do
log (talk dog)
log (talk cat)
Pseudo-code:
box
wraps n into a string
box :: Int -> String
box 0 = "0"
the same way Box
type constructor wraps a
into a Box
data Box a = Box a
box :: Box Int
box = Box 3
so Box
type constructor is a function:
Box :: a -> Box a
You can also read Box
this way: I cannot give you a concrete type (e.g. BoxType Int
) until you tell me what a
is.
Kinds = "How many more types do I need defined before I have a 'concrete' type?" 😄
-- also known as "concrect type"
Char :: Type
data Char
-- also known as "high kinded type"
Box :: Type -> Type
data Box a = Box a
BoxOfTwo :: Type -> Type -> Type
data BoxOfTwo a b = BoxOfTwo a b
Tuple :: Type -> Type -> Type
data Tuple a b;
IntOther :: Type -> Type
IntOther b = Tuple Int b
IntAll :: Type
data IntAll = Tuple Int Int
What about Maybe (also known as Option in other languages), it represents nullable types.
Maybe :: Type -> Type
data Maybe a = Just a | Nothing
MaybeInt :: Type
data MaybeInt = Maybe Int
MaybeChar :: Type
data MaybeChar = Maybe Char