Комментарии 34
Красивые картинки! :-)
+1
Скажите пожалуйста, а в чем смысл этой статьи? Какие цели вы преследовали, при ее написании?
Если говорить о ней, как о материале для начинающего, то боюсь, что в таком ключе она совершенно не годится. Статья не отвечает на главный вопрос: а в чем, собственно отличия алгебраических типов от традиционных структур данных? Не сказано и о преимуществе АТД конструкторов, которые можно использовать в функциях в подстановках и guard conditions. Не говоря уже о том, что в примерах вы используете монады, которые точно не будут понятны с первого взгляда.
Для продвинутого программиста, знакомого с языком Haskell, статья тоже не выглядит полезной. Возникает ощущение краткого конспекта по матану. Как список того что следует еще изучить в языке? Не думаю, скорее как тест того, все ли ты понял.
Чтобы комментарий не выглядел как откровенный наезд на автора, напишу все же благодарность, ибо любая статья достойна внимания. Тем более, повествующая о нестандартных языках :)
Тем кто действительно хочет разобраться в алгебраических типах данных, конструкторах и прочем, советую почитать материалы журнала «Практика функционального программирования», в частности второй выпуск. Также, не лишним будет упомянуть книгу Learn You a Haskell for a Great Good (в продаже имеется и русский перевод).
Если говорить о ней, как о материале для начинающего, то боюсь, что в таком ключе она совершенно не годится. Статья не отвечает на главный вопрос: а в чем, собственно отличия алгебраических типов от традиционных структур данных? Не сказано и о преимуществе АТД конструкторов, которые можно использовать в функциях в подстановках и guard conditions. Не говоря уже о том, что в примерах вы используете монады, которые точно не будут понятны с первого взгляда.
Для продвинутого программиста, знакомого с языком Haskell, статья тоже не выглядит полезной. Возникает ощущение краткого конспекта по матану. Как список того что следует еще изучить в языке? Не думаю, скорее как тест того, все ли ты понял.
Чтобы комментарий не выглядел как откровенный наезд на автора, напишу все же благодарность, ибо любая статья достойна внимания. Тем более, повествующая о нестандартных языках :)
Тем кто действительно хочет разобраться в алгебраических типах данных, конструкторах и прочем, советую почитать материалы журнала «Практика функционального программирования», в частности второй выпуск. Также, не лишним будет упомянуть книгу Learn You a Haskell for a Great Good (в продаже имеется и русский перевод).
+14
Для меня, только знакомого с Haskell (прочитал LYHGG), начало статьи было скучным, а начиная с экзистенциальных типов, пришлось самому искать информацию, потому что приведенная очень обрывочна. Т.е. для меня это был скорее список того, что еще можно почитать.
Итого про existential types, GADT с интересом прочитал в других местах, а вот про ограничения по kind найти не удалось, хотелось увидеть мотивацию и примеры, где это необходимо. Если кто подкинет ссылочку, буду благодарен!
Итого про existential types, GADT с интересом прочитал в других местах, а вот про ограничения по kind найти не удалось, хотелось увидеть мотивацию и примеры, где это необходимо. Если кто подкинет ссылочку, буду благодарен!
+2
Про экзистенциальные типы отлично написано опять же в «практике», но уже в четвертом выпуске.
+2
добавил пример с ограничениями. Вектор с натуральными числами в качестве длины
data Ze
data Su n
data Vec :: * -> * -> * where
Nil :: Vec a Ze
Cons :: a -> Vec a n -> Vec a (Su n)
+4
Я убрал примеры с монадами.
Отличие АТД от других одно — АТД — это универсальный тип данных. С помощью него можно представить большинство типов данных.
Добавил и это.
Собственно, это я и постарался показать — типы данных, которые можно создать благодаря АТД.
Это всё один тип данных.
Что касается pattern matching — механизм не используется в императивных языках, и, соответственно, понять этот плюс сложно.
Отличие АТД от других одно — АТД — это универсальный тип данных. С помощью него можно представить большинство типов данных.
Добавил и это.
Собственно, это я и постарался показать — типы данных, которые можно создать благодаря АТД.
Это всё один тип данных.
Что касается pattern matching — механизм не используется в императивных языках, и, соответственно, понять этот плюс сложно.
+2
pattern matching — механизм не используется в императивных языках
всегда думал что код типа
switch typeof a
case 'int':…
case 'string''…
default:…
}
или try/catch являються по сути pattern matching
возможно ошибался
+1
Под сопоставлением с образцом обычно понимают сопоставление со структурой данных. То есть не просто
Однако, в широко используемых императивных языках принят объектно-ориентированный подход, который подразумевает инкапсуляцию структуры объектов. То есть матчить там по сути нечего, разве что тип объекта в дереве наследования (что обозвали полиморфизмом).
a
имеет какой-то тип, а ещё и содержимое a
обладает определённой структурой.Однако, в широко используемых императивных языках принят объектно-ориентированный подход, который подразумевает инкапсуляцию структуры объектов. То есть матчить там по сути нечего, разве что тип объекта в дереве наследования (что обозвали полиморфизмом).
+5
a имеет какой-то тип, а ещё и содержимое a обладает определённой структурой
тоесть, предполагается наличие одного типа, но с разной внутренней структурой?
0
Да. Большинство паттернов состоят из значений (в том числе и из присвоенных им имен, которые для удобства можно называть переменными, хотя таковыми они не являются) и конструкторов типа.
Допустим, ваша функция принимает на вход два списка, и конкатенирует их. Вполне логично, что паттерны также должны представлять из себя списки:
Представьте, что вы в паттерне укажете данные типа Bool. Это будет ведь бессмысленно, правда?
Допустим, ваша функция принимает на вход два списка, и конкатенирует их. Вполне логично, что паттерны также должны представлять из себя списки:
(++) :: [a] -> [a] -> [a] --Функция принимает на вход два списка со зачениями типа a и возвращает список со значениями типа a
[] ++ ys = ys --Этот паттерн описывает, что делает функция, когда она применяется к пустому списку
x:xs ++ ys = x : (xs ++ ys) --А этот паттерн описывает, что делает функция, когда применяется к непустым спискам
Представьте, что вы в паттерне укажете данные типа Bool. Это будет ведь бессмысленно, правда?
+1
Как видим, смогли создать гетерогенный список, несмотря на то, что он гомогенный.Создать-то создали, только что с ним делать? Я бы расширил этот простой пример для понятности, используя ограничение класса типов:
data HeteroData = forall a. Show a => HeteroData a
instance Show HeteroData where
show (HeteroData x) = show x
list = [HeteroData 3.7, HeteroData "message", HeteroData True]
str = show list -- => [3.7,"message",True]
+3
спасибо! Я думал об этом, но постарался не использовать классы. Ведь понять, что такое экзистенциальные типы достаточно сложно
+3
Просто в вашем варианте
HeteroData
— это реально черный ящик, ничего и никак с его значением не сделать. Это сразу наводит на мысли, что что-то нам недорассказали. При дальнейшем поиске я и нашел, что в реальном мире эта фича часто употребляется именно вместе с классами.+2
Возникло ощущение, что это перевод — встречаются обороты, присущие иностранному языку и странно смотрящиеся в русском. Если так, то дайте, пожалуйста, ссылку на оригинал, а лучше статью оформите как перевод. Если я не прав, то прошу прощения.
+4
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
Спасибо, исправил.
… в качестве конструкторов могут использоваться спец-символы, например двоеточие (:), тогда пользуются инфиксной записью.
… в качестве конструкторов могут использоваться спец-символы, например двоеточие (:), тогда пользуются инфиксной записью.
+1
НЛО прилетело и опубликовало эту надпись здесь
почему нельзя?
{-# LANGUAGE TypeOperators #-}
data a +++++ c = D (a,c)
d= D ("s","s")
> :t d
d :: [Char] +++++ [Char]
+2
НЛО прилетело и опубликовало эту надпись здесь
Вы использовали спецсимволы в названии типа, а не в конструкторах типа. Если бы вы их использовали в конструкторах, то вам нужно было бы в качестве первого символа поставить двоеточие (исключением является конструктор пустого списка).
+2
Любой конструктор можно сделать инфиксным, использовав его в обратных одинарных кавычках в инфиксной нотации. И любой инфиксный оператор можно использовать в префиксной нотации, заключив его в скобки.
Двоеточие в качестве первого символа конструктора нужно использовать, когда сам конструктор состоит из специальных символов (например, @@, +++, @!* и т.д.), исключением является конструктор пустого списка [ ], который состоит из спецсимволов, но не имеет двоеточия в качестве первого символа. И да — конструкторы, состоящие из спецсимволов, используются обычно в инфиксной нотации.
Двоеточие в качестве первого символа конструктора нужно использовать, когда сам конструктор состоит из специальных символов (например, @@, +++, @!* и т.д.), исключением является конструктор пустого списка [ ], который состоит из спецсимволов, но не имеет двоеточия в качестве первого символа. И да — конструкторы, состоящие из спецсимволов, используются обычно в инфиксной нотации.
+1
НЛО прилетело и опубликовало эту надпись здесь
Мы можем вычитание выразить сложением, но оно от этого сложением на становится по сути.
Аналогично и с кванторами. То что мы квантор экзистенциальности / существования преобразовали из квантора всеобщности, типы от этого не становятся всеобщими по сути.
Как-то так )
вроде…
Аналогично и с кванторами. То что мы квантор экзистенциальности / существования преобразовали из квантора всеобщности, типы от этого не становятся всеобщими по сути.
Как-то так )
вроде…
+1
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Зоопарк Алгебрaических Типов Данных