При попытке скомпилировать следующий код, который представляет собой усовершенствованную версию read build на readMay из Safe package.Ошибка «переменная неоднородного типа» при определении пользовательской функции «чтение»
readI :: (Typeable a, Read a) => String -> a
readI str = case readMay str of
Just x -> x
Nothing -> error ("Prelude.read failed, expected type: " ++
(show (typeOf > (undefined :: a))) ++
"String was: " ++ str)
я получаю ошибку от GHC:
WavefrontSimple.hs: 54: 81:
Неопределенный тип переменной `а 'в ограничении:
` типируемых а'
, вытекающие из использование `typeOf 'в src/WavefrontSimple.hs: 54: 81-103
Вероятное исправление: добавьте сигнатуру типа, которая исправляет эти переменные типа`
Я не понимаю, почему. Что нужно исправить, чтобы понять, что я имел в виду?
EDIT: Ok, поэтому решение использовать ScopedTypeVariables
и forall a
в типе подписи работ. Но почему следующее приводит к очень похожей ошибке с той, что была выше? Компилятор должен вывести правильный тип, поскольку используется asTypeOf :: a -> a -> a
.
readI :: (Typeable a, Read a) => String -> a
readI str = let xx = undefined in
case readMay str of
Just x -> x `asTypeOf` xx
Nothing -> error ("Prelude.read failed, expected type: "
++ (show (typeOf xx)) ++
"String was: " ++ str)
Я проголосовал за закрытие, как обман перед редактированием. Теперь, когда вопрос был обновлен, я считаю, что он больше не является дубликатом, но не может удалить VTC. Думаю, мне просто придется ждать, пока он истечет сам по себе. – ephemient