Skip to content

Instantly share code, notes, and snippets.

@alpacaaa
Last active May 1, 2019 21:05
Show Gist options
  • Save alpacaaa/bb7563ec734d943d959ff6a0e58e2d87 to your computer and use it in GitHub Desktop.
Save alpacaaa/bb7563ec734d943d959ff6a0e58e2d87 to your computer and use it in GitHub Desktop.
How purity in Haskell makes your life easier
module Cart where
-- An Item is just a record (like an object in JS).
data Item
= Item
{ name :: String
, quantity :: Int
}
-- A ShoppingCart is a list (like an array in JS).
data ShoppingCart
= ShoppingCart [Item]
-- Why have a separate type for ShoppingCartId?
-- So that we don't get confused!
-- Types are cheap, use them to model your domain.
data ShoppingCartId
= ShoppingCartId String
-- There's no database here.
-- All we're doing is return a bunch of items as if they were fetched
-- from a real db :)
fetchShoppingCart :: ShoppingCartId -> IO ShoppingCart
fetchShoppingCart _
= pure (ShoppingCart items)
where
items
= [ Item "A book" 1
, Item "A chair" 3
]
-- This is just a `reduce` operation, which in Haskell is commonly
-- known as a `fold`. But it works exactly the same.
numberOfItems :: ShoppingCart -> Int
numberOfItems (ShoppingCart items)
= foldl (\acc item -> acc + quantity item) 0 items
-- Compose the two functions!
-- "do notation" takes a bit getting used to, but it's pretty sick.
numberOfItemsByCartId :: ShoppingCartId -> IO Int
numberOfItemsByCartId cartId = do
cart <- fetchShoppingCart cartId
pure (numberOfItems cart)
main :: IO ()
main = do
total <- numberOfItemsByCartId (ShoppingCartId "ab341")
putStrLn ("Wait for it, the total is: " ++ show total)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment