listhaskelloperator-overloadingtypeclasscons

How do I overload a certain operator in haskell to take different types on either side?


MRE:

class Foo s where
    myCons :: Char -> s -> s
    myCons c xs = <my definition of however I wish to interpret this>

instance (Eq, Show) Foo where
    (:) x y = x `myCons` y

Error:

Pattern bindings (except simple variables) not allowed in instance declaration:
      (:) x y = x `myCons` y

What am I doing wrong?

What I want to do:

fooFromList :: [Int] -> Foo
fooFromList [] = Foo []
fooFromList (x:xs) = let x' = (convertDigitToChar x) in x':(fooFromList xs)

Solution

  • I recommend simply extracting the Foo application outside of the recursion. (In fact... is a new type really needed, or have you just made it as a guess? What does Foo do that [Char] doesn't?)

    fooFromList :: [Int] -> Foo
    fooFromList xs = Foo (map convertDigitToChar xs)
    

    So if I am trying to make Foo an instance of Eq and Show, how would I do that?

    The compiler can write those instances for you, and it's rare to do something different than what the deriver does.

    data Foo = Foo [Char] deriving (Eq, Show)