Question

Je suis un débutant Haskell, mais une expérience Lisp / schéma précédent. En ce moment, je regarde les exemples de SICP et d'essayer de les mettre en œuvre en Haskell pour obtenir plus d'expérience pratique. Dans la conférence 3b auteurs présentent une fonction permettant de calculer les dérivées de façon symbolique. Il contient, entre autres, les lignes suivantes:

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

De plus, dans la conférence, quelques fonctions sont définies:

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

Est-il possible de le faire même chose en Haskell, à savoir vérifier l'atomicité et l'équivalence symbolique à une autre fonction? Ou plus général, quels sont les moyens de « désassembler » fonctions dans Haskell?

Était-ce utile?

La solution

Vos exemples Scheme n'examinent pas réellement les fonctions Scheme. J'ai fait récemment une certaine différenciation symbolique dans Haskell sur les valeurs du type:

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

Au lieu de discrimination à l'aide atom? ou eq? vous utilisez case (ou autre correspondance de motif) et ==.

Autres conseils

Tout d'abord, bien que SICP est grande, je recommande contre pour l'apprentissage Haskell. (#) Une partie de la difficulté à cette question découle de cette situation.

Dans Lisp / Scheme, un 'fonction' est pensée d'un morceau de code, et l'examen d'une fonction signifie simplement examiner son code. Dans Haskell, un « fonction » signifie quelque chose plus proche de la définition mathématique, comme la carte d'un ensemble a à un ensemble B. Ainsi, par exemple, il judicieux, dans le contexte Lisp, pour comparer deux fonctions: il suffit de comparer leur code. (Mais sont (x+y)^2 et x^2+2*x*y+y^2 différentes fonctions?) Dans Haskell, cela dépend de l'existence d'une procédure constructive pour déterminer l'égalité pour la classe des fonctions que vous envisagez.

De même, dans votre question, en Lisp / Scheme, vous écririez une fonction « Dérivation » qui différencie correctement lorsque donné les expressions, et à quelques erreurs sur ou renvoie les déchets sur les entrées arbitraires. En vertu du système de type de Haskell, c'est (AFAIK) impossible de le faire, parce que, si vous y pensez-il n'y a pas une telle chose comme différenciant une entrée arbitraire: vous ne pouvez distinguer une expression (ou peut-être une classe plus générale, mais pas encore tout). Alors que dans la réponse de Norman Ramsey, vous devez d'abord définir un type « d'expression » (ou classe de type), ce qui est très simple à faire, puis écrire la fonction

derive :: Expression -> Expression

qui démonte un Expression en utilisant les constructions de filtrages (ou quelque chose d'autre selon la façon dont Expressions ont été construites).


(#): La raison est que SICP a une philosophie tout à fait différente, ce qui implique l'utilisation d'un langage de programmation typées et en encourageant une absence de distinction entre le code et les données. Bien qu'il y ait un certain mérite à l'argument « code = données » (par exemple le fait que sur l'architecture de von Neumann nous utilisons, « tout est 0 et de 1 de toute façon »), ce n'est pas nécessairement une bonne façon de raisonner sur ou des problèmes de modélisation. (Voir Pourquoi est meilleur que Calcul Scheming pour en savoir plus.) Si vous voulez lire un livre Haskell avec une saveur fonctionnelle au lieu d'un monde réel un, peut-être Simon Thompson Haskell: Le métier de la programmation fonctionnelle ou de Richard Bird introduction à la programmation fonctionnelle en utilisant Haskell sont de meilleurs choix.

Je ne pense pas que vous pouvez le faire. Lisp est homoiconic , Haskell n'est pas.

Cependant, d'autres recherches sur Google mis en place Liskell , qui est (?) Un hybride intéressant.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top