Список — это линейная структура данных, если вы хотите прочитать конец списка, вам нужно пройти его до конца за линейное время. Элементы массива можно читать за O(1).
Я говорю не про изменение массива, а про доступ к произвольному элементу по индексу. Понятие «прохода» теряет смысл, так как я могу обращаться к любому элементу массива.
Нет, нельзя. Как можно говорить об одном проходе, если вы используете мутабельные массивы, которые позволяют вам обращаться к произвольному элементу по индексу в любом месте?
Повторно используемым — потому что мы можем использовать любые структуры данных, для которых определен Traversable. Любые эффекты можно так же запускать в другом порядке, обернув их в Backwards.
1) Я сомневаюсь, что kind как-то вообще связан с теорией категорий (может вы спутали с теорией типов?), скиньте мне пожалуйста ссылку, если я не прав.
2) Параметризованные типы — это типы, имеющие параметры, а не сами параметры.
3) Какие 2 типа данных имеются ввиду? И зачем иметь два разных типа?
4) Я не имел ввиду функцию `validate`. Не думаю, что это выглядит как ответ на вопрос.
На мой взгляд, это ужасная статья для перевода. Мало того, что она использует мощную систему типов для решения несуществующих проблем, так еще и отпугивает людей, которым действительно интересен Haskell.
Я прочитал статью несколько раз и все равно ничего не понял. Какую задачу тут помогли решить поднятые до «родов» (впервые слышу такой перевод, я привык к «видам») параметризованные типы данных?
И мы будем валидировать данные лишь в том случае, когда валидны все поля записи.
-- Этот код будет работать и для Identity, так как Identity так же имеет экземпляр класса Applicative:
Person <$> name <*> age
В коде реального приложения подобные заигрывания с семействами типов лишь для того, чтобы из Identity a вытащить a очень больно ударят по его читаемости. Когда вы читаете сигнатуру какой-нибудь функции, будет лучше, если вы сразу понимаете, Identity там или что-то другое.
Это задача уже другого плана. Он именно поэтому и «простой», так как с его помощью можно задавать включение определенных типов. Вы сами пробовали ответить на свой вопрос? Как насчет проверки длины списка?
Мне кажется, тут можно обойтись без зависимых типов и списков:
type Email = ...
type Postal = ...
type Office = ...
data Tuple a b = Tuple a b -- более известен как (,)
data Either a b = Left a | Right b -- два взаимоисключающих инварианта
data These a b = This a | That b | These a b -- два взаимно не исключаемых инварианта
data Cofree f a = a :< f (Cofree f a)
-- Должен быть либо почтовый адрес, либо электронный адрес
example1 :: Either Email Postal
-- Должен быть либо почтовый адрес, либо электронный адрес, либо оба
example2 :: These Email Postal
-- Должен быть либо почтовый адрес, либо одновременно электронный адрес и адрес в офисе
example3 :: Either Postal (Tuple Email Office)
-- Задание со звездочкой
example4 :: Either (Cofree Maybe Postal) (Tuple (Cofree Maybe Email) (Cofree Maybe Office))
Нет, нельзя. Как можно говорить об одном проходе, если вы используете мутабельные массивы, которые позволяют вам обращаться к произвольному элементу по индексу в любом месте?
2) Параметризованные типы — это типы, имеющие параметры, а не сами параметры.
3) Какие 2 типа данных имеются ввиду? И зачем иметь два разных типа?
4) Я не имел ввиду функцию `validate`. Не думаю, что это выглядит как ответ на вопрос.
На мой взгляд, это ужасная статья для перевода. Мало того, что она использует мощную систему типов для решения несуществующих проблем, так еще и отпугивает людей, которым действительно интересен Haskell.
В коде реального приложения подобные заигрывания с семействами типов лишь для того, чтобы из Identity a вытащить a очень больно ударят по его читаемости. Когда вы читаете сигнатуру какой-нибудь функции, будет лучше, если вы сразу понимаете, Identity там или что-то другое.