Reputation: 67
I have a question that I think is rather tricky.
The standard prelude contains the function
replicate :: Int -> a -> [a]
The following might seem like a reasonable definition for it
replicate n x = take n [x,x,..]
But it is actually not sufficient. Why not?
I know that the replicate
function is defined as:
replicate :: Int -> a -> [a]
replicate n x = take n (repeat x)
And repeat
is defined as:
repeat :: a -> [a]
repeat x = xs where xs = x:xs
Is the definition insufficient (from the question) because it uses an infinite list?
Upvotes: 3
Views: 153
Reputation: 477210
First of all there is a small syntax error in the question, it should be:
replicate n x = take n [x,x..]
-- ^ no comma
but let's not be picky.
Now when you use range syntax (i.e. x..
), then x
should be of a type that is an instance of Enum
. Indeed:
Prelude> :t \n x -> take n [x,x..]
\n x -> take n [x,x..] :: Enum a => Int -> a -> [a]
You can argue that x,x..
will only generate x
, but the Haskell compiler does not know that at compile time.
So the type in replicate
(in the question) is too specific: it implies a type constraint - Enum a
- that is actually not necessary.
Your own definition on the other hand is perfectly fine. Haskell has no problem with infinite lists since it uses lazy evaluation. Furthermore because you define xs
with xs
as tail, you actually constructed a circular linked list which also is better in terms of memory usage.
Upvotes: 6