У меня есть несколько типов экземпляров.Давайте назовем их A, B и C. Все они являются экземплярами класса типов X. Теперь я хотел бы создать отдельную функцию create
, которая создает экземпляр A, B или C с учетом некоторого ввода (скажем, строки).Система типов не может знать, какой ввод будет давать какой тип.Это то, что Хаскеллу не нравится, и я думаю, что знаю ответ, но хочу быть уверенным.Текущая ошибка, которую я получаю:
• Couldn't match expected type ‘c’ with actual type ‘GCCCommand’
‘c’ is a rigid type variable bound by
the type signature for:
compiler :: forall c. CompilerCommand c => String -> c
at src/System/Command/Typed/CC.hs:29:1-44
• In the expression: gcc path
In an equation for ‘compiler’:
compiler path
| exe == "g++" || exe == "gcc" || exe == "cc" || exe == "cpp"
= gcc path
where
exe = takeFileName path
• Relevant bindings include
compiler :: String -> c
(bound at src/System/Command/Typed/CC.hs:31:1)
Означает ли это, как я подозреваю, что в данном конкретном случае невозможно перегрузить тип возвращаемого значения, потому что компилятор не может заранее знать, какданные будут выглядеть в памяти?Как бы вы пошли, чтобы реализовать эту функцию?Я думал о создании чего-то вроде следующего:
data SuperX = SuperA A | SuperB B | SuperC C
create :: String -> SuperX
-- create can now be implemented
instance X SuperX where
-- a lot of boilerplate code ...
Однако стандартный код подсказывает, что это можно сделать лучше.Это действительно лучший способ сделать это?