Abhijeet Melkani
Abhijeet Melkani

Reputation: 111

Creating an algebraic data type in Haskell which has either an Int or an array of them

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

Answers (1)

John F. Miller
John F. Miller

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

Related Questions