I'm not sure this is possible. I have something like the following class:
data Bar a = Bar1 a | Bar2
class Foo f where
foo :: f a -> Either [String] a
instance Foo Bar where
foo (Bar1 x) = Right x
foo Bar2 = Left ["is Bar2"]
Now I want to be able to define an instance that given an implementation for Foo f
implement Foo [f]
.
So something like this:
data Bar a = Bar1 a | Bar2
class Foo f where
foo :: f a -> Either [String] a
instance Foo Bar where
foo (Bar1 x) = Right x
foo Bar2 = Left ["is Bar2"]
instance Foo f => Foo [f] where
foo as = foldr reducer (Right []) (foo <$> as)
where
reducer (Right n) (Right xs) = Right $ n:xs
reducer (Left xs) (Right _) = Left xs
reducer (Right _) (Left xs) = Left xs
reducer (Left xs) (Left ys) = Left $ xs ++ ys
Where the list instance just accumulates all lefts and if there no lefts it removes the outer list and moves it to the right (can this be written implemented easier?). The instance like this doesn't type check since the type isn't [f] a
but [f a]
. The type I expect is foo :: [f a] -> Either [String] [a]
I tried to write a type that this does for me:
type ApplyList (f :: Type -> Type) (a :: Type) = [f a]
instance Foo f => Foo (ApplyList f) where
...
But this doesn't work because I guess types do not support currying.
Is there a way to write this correctly?
Any help is appreciated!
foo
you expect for your instance? E.g. something likefoo :: Foo f => f [a] -> Either [String] a
? Or what? (Further, I'm pretty sure you don't want[f]
, which is a rather advanced thing in Haskell due to DataKinds -- and is not a type, e.g.[f] a
is ill-kinded.) – chi[f] a
is ill kinded. The type I'm looking for is[f a]
. – John Smithfoo :: [f a] -> Either [String] [a]
with your class: your class makes the return type to beEither [String] a
which does not depend onf
, so that can't be changed in the instances. You'll probably need some changes in your class definition, maybe adding another parametera
to the class, so that it can later be instantiated to[a]
. Maybe with some fundep (or type family?). – chia
, but the class says you can return only at most onea
. So you should rethink what abstraction this type class stands for. Onea
or manya
? Does that depend onf
? – Li-yao Xia