oczor icon indicating copy to clipboard operation
oczor copied to clipboard

Test case for recursive instantiation

Open nponeccop opened this issue 8 years ago • 7 comments

Непонятно, зачем рекурсия в функции:

renameVarsInExpr :: Expr -> Infer Expr
renameVarsInExpr x = flip cataM x $ \case
      ExprTypeF tp -> ExprType <$> renameVars vars tp
      x -> return $ embed x
    where
    vars = flip cata x $ \case
        ExprTypeF tp -> setToList $ ftv tp
        x -> ffold x

https://github.com/ptol/oczor/blob/1b3624970ed129daf961f9fd15315c498926396b/src/Oczor/Infer/State.hs#L68

Функцию почти не трогали, разве что Fix/unfix заменили на embed/project. Однако она на первый взгляд не имеет смысла - алгоритму W такой обход не требуется.

Замена на более логичный вариант не приводит к падению тестов.

renameVarsInExpr :: Expr -> Infer Expr
renameVarsInExpr (ExprType tp) = ExprType <$> renameVars vars tp where
   vars = setToList $ ftv tp

renameVarsInExpr x = return x

Как понять задумку исходного рекурсивного обхода? Или придумать тест кейс чтобы второй вариант упал?

nponeccop avatar Apr 10 '17 01:04 nponeccop

На мой неискушенный взгляд похоже на говнокод, особенно куча разных переменных с именем x.

sirikid avatar Apr 10 '17 02:04 sirikid

Классика хаскеля же. Однобуквенные локальные идентификаторы.

nponeccop avatar Apr 10 '17 02:04 nponeccop

Upd: Этот код вообще вызывается только из одного места, где он логически не нужен

https://github.com/ptol/oczor/blob/14dfe83f0ebd154701a77833cae84dff0c512672/src/Oczor/Infer/Infer.hs#L39

И комментирование его там тоже не приводит к падению тестов. Похоже что можно просто удалить саму функцию и её вызов

nponeccop avatar Apr 10 '17 06:04 nponeccop

Похоже просто дублирование. Так как реализация ftv уже рекурсивно проходит по TypeExpr и собирается все TypeVar, то проходить рекурсивно еще раз смысла нет.

ptol avatar Apr 10 '17 06:04 ptol

На мой неискушенный взгляд похоже на говнокод, особенно куча разных переменных с именем x.

Синтаксис Хаскеля не позволяет избавить от переменных в которых нет необходимости. Например в oczor case синтаксически просто список функций, поэтому можно заменить

case
  ExprTypeF tp -> setToList $ ftv tp
  x -> ffold x

на

case
  ExprTypeF tp -> setToList $ ftv 
  ffold

ptol avatar Apr 10 '17 06:04 ptol

Этот код вообще вызывается только из одного места, где он логически не нужен

Это на случай если внутри функции будет описание типа с TypeVar который уже есть в контексте.

ptol avatar Apr 10 '17 11:04 ptol

Так это нормально. Называется (в пейпере Карделли который я сейчас не могу найти) non-generic type variables. Они связаны наружным forall и их "освобождать" нельзя.

В любом случае нужен тест! Ниже аналоги в HNC:

https://github.com/nponeccop/HNC/blob/master/hn_tests/comp-2.hn https://github.com/nponeccop/HNC/blob/master/hn_tests/comp-2.cpp

Короче тебе задание придумать тест, который упадёт после комментирования renameVarsInExpr. Я там трогать не буду сейчас.

nponeccop avatar Apr 10 '17 16:04 nponeccop