Haskell error: Variable not in scope - haskell

I'm a bit new to Haskell but I've been working this problem for a couple hours with no luck.
I'm trying to implement something similar to a filter, except a predicate and list is passed to a function and it returns a tuple of two lists, one which is filtered by the predicate and one which is not.
divideList :: (a -> Bool) -> [a] -> ([a],[a])
divideList p xs = (f, nf) where
f = doFilter p xs
nf = doFilter (not . p) xs
doFilter :: (a -> Bool) -> [a] -> [a]
doFilter _ [] = []
doFilter p (x:xs) = [x | p x] ++ doFilter p xs
The second function, doFilter works properly. It applies the filter to its list and spits out the appropriate list. (i.e. If I just use doFilter (>3) [1,2,3,4,5,6] it will work properly)
My issue is with the first function. When I use divideList (>3) [1,2,3,4,5,6] I get a number of Variable not in scope errors. The errors are listed below:
AddListOperations.hs:20:23: error:
Variable not in scope: p :: a -> Bool
AddListOperations.hs:20:25: error: Variable not in scope: xs :: [a]
AddListOperations.hs:21:31: error:
Variable not in scope: p :: a -> Bool
AddListOperations.hs:21:34: error: Variable not in scope: xs :: [a]
Like I said, I have only been messing around with Haskell for a few days so let me know if I'm leaving out any important information.

Indent both f and nf:
divideList :: (a -> Bool) -> [a] -> ([a],[a])
divideList p xs = (f, nf) where
f = doFilter p xs
nf = doFilter (not . p) xs
After all, where would your where block stop?
By the way, divideList is partition from Data.List.

Thanks to Alec, I found that all I needed to do was indent the statements underneath where:
divideList :: (a -> Bool) -> [a] -> ([a],[a])
divideList p xs = (f, nf) where
f = doFilter p xs
nf = doFilter (not . p) xs

Related

Remove first element that fulfills predicate (Haskell)

I want to make a function that removes the first element that fulfills the predicate given in the second argument. Something like this:
removeFirst "abab" (< 'b') = "bab"
removeFirst "abab" (== 'b') = "aab"
removeFirst "abab" (> 'b') = "abab"
removeFirst [1,2,3,4] even = [1,3,4]
I wanted to do it by recursively, and came up with this:
removeFirst :: [a] -> (a -> Bool) -> [a]
removeFirst [] _ = []
rremoveFirst (x:xs) p = if p x then x : removeFirst xs p else removeFirst xs p
(Inspired by this question)
But I get a type-error, like this:
Couldn't match type ‘a’ with ‘Bool’
Expected: [Bool]
Actual: [a]
‘a’ is a rigid type variable bound by
the type signature for:
removeFirst :: forall a. [a] -> (a -> Bool) -> [a]
or this:
ghci> removeFirst [1,2,3,4] even
<interactive>:25:1: error:
* Variable not in scope: removeFirst :: [a0] -> (a1 -> Bool) -> t
* Perhaps you meant `rem' (imported from Prelude)
I know this is a relatively simple thing to program, I am just not familiar enough with Haskell yet. How can I do this "Haskell-style" (in one line)?
Before doing it "in style", why not first simply do it, so it works. This is how we learn.
"Variable not in scope: removeFirst ..." simply means you haven't defined the function named removeFirst.
So it seems you first tried to define it (and the error you show does not go with the code you show), then you got errors so it didn't get defined, and then you tried calling it and got the error saying it's not defined yet, naturally.
So, save your program in a source file, then load that file in GHCi. Then if you get any errors please copy-paste the full code from your file into your question (do not re-type it by hand). Also please specify what is it you do when you get the error messages, precisely. And be sure to include the error messages in full by copy-pasting them as well.
Then the logic of your code can be addressed.
Since others have posted working code, here's how I'd code this as a one-liner of sorts:
remFirst :: [a] -> (a -> Bool) -> [a]
remFirst xs p = foldr g z xs xs
where
g x r ~(_:tl) -- "r" for recursive result
| p x -- we've found it, then
= tl -- just return the tail
| otherwise
= x : r tl -- keep x and continue
z _ = [] -- none were found
Shortened, it becomes
remFirst xs p =
foldr (\x r ~(_:tl) -> if p x then tl else x : r tl)
(const []) xs xs
Not one line, but it works.
removeFirst :: [a] -> (a -> Bool) -> [a]
removeFirst (x:xs) pred
| pred x = xs
| otherwise = x : removeFirst xs pred
For a one-liner, I imagine you'd want to use foldl to walk across the list from the left.
EDIT
This solution uses guards, it first checks to see if the first element of the list passed in satisfies the predicate, and if not, it prepends it to the list and recursively checks the tail of the passed in list.
Using manual recursion does not lead to a one-liner solution, so let's try using some pre-built recursion scheme from the library.
Function scanl :: (b -> a -> b) -> b -> [a] -> [b] looks handy. It produces a succession of states, one state per input item.
Testing under the ghci interpreter:
$ ghci
λ>
λ> p = (=='b')
λ>
λ> xs = "ababcdab"
λ> ss = tail $ scanl (\(s,n) x -> if (p x) then (x,n+1) else (x,n)) (undefined,0) xs
λ>
λ> ss
[('a',0),('b',1),('a',1),('b',2),('c',2),('d',2),('a',2),('b',3)]
λ>
At that point, it is easy to spot and get rid of the one unwanted element, thru some simple data massaging:
λ>
λ> filter (\(x,n) -> (n /= 1) || (not $ p x)) ss
[('a',0),('a',1),('b',2),('c',2),('d',2),('a',2),('b',3)]
λ>
λ> map fst $ filter (\(x,n) -> (n /= 1) || (not $ p x)) ss
"aabcdab"
λ>
Let's now write our removeFirst function. I take the liberty to have the predicate as leftmost argument; this is what all library functions do.
removeFirst :: (a -> Bool) -> [a] -> [a]
removeFirst p =
let
stepFn = \(s,n) x -> if (p x) then (x,n+1) else (x,n)
p2 = \(x,n) -> (n /= 1) || (not $ p x)
in
map fst . filter p2 . tail . scanl stepFn (undefined,0)
If required, this version can be changed into a one-liner solution, just by expanding the values of stepFn and p2 into the last line. Left as an exercise for the reader. It makes for a long line, so it is debatable whether that improves readability.
Addendum:
Another approach consists in trying to find a library function, similar to splitAt :: Int -> [a] -> ([a], [a]) but taking a predicate instead of the list position.
So we submit the (a -> Bool) -> [a] -> ([a],[a]) type signature into the Hoogle specialized search engine.
This readily finds the break library function. It is exactly what we require.
λ>
λ> break (=='b') "zqababcdefab"
("zqa","babcdefab")
λ>
So we can write our removeFirst function like this:
removeFirst :: (a -> Bool) -> [a] -> [a]
removeFirst p xs = let (ys,zs) = break p xs in ys ++ (tail zs)
The source code for break simply uses manual recursion.

How can I map a function to a list and stop when a condition is fulfilled and tell me if it stopped or reached the end?

I want to apply a function over a list, but if, at any moment, a result returned by the function is of a certain kind, then I don't want to continue to iterate over the rest of the elements.
I know I could achieve this with this function:
example p f ls = takeWhile p $ map f ls
The thing is that I would like to know if it reached the end of the list, or if it failed to do so.
I thought of this function, but it seems a bit cumbersome:
haltmap :: Eq a => (a -> Bool) -> (b -> a) -> [a] -> [b] -> Either [a] [a]
haltmap _ _ acc [] = Right acc
haltmap p f acc (h:t)
| p output = Left acc
| otherwise = haltmap p f (acc ++ [output]) t
where output = f h
I use Left and Right to know if it went through the entire list or not.
I'm sure there's a better way to do that.
I'd use span for this. It's like takeWhile but it gives you a pair with the remainder of the list as well as the matching part, like this:
> span (<3) [1,2,3,2,1]
([1,2],[3,2,1])
Then you can check if the remainder is empty:
haltmap :: (a -> Bool) -> (b -> a) -> [b] -> Either [a] [a]
haltmap p f xs = (if null rest then Right else Left) ys
where
(ys, rest) = span p (map f xs)
You can use foldr for this. Because go does not evaluate the second argument unless needed, this will also work for infinite lists. (Will Ness also had an answer that also used foldr, but it seems they've deleted it).
import Data.Bifunctor (bimap)
haltmap :: Eq a => (b -> Bool) -> (a -> b) -> [a] -> Either [b] [b]
haltmap p f xs = foldr go (Right []) xs
where
go x a
| p output = let o = (output:) in bimap o o a
| otherwise = Left []
where output = f x
main = do
print $ haltmap (<5) (+1) [1..]
print $ haltmap (<12) (+1) [1..10]
Try it online!
Using a tuple with a Bool may be easier, though.
import Data.Bifunctor (second)
haltmap :: Eq a => (b -> Bool) -> (a -> b) -> [a] -> (Bool, [b])
haltmap p f xs = foldr go (True, []) xs
where
go x a
| p output = second (output:) a
| otherwise = (False, [])
where output = f x
haltmap (<5) (+1) [1..] //(False,[2,3,4])
haltmap (<12) (+1) [1..10] //(True,[2,3,4,5,6,7,8,9,10,11])
Try it online!
I found a solution with foldr, which is the following:
haltMap :: (a -> Bool) -> (b -> a) -> [b] -> Either [a] [a]
haltMap p f = foldr (\x acc -> if p x then Left []
else (either (\a -> Left (x:a)) (\b -> Right (x:b)) acc))
(Right []) . map f
Also, to return, instead of the partial list, the element which failed, all is needed it to change Left [] to Left x in the if clause, and change the (\a -> Left (x:a)) to Left in the else clause.

Haskell concat / filter according specific rules

According to following rules, I tried to solve the following problem:
No definition of recursion
No List of Comprehension
Only Prelude-Module is allowed.
Now I have to implement higher-order for concat and filter.
Im at this point:
concat' :: [[a]] -> [a]
concat' a = (concat a)
filter' :: (a -> Bool) -> [a] -> [a]
filter' p [] = []
filter' p (x:xs)
| p x = x : filter p xs
| otherwise = filter p xs
The concat function is working (nothing special so far) -> Is that a defined recursion? I mean I use the predefined concat from standard-prelude but myself I don't define it - or am I wrong?
For the filter, the function I've looked up the definition of standard prelude but that's either not working and it contains a definition of recursion.
I'm supposing the concat and filter functions should be avoided. Why would we need to implement concat and filter if they're already available? So try implementing them from scratch.
We can use folding instead of recursion and list comprehensions. The below solutions use the function foldr.
foldr :: Foldable t => (a -> b -> b) -> b -> t a -> b
concat' :: [[a]] -> [a]
concat' = foldr (++) []
filter' :: (a -> Bool) -> [a] -> [a]
filter' p = foldr (\x acc -> if p x then x:acc else acc) []
Examples:
main = do
print $ concat' ["A", "B", "CAB"] -- "ABCAB"
print $ filter' (\x -> x `mod` 2 == 0) [1..9] -- [2, 4, 6, 8]
You may do as follows;
concat' :: Monad m => m (m b) -> m b
concat' = (id =<<)
filter' p = ((\x-> if p x then [x] else []) =<<)
=<< is just flipped version of the monadic bind operator >>=.
filter' (< 10) [1,2,3,10,11,12]
[1,2,3]

Understanding Haskell function in a lambda calculus way

Im trying to define the filter function. Based on the function's definition, the filter' function is a function (say help function to differ from the main filter' function) that takes in a function and a list to give a list. The help function takes in a variable and gives back a Bool value. But according the line 4, the help function evaluates a along with [x] to give a Bool Value which then finally gives back a list.
So can I understand the help function as a function that takes in a and [a] to give a Bool value. The main filter' function then takes in this Bool value to give back a list?
Im aware that the function's definition does not suggest this but it's kinda logical based on the code. Thanks
filter' :: (a -> Bool) -> [a] -> [a]
filter' _ [] = []
filter' a (x:xs)
| a x == True = x:filter' a xs
| otherwise = filter' a xs
I think this will be clearer if we give the function of type a -> Bool a name other than a.
filter' :: (a -> Bool) -> [a] -> [a]
filter' _ [] = []
filter' f (x:xs)
| f x == True = x:filter' f xs
| otherwise = filter' f xs
Now f has type a -> Bool, x :: a, and xs :: [a].
I like your description of (a -> Bool) -> [a] -> [a] as "takes in a function and a list to give a list". The recursive calls to filter' in lines 4 & 5 have the same type. f is passed along unchanged. xs is a list of as, but it's one a shorter than the input list. There is only one function filter'. The definition of the function refers to itself - that's an essential part of what we mean by "recursive function".
You can use the syntax even more to aid your understanding:
filter' :: (a -> Bool) -> [a] -> [a]
filter' p [] = []
filter' p (x:xs)
| (p x) == True = x : ( filter' p xs )
| otherwise = ( filter' p xs )
Which is
filter' :: (a -> Bool) -> [a] -> [a]
filter' p [] = []
filter' p (x:xs)
| (p x) = x : ( filter' p xs )
| otherwise = ( filter' p xs )
Or translate it to the more basic constructs,
filter' :: (a -> Bool)
-> [a] -> [a]
filter' p = ( \ xs -> case xs of
{ [] -> []
; (x:ys) | p x -> x : ( filter' p ys )
; (x:ys) -> ( filter' p ys ) } )
" p" is for "predicate". It is used by filter' to test each x in the input xs, to decide whether to include that x or not in the output, according to the Boolean value that the testing has produced.
p is just passed around unchanged from one invocation of filter' to the next. This is usually coded away with the so called "worker-wrapper" transformation,
filter' :: (a -> Bool) -> [a] -> [a]
filter' p xs = go xs where
go [] = []
go (x:xs) | p x = x : go xs
| otherwise = go xs
Lastly, a simpler-looking definition could also be
filter' :: (a -> Bool) -> [a] -> [a]
filter' p xs = go xs where
go [] = []
go (x:xs) = [x | p x] ++ go xs
which corresponds nicely with the foldMap-based definition
filter' p = foldMap (\ x -> [x | p x])

How to pattern match the end of a list?

Say I wanted to remove all zeros at the end of a list:
removeEndingZeros :: (Num a, Eq a) => [a] -> [a]
removeEndingZeros (xs ++ [0]) = removeEndingZeros xs
removeEndingZeros xs = xs
This does not work because of the (++) operator in the argument. How can I determine the end of a list through pattern-matching?
There is a function in Data.List to do this:
dropWhileEnd :: (a -> Bool) -> [a] -> [a]
dropWhileEnd p = foldr (\x xs -> if p x && null xs then [] else x : xs) []
So you can drop the trailing zeros with
dropWhileEnd (== 0)
Another, very similar, function can be implemented like this:
dropWhileEnd2 :: (a -> Bool) -> [a] -> [a]
dropWhileEnd2 p = foldr (\x xs -> if null xs && p x then [] else x : xs) []
dropWhileEnd2 p has exactly the same semantics as reverse . dropWhile p . reverse, but can reasonably be expected to be faster by a constant factor. dropWhileEnd has different, non-comparable strictness properties than the others (it's stricter in some ways and less strict in others).
Can you figure out circumstances under which each can be expected to be faster?

Resources