[Haskell-cafe] list comprehension with multiple generator|targets

Mateusz Kowalczyk fuuzetsu at fuuzetsu.co.uk
Mon Nov 10 03:33:38 UTC 2014


On 11/10/2014 03:28 AM, Mateusz Kowalczyk wrote:
> On 11/10/2014 02:58 AM, Donn Cave wrote:
>> I'm guessing this isn't supported, but might be worth asking -
>> can I extend a list comprehension like  ['A' | A <- s] to multiple values?
>> Like,
>>
>> data V = A | B | C
>>
>> pv :: [V] -> [Char]
>> pv [] = []
>> pv (A:x) = 'A':(pv x)
>> pv (B:x) = 'B':(pv x)
>> pv (_:x) = pv x
>>
>> -- can that be a list comprehension, like
>>
>> pv s = [
>>           'A' | A <- s
>>           -- ??
>>           ]
>>
>> thanks,
>> 	Donn
> 
> You basically want map and filter. Moreover, you are also inlining a
> toChar function which complicates matters.
> 
> If you have ‘Eq V’ instance and ‘toChar’ function then you could write it as
> 
> [ toChar y | y <- [ x | x <- s, x /= C ] ]
>
> Where inner comprehension is just filter and outer is just map. It
> doesn't make much sense to do it this way and it imposes an extra
> constraint, Eq. Alternative (with LambdaCase):
> 
> map toChar $ filter (\case { C -> False; _ -> True }) s
> 
> But that's ugly and we still need toChar. Further, although not really
> applicable here, there might not be a reasonable toChar :: V -> Char for
> every constructor of V.

Oh, forgot to mention one thing. You could have a toChar :: V -> Maybe
Char and have a comprehension like

[ y | Just y <- [ toChar x | x <- s, x /= C ] ]

a.k.a.

mapMaybe toChar . filter (/= C)

and without Eq

mapMaybe toChar . filter (\case { C -> False; _ -> True })

but we still need to write toChar separately and the comprehension still
has Eq constraint. Of course we could inline the pattern match and so on
but in the end it's all just ugly. Stick to what you have.

> So in conclusion, the way you have now is pretty good: it avoids Eq
> constraint and it doesn't force us to write (possibly partial) toChar.
> 
> So to answer your question, no, you can't extend this very easily to
> multiple without effectively inlining your existing ‘pv’ function into
> the comprehension.
> 


-- 
Mateusz K.


More information about the Haskell-Cafe mailing list