2009-11-11 15 views
9

¿Hay alguna noción de calidad de puntero en Haskell? == requiere que las cosas deriven Eq, y tengo algo que contiene a (Valor -> Valor IO), y ni -> ni IO derivan Eq.Pointer equality in Haskell?

EDITAR: Estoy creando un intérprete para otro idioma que tiene tiene igualdad de puntero, así que estoy tratando de modelar este comportamiento al tiempo que puedo usar las funciones de Haskell para modelar cierres.

EDIT: Ejemplo: Quiero una función special que hacer esto:

> let x a = a * 2 
> let y = x 
> special x y 
True 
> let z a = a * 2 
> special x z 
False 

Respuesta

10

EDIT: Dado su ejemplo, podría modelar esto con la mónada IO. Simplemente asigne sus funciones a IORefs y compárelas.

Prelude Data.IORef> z <- newIORef (\x -> x) 
Prelude Data.IORef> y <- newIORef (\x -> x) 
Prelude Data.IORef> z == z 
True 
Prelude Data.IORef> z == y 
False 
+0

Solo quiero ver si las dos funciones que obtengo son de hecho la misma función. Estoy intentando crear un intérprete para otro idioma que tenga igualdad de puntero, y quiero imitar este comportamiento. – Claudiu

+2

Pero, ¿qué significa exactamente la misma función? (\ x -> x) es la misma función que (\ x -> x). La misma función que ((\ x y -> y) x), etc. Creo que lo que necesita es un dato adicional para rastrear la "dirección" de una función en su idioma interpretado. Una mónada que modele a a -> (Int, a) coalgebra podría estar en orden. – Apocalisp

+1

Tristemente tenemos el caso evil = ID {unId = const undefined} también, por lo que su ejemplo no es 100% verdadero. Esos molestos fondos. :) – Tirpen

3

IORefs derivan Ec. No entiendo qué más necesitas para obtener la igualdad del puntero.

Editar: Las únicas cosas que tiene sentido para comparar la igualdad del puntero son estructuras mutables. Pero como mencioné anteriormente, estructuras mutables, como IORefs, ya instancia Eq, que le permite ver si dos IORefs son de la misma estructura, que es exactamente la igualdad del puntero.

+0

lo siento, he solucionado mi pregunta. IO no deriva Eq, y tampoco lo hacen las funciones. Quiero probar si dos funciones son la misma función. – Claudiu

+0

Pero los IO no son "punteros". No veo lo que significaría compararlos. ¿Puede dar un ejemplo? – newacct

+0

No puede comparar dos funciones para ver si son iguales. Por ejemplo, podría escribir "foo x = 2 * x" y "bar x = x + x". Claramente foo y bar son iguales porque para todo x, foo x == bar x, pero en el caso general esto es indecidible. Sé que no es exactamente lo que querías; quieres una comparación "puede ser funciones diferentes". Pero no, Haskell no tiene eso. –

8

La igualdad del puntero rompería referential transparency, entonces NO.

Tal vez sorprendentemente, en realidad es possible para calcular extensional equality de funciones totales en compact spaces, pero en general (por ejemplo las funciones de los números enteros con la posible falta de terminación) esto es imposible.


EDIT: Estoy creando un intérprete para otro idioma

¿Puedes mantener el AST programa original o la ubicación de la fuente junto con las funciones Haskell que los haya traducido en? Parece que quieres "igualdad" basada en eso.

+3

Estoy bastante seguro de que las frases 'extensional equality' y' compact topology' no están en la jerga común. – yfeldblum

+1

las frases 'igualdad extensional' y' topología compacta' son las frases que me mantienen alejada de intentarlo haskell –

+0

Interesante enlace. Mi primer pensamiento fue "este tipo está hablando basura". Pero no estamos hablando de funciones generales, estamos hablando de _computable_ functions. Eso hace toda la diferencia. – Thomas

5

== requiere cosas que se deriva la ecuación

realidad (==) requiere una ejemplo de la ecuación, no necesariamente un deriva ejemplo. Lo que probablemente necesite hacer es proporcionar su propia instancia de Eq que simplemente ignora la parte (Value -> IO Value). Por ejemplo,

data D = D Int Bool (Value -> IO Value) 

instance Eq D where 
    D x y _ == D x' y' _ = x==x && y==y' 

¿Eso ayuda, tal vez?

+1

I ¿piensas que quieres decir 'x == x''? – mipadi

+0

sí, y lo hice por ahora – Claudiu

+1

Sí, 'x == x'' es lo que quise decir. –

3

Estoy creando un intérprete para otra lengua que tiene la igualdad puntero, así que estoy tratando de modelo de este comportamiento sin dejar de ser capaz de utilizar funciones Haskell para modelar cierres.

Estoy bastante seguro de que para escribir un intérprete así, su código debe ser monádico. ¿No tienes que mantener algún tipo de entorno o estado? Si es así, también podría mantener un contador para cierres de funciones. Por lo tanto, cada vez que creas un nuevo cierre lo equipas con una identificación única. Luego, para la equivalencia del puntero, simplemente compare estos identificadores.

3

Otra forma de hacerlo es explotar StableNames.

Sin embargo, special tendría que devolver sus resultados dentro de la mónada de IO a menos que desee abusar de UnsafePerformIO.

La solución IORef requiere IO durante la construcción de su estructura. La comprobación de StableNames solo lo usa cuando desea verificar la igualdad referencial.

+1

Esta es una solución bastante buena para verificar la igualdad de funciones, aunque 'StableName's no siempre son equivalentes cuando intuitivamente parece que pueden serlo. Solo quería agregar un enlace a los documentos: http://hackage.haskell.org/package/base-4.7.0.2/docs/System-Mem-StableName.html –