Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
435 views
in Technique[技术] by (71.8m points)

io - How do functional languages model side-effects?

Since side-effects break referential transparency, don't they go against the point of functional languages?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

There are two techniques that are used by purely functional programming languages to model side effects:

1) A world type that represents external state, where each value of that type is guaranteed by the type system to be used only once.

In a language that uses this approach the function print and read might have the types (string, world) -> world and world -> (string, world) respectively.

They might be used like this:

let main w =
  let w1 = print ("What's your name?", w) in
  let (name, w2) = read w1 in
  let w3 = print ("Your name is " ^ name, w2) in
  w3

But not like this:

let main w =
  let w1 = print ("What's your name?", w) in
  let (name, w2) = read w in
  let w3 = print ("Your name is " ^ name, w2) in
  w3

(because w is used twice)

All built-in functions with side-effects would take and return a world value. Since all functions with side-effects are either built-ins or call other functions with side-effects, this means that all functions with side-effects need to take and return a world.

This way it is not possible to call a function with side-effects twice with the same arguments and referential transparency is not violated.

2) An IO monad where all operations with side effects have to be executed inside that monad.

With this approach all operations with side effects would have type io something. For example print would be a function with type string -> io unit and read would have type io string.

The only way to access the value of performing operation would be to use the "monadic bind" operation (called >>= in haskell for example) with the IO operation as one argument and a function describing what to do with the result as the other operand.

The example from above would look like this with monadic IO:

let main =
  (print "What's your name?") >>=
  (lambda () -> read >>=
  (lambda name -> print ("Your name is " ^ name)))

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...