Lorsque j'essaie de compiler ceci:
Could not deduce (t ~ U.MVector s a)
from the context (U.Unbox a)
bound by the inferred type of myRead :: U.Unbox a => t -> a
at src/Main.hs:53:1-32
`t' is a rigid type variable bound by
the inferred type of myRead :: U.Unbox a => t -> a
at src/Main.hs:53:1
Expected type: U.MVector (PrimState (ST s)) a
Actual type: t
In the first argument of `MV.read', namely `mv'
In the second argument of `($)', namely `MV.read mv 0'
In the expression: runST $ MV.read mv 0
3 Réponses :
Le compilateur par défaut de voir l'argument MV code> sur le côté gauche à partir d'un type spécifique, mais nécessite quelque chose de type polymorphe à droite. Une signature de type peut corriger les choses. mhead :: MV.Unbox a => MV.MVector s a -> ST s a
mhead mv0 = MV.read mv0 0
mrx = runST $ do mv <- UV.unsafeThaw $ UV.enumFromStepN 0 1 20
-- ^^^ or however the mv is generated.
x <- MV.unsafeRead mv 17 -- arbitrary 'scratch pad'
MV.unsafeWrite mv 17 (2*x) -- computations
mhead mv
-- ^^^ we return just the first element, after all the mutation
La réponse par Applicatif vous indique comment amener votre code à compiler. Mais le code ne sera pas utilisable: le point de Maintenant tout matrice mutable que vous créez quelque part aura de type Il semble qu'il y ait un problème plus tôt qui vous a fait vouloir avoir cette fonction (impossible). P> runst code> est que le calcul impératif ne peut pas s'échapper, en raison de la variable de type liée existante là-bas. P>
mvector SA code> pour un fixe em> s, tandis que votre myread code> attend une valeur qui fournit une valeur fournie Un vecteur pour tout em> s. p>
Je conviens que c'est une fonction indésirable, j'essayais d'expliquer l'erreur de type. Est l'explication inepte? Si oui, je devrais le supprimer. Je pensais à l'écrivain comme un accroché à la manière dont l'inférence de type fonctionne avec St.
@Applicatif non, l'explication va bien. Ajouter peut-être que la fonction serait inutilisable, de sorte que les deux réponses ont ce fait important.
Je ne peux pas dire que j'ai compris une grande partie de ce que vous avez dit ci-dessus, cependant, je me demandais si vous pouviez plus expliquer pourquoi cette fonction est impossible. Le contexte est que j'ai une fonction qui prend dans un vecteur mutable, fait quelques calculs utilisant le vecteur mutable comme un espace à gratter temporaire, puis doit renvoyer une valeur de flotteur. Parce que je me fiche des changements sur le vecteur mutable, je me demandais s'il y avait un moyen d'ignorer son "changement d'état" et de renvoyer simplement l'une des valeurs de l'intérieur.
Il existe une manière multiple pour une fonction ne pas pure. Une évidence est si elle modifie les données. MyRead code> ne fait pas cela, et il semble vous faire croire que cela devrait être donc possible de le définir avec un type pur. Mais une autre cause d'impureté est si la valeur de la fonction dépend, par ex. le temps qu'il est évalué. Et ceci est le cas ici: myread code> appliqué à un vecteur donnera des résultats différents pour le même vecteur, si le vecteur a été modifié entre les deux. Par conséquent, myread code> doit avoir un type monadique.
Les autres réponses sont bonnes, mais je pense qu'il y a une chose fondamentale à propos de ST que vous manquez. Chaque appel à Runst fait efficacement un nouvel "ST Universe" dans lequel un code impératif est exécuté. Donc, si vous avez un appel à Downst pour faire le tableau et un appel séparé à Runst pour obtenir une valeur de cette matrice, les choses ne peuvent pas être fonctionnelles. Les deux appels à Runst veulent leurs propres univers uniques, alors que vous voulez qu'ils partagent un. P>
Quelles sont les réponses expliquées dans certains détails, c'est la manière dont ces univers uniques sont créés par une supercherie de type type. P>
Cette. Runst code> est censé avoir l'air pur de l'extérieur, et rien de mutable ne peut s'échapper du St code> monad.
Je pense que l'opinion du sage, de Viz Breitner et de Fischer, c'est que nous devons en savoir plus sur la façon dont vous êtes arrivé à ce point. Quelle fonction produisent le vecteur mutable que vous proposez d'appliquer maread? Voir la dernière phrase de la réponse de Breitner. Si nous savions ce que nous vous mettais dans ce coin, nous pourrions dire comment réanifier les choses afin qu'elles pendent ensemble. Quelques lignes de code supplémentaires seraient donc utiles. Par exemple, si
MV code> est à l'intérieur d'un bloc ST, la définition plus simplemradre mv = mv.read mv 0 code> (norunst code>) pourrait être utilisé .Permettez-moi de renforcer ce que l'application a dit: nous avons besoin de plus de contexte. Sans savoir ce que vous voulez réellement atteindre, nous ne pouvons pas trouver la solution appropriée.