Question

J'ai souvent trouver ce modèle dans le code Haskell:

options :: MVar OptionRecord
options = unsafePerformIO $ newEmptyMVar

...

doSomething :: Foo -> Bar
doSomething = unsafePerformIO $ do
  opt <- readMVar options
  doSomething' where ...

Fondamentalement, on a un dossier d'options ou quelque chose de similaire, qui est initialement fixé au lancement du programme.En tant que programmeur est paresseux, il ne veut pas porter le options enregistrement de tous les coins du programme.Il définit un MVar pour garder défini par une vilaine utilisation de unsafePerformIO.Le programmeur assure, que l'état est défini qu'une seule fois et avant toute opération a eu lieu.Maintenant, chaque partie du programme a utiliser unsafePerformIO encore une fois, juste pour extraire les options.

À mon avis, une telle variable est considérée comme de façon pragmatique pur (ne me tapez pas).Est-il une bibliothèque qui fait abstraction de ce concept à l'écart et s'assure que la variable est définie qu'une fois, c'est à direqu'aucun appel n'est fait avant que l'initialisation et que l'on ne doit pas écrire unsafeFireZeMissilesAndMakeYourCodeUglyAnd DisgustingBecauseOfThisLongFunctionName

Était-ce utile?

La solution

Si vous utilisez MVar pour la tenue de paramètres ou quelque chose de similaire, pourquoi n'essayez-vous pas de lecteur de monade?

foo :: ReaderT OptionRecord IO ()
foo = do
    options <- ask
    fireMissiles

main = runReaderT foo (OptionRecord "foo")

(Et Lecteur régulier si vous n'avez pas besoin IO :P)

Autres conseils

Ceux qui serait essentiel du commerce référentielle de transparence pour un peu de temporaire commodité méritent ni la pureté, ni la commodité.

C'est une mauvaise idée.Le code que vous êtes à la recherche de ce est mauvais code.*

Il n'y a pas moyen de les envelopper ce modèle en toute sécurité, car il n'est pas sûr modèle.Ne pas le faire dans votre code.Ne cherchez pas un moyen sûr de le faire.Il n'y a pas un moyen sûr de le faire.Mettre le unsafePerformIO sur le sol, lentement, et en arrière loin de la console...

*Il existe des raisons légitimes que les gens utilisent de haut niveau MVars, mais ces raisons ont à voir avec les liaisons à l'étranger de code pour la plupart, ou de quelques autres choses, lorsque l'autre est très salissant.Dans ces cas-là, autant que je sache, cependant, le haut niveau MVars sont pas accessible à partir de derrière unsafePerformIO.

Utiliser les paramètres implicites.Ils sont un peu moins lourd que de faire de chaque fonction Reader ou ReaderT dans son type.Vous ne devez changer le type de signatures de vos fonctions, mais je pense qu'un tel changement peut être scripté.(Serait sympa de faire une fonction pour un Haskell IDE.)

Il y a une raison importante pour ne pas utiliser ce modèle.Autant que je sache, dans

options :: MVar OptionRecord
options = unsafePerformIO $ newEmptyMVar

Haskell donne aucune garantie que options seront évaluées qu'une seule fois.Depuis le résultat de option est une pure valeur, il peut être memoized et réutilisés, mais il peut aussi être recalculés pour chaque appel (c'est à direinline) et le sens du programme ne doit pas changer (contrairement à votre cas).

Si vous décidez d'utiliser ce modèle, veillez à ajouter {-# NOINLINE options #-}, sinon il pourrait se inline et votre programme échoue!(Et par ce que nous sommes en train de sortir de la garantie donnée par la langue et le type de système et en s'appuyant uniquement sur la mise en œuvre d'un compilateur.)

Ce sujet a été largement discuté et solutions possibles sont bien résumées sur Haskell Wiki en Haut niveau de l'état mutable.Actuellement, il n'est pas possible en toute sécurité résumé ce modèle sans compilateur supplémentaires de soutien.

J'ai souvent trouver ce modèle dans le code Haskell:

Lire un code différent.

En tant que programmeur est paresseux, il ne veut pas transporter les options d'enregistrement de tous les coins du programme.Il définit un MVar à garder - défini par une vilaine utilisation de unsafePerformIO.Le programmeur assure, que l'état est défini qu'une seule fois et avant toute opération a eu lieu.Maintenant, chaque partie du programme est d'utiliser unsafePerformIO encore une fois, juste pour extraire les options.

Des sons comme littéralement exactement ce que le lecteur monade accomplit, sauf que le lecteur monade t-il de façon sécuritaire.Au lieu de s'adaptant à votre propre paresse, il suffit d'écrire réelle du bon code.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top