Вы можете использовать ExistentialQuantification
или GADTs
, но ни один из них не будет делать то, что вы хотите.Вы никогда не сможете выполнять арифметику с двумя значениями Point2D
.Все, что вы знаете о содержимом, это то, что они какой-то экземпляр Num.Вы говорите компилятору отказаться от всей остальной информации о них.Это означает, что вы говорите компилятору отказаться от любой информации, которая может иметь, что конкретная пара значений Point2D
содержит один и тот же тип.А без этой информации вы не сможете выполнять арифметику значений из двух Point2D
вместе.
Это почти наверняка не то, что вы хотите.Например, вы не можете написать функцию distance
.Какое возможное использование вы могли бы использовать для такого ограниченного типа?Все, что вы можете с ними сделать, - это преобразовать их содержимое в String
.
Редактировать:
Я думаю, что вижу, что вы пытаетесь сделать.Вы просто хотите убедиться, что все в Point2D является числом.Я не думаю, что вы действительно хотите стереть тип.
В этом случае, я бы пошел с версией GADT, с одним действительно важным изменением:
{-# LANGUAGE GADTs #-}
data Point2D a where
Point :: (Num a) => a -> a -> Point2D a
Конечный результат этогов том, что вы можете использовать конструктор Point
только с двумя значениями одного и того же экземпляра Num, но вы не потеряете тип.Кроме того, благодаря использованию GADTs
, сопоставление с образцом в конструкторе Point
восстанавливает для вас контекст Num, чего, как правило, и следовало ожидать.
Но я думаю, что самое важное здесь невыбрасывая тип содержимого.Это делает тип практически невозможным для работы.