6
votes

Quelle est une fonction paramétralement polymorphe?

Quelqu'un peut-il m'expliquer cela par rapport aux algorithmes de tri?


12 commentaires

Qu'entendez-vous par "recherches"?


Par rapport à un atout d'entiers


Eh bien, en un mot, c'est un Transformation naturelle . Mais en disant que cela ne fait que compliquer les choses.


@Lunar: Quicksort (comme d'autres fonctions de tri) ne pourrait jamais être implémentée comme une fonction paramétrymorphe paramétriquement. Raison: pour le tri, la fonction doit comparer les valeurs; Mais: puisque la fonction devrait fonctionner pour tous les types de types , il n'est pas garanti que les valeurs sont comparables (il existe de nombreux types dont les valeurs ne sont pas comparables).


Voir aussi Stackoverflow.com/questions/ 5671303 / ...


@Phynfo à moins qu'ils adhèrent à une interface commune, non? Je ne sais pas si Haskell permet à cela ou pas?


@Phynfo: une fonction de tri ne prendrait généralement que la fonction de comparaison comme l'un des arguments, comme dans la réponse d'Erisco. En fait, le premier endroit que j'ai jamais vu une fonction supérieure d'ordre était qsort dans la bibliothèque standard C.


Une chose à noter est la différence entre le polymorphisme paramétrique et les fonctions surchargées. Une fonction surchargée, comme show ( tostring dans java) se comporte de manière spécifique à un type, alors que les fonctions polymorphes paramétriques se comportent de manière indépendante de type. Les deux peuvent fonctionner sur "tous types" disponibles pour la langue.


@Alexandrec. Ce ne doit pas nécessairement être une transformation naturelle, car les types de données paramétriques n'ont pas besoin d'être foncé.


@Tomellis: C'est presque toujours le cas, n'est-ce pas? En fait, je ne trouve pas de type de données non foncé.


@Alexandrec. Que diriez-vous de Data FOO A = FOO A = FOO (A -> INT) ou barre de données A = bar (a -> a) ?


Le premier est foncé (bien que contrevriertly), la seconde n'est en effet pas (à moins que l'on ne limite à l'isomorphismes d'une manière ou d'une autre). Maintenant quelle est une fonction paramétrique (a -> a) -> b ?


3 Réponses :



7
votes

Une fonction agnostique aux types d'arguments qu'il fonctionne.

# preforming on integers
linear_search (==) 5 [1,2,3,4,5]
# returns Just 5

# preforming on strings
linear_search (elem) 'e' ["doctor", "apron", "horse", "sky"]
# returns Just "horse"


1 commentaires

Tout d'abord, il existe un B dans (A -> B -> bool) -> a -> [b] -> peut-être b . Deuxièmement, il devrait être juste x au lieu de juste n .



8
votes

Permettez-moi d'essayer la chose la plus simple que je puisse.

Supposons que vous ayez une paire d'entiers: p> xxx pré>

et supposons que vous voulez une fonction qui échange la position des entiers sur cette paire sur cette paire. Vous pouvez faire cela: p> xxx pré>

mais maintenant si vous avez besoin d'une fonction similaire pour double code> s, vous devez la mettre en œuvre againting: p> xxx pré>

Vous devez noter quelques éléments: (1) les codes de swapdouble code> et swapint code> sont identiques sauf leur Type Signatures, (2) Nulle part dans le code que vous faites référence à tout ce qui dépend de quels sont les types de x code> et y code>. Ce code est valide quels que soient leurs types. Il devrait donc y avoir un moyen d'écrire le code une seule fois et de permettre au compilateur spécialiser le code automatiquement pour chaque type dont vous avez besoin. La façon de faire c'est le polymorphisme paramétrique. Pour ce cas particulier, vous pouvez écrire: p> xxx pré>

Qu'est-ce que cela signifie? Vous dites au compilateur: il y a un échange de fonction, qui prend une paire (X, Y) où X est de type A et Y de type B et renvoie la paire (Y, X). A et B peuvent être n'importe quel type, cette fonction s'appelle ainsi une fonction polymorphe. Lorsque vous appliquez Swap code> sur une paire spécifique, le compilateur vérifiera le type de cette paire et instanciera automatiquement une version de cette fonction adéquate pour votre tuple. P>

Par exemple: P>

swap ('a', 1) = (1,'a')  -- in this case swap :: (Char, Int) -> (Int, Char) 
swap ( 0 , 5) = (5, 0 )  -- in this case swap :: (Int , Int) -> (Int, Int )


0 commentaires