Using Ord to create and compare empty lists - haskell

I am trying to create an empty list then confirm that it is empty so I can later on insert elements into it.
I tried to simply assign the function to an empty list but when i try to confirm that it is empty I get an Non-exhaustive patterns in function exception.
Here is what I have so far.
emptyList::Ord a => [(a,b)]
emptyList = []
isEmpty::Ord a => [(a,b)] -> Bool
isEmpty[(a,b)] = null [undefined, undefined]
I am trying to get something like
isEmpty emptyList
True
I guess my question here is that, how can I confirm that the list is empty based on the given type?

I think you are confusing the type ([(a,b)]) with the patterns. In your isEmpty function, you write:
isEmpty::Ord a => [(a,b)] -> Bool
isEmpty [(a,b)] = null [undefined, undefined]
But this does not mean that you are going to match lists of type [(a,b)]. You already said that in your type signature. Your [(a,b)] in the second line, means you define a pattern. The pattern sayd that you are only matching lists that contain exactly one element: a 2-tuple, with a the first item of that tuple, and b the second item of that tuple.
If you then pass it an empty list, or a list with two or more elements, then the pattern will not match, and hence it will raise an error.
If you want to match any list, you can simply use a variable:
isEmpty :: Ord a => [(a,b)] -> Bool
isEmpty ls = null ls
here isEmpty thus will call null with that variable. We can perform an η-reduction here, and write:
isEmpty :: Ord a => [(a,b)] -> Bool
isEmpty = null
There is no need at all, to restrict ourselves to only lists with 2-tuples where the first item of these tuples has a type that is a member of the Ord typeclass however, we can let this work with any list. So we can generalize the type to:
isEmpty :: [a] -> Bool
isEmpty = null
In fact null can operate over any Foldable, since it has type null :: Foldable f => f a -> Bool.
Given the above function defintion, there is no need to implement your own isEmpty, you can simply call null emptyList.

Related

How to use maybe in a list in Haskell?

I am using haskell and the following:
convertToBasis :: [String] -> Maybe [Basis]
convertToBasis [] = Nothing
convertToBasis (h:t) = basis : convertToBasis t
where
basis = toCandidateBasis h
Returns a type of [Maybe Basis] I want a type of Maybe [Basis]
toCandidateBasis is shown below:
toCandidateBasis :: String -> Maybe Basis
toCandidateBasis myStr = if not $ has7UniqueLetters myStr [] then
Nothing
else
Just (dedupAndSort myStr)
The function returns nothing if a String does not have 7 unique characters otherwise it removes duplicates and sorts the String alphabetically and return that result. Now the return type of the function is Maybe Basis. Hence when I when I get a list of strings and want to convert them to their respective candidate basises one by one, it will concat all the maybes and return me a type of:
[Maybe Basis]
But I want a type of
Maybe [Basis]
It should return Nothing only when the given Basis array is empty otherwise return some result. How do I do this?
There's really no reason to use a Maybe [a] unless there is a semantic difference between Nothing and Just [], which it sounds like there is not in your case. However, it is a fairly common use case to reduce a list [Maybe a] to a list [a] by removing all the Nothings— so common, in fact, that there's a builtin function for doing that: catMaybes :: [Maybe a] -> [a].

Make list from a custom data type in Haskell (reverse operation also)

I'm going to learn how to convert a data type to an array using Haskell. That's a case as I need to get that from the data as follows:
data List a = Nil | Cons (List a) a
listToList :: List a -> [a]
listToList Nil = []
listToList (Cons Nil a) = [a]
...another pattern match, I guess...
What is missing here to complete this conversion without non-exhaustive matching (flatten may be)? I'm embarrassed a few because there is a lack of comprehension how to handle on. Also, I would be grateful for any prompt about a reverse function (from [a] to List a).
You can make of an accumulator here. You define a helper function where you pass a value, and each recursive call, you pass a slighly modified copy of that value.
Your listToList thus then will look like:
listToList :: List a -> [a]
listToList = go []
where go … = …
Here you still need to implement go. go has as signature go :: [a] -> List a -> [a]. In case you encounter a Nil, then you can return the accumulator. In case you encounter a Cons x y, you prepend the accumulator with y and recurse on x.

Check if a string contains a certain character

I need to check if my string contain a specific character.
I tried this:
charFound :: Char -> String -> Bool
charFound c s = filter(\x -> x == c) s
But it gives me:
Couldn't match expected type Bool with actual type [Char]
I know that filter:
returns a list constructed from members of a list (the second argument) fulfilling a condition given by the first argument.
How could I reach the goal and return a bool instead of a list?
For your purpose, you could use the function elem :: Eq a => a -> [a] -> Bool from prelude. It does exactly what it says on the label. To implement this function, I would use something like this:
elem = any . (==)
or even more elementary:
elem x = foldr ((||) . (x ==)) False
Notice that due to the short-circuit behaviour of (||) this also works with infinite lists as long as x is found.
The type of filter is (a -> Bool) -> [a] -> [a].
You have supplied the first argument which has type Char -> Bool (which is correct), then the second argument which is String (that's [Char]) which is correct, so the type of filter (\x -> x == c) s is [Char].
But the type signature you have provided says the function returns a Bool, which doesn't match the actual type returned.
You probably want to use any instead of filter. It's type is (a -> Bool) -> [a] -> Bool.
There's also an all function that returns True if and only if all elements of the list satisfy the predicate passed. You may also consider the functions or and and that given a [Bool] compute the disjunction or conjunction of the values. So any f = or . map f and all f = and . map f.
For all list-related functions see the Data.List module.

How to create a base case for a tuple in Haskell?

I have the following function:
encode_single :: (Eq a) => [a] -> (Int, a)
encode_single (x:xs) = (count xs + 1, x)
However, Haskell complained about needing a base case, but I don't know how to do this because of the generic a type.
Thanks!
First of all, what you received is only a warning, not an error. Haskell does not need the base case of the empty list, it just suggests it.
Partial functions are most often an anti-pattern in functional programming so it just points out something that may be wrong. You can avoid the warning in different ways.
The first one is to make your function safe: if it cannot always return a value it's return type shouldn't be (Int, a) but Maybe (Int, a), so you could do:
encode_single :: (Eq a) => [a] -> Maybe (Int, a)
encode_single [] = Nothing
encode_single (x:xs) = Just (count xs + 1, x)
Otherwise you'd have to return a meaningful value for the empty case (just returning undefined isn't better than not defining that case). It might be appropriate to do somethign like:
encode_single [] = (0, undefined)
However this assumes that any code that uses the result of encode_single will not evaluate the second element of the tuple if the first element is zero (note that if the list isn't empty the first element is always positive, so 0 can be used as a sentinel value).
This may or may not be the case. However one thing is sure: this is not compile-time safe so you may receive some run-time errors when calling such a function.
Simply enough: at the type you desire you cannot write a total function of that specification. You need to change the type.
You can either add a default a or indicate partiality using Maybe.
encode_single :: a -> [a] -> (Int, a)
encode_single :: [a] -> Maybe (Int, a)
if you cannot change the type signature, you can piggyback on head i.e.
encode_single :: [a] -> (Int, a)
encode_single a = (length a, head a)
obviously, empty list input is not handled properly.

what is [a] as a type in Haskell?

This question is about type in Haskell programming language.
When I type
:t []
I get the return as:
[] :: [a]
What is [a]?
Rewriting it like so might make things clearer:
[] :: forall a. [a]
So, since it doesn't contain any value, haskell can't decide on a type and leaves it open. If you use it in a typed expression, however, like
x = []
f :: [Int] -> [Int]
f l = l
y = f x
it automatically gets resolved to [Int], since it is used as this type.
It's a placeholder. It basically means any type could go there. In other words, if you had a function
someFunc :: [Int] -> ()
You could pass [] to it because [] is [a], which will match [Int] (by replacing the a placeholder with the concrete Int type).
Now if you look at, say, id, you'll find it has the type a -> a. This means that it's a function that takes an object of any type, and returns an object of the same type. Interestingly, because the function knows absolutely nothing about the object it's given (since it has no constraints on the type), you know that this function has to do either of two things:
Return the input object, or
Return ⊥ (bottom).

Resources