1

I am new to haskell. Can someone explain how I can interpret this line of code in haskell :

filter (\(_, (varible1, _)) -> variable1 `notElem` [something1, something2])
4
  • 4
    Which part are you having problems with? Commented Jun 22, 2017 at 16:25
  • Actually I cannot understand filter (\(_, (varible1, _)) and also the flow in the code Commented Jun 22, 2017 at 16:27
  • 2
    I think you have to take a closer look at the brackets. (\(_, (varible1, _)) -> variable1 `notElem` [something1, something2]) is a single lambda expression. Commented Jun 22, 2017 at 16:28
  • I'm voting to close this question as off-topic because StackOverflow is not a good place to learn the bare-bones basics of a new programming language. You should use one of the several high-quality tutorials and/or textbooks available both online and in print to get started; SO will always be here for more specific questions. Commented Jun 29, 2017 at 2:17

2 Answers 2

6
-- Filter a list...
filter

-- ...of nested tuples where the first element of the second element of the tuple...
(\(_, (variable1, _)) ->

-- ...is not an element of [something1, something2]
variable1 `notElem` [something1, something2]) 

(_, (varible1, _)) deconstructs a nested tuple, and names one of the elements. Look up deconstruction to understand what's going on there.

Sign up to request clarification or add additional context in comments.

4 Comments

So does it return List of "nested" tupples ?
Yes. It would accept a list of something like [(1, (2, 3)), (9, (8, 7))], and return a list of the same type (potentially with some elements removed). Honestly, the nested tuples here kind of make things messy. I might have mapped the list first to remove the nesting unless you actually needed nested tuples to use later.
Thanks alot for your explanation :D
No problem. Always nice to have an excuse to look at Haskell code every once in awhile.
5

Let's start at the beginning.

\p -> e

is a lambda abstraction (an anonymous function) where p is a pattern and e is an expression that may use variables that appear in p.

(_, (variable1, _))

is a pattern constructed from the constructor (,), which constructs pairs. Here are some pairs:

(1, 2)
("Hello", "world!")
(1, (2, 3))

Here are some patterns which match pairs, used in lambda abstractions.

\(x, y) -> x
\(x,(y,z)) -> y

The second pattern matches a pair like (1, (2, 3)) and gives the first element of the second element. In this case, it would give 2. Its shape is like the pattern in your question, but what about the _ in your pattern?

_ is a valid variable name (variables can begin with underscores or lower-case letters). It is used to mean "a variable we don't use". The pattern (_, (y, _)) is like the pattern (x, (y, z)) except the only variable that has a name is y. Normally, you aren't allowed to reuse variable names in patterns. (x,x) is in invalid pattern, for instance. You are allowed to reuse _ though because Haskell knows you intend to throw that value away.

Now we can understand the expression

\(_, (variable1, _)) -> variable1

It is a function of type (a, (b, c)) -> b which takes a pair whose second element is itself a pair and gives the first element of the second element.

Now we need to understand

variable1 `notElem` [something1, something2]

To understand this expression, we need to know what the backticks do. Surrounding an identifier in backticks turns it into an infix operator. Infix operators are usually spelled with symbols, like x + y and xs ++ ys. The backticks let us convert normal identifiers, like notElem, into infix operators. This means that the above expression is the same as

notElem variable1 [something1, something2]

notElem is a function which takes an item and a list of items of the same type and gives True if the item does not appear in the list and False otherwise. It is the opposite of the elem test for membership.

Finally, filter. filter p xs is a function that takes a predicate p (i.e., a function which returns a Bool) and uses it to filter the list xs. filter gives a new list where elements (call them x) are included if p x is true. This filters the list of xs and gives a new list whose elements are those for which the predicate is true. For example,

> filter even [1,2,3,4]
[2,4]

So, we have

filter                  -- filter a list
  (\(_, (variable1, _)) -- by matching on the first element
                        -- of the second element of a pair
                        -- and calling it 'variable1'
     -> variable1 `notElem` [something1, something2])
                        -- and giving `True` if the element
                        -- is neither 'something1' nor 'something2'

This gives a function which takes a list of pairs whose second element is a pair and filters it to a list of pairs whose second element is a pair whose first element is neither something1 nor something2.

We can apply it, calling it f below:

f = filter (\(_, (varible1, _)) -> variable1 `notElem` [something1, something2])

> f [(1,(something1,2)), (1,(something3,3))]
[(1,(something3,3))]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.