Equivalent of IO Monad in other functional languages?

[Note: learning haskell, not familiar with other functional languages] I have a question about handling impure operations in functional or semi-functional languages other than Haskell (eg OCaml, F#, Scala, ..). Haskell uses the IO monad to (a) cleanly separate pure and impure code, and (b) prevent function-calls from being reordered when they have side-effects that must happen in the right order. How do other languages handle this? AIUI, whether a Haskell function is 'pure' or not can be seen from its method signature : if it returns IO then it is impure. All standard library functions that have side-effects (read/write/etc) return IO, and any function that uses an IO value must return type IO. Do other functional languages (1) use a similar approach, or (2) not provide a way to be certain that a function is 'pure' (side-effect-free)? And AIUI the Haskell compiler/runtime can postpone evaluation of any function (laziness), or reorder function calls whever it thinks this good. However using the monad design pattern (deliberately) prevents this (each operation passes its value as a parameter to the subsequent operation, thus forcing an order of evaluation). Do other languages (a) not support compiler/runtime reordering of functions, or (b) have some other way of preventing functions with side-effects from being reordered? Thanks.. Simon

Hello, F* uses a somewhat similar approach: https://fstar-lang.org/tutorial/ (section 2, Types and Effects) Best regards, Marcin Mrotek

Hello Simon,
If you changed your perspective, you would realize that all functions in
haskell are pure.
A function is pure if it returns the same output if given the same input.
Every monadic function (including functions returning IO) is also pure.
For example,
putStrLn :: String -> IO ()
-- A function that takes a string, and returns an impure computation
-- which, when executed will print the given String.
For any string, putStrLn applied to that same string always describes the
same impure computation, thus the function is actually pure.
I am not familiar with any other functional language, but there are not
many purely functional ones out there [1].
I guess the impure ones get around this issue by giving in to impurity, but
I'm not sure.
I'll be interested in hearing more about the other languages too.
[1] :
http://en.wikipedia.org/wiki/List_of_programming_languages_by_type#Pure
On 15 March 2015 at 22:25, Marcin Mrotek
Hello,
F* uses a somewhat similar approach: https://fstar-lang.org/tutorial/ (section 2, Types and Effects)
Best regards, Marcin Mrotek _______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
-- Regards Sumit Sahrawat

From that perspective isn't every language pure? Haskell's still got "randomIO" and "print <=< readMVar"
Tom
El Mar 15, 2015, a las 13:15, "Sumit Sahrawat, Maths & Computing, IIT (BHU)"
Hello Simon,
If you changed your perspective, you would realize that all functions in haskell are pure. A function is pure if it returns the same output if given the same input. Every monadic function (including functions returning IO) is also pure. For example,
putStrLn :: String -> IO () -- A function that takes a string, and returns an impure computation -- which, when executed will print the given String.
For any string, putStrLn applied to that same string always describes the same impure computation, thus the function is actually pure. I am not familiar with any other functional language, but there are not many purely functional ones out there [1]. I guess the impure ones get around this issue by giving in to impurity, but I'm not sure.
I'll be interested in hearing more about the other languages too.
[1] : http://en.wikipedia.org/wiki/List_of_programming_languages_by_type#Pure
On 15 March 2015 at 22:25, Marcin Mrotek
wrote: Hello,
F* uses a somewhat similar approach: https://fstar-lang.org/tutorial/ (section 2, Types and Effects)
Best regards, Marcin Mrotek _______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
-- Regards
Sumit Sahrawat _______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners

Haskell is impure only when you use the unsafe* functions (atleast that's
how I understand purity).
My understanding is that a language is impure if it allows one to write
arbitrary IO within a function and still give it a proper (mathematical)
function type. In other words impurity arises only if you can unwrap the IO
monad (which is what the unsafe functions do).
The two examples you give above are pure under such a perspective, but I
might be wrong.
On 15 March 2015 at 23:19,
From that perspective isn't every language pure? Haskell's still got "randomIO" and "print <=< readMVar"
Tom
El Mar 15, 2015, a las 13:15, "Sumit Sahrawat, Maths & Computing, IIT (BHU)"
escribió: Hello Simon,
If you changed your perspective, you would realize that all functions in haskell are pure. A function is pure if it returns the same output if given the same input. Every monadic function (including functions returning IO) is also pure. For example,
putStrLn :: String -> IO () -- A function that takes a string, and returns an impure computation -- which, when executed will print the given String.
For any string, putStrLn applied to that same string always describes the same impure computation, thus the function is actually pure. I am not familiar with any other functional language, but there are not many purely functional ones out there [1]. I guess the impure ones get around this issue by giving in to impurity, but I'm not sure.
I'll be interested in hearing more about the other languages too.
[1] : http://en.wikipedia.org/wiki/List_of_programming_languages_by_type#Pure
On 15 March 2015 at 22:25, Marcin Mrotek
wrote: Hello,
F* uses a somewhat similar approach: https://fstar-lang.org/tutorial/ (section 2, Types and Effects)
Best regards, Marcin Mrotek _______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
-- Regards
Sumit Sahrawat
_______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
-- Regards Sumit Sahrawat

Sumit Sahrawat, Maths & Computing, IIT (BHU) wrote:
On 15 March 2015 at 23:19,
wrote: From that perspective isn't every language pure? Haskell's still got "randomIO" and "print <=< readMVar"
Haskell is impure only when you use the unsafe* functions (atleast that's how I understand purity).
My understanding is that a language is impure if it allows one to write arbitrary IO within a function and still give it a proper (mathematical) function type. In other words impurity arises only if you can unwrap the IO monad (which is what the unsafe functions do).
The two examples you give above are pure under such a perspective, but I might be wrong.
You're right, indeed. A language is pure if supplying a value `x` of type `A` to the a function A -> B will always returns the same result, no matter how often or in which order this function is called. This is true for both randomIO :: Random a => IO a (readMVar >=> print) :: Show a => MVar a -> IO () because they return an IO action. This action will always be the same given the same arguments. The language would be impure if these functions had the types randomIO :: Random a => a (readMVar >=> print) :: Show a => MVar a -> () Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com

On 03/16/2015 03:04 PM, Heinrich Apfelmus wrote:
Sumit Sahrawat, Maths & Computing, IIT (BHU) wrote:
On 15 March 2015 at 23:19,
wrote: From that perspective isn't every language pure? Haskell's still got "randomIO" and "print <=< readMVar"
Haskell is impure only when you use the unsafe* functions (atleast that's how I understand purity).
My understanding is that a language is impure if it allows one to write arbitrary IO within a function and still give it a proper (mathematical) function type. In other words impurity arises only if you can unwrap the IO monad (which is what the unsafe functions do).
The two examples you give above are pure under such a perspective, but I might be wrong.
You're right, indeed. A language is pure if supplying a value `x` of type `A` to the a function
A -> B
will always returns the same result, no matter how often or in which order this function is called. This is true for both
randomIO :: Random a => IO a (readMVar >=> print) :: Show a => MVar a -> IO ()
because they return an IO action. This action will always be the same given the same arguments.
The language would be impure if these functions had the types
randomIO :: Random a => a (readMVar >=> print) :: Show a => MVar a -> ()
Maybe I should have phrased my original question differently. Let me try again.. In an imperative language, you can write something like the following pseudocode: String transform(String name) { print "enter greeting:" greeting = read-line-from-stdin return greeting + " " + name } From the "outside", there is no way to tell whether the function "transform" performs IO, mutates global state, mutates its parameter, or anything else. And this is just _normal_ for imperative-programming; if you want to write a unit-test for a method, you need to somehow _know_ what external state it might depend on/affect. And compilers cannot reorder or omit functions because any function might have side-effects. In Haskell, the function signature clearly indicates if this kind of thing is happening - any function like the above will have a return type of IO, thus clearly separating code with side-effects from code without side-effects. I was wondering what other functional or partly-functional languages (OCaml, F#, Scheme etc) do - do they also give the user of a function a way to tell whether the function has IO side-effects (reading/writing) or does the user just need to "consult the documentation" or "read the source code"? Thanks, Simon

On 03/16/2015 03:04 PM, Heinrich Apfelmus wrote:
Sumit Sahrawat, Maths & Computing, IIT (BHU) wrote:
On 15 March 2015 at 23:19,
wrote: From that perspective isn't every language pure? Haskell's still got "randomIO" and "print <=< readMVar"
Haskell is impure only when you use the unsafe* functions (atleast that's how I understand purity).
My understanding is that a language is impure if it allows one to write arbitrary IO within a function and still give it a proper (mathematical) function type. In other words impurity arises only if you can unwrap the IO monad (which is what the unsafe functions do).
The two examples you give above are pure under such a perspective, but I might be wrong.
You're right, indeed. A language is pure if supplying a value `x` of type `A` to the a function
A -> B
will always returns the same result, no matter how often or in which order this function is called. This is true for both
randomIO :: Random a => IO a (readMVar >=> print) :: Show a => MVar a -> IO ()
because they return an IO action. This action will always be the same given the same arguments.
The language would be impure if these functions had the types
randomIO :: Random a => a (readMVar >=> print) :: Show a => MVar a -> ()
Doesn't "pure" correspond to "can write a unit test for"? When a function's return value only ever depends on its inputs, then I can write a set of test-cases for various inputs, and assert that the return-value has the expected content. A function that reads from a file, stdin, etc. cannot be tested in the same way; I cannot _assert_ that the returned value has specific content. Sumit stated earlier that IO is "a pure program that can be executed", which seems similar to your description above (which I admit I don't yet 100% understand). How can I "assert" anything about this "program", or make a Haskell-based application 'safer' in any way by leveraging this kind of 'purity'? Thanks, Simon

Sorry for having strayed towards a different path. I'll try to answer only
your question this time :)
An example from [1], for SML (bottom of the page) shows a function, with
the following type signature in haskell
copyTextFile :: String -> String
One cannot write such a function in haskell that does the same thing
because the example uses IO within a function with a pure looking type.
I'm sure people experienced with other functional languages will have good
examples, so I'll leave it to them.
To answer your second question, I'm still not sure :).
I was just relaying how I understood purity, so that somebody might also
correct me if I'm wrong.
Summarizing the discussion above, a function is pure if it gives the same
output for the same input. Now a function returning 'IO a' always returns
the same IO instructions (these instructions might be impure), but the
function (by the virtue of always returning the same output for the same
inputs) is ultimately pure. Frerich has also raised an important point that
an IO computation might actually depend on some random file, which breaks
this pattern.
[1]: http://www.cs.cornell.edu/courses/cs312/2006fa/recitations/rec09.html
On 16 March 2015 at 20:15, Simon Kitching
On 03/16/2015 03:04 PM, Heinrich Apfelmus wrote:
Sumit Sahrawat, Maths & Computing, IIT (BHU) wrote:
On 15 March 2015 at 23:19,
wrote: From that perspective isn't every language pure? Haskell's still got
"randomIO" and "print <=< readMVar"
Haskell is impure only when you use the unsafe* functions (atleast that's how I understand purity).
My understanding is that a language is impure if it allows one to write arbitrary IO within a function and still give it a proper (mathematical) function type. In other words impurity arises only if you can unwrap the IO monad (which is what the unsafe functions do).
The two examples you give above are pure under such a perspective, but I might be wrong.
You're right, indeed. A language is pure if supplying a value `x` of type `A` to the a function
A -> B
will always returns the same result, no matter how often or in which order this function is called. This is true for both
randomIO :: Random a => IO a (readMVar >=> print) :: Show a => MVar a -> IO ()
because they return an IO action. This action will always be the same given the same arguments.
The language would be impure if these functions had the types
randomIO :: Random a => a (readMVar >=> print) :: Show a => MVar a -> ()
Doesn't "pure" correspond to "can write a unit test for"? When a function's return value only ever depends on its inputs, then I can write a set of test-cases for various inputs, and assert that the return-value has the expected content.
A function that reads from a file, stdin, etc. cannot be tested in the same way; I cannot _assert_ that the returned value has specific content.
Sumit stated earlier that IO is "a pure program that can be executed", which seems similar to your description above (which I admit I don't yet 100% understand). How can I "assert" anything about this "program", or make a Haskell-based application 'safer' in any way by leveraging this kind of 'purity'?
Thanks, Simon
_______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
-- Regards Sumit Sahrawat

Frerich, the function would still be pure, even if it returns a poisoned recipe as you say. Thus, a little thought leads me to believe that the pattern would still not break if no unsafe* functions are used. On 16 March 2015 at 20:28, Sumit Sahrawat, Maths & Computing, IIT (BHU) < sumit.sahrawat.apm13@iitbhu.ac.in> wrote:
Sorry for having strayed towards a different path. I'll try to answer only your question this time :)
An example from [1], for SML (bottom of the page) shows a function, with the following type signature in haskell
copyTextFile :: String -> String
One cannot write such a function in haskell that does the same thing because the example uses IO within a function with a pure looking type.
I'm sure people experienced with other functional languages will have good examples, so I'll leave it to them.
To answer your second question, I'm still not sure :). I was just relaying how I understood purity, so that somebody might also correct me if I'm wrong.
Summarizing the discussion above, a function is pure if it gives the same output for the same input. Now a function returning 'IO a' always returns the same IO instructions (these instructions might be impure), but the function (by the virtue of always returning the same output for the same inputs) is ultimately pure. Frerich has also raised an important point that an IO computation might actually depend on some random file, which breaks this pattern.
[1]: http://www.cs.cornell.edu/courses/cs312/2006fa/recitations/rec09.html
On 16 March 2015 at 20:15, Simon Kitching
wrote: On 03/16/2015 03:04 PM, Heinrich Apfelmus wrote:
Sumit Sahrawat, Maths & Computing, IIT (BHU) wrote:
On 15 March 2015 at 23:19,
wrote: From that perspective isn't every language pure? Haskell's still got
"randomIO" and "print <=< readMVar"
Haskell is impure only when you use the unsafe* functions (atleast that's how I understand purity).
My understanding is that a language is impure if it allows one to write arbitrary IO within a function and still give it a proper (mathematical) function type. In other words impurity arises only if you can unwrap the IO monad (which is what the unsafe functions do).
The two examples you give above are pure under such a perspective, but I might be wrong.
You're right, indeed. A language is pure if supplying a value `x` of type `A` to the a function
A -> B
will always returns the same result, no matter how often or in which order this function is called. This is true for both
randomIO :: Random a => IO a (readMVar >=> print) :: Show a => MVar a -> IO ()
because they return an IO action. This action will always be the same given the same arguments.
The language would be impure if these functions had the types
randomIO :: Random a => a (readMVar >=> print) :: Show a => MVar a -> ()
Doesn't "pure" correspond to "can write a unit test for"? When a function's return value only ever depends on its inputs, then I can write a set of test-cases for various inputs, and assert that the return-value has the expected content.
A function that reads from a file, stdin, etc. cannot be tested in the same way; I cannot _assert_ that the returned value has specific content.
Sumit stated earlier that IO is "a pure program that can be executed", which seems similar to your description above (which I admit I don't yet 100% understand). How can I "assert" anything about this "program", or make a Haskell-based application 'safer' in any way by leveraging this kind of 'purity'?
Thanks, Simon
_______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
-- Regards
Sumit Sahrawat
-- Regards Sumit Sahrawat

Hi, I also used to share this "Every function in Haskell is pure, as long as it does not use any of the unsafe* functions" view but by now I'm wondering whether that's really a useful definition. It may be true that putStrLn :: String -> IO () is pure in the sense that it only yields a 'recipe' for printing the given string instead of actually printing it. However, I think it's important to realize that putStrLn *could* actually yield a poisoned recipe, something which not *only* prints a string but which also plays a sound at 4AM. And the types won't let you know whether this is the case. Hence, even though putStrLn may be pure in the classical 'same input yields same output' sense, I wondr whether it's more useful to consider putStrLn to be impure on the grounds that a value of type 'IO a' means "anything can happen, and whatever happens doesn't necessarily only depend on the arguments". On 2015-03-15 18:57, Sumit Sahrawat, Maths & Computing, IIT (BHU) wrote:
Haskell is impure only when you use the unsafe* functions (atleast that's how I understand purity).
My understanding is that a language is impure if it allows one to write arbitrary IO within a function and still give it a proper (mathematical) function type. In other words impurity arises only if you can unwrap the IO monad (which is what the unsafe functions do).
The two examples you give above are pure under such a perspective, but I might be wrong.
On 15 March 2015 at 23:19,
wrote: From that perspective isn't every language pure? Haskell's still got "randomIO" and "print <=< readMVar"
Tom
El Mar 15, 2015, a las 13:15, "Sumit Sahrawat, Maths & Computing, IIT (BHU)"
escribió: Hello Simon,
If you changed your perspective, you would realize that all functions in haskell are pure. A function is pure if it returns the same output if given the same input. Every monadic function (including functions returning IO) is also pure. For example,
putStrLn :: String -> IO () -- A function that takes a string, and returns an impure computation -- which, when executed will print the given String.
For any string, putStrLn applied to that same string always describes the same impure computation, thus the function is actually pure. I am not familiar with any other functional language, but there are not many purely functional ones out there [1]. I guess the impure ones get around this issue by giving in to impurity, but I'm not sure.
I'll be interested in hearing more about the other languages too.
[1] : http://en.wikipedia.org/wiki/List_of_programming_languages_by_type#Pure [1]
On 15 March 2015 at 22:25, Marcin Mrotek
wrote: Hello, F* uses a somewhat similar approach: https://fstar-lang.org/tutorial/ [2] (section 2, Types and Effects)
Best regards, Marcin Mrotek
_______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners [3]
--
Regards
Sumit Sahrawat
_______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners [3]
--
Regards
Sumit Sahrawat
Links: ------ [1] http://en.wikipedia.org/wiki/List_of_programming_languages_by_type#Pure [2] https://fstar-lang.org/tutorial/ [3] http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
_______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
-- Frerich Raabe - raabe@froglogic.com www.froglogic.com - Multi-Platform GUI Testing

Frerich Raabe wrote:
I also used to share this "Every function in Haskell is pure, as long as it does not use any of the unsafe* functions" view but by now I'm wondering whether that's really a useful definition. It may be true that
putStrLn :: String -> IO ()
is pure in the sense that it only yields a 'recipe' for printing the given string instead of actually printing it. However, I think it's important to realize that putStrLn *could* actually yield a poisoned recipe, something which not *only* prints a string but which also plays a sound at 4AM. And the types won't let you know whether this is the case.
Hence, even though putStrLn may be pure in the classical 'same input yields same output' sense, I wondr whether it's more useful to consider putStrLn to be impure on the grounds that a value of type 'IO a' means "anything can happen, and whatever happens doesn't necessarily only depend on the arguments".
Well, purity of functions is still a useful concept, because it provides a useful invariant in the types. For instance, the well-known function map :: (a -> b) -> [a] -> [b] may assume that the first argument always returns equal results given equal arguments and hence can be applied in any order and as often as desired. On the other hand, mapM :: (a -> IO b) -> [a] -> IO [b] may not assume that and must be careful about the sequence of operations. Of course, an action IO a means that "anything can happen", but I don't think it's useful to call that "impure". It's a good thing that the nastiness of the `IO` type constructor is separated cleanly from the properties of the function arrow `->`. That leaves the question of how to reason about `IO` programs. This is explored in detail in Simon Peyton-Jones' tutorial "Tackling the awkward squad: monadic input/output, concurrency, exceptions, and foreign-language calls in Haskell" http://research.microsoft.com/en-us/um/people/simonpj/papers/marktoberdorf/ You may also like "The Operational Monad Tutorial", which doesn't cover IO, but tries to explain how other monads can be understood and implemented in terms of operational semantics: http://apfelmus.nfshost.com/articles/operational-monad.html Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com

Scalaz implements IO and ST as a library for Scala. http://eed3si9n.com/learning-scalaz/IO+Monad.html On 16/03/15 02:17, Simon Kitching wrote:
[Note: learning haskell, not familiar with other functional languages]
I have a question about handling impure operations in functional or semi-functional languages other than Haskell (eg OCaml, F#, Scala, ..).
Haskell uses the IO monad to (a) cleanly separate pure and impure code, and (b) prevent function-calls from being reordered when they have side-effects that must happen in the right order. How do other languages handle this?
AIUI, whether a Haskell function is 'pure' or not can be seen from its method signature : if it returns IO then it is impure. All standard library functions that have side-effects (read/write/etc) return IO, and any function that uses an IO value must return type IO. Do other functional languages (1) use a similar approach, or (2) not provide a way to be certain that a function is 'pure' (side-effect-free)?
And AIUI the Haskell compiler/runtime can postpone evaluation of any function (laziness), or reorder function calls whever it thinks this good. However using the monad design pattern (deliberately) prevents this (each operation passes its value as a parameter to the subsequent operation, thus forcing an order of evaluation). Do other languages (a) not support compiler/runtime reordering of functions, or (b) have some other way of preventing functions with side-effects from being reordered?
Thanks.. Simon _______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners

On Sun, Mar 15, 2015, at 09:17 AM, Simon Kitching wrote:
And AIUI the Haskell compiler/runtime can postpone evaluation of any function (laziness), or reorder function calls whever it thinks this good.
It's not that it "can" but that it must. Haskell's evaluation strategy is a part of the language specification. Consider this expression: let f = 1 : f in take 5 f You can paste this into ghci and feel confident that it's going to terminate. You're not at the whim of the runtime. I think you may find these articles interesting: https://wiki.haskell.org/Lazy_evaluation https://wiki.haskell.org/Non-strict_semantics -Karl

Karl Voelker wrote:
On Sun, Mar 15, 2015, at 09:17 AM, Simon Kitching wrote:
And AIUI the Haskell compiler/runtime can postpone evaluation of any function (laziness), or reorder function calls whever it thinks this good.
It's not that it "can" but that it must. Haskell's evaluation strategy is a part of the language specification.
Consider this expression:
let f = 1 : f in take 5 f
You can paste this into ghci and feel confident that it's going to terminate. You're not at the whim of the runtime.
I think you may find these articles interesting:
https://wiki.haskell.org/Lazy_evaluation https://wiki.haskell.org/Non-strict_semantics
Strictly speaking, the Haskell language standard only specifies that Haskell has non-strict semantics, not that it needs to be evaluated using lazy evaluation. Of course, the two are related. I have tried to expand on the details here: https://hackhands.com/non-strict-semantics-haskell Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com

Hi Heinrich,
Thanks for confirming my concepts. It took me a long time pondering over
what it meant to be purely functional.
Great articles btw (+1).
On 16 March 2015 at 19:41, Heinrich Apfelmus
Karl Voelker wrote:
On Sun, Mar 15, 2015, at 09:17 AM, Simon Kitching wrote:
And AIUI the Haskell compiler/runtime can postpone evaluation of any function (laziness), or reorder function calls whever it thinks this good.
It's not that it "can" but that it must. Haskell's evaluation strategy is a part of the language specification.
Consider this expression:
let f = 1 : f in take 5 f
You can paste this into ghci and feel confident that it's going to terminate. You're not at the whim of the runtime.
I think you may find these articles interesting:
https://wiki.haskell.org/Lazy_evaluation https://wiki.haskell.org/Non-strict_semantics
Strictly speaking, the Haskell language standard only specifies that Haskell has non-strict semantics, not that it needs to be evaluated using lazy evaluation.
Of course, the two are related. I have tried to expand on the details here:
https://hackhands.com/non-strict-semantics-haskell
Best regards, Heinrich Apfelmus
-- http://apfelmus.nfshost.com
_______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
-- Regards Sumit Sahrawat
participants (8)
-
amindfv@gmail.com
-
Frerich Raabe
-
Heinrich Apfelmus
-
Karl Voelker
-
Marcin Mrotek
-
Simon Kitching
-
Sumit Sahrawat, Maths & Computing, IIT (BHU)
-
Tony Morris