Я думаю, что хитрость в том, что вы не применяете это на уровне типов, вы используете «умные конструкторы»: то есть разрешаете создание таких «кортежей» только через функцию, которая генерирует такие значения:
module Test(MyType,x,y,z,createMyType) where
data MyType = MT { x :: Int, y :: Int, z :: Int }
createMyType :: Int -> Int -> MyType
createMyType myX myY = MT { x = myX, y = myY, z = 5 - myX - myY }
Если вы хотите сгенерировать все возможные такие значения, то вы можете написать для этого функцию с заданными или указанными границами.
Вполне возможно, можно использовать церковь уровня типаЦифры или что-то подобное для обеспечения их создания, но это почти определенно слишком много работы для того, что вы, вероятно, хотите / нуждаетесь.
Это может быть не то, что вы хотите (т. Е. «За исключением использования just (x,y), поскольку z = 5 - x - y "), но это имеет больше смысла, чем пытаться установить какое-то принудительное ограничение на уровне типов для допустимых значений.
Типы могут обеспечить правильный" тип "ценность (не каламбур);чтобы гарантировать достоверность значений, вы скрываете конструктор и разрешаете создание только с помощью утвержденных функций, которые гарантируют любые необходимые вам инварианты.