Nano Hash - криптовалюты, майнинг, программирование

Почему OCaml не может определить следующий тип:

Рассмотрим следующий код

module type Foo = sig 
  type t
  val do_with_t : t -> unit
end

let any_foo t (module F : Foo) = F.do_with_t t

Что отклоняется следующей прекрасной ошибкой типа:

Error: This expression has type F.t but an expression was expected of type F.t
      The type constructor F.t would escape its scope

Но будет принято после того, как я добавлю следующую аннотацию типа:

let any_foo (type s) (t:s) (module F : Foo with type t = s) = F.do_with_t t

Ограничение совместного использования имеет для меня смысл, поэтому мой вопрос в том, почему OCaml не может вывести сигнатуру типа из моего использования t внутри функции.

15.04.2013

  • Что вы ожидаете от типа any_foo, не вводя s? 15.04.2013
  • Для модуля необходимо указать его тип. В противном случае это стало бесплатным типом. 17.04.2013

Ответы:


1

На самом деле это не отвечает на ваш вопрос, но в вашем случае вам просто нужно ввести новую переменную типа s:

let any_foo (type s) t (module F : Foo with type t = s) = F.do_with_t t

т.е. вам не нужен (t:s), так как вывод типа здесь будет работать нормально.

15.04.2013

2

Я не эксперт, но вот мое мнение по этому поводу.

Настоящая ошибка - это последний бит сообщения:

Конструктор типа F.t выйдет за пределы своей области видимости.

Чтобы понять сообщение об ошибке, давайте сначала перепишем any_foo без сопоставления аргумента с шаблоном и переименуем аргумент, чтобы облегчить объяснение:

let any_foo arg foo = 
  let (module F : Foo) = foo in
    F.do_with_t arg

Здесь вы используете первоклассные модули и распаковываете переменную foo в новый модуль F, в рамках этого оператора let.

Теперь давайте рассмотрим тип аргумента arg, который может быть выведен из этого факта. Ясно, что это тип F.t, но, что критически важно, это тип, который известен только в текущей области, потому что module F известен только в текущей области.

Теперь попробуем определить тип результирующей any_foo функции:

val any_foo : F.t -> (module Foo) -> unit

И вот ваша проблема, вы пытаетесь раскрыть только что созданный тип F.t из глубины области действия функции. Другими словами, вы ожидаете, что вызывающая сторона знает тип, который существует только внутри вашей функции. Или, говоря другими словами, вы ожидаете, что тип F.t «ускользнет» из своей области и попадет в более широкую аудиторию.

Решение, объясненное

Теперь, когда мы знаем проблему, мы можем осознать необходимость объяснить компилятору, что этот тип существует во «внешней» области и что аргумент arg относится к этому типу.

Другими словами, нам нужно добавить ограничение к нашему недавно созданному модулю F, чтобы сказать, что тип аргумента arg равен типу t внутри нашего нового модуля F. Для этого мы можем использовать локально абстрактный тип.

Продолжая использовать ту же функцию, мы можем добавить локально абстрактный тип a и ограничить им модуль F:

let (type a) any_foo arg foo = 
  let (module F : Foo with type t = a) = foo in
    F.do_with_t arg

Давайте теперь рассмотрим тип any_foo.

val any_foo : 'a -> (module Foo with type t = 'a) -> unit

Никаких проблем нет.

Для полноты картины вернемся к нашей версии сопоставления с образцом:

let (type a) any_foo arg (module F : Foo with type t = a) =
  F.do_with_t arg
07.02.2014
Новые материалы

Кластеризация: более глубокий взгляд
Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

Как написать эффективное резюме
Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

Частный метод Python: улучшение инкапсуляции и безопасности
Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

Как я автоматизирую тестирование с помощью Jest
Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..