Meaning of overlapping pattern in Haskell - haskell

My current understanding of pattern overlapping in Haskell is that 2 patterns are considered to be overlapping if some argument values passed to a function can be matched by multiple patterns.
Given:
last :: [a] -> a
last [x] = x
last (_ : xs) = last xs
passing the argument value [1] would match both the first pattern [x] and the 2nd pattern (_ : xs) - so that would mean the function has overlapping patterns even though both patterns can be matched.
What makes this confusing is that although the patterns are (by the definition above) overlapping, GHC does not show any warning about them being overlapping.
Reverting the 2 pattern matches in the last function does show the overlapping warning:
last :: [a] -> a
last (_ : xs) = last xs
last [x] = x
Warning:
src\OverlappingPatterns.hs:6:1: Warning:
Pattern match(es) are overlapped
In an equation for `last': last [x] = ...
It is almost as though GHC consideres the patterns overlapping if a previous pattern makes it impossible to match a pattern which occurs later.
What is the correct way to determine if a function has overlapping patterns or not?
Update
I am looking for the overlapping pattern definition used in fp101x course.
According to the definition used in fp101x the following function has overlapping patterns:
last :: [a] -> a
last [x] = x
last (_ : xs) = last xs
This is in contradiction with GHC definition of overlapping pattern which does not consider it to have any overlapping patterns.
Without a proper definition of what overlapping pattern means in the fp101x course context, it is impossible to solve that exercise. And the definition used there is not the GHC one.

The updated question clarifies the OP wants a formal definition of overlapping patterns. Here "overlapping" is meant in the sense used by GHC when it emits its warnings: that is, when it detects that a case branch is unreachable because its pattern does not match with anything which is not already handled by earlier branch.
A possible formal definition can indeed follow that intuition. That is, for any pattern p one can first define the set of values (denotations) [[p]] matching with p. (For this, it is important to know the type of the variables involved in p -- [[p]] depends on a type environment Gamma.) Then, one can say that in the sequence of patterns
q0 q1 ... qn p
the pattern p is overlapping iff [[p]], as a set, is included in [[q0]] union ... union [[qn]].
The above definition is hardly operative, though -- it does not immediately lead to an algorithm for checking overlaps. Indeed, computing [[p]] is unfeasible since it is an infinite set, in general.
To define an algorithm, I'd try to define a representation for the set of terms "not yet matched" by any pattern q0 .. qn. As an example, suppose we work with lists of booleans:
Remaining: _ (that is, any list)
q0 = []
Remaining: _:_ (any non empty list)
q1 = (True:xs)
Remaining: False:_
p = (True:False:ys)
Remaining: False:_
Here, the "remaining" set did not change, so the last pattern is overlapping.
As another example:
Remaining: _
q0 = True:[]
Remaining: [] , False:_ , True:_:_
q1 = False:xs
Remaining: [], True:_:_
q2 = True:False:xs
Remaining: [], True:True:_
q3 = []
Remaining: True:True:_
p = True:xs
Remaining: nothing -- not overlapping (and exhaustive as well!)
As you can see, in each step we match each of the "remaining" samples with the pattern at hand. This generates a new set of remaining samples (possibly none). The collection of all these samples forms the new remaining set.
For this, note that it is important to know the list of constructors for each type. This is because when matching with True, you must know there's another False case remaining. Similarly, if you match against [], there's another _:_ case remaining. Roughly, when matching against constructor K, all other constructors of the same type remain.
The above examples are not yet an algorithm, but they can get you started, hopefully.
All of this of course ignores case guards (which make the overlap undecidable), pattern guards, GADTs (which can further refine the remaining set in quite subtle ways).

I am looking for the overlapping pattern definition used in fp101x course.
"Patterns that do not rely on the order in which they are matched are
called disjoint or non-overlapping." (from "Programming in Haskell"
Graham Hutton)
So this example would be non-overlapping
foldr :: (a → b → b) → b → [a] → b
foldr v [] = v
foldr f v (x : xs) = f x (foldr f v xs)
Because you can change the order of pattern-matching like this:
foldr :: (a → b → b) → b → [a] → b
foldr f v (x : xs) = f x (foldr f v xs)
foldr v [] = v
And here you can't:
last :: [a] -> a
last [x] = x
last (_ : xs) = last xs
So the last one )) is overlapping.

I think the thing is that in the first case, not all matches of [x] will match (_:xs). On the second case, the converse is true (no one matching (_:xs) will fall through [x]). So, overlapping really means that there is an unreachable pattern.
This is what GHC documentation has to say about it:
By default, the compiler will warn you if a set of patterns are either
incomplete (i.e., you're only matching on a subset of an algebraic
data type's constructors), or overlapping, i.e.,
f :: String -> Int
f [] = 0
f (_:xs) = 1
f "2" = 2
where the last pattern match in `f' won't ever be reached, as
the second pattern overlaps it. More often than not, redundant
patterns is a programmer mistake/error, so this option is enabled by
default.
Maybe "unreachable pattern" would be a better choice of words.

I would suggest using reasoning logic in combination with compiler messages and test results would be a better way to understand if a function has overlapping patterns or not. As two examples, the first which has already been listed, indeed results in a compiler warning.
-- The first definition should work as expected.
last1 :: [a] -> a
last1 [x] = x
last1 (_:xs) = last xs
in the second case if we swap the last two lines around then a compiler error which states. Program error: pattern match failure: init1 [] results
last :: [a] -> a
last (_:xs) = last xs
last [x] = x
This matches the logic of passing a singleton list which could match in both patterns, and in this case the now second line.
last (_:xs) = last xs
will match in both cases. If we then move onto the second example
-- The first definition should work as expected
drop :: Int -> [a] -> [a]
drop 0 xs = xs
drop n [] = []
drop n (_:xs) = drop1 (n - 1) xs
In the second case if we again swap the last line with the first line then we don't get a compiler error but we also don't get the results we expect. Main> drop 1 [1,2,3] returns an empty list []
drop :: Int -> [a] -> [a]
drop n (_:xs) = drop1 (n - 1) xs
drop 0 xs = xs
drop n [] = []
In summary I think this is why reasoning (as oppose to a formal definition) for determining overlapping patterns works ok.

Related

Pattern match is redundant, haskell

I'm new to haskell and I'm learning from one of the books. I came across an example in which I have the following error but I don't know why.
myMap :: (a -> b) -> [a] -> [b]
myMap _ _ = []
myMap f (x:xs) = f x : myMap f xs
The error is in the last line : Pattern match is redundant.
If anyone can help, thanks.
The first definition of your function (myMap _ _) captures any input. If you think about it, the definition is saying:
If the first argument is anything (_), and the second argument is anything (_), return [].
Then the second definition considers only cases where the second argument was a non-empty list. But by the time we get to the second definition, all inputs are already taken care of.
To fix this, simply swap the two definitions, so the _ _ pattern match is applied only when the f (x : xs) cannot be.
As others have noted, you can just swap the order of the pattern matches. But in this case, I would prefer a different approach. A list that does not match the x:xs pattern must actually be empty. So we can write
myMap :: (a -> b) -> [a] -> [b]
myMap _ [] = []
myMap f (x:xs) = f x : myMap f xs
This way, you can put the patterns in whichever order you like. Moreover, using explicit patterns rather than wildcards makes it easy to see that you've made all the distinctions you intended to, and not missed anything important. As a rule of thumb, a fall-through pattern likely makes sense only if it reduces the number of lines of code you need to write.

Why does Sieve of Eratosthenes need extra helper function for merging infinite lists?

I'm working with the Sieve of Eratosthenes code from Literate Programming (http://en.literateprograms.org/Sieve_of_Eratosthenes_%28Haskell%29), modified slightly to include edge cases on merge and diff:
primesInit = [2,3,5,7,11,13]
primes = primesInit ++ [i | i <- diff [15,17..] nonprimes]
nonprimes = foldr1 f . map g $ tail primes
where g p = [n * p | n <- [p,p+2..]]
f (x:xt) ys = x : (merge xt ys)
merge :: (Ord a) => [a] -> [a] -> [a]
merge [] ys = ys
merge xs [] = xs
merge xs#(x:xt) ys#(y:yt)
| x < y = x : merge xt ys
| x == y = x : merge xt yt
| x > y = y : merge xs yt
diff :: (Ord a) => [a] -> [a] -> [a]
diff [] ys = []
diff xs [] = xs
diff xs#(x:xt) ys#(y:yt)
| x < y = x : diff xt ys
| x == y = diff xt yt
| x > y = diff xs yt
Both merge and diff on their own are lazy. So is nonprimes and primes. But if we change the definition of primes to remove f, as in:
nonprimes = foldr1 merge . map g $ tail primes
where g p = [n * p | n <- [p,p+2..]]
Now nonprimes isn't lazy. I've also recreated this with take 20 $ foldr1 merge [[i*n | n <- [3,7..]] | i <- [5,9..]] (GHCI runs out of memory and exits).
Based on http://www.haskell.org/haskellwiki/Performance/Laziness , one easy source of non-laziness is recursing before returning a data constructor. But merge doesn't have this problem; it returns a cons-cell that contains the recursive call as the second item. Nor should the use of foldr be a culprit here by itself (It's foldl that can't do infinite lists).
So, why does merge need to be separated from foldr1 by f, which essentially does the first call to merge manually? All f does is return a cons cell that contains the call to merge as the second item, right?
NOTE: Someone else on Stack Overflow was working with similar code and ran into the same problem I did, but they accepted an answer that looked to me like basically different code. I'm asking why, not how, as it seems that laziness is somewhat important in Haskell.
Let's compare those two functions again:
merge [] ys = ys
merge xs [] = xs
merge xs#(x:xt) ys#(y:yt)
| x < y = x : merge xt ys
| x == y = x : merge xt yt
| x > y = y : merge xs yt
and
f (x:xt) ys = x : (merge xt ys)
Let's ignore the semantic differences between the two, though they are significant - f is a lot more restricted as far as when it's valid to call. Instead, lets look at only the strictness properties.
Pattern matches in multiple equations are checked top-down. Multiple pattern matches within a single equation are checked left-to-right. So the first thing merge does is force the constructor of its first argument, in order to determine if the first equation matches. If the first equation doesn't match, it forces the constructor of the second argument, in order to determine if the second equation matches. Only if neither equation matches does it move to the third case. The compiler is smart enough to know it's already forced both arguments at this point, so it doesn't do it again - but those pattern matches would require the arguments to be forced if it hadn't already been.
But the important thing here is that the process of figuring out which equation matches causes both arguments to be forced before any constructor is produced.
Now, contrast that with f. In the definition of f, the only pattern-matching is on the first argument. As such, f is somewhat less strict than merge. It produces a constructor before examining its second argument.
And it turns out that if you closely examine the behavior of foldr, it works on infinite lists precisely when the function passed to it doesn't (always) examine its second argument before producing a constructor.
The parenthetical "always" there is interesting. One of my favorite examples of using foldr and laziness together is:
dropRWhile :: (a -> Bool) -> [a] -> [a]
dropRWhile p = foldr (\x xs -> if p x && null xs then [] else x:xs) []
This is a maximally-lazy function that works like dropWhile, except from the back (right) of the list. If the current element doesn't match the predicate, it's returned immediately. If it does match the predicate, it looks ahead until it finds something that either doesn't match, or the end of the list. This will be productive on infinite lists, so long as it eventually finds an element that doesn't match the predicate. And that is the source of the "always" parenthetical up above - a function that usually doesn't examine its second argument before producing a constructor still allows foldr to usually work on infinite lists.
To determine the first element of its output, merge needs to evaluate both arguments enough to determine if they are empty lists or not. Without that information it can't be determined which case of the function definition applies.
In combination with foldr1 it becomes a problem that merge tries to evaluate its second argument. nonprimes in an expression of this form:
foldr1 merge [a,b,c,...]
To evaluate this, first `foldr1 is expanded:
merge a (foldr1 merge [b,c,...])
To now evaluate merge, the cases of its function definition are checked. First a is evaluated, and it turns out to not be an empty list. So the first case of merge doesn't apply. Next, the second parameter of merge needs to be evaluated to see if it is an empty list and if the second case of the definition of merge applies. This second parameter is foldr1 merge [b,c,...].
But to evaluate this we are in the same situation as before with foldr1 merge [a,b,c,...], and we just the same end up with merge b (foldr1 merge [c,...]), where merge again needs to evaluate it's second parameter to check if it's an empty list.
And so on. Each evaluation of merge requires another evaluation of merge first, which ends up in infinite recursion.
With f that problem is avoided, since it doesn't need to look at its second parameter for the top level evaluation. foldr1 f [a,b,c...] is f a (foldr1 f [b,c,...]) which evaluates to a non-empty list a0 : merge a' (foldr1 f [b,c,...]). So foldr1 f ... never is an empty list. This can be determined without any infinite recursion.
Now also the evaluation of merge a' (foldr1 f [b,c,...]) isn't a problem, since the second parameter evaluates to some b0 : ..., which is all merge needs to know to start producing a result.

Using patterns to find the nth element

I'm working through Learn You A Haskell in order to come up to speed with the basics of Haskell. I'm very comfortable with both functional programming and pattern matching, but the latter more so with how Mathematica does it.
In the same spirit as the naïve implementation of head in Chapter 4.1, I proceeded with a naïve implementation of last as:
last1 :: [a] -> a
last1 (_:x:[]) = x
However, calling last1 [1,2,3,4] gave an error Exception: ... Non-exhaustive patterns in function last1. I understand that this error implies that the pattern specified does not cover all possible inputs and usually, a catch-all pattern is necessary (which I've not provided). However, I'm not exactly sure why I get this error for my input.
Question 1: My understanding (of my incorrect approach) is that the first element is captured by _ and the rest get assigned to x, which isn't exactly what I had intended. However, shouldn't this give a type error, because I specified [a] -> a, but x is now a list?
Note that this is not about how to write a working last function — I know I can write it as (among other possibilities)
last2 :: [a] -> a
last2 [x] = x
last2 (_:x) = last2 x
Question 2: Along the same theme of better understanding pattern matching in Haskell, how can I use pattern matching to pick out the last element or more generally, the nth element from a given list, say, [1..10]?
This answer suggests that you can bind the last element using pattern matching with the ViewPatterns extension, but it seems strange that there isn't an analogous "simple" pattern like for head
In Mathematica, I would probably write it as:
Range[10] /. {Repeated[_, {5}], x_, ___} :> x
(* 6 *)
to pick out the 6th element and
Range[10] /. {___, x_} :> x
(* 10 *)
to pick out the last element of a non-empty list.
I apologize if this is covered later in the text, but I'm trying to relate each topic and concept as I come across them, to how it is handled in other languages that I know so that I can appreciate the differences and similarities.
To make sense of the result of your first attempt, you need to see how the
list data is defined. Lists enjoy a somewhat special syntax, but you would
write it something like this.
data List a = (:) a (List a)
| []
So, your list [1 .. 10] is actually structured as
(1 : (2 : (3 : (4 : []))))
In addition, due to the right associativity of the (:) operator, your pattern
for last1 actually looks like
last1 :: [a] -> a
last1 (_:(x:[])) = x
That is why 'x' has same type as an element of your list; it is the first
argument to the (:) constructor.
Pattern matching allows you to deconstruct data structures like lists, but you
need to know what "shape" they have to do so. That is why you cannot directly
specify a pattern that will extract the last element of a list, because there
are an infinite number of lengths a list can have. That is why the working
solution (last2) uses recursion to solve the problem. You know what pattern
a list of length one has and where to find the final element; for everything
else, you can just throw away the first element and extract the last element
of the resulting, shorter, list.
If you wanted, you could add more patterns, but it would not prove that
helpful. You could write it as
last2 :: [a] -> a
last2 (x:[]) = x
last2 (_:x:[]) = x
last2 (_:_:x:[]) = x
...
last2 (x:xs) = last2 xs
But without an infinite number of cases, you could never complete the function
for all lengths of input lists. Its even more dubious when you consider the fact that
lists can actually be infinitely long; what pattern would you use to match that?
There is no way to have pattern match get the "last" element without using view patterns. That is because there is no way to get the last element of a list without using recursion (at least implicitly), and what is more, there is no decidable way to get the last element.
Your code
last1 (_:x:[]) = x
should be parsed like
last1 (_:(x:[])) = x
which can be de-sugared into
last1 a = case a of
(_:b) -> case b of
(x:c) -> case c of
[] -> x
having completed this exercise we see what your code does: you have written a pattern that will match a list IF the outermost constructor of a list is a cons cell AND the next constructor is a cons AND the third constructor is a nil.
so in the case of
last1 [1,2,3,4]
we have
last1 [1,2,3,4]
= last1 (1:(2:(3:(4:[]))))
= case (1:(2:(3:(4:[])))) of
(_:b) -> case b of
(x:c) -> case c of
[] -> x
= case (2:(3:(4:[]))) of
(x:c) -> case c of
[] -> x
= let x = 2 in case (3:(4:[])) of
[] -> x
= pattern match failure
Your example
last1 (_:x:[]) = x
only matches lists containing two elements i.e. lists of the form a:b:[]. _ matches the head of the list without binding, x matches the following element, and the empty list matches itself.
When pattern matching lists, only the right-most item represents a list - the tail of the matched list.
You can get the nth element from a list with a function like:
getNth :: [a] -> Int -> a
getNth [] _ = error "Out of range"
getNth (h:t) 0 = h
getNth (h:t) n = getNth t (n-1)
This built-in using the !! operator e.g. [1..10] !! 5
You can indeed use ViewPatterns to do pattern matching at the end of a list, so let's do:
{-# LANGUAGE ViewPatterns #-}
and redefine your last1 and last2 by reversing the list before we pattern match.
This makes it O(n), but that's unavoidable with a list.
last1 (reverse -> (x:_)) = x
The syntax
mainFunction (viewFunction -> pattern) = resultExpression
is syntactic sugar for
mainFunction x = case viewFunction x of pattern -> resultExpression
so you can see it actually just reverses the list then pattern matches that, but it feels nicer.
viewFunction is just any function you like.
(One of the aims of the extension was to allow people to cleanly and easily use accessor functions
for pattern matching so they didn't have to use the underlying structure of their data type when
defining functions on it.)
This last1 gives an error if the list is empty, just like the original last does.
*Main> last []
*** Exception: Prelude.last: empty list
*Main> last1 []
*** Exception: Patterns.so.lhs:7:6-33: Non-exhaustive patterns in function last1
Well, OK, not exactly, but we can change that by adding
last1 _ = error "last1: empty list"
which gives you
*Main> last1 []
*** Exception: last1: empty list
We can of course use the same trick for last2:
last2 (reverse -> (_:x:_)) = x
last2 _ = error "last2: list must have at least two elements"
But it would be nicer to define
maybeLast2 (reverse -> (_:x:_)) = Just x
maybeLast2 _ = Nothing
You can carry on this way with for example last4:
last4 (reverse -> (_:_:_:x:_)) = x
And you can see that using the reverse viewpattern,
we've changed the semantics of (_:_:_:x:_) from
(ignore1st,ignore2nd,ignore3rd,get4th,ignoreTheRestOfTheList) to
(ignoreLast,ignore2ndLast,ignore3rdLast,get4thLast,ignoreTheRestOfTheList).
You note that in Mathematica, the number of underscores is used to indicate the number of elements being ignored.
In Haskell, we just use the one _, but it can be used for any ignored value, and in the presence of the
asymmetric list constructor :, the semantics depend on which side you're on, so in a:b, the a must mean an
element and the b must be a list (which could itself be c:d because : is right associative - a:b:c means
a:(b:c)). This is why a final underscore in any list pattern reresents ignoreTheRestOfTheList, and in the
presence of the reverse viewfunction, that means ignoring the front elements of the list.
The recursion/backtracking that's hidden under the hood in Mathematica is explicit here with the viewFunction reverse (which is a recursive function).

Can you use pattern matching to bind the last element of a list?

Since there is a way to bind the head and tail of a list via pattern matching, I'm wondering if you can use pattern matching to bind the last element of a list?
Yes, you can, using the ViewPatterns extension.
Prelude> :set -XViewPatterns
Prelude> let f (last -> x) = x*2
Prelude> f [1, 2, 3]
6
Note that this pattern will always succeed, though, so you'll probably want to add a pattern for the case where the list is empty, else last will throw an exception.
Prelude> f []
*** Exception: Prelude.last: empty list
Also note that this is just syntactic sugar. Unlike normal pattern matching, this is O(n), since you're still accessing the last element of a singly-linked list. If you need more efficient access, consider using a different data structure such as Data.Sequence, which offers O(1) access to both ends.
You can use ViewPatterns to do pattern matching at the end of a list, so let's do
{-# LANGUAGE ViewPatterns #-}
and use reverse as the viewFunction, because it always succeeds, so for example
printLast :: Show a => IO ()
printLast (reverse -> (x:_)) = print x
printLast _ = putStrLn "Sorry, there wasn't a last element to print."
This is safe in the sense that it doesn't throw any exceptions as long as you covered all the possibilities.
(You could rewrite it to return a Maybe, for example.)
The syntax
mainFunction (viewFunction -> pattern) = resultExpression
is syntactic sugar for
mainFunction x = case viewFunction x of pattern -> resultExpression
so you can see it actually just reverses the list then pattern matches that, but it feels nicer.
viewFunction is just any function you like.
(One of the aims of the extension was to allow people to cleanly and easily use accessor functions
for pattern matching so they didn't have to use the underlying structure of their data type when
defining functions on it.)
The other answers explain the ViewPatterns-based solutions. If you want to make it more pattern matching-like, you can package that into a PatternSynonym:
tailLast :: [a] -> Maybe ([a], a)
tailLast xs#(_:_) = Just (init xs, last xs)
tailLast _ = Nothing
pattern Split x1 xs xn = x1 : (tailLast -> Just (xs, xn))
and then write your function as e.g.
foo :: [a] -> (a, [a], a)
foo (Split head mid last) = (head, mid, last)
foo _ = error "foo: empty list"
This is my first day of Haskell programming and I also encountered the same issue, but I could not resolve to use some kind of external artifact as suggested in previous solutions.
My feeling about Haskell is that if the core language has no solution for your problem, then the solution is to transform your problem until it works for the language.
In this case transforming the problem means transforming a tail problem into a head problem, which seems the only supported operation in pattern matching. It turns that you can easily do that using a list inversion, then work on the reversed list using head elements as you would use tail elements in the original list, and finally, if necessary, revert the result back to initial order (eg. if it was a list).
For example, given a list of integers (eg. [1,2,3,4,5,6]), assume we want to build this list in which every second element of the original list starting from the end is replaced by its double (exercise taken from Homework1 of this excellent introduction to Haskell) : [2,2,6,4,10,6].
Then we can use the following:
revert :: [Integer] -> [Integer]
revert [] = []
revert (x:[]) = [x]
revert (x:xs) = (revert xs) ++ [x]
doubleSecond :: [Integer] -> [Integer]
doubleSecond [] = []
doubleSecond (x:[]) = [x]
doubleSecond (x:y:xs) = (x:2*y : (doubleSecond xs))
doubleBeforeLast :: [Integer] -> [Integer]
doubleBeforeLast l = ( revert (doubleSecond (revert l)) )
main = putStrLn (show (doubleBeforeLast [1,2,3,4,5,6,7,8,9]))
It's obviously much longer than previous solutions, but it feels more Haskell-ish to me.

When destructuring tuples in Haskell, where can the elements be used?

I am reading a tutorial that uses the following example (that I'll generalize somewhat):
f :: Foo -> (Int, Foo)
...
fList :: Foo -> [Int]
fList foo = x : fList bar
where
(x, bar) = f foo
My question lies in the fact that it seems you can refer to x and bar, by name, outside of the tuple where they are obtained. This would seem to act like destructuring parameter lists in other languages, if my guess is correct. (In other words, I didn't have to do the following:)
fList foo = (fst tuple) : fList (snd tuple)
where
tuple = f foo
Am I right about this behavior? I've never seen it mentioned yet in the tutorials/books I've been reading. Can someone point me to more info on the subject?
Edit: Can anything (lists, arrays, etc.) be destructured in a similar way, or can you only do this with tuples?
Seeing your edit, I think what your asking about is Pattern matching.
And to answer your question: Yes, anything you can construct, you can also 'deconstruct' using the constructors. For example, you're probably familiar with this form of pattern matching:
head :: [a] -> a
head (x:xs) = x
head [] = error "Can't take head of empty list"
However, there are more places where you can use pattern matching, other valid notations are:
head xs = case xs of
(y:ys) -> y
[] -> error "Can't take head of empty list"
head xs = let (y:ys) = xs
in y
head xs = y
where
(y:ys) = xs
Note that the last two examples are a bit different from the first to because they give different error messages when you call them with an empty list.
Although these examples are specific to lists, you can do the same with other data types, like so:
first :: (a, b) -> a
first tuple = x
where
(x, y) = tuple
second :: (a, b) -> b
second tuple = let (x, y) = tuple
in y
fromJust :: Maybe a -> a
fromJust ma = x
where
(Just x) = ma
Again, the last function will also crash if you call it with Nothing.
To sum up; if you can create something using constructors (like (:) and [] for lists, or (,) for tuples, or Nothing and Just for Maybe), you can use those same constructors to do pattern matching in a variety of ways.
Am I right about this behavior?
Yes. The names exist only in the block where you have defined them, though. In your case, this means the logical unit that your where clause is applied to, i.e. the expression inside fList.
Another way to look at it is that code like this
x where x = 3
is roughly equivalent to
let x = 3 in x
Yes, you're right. Names bound in a where clause are visible to the full declaration preceding the where clause. In your case those names are f and bar.
(One of the hard things about learning Haskell is that it is not just permitted but common to use variables in the source code in locations that precede the locations where those variables are defined.)
The place to read more about where clauses is in the Haskell 98 Report or in one of the many fine tutorials to be found at haskell.org.

Resources