Есть класс типов, объявленный следующим образом:
newtype Fix f = Fix { unFix :: f (Fix f) }
class Functor f => Fixable t f where
toFix :: t -> Fix f
fromFix :: Fix f -> t
Следующие типы данных являются его экземплярами:
-- Сам тип Fix
instance Functor f => Fixable (Fix f) f where
toFix = id
fromFix = id
-- И список
data ListF a b = Nil | Cons a b deriving (Eq, Functor)
instance Fixable [a] (ListF a) where
toFix = apo go
where go (x:xs) = Cons x (Right xs)
go _ = Nil
fromFix = cata go
where go (Cons x xs) = x:xs
go _ = []
В данном куске кода возникает ошибка:
main :: IO ()
main = putStrLn $ someFunc [\a b -> a ++ b, \a b -> a ++ b ++ a] "str1" "str2"
where someFunc cs = para go cs
Из контекста понятно, что cs - список функций типа:
String -> String -> String
Но компилятор выводит слишком общий тип, а именно:
someFunc :: Fixable t (ListF (String -> String -> String)) -> (String -> String -> String)
В связи с чем возникает ошибка типизации, и компилятор требует использование расширения FlexibleContexts. Если же указать тип функции явно:
someFunc :: [String -> String -> String] -> (String -> String -> String)
код компилируется без ошибок. Как сделать так, чтобы компилятор сам выводил нужный тип?