Применяют ли какие-либо языки сохраненные обобщения для функций, передаваемых в качестве параметров? - PullRequest
0 голосов
/ 07 декабря 2018

Сегодня натолкнулся на это в F #:

let test<'a> (f: 'a -> unit) =
    let x = f 123
    let y = f "wow"
    ()

, что приводит к ошибке компилятора, поскольку универсальный параметр должен быть одинаковым в каждом вызове test <'a>, как описано здесь: Типвывод не работает при передаче функции карты

Хотя это имеет смысл, мне стало любопытно, есть ли еще какие-либо языки, которые реализовали что-то подобное - может быть, своего рода «дженерики на уровне параметров»"?

В качестве продолжения, какие проблемы возникают при реализации чего-то подобного?

Ответы [ 2 ]

0 голосов
/ 07 декабря 2018

Можно также утверждать, что C ++ поддерживает это с его странным, но довольно мощным подходом к параметрическому полиморфизму.

template<typename T>
void test(T f)
{
  std::cout << f(123)   << std::endl;
  std::cout << f("wow") << std::endl;
}

int main()
{
  test([](auto const & v) 
    { 
      // Note: This is a compile-time test
      if (std::is_same_v<int, std::decay_t<decltype(v)>>)
      {
        return 0;
      }
      else
      {
        return 1;
      }
    });
}
0 голосов
/ 07 декабря 2018

Конечно.В Haskell такие вещи называются «типами более высокого ранга»: это типы, в которых вам разрешено «перемещать количественное определение в скобках»:

test :: (forall a. a -> ()) -> ()
test f = let x = f 123
             y = f "wow"
         in ()

«Вызов» такжеописано в приведенной ссылке:

Восстановление типа ранга N вообще неразрешимо, и в их присутствии требуются некоторые явные аннотации типов.

Только типы ранга 2но разрешимы, AFAIK (см. здесь ).Вот почему есть два разных флага для их включения в GHC.

...