Dilawar
Dilawar

Reputation: 5645

Creating infinite list out of ADT

In Haskell,

 > a = [1,1..]

creates an infinite list. Now I have the following

data Subunit = O | P deriving (Eq, Show)           

And if I do

b :: [Subunit]                                                                   
b = take 6 [P,P..]  

I get the following:

 parse error on input ‘]’

Why this is failing? What I need to add to be able to create an infinite list?

Upvotes: 6

Views: 188

Answers (5)

Reid Barton
Reid Barton

Reputation: 15029

As yet another alternative, to do what it looks like you want to do directly, use

b :: [Subunit]
b = replicate 6 P

Upvotes: 1

behzad.nouri
behzad.nouri

Reputation: 78021

[n,n'..] is syntax sugar for enumFromThen so you need your type be an instance of Enum type class.

You also need a value, not a value constructor:

\> data Subunit = O | P deriving (Eq, Show, Enum)
\> let a = P
\> take 6 [a,a..]
[P,P,P,P,P,P]

or (per @sepp2k comment):

\> take 6 [P,P ..]
   --         ^ space
[P,P,P,P,P,P]

Upvotes: 3

chi
chi

Reputation: 116174

Nice catch! Indeed it errors out ...

> take 10 [P, P..]

<interactive>:6:16: parse error on input ‘]’

... but this does not

> take 10 [P, P ..]   -- one more space
[P,P,P,P,P,P,P,P,P,P]

Why the whitespace is significant? Because otherwise the syntax overlaps with module-prefixed names, which have the form Module.name. Here's how the operator . from Prelude is accessed, for instance.

> :t (Prelude..)
(Prelude..) :: (b -> c) -> (a -> b) -> a -> c
> :t succ Prelude.. succ   -- infix use!
succ Prelude.. succ :: Enum c => c -> c

Hence, P.. is . from module P, while P .. works fine in a list enumeration.

(Yes, this is an unfortunate quirk of the syntax ...)

Upvotes: 11

Random Dev
Random Dev

Reputation: 52300

as an alternative to behzads answer you can do

b :: [Subunit]
b = take 6 $ repeat P

too - this one does not need the Enum

Upvotes: 3

HKTonyLee
HKTonyLee

Reputation: 3310

You may use this line to generate infinite list of ADT.

infiniteSubunit = P:infiniteSubunit

Then you can use it as is.

b :: [Subunit]                                                                   
b = take 6 infiniteSubunit

Upvotes: 1

Related Questions