Check if a string contains a certain character - haskell

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.

Related

Higher Order Functions evaluation

Create a high-order function in Haskell that takes in another function. That second function takes in a list and evaluates to each index to be true or false. The high order function should evaluate to true if the second function evaluates to true for at least 2 indexes in the list
This is what I have so far
Bool _ _ = []
Bool f (x y :xs) = f x y : Bool f xs
Split your task into subtasks:
Create a high-order function in Haskell that takes in another function.
higherOrder :: (a -> b) -> Bool
higherOrder f = undefined -- a higher order function that takes
-- in another function
We have not learned anything about the type of the passed function, which is why we use the placeholder a -> b. This will be change later, once we learn more about f.
That second function takes in a list and evaluates to each index to be true or false.
This function is passed in. You don't need to implement it, it will be provided as an argument. You do however need to know its type signature, in this case
f :: [a] -> [Bool] -- a function taking a list of any type
-- ([a]), evaluating it to a list of booleans
-- example usage
f [1, 2, 3] == [True, False, True]
Which we use to update the type of our higherOrder
higherOrder :: ([a] -> [Bool]) -> Bool
The high order function should evaluate to true if the second function evaluates to true for at least 2 indexes in the list
You could replace this step with a simpler step: Write a function atLeastTwo :: [Bool] -> Bool, that takes a list of Booleans ([Bool]) and returns True if at least two indexes' values are true.
atLeastTwo :: [Bool] -> Bool
atLeastTwo xs = undefined
Maybe you can implement atLeastTwo by filtering the list, keeping only True values and then counting its length. You might find filter :: (a -> [Bool]) -> [a] -> [a] and length :: [a] -> Int1 useful.
Putting it all together you will discover that the task description is not clear. It does not talk about the list that is passed to higherOrder. In your case it probably should have been passed as a second parameter (xs) so we update higherOrder again to
higherOrder :: ([a] -> [Bool]) -> [a] -> Bool
higherOrder f xs = undefined
Proposal for an updated assignment
A more natural problem would be, where the passed function processes a list element (a -> Bool) instead of a list ( [a] -> [Bool]), and would read:
[Updated/alternative assignment: replacing ([a] -> [Bool]) with (a -> Bool).]
Implement a (higher-order) function atLeastTwoTrues :: (a -> Bool) -> [a] -> Bool. The first argument being passed to atLeastTwoTrues should be a function that can evaluate a value to either True or False. The second argument is a list of values. Your function should return True if and only if at least two elements of the passed list evaluate to True using the first argument.
This would avoid some ambiguity but is a different problem.
Good luck and enjoy your Haskell journey. It is difficult at the start. It has been for all of us. Don't give up, because once you start to master it, you will enjoy it.
1This is actually not the complete truth since length works with more data types than just lists and has a more general type.
Prelude> :t length
length :: Foldable t => t a -> Int

Attempting to model operators for Integrated Dynamics

Integrated Dynamics is a Minecraft mod that uses lazy operators with currying, and acts very similarly to Haskell. I've been writing functions that have the same signature though do not perform anything to try and more easily explore combining the operators. An example is itemName :: Item -> String with itemName _ = "".This is to give in ghci :t itemName as Item -> String.
I've tried to make a couple slightly more complicated ones such as
itemListCount :: (Num c) => [a] -> b -> c
itemListCount _ _ = 0
I'd like to see the signature of this if I pipe it directly with greater than or less than, expecting to see something like [a] -> b -> c -> d. a List, an Item(custm data type) an integer and return a boolean. when calling with :t (lessThan . itemListCount) This gives error:
Couldn't match type 'b0 -> Integer' with 'Int'.
Expected type: [a] -> Int
Actual type: [a] -> b0 -> Integer
Is this because I'm calling it with :t that it's trying to evaluate instead of combining the functions?
(lessThan . itemListCount) is the same as \x -> lessThan (itemListCount x). It's a function, which takes one value, then calls itemListCount with this value, and then calls lessThan with whatever itemListCount returned.
itemListCount's type is (ignoring the Num constraint) [a] -> b -> c. It is a function which takes a list of any type, and then returns a function which takes any type as input and returns any number type as output.
So in \x -> lessThan (itemListCount x), x should be a list of any type, and (itemListCount x) is a function which takes any type as input and returns any number type as output. Presumably, this is not a valid argument for lessThan.

Match type error when counting palindromes in a list in Haskell

I'm getting a match type [Char] with String -> Bool error:
isPalindrome :: String -> Bool
isPalindrome w = w == reverse w
countPalindromes :: [String] -> Int
countPalindromes ss = length (filter (== isPalindrome) ss)
countPalindromes uses isPalindrome to check if a string is a palindrome.
I now have a different issue than in my first question about this palindrome count task. The first issue was solved, and I was instructed to open a new question to solve the new issue. Which is why this is a different question.
isPalindrome :: String -> Bool, which is to say that it expects a string, then gives you a boolean to say whether or not that string is a palindrome.
(==) :: Eq a => a -> a -> Bool, which is to say that it expects two values of typeclass Eq (in other words: anything equatable) and tells you whether or not they are equal.
Pair those together and you get (== isPalindrome) :: (String -> Bool) -> Bool*. You've handed (==) a String -> Bool value, so it's expecting one more and will tell you if the two are equal. That's not quite what you want, though. You're not comparing two functions....
In fact, you're not comparing any two things at all. You only want to see which values passed to countPalindromes return True when called by isPalindrome. That's what filter is for!
filter :: (a -> Bool) -> [a] -> [a]
It's looking for an a -> Bool to pass as the first argument. This is the function that will be deciding what makes it through the filter and what doesn't, and in this case you want to use some derivation of isPalindrome. Looking again at isPalindrome in this context we see:
isPalindrome :: String -> Bool
that looks an awful lot like an a -> Bool function! Let's try substituting all the as in filter's type signature with String.
filter :: (String -> Bool) -> [String] -> [String]
That looks like it's exactly what you're wanting! Try, then, using filter isPalindrome instead of filter (== isPalindrome).
* nitpick: functions (more generally: values of type (-> r)) are not members of the Eq typeclass so you'd actually get an error saying that you can't tell if a String -> Bool is equal to another String -> Bool. It's not relevant to the problem at-hand, though, so I'm pretending that's not an issue and burying this explanation down here.

what does ((Ord, Ord) -> Bool) -> [String] -> String mean in haskell

I changed this question to make it more clear. shortestStringHelper has type (Int -> Int -> Bool) -> [String] -> String. Note the String may appear as [Char] instead depending on how Haskell feels at the time. This function will look a lot like shortestString and shortestString' but it is more general because it takes a function as an argument (Int -> Int -> Bool). Note: Depending on how you write it, you may get (Int -> Int -> Bool) -> [[a]] -> [a], which is also ok.
I know how to write the find the shortest string
shortestString :: [String] -> String
shortestString lst = if null lst then "" else foldl (\shortest x -> if length x < length shortest then x else shortest) (head lst) lst
shortestString' :: [String] -> String
shortestString' lst = if null lst then "" else foldl (\shortest x -> if length x <= length shortest then x else shortest) (head lst) lst
and they work, but I am not sure if I understand this question, and I don't know what does ((Ord, Ord) -> Bool) means.
Ord means something incompatible with that in the Prelude, but ordinarily the type signature you give would be a function with two arguments.
The first argument has type (Ord, Ord) -> Bool, a function that takes a pair of Ord and returns a Bool. In context, this might be intended as a generalized comparison function, such as one that compares the lengths of two strings expressed as whatever an Ord is here. This is unusual, because you would expect something like that to be written like isShorter :: String -> String -> Bool, or maybe isShorter :: [a] -> [a] -> Bool.
The second argument has type [String], a list of String objects. The function returns a single String.
However, you haven’t given us enough information to understand what’s going on in this specific assignment.
Edit: You’ve updated your question so that the type of the first argument is (Int, Int) -> Bool rather than (Ord, Ord) -> Bool, which makes more sense. This might be a way to wrap a comparison on two arguments, such as the lengths of two strings, for a higher-order function that expects one argument.

Couldn't match type ‘a’ with ‘Int’ in Haskell

place n x is meant to find the place of integer n in the list x, for example place 2 [1,2,3] will return 1:
place :: Int -> [a] -> Int
place n x = length $ takeWhile (/=n) x
But it gets the error Couldn't match type ‘a’ with ‘Int’
Why? takeWhile should return a list and its length is an integer, hence place should output an Int eventually.
The correct type signature for place is:
place :: Int -> [Int] -> Int
When you use [a] in place of [Int] you are saying that place will work on a list of any type. For instance, I could call it like this:
place 3 [True, False, False, True]
or call it with a list of Char:
place 4 "this is a test"
But neither of these can work because takeWhile will compare each element of the list against the Int n. This forces the list to be a list of Ints.
You are using (/=) :: Eq ty => ty -> ty -> Bool where that second ty ~ Int due to the type of n. If ty is Int then the type of the other argument of (/=) (x) must be Int too.
find the place of integer n in the list x
ah, but there are no integers in the list at all. The type is [a]. Only if the type were [Int] would it be possible to find an n in it.
Now, you might say “[Int] is a possible instantiation of [a], so it could still work in that case”. Well, it could – but only in that case, and therefore it would be stupid not to enforce a ~ Int in the type signature.
More reasonably, you might want to find any type of number which happens to be equal to the integer n. Well, you can do that:
place' :: (Num a, Eq a) => Int -> [a] -> Int
place' n = length . takeWhile (/= fromIntegral n)
Here, I first convert n to the type of number that's contained in the list, and then compare it with those numbers.

Resources