2012-07-19 5 views
11

Quiero una función que obtenga el tipo de valor en tiempo de ejecución. Ejemplo del uso:¿Cómo obtengo el tipo de valor en Scheme?

(get-type a) 

donde a ha sido define d para ser algún valor Esquema arbitraria.

¿Cómo puedo hacer esto? ¿O debo implementarlo yo mismo, usando una pila cond de boolean?, number?, etc.?

Respuesta

11

En las implementaciones de Scheme con un sistema de objetos similar a Tiny-CLOS, puede simplemente usar class-of. He aquí un ejemplo de sesión de la raqueta, utilizando Swindle:

$ racket -I swindle 
Welcome to Racket v5.2.1. 
-> (class-of 42) 
#<primitive-class:exact-integer> 
-> (class-of #t) 
#<primitive-class:boolean> 
-> (class-of 'foo) 
#<primitive-class:symbol> 
-> (class-of "bar") 
#<primitive-class:immutable-string> 

Y de manera similar con el uso de Guile GooPs:

[email protected](guile-user)> ,use (oop goops) 
[email protected](guile-user)> (class-of 42) 
$1 = #<<class> <integer> 14d6a50> 
[email protected](guile-user)> (class-of #t) 
$2 = #<<class> <boolean> 14c0000> 
[email protected](guile-user)> (class-of 'foo) 
$3 = #<<class> <symbol> 14d3a50> 
[email protected](guile-user)> (class-of "bar") 
$4 = #<<class> <string> 14d3b40> 
4

para comprobar el tipo de algo sólo tiene que añadir un signo de interrogación después del tipo, por ejemplo para comprobar si x es un número:

(define get-Type 
    (lambda (x) 
    (cond ((number? x) "Number") 
      ((pair? x) "Pair") 
      ((string? x) "String") 
      ((list? x) "List")))) 

sólo seguir con eso.

+6

El OP preguntó específicamente si había una alternativa a este enfoque. Además, ¿por qué usar 'si' anidado cuando puedes usar 'cond'? \ * boggles \ * –

+0

@ewein @Chris Jester-Young le falta esto? Para '(get-Type (car (string-> list (number-> string 5))))' esto no devuelve nada. – ArtB

+1

Resulta que en mi caso el bit que faltaba era 'character?'. Para completar, también hay 'vector?'. – ArtB

9

En la raqueta, se puede utilizar el paquete describe por Doug Williams desde el planeta. Funciona así:

> (require (planet williams/describe/describe)) 
> (variant (λ (x) x)) 
'procedure 
> (describe #\a) 
#\a is the character whose code-point number is 97(#x61) and 
general category is ’ll (letter, lowercase) 
+0

Este paquete es realmente útil. Ojalá fuera parte del núcleo de Racket. – Salil

3

Todas las respuestas aquí son útiles, pero creo que la gente ha olvidado de explicar por qué esto podría ser difícil; el estándar Scheme no incluye un sistema de tipo estático, por lo que no se puede decir que los valores tengan solo un "tipo". Las cosas se vuelven interesantes dentro y alrededor de los subtipos (por ejemplo, número frente a coma flotante) y tipos de unión (¿qué tipo le das a una función que devuelve un número o una cadena?).

Si describes un poco más el uso deseado, es posible que descubras que hay respuestas más específicas que te ayudarán más.

+5

Él dice "en tiempo de ejecución", por lo que esto no tiene nada que ver con los tipos estáticos. Son los tipos de valores dinámicos (en tiempo de ejecución) que busca después de – newacct

+0

. Falta el punto de John, en el sentido de que los tipos de tiempo de ejecución dinámico no siempre tienen suficiente información para desambiguar. Ejemplo concreto: digamos que tengo un programa que trata con colores y nombres. Puedo elegir representar valores de estos tipos con solo cadenas. Entonces, si veo la palabra "Gris", no tengo suficiente información para distinguir el tipo porque estoy usando la misma representación. – dyoo

+0

Ídem; puede eliminar la palabra "estática" de mi publicación, y todavía tiene sentido. El ejemplo de Danny es bueno. De hecho, el lenguaje C tiene el mismo problema: no hay operador de "qué es el tipo de este valor", porque muchos valores tienen la misma representación. –

Cuestiones relacionadas