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

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

Related

Apply a function to every element in a list to every element in another list

I'd like a more elegant way to write the following two functions, ideally in one :
applyOperatorBetweenVariableLists:: [Variable] -> String -> [Variable] -> [Variable]
applyOperatorBetweenVariableLists firstList operator secondList = concat $ map (test firstList operator) secondList
test:: [Variable] -> String -> Variable -> [Variable]
test firstVariables operator secondVariable = concat $ map (applyOperatorBetweenVariables secondVariable operator) firstVariables
The declaration of applyOperatorBetweenVariables is :
applyOperatorBetweenVariables:: Variable -> String -> Variable -> [Variable]
I'm quite sure there must be a Prelude Function that does exactly this, or a very elegant way to write it.
This can be done concisely with a do block:
applyOperatorBetweenVariableLists firstList operator secondList = do
secondVariable <- secondList
firstVariable <- firstList
applyOperatorBetweenVariables secondVariable operator firstVariable
If you wanted to be even more concise, you could reorder the arguments to both applyOperatorBetweenVariableLists and applyOperatorBetweenVariables, and then use either liftJoin2 or bind2 to implement it (like my final sentence below but with it in place of liftA2).
My original answer was wrong, as it left a layer of nesting (i.e., should have done an extra concat or join):
That's almost just liftA2, but your arguments are in a weird order. Here's how you'd implement what you wrote in terms of that:
import Control.Applicative (liftA2)
applyOperatorBetweenVariableLists firstList operator secondList = liftA2 (flip applyOperatorBetweenVariables operator) secondList firstList
From that definition, it should be clear how you could change and simplify that to applyOperatorBetweenVariableLists = liftA2 . applyOperatorBetweenVariables just by reordering the arguments to it and to applyOperatorBetweenVariables.

Functional Programming-Style Map Function that adds elements?

I know and love my filter, map and reduce, which happen to be part of more and more languages that are not really purely functional.
I found myself needing a similar function though: something like map, but instead of one to one it would be one to many.
I.e. one element of the original list might be mapped to multiple elements in the target list.
Is there already something like this out there or do I have to roll my own?
This is exactly what >>= specialized to lists does.
> [1..6] >>= \x -> take (x `mod` 3) [1..]
[1,1,2,1,1,2]
It's concatenating together the results of
> map (\x -> take (x `mod` 3) [1..]) [1..6]
[[1],[1,2],[],[1],[1,2],[]]
You do not have to roll your own. There are many relevant functions here, but I'll highlight three.
First of all, there is the concat function, which already comes in the Prelude (the standard library that's loaded by default). What this function does, when applied to a list of lists, is return the list that contains concatenated contents of the sublists.
EXERCISE: Write your own version of concat :: [[a]] -> [a].
So using concat together with map, you could write this function:
concatMap :: (a -> [b]) -> [a] -> [b]
concatMap f = concat . map f
...except that you don't actually need to write it, because it's such a common pattern that the Prelude already has it (at a more general type than what I show here—the library version takes any Foldable, not just lists).
Finally, there is also the Monad instance for list, which can be defined this way:
instance Monad [] where
return a = [a]
as >>= f = concatMap f as
So the >>= operator (the centerpiece of the Monad class), when working with lists, is exactly the same thing as concatMap.
EXERCISE: Skim through the documentation of the Data.List module. Figure out how to import the module into your code and play around with some of the functions.

Beginner: Converting Types in Haskell

First post here, please go easy on me. Found several threads with similar issues, none of those applied directly or if one did, the execution was far enough over my head.
If i have code p=['1','2','3','4'] that stores digits as characters in p, how do i create a list q that can equal [1,2,3,4]?
I've been trying all sorts of things, mostly arriving at my q being out of scope or any function i try to convert Char -> Int lacking accompanying binding.
I seem to find indication everywhere that there is such a thing as digitToInt, where digitToInt '1' should yield an output of 1 but i apparently lack bindings, even with the exact input from this page:
http://zvon.org/other/haskell/Outputchar/digitToInt_f.html
At this point reading more things i am just becoming more confused. Please help with either a viable solution that might show me where i'm messing up or with an explanation why this digitToInt :: Char -> Int seems to not work for me in the slightest.
Thank you.
digitToInt is something that already exists. It used to live in the Char module but now it lives in Data.Char, so we have to import Data.Char to use it.
Prelude> import Data.Char
Prelude Data.Char> digitToInt '1'
1
You can use digitToInt on every element of a list with map digitToInt. map :: (a->b) -> [a] -> [b] applies a function (a->b) to each element of a list of as, [a] to get a list of bs, [b].
Prelude Data.Char> map digitToInt ['1', '2', '3', '4']
[1,2,3,4]
Lacks an accompanying binding
You don't need to define digitToInt or other imports by writing it's type signature digitToInt :: Char -> Int. A signature written without a binding like that
alwaysSeven :: Char -> Int
will give the following error.
The type signature for `alwaysSeven' lacks an accompanying binding
You only provide a type signature when it comes right before a declaration.
alwaysSeven :: Char -> Int
alwaysSeven x = 7
Without importing anything you can also use a very simply trick, and push ((:[])) the character in an empty list (making a singleton list) before reading the value:
map (read . (:[])) "1234"
This will need the context of the type of the list to be deducible, but it will work for any type you want without modifications. Otherwise you'll need to specify the type yourself:
(map (read . (:[])) "1234") :: [Int]
-- [1,2,3,4]
(map (read . (:[])) "1234") :: [Double]
-- [1.0,2.0,3.0,4.0]

Inverse of 'concat': transforming a flattened list into a nested list [duplicate]

This question already has answers here:
Haskell: Is there an idiomatic way to insert every item in a list into its own list?
(6 answers)
Closed 5 years ago.
Given a flattened list in Haskell:
['a', 'b','c','d']
how can I change it to:
[['a'], ['b'], ['c'], ['d']]
One way to describe what you want to do is to take each element in your list and wrap it, individually, with another list. Or, you'd like to perform the operation 'a' ---> ['a'] to each element of the list.
Whenever you're speaking about turning "each element of the list, individually, into something else" you're talking about a map [0] and so we'll write this function a bit like
example :: [Char] -> [[Char]]
example cs = map _ cs
Where the _ is the function 'a' ---> ['a']. This function can be written as an explicit anonymous function, though
example :: [Char] -> [[Char]]
example cs = map (\c -> [c]) cs
And this will achieve what we need!
But we can go a little further. First, in Haskell you're allowed to drop the last argument applied if it's the same as the last input argument. Or, more concretely, we can also write example as
example :: [Char] -> [[Char]]
example = map (\c -> [c])
by simply deleting the cs in both the argument list and as an argument to map. Second, we can take note that example's type is weaker than it could be. A better way of writing it is certainly
example :: [a] -> [[a]]
example = map (\c -> [c])
which reflects the fact that we didn't use anything specific to Char on the inside.
[0] Or, more generally, an fmap
You can do:
singleton x = [x]
f = map singleton
Well, Ting already answered, but I feel compelled to introduce you to the monkey operator (:[])
You can use this in place of singleton.
map (:[]) ['a', 'b', 'c', 'd']

Difference between composition and function application [duplicate]

This question already has answers here:
What is the difference between . (dot) and $ (dollar sign)?
(13 answers)
Closed 8 years ago.
The first problem in 99 Haskell Problems is to "find the last element of a list". I came up with two solutions:
Solution 1 (This works)
myLast :: [a] -> a
myLast = head . reverse
Solution 2 (This doesn't work)
myLast :: [a] -> a
myLast = head $ reverse
Question
Why does solution 1 work but not solution 2? What I'm most confused by is how neither implementations supply pattern matching.
head is a function of one argument1. If you use f $ x to apply a function to something, it's the same as simply writing f x (or if you like f(x), or (f)x, all the same thing... just uglier): the argument is "filled in" by the specified variable. So the result of head $ reverse will simply be whatever result head gives you when fed with an argument of reverse's type... ...which however doesn't work, because head needs a list but reverse is a function. $ itself doesn't care about this but just hands on the parameter, for instance you could write
Prelude> :t map $ reverse
map $ reverse :: [[a]] -> [[a]]
because the first argument of map is in fact a function.
With (.) it's different. That cares about what type the argument to its right has (must also be a function), and it doesn't simply feed it to the left function right away. Rather, f . g yields another function, which does the following: it waits for some argument x, which it feeds to g, and then feeds the result of that to f.
Now, if you write
myLast' = head . reverse
it means just, you define myLast as this function that (.) gives you as the composition of head and reverse. That there are no arguments mentioned for myLast here doesn't matter: [a] -> a is just some type so you can define variables with this type (like myLast), by assigning them to values that happen to have such a function type (like head . reverse). You could, if you wanted, make the parameter explicit:
myLast'' x = (head . reverse) x
Note that the parens are needed because otherwise it's parsed as head . (reverse x) – which wouldn't work, because reverse x is not a function anymore, just a result list. And therefore you couldn't compose it with head; what you could however do is apply head to it:
myLast''' x = head $ reverse x
1In fact, every function in Haskell has just one argument... but we say "two-argument function" for things like (+) :: Int -> Int -> Int, though really this is a one-argument function returning a one-argument function returning an Int: (+) :: Int -> (Int -> Int).
Roughly, application ($) is used between a function and its argument (a list in this case), while composition (.) is used between two functions.
About pattern matching: in the first solution, the function reverse will perform the needed pattern match for you, so myLast does not have to.

Resources