2016-03-18 4 views
2

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?

+2

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

Répondre

1

FYI, ce problème était de longue date et comme je le regardais aujourd'hui, j'ai remarqué que it had been fixed juste quelques jours avant que vous posiez votre question. Le correctif fait partie de la version actuellement publiée (version 2.5.1.1).