Haskell Programming simple function recurrsion - function

for this program an element and a list is taken in and a new list is returned. if there are any occurrences of the element in the list, they should be deleted in the list that is returned.
allOcrDelete :: Eq a => a -> [a] -> [a]
allOcrDelete del = if head [a] == number then allOcrDelete(tail [a])
else del ++ [head [a]] ++ allOcrDelete(tail [a])
this is what i have so far. i'm not sure how to take an element and a list as parameters and how to take the head or tail and compare the head to the element to be deleted

As jamshidh mentioned, you can use filter and write:
allOcrDelete del = filter (/= del)
(allOcrDelete is a special case of filter)
A naive implementation could be:
module Main where
allOcrDelete :: Eq a => a -> [a] -> [a]
allOcrDelete _ [] = []
allOcrDelete del (x:xs)
| del == x = allOcrDelete del xs
| otherwise = x:allOcrDelete del xs
main = do
print $ allOcrDelete 2 [1,2,5,3,2,4,5,2]
Note:
you don't need to use the head and tail functions in this case because pattern matching the list against (x:xs) will already split the list into the head x and the tail xs (this is a common pattern in Haskell)

First let me say, don't use head and tail, ever. ...Well, at least not until you've gathered so much experience that you can recognise the few cases when it actually makes something more concise. Usually pattern matching (or folding etc.) is not only much safer but also far more readable & intuitive.
So in your case, you're trying to get head [a]. What is [a]? You evidently mean, “the argument of the function which has type [a], but that's not possible to write in Haskell code. (What if there was yet another element of the same type?) To use an argument, you have to _bring it in scope, with some arbitrary name (only, names can't contain brackets), e.g.
delete' del xs = if head xs == number then delete'(tail xs)
else del ++ [head xs] ++ delete'(tail xs)
would work. (Sort of. number also doesn't make sense there: you probably want to compare with del, instead of inserting that.)
However, since the only thing you do with xs is call those evil head and tail functions, you should rather write it this way:
delete' del (x:xs) = if x == number then delete' xs
else del ++ [x] ++ delete' xs

Related

Haskell-- Trying to make my foldl function work

I have a function that converts [a, b, c, d, . . . ] to [(a,b), (c, d), . . .]. Now this works and here is the code for that:
makeTuple :: [a] -> [(a,a)]
makeTuple [] = []
makeTuple [a] = []
makeTuple (x:y:xs) = (x,y): (makeTuple xs)
Now the next thing I have to do is this: Using the previous function, convert each tuple to a product of its two elements, using foldl and a lambda expression. And this is what I have:
productTuple [x] = foldl makeTuple [] [x]
Now I am not sure if this is exactly what is being asked of me. I'm not sure if I should make a separate function with the type declaration and whatnot. Maybe someone can tell me if that is the best way to approach this. Also this code does not work, and I don't know why,I need help with this part. (notice that it says to use a lambda, but I have no idea how to really properly use those, which is another part I need help with) I would really appreciate it, thanks.
The lambda function should respect this signature :
[a] -> (b,b) -> [a]
The accumulator has the type [a], the tuple has the type (b,b)
You can try a lambda like this \acc (a, b) -> acc++[a*b]
The final function could look like :
productTuple :: Num a => [a] -> [a]
productTuple xs = foldl (\acc (a, b) -> acc++[a*b]) [] (makeTuple xs)
You have some examples of foldl function here
I tried this code here
The exercise is asking you to preprocess the input lists with the makeTuple, and then fold over it.
productTuple :: [Int] -> [Int]
productTuple xs = foldl (some lambda) something (makeTuple xs)
It is not the most convenient way to do it, but I guess that the point of the exercise is to force you to use foldl just for the sake of it.

Beginner Haskell: Making a last function with reverse

I'm attempting to make a function that generates the last item in a list. I want to use reverse and !!. This is what I have so far:
myLast :: [a] -> [a] -> Int -> a
myLast xs = (reverse xs) !! 1
I know the problem lies somewhere within the type, but I'm having trouble identifying how to fix it.
A function's type signature has nothing to do with what you use in the function, it only describes how other people can use this function you're defining. So by writing
myLast :: [a] -> [a] -> Int -> a
you're saying, users need to supply two lists and and integer. Just to get the last element of one of the lists?? That doesn't make sense.
You surely mean
myLast :: [a] -> a
You should generally write that down before even thinking about how you're going to implement that function.
With that signature, you can write various implementations:
myLast :: [a] -> a
myLast xs = head $ reverse xs
myLast' :: [a] -> a
myLast' [l] = l
myLast' (_:xs) = myLast' xs
myLast'' :: [a] -> a
myLast'' = fix $ \f (x:xs) -> maybe x id . teaspoon $ f xs
or whatever weird implementation you choose, it has nothing to do with the signature.
On an unrelated note: though last is actually a standard function from the prelude, it's a kind of function avoided in modern Haskell: last [] gives an error, because the is no a value to be found in the empty list! Errors are bad. Hence the “ideal” way to write it is actually
myLast :: [a] -> Maybe a
myLast [] = Nothing
myLast [x] = x
myLast (_:xs) = myLast xs
I would recommend not using !! at all, but to use head.
myLast xs = head (reverse xs)
Head returns the first element of the list it is given as argument.
If you insist on using !!, in Haskell arrays are indeed zero-based, which means that !! 0 gets the first element, !! 1 the second, etc.
As for the type: myLast takes an array of some type and returns one item of that same type. That is denoted as follows:
myLast :: [a] -> a
#leftaroundabout covered this way better in his answer.
Based on #leftaroundabout 's answer, here's an implementation that should do what you want:
safeHead :: [a] -> Maybe a
safeHead [] = Nothing
safeHead (x:_) = Just x
myLast :: [a] -> Maybe a
myLast [] = Nothing
myLast xs = safeHead $ reverse xs
The Maybe type is constructed as follows (from Hackage):
data Maybe a = Nothing | Just a
deriving (Eq, Ord)
myLast [1, 2, 3, 4], for example, will return Just 4. If you want to use the value 4 you can use the function fromJust function from the Data.Maybe module (fromJust (Just 4) returns 4). fromJust is defined like this:
-- | The 'fromJust' function extracts the element out of a 'Just' and
-- throws an error if its argument is 'Nothing'.
--
-- ==== __Examples__
--
-- Basic usage:
--
-- >>> fromJust (Just 1)
-- 1
--
-- >>> 2 * (fromJust (Just 10))
-- 20
--
-- >>> 2 * (fromJust Nothing)
-- *** Exception: Maybe.fromJust: Nothing
--
fromJust :: Maybe a -> a
fromJust Nothing = error "Maybe.fromJust: Nothing" -- yuck
fromJust (Just x) = x

Rewriting an uncurried function haskell

I've been learning about uncurrying and applying $ in functions in haskell but I'm still having issues converting an uncurried function to something less mysterious.
The function I'm given is
apple = map $ uncurry $ flip ($)
and I realize that this takes a list of tuples and applies to corresponding function in the tuple to the variable inside. So I'm trying to rewrite it as
apple ls = foldr function _ ls
where function (a,b) c = (uncurry b) (a,c)
I get the error for _ as a parse error and I have no idea which starting point to use. I need to make this polymorphic and I'm realizing that this most likely will not be the way to make it less mysterious. Any ideas? They'd be greatly appreciated
Apple has the type
apple :: [(a, a->b)] -> [b]
We could rewrite it as
apple ls = map (\(a, f) -> f a) ls
So writing this with foldr is very doable,
apple ls = foldr (\(a, f) rest -> f a : rest) [] ls
Or, we can rewrite this to pointfree
apple = foldr ( (:) . (uncurry . flip $ ($)) ) []
The reason for the parse error is that _ is the special syntax for "variables I don't care about". This let's you write things like
foo _ _ _ _ a = a
And not get an error about repeated variables. Basically we just filled in _ with the starting empty list and fixed function so that it appends to c rather than trying to apply it to a.
If I wanted to write this in the clearest way possible, then the original
apple = map . uncurry . flip $ ($)
Is quite nice.
The key for understanding is removing complexity.
Thus I would suggest you deal with a single tuple first. Write the following function:
tapp :: (a, a ->b) -> b
in terms of ($) and flip and uncurry.
(To make it even easier, you could first do it for a tuple (a -> b, a) first).
Next, make clear to yourself how map works: If you have a function f :: (a -> b), then map f will be a function [a] -> [b]. Hence map tapp does what you want.
You can now replace tapp in map (tapp) by it's definition (this are the benefits of referential transparency).
And this should take you back to your original expression. More or less so, because, for example:
f $ g h
can be written
f (g h)
or
(f . g) h

Sort a list into tuples

I’m new to Haskell and am trying to sort a list of tuples using their first element, using the sort function. So if I had ["a", "b", "a", "c", "c"] I would get something like [(1,"b"), (2,"a"), (2,"c")] (in alphabetical order in the event of the same number).
How would I go about doing this? I am totally lost at the moment… I am still trying to get into the ‘Haskell way of thinking’.
import Data.List (sort, group)
import Control.Arrow ((&&&))
answer :: Eq a => [a] -> [(Int, a)]
answer = sort . map (length &&& head) . group . sort
But as you're a beginner, it's perhaps a bit much to tell you about &&&, so I'll rewrite it like this:
import Data.List (sort, group)
answer :: Eq a => [a] -> [(Int, a)]
answer = sort . map f . group . sort
where f xs # (x:_) = (length xs, x)
You'll note I'm calling sort twice. This is intentional.
The final sort (the one on the left) sorts the output list of tuples, and it just so happens that it sorts in ascending order of the first element of the tuple, breaking ties by sorting on the second element of the tuple.
The initial sort (the one on the right) sorts the input list, because of what group does: it groups adjacent equal elements into a sublist. (Incidentally, these sublists are guaranteed never to be empty --- otherwise it wouldn't be safe to use head or ignore the empty list option in the pattern match.)
The map f then turns these lists (e.g. ["a", "a"]) into what we're interested in: the number of times these elements occur, and a single representative of these elements (e.g. (2, "a")).
The idiom here is that we're using a pipeline: our input goes into a function, the output of that function goes into another function, and so on until the function at the end of the pipeline produces output that we present as our own output. Note that this only works because each function takes only a single argument (map takes two arguments, f is the first of those arguments, so map f takes one argument).
As a consequence of this, answer is a function even though its argument doesn't explicitly appear. This is point-free style.
In non point-free style, it would look like
answer xs = sort . map f . group . sort $ xs
where f xs # (x:_) = (length xs, x)
or
answer xs = sort $ map f $ group $ sort xs
where f xs # (x:_) = (length xs, x)
or
answer xs = sort (map f (group (sort xs)))
where f xs # (x:_) = (length xs, x)
It is a good idea to use point-free style when it makes your code clearer.
If you like, you can use the <<< operator (from Control.Arrow again, sorry) to make the dataflow direction superficially more explicit:
import Data.List (sort, group)
import Control.Arrow ((<<<))
answer :: Eq a => [a] -> [(Int, a)]
answer = sort <<< map f <<< group <<< sort
where f xs # (x:_) = (length xs, x)
Some people think that this is the wrong way round and want the functions that "happen" first to be on the left. These people can use >>> (also from Control.Arrow), which is exactly the same as <<< except its arguments are flipped round:
import Data.List (sort, group)
import Control.Arrow ((>>>))
answer :: Eq a => [a] -> [(Int, a)]
answer = sort >>> group >>> map f >>> sort
where f xs # (x:_) = (length xs, x)

Function application: Why is $ used here?

A while ago, I asked a question about $, and got useful answers -- in fact, I thought I understood how to use it.
It seems I was wrong :(
This example shows up in a tutorial:
instance Monad [] where
xs >>= f = concat . map f $ xs
I can't for the life of me see why $ was used there; ghci isn't helping me either, as even tests I do there seem to show equivalence with the version that would simply omit the $. Can someone clarify this for me?
The $ is used here because it has lower precedence than normal function application.
Another way to write this code is like so:
instance Monad [] where
xs >>= f = (concat . map f) xs
The idea here is to first construct a function (concat . map f) and then apply it to its argument (xs). As shown, this can also be done by simply putting parenthesis around the first part.
Note that omitting the $ in the original definition is not possible, it will result in a type error. This is because the function composition operator (the .) has a lower precedence than normal function application effectively turning the expression into:
instance Monad [] where
xs >>= f = concat . (map f xs)
Which doesn't make sense, because the second argument to the function composition operator isn't a function at all. Although the following definition does make sense:
instance Monad [] where
xs >>= f = concat (map f xs)
Incidentally, this is also the definition I would prefer, because it seems to me to be a lot clearer.
I'd like to explain why IMHO this is not the used style there:
instance Monad [] where
xs >>= f = concat (map f xs)
concat . map f is an example of so-called pointfree-style writing; where pointfree means "without the point of application". Remember that in maths, in the expression y=f(x), we say that f is applied on the point x. In most cases, you can actually do a final step, replacing:
f x = something $ x
with
f = something
like f = concat . map f, and this is actually pointfree style.
Which is clearer is arguable, but the pointfree style gives a different point of view which is also useful, so sometimes is used even when not exactly needed.
EDIT: I have replaced pointless with pointfree and fixed some examples, after the comment by Alasdair, whom I should thank.
The reason $ is used here is doe to the type signature of (.):
(.) :: (b -> c) -> (a -> c) -> a -> c
Here we have
map f :: [a] -> [[b]]
and
concat :: [[b]] -> [b]
So we end up with
concat . map f :: [a] -> [b]
and the type of (.) could be written as
(.) :: ([[b]] -> [b]) -> ([a] -> [[b]]) -> [a] -> [b]
If we were to use concat . map f xs, we'd see that
map f xs :: [[b]]
And so cannot be used with (.). (the type would have to be (.) :: (a -> b) -> a -> b