{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}

module Prometheus.Label (
    Label (..)
,   LabelPairs
,   Label0
,   Label1
,   Label2
,   Label3
,   Label4
,   Label5
,   Label6
,   Label7
,   Label8
,   Label9
) where

import Data.Text

-- | A list of tuples where the first value is the label and the second is the
-- value of that label.
type LabelPairs = [(Text, Text)]

-- | Label describes a class of types that can be used to as the label of
-- a vector.
class Ord l => Label l where
    labelPairs :: l -> l -> LabelPairs

type Label0 = ()

instance Label () where
    labelPairs :: () -> () -> LabelPairs
labelPairs () () = []

type Label1 = Text

instance Label Text where
    labelPairs :: Text -> Text -> LabelPairs
labelPairs Text
key Text
value = [(Text
key, Text
value)]

type Label2 = (Text, Text)

instance (a ~ Text, b ~ a) => Label (a, b)  where
    labelPairs :: (a, b) -> (a, b) -> LabelPairs
labelPairs (a
k1, b
k2) (a
v1, b
v2) = [(a
Text
k1, a
Text
v1), (b
Text
k2, b
Text
v2)]

type Label3 = (Text, Text, Text)

instance (a ~ Text, b ~ a, c ~ a) => Label (a, b, c)  where
    labelPairs :: (a, b, c) -> (a, b, c) -> LabelPairs
labelPairs (a
k1, b
k2, c
k3) (a
v1, b
v2, c
v3) = [(a
Text
k1, a
Text
v1), (b
Text
k2, b
Text
v2), (c
Text
k3, c
Text
v3)]

type Label4 = (Text, Text, Text, Text)

instance (a ~ Text, b ~ a, c ~ a, d ~ a) => Label (a, b, c, d)  where
    labelPairs :: (a, b, c, d) -> (a, b, c, d) -> LabelPairs
labelPairs (a
k1, b
k2, c
k3, d
k4) (a
v1, b
v2, c
v3, d
v4) =
            [(a
Text
k1, a
Text
v1), (b
Text
k2, b
Text
v2), (c
Text
k3, c
Text
v3), (d
Text
k4, d
Text
v4)]

type Label5 = (Text, Text, Text, Text, Text)

instance (a ~ Text, b ~ a, c ~ a, d ~ a, e ~ a) => Label (a, b, c, d, e)  where
    labelPairs :: (a, b, c, d, e) -> (a, b, c, d, e) -> LabelPairs
labelPairs (a
k1, b
k2, c
k3, d
k4, e
k5) (a
v1, b
v2, c
v3, d
v4, e
v5) =
            [(a
Text
k1, a
Text
v1), (b
Text
k2, b
Text
v2), (c
Text
k3, c
Text
v3), (d
Text
k4, d
Text
v4), (e
Text
k5, e
Text
v5)]

type Label6 = (Text, Text, Text, Text, Text, Text)

instance (a ~ Text, b ~ a, c ~ a, d ~ a, e ~ a, f ~ a) => Label (a, b, c, d, e, f)  where
    labelPairs :: (a, b, c, d, e, f) -> (a, b, c, d, e, f) -> LabelPairs
labelPairs (a
k1, b
k2, c
k3, d
k4, e
k5, f
k6) (a
v1, b
v2, c
v3, d
v4, e
v5, f
v6) =
            [(a
Text
k1, a
Text
v1), (b
Text
k2, b
Text
v2), (c
Text
k3, c
Text
v3), (d
Text
k4, d
Text
v4), (e
Text
k5, e
Text
v5), (f
Text
k6, f
Text
v6)]

type Label7 = (Text, Text, Text, Text, Text, Text, Text)

instance (a ~ Text, b ~ a, c ~ a, d ~ a, e ~ a, f ~ a, g ~ a) => Label (a, b, c, d, e, f, g)  where
    labelPairs :: (a, b, c, d, e, f, g) -> (a, b, c, d, e, f, g) -> LabelPairs
labelPairs (a
k1, b
k2, c
k3, d
k4, e
k5, f
k6, g
k7) (a
v1, b
v2, c
v3, d
v4, e
v5, f
v6, g
v7) =
            [(a
Text
k1, a
Text
v1), (b
Text
k2, b
Text
v2), (c
Text
k3, c
Text
v3), (d
Text
k4, d
Text
v4), (e
Text
k5, e
Text
v5), (f
Text
k6, f
Text
v6),
             (g
Text
k7, g
Text
v7)]

type Label8 = (Text, Text, Text, Text, Text, Text, Text, Text)

instance (a ~ Text, b ~ a, c ~ a, d ~ a, e ~ a, f ~ a, g ~ a, h ~ a) => Label (a, b, c, d, e, f, g, h) where
    labelPairs :: (a, b, c, d, e, f, g, h) -> (a, b, c, d, e, f, g, h) -> LabelPairs
labelPairs (a
k1, b
k2, c
k3, d
k4, e
k5, f
k6, g
k7, h
k8)
               (a
v1, b
v2, c
v3, d
v4, e
v5, f
v6, g
v7, h
v8) =
            [(a
Text
k1, a
Text
v1), (b
Text
k2, b
Text
v2), (c
Text
k3, c
Text
v3), (d
Text
k4, d
Text
v4), (e
Text
k5, e
Text
v5), (f
Text
k6, f
Text
v6),
             (g
Text
k7, g
Text
v7), (h
Text
k8, h
Text
v8)]

type Label9 = (Text, Text, Text, Text, Text, Text, Text, Text,
               Text)

instance (a ~ Text, b ~ a, c ~ a, d ~ a, e ~ a, f ~ a, g ~ a, h ~ a, i ~ a) => Label (a, b, c, d, e, f, g, h, i) where
    labelPairs :: (a, b, c, d, e, f, g, h, i)
-> (a, b, c, d, e, f, g, h, i) -> LabelPairs
labelPairs (a
k1, b
k2, c
k3, d
k4, e
k5, f
k6, g
k7, h
k8, i
k9)
               (a
v1, b
v2, c
v3, d
v4, e
v5, f
v6, g
v7, h
v8, i
v9) =
            [(a
Text
k1, a
Text
v1), (b
Text
k2, b
Text
v2), (c
Text
k3, c
Text
v3), (d
Text
k4, d
Text
v4), (e
Text
k5, e
Text
v5), (f
Text
k6, f
Text
v6),
             (g
Text
k7, g
Text
v7), (h
Text
k8, h
Text
v8), (i
Text
k9, i
Text
v9)]