2011-07-25 8 views
10

Esto probablemente no sea posible, ya que ya revisé la lista de todas las extensiones de GHC y esto no está allí, pero pensé que lo haría por si acaso.En Haskell puedo hacer literales numéricos no polimórficos por defecto?

¿Hay alguna manera de hacerlo de modo que 2 tiene tipo Int (o Integer) en lugar de la habitual Num a => a?

(La razón por la que me gustaría este comportamiento es que hace que los mensajes de error sean más claros y que la inferencia sea más probable (especialmente con las clases de tipo). Siempre pude escribir (2 :: Int) en todas partes, pero más bien, el comportamiento "más seguro" es el menos explícito)

+1

sí, no lo hagas :) la inferencia tipo generalmente no es tan mala. ¿tal vez si publica un problema de ejemplo, las personas pueden ayudarlo a solucionarlo de otra manera? puede establecer los valores predeterminados a través de http://www.haskell.org/tutorial/numbers.html. también puede desarrollar prototipando los tipos de funciones de nivel superior fijándolos en 'f = undefined :: DesiredType', y eliminarlos adecuadamente. – gatoatigrado

+0

Las constantes polimórficas no me impiden hacer nada, pero sí hacen que los mensajes de error sean menos directos, por lo general cambian "no podría coincidir con el tipo esperado ..." a un "sin instancia para ...". Los valores predeterminados no suelen permitir deducir una instancia para una clase (y se siente como un hack) – Owen

Respuesta

13

Hay una manera (un poco abusiva e inconveniente) de hacer esto usando extensiones GHC.

{-# LANGUAGE RebindableSyntax #-} 

import qualified Prelude as P 
import Prelude hiding (Num(..)) 

fromInteger :: Integer -> Integer 
fromInteger = id 

En GHCi:

> :set -XRebindableSyntax 
> :t 2 
2 :: Integer 

Con la extensión RebindindableSyntax habilitado, GHC usar cualquier fromInteger está en el ámbito de manejar literales numéricos. La única restricción es que debe tomar un argumento de tipo Integer (en realidad, incluso esto no es obligatorio, pero si no lo hace obtendrá un error de tipo de literales numéricos).

Tenga en cuenta que, dado que el estándar fromInteger es parte de la clase Num, es posible que necesite modificar algunas cosas para que todo funcione correctamente.

+1

Hmm, quizás lo mejor es ocultar 'fromInteger':' import Preludio oculto (Num (fromInteger)) ' – luqui

+0

Gracias ! Probé esto y obtiene exactamente el comportamiento que quiero ... aunque es un poco prolijo (también hace incómoda la aritmética, pero de todos modos no hago aritmética). – Owen

+0

@luqui: Quizás. No estoy seguro de la parte superior de mi cabeza si se oculta solo que tendría resultados extraños al usar otras funciones en 'Num'. –

4

Creo que debería agregar "default()" a estas respuestas, aunque creo que Gatoatigrado lo mencionó de pasada. El estándar Haskell 98 tiene un section 4.3.4 que finalmente describe cómo alterar algunos valores predeterminados de Num a => a. La orden de incumplimiento implícita está dada por

default (Integer, Double) 

y se puede cambiar, p. poniendo

default (Int) 

o

default() 

en el archivo de origen.

Cuestiones relacionadas