2

I need to use List Comprehension to generate a list like this one: ["AaBB", "AbBB", "AcBB", "AdBB", "AeBB", "AfBB","AgBB"]. But I've been running into some problems creating a expression to do it

I've tried to create a list which every element would be a string concatenation, something like this "A" + x + "BB" where x is a element from a range of letters starting with "a" and ending with "g"

module C where
    genList :: [String]
    genList = [ "A" ++ x ++ "BB" | x <- ["a" .. "g"]] 

So, I was expecting to generate a list similar to the one asked in the problem. But instead I just got this compiling error:

Prelude> :l exC
[1 of 1] Compiling C                ( exC.hs, interpreted )

exC.hs:3:41: error:
    • No instance for (Enum [Char])
        arising from the arithmetic sequence ‘"a" .. "g"’
    • In the expression: ["a" .. "g"]
      In a stmt of a list comprehension: x <- ["a" .. "g"]
      In the expression: ["A" ++ x ++ "BB" | x <- ["a" .. "g"]]
  |
3 |     genList = [ "A" ++ x ++ "BB" | x <- ["a" .. "g"]] 
  |                                         ^^^^^^^^^^^^
Failed, no modules loaded.

2 Answers 2

4

You can't use the .. syntax to build a list of strings. Luckily, you're using it for single-character strings here, so you can just use it to build a list of characters instead: [ "A" ++ x : "BB" | x <- ['a' .. 'g']]

Sign up to request clarification or add additional context in comments.

1 Comment

To expand on this (I had just started on my own answer, now redundant, but I believe this point may be helpful to the OP): as the error message says, the .. syntax is only defined for members of the Enum typeclass. Specifically it's syntactic sugar for the enumFromTo function. And there's a very good reason why Char is an instance of Enum while String isn't. What would you say the "next" string after say "hello" is?
0

Strings are not an instance of the Enum typeclass. Stricly speaking one could make it an instance, but that would likely not be beneficial much. Since that would yield "a", "a\NUL", "a\NUL\NUL", etc. if we yield these in lexicographical order.

You probably want to use a Character here, like @JosephSible wrote in his answer:

[ 'A': x : "BB" | x <- ['a' .. 'g']]

or we can make use of a functor map here:

('A':) . (:"BB") <$> ['a' .. 'g']

This gives us:

Prelude> ('A':) . (:"BB") <$> ['a' .. 'g']
["AaBB","AbBB","AcBB","AdBB","AeBB","AfBB","AgBB"]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.