0
votes

Hello I wrote my first program with type family

{-# LANGUAGE TypeFamilies #-}

data Colist a = Colist (Maybe (a,Colist a))

class Listable l where type Item l :: *
    toList :: l -> [Item l]

instance Listable (Colist a) where 
    type Item (Colist a) = (Colist a)
    toList x = [x]

The program should take Colist a and take it into a list I get the error that 'Item l' couldn't be matched with actual type 'l'. But I wrote that the Item x EQUALS (Colist a). Where is my mistake?

1
I think you meant type Item (Colist a) = a. And you probably meant toList to be a method of Listable?Benjamin Hodgson
You need to include the code that causes the error if you want a good explanation. This code loads just fine (after fixing indentation errors). That said: it is because, like all type family first-timers, you have not yet understood what "type families are not injective" means.Daniel Wagner
imgur.com/a/bIjXI I get this errorAnonnnn
Don't post images of text on SO -- copy & paste the actual error text message inside your question, so that everyone will notice that and read it immediately. Hiding important information under a link to an image makes it less likely others will simply skip the question, providing no help.chi

1 Answers

2
votes

Did you mean...

{-# LANGUAGE TypeFamilies #-}

newtype List a = List (Maybe (a, List a))

class Listable l where
    type Item l :: *
    toList :: l -> [Item l]

instance Listable (List a) where
    type Item (List a) = a

    toList (List Nothing) = []
    toList (List (Just (x, xs)) = x : toList xs

I've changed a few things about your code. Zero, I renamed Colist to List (because there's no such thing as a coinductive list in Haskell). One, I fixed the indentation, making toList a method of the Listable class. Two, I made List a's instance of Item return a, not List a. Three, I fixed toList to actually return a list of the elements of the List - your version just put the whole List in a singleton list.

I strongly suspect you're misusing type families here though. Here's a much simpler and more Haskell-ish formulation of this class:

class Listable l where
    toList :: l a -> [a]

instance Listable List where
    toList (List Nothing) = []
    toList (List (Just (x, xs)) = x : toList xs

Or you can just derive Foldable and get toList for free:

newtype List a = List (Maybe (a, List a)) deriving Foldable

ghci> import Data.Foldable
ghci> toList $ List (Just ('a', List Nothing))
"a"