LINUX.ORG.RU

История изменений

Исправление AndreyKl, (текущая версия) :

По-моему, всё, приводимое ранее, и было кортежами.

Я так понимаю тебя смущает «уникальность» типа для каждого списка. Т.е. список 'a' ::: True ::: HNil будет иметь тип HList Char (HList Bool (HList [])), а список (1::Int) ::: HNil будет иметь тип HList Int (HList []).

Я в общем понимаю что это не совсем привычно. Но всё таки я могу привести пару интересных примеров. Первое это некоторый промежуточный тип между обычным списком и гетерогенным (в смысле представленном в коде который я привёл). Это список с известной на этапе компиляции длиной. выглидит например так Vect a n где a - тип элементов в коллекции, а n - число эл-тов в списке. При этом туда можно добавлять элементы, убирать элементы и длина остаётся известной на этапе компиляции (ну т.е. если мы убрали один эл-т, то длина уменьшилась, стал тип Vect a (n-1), если прибавили, то длина увеличилась - Vect a (n+1)). Ну при этом есть дополнительная гарантия, а именно что мы никогда не вызовем head на пустом списке (пока фильтровать не начнём, конечно.. но это детали:) ).

Если следовать твоей логике то это кортеж или не кортеж? В пользу того что это кортеж говорит что тип меняется при добавлении/удалении эл-та, т.е. как у кортежа. А в пользу того что список - то что тип эл-тов один и тот же. И можно легко определить обычные для списков операции.

Сразу скажу не встречал чтобы кто то окрестил такую конструкцию кортежем. Т.е. можно конечно наверное, но смысла мало.

Следующий пример чуть более непонятный: в языках с зависимыми типами очень многие типы уникальны в том смысле что прямо зависят от значений. Т.е. там «уникальность» типов в этом смысле гораздо более заметна чем например в хаскеле. Приведу пример: функия число аргументов (а значит и тип) которой зависят от первого аргумента:

adder 0 : Int -> Int
adder 1 : Int -> Int -> Int
adder 2 : Int -> Int -> Int -> Int
т.е. если передано значение 0 - то ф-ция ожидает один аргумент и вернёт его, если передано значение 1 - ф-ция ожидает два арг-та и вернёт их сумму. Если передано 2 - ф-ция ожидает три арг-та и вернёт их сумму.

Вопрос: что это? Ну явно не функция, потому что ну странно - разное ведь число аргументов и типы разные. Может это три разных функции? однако действие они выполняют одно и то же (суммируют переданные аргументы) и называются одинаково.

Т.е. я хочу сказать что в целом аргумент «уникальный тип для каждого значения значит не список а кортеж» - выглядит не слишком убедительно. Мне кажется нужно смотреть на то как ведёт себя структура.

По моему «гетерогенный список» себя «ведёт» скорее как список нежели чем как кортеж.

Исходная версия AndreyKl, :

По-моему, всё, приводимое ранее, и было кортежами.

Я так понимаю тебя смущает «уникальность» типа для каждого списка. Т.е. список 'a' ::: True ::: HNil будет иметь тип HList Char (HList Bool (HList [])), а список (1::Int) ::: HNil будет иметь тип HList Int (HList []).

Я в общем понимаю что это не совсем привычно. Но всё таки я могу привести пару интересных примеров. Первое это некоторый промежуточный тип между обычным списком и гетерогенным (в смысле представленном в коде который я привёл). Это список с известной на этапе компиляции длиной. выглидит например так Vect a n где a - тип элементов в коллекции, а n - число эл-тов в списке. При этом туда можно добавлять элементы, убирать элементы и длина остаётся известной на этапе компиляции (ну т.е. если мы убрали один эл-т, то длина уменьшилась, стал тип Vect a (n-1), если прибавили, то длина увеличилась - Vect a (n+1)). Ну при этом есть дополнительная гарантия, а именно что мы никогда не вызовем head на пустом списке (пока фильтровать не начнём, конечно.. но это детали:) ).

Если следовать твоей логике то это кортеж или не кортеж? В пользу того что это кортеж говорит что тип меняется при добавлении/удалении эл-та, т.е. как у кортежа. А в пользу того что список - то что тип эл-тов один и тот же. И можно легко определить обычные для списков операции.

Сразу скажу не встречал чтобы кто то окрестил такую конструкцию кортежем. Т.е. можно конечно наверное, но смысла мало.

Следующий пример чуть более непонятный: в языках с зависимыми типами очень многие типы уникальны в том смысле что прямо зависят от значений. Типы прямо зависят от значений, т.е. например Т.е. там «уникальность» типов в этом смысле гораздо более заметна чем например в хаскеле. Приведу пример: функия число аргументов (а значит и тип) которой зависят от первого аргумента:

adder 0 : Int -> Int
adder 1 : Int -> Int -> Int
adder 2 : Int -> Int -> Int -> Int
т.е. если передано значение 0 - то ф-ция ожидает один аргумент и вернёт его, если передано значение 1 - ф-ция ожидает два арг-та и вернёт их сумму. Если передано 2 - ф-ция ожидает три арг-та и вернёт их сумму.

Вопрос: что это? Ну явно не функция, потому что ну странно - разное ведь число аргументов и типы разные. Может это три разных функции? однако действие они выполняют одно и то же (суммируют переданные аргументы) и называются одинаково.

Т.е. я хочу сказать что в целом аргумент «уникальный тип для каждого значения значит не список а кортеж» - выглядит не слишком убедительно. Мне кажется нужно смотреть на то как ведёт себя структура.

По моему «гетерогенный список» себя «ведёт» скорее как список нежели чем как кортеж.