Advertisement
Guest User

Untitled

a guest
May 3rd, 2016
67
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.33 KB | None | 0 0
  1. type Observation a
  2. = ObservedValue a
  3. | ObservedError Exception
  4. | DoneObserving
  5.  
  6. observable: (Observation a -> ()) -> ()
  7. observer : Observation a -> ()
  8.  
  9. enumerable: () -> (() -> Observation a)
  10. enumerator: () -> Observation a
  11.  
  12. ---------------------------------------------------
  13.  
  14. domain Bookkeeping
  15.  
  16. type alias AccountingSystemId = String
  17. type alias EntityName = String
  18. type alias AccountingSystemStatus = Created | Preparing | Ready | Forgotten
  19. type alias AccountingSystemUse = Empty | Domestic | SelfEmployed | SmallBusiness | Business | Enterprise
  20.  
  21. aggregate a: AccountingSystem
  22. identifier id: AccountingSystemId
  23. field name: EntityName
  24. field isActive: Boolean
  25. field status: AccountingSystemStatus
  26.  
  27. new event Created { name: EntityName } = { name = name, isActive = false, status = Created }
  28. event Preparing { use: AccountingSystemUse } = { a | status = Preparing }
  29. event SetReady {} = { a | status = Ready }
  30. event Forgotten {} = { a | status = Forgotten }
  31. // event CreationRejected { name: EntityName } = a // this is a transient event or message, goes to the hub but do not gets registered by the aggregate because it does not change state or ever will ¿really?
  32. transient event CreationRejected { name: EntityName }
  33. transient event PreparingRejected { use: AccountingSystemUse }
  34. transient event FinishPreparationRejected { }
  35. transient event SetReadyRejected { }
  36. transient event NoOp {}
  37.  
  38. event Activated {} = { a | isActive = True }
  39. event Deactivated {} = { a | isActive = False }
  40.  
  41. new command Create { name: EntityName } =
  42. case isValidEntityName name of
  43. True -> [ Created { name = name } ]
  44. False -> [ CreationRejected { name = name } ]
  45.  
  46. command PrepareForUse { use: AccountingSystemUse } =
  47. case a.status of
  48. Created -> [ Preparing { use = use } ]
  49. _ -> [ PreparingRejected { use = use } ]
  50.  
  51. command FinishPreparation {} =
  52. case a.status of
  53. Preparing -> [ SetReady {} ]
  54. _ -> [ SetReadyRejected {} ]
  55.  
  56. command Forget {} =
  57. case a.status of
  58. Created -> [ Forgotten { } ]
  59. Ready -> [ Forgotten { } ]
  60. _ -> [ ForgettingRejected { } ] // Or maybe stop preparation
  61.  
  62. command Activate {} = [ Activated {} ]
  63.  
  64. command Deactivate {} = [ Deactivated {} ]
  65.  
  66. process p: PrepareAccountingSystemForDomesticUse
  67. identifier id: String
  68.  
  69. new event e: AccountingSystem.Created
  70.  
  71. SQL-projection p: AccountingSystemList
  72.  
  73.  
  74.  
  75. function isValidEntityName name: EntityName = Regex.isMatch name @"[\w]{5, 20}"
  76.  
  77. ---------------------------------------------------
  78. module SortedList (SortedList, new, add, ...) where
  79.  
  80. type Comparison
  81. = Equals
  82. | LeftLessThanRight
  83. | LeftGreaterThanRight
  84.  
  85. type alias AvlNode a
  86. { value : a
  87. , count : Int
  88. , height: Int
  89. , left : Maybe (Tree a)
  90. , right : Maybe (Tree a)
  91. }
  92.  
  93. type alias SortedList a =
  94. { root: Maybe (AvlNode a)
  95. , comparer: a -> a -> Comparison
  96. }
  97.  
  98. new: (a -> a -> Comparison) -> SortedList a
  99. new comparer =
  100. { root = Nothing
  101. , comparer = comparer
  102. }
  103.  
  104. count: SortedList a -> Comparison
  105. count {_ | root: Maybe (AvlNode a)} =
  106. case root of
  107. Nothing -> 0
  108. Just node -> node.count
  109.  
  110. add: SortedList a -> a -> SortedList a
  111. add list value =
  112. let
  113. newRoot = Just (addValue list.comparer list.root value)
  114. in
  115. { list | root = newRoot }
  116.  
  117.  
  118. ---------------------------------
  119. addValue: (a -> a -> Comparison) -> Maybe(AvlNode a) -> a -> AvlNode a
  120. addValue comparer tree value =
  121.  
  122.  
  123. nodeHeight: Maybe (AvlNode a) -> Int
  124. nodeHeight node =
  125. case node of
  126. Nothing ->
  127. 0
  128. Just n ->
  129. n.height
  130.  
  131. nodeCount: Maybe (AvlNode a) -> Int
  132. nodeCount node =
  133. case node of
  134. Nothing ->
  135. 0
  136. Just n ->
  137. n.count
  138.  
  139. insertAsNode: (a -> a -> Comparison) -> Maybe (AvlTree a) -> a -> Maybe (AvlTree a)
  140. insertAsNode comparer root value =
  141. case root of
  142. Nothing ->
  143. { value = value
  144. , count = 1
  145. , height = 1
  146. , left = Nothing
  147. , right = Nothing
  148. }
  149. Just node ->
  150. case comparer node.value value of
  151. Equals | LeftLessThanRight ->
  152. let
  153. newRoot = updateCountHeight
  154. { node
  155. | left = insertAsNode comparer node.left value
  156. , right = node.right
  157. }
  158. in
  159. balanceNode (Just newRoot)
  160. LeftGreaterThanRight ->
  161. let
  162. newRoot = updateCountHeight
  163. { node
  164. | left = node.left
  165. , right = insertAsNode comparer node.right value
  166. }
  167. in
  168. balanceNode (Just newRoot)
  169.  
  170. deleteAsNode: (a -> a -> Comparison) -> Maybe (AvlTree a) -> a -> Maybe (AvlTree a)
  171. deleteAsNode comparer root value =
  172. case root of
  173. Nothing ->
  174. Nothing
  175. Just node ->
  176. case comparer node.value value of
  177. LeftLessThanRight ->
  178. let
  179. newRoot = updateCountHeight
  180. { node
  181. | right = deleteAsNode comparer node.right value
  182. }
  183. in
  184. balanceNode (Just newRoot)
  185. LeftGreaterThanRight ->
  186. let
  187. newRoot = updateCountHeight
  188. { node
  189. | left = deleteAsNode comparer node.left value
  190. }
  191. in
  192. balanceNode (Just newRoot)
  193. Equals ->
  194.  
  195.  
  196.  
  197. balanceNode: Maybe (AvlTree a) -> Maybe (AvlTree a)
  198. balanceNode root =
  199. case root of
  200. Nothing ->
  201. Nothing
  202. Just node ->
  203. let
  204. lh = nodeHeight node.left
  205. rh = nodeHeight node.right
  206. diff = Math.abs (lh - rh)
  207. in
  208. if diff <= 1
  209. then
  210. node
  211. else
  212. case node of
  213. { na
  214. | left:
  215. { nb
  216. | left: t1
  217. , right:
  218. { nc
  219. | left: t2
  220. , right: t3
  221. }
  222. }
  223. , right = t4
  224. } ->
  225. updateCountHeight
  226. { nc
  227. | left = updateCountHeight
  228. { nb
  229. | left = t1
  230. , right = t2
  231. }
  232. , right = updateCountHeight
  233. { na
  234. | left = t3
  235. , right = t4
  236. }
  237. }
  238. { na
  239. , left = t1
  240. | right:
  241. { nb
  242. | left:
  243. { nc
  244. | left: t2
  245. , right: t3
  246. }
  247. , right: t4
  248. }
  249. } ->
  250. updateCountHeight
  251. { nc
  252. | left = updateCountHeight
  253. { na
  254. | left = t1
  255. , right = t2
  256. }
  257. , right = updateCountHeight
  258. { nb
  259. | left = t3
  260. , right = t4
  261. }
  262. }
  263. _ ->
  264. node
  265.  
  266. updateCountHeight: Maybe (AvlTree a) -> Maybe (AvlTree a)
  267. updateCountHeight root =
  268. case root of
  269. Nothing ->
  270. Nothing
  271. Just node ->
  272. Just
  273. { node
  274. | count = (nodeCount node.left) + (nodeCount node.right) + 1
  275. , height = (Math.max (nodeHeight node.left) (nodeHeight node.right)) + 1
  276. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement