При попытке скомпилировать следующий код, который представляет собой расширенную версию сборки 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:
Переменная неоднозначного типа `a 'в ограничении:
` Typeable a'
возникающая в результате использования `typeOf 'в src / WavefrontSimple.hs: 54: 81- 103
Возможное исправление: добавьте сигнатуру типа, которая исправляет эти переменные типа `
Не понимаю почему. Что нужно исправить, чтобы получить то, что я имел в виду?
РЕДАКТИРОВАТЬ: Итак, решение использовать 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)