This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// functors are computational contexts around values | |
// or, you could say they are boxes around values | |
// one instance of a functor is Maybe | |
// say you have a function that might return a value or undefined | |
function possiblyAValue() { | |
return Math.floor((Math.random() * 2)) === 0 ? undefined : { hey: { iAm: 'A value!' } } | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- our bank functions | |
deposit :: Int -> State [Transaction] () | |
deposit amount = modify (\transactions -> transactions ++ [Deposit amount]) | |
withdraw :: Int -> State [Transaction] () | |
withdraw amount = modify (\transactions -> transactions ++ [Withdrawal amount]) | |
getStatement :: State [Transaction] String | |
getStatement = gets generateStatement -- the details of generateStatement are out of scope of this post |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
printStatement :: State [Transaction] () | |
printStatement = do | |
transactions <- get | |
let statement = generateStatement transactions | |
putStr statement |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
printStatement :: StateT [Transaction] IO () | |
printStatement = do | |
transactions <- get | |
let statement = generateStatement transactions | |
lift (putStr statement) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
lift :: m a -> t m a | |
-- more concretely for our use case | |
lift :: IO () -> StateT [Transaction] IO () |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
main = do | |
runStateT useMyBank [] | |
pure () - we need to return IO () for main | |
useMyBank :: StateT [Transaction] IO () | |
useMyBank = do | |
deposit 200 | |
withdraw 100 | |
printStatement |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
it "sends statement to the aether" $ do | |
runStateT printStatement [Deposit 100] `shouldBe` … -- the return type is IO ((), [Transaction]), statement is gone |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
printStatement :: StateT [Transaction] IO () | |
printStatement = innerPrintStatement putStr | |
innerPrintStatement :: Monad m => (String -> m ()) -> StateT [Transaction] m () | |
innerPrintStatement printer = do | |
transactions <- get | |
let statement = generateStatement transactions | |
lift (printer statement) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
testPrintStatement :: StateT [Transaction] (Writer String) () | |
testPrintStatement = innerPrintStatement (\statement -> tell statement) | |
it "prints a statement" $ do | |
-- evalStateT works just like evalState, except it will return us a `Writer String ()` instead of just `()` | |
-- we can then use execWriter to get the String from Writer String () | |
execWriter (evalStateT testPrintStatement [Deposit 100, Withdrawal 50]) `shouldBe` "Deposited 100\nWithdrew 50" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
areTheseEqual :: a -> a -> Bool | |
areTheseEqual a b = a == b |
OlderNewer