1

我正在研究在纯编程语言中产生计算效果的可能方法。

Monads 通常作为一种在纯语言中包装副作用的方式呈现。不过,我看不出他们有什么帮助。我看到的问题是可以复制或丢弃单子。

在纯语言中,操作的结果应该只取决于它的参数。但是用一种假设的语言

putStrLn :: String -> IO ()

编码

let a = putStrLn "1"
let b = putStrLn "2"
in ()

将获取类型Unit并且无法捕获副作用的存在。

我以后也可以

let a1 = do
  _ <- a
  _ <- putStrLn "2.1"
let a2 = do
  _ <- a
  _ <- putStrLn "2.2"
in ()

大概将(不是最新的)状态a分为两条路径a1a2. 还是所有效果都延迟到IO ()从主函数返回一个选定的术语?然后我想知道如何编译保持可变状态的可复制单子(当单子确实分歧时,在什么时候以及如何复制状态?)

相比之下,独特的类型似乎能够自然地捕捉到唯一一个上下文的存在

putStrLn :: 1 IO () -> String -> 1 IO ()

main :: 1 IO () -> 1 IO ()
main io = 
  let a = putStrLn io "1"
  let b = putStrLn a "2"

  // compile error, a has type 0 IO ()
  // let a1 = putStrLn a "2.1"
  in b

这似乎捕捉到状态被不可逆转地修改并且无法再次访问。因此,函数调用的所有结果确实只取决于它们的参数。

4

0 回答 0