Si je définisComment définir une fonction d'ordre supérieur qui applique une fonction polymorphique à un type spécifique
fun id x = x
alors naturellement id
est de type 'a -> 'a
Bien sûr, id 0
évalue à 0
, ce qui rend Sens parfait.
Depuis ce sens parfait, je devrais pouvoir résumer par une fonction:
fun applyToZero (f: 'a -> 'a) = f 0
Avec l'espoir que applyToZero
aura le type ('a -> 'a) -> int
et applyToZero id
évaluera à 0
Mais quand je essayer de définir applyToZero
comme ci-dessus, SML/NJ donne un message d'erreur impair qui commence:
unexpected exception (bug?) in SML/NJ: Match [nonexhaustive match failure]
raised at: ../compiler/Elaborator/types/unify.sml:84.37
Cela ressemble presque à un bogue dans le compilateur lui-même. Bizarre, mais possible.
Mais PolyML n'aime pas non plus (bien que son message d'erreur est moins étrange):
> fun applyToZero (f: 'a -> 'a) = f 0;
poly: : error: Type error in function application.
Function: f : 'a -> 'a
Argument: 0 : int
Reason: Can't unify int to 'a (Cannot unify with explicit type variable)
Found near f 0
Ce qui suit fonctionne le:
fun ignoreF (f: 'a -> 'a) = 1
avec le type inféré ('a -> 'a) -> int
. Cela montre qu'il n'est pas impossible de créer une fonction d'ordre supérieur de ce type.
Pourquoi SML n'accepte-t-il pas ma définition de applyToZero
? Y at-il une solution de contournement qui me permettra de le définir de sorte que son type est ('a -> 'a) -> int
?
Motivation: dans ma tentative de résoudre le puzzle this question, j'ai pu définir une fonction tofun
de type int -> 'a -> 'a
et une autre fonction fromfun
avec la propriété désirée qui fromfun (tofun n) = n
pour tous les entiers n
. Cependant, le type déduit de mon travail fromfun
est ('int -> 'int) -> 'int)
. Toutes mes tentatives d'ajouter des annotations de type pour que SML l'accepte comme ('a -> 'a) -> int
ont échoué. Je ne veux pas montrer ma définition de fromfun
puisque la personne qui a posé cette question pourrait encore travailler sur ce puzzle, mais la définition de applyToZero
déclenche exactement les mêmes messages d'erreur.
Haskell prend en charge les types les mieux classés décrits par Andreas. [Voici quelques cas d'utilisation pratiques] (http://stackoverflow.com/questions/1476480/what-uses-have-you-found-for-higher-rank-types-in-haskell) [StackOverflow]. Pédanterie mineure: Vous ne pouvez pas appliquer une fonction à un type dans SML, car SML n'a pas de fonctions au niveau du type (ou de types dépendants). –