Apply two functions to a list of tuples [closed] - haskell

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I have a list of tuples containing information in the following form as so:
carDatabase :: [Car]
carDatabase = [("Ford", "Focus", 2003, [("Autotrader", 9995), ("Parkers", 9495), ("Motors", 9995)]), ("Vauxhall", "Corsa", 2005, [("Autotrader", 5995), ("FOW", 7000), ("Gumtree", 6500)]), ...]
And what I am trying to do is map this list to return a list of strings with the first element of each tuple (I have a function that does this with carMan (x,_,_,_) = x) but also using the toLower function and I cannot work out a way to combine them, be it with function compositions or mapping a map etc.
This is the closest I've got.
mapTest :: [Car] -> [String]
mapTest cs = map toLower (map carMan cs)
Any help would be appreciated.
This is the error I get with:
mapTest :: [Car] -> [String]
mapTest cs = map (toLower . carMan) cs
Couldn't match type ‘Char’ with ‘[Char]’
Expected type: Char -> String
Actual type: Char -> Char
In the first argument of ‘(.)’, namely ‘toLower’
In the first argument of ‘map’, namely ‘(toLower . carMan)’
cars.hs:197:37:
Couldn't match type ‘[Char]’ with ‘Char’
Expected type: [(Char, String, Int, [(String, Int)])]
Actual type: [Car]
In the second argument of ‘map’, namely ‘cs’
In the expression: map (toLower . carMan) cs

You can do this with function composition using .
map ((map toLower) . carMan) cs
Or make it a helper function:
strLower :: String -> String
strLower = map toLower
mapTest :: [Car] -> [String]
mapTest = map (strLower . carMan)

Related

read::Int not working in Haskell in example

Here is the problem. It looks simple yet
main = do
s <- getContents
let list = map (read::Int) (words s)
print list
Couldn't match expected type `Int' with actual type `String -> a0'
Probable cause: `read' is applied to too few arguments
In the first argument of `map', namely `(read :: Int)'
In the expression: map (read :: Int) (words s)
The problem was that I thought :: is like casting and I have to put the return type. The solution was to add full wanted |function signature instread.
read is a function (of type Read a => String -> a), so it can't have type Int. You could do read :: String -> Int, or you could put a type signature on list rather than read, so you get:
let list :: [Int]
list = map read (words s)

haskell: change lowercases to capitals in a list of strings [duplicate]

This question already has answers here:
Haskell - Capitalize all letters in a list [String] with toUpper
(3 answers)
Closed 7 years ago.
My problem is, I would like to change every lowercase letter of the list ["hello","wHatS", "up?"] into capitals.
map toUpper [x] does not work realy...
it should return ["HELLO", "WHATS", "UP?"]..
Take a look at type of toUpper, it's Char -> Char, but you have [[Char]]. It means that you have two layers of list functor here, so you should map it twice.
For pedagogical reasons we may use map here, like this:
map (map toUpper) yourList
Parenthesis are important here, we give one argument to map :: (a -> b) -> [a] -> [b] and get another function of type [Char] -> [Char] (just what we need!) because of curring.
Once you learn about functors, you may prefer fmap and <$> for this task:
(toUpper <$>) <$> yourList

Create concatenate function in Haskell: [String] -> String

I'm having a lot of trouble getting this function to work:
concatenate :: [String] -> String
It is designed to simply take a list of strings and return a single string that is the result of the concatenations of each element of the list from head to tail. I'm trying to stay within the map, foldl, and foldr functions. I feel like I know what the concept of these functions do well enough, but the most common problem I'm running into is that I'm having a conflict of types. GHC will expect a [Char] for example, and I'll put in code that is apparently trying to use a [[Char]] without me knowing it.
For example: concatenate (x:xs) = foldr (++) x (concatenate xs)
And I get the following compile error:
Couldn't match type `Char' with `[Char]'
Expected type: [[Char]]
Actual type: String
In the return type of a call of `concatenate'
In the third argument of `foldr', namely `(concatenate xs)'
In the expression: foldr (++) x (concatenate xs)
I'm very new to Haskell, so please feel free to laugh. Harshness is expected, and welcomed, as long as an explanation fit for a newbie is also included. Thank you for any and all help.
You actually don't need the recursive call there. The function foldr already simulates a recursive call. All you need to do is use:
concatenate :: [String] -> String
concatenate ls = foldr (++) "" ls
And remember that there's a concat function already, which is more generic, as it works on any list of list (as opposed to simply list of strings).

Using the haskell map function with a string

I'm trying to use the map function in haskell
I've got this:
lexi :: String -> [[String]]
lexi x = map (words.lines) x
I want to be able to put a string in to x, so it can be run like this
lexi ("string here")
But get the error
Couldn't match type ‘[Char]’ with ‘Char’
Expected type: String -> String
Actual type: String -> [String]
In the second argument of ‘(.)’, namely ‘lines’
In the first argument of ‘map’, namely ‘(words . lines)’
Couldn't match type ‘Char’ with ‘[Char]’
Expected type: [String]
Actual type: String
In the second argument of ‘map’, namely ‘x’
In the expression: map (words . lines) x
I know that if I use
lexi = map (words.lines)
it works fine when I run lexi ("string here"), but need the variable to use later on
Could some please explain why this doesn't work and how to fix it?
Thank you :)
This answer refers to an old version of the question.
So let's get this quite clear (please always add the type signature of all functions you're talking about!)
function :: Char -> [String]
Well, then the type of map function is [Char] -> [[String]], i.e. String -> [[String]]. But you want the result to be only [String], not a triply-nested list. You probably want to join the lists of two levels together; in general the function to use for list-joining purposes is concat (or more generally, join from the Control.Monad module). In this case, you have two different options:
Join the result of each call to function. I.e., instead of mapping function alone, you map join . function, which has type Char -> String. Mapping that has the desired type String -> [String].
lexi = map $ join . function
Join the final result of the mapping, i.e. lexi = join . map function. This combination of mapping and joining the results is actually an extremely common task, it has a special operator: monadic bind!
lexi x = x >>= function
New version
So we know that
words, lines :: String -> [String]
thus words . lines can not work, because you're trying to feed a list of strings into a function that only accepts a single string. What you can of course do though is map words over the result, i.e. map words . lines. That has in fact the correct signature and probably does just what you want.

Can't compile because of types when using nub, map and take

I've got this simple function:
bombplaces::Int->[(Int,Int)]->[(Int,Int)]
bombplaces bombCount listOfPossiblePoints = nub (map (take bombCount) (perms listOfPossiblePoints))
bombs are (x,y) (carthesian points)
i need to get an all permutations and take only first few (bombCount) points.
I'm getting following error:
Couldn't match expected type `(Int,Int)' with actual type `[a0]'
Expected type: [a0] -> (Int,Int)
Actual type: [a0] -> [a0]
In the return type of a call of `take'
In the first argument of `map', namely `(take liczbaBomb)'
If you remove the type signature and ask GHCi for the type, your problem will be obvious:
> :t bombplaces
bombplaces :: Eq a => Int -> [a] -> [[a]]
That is, bombplaces wants to return a list of lists whereas you want it to return a plain list. You need to either change the type signature, or change the definition of the function, depending on what you want the behaviour to be.
N.B. You didn't tell us what definition of perms you are using, so I assumed the obvious one.

Resources