Partition using recursion - haskell

Trying to learn myself some haskell, I know about the function
partition :: (a -> Bool) -> [a] -> ([a], [a])
would I be able to this using recursion rather than using the function. eg id have my own defined function
partition':: (a -> Bool) -> [a] -> ([a], [a])
which would use recursion

Here's one recursive definition:
partition':: (a -> Bool) -> [a] -> ([a], [a])
partition' _ [] = ([],[])
partition' f (x:xs) | f x = (x:matched,notMatched)
| otherwise = (matched,x:notMatched)
where (matched,notMatched) = partition' f xs

Related

how to create my own map using another function i defined in haskell

I am trying to create map using another function that I have been supplied with can anyone help so
I have created:
ConcatListsOnFunc :: (a -> [b]) -> [a] -> [b]
ConcatListsOnFuncf [] = []
ConcatListsOnFunc func (y:ys) = func y ++ flattenMap func ys
and i was wondering how i can use that function above to implement the higher order function map
which is of type
myMap :: (a -> b) -> [a] -> [b]
from myMap with input (+1) [1,2,3] should give output [2,3,4]
can anyone help is there a way to create myMap using my previously defined function with a lambda function?
You can wrap items in a singleton list, so:
myMap :: (a -> b) -> [a] -> [b]
myMap f = concatListsOfFunc (\x -> [f x])

Types and higher-order function in Haskell

Could someone help me to understand this issue.
I have this simple function:
takeAsLong :: [a] -> (a -> Bool) -> [a]
takeAsLong [] _ = []
takeAsLong (x:xs) test | test x = x : takeAsLong xs test
| otherwise = []
But when I try to rewrite it using if-then-else I have an error.
takeAsLong :: [a] -> (a -> Bool) -> [a]
takeAsLong [] _ = []
takeAsLong (x:xs) test = if test x then x : takeAsLong [xs] test else []
The error is in the recursive call of "takeAsLong [xs] test" but I dont understand why it doesnt like it?
Error msg:
Couldn't match type ‘a’ with ‘[a]’
Expected: [a] -> Bool
Actual: a -> Bool
‘a’ is a rigid type variable bound by
the type signature for:
takeAsLong :: forall a. [a] -> (a -> Bool) -> [a]
So why does it expect function test to be [a] -> Bool and why version with guards doesnt have same issue?
xs is a list of items except the first item. If you use [xs] then you wrapt that list in a singleton list.
You thus should call takeAsLong xs test instead of takeAsLong [xs] test:
takeAsLong :: [a] -> (a -> Bool) -> [a]
takeAsLong [] _ = []
takeAsLong (x:xs) test = if test x then x : takeAsLong xs test else []
Using an if-then-else is not that common. Usually the predicate will also be the first parameter. So a more "Haskell-ish" version is likely:
takeAsLong :: (a -> Bool) -> [a] -> [a]
takeAsLong p = go
where go [] = []
go (x:xs)
| p x = x : go xs
| otherwise = []
This function already exists and is known as takeWhile :: (a -> Bool) -> [a] -> [a]
The main problem here is in the part takeAsLong [xs] when you do that you are giving to the function takeAsLong :: [a] -> (a -> Bool) -> [a] a list of lists, takeAsLong :: [[a]] -> (a -> Bool) -> [a] that type is the one would work, but you type is the other one.
There is how to do it in #willem answer:
takeAsLong :: [a] -> (a -> Bool) -> [a]
takeAsLong [] _ = []
takeAsLong (x:xs) test = if test x then x : takeAsLong xs test else []

Basic encryption using higher order functions in Haskell

I'm working on a problem that runs along the lines of basic encryption. I'm trying to create a function called encryptf that
takes a list xs of a's
takes a list ys of a's
returns a function that maps elements of xs to the corresponding elements of ys and maps everything else to itself.
So far it looks like this:
encryptf :: Eq a => [a] -> [a] -> (a -> a)
encryptf xs ys = \f -> head [d | (c,d) <- (zip xs ys)]
Then there's a second function called encryptString that looks like this:
encryptString :: (a -> a) -> [a] -> [a]
encryptString f xs = map f xs
and these functions will be used like this:
encryptString (encryptf "abc" "xyz") "dcba"
and that would return "dzyx"
Now I know that my encryptf function is wrong, because it would change everything to the first element of ys. I'm not sure where to go from here. Any help would be appreciated.
The idea is you search the given character in zipped list, and if it there then return second pair and if not then return the character itself.
encryptf :: Eq a => [a] -> [a] -> (a -> a)
encryptf xs ys =
let ret = zip xs ys in
\f ->
case lookup f ret of
Just c -> c
Nothing -> f
encryptString :: (a -> a) -> [a] -> [a]
encryptString f xs = map f xs
*Main> encryptString (encryptf "abc" "xyz") "dcba"
"dzyx"

Haskell: Defining map function using unfold

I have the following Haskell method
unfold :: (a -> Bool) -> (a -> b) -> (a -> a) -> a -> [b]
unfold p h t x
| p x = []
| otherwise = (h x):(unfold p h t (t x))
How can i define the regular prelude map f x method using this given unfold method.
If you define:
map' :: (a -> b) -> [a] -> [b]
map' f = unfold null (f.head) tail
then
\> map' show [1..5]
["1","2","3","4","5"]
\> map' (+1) []
[]

Function in a function testing prog

I have a question about a selecting process.
I want to make a program where you type in a operation, a value and a list.
For example: programName (>) 4 [1,2,4,2,5], and it should return: [1,2,3].
I know how to make a program that make the function take takes whats equal in a list and make a new list like this:
programEqual :: Eq a => a -> [a] -> [a]
programEqual e [] = []
programEqual e (x:xs) = if (e == x) then e : takeEqual e xs else takeEqual e xs
I also understand that that you need two functions for this, but I can't understand how I should get the (tester) stuff in there.
You can adapt your previous program by adding a function argument. Here's a hint:
programEqual :: (a -> a -> Bool) -> a -> [a] -> [a]
programEqual f e [] = []
programEqual f e (x:xs) = if ....
If you want to implement that the easiest way possible
Just use filter:
filter :: (a -> Bool) -> [a] -> [a]
filter (< 4) [1, 2, 4, 2, 5] == [1, 2, 2]
If you want to pass the operator and the operand separately:
filter' op x = filter (op x)
and then
filter' (<) 4 [1,2,4,2,5] == [1,2,2]
If you want to tinker
There's a very useful function defined in Data.List:
takeWhile :: (a -> Bool) -> [a] -> [a]
Its signature should be rather helpful for you.
Here's a hint:
(>) :: Int -> Int -> Bool -- simplified from Eq a => ..
(> 4) :: Int -> Bool

Resources