Reputation: 572
I'm learning Haskell and I have tried to implement the replicate
function on my own and below is result of my work:
replicate' :: Enum a => a -> b -> [b]
replicate' a b = [b | _ <- [1..a]]
but during loading script into ghci I got msg:
proginhaskell.hs:152:29:
Could not deduce (Num a) arising from the literal `1'
from the context (Enum a)
bound by the type signature for
replicate' :: Enum a => a -> b -> [b]
at proginhaskell.hs:152:1-34
Possible fix:
add (Num a) to the context of
the type signature for replicate' :: Enum a => a -> b -> [b]
In the expression: 1
In the expression: [1 .. a]
In a stmt of a list comprehension: _ <- [1 .. a]
I would like to ask how to repair this problem. Is it correct way to implement replicate function ?
Upvotes: 2
Views: 3500
Reputation: 53901
The problem is that you're using the list expression [1..a]
that means that we have to be able to treat 1
as the same type as a
. The type of 1
is
1 :: Num a => a -- Numbers are actually polymorphic!
So GHC is complaining that you haven't said that a
is a Num
instance. So you can just add Num
to your constraints on a
.
replicate' :: (Enum a, Num a) => a -> b -> [b]
replicate' a b = [b | _ <- [1..a]]
As for how good this code is, I'd probably write it with take
, but both are fine implementations. If you're curious how it's actually implemented (though with a more restrictive replicate :: Int -> a -> [a]
)
replicate n x = take n (repeat x)
Upvotes: 5
Reputation: 1739
From this snippet of code [1..a]
the compiler inferes that a
should have the same of type as 1
. Since 1
is a Num
, it follows that a
should be of type Num
. So instead of Enum a
you should have (Enum a, Num a)
as your context.
Upvotes: 2