| title | M05 - Burritos Everywhere | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| author | Walker Leite | ||||||||||
| patat |
|
In this module we will see more fundamental type classes of PureScript and Haskell.
To run this presentation type (you will need nix):
../../slide README.md- LovelaceAcademy Discord
- StackExchange (:bulb: use the tag lovelace-academy)
- Plutonomicon Discord
- PureScript (modules 2-4)
Functor is a type class which enables map operations over some type
class Functor :: (Type -> Type) -> Constraint
class Functor f where
map :: forall a b. (a -> b) -> f a -> f b
infixl 4 map <$>So we can:
(+) 3 <$> Just 2
-- Just 5What happens when you map a function that receives more than one argument?
-- + :: Int -> Int -> Int
x = (+) <$> Just 3
-- ok: x = Just ((+) 3) :: Maybe (Int -> Int)
y = x ?? Just 2
-- ?? can't be <$> :: (a -> b) -> f a -> f b
-- what ?? would be to have: y = Just 5 :: Maybe Intclass Apply :: (Type -> Type) -> Constraint
class (Functor f) <= Apply f where
apply :: forall a b. f (a -> b) -> f a -> f b
infixl 4 apply <*>So we can:
x = (+) <$> Just 2
-- x = Just ((+) 3) :: Maybe (Int -> Int)
y = x <*> Just 3
-- y = Just 5 :: Maybe IntOr even:
(+) <$> Just 2 <*> Just 3
-- Just 5 :: Maybe IntYou can have any number of arguments:
foo = functionTakingNArguments <$> computationProducingArg1
<*> computationProducingArg2
<*> ...
<*> computationProducingArgN💡 nothing says that computations must happen sequentially, actually
Applyallows parallel computation and we'll see it in the future
What if you don't know the box type, eg:
x :: forall f. Apply f => f Int
x = (+) <$> ?? 2 <*> ?? 3
-- ?? would be :: Int -> f Intclass Applicative :: (Type -> Type) -> Constraint
class (Apply f) <= Applicative f where
pure :: forall a. a -> f aSo we can:
x :: forall f. Applicative f => f Int
x = (+) <$> pure 2 <*> pure 3
y :: Maybe Int
y = x
-- like magic: y = Just 5data Maybe a = Nothing | Just a
half x = case even x of
true -> Just (x `div` 2)
false -> Nothingdata Maybe a = Nothing | Just a
half :: Int -> Maybe Int
half x = case even x of
true -> Just (x `div` 2)
false -> Nothing> Just 3 >>= half
Nothing
> Just 4 >>= half
Just 2
> Nothing >>= half
Nothing
-- (>>=) :: f a -> (a -> f b) -> f bclass Bind :: (Type -> Type) -> Constraint
class (Apply m) <= Bind m where
bind :: forall a b. m a -> (a -> m b) -> m b
infixl 1 bind as >>=
instance Bind Maybe where
bind (Just x) fn = fn x
bind Nothing _ = Nothing> Just 20 >>= half >>= half >>= half
NothingPut simply Monad is Bind (>>=) + Applicative (pure):
class (Applicative m, Bind m) <= Monad mSo, as in Applicative, we can:
xs :: forall m. Monad m => m Int
xs = pure 20 >>= half
ys :: Maybe Int
ys = xs
ys :: Tuple String Int
ys = xs
-- Tuple bind works on the snd valueThe do notation is a syntax suggar for >>=:
module Main where
import Prelude (($), (>>=), (==), div, bind, show)
import Data.Maybe (Maybe(Nothing, Just))
import Data.Int (even)
import Effect.Console (log)
half x = case even x of
true -> Just (x `div` 2)
false -> Nothing
x = do
v <- Just 20
v' <- half v
half v'
-- translates to
y = Just 20 >>= \v -> half v >>= \v' -> half v'
-- which is the same of
z = Just 20 >>= half >>= half
main = log $ show [x, y, z]The Effect is a type without constructors that represent effects in the runtime.
data Effect aThe underlying ais the return type, it can be Unit to represent a non-returning Effect
module Main where
import Prelude (Unit, unit, pure)
import Effect (Effect)
import Effect.Console (log)
main :: Effect Unit
main = log "hello"
-- the side-effect in this case is logging in the console
module Main where
import Prelude (Unit, ($), (>>=), (<>), show)
import Effect (Effect)
import Effect.Console (log)
import Effect.Now (nowDate)
main :: Effect Unit
main = nowDate >>= \d -> log $ "the current date is " <> show dmodule Main where
import Prelude (Unit, ($), (>>=), (<>), (>>>), (<$>), (<*>), bind, pure, discard, show)
import Effect (Effect)
import Effect.Console (log)
import Effect.Now (nowDate, nowTime)
import Effect.Random (random)
showNowDate :: Effect String
showNowDate = do
d <- nowDate
pure $ "the current date is: " <> show d
showNowTime :: Effect String
showNowTime = (\d -> "the current date is: " <> show d) <$> nowTime
logRandom :: Effect Unit
logRandom = show >>> (<>) "here is a random number: " <$> random >>= log
main :: Effect Unit
main = do
showNowDate >>= log
showNowTime >>= log
logRandomPictures and examples from adit.io
In module 04 we've used buildTx to simulate a transaction build, in this module we'll simulate a Contract behavior using what we've learned so far.
type Validator = Redeemer -> ScriptContext -> Datum -> Boolean
data Contract a = Contract a
buildTx :: Inputs -> Outputs -> Redeemer -> Validator -> Contract Boolean
runContract :: forall a. Contract a -> Effect aChange previous created buildTx to return the value using the Contract monad and implement the missing definitions. runContract must log in the console the contract execution.








