diff --git a/src/Data/Float/Utils.hs b/src/Data/Float/Utils.hs
index 9639ba360a57be4345fa930df6ad5eb1d109e079..4ce7ee745a1402d52186ce8df1fa4c20f21f1c5b 100644
--- a/src/Data/Float/Utils.hs
+++ b/src/Data/Float/Utils.hs
@@ -45,6 +45,7 @@ newtype MaxDouble = MaxDouble Double
                    , RealFrac
                    , Floating
                    , RealFloat
+                   , NFData
                    )
 
 
diff --git a/src/MA/Functors.hs b/src/MA/Functors.hs
index c254fcad66b4393419c9e2474ee2d44ba8ad2543..abb501ea66e0bd81ea2258e1ffaa004df6f55f1b 100644
--- a/src/MA/Functors.hs
+++ b/src/MA/Functors.hs
@@ -12,12 +12,12 @@ import MA.Functors.Distribution (distribution)
 import MA.Functors.GroupValued (intValued, realValued, complexValued)
 import MA.Functors.Polynomial (polynomial)
 import MA.Functors.Powerset (powerset)
-import MA.Functors.MonoidValued (maxIntValued)
+import MA.Functors.MonoidValued (maxIntValued, maxRealValued)
 import MA.Functors.SomeFunctor
 
 registeredFunctors :: [[FunctorDescription SomeFunctor]]
 registeredFunctors =
-  [ [someFunctor maxIntValued]
+  [ [someFunctor maxIntValued, someFunctor maxRealValued ]
   , [someFunctor intValued, someFunctor realValued, someFunctor complexValued]
   , [someFunctor powerset, someFunctor bag, someFunctor distribution]
   , [someFunctor polynomial]
diff --git a/src/MA/Functors/MonoidValued.hs b/src/MA/Functors/MonoidValued.hs
index e8d3d658ec6183bdda7ea5aee4266c587152ab23..bca6ad7eb51a7e46877ca05cf41a4f65c907a6d9 100644
--- a/src/MA/Functors/MonoidValued.hs
+++ b/src/MA/Functors/MonoidValued.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE FlexibleContexts #-}
 {-# LANGUAGE BangPatterns #-}
 {-# LANGUAGE FlexibleInstances #-}
 {-# LANGUAGE TemplateHaskell #-}
@@ -8,7 +9,12 @@
 -- The 'RefinementInterface' implementation for such functors doesn't fulfil the
 -- same runtime complexity criteria as the other functors and it also uses tons
 -- of space, but it works and satisfies the axioms.
-module MA.Functors.MonoidValued (SlowMonoidValued(..), maxIntValued) where
+module MA.Functors.MonoidValued
+  ( SlowMonoidValued(..)
+  , maxIntValued
+  , maxRealValued
+  )
+where
 
 import           Data.List                      ( foldl' )
 import           Data.Semigroup                 ( Max(..) )
@@ -27,6 +33,9 @@ import           MA.FunctorDescription
 import qualified MA.Parser.Lexer               as L
 import           MA.FunctorExpression.Parser
 import           MA.Coalgebra.Parser
+import           Data.Float.Utils               ( MaxDouble(..) )
+import           MA.Parser.Types
+
 
 data SlowMonoidValued m a = SlowMonoidValued a
 
@@ -45,7 +54,7 @@ deriving instance Traversable (SlowMonoidValued m)
 maxIntValued :: FunctorDescription (SlowMonoidValued (Max Int))
 maxIntValued = FunctorDescription
   { name = "Max-valued"
-  , syntaxExample = "Max^X"
+  , syntaxExample = "(Z, max)^X"
   , functorExprParser =
     prefix
       -- We need this try here, so that parenthesis can still be parsed as
@@ -59,6 +68,26 @@ maxIntValued = FunctorDescription
       )
   }
 
+
+-- | The @(ℝ, max)^X@ functor
+maxRealValued :: FunctorDescription (SlowMonoidValued MaxDouble)
+maxRealValued = FunctorDescription
+  { name = "Max-valued"
+  , syntaxExample = "(R, max)^X"
+  , functorExprParser =
+    prefix
+      -- We need this try here, so that parenthesis can still be parsed as
+      -- normal if they don't contain exactly (Z, max)
+      (  try
+          (L.parens
+            ((L.symbol "R" <|> L.symbol "ℝ") >> L.comma >> L.symbol "max")
+          )
+      >> L.symbol "^"
+      >> pure SlowMonoidValued
+      )
+  }
+
+
 type LabelCountMap m = M.Map m Int
 
 type instance Label (SlowMonoidValued m) = m
@@ -96,8 +125,17 @@ sumCounts :: Monoid m => LabelCountMap m -> m
 sumCounts = M.foldlWithKey' (\a x -> (<> a) . multiply x) mempty
   where multiply x n = mconcat (replicate n x)
 
+
 instance ParseMorphism (SlowMonoidValued (Max Int)) where
-  parseMorphismPoint (SlowMonoidValued inner) = do
+  parseMorphismPoint (SlowMonoidValued inner) = parseMorphismPointHelper inner (Max <$> (L.signed L.decimal))
+
+
+instance ParseMorphism (SlowMonoidValued MaxDouble) where
+  parseMorphismPoint (SlowMonoidValued inner) = parseMorphismPointHelper inner (MaxDouble <$> L.signed L.float)
+
+
+parseMorphismPointHelper :: (MonadParser m, Ord x, Monoid w) => m x -> m w -> m (w, V.Vector (x, w))
+parseMorphismPointHelper inner weightParser = do
     !successors <- V.sortOn fst . V.fromList <$> L.braces (edge `sepBy` L.comma)
 
     when (V.hasDuplicates (fmap fst successors))
@@ -105,4 +143,4 @@ instance ParseMorphism (SlowMonoidValued (Max Int)) where
 
     let !h1 = fold (V.map snd successors)
     return (h1, successors)
-    where edge = (,) <$> inner <*> (L.colon *> (Max <$> (L.signed L.decimal)))
+    where edge = (,) <$> inner <*> (L.colon *> weightParser)
diff --git a/tests/MA/Functors/MonoidValuedSpec.hs b/tests/MA/Functors/MonoidValuedSpec.hs
index 901e12eca87eaa3a6520507975f530c3a95caa66..6f2c4579fc3b3747163907a5a80ff5f8e5849db8 100644
--- a/tests/MA/Functors/MonoidValuedSpec.hs
+++ b/tests/MA/Functors/MonoidValuedSpec.hs
@@ -32,11 +32,14 @@ import qualified Data.Partition                as Part
 import           MA.Algorithm
 import           MA.Functors.Polynomial
 import           MA.Coalgebra.RefinementTypes
+import           Data.Float.Utils
 
 spec :: Spec
 spec = do
   maxIntParseSpec
   maxIntRefineSpec
+  maxRealParseSpec
+  maxRealRefineSpec
 
 
 maxIntParseSpec :: Spec
@@ -81,6 +84,7 @@ maxIntParseSpec = describe "maxInt parsing" $ do
 
   it "works with negative numbers" $ p `shouldSucceedOn` "x: {x: -2}"
 
+
 maxIntRefineSpec :: Spec
 maxIntRefineSpec = describe "maxInt refine" $ do
   let p = fmap snd
@@ -97,6 +101,67 @@ maxIntRefineSpec = describe "maxInt refine" $ do
     part <- stToIO (refine proxy enc)
     (Part.toBlocks part) `shouldMatchList` [[0, 1]]
 
+
+maxRealParseSpec :: Spec
+maxRealParseSpec = describe "maxReal parsing" $ do
+  it "can parse (R, max)^X as functor expression"
+    $ parseFunctorExpression [[functorExprParser maxRealValued]] "" "(R, max)^X"
+    `shouldParse` (Functor 1 (SlowMonoidValued Variable))
+
+  it "can parse (ℝ, max)^X as functor expression"
+    $ parseFunctorExpression [[functorExprParser maxRealValued]] "" "(ℝ, max)^X"
+    `shouldParse` (Functor 1 (SlowMonoidValued Variable))
+
+  it "nests correctly in functor expressions"
+    $ parseFunctorExpression [[functorExprParser maxRealValued]]
+                             ""
+                             "(R, max)^((R, max)^X)"
+    `shouldParse` (Functor
+                    1
+                    (SlowMonoidValued (Functor 1 (SlowMonoidValued Variable)))
+                  )
+
+  it "still parses parenthesis in functor expressions correctly" $ do
+    parseFunctorExpression [[functorExprParser maxRealValued]] "" "((R, max)^X)"
+      `shouldParse` (Functor 1 (SlowMonoidValued Variable))
+    parseFunctorExpression [[functorExprParser maxRealValued]] "" "(R, max)^(X)"
+      `shouldParse` (Functor 1 (SlowMonoidValued Variable))
+
+
+  let p = fmap snd
+        . parseMorphisms (Functor 1 (SlowMonoidValued @MaxDouble Variable)) ""
+
+  it "parses an empty successor list"
+    $ p "x: {}"
+    `shouldParse` encoding [Sorted 1 mempty] []
+
+  it "parses a simple example"
+    $ p "x: {x: 2.5, y: 3.7}\ny: {}"
+    `shouldParse` encoding [Sorted 1 3.7, Sorted 1 mempty]
+                           [(0, (Sorted 1 2.5), 0), (0, (Sorted 1 3.7), 1)]
+
+  it "fails on duplicate edges" $ p `shouldFailOn` "x: {x: 2.3, x: 3.6}"
+
+  it "works with negative numbers" $ p `shouldSucceedOn` "x: {x: -2.8}"
+
+
+maxRealRefineSpec :: Spec
+maxRealRefineSpec = describe "maxReal refine" $ do
+  let p = fmap snd
+        . parseMorphisms (Functor 1 (SlowMonoidValued @MaxDouble Variable)) ""
+      proxy = Proxy @(Desorted (SlowMonoidValued MaxDouble))
+
+  it "it distinguishes different maximas with equal sums" $ do
+    let Right enc = p "x: {x: 1.1, y: 3.1}\ny: {x: 2.1, y: 2.1}"
+    part <- stToIO (refine proxy enc)
+    (Part.toBlocks part) `shouldMatchList` [[0], [1]]
+
+  it "identifies equal maximas with different sums" $ do
+    let Right enc = p "x: {x: 1.1, y: 3.1}\ny: {x: 3.1, y: 2.1}"
+    part <- stToIO (refine proxy enc)
+    (Part.toBlocks part) `shouldMatchList` [[0, 1]]
+
+
 -- FIXME: Remove duplicate definition of this function
 encoding :: [h1] -> [(Int, l, Int)] -> Encoding l h1
 encoding h1 es = Encoding.new (V.fromList h1) (V.fromList (map toEdge es))