Царапая на поверхности системы типа Haskell, запустил это:
Prelude> e = []
Prelude> ec = tail "a"
Prelude> en = tail [1]
Prelude> :t e
e :: [a]
Prelude> :t ec
ec :: [Char]
Prelude> :t en
en :: Num a => [a]
Prelude> en == e
True
Prelude> ec == e
True
Каким-то образом, несмотря на то, что en и ec имеют разные типы, они оба проверяют True на == e. Я говорю "как-то" не потому, что я удивлен (я не удивлен), а потому, что я не знаю, как называется правило/механизм, который позволяет это. Это как если бы переменная типа "a" в выражении "[] == en" могла принимать значение "Num" для оценки. И, аналогично, при тестировании с "[] == ec" разрешается стать "Char".
Причина, по которой я не уверен, что моя интерпретация верна, заключается в следующем:
Prelude> (en == e) && (ec == e)
True
потому что интуитивно это подразумевает, что в одном и том же выражении e принимает оба значения Num и Char "одновременно" (по крайней мере, так, как я использую для интерпретации семантики &&). Разве "допущение" Чар действует только во время оценки (ec == e) и (en == e) оценивается независимо, в отдельном... сокращении? (Я предполагаю терминологию здесь).
И тогда приходит это:
Prelude> en == es
<interactive>:80:1: error:
• No instance for (Num Char) arising from a use of ‘en
• In the first argument of ‘(==), namely ‘en
In the expression: en == es
In an equation for ‘it: it = en == es
Prelude> es == en
<interactive>:81:7: error:
• No instance for (Num Char) arising from a use of ‘en
• In the second argument of ‘(==), namely ‘en
In the expression: es == en
In an equation for ‘it: it = es == en
Не удивляет исключение, но удивляет, что в обоих тестах сообщение об ошибке жалуется на "использование" en "" - и не имеет значения, является ли он первым или вторым операндом.
Возможно, необходимо извлечь важный урок о системе типов Хаскелла. Спасибо за ваше время!