Можно ли вообще использовать такой параметр, как `id`, в F#?

Можно ли иметь параметр, представляющий что-то вроде id (что-то типа 'T -> 'T), и использовать его в общем?

то есть ниже у меня есть id_like, что я хотел бы иметь возможность работать с объектами любого типа. Однако оказывается, что как только я работаю с объектом определенного типа, компилятор специализируется id_like и не позволяет ему работать ни с чем другим.

Ниже я получаю FS0064: This construct causes code to be less generic than indicated by the type annotations, когда я работаю с a, а затем ошибка компиляции, когда я пытаюсь работать с b.

let f (id_like: 'T -> 'T) (a: int) (b: bool) =
    let a1 = id_like a
    let b1 = id_like b
    a1, b1

let _ = f id 0 false

Если нет, то это просто артефакт использования Хиндли-Милнера? Является ли HM «жадным» в случаях, когда параметры содержат функции?

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
69
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

К сожалению, это не разрешено, потому что это сделало бы вывод типа неразрешимым. Полученный язык эквивалентен System F (полиморфное лямбда-исчисление).

Вместо этого системы типов Хиндли-Милнера обеспечивают «let-полиморфизм»: только значения, связанные в конструкции let, являются полиморфными:

let id x = x
  in ... (id 3) ... (id "text") ...

Параметры в лямбда-абстракциях (т. е. определениях функций) мономорфны.

Спасибо! Похоже, что «пусть полиморфизм» требуется только для вывода типа. Знаете ли вы, есть ли техническая причина, по которой это также невозможно, когда тип явно аннотирован? Или это то, что потенциально может быть добавлено в компилятор?

Dax Fohl 21.12.2022 20:48

F# использует дженерики .NET, поэтому я не думаю, что это возможно. Он также не поддерживается в C#.

Brian Berns 21.12.2022 21:17

Спасибо также за образование. Я работал время от времени (в основном без перерыва) в течение пары лет, пытаясь создать механизм вывода типов, который делал бы именно это, что и было реальной мотивацией вопроса. (И пытаясь сделать это, не ссылаясь ни на что, чтобы я мог видеть, что я могу придумать). Приятно осознавать, что у него уже есть имя, и это доказуемо неразрешимо, и я могу перейти к моему следующему проекту.

Dax Fohl 24.12.2022 19:41

вы можете обойти проблему, обернув функцию в интерфейс

type Id_Wrapper() = 
    member __.Apply<'a> (x: 'a) = id x

let g (id_like : Id_Wrapper) (a: int) (b: bool) = 
    let a1 = id_like.Apply a
    let b1 = id_like.Apply b
    a1, b1

тип выводится для каждого приложения Apply, которые затем могут быть разными типами

этот код компилируется

Другие вопросы по теме