Reputation: 111
What I require is a data type that either contains an exact value or contains a list of possible candidates. (I will be using values of type Int).
What I would want is that if I perform an f: Int -> ...
function on a Cell
which has an exact value it is performed on the value and if I perform a function of the form f : [Int] -> ...
on a Cell
with candidates it performs the function on the array of candidates. Hence I define my data like this:
data Cell a = Exactly a | Candidates [a] deriving (Eq, Read, Show)
instance Functor Cell where
fmap f (Exactly x) = Exactly (f x)
fmap f (Candidates (x:xs)) = Candidates ( f (x:xs))
This does not compile and gives me an error of the form
Occurs check: cannot construct the infinite type: b ~ [b] ...
If I edit my code to
fmap f (Candidates (x:xs)) = Candidates ( map f (x:xs))
this does compile but then does not serve my function well as sometimes I would have to work on the whole array rather than the members element-wise.
Thanks for help.
Upvotes: 0
Views: 283
Reputation: 27217
Your problem is with this line
fmap f (Candidates (x:xs)) = Candidates ( f (x:xs))
the function f
works only on single values and you are trying to apply it to a list. What you need to do is apply f to each element in the list.
Try:
fmap f (Candidates xs) = Candidates ( fmap f xs)
This will apply f to each member of xs.
As an aside, have you read this article (or similar) about the list monad?
Upvotes: 4