Question

J'ai écrit une fonction en haskell qui prend un peu de paramètres comme Word32, Chaîne d'ignorer (nourrissage) et les sorties IO Word32.Maintenant, c'est un la fonction dans le vrai sens du terme: pour les mêmes entrées, la sortie sera toujours la même.Il n'y a pas d'effets secondaires.La raison, la fonction renvoie IO Word32 au lieu de Word32 est que la fonction de mises à jour nombre de 32 bits de registres à Décalage à Rétroaction Linéaire (lfsr) et d'autres registres plusieurs fois dans une boucle pour calculer la finale Word32 de sortie.

Ma question est la suivante:Étant donné que cette fonction effectivement n'a pas d'effets secondaires, est-il possible de cacher ce registre mises à jour à l'intérieur de la fonction de mise en œuvre, de sorte que la fonction renvoie Word32 et pas IO Word32?Si oui, comment?

Était-ce utile?

La solution

Oui!Haskell peut le faire.

La ST monade

Si vous utilisez réellement mutable état (registres), qui sont entièrement cachée de l'observateur en dehors de la fonction, alors vous êtes dans la ST monade, une monade pour les effets de mémoire seulement.Vous entrez dans le monde via ST runST, et lorsque vous quittez la fonction, tous les effets sont garantis de ne pas être visible.

C'est précisément le droit de calcul environnement de travail avec les locaux, mutable état.

Purement fonctionnelle de l'état:l'État de monade

Si, toutefois, vous n'êtes pas en train de muter, des registres ou des cellules, mais plutôt de la mise à jour d'un point de vue purement fonctionnel de la valeur à de nombreuses reprises, la simplification de l'environnement est disponible: l'État de monade.Ceci ne permet pas mutable état, mais donne une illusion de l'état local.

IO, et unsafePerformIO

Enfin, si vous avez locales, mutable effets, comme dans le ST monade, mais pour une raison ou une autre, vous allez avoir besoin d'opérations d'e / s sur cet état (comme par exemple via une institution financière étrangère appel), vous pouvez simuler le ST monade, avec presque autant de sécurité, en utilisant unsafePerformIO, au lieu de runST, à introduire un local IO environnement.Comme le IO monade n'ont pas de belles types d'appliquer l'abstraction, vous devrez manuellement vous assurer que les effets secondaires ne seront pas observables.

Autres conseils

Si vous avez importé cette fonction à l'aide de la FFI, il suffit de retirer le IO à partir du type de retour.Autre chose, l'utilisation unsafePerformIO :: IO a -> a à partir de System.IO.Unsafe.Veuillez noter que cette fonction est l'une des plus dangereuses fonctions en Haskell.Ne l'utilisez pas, si vous n'êtes pas vraiment shure sur les conséquences.Mais pour votre but, il semble correct.

Oui, ce serait une utilisation légitime d'UNSAREPERFORMIO. Mais ça ne va que si vous êtes vraiment sûr qu'il n'y ait aucun effet visible.

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