Я не уверен, что это возможно. У меня есть что-то вроде следующего класса:
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"]
Теперь я хочу иметь возможность определить экземпляр, в котором реализована реализация Foo f
для реализации Foo [f]
.
Что-то вроде этого:
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
Где экземпляр списка просто накапливает все левые, и если левых нет, он удаляет внешний список и перемещает его вправо (можно ли это написать проще?). Такой экземпляр не проверяет тип, поскольку тип не [f] a
, а [f a]
. Тип, который я ожидаю, это foo :: [f a] -> Either [String] [a]
Я попытался написать тип, который это делает для меня:
type ApplyList (f :: Type -> Type) (a :: Type) = [f a]
instance Foo f => Foo (ApplyList f) where
...
Но это не работает, потому что я предполагаю, что типы не поддерживают каррирование.
Есть ли способ написать это правильно?
Любая помощь приветствуется!
foo
, который вы ожидаете для своего экземпляра? Например. что-то вродеfoo :: Foo f => f [a] -> Either [String] a
? Или что? (Кроме того, я почти уверен, что вам не нужен[f]
, который является довольно продвинутой вещью в Haskell из-за DataKinds — и не является типом, например,[f] a
недоброжелателен.) - person chi   schedule 18.05.2020[f] a
плохо относится. Я ищу тип[f a]
. - person John Smith   schedule 18.05.2020foo :: [f a] -> Either [String] [a]
с вашим классом: ваш класс делает тип возвращаемого значенияEither [String] a
, который не зависит отf
, поэтому его нельзя изменить в экземплярах. Вам, вероятно, потребуются некоторые изменения в определении вашего класса, возможно, добавление в класс еще одного параметраa
, чтобы позже его можно было преобразовать в[a]
. Может быть, с каким-нибудь фундэпом (или типом семьи?). - person chi   schedule 18.05.2020a
, но класс говорит, что вы можете вернуть не более одногоa
. Поэтому вам следует переосмыслить, какую абстракцию представляет этот класс типов. Одинa
или многоa
? Это зависит отf
? - person Li-yao Xia   schedule 18.05.2020