Обертка побочных эффектов в чистых языках программирования

Я изучаю возможные способы получения вычислительных эффектов на чистом языке программирования.

Монады обычно представляют как способ обернуть побочные эффекты чистыми языками. Но я не понимаю, как они помогают. Проблема, которую я вижу, в том, что монады можно копировать или отбрасывать.

На чистом языке результат операции должен зависеть только от ее аргументов. Но на гипотетическом языке с

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 на два пути a1 а также a2. Или все эффекты задерживаются до тех пор, пока не будет выбран один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

Кажется, что это состояние необратимо изменено и к нему нельзя получить доступ снова. Таким образом, все результаты вызовов функций действительно зависят только от их аргументов.

0 ответов

Другие вопросы по тегам