Puede usar ExistentialQuantification
o GADTs
, pero ninguno va a hacer lo que quiera. Nunca podrá hacer aritmética con dos valores de Point2D
. Todo lo que sabes sobre el contenido es que son alguna instancia de de Num. Le está diciendo al compilador que descarte toda otra información sobre ellos. Esto significa que le está diciendo al compilador que descarte cualquier información que pueda tener sobre un par particular de valores de Point2D
que contenga el mismo tipo. Y sin esa información, no podrá hacer ninguna aritmética sobre los valores de dos Point2D
juntos.
Esto casi seguro no es lo que desea. No puede escribir una función distance
, por ejemplo. ¿Qué uso posible podría tener para un tipo tan limitado? Todo lo que puede hacer con ellos es convertir sus contenidos a String
.
Editar:
creo ver lo que estás tratando de hacer. Solo quiere asegurarse de que todo en un Point2D sea un número. No creo que realmente quieras borrar el tipo.
En ese caso, me gustaría ir con la versión GADT, con un cambio muy importante:
{-# LANGUAGE GADTs #-}
data Point2D a where
Point :: (Num a) => a -> a -> Point2D a
El resultado final de esto es que sólo se puede utilizar el constructor Point
con dos valores del mismo instancia de Num, pero no pierdes el tipo. Además, gracias al uso de GADTs
, la coincidencia de patrones en el constructor Point
recupera el contexto numérico para usted, que es básicamente lo que usted esperaría.
Pero creo que lo más importante aquí es no tirar el tipo de contenido. Hacerlo hace que el tipo sea básicamente imposible de trabajar.
En general, es mejor poner sus restricciones de tipo donde realmente se necesitan. No es el tipo de datos, sino los métodos donde se necesita el tipo Num, por lo que debe declararse allí. El sistema tipo se encargará del resto. – amccausl