
Following is a simple program which uses monadic type binder. I dont understand that how can the last labda function 'F2' has access to value 'val1' since it was passed to the input of 'F1' and was not an input to 'F2' (>>?) :: Maybe a -> (a -> Maybe b) -> Maybe b Nothing >>? _ = Nothing Just v >>? f = f v var_access_test val = Just (val, (val + 1)) >>? \(val1, s) -> Just (s, (s + 1)) >>? -- F1 \(val2, s) -> Just (val, (val1, (val2, (s)))) -- F2 -- I guess -- F2 :: (Int, Int) -> Maybe (Int, (int, (Int. Int))) -- So how can the F2 function return 'val1' even though it was not an input to it. -- output of var_access_test 3 -- Just (3,(3,(4,5))) Although this might be something very trivial but I am stuck here and not able to understand how this is working. (considering the functions to be pure they can only access values passed to them as input). - Divam

I dont understand that how can the last labda function 'F2' has access to value 'val1' since it was passed to the input of 'F1' and was not an input to 'F2'
This is ONE nested function, not F1 >>? F2:
\(val1, s) -> | Just (s, (s + 1)) >>? -- F1
\(val2, s) -> Just (val, (val1, (val2, (s)))) | -- F2
The vertical bars delineate the body of the \(val1,s) abstraction. That's
why val1 is still in scope in the second line.
-- Kim-Ee
On Sat, Dec 29, 2012 at 8:14 AM, Divam
Following is a simple program which uses monadic type binder. I dont understand that how can the last labda function 'F2' has access to value 'val1' since it was passed to the input of 'F1' and was not an input to 'F2'
(>>?) :: Maybe a -> (a -> Maybe b) -> Maybe b Nothing >>? _ = Nothing Just v >>? f = f v
var_access_test val = Just (val, (val + 1)) >>? \(val1, s) -> Just (s, (s + 1)) >>? -- F1 \(val2, s) -> Just (val, (val1, (val2, (s)))) -- F2
-- I guess -- F2 :: (Int, Int) -> Maybe (Int, (int, (Int. Int))) -- So how can the F2 function return 'val1' even though it was not an input to it. -- output of var_access_test 3 -- Just (3,(3,(4,5)))
Although this might be something very trivial but I am stuck here and not able to understand how this is working. (considering the functions to be pure they can only access values passed to them as input).
- Divam
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners

On Fri, Dec 28, 2012 at 8:14 PM, Divam
Although this might be something very trivial but I am stuck here and not able to understand how this is working. (considering the functions to be pure they can only access values passed to them as input).
They can access any bindings in the same scope; since a lambda binding does not define a new scope in the same way a top level binding does, the earlier bindings are still in scope and accessible. Consider this: a multi-parameter binding such as \a b c -> a + b + c is really the same thing as \a -> (\b -> (\c -> a + b + c)) (This is, in fact, how partial function application works.) a is still in scope when b is defined, a and b are still in scope when c is defined. What you can't do in a pure function is *change* them; all bindings are read only, whether in or inward of their scope. Inward scopes can redefine bindings, but those new bindings are unrelated to the outer ones. Also consider this: in Haskell, a function is a binding like any other. If you couldn't refer to bindings from outer scopes, you couldn't define new functions! Well, aside from anonymous ones/lambdas, which are useful but somewhat limiting if you can't name and reuse them. -- brandon s allbery kf8nh sine nomine associates allbery.b@gmail.com ballbery@sinenomine.net unix, openafs, kerberos, infrastructure, xmonad http://sinenomine.net

This is ONE nested function, not F1 >>? F2:
Kim, This is a very useful insight
(This is, in fact, how partial function application works.) a is still in
scope when b is defined, a and b are still in scope when c is defined.
Brandon, I need to study this again, still dont understood how its related
to partial function application.
Also consider this: in Haskell, a function is a binding like any other.
If you couldn't refer to bindings from outer scopes, you couldn't define
new functions! Well, aside from anonymous ones/lambdas, which are useful
but somewhat limiting if you can't name and reuse them.
Brandon, This is quite strange thing, the functions can access the globally
defined variables and therefore there output is dependent not just on
inputs but on those variables too. This goes against the understanding of
pure functions.
Also there may be another way to look at this - all the global variables
are inputs to all the functions. I think this is how the haskell looks at
this scenario.
Thanks for your quick replies
Divam
On 29 December 2012 07:29, Brandon Allbery
On Fri, Dec 28, 2012 at 8:14 PM, Divam
wrote: Although this might be something very trivial but I am stuck here and not able to understand how this is working. (considering the functions to be pure they can only access values passed to them as input).
They can access any bindings in the same scope; since a lambda binding does not define a new scope in the same way a top level binding does, the earlier bindings are still in scope and accessible.
Consider this: a multi-parameter binding such as
\a b c -> a + b + c
is really the same thing as
\a -> (\b -> (\c -> a + b + c))
(This is, in fact, how partial function application works.) a is still in scope when b is defined, a and b are still in scope when c is defined.
What you can't do in a pure function is *change* them; all bindings are read only, whether in or inward of their scope. Inward scopes can redefine bindings, but those new bindings are unrelated to the outer ones.
Also consider this: in Haskell, a function is a binding like any other. If you couldn't refer to bindings from outer scopes, you couldn't define new functions! Well, aside from anonymous ones/lambdas, which are useful but somewhat limiting if you can't name and reuse them.
-- brandon s allbery kf8nh sine nomine associates allbery.b@gmail.com ballbery@sinenomine.net unix, openafs, kerberos, infrastructure, xmonad http://sinenomine.net

On Fri, Dec 28, 2012 at 10:57 PM, Divam
(This is, in fact, how partial function application works.) a is still in scope when b is defined, a and b are still in scope when c is defined.
Brandon, I need to study this again, still dont understood how its related to partial function application.
A function of multiple arguments is actually a function of a single argument which returns a function that takes the next argument, and so on. Partial application therefore happens automatically.
Brandon, This is quite strange thing, the functions can access the globally defined variables and therefore there output is dependent not just on inputs but on those variables too. This goes against the understanding of pure functions.
You may be using a different definition of "pure" than Haskell does; the point of pure functions in Haskell is that they cannot *change* anything outside of the function scope, not that they can't *see* anything.
Also there may be another way to look at this - all the global variables are inputs to all the functions. I think this is how the haskell looks at this scenario.
There are no variables involved. "Variables" can vary; bindings are immutable. This is key to purity. -- brandon s allbery kf8nh sine nomine associates allbery.b@gmail.com ballbery@sinenomine.net unix, openafs, kerberos, infrastructure, xmonad http://sinenomine.net

Hi,
Brandon, I need to study this again, still dont understood how its related to partial function application.
Take a look at: http://learnyouahaskell.com/higher-order-functions#lambdas addThree :: (Num a) => a -> a -> a -> a addThree x y z = x + y + z can be defined as: addThree :: (Num a) => a -> a -> a -> a addThree = \x -> \y -> \z -> x + y + z and with brackets it would be: addThree = \x -> (\y -> (\z -> (x + y + z))) Now, you just need to put brackets to see what's going on there (i've simplified your code for clarity): t v = Just v >>? \v1 -> Just (v + 1) >>? \v2 -> Just (v + v1 + v2) This would be (it actually is!): t v = Just v >>? \v1 -> (Just (v + 1) >>? \v2 -> (Just (v + v1 + v2) ) ) Now, if you will put braces in wrong place: t v = Just v >>? (\v1 -> Just (v + 1)) >>? (\v2 -> Just (v + v1 + v2)) Then you will get: Not in scope: `v1'
Also consider this: in Haskell, a function is a binding like any other. If you couldn't refer to bindings from outer scopes, you couldn't define new functions! Well, aside from anonymous ones/lambdas, which are useful but somewhat limiting if you can't name and reuse them.
Brandon, This is quite strange thing, the functions can access the globally defined variables and therefore there output is dependent not just on inputs but on those variables too. This goes against the understanding of pure functions.
These 'global expressions' do not change during execution, output is dependent only on input, and function could be defined in terms of arguments and some 'constants' ('global expressions') and other functions (also 'global expressions' (there is no difference). Emanuel
participants (4)
-
Brandon Allbery
-
Divam
-
Emanuel Koczwara
-
Kim-Ee Yeoh