Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

First element in a list haskell

Tags:

haskell

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)
like image 865
Q_96 Avatar asked Apr 30 '20 16:04

Q_96


People also ask

How do I remove the last element in a list Haskell?

items. pop_back(); Removes last element from items, without returning anything.


2 Answers

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

like image 188
Alejandro De Cicco Avatar answered Nov 10 '22 00:11

Alejandro De Cicco


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.

like image 36
Russell Emerine Avatar answered Nov 10 '22 00:11

Russell Emerine