Подтвердить что ты не робот

Не удалось сопоставить ожидаемый тип с предполагаемым типом, ошибка переменной жесткого типа

Что не так с этой функцией?

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"
4b9b3361

Ответ 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.