Pregunta

Yo soy muy novato Haskell, aunque tenía una experiencia Lisp / Scheme anterior. En este momento estoy buscando en los ejemplos de SICP y tratando de ponerlas en práctica en Haskell para obtener más experiencia práctica. En la conferencia 3b autores presentan una función para el cálculo de los derivados simbólicamente. Contiene, entre otras, las siguientes líneas:

(define (deriv exp var)
    (cond ((constant? exp var) 0)
          ((same-var? exp var) 1)
; ...

Además, en la conferencia, se definen algunas funciones más:

(define (constant? exp var)
    (and (atom? exp)
         (not (eq? exp var))))

¿Hay una manera de hacer lo mismo en Haskell, es decir, comprobar si la atomicidad y la equivalencia simbólica a alguna otra función? O más en general, ¿cuáles son los medios de "desmontar" funciones en Haskell?

¿Fue útil?

Solución

Sus ejemplos Esquema realidad no se examinan funcionamiento del Esquema. Hace poco hice alguna diferenciación simbólica en Haskell sobre valores del tipo siguiente:

data Exp a = Lit a
           | Exp a :*: Exp a
           | Exp a :+: Exp a
           | Var String
  deriving Eq

En lugar de discriminar usando atom? o eq? utiliza case (u otra coincidencia de patrones) y ==.

Otros consejos

En primer lugar, aunque SICP es genial, se lo recomiendo en contra de ella para aprender Haskell. (#) Parte de la dificultad de esta pregunta se deriva de esto.

En Lisp / Scheme, un 'función' se cree de una pieza de código, y el examen de una función simplemente significa examinar su código. En Haskell, un 'función' significa algo más cercano a su definición matemática, como una mapa de un conjunto a a un conjunto B. Así, por ejemplo, tiene sentido, en el contexto de Lisp, para comparar dos funciones: simplemente comparar su código. (Pero son (x+y)^2 y x^2+2*x*y+y^2 diferentes funciones?) En Haskell, que depende de si existe un procedimiento constructivo para la determinación de la igualdad para la clase de funciones que está considerando.

Del mismo modo, al igual que en su pregunta, en Lisp / Scheme, podría escribir una función de "deriva" que diferencia correctamente cuando se les expresiones, y sólo los errores o se devuelve basura en las entradas arbitrarias. Bajo el sistema de tipos de Haskell, esto es (que yo sepa) imposible de hacer, porque, si se piensa en ello, no hay tal cosa como la diferenciación de una entrada arbitraria: sólo se puede diferenciar una expresión (o, posiblemente, una clase más general, pero todavía no todo). Así como en la respuesta de Norman Ramsey, se define primero un tipo de "Expresión" (o clase de tipo), lo que es muy sencillo de hacer, y luego escribir la función

derive :: Expression -> Expression

que desmonta un Expression usando las construcciones de patrones de coincidencia (o algo más dependiendo de cómo se construyeron Expressions).


(#): La razón es que SICP tiene una filosofía completamente diferente, que implica el uso de un lenguaje de programación sin tipo y el fomento de la falta de distinción entre el código y los datos. Aunque hay algo de mérito en el "código = datos" argumento (por ejemplo, el hecho de que en la arquitectura von Neumann que utilizamos, "todo es 0s y 1s de todos modos"), no es necesariamente una buena manera de razonar acerca de o problemas de modelado. (Véase de Philip Wadler ¿Por qué es mejor que Calculando Scheming para obtener más información.) Si desea leer un libro con un sabor Haskell funcional en lugar de una mundo real uno, tal vez de Simon Thompson Haskell: El arte de la programación funcional o Richard de pájaro Introducción a la programación funcional Haskell utilizando son mejores opciones.

No creo que se puede hacer eso. Lisp es homoiconic , Haskell es no.

Sin embargo, además de buscar en Google aparecido Liskell , que es (?) Un híbrido interesante.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top