Leave a comment

Comments 5

thesz October 18 2013, 12:12:24 UTC
Скорее всего ошибка компилятора.

Reply


besm6 October 18 2013, 13:21:54 UTC
Я, кажется, сталкивался с подобным. Я так понимаю, он выводит тип, анализируя не вообще всё, а как только сможет сделать вывод о типе. Иногда он из-за этого ставит конкретный тип вместо класса. Из первого выражения для deduceTypes он делает правильный вывод о типе deduceTypes, а из второго - о конкретном типе входящей туда переменной op (из BoolOp следует, что это CmpPredicate), и как следствие - о типе deduceOperationTypes, более узком, чем следует из ее определения. Ну и, анализируя третье, выдает конфликт типов, поскольку тип для deduceOperationTypes он уже вывел. А расширять уже выведенный тип посредством поиска, что общего между CmpPredicate и BinaryOperation, хаскель не обучен.

Так, по логике, если он будет пытаться следить за самым широким вариантом, то он может правильно вывести тип первого аргумента для deduceOperationTypes (он следует из применения resultType), но не сможет грамотно ограничить второй и третий. Или сможет, но за невменяемое время.

Reply

lispnik October 25 2013, 03:06:10 UTC
Да, похоже, так и есть.

Reply


lomeo October 18 2013, 14:53:01 UTC
Это polymorphic recursion косячит. Вывод типов таких функций завершается при первом удобном случае (потому что иначе вывод может не завершиться), а дальше уже в игру вступает type checker.

Простой пример:

> let { f Nothing = f (Just "String"); f (Just x) = f (Just True) }

ломается, хотя

> let { f :: Maybe t -> Bool; f Nothing = f (Just "String"); f (Just x) = f (Just True) }

работает

Reply

lispnik October 25 2013, 03:05:40 UTC
Прошу прощения я запоздалый ответ. Да, видимо, дело в этом. Спасибо.

Reply


Leave a comment

Up