Не удалось сопоставить ожидаемый тип с предполагаемым типом, ошибка переменной жесткого типа
Что не так с этой функцией?
test :: Show s => s
test = "asdasd"
String является экземпляром класса Show
, поэтому кажется правильным.
Ошибка
src\Main.hs:224:7:
Couldn't match expected type 's' against inferred type '[Char]'
's' is a rigid type variable bound by
the type signature for 'test' at src\Main.hs:223:13
In the expression: "asdasd"
In the definition of 'test': test = "asdasd"
Ответы
Ответ 1
test :: Foo a => a
означает "для любого типа, который является экземпляром Foo
, test
является значением этого типа". Поэтому в любом месте, где вы можете использовать значение типа X
, где X
- это экземпляр Foo
, вы можете использовать значение типа Foo a => a
.
Что-то вроде test :: Num a => a; test = 42
работает, потому что 42 может быть значением типа Int
или Integer
или Float
или что-либо еще, что является экземпляром Num
.
Однако "asdasd"
не может быть Int
или что-либо еще, что является экземпляром Show
- он может быть только когда-либо String
. Как следствие, он не соответствует типу Show s => s
.
Ответ 2
Да, String
- это экземпляр Show
. Но это не позволяет использовать строку как значение abritary Show
. 1
может быть Num a => a
, потому что есть 1 :: Integer
, a 1 :: Double
, a 1 :: Word16
и т.д. Если "asdasd"
может быть типа Show a => a
, то будет "asdasd" :: Bool
, "asdasd" :: String
, "asdasd" :: Int
и т.д. Нет. Следовательно, "asdasd"
не может быть типа Show a => a
. Тип строковой константы не становится намного более общим, чем String
.