summaryrefslogtreecommitdiff
path: root/src/lib/Codec/Pesto/Graph.lhs
diff options
context:
space:
mode:
authorLars-Dominik Braun <lars@6xq.net>2023-01-19 14:56:41 +0100
committerLars-Dominik Braun <lars@6xq.net>2023-01-19 14:56:41 +0100
commitcc2aaa6e46dfac12dfad39414925d5a535a91d19 (patch)
treea257c2cecf7344263bc9775828fc47689423da2d /src/lib/Codec/Pesto/Graph.lhs
parent623f8efba15e167ebae89618cb5362c3f9486ec0 (diff)
downloadpesto-cc2aaa6e46dfac12dfad39414925d5a535a91d19.tar.gz
pesto-cc2aaa6e46dfac12dfad39414925d5a535a91d19.tar.bz2
pesto-cc2aaa6e46dfac12dfad39414925d5a535a91d19.zip
graph: Add ingredient mergingHEADmaster
Diffstat (limited to 'src/lib/Codec/Pesto/Graph.lhs')
-rw-r--r--src/lib/Codec/Pesto/Graph.lhs89
1 files changed, 87 insertions, 2 deletions
diff --git a/src/lib/Codec/Pesto/Graph.lhs b/src/lib/Codec/Pesto/Graph.lhs
index 43142b6..5628ec3 100644
--- a/src/lib/Codec/Pesto/Graph.lhs
+++ b/src/lib/Codec/Pesto/Graph.lhs
@@ -16,6 +16,8 @@ Language semantics
> , resolveReferences
> , test
> , extract
+> , extractIngredients
+> , mergeQuantity
> , NodeId
> , Node
> , Nodes
@@ -23,8 +25,9 @@ Language semantics
> , Edges
> ) where
> import Data.Char (toLower)
-> import Data.List (sort, nub)
+> import Data.List (sort, nub, sortOn)
> import Test.HUnit hiding (test, Node)
+> import Data.Ratio ((%), Ratio)
>
> import Codec.Pesto.Parse hiding (test)
@@ -264,6 +267,76 @@ results with the same name). They are permitted at this stage, but rejected
> , cmpGraphRef "|foobar *foobar >foobar *foobar" [(0, 1), (0, 3), (2, 1), (2, 3)]
> ]
+Quantities
+++++++++++
+
+.. Does not really fit here. Move?
+
+Lists of quantities, for instance for a shopping basket, can be extracted and merged.
+
+> extractIngredients :: [Node Instruction] -> [Quantity]
+> extractIngredients nodes = foldl f [] nodes
+> where
+> f xs (_, Ingredient q) = q:xs
+> f xs _ = xs
+
+> mergeQuantity :: [Quantity] -> [Quantity]
+> mergeQuantity ingredients = reverse $ foldl foldQty [] sortedIngredients
+> where
+> sortedIngredients = sortOn sortKey ingredients
+> sortKey (Quantity _ b c) = (c, b)
+> foldQty ((Quantity (Exact (AmountRatio prevAmount)) prevUnit prevObject):xs)
+> (Quantity (Exact (AmountRatio qamount)) qunit qobject)
+> | prevObject == qobject && prevUnit == qunit
+> = (Quantity (Exact (AmountRatio (prevAmount + qamount))) qunit qobject):xs
+> foldQty ((Quantity (Exact (AmountStr "")) prevUnit prevObject):xs)
+> (Quantity (Exact (AmountStr "")) qunit qobject)
+> | prevObject == qobject && prevUnit == qunit
+> = (Quantity (Exact (AmountStr "")) qunit qobject):xs
+> foldQty xs x = x:xs
+
+> testQuantity :: [Test]
+> testQuantity = [
+
+Quantities are merged when their objects and units match.
+
+> cmpMerge [
+> exactRatioQuantity (1%1) "kg" "apples"
+> , exactRatioQuantity (2%1) "kg" "apples"
+> , exactRatioQuantity (1%2) "" "bananas"
+> , exactRatioQuantity (3%4) "" "bananas"
+> , exactRatioQuantity (5%1) "" "peas"
+> , exactRatioQuantity (200%1) "g" "peas"
+> ]
+> [
+> exactRatioQuantity (3%1) "kg" "apples"
+> , exactRatioQuantity (5%4) "" "bananas"
+> , exactRatioQuantity (5%1) "" "peas"
+> , exactRatioQuantity (200%1) "g" "peas"
+> ]
+
+Objects without any quantity can also be merged.
+
+> , cmpMerge [
+> strQuantity "apples"
+> , strQuantity "apples"
+> ]
+> [ strQuantity "apples" ]
+
+The merged quantities are sorted.
+
+> , cmpMerge [
+> strQuantity "b"
+> , strQuantity "c"
+> , strQuantity "a"
+> ]
+> [
+> strQuantity "a"
+> , strQuantity "b"
+> , strQuantity "c"
+> ]
+> ]
+
Appendix
++++++++
@@ -295,7 +368,19 @@ Get all nodes with edges pointing towards nodeid
> outgoingEdges edges nodeid = filter ((==) nodeid . fst) edges
> outgoingNodes nodes edges nodeid = map ((!!) nodes . snd) $ outgoingEdges edges nodeid
-> test = ["graph" ~: testGraph, "ref" ~: testRef, "extract" ~: testExtract]
+> test = [
+> "graph" ~: testGraph
+> , "ref" ~: testRef
+> , "extract" ~: testExtract
+> , "quantity" ~: testQuantity
+> ]
+
+> cmpMerge value expected = (mergeQuantity value) ~?= expected
+> strQuantity = Quantity (Exact (AmountStr "")) ""
+> exactRatioQuantity :: Ratio Integer -> Unit -> Object -> Quantity
+> exactRatioQuantity qamount qunit qobject =
+> Quantity (Exact (AmountRatio qamount)) qunit qobject
+
> third (_, _, x) = x