I am just starting to learn Haskell and I have the assignment to use higher order functions to create a function with the following type definition
-- compr :: (a->b) -> (a -> Bool) -> [a] -> [b]
The function is not relevant, can be the simplest functions so my idea was like this:
identity x = x
booleans x | x == 1 = True
| x ==0 = False
| otherwise = False
compr identity booleans xs = filter booleans(map (identity) xs)
but this function has this type
compr :: (a->b) -> (b -> Bool) -> [a] -> [b]
I have tried everything but with no positive results. I hope you can help me.
You almost got it, but you need to apply the filter before the map. In that way, the filter applies to [a] instead of [b], and the predicate gets the right type.
> compr identity booleans xs = map identity (filter booleans xs)
> :t compr
compr :: (a -> b) -> (a -> Bool) -> [a] -> [b]
By the way, I find the names you use for your variables to be misleading. For instance, the identity variable in the definition of compr has nothing to do with the identity function you declared before.
I'd suggest you use more generic variable names instead, e.g.
> compr f p xs = map f (filter p xs)
where f stands for "function" and p for predicate.
There is already a standard library function in Haskell called id (id :: a -> a) to replace your identity function. So accordingly depending on how you will define your booleans function you might simplify your comp function as follows;
booleans x | x == 1 = True
| otherwise = False
compr :: (a -> Bool) -> [a] -> [a]
compr = filter booleans . map id
*Main> compr booleans [1,2,3,4]
[1]
Related
I was hoping to find a better way to solve a problem I've encountered in Haskell.
Given a list and a condition create a new list with only elements which satisfy the condition. Below is a solution I used. Is there a better alternative which doesn't involve maybes?
eg :: (Eq a, Num a) => (a -> Bool) -> [a] -> [a]
eg cond i = catMaybes (map (\x-> if cond x then Just x else Nothing) i)
Your eg is equivalent to filter :: (a -> Bool) -> [a] -> [a]. Indeed, you can filter with:
filter (\x -> some_condition x) my_list
If some_condition is for example a simple a -> Bool function, this is equivalent to:
filter some_condition my_list
Neither your implementation of eg nor the one with filter require the Eq a and Num a type constraints by the way: one can simply use guards or pattern match on the outcome of cond x.
filter is implemented with explicit recursion [src]:
filter :: (a -> Bool) -> [a] -> [a]
filter _pred [] = []
filter pred (x:xs)
| pred x = x : filter pred xs
| otherwise = filter pred xs
Here for an empty list it thus returns the empty list, and when the list is not empty, it will only prepend x if pred x is satisfied.
There is a similar question I found here that asks almost the same thing, but not quite.
The question I have is how to compose a list of functions of type (a -> Bool) to be one function that is also (a -> Bool).
Ex.
compose :: [(a -> Bool)] -> (a -> Bool)
compose [] = **?**
compose (x:xs) = x **?** compose xs
The question that was similar to this was taking three functions and mixing them all like so:
newFunction x f g y = f x || g x || y x
But this is very limited because you have to supply a specific number of functions, and it does not return another function, it returns a Boolean. I essentially want a function that gives me the above function without functions as arguments.
I tried messing with Monoids to make this work but I ran into issues with wrapping the functions into a Monoid in the first place, let alone actually composing them together as newFunction does.
Is there a way to compose a list of functions of type (a -> Bool) to one function of the same type?
We can make use of any :: Foldable => (a -> Bool) -> f a -> Bool here:
compose :: Foldable f => f (a -> Bool) -> a -> Bool
compose = flip (any . flip ($))
or as #chepner suggests, with a (&):
import Data.Function((&))
compose :: Foldable f => f (a -> Bool) -> a -> Bool
compose = flip (any . (&))
or without the point-free styling (and probably simpler to understand):
compose :: Foldable f => f (a -> Bool) -> a -> Bool
compose l x = any ($ x) l
The above will work with any sort of Foldable, so a list [], Maybe, etc.
Look: compose xs in your definition is a function. So you can call it with an argument - like compose xs a, - and that will return a Bool.
You can use this to define the recursive case.
First of all, the recursive case must return a function - because that's what your type signature states. So it must look something like:
compose (x:xs) = \a -> ...
Now, the logic would go like this: first of all, call the first function in the list - like x a, - and if it returns true, then that's the result; otherwise, call the composition of the tail - like compose xs a. Let's write that down:
compose (x:xs) = \a -> x a || compose xs a
Next up, you need to decide what to do with the empty list. Obviously it can be either a function that always returns True or a function that always returns False, there can be no other options unless you can inspect the argument somehow, which you can't, because it's of generic type.
So, should it return True or False? Let's see: if it returns True, then any composition will always be True, that's how the || operator works. So we might as well just write compose _ = \_ -> True. Therefore, the only sane variant is for it to return False.
Summing up all of the above, here's your definition:
compose [] = \a -> False
compose (x:xs) = \a -> x a || compose xs a
And of course, you can use a shorter syntax instead of returning lambdas:
compose [] a = False
compose (x:xs) a = x a || compose xs a
To implement this using monoids you can use the Any (from Data.Monoid) boolean wrapper which implements the disjunction behaviour you want when combining values e.g.
(Any False) `mappend` (Any True)
=> Any {getAny = True}
Functions which return monoidal values are themselves monoids - mappending two such functions returns a function which evalulates the argument on both functions and mappends the results e.g.
f :: Int -> Any
f x = Any $ x > 10
g :: Int -> Any
g x = Any $ x < 3
comp :: Int -> Any
comp = f `mappend` g
comp 0
=> Any {getAny = True}
comp 4
=> Any {getAny = False}
comp 11
=> Any {getAny = True}
So if you lift each a -> Bool into a function a -> Any then these be composed with mappend.
mconcat reduces a list of monoidal values into a single value so applying this to a list of a -> Any function returns a function which applies the disjunction to each result. You then need to unwrap the Bool from the resulting Any value with getAny.
import Data.Monoid
compose :: [(a -> Bool)] -> (a -> Bool)
compose fs x = let anyfs = map (\f -> Any . f) fs
combined = mconcat anyfs
anyResult = combined x
in getAny anyResult
This can also be written as:
compose :: [(a -> Bool)] -> (a -> Bool)
compose = (getAny .) . mconcat . (map (Any .))
As danidiaz points out in the comments, you can also use foldMap. This also has a more general type:
compose :: Foldable t => t (a -> Bool) -> a -> Bool
compose = (getAny .) . foldMap (Any .)
A simpler example (I am no Haskeller), based on your requirements:
compose :: [(a -> Bool)] -> (a -> Bool)
compose [] = (\y -> False)
compose (x:xs) = (\y -> (x y) || ((compose xs) y))
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 want to write a function in Haskell that rotates the list given as the second argument by the number of positions indicated by the first argument. Using pattern matching, implement a recursive function
I have written the following function:
rotate :: Int -> [a] -> [a]
rotate 0 [y]= [y]
rotate x [y]= rotate((x-1) [tail [y] ++ head [y]])
but this function always produces a error. Is there any way to solve it?
The function should do the following when it runs:
rotate 1 "abcdef"
"bcdefa"
[y] does not mean "let y be a list". It means "this argument is a list containing one element called y". You have the right structure, but you don't need the brackets around the y.
rotate :: Int -> [a] -> [a]
rotate 0 y = y
rotate x y = rotate (x-1) (tail y ++ [head y])
TL&DR
rotate :: Int -> [a] -> [a]
rotate = drop <> take
In Haskell the most concise but also a curious way to rotate a list could be using the Semigroup type class instance of the function type (a -> b). Lets check the relevant part of the instance.
instance Semigroup b => Semigroup (a -> b) where
f <> g = \x -> f x <> g x
First things first, <> is in fact the inline version of the mappend function from the Monoid type class.
Then we see, the Semigroup b => constraint in the type signature states that the return type b should also be a member of Semigroup type class. Since we use drop :: Int -> [a] -> [a] and take :: Int -> [a] -> [a] we can quickly notice that b is in fact another function with type signature [a] -> [a] so it is a member of Semigroup type class if and only if it's b, which happens to be [a] is also a member of the Semigroup type class and it is.
instance Semigroup [a] where
(<>) = (++)
So everything holds so far but how does it work?
We can deduce from the type signatures as follows;
(drop :: Int -> ([a] -> [a])) <> (take :: Int -> ([a] -> [a])) is
\n -> (drop n :: [a] -> [a]) <> (take n :: [a] -> [a]) which is
\n -> \xs -> (drop n xs :: [a]) <> (take n xs :: [a]) which is
\n -> \xs -> (drop n xs) ++ (take n xs)
This is basically better than the answers using recursive ++ operator to add the head as a singleton list to the end of the tail since it yields an O(n^2) time complexity.
I think you want something like this:
rotate :: Int -> [a] -> [a]
rotate 0 x = x
rotate times (x:xs) = rotate (times - 1) (xs ++ [x])
I want to define a function that computes the number of elements in a list that satisfy a given predicate:
number_of_elements :: (a -> Bool) -> [a] -> Int
number_of_elements f xs = length (filter f xs)
For example:
number_of_elements (==2) [2,1,54,1,2]
should return 2.
We can write it shorter:
number_of_elements f = length . filter f
Is it possible to write it without f parameter?
Sure it is:
number_of_elements = (length .) . filter
I don't think you can get more readable than the what you suggested. However, just for the fun of it you can do this:
numberOfElements = (.) (.) (.) length filter
or
(.:) = (.) . (.)
numberOfElements = length .: filter
You might like to read about Semantic Editor Combinators. Take the result combinator from there:
result :: (output -> output') -> (input -> output) -> (input -> output')
result = (.)
The result combinator takes a function and applies it to the result of another function. Now, looking at the functions we have:
filter :: (a -> Bool) -> [a] -> [a]
length :: [a] -> Int
Now, length applies to [a]'s; which, it happens, is the result type of functions of the form foo :: [a] -> [a]. So,
result length :: ([a] -> [a]) -> ([a] -> Int)
But the result of filter is exactly an [a] -> [a] function, so we want to apply result length to the result of filter:
number_of_elements = result (result length) filter