So i need to do a find2 method that take the first Element out.
For example find2 :: (a -> Bool) -> [a] -> a
and find2 (>4) [1 .. 10]
Should have a the output 5
I am not good with haskell, but i want to learn it.
My first try was
find2 :: (a -> Bool) -> [a] -> a
find2 p [] = []
find2 p (x:xs)
|p x = x+1
|otherwise = finde p xs
but i am getting an error
* Couldn't match expected type `a' with actual type `[a0]'
`a' is a rigid type variable bound by
the type signature for:
find2 :: forall a. (a -> Bool) -> [a] -> a
at C:\\Users\XY\Desctop\XY.hs:30:1-32
* In the expression: []
In an equation for `find2': find2 p [] = []
* Relevant bindings include
p :: a -> Bool
(bound at C:\\Users\XY\Desctop\XY.hs:31:7)
find2 :: (a -> Bool) -> [a] -> a
(bound at C:\\Users\XY\Desctop\XY.hs:31:1)
There is a problem here. There might not be a value in your list for which p holds true. You can see that problem in the base case of your function, when you return an empty list. However, you declared your function to return a single a value, and not a list.
Because of that, you need a way to differentiate a found value from an empty value. For this you can declare your function to return Maybe a instead of a. That way, when you reach the empty list case, you can return Nothing, and if you find the element you were looking for you can return Just x. It would look like this:
find2 :: (a -> Bool) -> [a] -> Maybe a
find2 p [] = Nothing
find2 p (x:xs)
|p x = Just x
|otherwise = find2 p xs
If you're not familiar with the Maybe type, you can read more about it here
If you're ok with erroring when the list contains no satisfactory elements, you can do this:
find p xs = head (filter p xs)
or the equivalent point-free, which I like more
find p = head . filter p
(not this though, it's over the top)
find = (head .) . filter -- obscure, not a good choice
If you want to return it in a Maybe, you can import Data.Maybe and do this:
find p = listToMaybe . filter p
If you want it in a list, this never errors:
find p = take 1 . filter p
You can use dropWhile (not . p) instead of filter p if you like, too.
Manually defining the recursion is fine too, but I think it's work that isn't necessary.
Related
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.
Given a condition, I want to search through a list of elements and return the first element that reaches the condition, and the previous one.
In C/C++ this is easy :
int i = 0;
for(;;i++) if (arr[i] == 0) break;
After we get the index where the condition is met, getting the previous element is easy, through "arr[i-1]"
In Haskell:
dropWhile (/=0) list gives us the last element I want
takeWhile (/=0) list gives us the first element I want
But I don't see a way of getting both in a simple manner. I could enumerate the list and use indexing, but that seems messy. Is there a proper way of doing this, or a way of working around this?
I would zip the list with its tail so that you have pairs of elements
available. Then you can just use find on the list of pairs:
f :: [Int] -> Maybe (Int, Int)
f xs = find ((>3) . snd) (zip xs (tail xs))
> f [1..10]
Just (3,4)
If the first element matches the predicate this will return
Nothing (or the second match if there is one) so you might need to special-case that if you want something
different.
As Robin Zigmond says break can also work:
g :: [Int] -> (Int, Int)
g xs = case break (>3) xs of (_, []) -> error "not found"
([], _) -> error "first element"
(ys, z:_) -> (last ys, z)
(Or have this return a Maybe as well, depending on what you need.)
But this will, I think, keep the whole prefix ys in memory until it
finds the match, whereas f can start garbage-collecting the elements
it has moved past. For small lists it doesn't matter.
I would use a zipper-like search:
type ZipperList a = ([a], [a])
toZipperList :: [a] -> ZipperList a
toZipperList = (,) []
moveUntil' :: (a -> Bool) -> ZipperList a -> ZipperList a
moveUntil' _ (xs, []) = (xs, [])
moveUntil' f (xs, (y:ys))
| f y = (xs, (y:ys))
| otherwise = moveUntil' f (y:xs, ys)
moveUntil :: (a -> Bool) -> [a] -> ZipperList a
moveUntil f = moveUntil' f . toZipperList
example :: [Int]
example = [2,3,5,7,11,13,17,19]
result :: ZipperList Int
result = moveUntil (>10) example -- ([7,5,3,2], [11,13,17,19])
The good thing about zippers is that they are efficient, you can access as many elements near the index you want, and you can move the focus of the zipper forwards and backwards. Learn more about zippers here:
http://learnyouahaskell.com/zippers
Note that my moveUntil function is like break from the Prelude but the initial part of the list is reversed. Hence you can simply get the head of both lists.
A non-awkward way of implementing this as a fold is making it a paramorphism. For general explanatory notes, see this answer by dfeuer (I took foldrWithTails from it):
-- The extra [a] argument f takes with respect to foldr
-- is the tail of the list at each step of the fold.
foldrWithTails :: (a -> [a] -> b -> b) -> b -> [a] -> b
foldrWithTails f n = go
where
go (a : as) = f a as (go as)
go [] = n
boundary :: (a -> Bool) -> [a] -> Maybe (a, a)
boundary p = foldrWithTails findBoundary Nothing
where
findBoundary x (y : _) bnd
| p y = Just (x, y)
| otherwise = bnd
findBoundary _ [] _ = Nothing
Notes:
If p y is true we don't have to look at bnd to get the result. That makes the solution adequately lazy. You can check that by trying out boundary (> 1000000) [0..] in GHCi.
This solution gives no special treatment to the edge case of the first element of the list matching the condition. For instance:
GHCi> boundary (<1) [0..9]
Nothing
GHCi> boundary even [0..9]
Just (1,2)
There's several alternatives; either way, you'll have to implement this yourself. You could use explicit recursion:
getLastAndFirst :: (a -> Bool) -> [a] -> Maybe (a, a)
getLastAndFirst p (x : xs#(y:ys))
| p y = Just (x, y)
| otherwise = getLastAndFirst p xs
getLastAndFirst _ [] = Nothing
Alternately, you could use a fold, but that would look fairly similar to the above, except less readable.
A third option is to use break, as suggested in the comments:
getLastAndFirst' :: (a -> Bool) -> [a] -> Maybe (a,a)
getLastAndFirst' p l =
case break p l of
(xs#(_:_), (y:_)) -> Just (last xs, y)
_ -> Nothing
(\(xs, ys) -> [last xs, head ys]) $ break (==0) list
Using break as Robin Zigmond suggested ended up short and simple, not using Maybe to catch edge-cases, but I could replace the lambda with a simple function that used Maybe.
I toyed a bit more with the solution and came up with
breakAround :: Int -> Int -> (a -> Bool) -> [a] -> [a]
breakAround m n cond list = (\(xs, ys) -> (reverse (reverse take m (reverse xs))) ++ take n ys) $ break (cond) list
which takes two integers, a predicate, and a list of a, and returns a single list of m elements before the predicate and n elements after.
Example: breakAround 3 2 (==0) [3,2,1,0,10,20,30] would return [3,2,1,0,10]
I'm learning Haskell and I've been wrestling with this problem:
Write func :: (a -> Bool) -> [a] -> [a] (take elements of a list until the predicate is false) using foldr
This is what I have so far:
func :: (a -> Bool) -> [a] -> [a]
func f li = foldr f True li
and got the following errors:
Couldn't match expected type ‘[a]’ with actual type ‘Bool’
and
Couldn't match type ‘Bool’ with ‘Bool -> Bool’
Expected type: a -> Bool -> Bool
Actual type: a -> Bool
I'm a bit confused since I learned foldr by passing a function with two arguments and getting a single value. For example I've used the function by calling
foldr (\x -> \y -> x*y*5) 1 [1,2,3,4,5]
to get a single value but not sure how it works when passing a single argument function into foldr and getting a list in return. Thank you very much.
Let’s do an easier case first, and write a function that uses foldr to do nothing (to break down the list and make a the same list). Let’s look at the type signature of foldr:
foldr :: (a -> b -> b) -> b -> [a] -> [b]
And we want to write an expression of the form
foldr ?1 ?2 :: [a] -> [a]
Now this tells us that (in the signature of foldr) we can replace b with [a].
A thing we haven’t worked out, ?2, is what we replace the end of the list with and it has type b = [a]. We don’t really have anything of type a so let’s just try the most stupid thing we can:
foldr ?1 []
And now the next missing thing: we have ?1 :: a -> [a] -> [a]. Let’s write a function for this. Now there are two reasonable things we can do with a list of things and another thing and nothing else:
Add it to the start
Add it to the end
I think 1 is more reasonable so let’s try that:
myFunc = foldr (\x xs -> x : xs) []
And now we can try it out:
> myFunc [1,2,3,4]
[1,2,3,4]
So what is the intuition for foldr here? Well one way to think of it is that the function passed gets put into your list instead of :, with the other item replacing [] so we get
foldr f x [1,2,3,4]
——>
foldr f x (1:(2:(3:(4:[]))))
——>
f 1 (f 2 (f 3 (f 4 x)))
So how can we do what we want (essentially implement takeWhile with foldr) by choosing our function carefully? Well there are two cases:
The predicate is true on the item being considered
The predicate is false for the item being considered
In case 1 we need to include our item in the list, and so we can try doing things like we did with our identity function above.
In case 2, we want to not include the item, and not include anything after it, so we can just return [].
Suppose our function does the right thing for the predicate "less than 3", here is how we might evaluate it:
f 1 (f 2 (f 3 (f 4 x)))
--T T F F (Result of predicate)
-- what f should become:
1 : (2 : ([] ))
——>
[1,2]
So all we need to do is implement f. Suppose the predicate is called p. Then:
f x xs = if p x then x : xs else []
And now we can write
func p = foldr f [] where
f x xs = if p x then x : xs else []
I'm practicing some Haskell to understand the \, case.. of and Maybe better.
I've got this little function here which should return Nothing if the array is empty, Just y if y is equal to the head of the array xs and Just (tail xs) if y is not equal to the head of the array xs.
I set the return type of the function to Maybe a because in one case it should return an Int and in the other an [Int].
funct :: Int -> [Int] -> Maybe a
funct = \y xs -> case xs of
[] -> Nothing
xs -> if ((head xs) == y)
then Just y
else Just (tail xs)
What am I missing? I am getting the error that it couldn't match type a with [Int]. Isn't the a in Maybe a generic or is it influenced by the fact that I "used" the a as an Int in the Just y part?
EDIT: Ok my suggestion was bs, I tested it with Just (tail xs) in the then and else part and I'm still getting the same error.
set the return type of the function to Maybe a because in one case it should return an Int and in the other an [Int].
Haskell is statically typed. Meaning it can not - at runtime - have a different return type. It can only have one return type. a is not an ad hoc type (in the sense that it can be any type at runtime). It means that a will be determined - at compile time - based on the types of other parameters.
For instance you can write: foo :: a -> a -> a to specify that if foo takes two Ints (again known at compile time), the result will be an Int.
You can however use Either a b to say that you will either return a Left a, or a Right b. So you can rewrite it to:
funct :: Int -> [Int] -> Maybe (Either Int [Int])
funct = \y xs -> case xs of
[] -> Nothing
xs -> if ((head xs) == y)
then Just (Left y)
else Just (Right (tail xs))
Your function however is quite verbose, you can make it more clear and compact as follows:
funct :: Int -> [Int] -> Maybe (Either Int [Int])
funct _ [] = Nothing
funct y (h:t) | h == y = Just (Left y)
| otherwise = Just (Right t)
Furthermore we can generalize it to:
funct :: Eq a => a -> [a] -> Maybe (Either a [a])
funct _ [] = Nothing
funct y (h:t) | h == y = Just (Left y)
| otherwise = Just (Right t)
Here Eq is a typeclass that specifies that there exists a function (==) :: a -> a -> Bool that we can use. Otherwise using == in the body of the function would not be possible.
Furthermore we use patterns in the head of every clause. [] is a pattern that describes the empty list. (h:t) on the other hand is a pattern describing a list containing at least one element: the head h, followed by a (possibly empty tail t).
I have recently been teaching myself Haskell, and one of my exercises was to re-implement the filter function. However, of all the exercises I have performed, my answer for this one seems to me the most ugly and long. How could I improve it? Are there any Haskell tricks I don't yet know?
myfilter :: (a -> Bool) -> [a] -> [a]
myfilter f (x:xs) = if f x
then x : myfilter f xs
else myfilter f xs
myfilter _ [] = []
Thank You
The simplest way to neaten your implementation is to use guards. Instead of pattern = value, you can write write pattern | boolean = value; this will only match when boolean is true. Thus, we can get
filter1 :: (a -> Bool) -> [a] -> [a]
filter1 p (x:xs) | p x = x : filter1 p xs
| otherwise = filter1 p xs
filter1 _ [] = []
(Note that otherwise is just a synonym for True.) Now, we have filter p xs in two places, so we can move it out into a where clause; these are shared by everything which shares a common pattern, even if it has a different guard:
filter2 :: (a -> Bool) -> [a] -> [a]
filter2 p (x:xs) | p x = x : xs'
| otherwise = xs'
where xs' = filter2 p xs
filter2 _ [] = []
(This implementation is the one used by GHCs Prelude.)
Now, neither of these are tail-recursive. This can be disadvantageous, but it does make the function lazy. If we want a tail-recursive version, we could write
filter3 :: (a -> Bool) -> [a] -> [a]
filter3 p xs = let filter3' p (x:xs) ys | p x = next $! x:ys
| otherwise = next $! ys
where next = filter3' p xs
filter3' _ [] ys = reverse ys
in filter3' p xs []
Note, however, that this would fail on infinite lists (though all the other implementations will work), thanks to the reverse, so we make it strict with $!. (I think I did this right—I could have forced the wrong variable. I think I got this one right, though.)
Those implementations all look like yours. There are, of course, others. One is based on foldr:
filter4 :: (a -> Bool) -> [a] -> [a]
filter4 p = let check x | p x = (x :)
| otherwise = id
in foldr check []
We take advantage of point-free style here; since xs would be the last argument to both filter4 and foldr check [], we can elide it, and similarly with the last argument of check.
You could also take advantage of the list monad:
import Control.Monad
filter5 :: MonadPlus m => (a -> Bool) -> m a -> m a
filter5 p xs = do x <- xs
guard $ p x
return x
The list monad represents nondeterminism. You pick an element x from xs, make sure that it satisfies p, and then return it if it does. All of these results are then collected together. But note that this is now more general; this works for any MonadPlus (a monad which is also a monoid; that is, which has an associative binary operation mplus—++ for lists—and an identity element mzero—[] for lists), such as [] or Maybe. For instance, filter5 even $ Just 1 == Nothing, and filter5 even $ Just 2 == Just 2.
We can also adapt the foldr-based version to get a different generic type signature:
import Control.Monad
import qualified Data.Foldable as F
import qualified Data.Monoid as M
filter6 :: (F.Foldable f, MonadPlus m, M.Monoid (m a))
=> (a -> Bool) -> f a -> m a
filter6 p = let check x | p x = return x
| otherwise = mzero
in F.foldMap check
The Data.Foldable module provides the Foldable type class, which represents any structure which can be folded like a list (placing the result in a generic Monoid instead.) Our filter requires a MonadPlus constraint on the result as well so that we can write return x. The foldMap function requires a function which converts everything to elements of a Monoid, and then concatenates all of them together. The mismatch between the f a on the left and the m a on the right means you could, for instance, filter6 a Maybe and get back a list.
I'm sure that there are (many!) other implementations of filter, but these are the 6 that I could think of relatively quickly. Now, which of these do I actually like best? It's a tossup between the straightforward filter2 and the foldr-based filter4. And filter5 is nice for its generic type signature. (I don't think I've ever needed a type signature like filter6's.) The fact that filter2 is used by GHC is a plus, but GHC also uses some funky rewrite rules, so it's not obvious to me that it's superior without those. Personally, I would probably go with filter4 (or filter5 if I needed the genericity), but filter2 is definitely fine.
How about a list comprehension?
myfilter f xs = [x | x <- xs, f x]
You could at least DRY it up a bit by pulling out that common myfilter f xs code:
myfilter :: (a -> Bool) -> [a] -> [a]
myfilter f (x:xs) = if f x
then x : rest
else rest
where rest = myfilter f xs
myfilter _ [] = []
For comparison, here's Wikipedia's implementation:
myfilter :: (a -> Bool) -> [a] -> [a]
myfilter _ [] = []
myfilter f (x:xs) | f x = x : myfilter f xs
| otherwise = myfilter f xs
In Haskell, most of the time you can (and should) use guards instead of if-then-else:
myfilter :: (a -> Bool) -> [a] -> [a]
myfilter f (x:xs)
| f x = x : myfilter f xs
| otherwise = myfilter f xs
myfilter _ [] = []
This ends up being basically the same definition as used in the standard library.