Как индексировать тип «элемент» по значению «контейнер источника»?

Итак, у меня есть ситуация, очень похожая на этот (очень упрощенный) код:

import Data.Maybe
import Data.List

data Container a = Container [a] 

-- Assumption: an Element can only obtained from a Container.  The operation
-- guarentees the Element is in the Container.
data Element a = Element (Container a) a

-- This operation is only valid for Elements that have the same Container.
before :: Eq a => Element a -> Element a -> Bool
before (Element (Container xs) x) (Element (Container ys) y) 
    | xs == ys = fromJust (elemIndex x xs) < fromJust (elemIndex y xs)
    | otherwise = error "Elements from different Containers"

Как я могу использовать Haskell 'Система типов s (или расширения GHC) для ограниченияbefore и аналогичные операции от взятияElementс разныхContainers? Я'мы смотрели вGADTs а такжеDataKinds но, ну, этоЭто займет много времени, и я мог бы использовать некоторые предложения или указатели. (Еще одна идея, которую ямы думали, но еще нет: использовать такой же трюк, какST монадыs параметр ...)

Я слишком пессимистичен, если решу, что для этого потребуется язык с зависимой типизацией? Потому что, поскольку мое ограниченное понимание зависимой типизации идет, я думаю, что яя пытаюсь проиндексироватьElement тип по значениямContainer тип.

РЕДАКТИРОВАТЬ: Просто для дополнительного цвета, все это в конечном итоге возникает, потому что яЯ пытаюсь определить что-то очень похожее на это:

import Data.Function
import Data.Ix

-- I want to use Elements as Array indexes; so Elements need to know
-- their Container to calculate their Int
instance Eq a => Ix (Element a) where
    -- Ignore how crap this code is
    range (l, u) = map (getSibling l) [getIndex l .. getIndex u]
    index (l,u) i = index (getIndex l, getIndex u) (getIndex i)
    inRange (l,u) i = inRange (getIndex l, getIndex u) (getIndex i)

getIndex :: Eq a => Element a -> Int
getIndex (Element (Container xs) x) = fromJust $ elemIndex x xs

getList :: Element a -> [a]
getList (Element (Container xs) _) = xs

getSibling :: Element a -> Int -> Element a
getSibling (Element (Container xs) _) i = Element (Container xs) (xs!!i)

instance Eq a => Eq (Element a) where
    (==) = (==) `on` getIndex

instance Eq a => Ord (Element a) where
    compare = compare `on` getIndex

Весь этот код требует, чтобы вы никогда "микс» Elementс разныхContainers.

Ответы на вопрос(2)

Ваш ответ на вопрос