How to get an element in a Haskell list? - list

I want to make a function that looks up a String in a list of type [(String, Int)] and returns the Int paired with the String.
Like this:
λ> assignmentVariable "x" [("x", 3), ("y", 4), ("z", 1)]
3
Here's what I've tried:
assignmentVariable :: String -> [(String, Int)] -> Int
assignmentVariable [] = error "list is empty"
assignmentVariable n (x:xs) = if x == n
then xs
else assignmentVariable
How could I write this?

Let's take the posted code:
assignmentVariable::String -> [(String, Integer)] -> Integer
assignmentVariable [] = error "list is empty"
assignmentVariable n (x:xs) = if x == n then xs else ...
The first equation has only one argument, while the second has two. Let's fix that.
assignmentVariable::String -> [(String, Integer)] -> Integer
assignmentVariable _ [] = error "list is empty"
assignmentVariable n (x:xs) = if x == n then xs else ...
Since we do x == n, these variables must be of the same type.
However, n::String and x::(String,Integer). We need to split x into its components before comparing.
assignmentVariable::String -> [(String, Integer)] -> Integer
assignmentVariable _ [] = error "list is empty"
assignmentVariable n ((m,x):xs) = if m == n then xs else ...
The result xs is a list, not an Integer as the type signature suggests. You just want x there.
assignmentVariable::String -> [(String, Integer)] -> Integer
assignmentVariable _ [] = error "list is empty"
assignmentVariable n ((m,x):xs) = if m == n then x else ...
Finally, the recursive call. When m/=n, we want to try the other pairs in the list xs, so:
assignmentVariable::String -> [(String, Integer)] -> Integer
assignmentVariable _ [] = error "list is empty"
assignmentVariable n ((m,x):xs) = if m == n
then x
else assignmentVariable n xs

You want to pattern-match on the pair.
assignmentVariable expected ((key, value) : rest)
If the variable name matches the expected name, the first element of the pair…
= if key == expected
You return the associated value, the second element of the pair.
then value
Otherwise, you try to find the value in the rest of the list.
else assignmentVariable expected rest
You can implement it without pattern-matching, of course:
assignmentVariable expected list
= if expected == fst (head list)
then snd (head list)
else assignmentVariable expected (tail list)
However, this is not the usual style in Haskell code.
This function also exists in the Prelude, by the name of lookup.

You're halfway there, actually!
First, it would be better to make a more general type signature, and a better name:
myLookup :: (Eq a) => a -> [(a, b)] -> b
You've done well to have sorted out the edge case of [], but you've not quite finished:
myLookup _ [] = error "myLookup: empty list."
myLookup n ((x, b):xs) = if x == n
then b
else myLookup n xs
Your problem was what you put after the else: you weren't recursively calling the function, you were returning the function, which doesn't make any sense - you need to call it again with different arguments to recur.
If you want to improve, try making a similar function of type Eq a => a -> [(a, b)] -> Maybe b for a challenge.

Just for posterity, I would like to propose an alternative implementation:
assignmentVariables :: Eq a => a -> [(a, b)] -> [b]
assignmentVariables n xs = [v | (n', v) <- xs, n == n']
You can run it in ghci:
> assignmentVariables "x" [("x", 3), ("y", 4), ("z", 1)]
[3]
"Ah!", I hear you say, "But it returns [3] and not 3!". But don't give up on it yet; there are several advantages of the behavior of this function over the behavior you proposed.
The type of assignmentVariables is more honest than the type of assignmentVariable. It doesn't promise to return a value when it doesn't find the given key in its lookup table. This means that, unlike your version, this version will not cause runtime crashes. Moreover, it has a clean way to report the unlikely situation where there are conflicts in the lookup table: it will return all values associated with the given key, even if there are many.
The consumer of the call then gets to decide how to handle the exceptional cases: one can write
case assignmentVariables key lookupTable of
[] -> -- do something appropriate to complain about missing keys
[value] -> -- do something with the value
values -> -- do conflict resolution; for example, use the first value or complain or something
or may simply treat the output of assignmentVariables as a nondeterministic value. The key here is that you are not locked into one behavior (which, of all the choices, crashing? really?).

Related

How to check if length of a list is not equal to length of a list within a list in haskell

Hi Guys I am trying to check whether the length of a list is not equal to length of a list within a list using haskells length function and pattern matching
This is the function i have and its type:
func :: [String] -> [[String]] -> String
where the return string is either "Error different lengths found" OR
"Lengths are the same"
This is what i would input and the expected output see below:
["Planet", "City"] [["Jupiter", "Earth"], ["Berlin", "Madrid", "Krakow"] ]
Output should be "Error different lengths found" due to ["Berlin", "Madrid", "Krakow"] being of size 3 where as ["Planet", "City"] is of size 2
bit unsure how to do this and would appreciate any help!
Something like this would check it in linear time.
compLength :: [String] -> [[String]] -> String
compLength s = go (length s)
where go _ [] = "All Good! Hurray!"
go n (y:ys)
| n /= length y = "Error different lengths found" ++ " [" ++ unwords y ++ "]"
| otherwise = go n ys
I think this gives you the base and the necessary information to tailor the output to your exact needs.
You can write a helper function to check if two lists have the same length, so you can implement a function:
sameLength :: [a] -> [a] -> Bool
sameLength … = …
When you have implemented such function, it is only a matter to check if all sublists have the same length. We can do this with all :: Foldable f => (a -> Bool) -> f a -> Bool:
func :: [a] -> [[a]] -> Bool
func xs yss
| all (sameLength xs) yss = "Lengths are the same"
| otherwise = "Error different lengths found"

Function to find the most frequent element

I am trying to code a function that returns the element that appears the most in a list. So far I have the following
task :: Eq a => [a] -> a
task xs = (map ((\l#(x:xs) -> (x,length l)) (occur (sort xs))))
occur is a function that takes a list and returns a list of pairs with the elements of the inputted list along with the amount of times they appear. So for example for a list [1,1,2,3,3] the output would be [(1,2),(2,1),(3,2)].
However, I am getting some errors related to the arguments of map. Can anyone tell me what I'm doing wrong?
A map maps every item to another item, so here \l is a 2-tuple, like (1,2), (2, 1) or (3, 2). It thus does not make much sense to work with length l, since length :: Foldable f => f a -> Int will always return one for a 2-tuple: this is because only the second part of the 2-tuple is used in the foldable. But we do not need length in the first place.
What you need is a function that can retrieve the maximum based on the second item of the 2-tuple. We can make use of the maximumOn :: Ord b => (a -> b) -> [a] -> a from the exta package, or we can implement our own function to calculate the maximum on a list of items.
Such function thus should look like:
maximumSnd :: Ord b => [(a, b)] -> (a, b)
maximumSnd [] = error "Empty list"
maximumSnd (x:xs) = go xs x
where go [] m = m
go (x#(xa, xb):xs) (ya, yb)
| xb > yb = go … … -- (1)
| otherwise = go … … -- (2)
Here (1) should be implemented such that we make a recursive call but work with x as the new maximum we found thus far. (2) should make a recursive call with the same thus far maximum.
Once we have implemented the maxSnd function, we can use this function as a helper function for:
task :: Eq a => [a] -> (a, Int)
task xs = maxSnd (occur xs)
or we can use fst :: (a, b) -> a to retrieve the first item of the 2-tuple:
task :: Eq a => [a] -> a
task xs = (fst . maxSnd) (occur xs)
In case there are two characters with a maximum number of elements, the maximumSnd will return the first one in the list of occurrences.

Haskell function returns prefix

I am trying to create a function in haskell that takes a predicate and a list as arguments and returns the prefix of the list satisfying the predicate.
the test being:
p1tests = [myTakeWhile (/= ' ') "This is practice." == "This"]
I have this so far..
myTakeWhile :: (a-> Bool ) -> [a] -> [a]
myTakeWhile [] =[]
myTakeWhile (x:xs)=[] : map (x:) (myTakeWhile xs)
I receive errors saying except type
You need to work with both the predicate and the elements in the list. The function thus should look like:
myTakeWhile :: (a -> Bool) -> [a] -> [a]
myTakeWhile _ [] = []
myTakeWhile p (x:xs)
| p x = …
| otherwise = …
where the p x guard thus covers the case where the predicate is satisfied for the first item of the list, and the otherwise is not.
In case the predicate is satisfied, we have to yield x and recurse on the tail of the list. I keep filling in … as an exercise.

How to get the Index of an element in a list, by not using "list comprehensions"?

I'm new in haskell programming and I try to solve a problem by/not using list comprehensions.
The Problem is to find the index of an element in a list and return a list of the indexes (where the elements in the list was found.)
I already solved the problem by using list comprehensions but now i have some problems to solve the problem without using list comprehensions.
On my recursive way:
I tried to zip a list of [0..(length list)] and the list as it self.
then if the element a equals an element in the list -> make a new list with the first element of the Tupel of the zipped list(my index) and after that search the function on a recursive way until the list is [].
That's my list comprehension (works):
positions :: Eq a => a -> [a] -> [Int]
positions a list = [x | (x,y) <- zip [0..(length list)] list, a == y]
That's my recursive way (not working):
positions' :: Eq a => a -> [a] -> [Int]
positions' _ [] = []
positions' a (x:xs) =
let ((n,m):ns) = zip [0..(length (x:xs))] (x:xs)
in if (a == m) then n:(positions' a xs)
else (positions' a xs)
*sorry I don't know how to highlight words
but ghci says:
*Main> positions' 2 [1,2,3,4,5,6,7,8,8,9,2]
[0,0]
and it should be like that (my list comprehension):
*Main> positions 2 [1,2,3,4,5,6,7,8,8,9,2]
[1,10]
Where is my mistake ?
The problem with your attempt is simply that when you say:
let ((n,m):ns) = zip [0..(length (x:xs))] (x:xs)
then n will always be 0. That's because you are matching (n,m) against the first element of zip [0..(length (x:xs))] (x:xs), which will necessarily always be (0,x).
That's not a problem in itself - but it does mean you have to handle the recursive step properly. The way you have it now, positions _ _, if non-empty, will always have 0 as its first element, because the only way you allow it to find a match is if it's at the head of the list, resulting in an index of 0. That means that your result will always be a list of the correct length, but with all elements 0 - as you're seeing.
The problem isn't with your recursion scheme though, it's to do with the fact that you're not modifying the result to account for the fact that you don't always want 0 added to the front of the result list. Since each recursive call just adds 1 to the index you want to find, all you need to do is map the increment function (+1) over the recursive result:
positions' :: Eq a => a -> [a] -> [Int]
positions' _ [] = []
positions' a (x:xs) =
let ((0,m):ns) = zip [0..(length (x:xs))] (x:xs)
in if (a == m) then 0:(map (+1) (positions' a xs))
else (map (+1) (positions' a xs))
(Note that I've changed your let to be explicit that n will always be 0 - I prefer to be explicit this way but this in itself doesn't change the output.) Since m is always bound to x and ns isn't used at all, we can elide the let, inlining the definition of m:
positions' :: Eq a => a -> [a] -> [Int]
positions' _ [] = []
positions' a (x:xs) =
if a == x
then 0 : map (+1) (positions' a xs)
else map (+1) (positions' a xs)
You could go on to factor out the repeated map (+1) (positions' a xs) if you wanted to.
Incidentally, you didn't need explicit recursion to avoid a list comprehension here. For one, list comprehensions are basically a replacement for uses of map and filter. I was going to write this out explicitly, but I see #WillemVanOnsem has given this as an answer so I will simply refer you to his answer.
Another way, although perhaps not acceptable if you were asked to implement this yourself, would be to just use the built-in elemIndices function, which does exactly what you are trying to implement here.
We can make use of a filter :: (a -> Bool) -> [a] -> [a] and map :: (a -> b) -> [a] -> [b] approach, like:
positions :: Eq a => a -> [a] -> [Int]
positions x = map fst . filter ((x ==) . snd) . zip [0..]
We thus first construct tuples of the form (i, yi), next we filter such that we only retain these tuples for which x == yi, and finally we fetch the first item of these tuples.
For example:
Prelude> positions 'o' "foobaraboof"
[1,2,8,9]
Your
let ((n,m):ns) = zip [0..(length (x:xs))] (x:xs)
is equivalent to
== {- by laziness -}
let ((n,m):ns) = zip [0..] (x:xs)
== {- by definition of zip -}
let ((n,m):ns) = (0,x) : zip [1..] xs
== {- by pattern matching -}
let {(n,m) = (0,x)
; ns = zip [1..] xs }
== {- by pattern matching -}
let { n = 0
; m = x
; ns = zip [1..] xs }
but you never reference ns! So we don't need its binding at all:
positions' a (x:xs) =
let { n = 0 ; m = x } in
if (a == m) then n : (positions' a xs)
else (positions' a xs)
and so, by substitution, you actually have
positions' :: Eq a => a -> [a] -> [Int]
positions' _ [] = []
positions' a (x:xs) =
if (a == x) then 0 : (positions' a xs) -- NB: 0
else (positions' a xs)
And this is why all you ever produce are 0s. But you want to produce the correct index: 0, 1, 2, 3, ....
First, let's tweak your code a little bit further into
positions' :: Eq a => a -> [a] -> [Int]
positions' a = go xs
where
go [] = []
go (x:xs) | a == x = 0 : go xs -- NB: 0
| otherwise = go xs
This is known as a worker/wrapper transform. go is a worker, positions' is a wrapper. There's no need to pass a around from call to call, it doesn't change, and we have access to it anyway. It is in the enclosing scope with respect to the inner function, go. We've also used guards instead of the more verbose and less visually apparent if ... then ... else.
Now we just need to use something -- the correct index value -- instead of 0.
To use it, we must have it first. What is it? It starts as 0, then it is incremented on each step along the input list.
When do we make a step along the input list? At the recursive call:
positions' :: Eq a => a -> [a] -> [Int]
positions' a = go xs 0
where
go [] _ = []
go (x:xs) i | a == x = 0 : go xs (i+1) -- NB: 0
| otherwise = go xs (i+1)
_ as a pattern means we don't care about the argument's value -- it's there but we're not going to use it.
Now all that's left for us to do is to use that i in place of that 0.

nub not compiling when checking a list for duplicates

Working on a sudoku inspired assignment and I need to implement a function that checks if a Block Cell has no repeated elements in it (to check if its a valid solution to the puzzle).
okBlock :: Block Cell -> Bool
okBlock b = okList $ filter (/= Nothing) b
where
okList :: [a]-> Bool
okList list
| (length list) == (length (nub list)) = True
| otherwise = False
Block a = [a]
Cell = [Maybe Int]
Haskell complains saying No instance for (Eq a) arising from a use of "==" Possible fix: add (Eq a) to the context of the type signature for okList...
Adding Eq a to the type signature does not help. I have tried the function in the terminal and it works fine for for lists, and for lists of lists (i.e the type I am feeding it in the function).
What am I missing here?
Well you can only filter out duplicates, if there is a way to check whether two values are duplicates. If we look at the type signature for nub, we see:
nub :: Eq a => [a] -> [a]
So that means that in order to filter out duplicates in a list of as, we need a to be an instance of the Eq class. We can thus simply forward the type constraint further in the signatures of the functions:
okBlock :: Block Cell -> Bool
okBlock b = okList $ filter (/= Nothing) b
where
okList :: Eq => [a] -> Bool
okList list
| (length list) == (length (nub list)) = True
| otherwise = False
We do not need to specify that Cell is an instance of Eq because:
Int is an instance of Eq;
if a is an instance of Eq, so is Maybe a, so Maybe Int is an instance of Eq; and
if a is an instance of Eq, so is [a], so [Maybe Int] is an instance of Eq.
That being said we can do some syntactical improvements of the code:
there is no need to work with guards if you simply return the result of the guard True and False, and
you can use an eta reduction and omit the b in okBlock.
you don't need parentheses around function application (unless to feed to result straight to another, non-infix function).
This gives us:
okBlock :: Block Cell -> Bool
okBlock = okList . filter (/= Nothing)
where
okList :: Eq => [a] -> Bool
okList list = length list == length (nub list)
A final note is that usually you do not have to specify a type signature. In that case Haskell will aim to dervice the most generic type signature. So you can write:
okBlock = okList . filter (/= Nothing)
where
okList list = length list == length (nub list)
Now okBlock will have type:
Prelude Data.List> :t okBlock
okBlock :: Eq a => [Maybe a] -> Bool
Three points that are too big to make in a comment.
nub is horribly slow
nub takes O(n^2) time to process a list of length n. Unless you know the list is very short, this is the wrong function to use to remove duplicates from a list. Adding a bit more information about what sort of thing you're working with allows more efficient nubbing. The simplest, and probably most general, approach that isn't absolutely wretched is to use an Ord constraint:
import qualified Data.Set as S
nubOrd :: Ord a => [a] -> [a]
nubOrd = go S.empty where
go _seen [] = []
go seen (a : as)
| a `S.member` seen = go seen as
| otherwise = go (S.insert a seen) as
length is wasteful
Suppose I write
sameLength :: [a] -> [b] -> Bool
sameLength xs ys = length xs == length ys
(which uses the approach you did). Now imagine I calculate
sameLength [1..16] [1..2^100]
How long will that take? Calculating length [1..16] will take nanoseconds. Calculating length [1..2^100] will probably take billions of years using current hardware. Whoops. What's the right way? Pattern match!
sameLength [] [] = True
sameLength (_ : xs) (_ : ys) = sameLength xs ys
sameLength _ _ = False
Nubbing isn't the right solution to this problem
Suppose I ask noDuplicates (1 : [1,2..]). Obviously, there's a duplicate, right at the beginning. But if I use sameLength and nub to check, I will never get an answer. It will keep building the nubbed list and comparing it to the original list until the seen becomes so large it exhausts your computer's memory. How can you fix that? By directly calculating what you need:
noDuplicates = go S.empty where
go _seen [] = True
go seen (x : xs)
| x `S.member` seen = False
| otherwise = go (S.insert x seen) xs
Now the program will conclude that there's a duplicate the moment it sees the second 1.