Search code examples
haskellscopeghci

Output all instances from 1 to 8 where the length of the spelling of a number is greater than the length of the spelling of a value higher than it?


I'm a complete Haskell noob and I've been trying to do this for an entire day now.

So one output could be:

Three,Six

(3 is less than 6 but the spelling of it is longer than the spelling of 6)

I came up with this in Haskell but the variables go out of scope, I don't really understand scope in Haskell yet. This might be completely wrong but any help is appreciated.

let numbers = [("One",1),("Two",2),("Three",3),("Four",4),("Five",5),("Six",6),("Seven",7),("Eight",8)]

[([ x | x <- numbers], [y | y <- numbers]) | length (fst x) > length (fst y), snd x < snd y]

Can someone help me to correct this nested list comprehension? Or even tell me if I can use a nested list comprehension at all?

To clarify:

I want to output a list of pairs, where the spelling of the first element in the pair is longer than the spelling of the second element in the pair, but also, the first element in the pair as a number, is less than the second element in the pair as a number.


Solution

  • It sounds like you want something like this:

    [(y1, y2) | (x1, y1) <- numbers, (x2, y2) <- numbers, length x1 > length x2, y1 < y2]
    

    That is, it's a list of pairs of numbers - with the requirements you specify. I'm not able to test this at a moment, I think it should work but let me know if you have any issues with it.

    Your scope issues were because you were trying to do nested comprehensions and access variables from the inner comprehension in the outer one - this is not allowed, because a variable used inside a comprehension is only in scope in that particular comprehension.

    I have also replaced your uses of fst and snd by explicit pattern-matching on the elements of the pair, which is almost always preferred because it's more explicit.