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)
7
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)
You can not override existing functions. Haskell uses ad-hoc polymorphism for this.
What you can however do in the case of a list, is work with the OverloadedLists
extension [ghc-doc].
If you thus have a data type Foo
with:
data Foo a = MyEmpty | MyCons a (Foo a)
You can use:
import GHC.IsList (IsList)
instance IsList (Foo a) where
type Item (Foo a) = a
toList = foldr MyCons MyEmpty
fromList MyEmpty = []
fromList (MyCons x xs) = x : fromList xs
If you then compile with -XOverloadedLists
, you can use list literals in your code that are then of type Foo a
.
But this does not overload the (:)
function: if you use :
, it will still use the (:) :: a -> [a] -> [a]
one.
1