module Chiasma.Ui.Measure.Balance where
import Data.List (zipWith3)
import qualified Data.List.NonEmpty as NonEmpty
import Chiasma.Ui.Measure.Weights (
amendAndNormalizeWeights,
normalizeWeights,
)
zipWith3NE :: (a -> b -> c -> d) -> NonEmpty a -> NonEmpty b -> NonEmpty c -> NonEmpty d
zipWith3NE :: forall a b c d.
(a -> b -> c -> d)
-> NonEmpty a -> NonEmpty b -> NonEmpty c -> NonEmpty d
zipWith3NE a -> b -> c -> d
z ~(a
a :| [a]
as) ~(b
b :| [b]
bs) ~(c
c :| [c]
cs) =
a -> b -> c -> d
z a
a b
b c
c d -> [d] -> NonEmpty d
forall a. a -> [a] -> NonEmpty a
:| (a -> b -> c -> d) -> [a] -> [b] -> [c] -> [d]
forall a b c d. (a -> b -> c -> d) -> [a] -> [b] -> [c] -> [d]
zipWith3 a -> b -> c -> d
z [a]
as [b]
bs [c]
cs
data Balance =
Balance {
Balance -> NonEmpty Float
balanceMin :: NonEmpty Float,
Balance -> NonEmpty (Maybe Float)
balanceMax :: NonEmpty (Maybe Float),
Balance -> NonEmpty Float
balanceWeights :: NonEmpty Float,
Balance -> NonEmpty Bool
balanceMinimized :: NonEmpty Bool,
Balance -> Float
balanceTotal :: Float
}
reverseWeights :: NonEmpty Float -> NonEmpty Float
reverseWeights :: NonEmpty Float -> NonEmpty Float
reverseWeights NonEmpty Float
weights =
Float -> Float
rev (Float -> Float) -> NonEmpty Float -> NonEmpty Float
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> NonEmpty Float
r
where
rev :: Float -> Float
rev Float
a =
Float -> Maybe Float -> Float
forall a. a -> Maybe a -> a
fromMaybe Float
a (Float
a Float -> Float -> Maybe Float
forall a. (Eq a, Fractional a) => a -> a -> Maybe a
/ Float
norm)
r :: NonEmpty Float
r =
(Float -> Float) -> NonEmpty Float -> NonEmpty Float
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Float
1 Float -> Float -> Float
forall a. Num a => a -> a -> a
-) NonEmpty Float
weights
norm :: Float
norm =
NonEmpty Float -> Float
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum NonEmpty Float
r
cutSizes :: Balance -> NonEmpty Float
cutSizes :: Balance -> NonEmpty Float
cutSizes (Balance NonEmpty Float
minSizes NonEmpty (Maybe Float)
_ NonEmpty Float
weights NonEmpty Bool
_ Float
total) =
Float -> Float
addNegatives (Float -> Float) -> NonEmpty Float -> NonEmpty Float
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> NonEmpty Float
truncatedWeighted
where
surplus :: Float
surplus =
NonEmpty Float -> Float
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum NonEmpty Float
minSizes Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
total
surplusDistWeighted :: NonEmpty Float
surplusDistWeighted =
(Float -> Float) -> NonEmpty Float -> NonEmpty Float
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Float
surplus Float -> Float -> Float
forall a. Num a => a -> a -> a
*) (NonEmpty Float -> NonEmpty Float
reverseWeights NonEmpty Float
weights)
truncatedWeighted :: NonEmpty Float
truncatedWeighted =
((Float, Float) -> Float)
-> NonEmpty (Float, Float) -> NonEmpty Float
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((Float -> Float -> Float) -> (Float, Float) -> Float
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry (-)) (NonEmpty Float -> NonEmpty Float -> NonEmpty (Float, Float)
forall a b. NonEmpty a -> NonEmpty b -> NonEmpty (a, b)
NonEmpty.zip NonEmpty Float
minSizes NonEmpty Float
surplusDistWeighted)
negOrZero :: a -> a
negOrZero a
a =
if a
a a -> a -> Bool
forall a. Ord a => a -> a -> Bool
< a
0 then a
a else a
0
neg :: NonEmpty Float
neg =
(Float -> Float) -> NonEmpty Float -> NonEmpty Float
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Float -> Float
forall {a}. (Ord a, Num a) => a -> a
negOrZero NonEmpty Float
truncatedWeighted
negTotal :: Float
negTotal =
NonEmpty Float -> Float
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum NonEmpty Float
neg
negCount :: Int
negCount =
[Float] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ((Float -> Bool) -> NonEmpty Float -> [Float]
forall a. (a -> Bool) -> NonEmpty a -> [a]
NonEmpty.filter (Float -> Float -> Bool
forall a. Ord a => a -> a -> Bool
< Float
0) NonEmpty Float
neg)
negativesDist :: Float
negativesDist =
Float -> Maybe Float -> Float
forall a. a -> Maybe a -> a
fromMaybe Float
0 (Float
negTotal Float -> Float -> Maybe Float
forall a. (Eq a, Fractional a) => a -> a -> Maybe a
/ Int -> Float
forall a b. (Real a, Fractional b) => a -> b
realToFrac (NonEmpty Float -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length NonEmpty Float
minSizes Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
negCount))
addNegatives :: Float -> Float
addNegatives Float
a =
if Float
a Float -> Float -> Bool
forall a. Ord a => a -> a -> Bool
< Float
0 then Float
0 else Float
a Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
negativesDist
distributeOnUnbounded :: Balance -> NonEmpty Float
distributeOnUnbounded :: Balance -> NonEmpty Float
distributeOnUnbounded (Balance NonEmpty Float
min' NonEmpty (Maybe Float)
max' NonEmpty Float
weights NonEmpty Bool
_ Float
total) =
(Float -> Float -> Float)
-> NonEmpty Float -> NonEmpty Float -> NonEmpty Float
forall a b c.
(a -> b -> c) -> NonEmpty a -> NonEmpty b -> NonEmpty c
NonEmpty.zipWith Float -> Float -> Float
addWeights NonEmpty Float
initial NonEmpty Float
newWeights
where
initial :: NonEmpty Float
initial = (Float -> Maybe Float -> Float)
-> NonEmpty Float -> NonEmpty (Maybe Float) -> NonEmpty Float
forall a b c.
(a -> b -> c) -> NonEmpty a -> NonEmpty b -> NonEmpty c
NonEmpty.zipWith Float -> Maybe Float -> Float
forall a. a -> Maybe a -> a
fromMaybe NonEmpty Float
min' NonEmpty (Maybe Float)
max'
newWeights :: NonEmpty Float
newWeights = NonEmpty Float -> NonEmpty Float
normalizeWeights (NonEmpty Float -> NonEmpty Float)
-> NonEmpty Float -> NonEmpty Float
forall a b. (a -> b) -> a -> b
$ (Float -> Maybe Float -> Float)
-> NonEmpty Float -> NonEmpty (Maybe Float) -> NonEmpty Float
forall a b c.
(a -> b -> c) -> NonEmpty a -> NonEmpty b -> NonEmpty c
NonEmpty.zipWith Float -> Maybe Float -> Float
forall {b} {a}. Num b => b -> Maybe a -> b
weightOrZeroIfMax NonEmpty Float
weights NonEmpty (Maybe Float)
max'
addWeights :: Float -> Float -> Float
addWeights Float
i Float
w = Float
i Float -> Float -> Float
forall a. Num a => a -> a -> a
+ (Float
w Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
surplus)
surplus :: Float
surplus = Float
total Float -> Float -> Float
forall a. Num a => a -> a -> a
- NonEmpty Float -> Float
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum NonEmpty Float
initial
weightOrZeroIfMax :: b -> Maybe a -> b
weightOrZeroIfMax b
w = b -> (a -> b) -> Maybe a -> b
forall b a. b -> (a -> b) -> Maybe a -> b
maybe b
w (b -> a -> b
forall a b. a -> b -> a
const b
0)
weightsWithoutMinimized :: Balance -> NonEmpty Float
weightsWithoutMinimized :: Balance -> NonEmpty Float
weightsWithoutMinimized (Balance NonEmpty Float
_ NonEmpty (Maybe Float)
_ NonEmpty Float
weights NonEmpty Bool
minimized Float
_) =
NonEmpty Float -> NonEmpty Float
normalizeWeights NonEmpty Float
zeroIfMinimizedWeights
where
zeroIfMinimizedWeights :: NonEmpty Float
zeroIfMinimizedWeights = (Float -> Bool -> Float)
-> NonEmpty Float -> NonEmpty Bool -> NonEmpty Float
forall a b c.
(a -> b -> c) -> NonEmpty a -> NonEmpty b -> NonEmpty c
NonEmpty.zipWith Float -> Bool -> Float
forall {p}. Num p => p -> Bool -> p
zeroIfMinimized NonEmpty Float
weights NonEmpty Bool
minimized
zeroIfMinimized :: p -> Bool -> p
zeroIfMinimized p
w Bool
m = if Bool
m then p
0 else p
w
trimWeights :: NonEmpty Bool -> NonEmpty Float -> NonEmpty Float
trimWeights :: NonEmpty Bool -> NonEmpty Float -> NonEmpty Float
trimWeights NonEmpty Bool
unsat NonEmpty Float
withoutMinimized =
NonEmpty (Maybe Float) -> NonEmpty Float
amendAndNormalizeWeights NonEmpty (Maybe Float)
onlyUnsat
where
onlyUnsat :: NonEmpty (Maybe Float)
onlyUnsat = (Bool -> Float -> Maybe Float)
-> NonEmpty Bool -> NonEmpty Float -> NonEmpty (Maybe Float)
forall a b c.
(a -> b -> c) -> NonEmpty a -> NonEmpty b -> NonEmpty c
NonEmpty.zipWith Bool -> Float -> Maybe Float
forall {a}. Bool -> a -> Maybe a
weightIfUnsat NonEmpty Bool
unsat NonEmpty Float
withoutMinimized
weightIfUnsat :: Bool -> a -> Maybe a
weightIfUnsat Bool
s a
w = if Bool
s then a -> Maybe a
forall a. a -> Maybe a
Just a
w else Maybe a
forall a. Maybe a
Nothing
distRest :: Balance -> Float -> NonEmpty Float -> NonEmpty Float -> NonEmpty Float
distRest :: Balance
-> Float -> NonEmpty Float -> NonEmpty Float -> NonEmpty Float
distRest Balance
balance Float
rest NonEmpty Float
sizes NonEmpty Float
effectiveMax =
(Float -> Float -> Float)
-> NonEmpty Float -> NonEmpty Float -> NonEmpty Float
forall a b c.
(a -> b -> c) -> NonEmpty a -> NonEmpty b -> NonEmpty c
NonEmpty.zipWith Float -> Float -> Float
addRestWeights NonEmpty Float
sizes NonEmpty Float
restW
where
unsat :: NonEmpty Bool
unsat = (Float -> Float -> Bool)
-> NonEmpty Float -> NonEmpty Float -> NonEmpty Bool
forall a b c.
(a -> b -> c) -> NonEmpty a -> NonEmpty b -> NonEmpty c
NonEmpty.zipWith Float -> Float -> Bool
forall a. Ord a => a -> a -> Bool
(>) NonEmpty Float
effectiveMax NonEmpty Float
sizes
unsatLeft :: Bool
unsatLeft = NonEmpty Bool -> Bool
forall (t :: * -> *). Foldable t => t Bool -> Bool
or NonEmpty Bool
unsat
withoutMinimized :: NonEmpty Float
withoutMinimized = Balance -> NonEmpty Float
weightsWithoutMinimized Balance
balance
restW :: NonEmpty Float
restW =
if Bool
unsatLeft
then NonEmpty Bool -> NonEmpty Float -> NonEmpty Float
trimWeights NonEmpty Bool
unsat NonEmpty Float
withoutMinimized
else NonEmpty Float
withoutMinimized
addRestWeights :: Float -> Float -> Float
addRestWeights Float
s Float
w = Float
s Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
w Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
rest
saturate :: NonEmpty Float -> NonEmpty Float -> NonEmpty Float -> Float -> NonEmpty Float
saturate :: NonEmpty Float
-> NonEmpty Float -> NonEmpty Float -> Float -> NonEmpty Float
saturate NonEmpty Float
initial NonEmpty Float
max' NonEmpty Float
initialWeights Float
total =
NonEmpty Float -> NonEmpty Float -> NonEmpty Float
loop NonEmpty Float
initial NonEmpty Float
initialWeights
where
loop :: NonEmpty Float -> NonEmpty Float -> NonEmpty Float
loop NonEmpty Float
current NonEmpty Float
weights =
if NonEmpty Float
new NonEmpty Float -> NonEmpty Float -> Bool
forall a. Eq a => a -> a -> Bool
== NonEmpty Float
current Bool -> Bool -> Bool
|| Float
rest Float -> Float -> Bool
forall a. Ord a => a -> a -> Bool
<= Float
0 then NonEmpty Float
new else NonEmpty Float -> NonEmpty Float -> NonEmpty Float
loop NonEmpty Float
new NonEmpty Float
newWeights
where
rest :: Float
rest = Float
total Float -> Float -> Float
forall a. Num a => a -> a -> a
- NonEmpty Float -> Float
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum NonEmpty Float
current
unsatWeights :: NonEmpty Float
unsatWeights = (Float -> Float -> Float -> Float)
-> NonEmpty Float
-> NonEmpty Float
-> NonEmpty Float
-> NonEmpty Float
forall a b c d.
(a -> b -> c -> d)
-> NonEmpty a -> NonEmpty b -> NonEmpty c -> NonEmpty d
zipWith3NE (\Float
s Float
m Float
w -> if Float
s Float -> Float -> Bool
forall a. Ord a => a -> a -> Bool
>= Float
m then Float
0 else Float
w) NonEmpty Float
current NonEmpty Float
max' NonEmpty Float
weights
newWeights :: NonEmpty Float
newWeights = NonEmpty Float -> NonEmpty Float
normalizeWeights NonEmpty Float
unsatWeights
new :: NonEmpty Float
new = (Float -> Float -> Float -> Float)
-> NonEmpty Float
-> NonEmpty Float
-> NonEmpty Float
-> NonEmpty Float
forall a b c d.
(a -> b -> c -> d)
-> NonEmpty a -> NonEmpty b -> NonEmpty c -> NonEmpty d
zipWith3NE (\Float
l Float
h Float
w -> Float -> Float -> Float
forall a. Ord a => a -> a -> a
min (Float
l Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
w Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
rest) Float
h) NonEmpty Float
current NonEmpty Float
max' NonEmpty Float
newWeights
distributeOnAll :: Balance -> NonEmpty Float
distributeOnAll :: Balance -> NonEmpty Float
distributeOnAll balance :: Balance
balance@(Balance NonEmpty Float
min' NonEmpty (Maybe Float)
max' NonEmpty Float
weights NonEmpty Bool
_ Float
total) =
if Float
rest Float -> Float -> Bool
forall a. Ord a => a -> a -> Bool
<= Float
0 then NonEmpty Float
sizes else Balance
-> Float -> NonEmpty Float -> NonEmpty Float -> NonEmpty Float
distRest Balance
balance Float
rest NonEmpty Float
sizes NonEmpty Float
effectiveMax
where
effectiveMax :: NonEmpty Float
effectiveMax = Float -> Maybe Float -> Float
forall a. a -> Maybe a -> a
fromMaybe Float
1e6 (Maybe Float -> Float) -> NonEmpty (Maybe Float) -> NonEmpty Float
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> NonEmpty (Maybe Float)
max'
sizes :: NonEmpty Float
sizes = NonEmpty Float
-> NonEmpty Float -> NonEmpty Float -> Float -> NonEmpty Float
saturate NonEmpty Float
min' NonEmpty Float
effectiveMax NonEmpty Float
weights Float
total
rest :: Float
rest = Float
total Float -> Float -> Float
forall a. Num a => a -> a -> a
- NonEmpty Float -> Float
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum NonEmpty Float
sizes
hasUnbounded :: Balance -> Bool
hasUnbounded :: Balance -> Bool
hasUnbounded =
(Maybe Float -> Bool) -> NonEmpty (Maybe Float) -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any Maybe Float -> Bool
forall a. Maybe a -> Bool
isNothing (NonEmpty (Maybe Float) -> Bool)
-> (Balance -> NonEmpty (Maybe Float)) -> Balance -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Balance -> NonEmpty (Maybe Float)
balanceMax
distributeSizes :: Balance -> NonEmpty Float
distributeSizes :: Balance -> NonEmpty Float
distributeSizes Balance
balance =
Balance -> NonEmpty Float
handler Balance
balance
where
handler :: Balance -> NonEmpty Float
handler =
if (Float
maxTotal Float -> Float -> Bool
forall a. Ord a => a -> a -> Bool
< Balance -> Float
balanceTotal Balance
balance) Bool -> Bool -> Bool
&& Balance -> Bool
hasUnbounded Balance
balance
then Balance -> NonEmpty Float
distributeOnUnbounded
else Balance -> NonEmpty Float
distributeOnAll
maxTotal :: Float
maxTotal = [Float] -> Float
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum ([Maybe Float] -> [Float]
forall a. [Maybe a] -> [a]
catMaybes ([Maybe Float] -> [Float]) -> [Maybe Float] -> [Float]
forall a b. (a -> b) -> a -> b
$ NonEmpty (Maybe Float) -> [Maybe Float]
forall a. NonEmpty a -> [a]
NonEmpty.toList (NonEmpty (Maybe Float) -> [Maybe Float])
-> NonEmpty (Maybe Float) -> [Maybe Float]
forall a b. (a -> b) -> a -> b
$ Balance -> NonEmpty (Maybe Float)
balanceMax Balance
balance)
roundSizes :: NonEmpty Float -> NonEmpty Int
roundSizes :: NonEmpty Float -> NonEmpty Int
roundSizes (Float
h :| [Float]
t) =
Int
roundedHead Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Float -> Int
forall a b. (RealFrac a, Integral b) => a -> b
round Float
surplus Int -> [Int] -> NonEmpty Int
forall a. a -> [a] -> NonEmpty a
:| [Int]
roundedTail
where
(Float
surplus, [Int]
roundedTail) = (Float -> Float -> (Float, Int))
-> Float -> [Float] -> (Float, [Int])
forall (t :: * -> *) s a b.
Traversable t =>
(s -> a -> (s, b)) -> s -> t a -> (s, t b)
mapAccumL Float -> Float -> (Float, Int)
forall {a} {b}. (RealFrac a, Integral b) => a -> a -> (a, b)
folder Float
diff0 [Float]
t
(Int
roundedHead, Float
diff0) = Float -> (Int, Float)
forall {b} {a}. (RealFrac b, Integral a) => b -> (a, b)
diff Float
h
folder :: a -> a -> (a, b)
folder a
z a
a =
(a
z a -> a -> a
forall a. Num a => a -> a -> a
+ a
z1, b
a1)
where
(b
a1, a
z1) = a -> (b, a)
forall {b} {a}. (RealFrac b, Integral a) => b -> (a, b)
diff a
a
diff :: b -> (a, b)
diff b
a = (b -> a
forall a b. (RealFrac a, Integral b) => a -> b
floor b
a, b
a b -> b -> b
forall a. Num a => a -> a -> a
- Int -> b
forall a b. (Integral a, Num b) => a -> b
fromIntegral (b -> Int
forall a b. (RealFrac a, Integral b) => a -> b
floor b
a :: Int))
ensureMinimum2 :: NonEmpty Float -> NonEmpty Float
ensureMinimum2 :: NonEmpty Float -> NonEmpty Float
ensureMinimum2 NonEmpty Float
sizes =
Float -> Float
choose (Float -> Float) -> NonEmpty Float -> NonEmpty Float
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> NonEmpty Float
positives
where
positive :: Float -> Float
positive =
Float -> Float -> Float
forall a. Ord a => a -> a -> a
max Float
0
positives :: NonEmpty Float
positives =
Float -> Float
positive (Float -> Float) -> NonEmpty Float -> NonEmpty Float
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> NonEmpty Float
sizes
overTwoCount :: Int
overTwoCount =
[Float] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ((Float -> Bool) -> NonEmpty Float -> [Float]
forall a. (a -> Bool) -> NonEmpty a -> [a]
NonEmpty.filter (Float -> Float -> Bool
forall a. Ord a => a -> a -> Bool
>= Float
2) NonEmpty Float
sizes)
unders :: NonEmpty Float
unders =
Float -> Float
amountUnderTwo (Float -> Float) -> NonEmpty Float -> NonEmpty Float
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> NonEmpty Float
positives
amountUnderTwoDist :: Float
amountUnderTwoDist =
Float -> Maybe Float -> Float
forall a. a -> Maybe a -> a
fromMaybe Float
0 (NonEmpty Float -> Float
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum NonEmpty Float
unders Float -> Float -> Maybe Float
forall a. (Eq a, Fractional a) => a -> a -> Maybe a
/ Int -> Float
forall a b. (Real a, Fractional b) => a -> b
realToFrac Int
overTwoCount)
amountUnderTwo :: Float -> Float
amountUnderTwo Float
a =
Float -> Float
positive (Float
2 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
a)
choose :: Float -> Float
choose Float
a =
Float -> Float -> Float
forall a. Ord a => a -> a -> a
max Float
2 (Float
a Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
amountUnderTwoDist)
rectifySizes :: NonEmpty Float -> NonEmpty Int
rectifySizes :: NonEmpty Float -> NonEmpty Int
rectifySizes =
NonEmpty Float -> NonEmpty Int
roundSizes (NonEmpty Float -> NonEmpty Int)
-> (NonEmpty Float -> NonEmpty Float)
-> NonEmpty Float
-> NonEmpty Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NonEmpty Float -> NonEmpty Float
ensureMinimum2
balanceSizes :: NonEmpty Float -> NonEmpty (Maybe Float) -> NonEmpty Float -> NonEmpty Bool -> Float -> NonEmpty Int
balanceSizes :: NonEmpty Float
-> NonEmpty (Maybe Float)
-> NonEmpty Float
-> NonEmpty Bool
-> Float
-> NonEmpty Int
balanceSizes NonEmpty Float
minSizes NonEmpty (Maybe Float)
maxSizes NonEmpty Float
weights NonEmpty Bool
minimized Float
total =
NonEmpty Float -> NonEmpty Int
rectifySizes (Balance -> NonEmpty Float
fit Balance
balance)
where
fit :: Balance -> NonEmpty Float
fit = if NonEmpty Float -> Float
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum NonEmpty Float
minSizes Float -> Float -> Bool
forall a. Ord a => a -> a -> Bool
> Float
total then Balance -> NonEmpty Float
cutSizes else Balance -> NonEmpty Float
distributeSizes
balance :: Balance
balance = NonEmpty Float
-> NonEmpty (Maybe Float)
-> NonEmpty Float
-> NonEmpty Bool
-> Float
-> Balance
Balance NonEmpty Float
minSizes NonEmpty (Maybe Float)
maxSizes NonEmpty Float
weights NonEmpty Bool
minimized Float
total