Il est une bibliothèque qui fournit un type de données F
et une fonction de typeComment terminer un calcul qui s'exécute dans la monade `IO`?
ffoldlIO :: (b -> a -> IO b) -> b -> F a -> IO b
La fonction est similaire à
foldlIO :: (b -> a -> IO b) -> b -> [a] -> IO b
foldlIO f a = \xs -> foldr (\x r (!a') -> f a' x >>= r) return xs a
Je me demande si foldlIO
(et donc ffoldlIO
) peut fonctionner dans un court -circuit de mode.
Considérons cet exemple:
example1 :: IO Int
example1 = foldlIO (\a x -> if a < 4 then return (a + x) else return a) 0 [1..5]
Ici foldlIO
parcourt toute la liste, mais si l'on jette une exception pour arrêter le calcul et l'attraper? Quelque chose comme ceci:
data Terminate = Terminate
deriving (Show)
instance Exception Terminate
example2 :: IO Int
example2 = do
ra <- newIORef 0
let step a x
| a' < 4 = return a'
| otherwise = writeIORef ra a' >> throwIO Terminate
where a' = a + x
foldlIO step 0 [1..] `catch` \(_ :: Terminate) -> readIORef ra
Est-ce fiable? Y at-il un meilleur moyen de terminer un calcul qui s'exécute dans la monade IO
(et aucune autre monade) ou suis-je pas censé faire cela du tout?
C'est plus ou moins ce que j'ai écrit aussi. 'ContT' est (in) célèbre pour être dur pour les débutants, donc plus de commentaires aideraient aussi. Je suggère aussi d'ajouter 'lift (putStrLn" foo ") >> ...' quelque part pour montrer comment faire pour IO dans 'ContT _ IO _'. – chi
Ce calcul s'exécute dans 'ContT Int IO Int' au lieu de' IO' plaine comme j'ai demandé. Je vais modifier la question pour la rendre moins confuse, désolé. – user3237465
"vous pouvez définir votre propre version de' foldM' "- Je ne peux pas: la bibliothèque fournit seulement' ffoldlIO' et c'est beaucoup trop compliqué pour implémenter mon propre 'foldM'. Les listes dans la question sont juste pour un exemple de ce que je veux réaliser. – user3237465