Question

Je me demandais s'il est possible de faire correspondre contre les mêmes valeurs pour plusieurs fois avec les installations de correspondance de motif de langages de programmation fonctionnelle (Haskell / F # / Caml).

Il suffit de penser l'exemple suivant:

plus a a = 2 * a
plus a b = a + b

La première variante serait appelée lorsque la fonction est appelée avec deux valeurs similaires (qui serait stocké dans a).

Une application plus utile serait ce (simplifier un AST).

simplify (Add a a) = Mult 2 a

Mais Haskell rejette ces codes et me met en garde contre contradictoires définitions pour a - Je dois faire le cas explicite / si-chèques au lieu de savoir si la fonction a des valeurs identiques. Y at-il astuce pour indiquer qu'une variable je veux faire correspondre aura lieu plusieurs fois?

Était-ce utile?

La solution

est appelé modèle non linéaire . Il y a eu plusieurs discussions sur la liste de diffusion haskell-café à ce sujet, il n'y a pas longtemps. Voici deux:

http://www.mail-archive.com/ haskell-cafe@haskell.org/msg59617.html

http://www.mail-archive.com/ haskell-cafe@haskell.org/msg62491.html

Bottom line:. Il est impossible de mettre en œuvre, mais il a été décidé contre par souci de simplicité

Par ailleurs, vous n'avez pas besoin if ou case pour contourner ce; le moyen (légèrement) plus propre est d'utiliser un garde:

a `plus` b
  | a == b = 2*a
  | otherwise = a+b

Autres conseils

Vous ne pouvez pas avoir deux paramètres avec le même nom pour indiquer qu'ils doivent être égaux, mais vous pouvez utiliser gardes pour distinguer les cas comme celui-ci:

plus a b
  | a == b    = 2 * a
  | otherwise = a + b

Ceci est plus souple car il travaille également pour des conditions plus complexes que la simple égalité.

Je viens de regarder les fils de la liste de diffusion figurant dans la réponse de Thomas, et la première réponse dans l'un d'entre eux fait le bon sens, et explique pourquoi un tel « modèle » ne serait pas beaucoup de sens en général: ce si a est une fonction ? (Il est impossible en général de le vérifier deux fonctions sont égales.)

Haskell ne fait pas l'unification.

Je l'ai mis en place un nouveau langage de programmation fonctionnelle qui peut gérer des modèles non-linéaires dans Haskell.

https://github.com/egison/egison

Dans ma langue, votre fonction plus en écrit comme suit.

(define $plus
  (match-lambda [integer integer]
    {[[$a ,a] (* a 2)]
     [[$a $b] (+ a b)]}))
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top