Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Haskell fmap over custom data type

In my project I have a few data types that look like this

data StructureA = StructureA [Int] Bool Int
data StructureB = StructureB [String] String

My goal is to map functions over arrays contained inside instances of such datatypes

inst = StructureA [1,1,1] True 0
fmap (+1) inst -- [2,2,2]

My initial solution solution looks like this

instance Functor StructureA where
    fmap (StructureA arr _ _) = fmap arr

However, I get kind mismatch error.

Question is how I can declare a function that can be polymorphically applied over such data structures?

like image 710
user8856277 Avatar asked Sep 12 '25 18:09

user8856277


1 Answers

You can only declare a Functor instance over a parameterized type (* -> * to be precise): a type that still needs an extra (and exactly one) type parameter.

So first we will need to introduce a type parameter. Even if you never plan to use something else than Ints, we can easily abstract that away with:

data Structure a = Structure [a] Bool Int

We can for example declare the StructureA as a type synomym:

type StructureA = Structure Int

Now we can make it a Functor instance, by writing:

instance Functor Structure where
    fmap f (Structure as b c) = ...

Note that we here did not write (Structure a), but Structure, since - like we already said - fmap has the freedom to change the type over which the collection works: the f function can have for example type Int -> Char to convert a Structure Int to a Structure Char.

Now we still need to implement fmap. fmap has type fmap :: Functor f => (a -> b) -> f a -> f b so that means it takes a function, and in this case a Structure a, and constructs a Structure b. Based on your question (and the design decisions we have made), the only part we can map is the first parameter, so we construct a new Structure, where the second parameter is the result of an fmap f, but then over the second parameter, so:

instance Functor Structure where
    fmap f (Structure as b c) = Structure (fmap f as) b c
like image 98
Willem Van Onsem Avatar answered Sep 15 '25 07:09

Willem Van Onsem