How does the Lambda function work on lists in Haskell? - haskell

I have this line of code and don't quite understand why the outcome is [False, False]
i :: [Bool]
i = filter (\x-> (not x)) [False,False,True,True,True]
I thought it would come out to [True,True,True].
Would really appreciate a short explanation of the Outcome here. Thanks in advance

According to the documentation,
filter, applied to a predicate and a list, returns the list of those elements that satisfy the predicate, i.e. [...]:
>>> filter odd [1, 2, 3]
[1,3]
The expression that defines i is essentially saying:
Filter the booleans x for which not x is True from the list [False, False, True, True, True]
For the first entry, not False is True, so it is retained.
For the second entry, not False is again True, so this is retained as well.
For the remaining three entries, not True is False, so these
entries are dropped.
The result is [False, False].

Because filter keeps the elements where the predicate is true. These elements are now False, False.

Related

What kind of comprehension is this?

One of my students found that, for ell (a list of string) and estr (a string), the following expression is True iff a member of ell is contained in estr:
any(t in estr for t in ell)
Can anyone explain why this is syntactically legal, and if so what does the comprehension generate?
This is a generator expression.
func_that_takes_any_iterable(i for i in iterable)
It's like a list comprehension, but a generator, meaning it only produces one element at a time:
>>> a = [i for i in range(10)]
>>> b = (i for i in range(10))
>>> print(a)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> print(b)
<generator object <genexpr> at 0x7fb9113fae40>
>>> print(list(b))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> print(list(b))
[]
When using a generator expression in isolation, the parentheses are required for syntax reasons. When creating one as an argument to a function, the syntax allows for the extra parentheses to be absent.
Most functions don't care what type of iterable they're given - list, tuple, dict, generator, etc - and generators are perfectly valid. They're also marginally more memory-efficient than list comprehensions, since they don't generate the entire thing up front. For all() and any(), this is especially good, since those methods short-circuit as soon as they would return False and True respectively.
As of python 3.8, the syntactic restrictions for the walrus operator := are similar - in isolation, it must be used inside its own set of parentheses, but inside another expression it can generally be used without them.
This is syntactically legal because it's not a list. Anything of the form (x for x in array) is a generator. Think of it like lazy list, which will generate answer only when you ask.
Now generator are also an iterable so it's perfectly fine for it to be inside an any() function.
willBeTrue = any(True for i in range(20))
So this will basically generate 20 Trues and any function looks for any true value; thus will return True.
Now coming to your expression:
ans = any(t in estr for t in ell)
This {t in estr} returns a boolean value. Now generator makes len(ell) amount of those boolean value and any thinks good.. since atleast one is true I return True.

Is there a way to pull the index of a Python list of booleans of where short circuiting occurs?

My main focus has been on any and all function of Python 3.7. Sometimes, I would like to figure out where the short-circuit occurs in a list of booleans
i.e.
any([False, False, True, False, True, True])
would return 2.
What is a way to do so without using a loop?
Edit: I realized that this is a first occurrence problem. Which, already has many solutions out there :p
You can use itertools.takewhile, which accepts a function and an iterable. Each element of the iterable is passed into the function and taken until the first False.
>>> from itertools import takewhile
>>> lst = [False, False, True, False, True, True]
>>> len(list(takewhile(lambda x: not x, lst)))
2
Another option from the comments is
next(i for i, val in enumerate(mylist) if val)
which makes an iterator of indices of truthy values in mylist and forwards it one step to the first truthy value index, which is also short-circuiting and space-efficient.
any does short circuit although it doesn't produce an index.

Why is a list containing an empty string truthy?

I have caught something in my work returning a list containing an empty string. I've created an example for simplicity:
big_ol_trickster = [""]
if big_ol_trickster:
foo()
else:
print("You can't trick me!")
And this conditional would be satisfied every time. So I've got a question for the python wizards out there: Why is [] == False and "" == False but [""] == True?
Empty lists are Falsey. [""] is not empty. It contains a single element (which happens to be Falsey as well). The Falsey-ness is not evaluated recursively.
To know why is that, look at the implementation of the __bool__ dunder method for the list class. This the method that is called to evaluate truth-value in python. And, yes, you can override it.
[False, False] -> this is also Truthy, it can be counter-intuitive. That's why when you try to use sequences in if conditions you sometimes get "truth-value of sequences can be ambiguous, use any() or all() instead"

1==(int)0.5*2 => false, 1==((int)0.5*2) => true, why?

See title. 1==(int)0.5*2 evaluates to false, but 1==((int)0.5*2) evaluates to true. However (1==(int)0.5)*2 gives an error so the first expression is not parsed as this. Somehow the extra parentheses in 1==((int)0.5*2) are changing the precedence of the cast and the multiply.
What exactly causes this? And is this supposed to happen or is it a parsing bug?
This is how the expression should look like:
1 == 0.5*2 as int //--> true
1 == (int)(0.5*2) //--> true
this one:
1==(int)0.5*2
gives false, as (int)0.5 == 0
and this one: (1==(int)0.5)*2 doesn't make sense at all, as you try to multiply false (see the previous example) by 2, which is NOT allowed

Haskell Folding commutative, associative functions on Foldables containing bottom type

I recently tried running the code:
> let _l_ = _l_
> any [True, _l_, False]
True
> any [False, _l_, True]
> -- _l_
I was wondering if this is considered correct behavior since any is defined as foldr (||) False and || is associative and commutative.
Shouldn't _l_ || True == True || _l_ be true, and (False || _l_) || True == False || (_l_ || True) be true?
How would I implement an any that would result in an associative, commutative function application?
I am new to trying to understand bottom; should || be returning at all?
Thanks
This behavior is correct.
Shouldn't _l_ || True == True || _l_ be true
This isn't true in the presence of bottom. || has to evaluate one side first, then iff that value is False, it has to evaluate the other side. The definition from GHC.Classes is
(||) :: Bool -> Bool -> Bool
True || _ = True
False || x = x
So you can see it checks the left argument first. If the left argument is bottom, then the computation diverges and the whole thing is bottom. But if the left argument is True, the right argument is never examined, so even if it's bottom the result is still True.
(False || _l_) || True == False || (_l_ || True) be true?
This is true, both values are bottom. || is associative even in the presence of bottoms, but not commutative.
There are a few approaches you can take to building a commutative any, but they tend to involve concurrency. One approach is to use a function like por, which races two values and returns True if either is True, False if both return False, and otherwise diverges. Or you could build it yourself.
I think commutativity can be promised only on "classical logic" segment. Once you permit "non-classical" results, like non-termination, it is not possible to guarantee what the outcome is going to be, let alone commutativity.
For example, evaluating any (repeat False++[True]) is never going to produce the same result as any (True:repeat False).

Resources