Create a gist now

Instantly share code, notes, and snippets.

Embed
Haskell implementation of Greg Young's CQRS sample: https://github.com/gregoryyoung/m-r Love the sheer elegance of Haskell; no need for all that infrastructure crap
module InventoryItems(Command(..), Event(..), handle) where
import Data.Maybe(isJust)
type Id = String
type Name = String
type Amount = Int
data Command = CreateInventoryItem Id
| RenameInventoryItem Id Name
| RemoveItemsFromInventory Id Amount
| AddItemsToInventory Id Amount
| DeactivateInventoryItem Id
deriving (Show)
data Event = InventoryItemCreated Id
| InventoryItemRenamed Id Name
| ItemsRemovedFromInventory Id Amount
| ItemsCheckedInToInventory Id Amount
| InventoryItemDeactivated Id
deriving (Show, Read)
data Item = Item { itemId :: Id
, itemActivated :: Bool
}
handle :: [Event] -> Command -> [Event]
handle events command =
handle' item command
where item = apply events
handle' maybeItem (CreateInventoryItem id)
| itemExists = error "item already created"
| otherwise = [InventoryItemCreated id]
where itemExists = isJust maybeItem
handle' Nothing _command = error "please create the item first"
handle' (Just item) (DeactivateInventoryItem id)
| deactivated = error "already deactivated"
| otherwise = [InventoryItemDeactivated id]
where deactivated = not (itemActivated item)
handle' (Just Item {itemActivated = False}) _command = error "item is deactivated"
handle' (Just item) (RenameInventoryItem id name)
| invalidName = error "newName"
| otherwise = [InventoryItemRenamed id name]
where invalidName = name == []
handle' (Just item) (RemoveItemsFromInventory id amount)
| invalidAmount = error "can't remove negative amount from inventory"
| otherwise = [ItemsRemovedFromInventory id amount]
where invalidAmount = amount <= 0
handle' (Just item) (AddItemsToInventory id amount)
| invalidAmount = error "must have an amount > 0 to checkin to inventory"
| otherwise = [ItemsCheckedInToInventory id amount]
where invalidAmount = amount <= 0
apply events = foldl apply' Nothing events
apply' Nothing (InventoryItemCreated id) = Just (Item id True)
apply' (Just item) (InventoryItemDeactivated id) = Just (item {itemActivated = False})
apply' (Just item) _ = Just item
@yevhen

This comment has been minimized.

Show comment
Hide comment
@yevhen

yevhen Jan 2, 2014

There is no neeed for any of that infrastructure crap in C# either, even including DelegateAdjuster. I believe that Greg was just having fun (trolling actually). All that crap, including DelegateAdjuster could be substituted by using dynamic and casting to object.

yevhen commented Jan 2, 2014

There is no neeed for any of that infrastructure crap in C# either, even including DelegateAdjuster. I believe that Greg was just having fun (trolling actually). All that crap, including DelegateAdjuster could be substituted by using dynamic and casting to object.

@yevhen

This comment has been minimized.

Show comment
Hide comment
@yevhen

yevhen Jan 2, 2014

Stii, on overall, it won't be that terse in C#, fo sure :)

yevhen commented Jan 2, 2014

Stii, on overall, it won't be that terse in C#, fo sure :)

@ToJans

This comment has been minimized.

Show comment
Hide comment
@ToJans

ToJans Jan 3, 2014

Agreed!

Owner

ToJans commented Jan 3, 2014

Agreed!

@henry-hz

This comment has been minimized.

Show comment
Hide comment
@henry-hz

henry-hz Dec 30, 2015

This is more than elegance, it's an electronic poem :) Just a fantastic comparison.

This is more than elegance, it's an electronic poem :) Just a fantastic comparison.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment