2
votes

i come across a problem with haskell about recursive Functor instance.

data List x = Hol | Hoofd x (List x)
            deriving (Show,Eq,Ord)
instance Functor List where 
        fmap f (Hoofd x (Hoofd x)) = Hoofd (f x) Hoofd(f x)
        fmap f Hol               = Hol     
        fmap f Hoofd x (Hol)     = Hoofd (f x)  

I made a datatype List in which i need to inplement the Functor Fmap instance, i tried to use in the datatype deriving (Functor) but i gives me back an error with: can't derive Functor must use DeriveFunctor which i also did not understand...

please help

2
What's the exact error?Carcigenicate
Your implementation is close to correct. It uses an unnecessary case but that's probably fine; But it has wrong parentheses placement and some missing function parameters.Cubic
Do you understand the Functor instance for the regular list? Your type is isomorphic to it, so fmap is really just map adapted to your constructor names.chepner

2 Answers

2
votes

There are two ways you can make a class-instance for some type: either

  • Use a deriving clause. This only works for simple classes where there's one obvious way to define the instance's methods. In Haskell98, these classes were only Eq, Ord, Enum, Bounded, Show, and Read. By now, the language has evolved a lot and GHC can now derive many more classes, but it always requires switching on a language extension. In particular, to derive Functor, you need to put

    {-# LANGUAGE DerivingFunctor #-}
    

    at the top of your source file, or alternatively call the compiler/intepreter with

    $ ghc -XDeriveFunctor
    

    (I wouldn't recommend the latter; your file wouln't be “self-sufficient” if you do that.)

    With that extension enabled, you can simply write

    data List x = Hol | Hoofd x (List x)
            deriving (Show, Eq, Ord, Functor)
    
  • Write the instance yourself. That's what you've done in your code snippet, which has nothing to do with deriving. Your implementation is faulty, which is something you might well ask a question about, but then you should include the information what's currently going wrong.

0
votes

EDIT

found the problem my datatype is recursive but mine Functor instance was not.

data List x = Hol | Hoofd x (List x)
            deriving (Show,Eq,Ord)


instance Functor List where
            fmap f Hol = Hol
            fmap f (Hoofd x rest) = Hoofd (f x) (fmap f rest)

Now it works, if there is another element which needs to be processed it will be send back to the instance until there is noting to process