2012-09-01 4 views
0

Dans un problème similaire à celui montré dans this question, est-il possible d'avoir une expression Haskell de type "générique" a? Quelque chose comme,Haskell: expression de type "générique"

myExpression :: a

Je suis nouveau à Haskell, mais de ce que j'ai été voir ce ne peut être atteint.

+0

Une meilleure question pourrait être "pourquoi voudriez-vous faire cela?" Il pourrait être utile dans un langage orienté objet, mais dans Haskell ce ne serait pas très utile du tout. – MathematicalOrchid

+0

À ce moment-là, j'étais curieux de savoir si cela pouvait être réalisé ou non, mais maintenant je peux vraiment voir l'utilité de l'expression du bas et sa relation avec les fonctions partielles, les fonctions strictes et non strictes et la stratégie d'évaluation. – acrespo

Répondre

7

Non, il n'y a rien qui satisfait autre que le fond, par ex.

myExpression = myExpression 

-- or, 

myExpression = undefined 

Est-il possible raisonnable qu'il pourrait être possible? Une expression non-bottom qui est à la fois Integer et de type Maybe (String -> IO()) (par exemple).


De plus, étant donné the question you mention, une réponse qui a prouvé que la seule fonction non-fond avec la signature de type a -> a est id, nous avons une preuve qu'il ne peut pas être une expression non-fond avec le type a. S'il y avait, alors

f _ = myExpression 

pourrait avoir le type a -> a, ce qui est ni id, ni en bas, à savoir une contradiction.

1

Vous pouvez lire cette signature de type que "pour tous les types un, MyExpression est de type un". Cela signifie que myExpression doit avoir une valeur qui existe dans tous les types. Mathématiquement parlant, aucune valeur de ce type n'existe, car et pourraient être des «blaireaux» ou des «choses qui ne sont pas des blaireaux», et ces deux ensembles sont nécessairement distincts.

Dans le système de type Haskell, la seule valeur valide pour myExpression à prendre est undefined, alias bottom.

1

Alors que de façon abstraite il n'y a qu'une seule valeur qui a le type "a", en bas, il existe une variété d'interprétations possibles à l'exécution.

myExpression = myExpression 

Cela ne s'arrêtera jamais.

myExpression = undefined 

Cela (lors de l'utilisation GHC) print "* Exception: Prelude.undefined"

myExpression = error "Hello! 

Ce imprimera "* Exception: Bonjour!" Le comportement de cette version de bas dépend des bibliothèques que vous avez importées.

Puisque vous posez des questions sur un type "générique", vous pourriez vouloir dire le type de choses qui peuvent utilement contenir n'importe quelle valeur.Dans ce cas, jetez un oeil à Data.Dynamic, ce qui vous permet de convertir tout ce qui a une représentation en mémoire à une valeur de type "Dynamique". Plus tard, lorsque vous utilisez une valeur de type "Dynamique", vous pouvez essayer de le transformer en un type plus spécifique avec lequel vous pouvez réellement faire quelque chose d'utile.

+0

Il est à noter que tout en transformant les choses en «Dynamic» et en retour est possible, c'est loin d'être conseillé, surtout pour les débutants. @acrespo: Le type 'a' représente tout type que vous aimez, donc si vous avez une fonction' a -> Bool', vous pouvez l'utiliser sur n'importe quoi, mais si c'est de type 'Num a => a -> Bool' , vous pouvez l'utiliser sur n'importe quel type qui est un type Num'eric. Ainsi 'a' signifie" tout type que vous aimez "- vous n'avez pas besoin de trouver quelque chose de type' a' pour utiliser cette fonction. Assurez-vous d'étudier les types et les classes de chapitre de _Learn You a Haskell for Great Good_, http://learnyouahaskell.com/. – AndrewC