0
votes

Effets secondaires de déclaration d'instance

dis que je voulais créer une enveloppe pour Uttime : xxx pré>

disons maintenant que je voulais construire une valeur par défaut pour que "maintenant", par exemple p> xxx pré>

ceci (évidemment) échoue avec: P>

   • Couldn't match expected type ‘UTCTime’
                  with actual type ‘IO UTCTime’
    • In the first argument of ‘CustomDateStamp’, namely ‘getCurrentTime’
      In the expression: CustomDateStamp getCurrentTime def
      In an equation for ‘def’: def = CustomDateStamp getCurrentTime def
    |
98  |     def = CustomDateStamp getCurrentTime def
    |                   ^^^^^^^^^^^^^^


1 commentaires

Ce n'est pas une bonne idée. Dans un langage paresseux, il est très difficile de prédire lorsque les expressions sont évaluées, mais nous ne nous soucions pas de ce que la pureté garantit que le résultat final est le même. Votre instance casse cette propriété: let t = def in (t, t) ne devient plus équivalent à (def, def) , car ce dernier peut être évalué avec une paire avec une paire avec une paire différents composants. Plus de manière pragmatique, def ne peut être évalué qu'à l'heure imprimée à l'écran au lieu de la création-temps, causant des horodatages très perplexes.


3 Réponses :


4
votes

à une première approximation: vous ne pouvez pas faire ça. Une fois dans IO, toujours en Io (et il y a déjà une instance par défaut pour io a qui ne fait pas ce que vous voulez). Cuisson un plan différent.


4 commentaires

Techniquement, vous peut le faire avec USAfe-io, mais cela ne fonctionnera pas comme vous vous attendez.


Oui, il y a une deuxième approximation qui est différente de celle du premier. Mais ma réponse et ma recommandation sont debout.


Pensez-vous que la par défaut (io a) instance fournie "devrait" être là à partir d'un point de vue de conception? Je suppose que cela donne une commodité parfois, au coût de la prévention des cas de défaillance - (IO -) - des instances de l'environnement?


@moongoose Les instances d'IO et de fonctions Synergize bien: des bibliothèques qui prennent un rappel, disent, keyEvent -> io () , peuvent être facilement donnés def et c'est une valeur déforme sensée. (essentiellement, ignorer l'événement et ne rien faire). Je pense que je suis assez bien excluant les instances qui font l'Io actuel; En dépit d'aimer par défaut plus que la plupart des haskellers, et donc probablement l'utilisant plus que la plupart des choses, je n'ai vraiment ressenti vraiment aucune douleur de exclure des exemples d'IO passionnantes.



0
votes

Etant donné que getCurrenttime :: ut uttique Vous ne pouvez pas simplement l'appeler. Il n'y a pas de fonction avec type io a -> a

sauf inadaperformio (et d'autres trucs magiques comme celui-ci). Je vous décourage fort de prendre cette route.


4 commentaires

Cela ne fonctionnera toujours pas comme la puissance attend. En fonction des raisons, ce sera parfois le réel actuel, d'autres fois, ce sera un point sur le passé.


En effet, il n'y a pas de moyen significatif comment cela peut fonctionner, mais cela fonctionnera en première approximation. Parce que le compilateur ne cache pas le résultat d'appel de la fonction.


@talex, les résultats des appels de fonction ne sont pas mis en cache, mais cela n'est pas considéré comme un appel de fonction dans ce contexte. Sans optimisation, il sera mis en œuvre à l'aide d'un appel de fonction (appliquer un argument de dictionnaire) et donc vraisemblablement pas mis en cache. Avec l'optimisation, le spécialisateur souleva presque certainement l'appel au niveau supérieur et exécutez l'action io uniquement la première fois qu'un horodatage est demandé.


Le conseil habituel s'applique. Commencer les programmeurs Haskell ne devrait pas utiliser aucun danger dangereux io (sauf ce qui est dans débog.trace ). Les programmeurs de Haskell avancés savent qu'ils ne devraient presque jamais utiliser io . Il y a un très petit nombre de situations où les programmeurs avancés savent qu'ils peuvent l'utiliser en toute sécurité (généralement en combinaison avec le FFI). Dans le reste, ils prendront des soins extrêmes et peuvent bien expédier du code subtilement de buggy jusqu'à ce que quelqu'un vous déclenche. Oui, cela inclut les programmeurs de Haskell avancés qui ont écrit le système d'exécution GHC; Ce genre de choses est dur pour avoir raison.



2
votes

Je jetterais dans le mélange que vous pouvez écrire ceci pour un type dans lequel la valeur par défaut nécessite une action IO, xxx

(facilement réglable pour par exemple, une pile MTL). Un peu controversé parce que le chevauchement est méchant.

edit: nécessite se chevauchant , io CustomDateStamp est plus spécifique que io a devrait sélectionner cette instance en cas de portée.


1 commentaires

Je conviens que cela serait raisonnable dans un monde hypothétique dans lequel les cas qui se chevauchent sont raisonnables. Nous ne vivons pas dans ce monde, cependant.