Dans ce contexte:Laissez-lier les résultats intermédiaires dans monade IO
open import IO
open import Data.String
open import Data.Unit
open import Coinduction
postulate
A : Set
f : String → A
g₁ g₂ : A → String
disons que je veux mettre en œuvre quelque chose comme
foo : IO ⊤
foo = ♯ readFiniteFile "input.txt" >>= \s →
♯ (♯ putStrLn (g₁ (f s)) >>
♯ putStrLn (g₂ (f s)))
par let
-binding le résultat intermédiaire f s
. J'espérais cela fonctionnerait:
foo₁ : IO ⊤
foo₁ = ♯ readFiniteFile "input.txt" >>= \s →
let x = f s in
♯ (♯ putStrLn (g₁ x) >>
♯ putStrLn (g₂ x))
mais cette tentative échoue avec
Non implémenté: constructeur CoInductive dans le cadre d'un laisser lié variables
donc j'ai essayé de sortir le ♯
:
foo₂ : IO ⊤
foo₂ = ♯ readFiniteFile "input.txt" >>= \s →
♯ (let x = f s in
♯ putStrLn (g₁ x) >>
♯ putStrLn (g₂ x))
même problème que précédemment.
j'ai réussi à contourner ce il suffit de soulever le ♯
pas forcement:
_>>′_ : ∀ {a} {A B : Set a} → IO A → IO B → IO B
m >>′ m′ = ♯ m >> ♯ m′
foo₂ : IO ⊤
foo₂ = ♯ readFiniteFile "input.txt" >>= \s →
♯ let x = f s in
putStrLn (g₁ x) >>′ putStrLn (g₂ x)
mais pourquoi est-ce que le travail si la version « inline » ne fonctionne pas?
J'ai jeté un coup d'œil sur les projets que j'ai lancés avec «IO» et j'ai fini par faire le même genre de choses. Et ils fonctionnent bien. Ulf [IO] (https://github.com/UlfNorell/agda-prelude/blob/master/src/Prelude/IO.agda) pourrait être plus agréable à travailler: c'est une monade traditionnelle plutôt qu'un type coinductif (mais cela signifie également que vous devez supposer que tous les fichiers que vous traitez sont finis). – gallais