让 IO monad 中的绑定中间结果
Let-binding intermediate results in IO monad
鉴于此背景:
open import IO
open import Data.String
open import Data.Unit
open import Coinduction
postulate
A : Set
f : String → A
g₁ g₂ : A → String
假设我想实现类似
的东西
foo : IO ⊤
foo = ♯ readFiniteFile "input.txt" >>= \s →
♯ (♯ putStrLn (g₁ (f s)) >>
♯ putStrLn (g₂ (f s)))
通过let
绑定中间结果f s
。我希望这会起作用:
foo₁ : IO ⊤
foo₁ = ♯ readFiniteFile "input.txt" >>= \s →
let x = f s in
♯ (♯ putStrLn (g₁ x) >>
♯ putStrLn (g₂ x))
但这失败了
Not implemented: coinductive constructor in the scope of a
let-bound variable
所以我试着搬出 ♯
:
foo₂ : IO ⊤
foo₂ = ♯ readFiniteFile "input.txt" >>= \s →
♯ (let x = f s in
♯ putStrLn (g₁ x) >>
♯ putStrLn (g₂ x))
和以前一样的问题。
我通过取消 ♯
ening 步骤成功解决了这个问题:
_>>′_ : ∀ {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)
但是为什么 "inlined" 版本不起作用?
仅供参考,这个问题是一个长期存在的问题,当我今天查看它时,我注意到 it had been fixed 就在您提出问题的前几天。该修复是当前发布版本(版本 2.5.1.1)的一部分。
鉴于此背景:
open import IO
open import Data.String
open import Data.Unit
open import Coinduction
postulate
A : Set
f : String → A
g₁ g₂ : A → String
假设我想实现类似
的东西foo : IO ⊤
foo = ♯ readFiniteFile "input.txt" >>= \s →
♯ (♯ putStrLn (g₁ (f s)) >>
♯ putStrLn (g₂ (f s)))
通过let
绑定中间结果f s
。我希望这会起作用:
foo₁ : IO ⊤
foo₁ = ♯ readFiniteFile "input.txt" >>= \s →
let x = f s in
♯ (♯ putStrLn (g₁ x) >>
♯ putStrLn (g₂ x))
但这失败了
Not implemented: coinductive constructor in the scope of a let-bound variable
所以我试着搬出 ♯
:
foo₂ : IO ⊤
foo₂ = ♯ readFiniteFile "input.txt" >>= \s →
♯ (let x = f s in
♯ putStrLn (g₁ x) >>
♯ putStrLn (g₂ x))
和以前一样的问题。
我通过取消 ♯
ening 步骤成功解决了这个问题:
_>>′_ : ∀ {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)
但是为什么 "inlined" 版本不起作用?
仅供参考,这个问题是一个长期存在的问题,当我今天查看它时,我注意到 it had been fixed 就在您提出问题的前几天。该修复是当前发布版本(版本 2.5.1.1)的一部分。