LINUX.ORG.RU

[haskell][news] GHC 7.4

 ,


1

2

Уже была новость про RC. -XSafe, -XTrustworthy, -XUnsafe, -XPolyKinds, compiler plugins.

Ещё из новых возможностей - в GHCi теперь кроме функций можно давать любые определения (data, type, newtype, class, instance, deriving, foreign). Функции по-прежнему требуют подставлять let (как в do-блоке, может, в будущем уберут такое поведение).

-XConstraintKinds (заметка в блоге автора). Если -XPolyKinds не очень много меняет - просто позволяет писать чуть более строго типизированный type-level код, то -XConstraintKinds - несколько более мощное расширение. Оно добавляет новый kind - Constraint. Если все типы объединяются в kind *, то все классы типов объединяются в kind Constraint, более того, теперь можно проводить forall квантификацию не только по типам (:: *), но и по классам типов (:: Constraint). Например, теперь можно делать динамическую диспетчеризацию (позднее связывание) и Dynamic-like типы более удобно.

Пример.

module Shape where

-- * Объекты (типы данных).

data Circle = Circle Double
  deriving ( Show, Eq )

data Square = Square Double
  deriving ( Show, Eq )

-- * Интерфейс (набор методов).

class ShapeInterface a where
  perimeter :: a -> Double
  area :: a -> Double

-- * Реализация интерфейса (определения методов).

instance ShapeInterface Circle where
  perimeter (Circle r) = 2 * pi * r
  area (Circle r) = pi * r * r

instance ShapeInterface Square where
  perimeter (Square s) = 4 * s
  area (Square s) = s * s

это статическая диспетчеризация (раннее связывание, специфицирующая метод функция подставляется во время компиляции). Раньше для динамической диспетчеризации нужно было писать:

{-# LANGUAGE ExistentialQuantification #-}

module ShapeDynamic where

import Shape

-- * Динамический тип -- обвёртка с помощью existential quantification.

data Shape = forall a. ShapeInterface a => Shape a

-- * Реализация интерфейса для динамического типа.

instance ShapeInterface Shape where
  perimeter (Shape x) = perimeter x
  area (Shape x) = area x

-- * Умные конструкторы для динамических объектов.

circle :: Double -> Shape
circle = Shape . Circle

square :: Double -> Shape
square = Shape . Square

-- * Использование.

shapes :: [Shape]
shapes = [circle 2, square 3]

example :: [Double]
example = map area shapes

-- shapes
-- > No instance for (Show Shape)

-- example
-- > [12.566370614359172,9.0]

который уже реализует динамическую диспетчеризацию (позднее связывание, выбор специфицирующей метод функции будет произведён во время выполнения).

Если после вдруг окажется, что кроме ShapeInterface нужны другие интерфейсы, то нужно возвращаться и править обвёртку. Либо писать обвёртку на каждый интерфейс (а это адъ). Например, чтобы добавить интерфейс Show:

data Shape = forall a. (Show a, ShapeInterface a) => Shape a

instance Show Shape where
  show (Shape x) = show x

-- shapes
-- > [Circle 2.0,Square 3.0]

Теперь, с помощью -XConstraintKinds, можно написать так:

{-# LANGUAGE Rank2Types, KindSignatures, GADTs, ConstraintKinds,
             FlexibleInstances, UndecidableInstances #-}

module ShapeDynamicNew where

import GHC.Prim ( Constraint )

import Shape

-- * Общее место.

-- | Dynamic строит тип (*) из одно-параметрического класса типов
-- (* -> Constraint). Класс типов передаётся как аргумент конструктору типов.
-- Конструктор данных принимает любые объекты разделяющие интерфейс данного
-- класса типов и возвращает динамический объект построенного типа Dynamic cls.
data Dynamic :: (* -> Constraint) -> * where
  Dynamic :: forall cls a. cls a => a -> Dynamic cls

-- * Складываем необходимые интерфейсы.

class (Show t, ShapeInterface t) => ShowShapeInterface t
instance (Show t, ShapeInterface t) => ShowShapeInterface t

-- * Динамический тип -- все те объекты которые разделяют данный интерфейс(ы).

type Shape = Dynamic ShowShapeInterface

-- * Реализация интерфейса для динамического типа.

instance ShapeInterface Shape where
  perimeter (Dynamic x) = perimeter x
  area (Dynamic x) = area x

instance Show Shape where
  show (Dynamic x) = show x

-- Умные конструкторы для динамических объектов.

circle :: Double -> Shape
circle = Dynamic . Circle

square :: Double -> Shape
square = Dynamic . Square

-- * Использование.

shapes :: [Shape]
shapes = [circle 2.0, square 3.0]

example :: [Double]
example = map area shapes

-- shapes
-- > [Circle 2.0,Square 3.0]

-- example
-- > [12.566370614359172,9.0]
★★★★
Ответ на: комментарий от anonymous

Любой терм может иметь сколько угодно типов.

Коль скоро терм это стрелка... :) У неё может быть только один домен и кодомен.

Простейший пример - нетривиальное отношение подтипирования с типами пересечениями и объединениями.

Нафиг эти подтипы. Вот дерево - подтип графа, или наоборот? Единственное нормальное определение подтипов это структурные подтипы, и для них вся эта машинерия с образованием подтипов и их «нетривиальными отношениями» сводится к терминологической обвёрке над нормальной системой типов где у терма ровно один тип.

Я и стараюсь это делать

Только без ссылок на источники, да.

quasimoto ★★★★
() автор топика
Ответ на: комментарий от quasimoto

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

quasimoto ★★★★
() автор топика
Ответ на: комментарий от Miguel

Мне показался забавным ответ[1] обиженного Одерского:

My response will probably not please him. I think that we need to take away sharp knifes from people who have a tendency to cut themselves. [...] So, I believe here is what we need do: Truly advanced, and dangerously powerful, features such as implicit conversions and higher-kinded types will in the future be enabled only under a special compiler flag.

[1] http://news.ycombinator.com/item?id=3443436

dave ★★★★★
()
Ответ на: комментарий от buddhist

Мне в Scheme не хватает CLOS и параметров &key. Да и Racket видится как объединение разных дипломных работ студентов, курируемых примерно одними и теми же преподавателями.

dave ★★★★★
()
Ответ на: комментарий от dave

Для меня в Схеме вся прелесть в отдельных ОО-системах. Racket != Scheme, это кошмар :) По поводу ключевых параметров ничего не могу сказать, они мне особо не нужны.

buddhist ★★★★★
()
Ответ на: комментарий от buddhist

А есть развитый графический тулкит уровня CAPI из LispWorks? Смотрел Racket, но там выглядит бедновато. Подозреваю, что у других реализаций Схемы и того нет.

Идея сочетать Схему с кодом на Си как-то не очень прельщает. Это хорошо, если логику можно отделить от ГУИ. А если все слито воедино? Тут и хороши графические тулкиты, особенно межплатформенные.

Вот, и приходится для своего небольшого проекта в качестве хобби смотреть в сторону Java, выбирая между SWT и Swing. Нужно хорошее ГУИ. Редактор диаграмм, вывод графиков, таблиц и прочие вещи.

Что посоветуешь на счет Схемы?

dave ★★★★★
()
Ответ на: комментарий от quasimoto

Коль скоро терм это стрелка... :) У неё может быть только один домен и кодомен.

Не, ну это пушка. Стрелка - это модель терма. То есть мы, _наверное_, можем моделировать терм стрелкой - но встает вопрос корректности модели. Нам известно, что терм может иметь сколь угодно много типов (это эмпирический факт, он получен из наблюдений), если моделируя терм стрелкой мы не можем получить сколь угодно большое количество типов - значит модель некорректна. И применять ее нельзя. Надо ее менять.

Нафиг эти подтипы.

Ну это твое мнение, а между тем на данный момент не существует _ни одного_ не маргинального ЯП без подтипирования.

Единственное нормальное определение подтипов это структурные подтипы

Опять личное мнение человека, который не способен выбраться за пределы мирка из двух диссеров.

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

Я могу возразить - вся эта «нормальная» система типов в данном случае сводится к терминологической обертке над этой машинерией с образованием подтипов.

Только без ссылок на источники, да.

Ну почитай тот же тапл, там про подтипирование есть.

Еще раз - есть общепринятые формально строгие математические определения. И, согласно им, тайпклассы образуют решетку на множестве типов, а любая решетка является системой типов.

anonymous
()
Ответ на: комментарий от dave

Ну, если ориентироваться на Java, то тут можно посоветовать Kawa — это вполне себе неплохая гнушная реализация Схемы на JVM с возможностью использовать классы Java. А так, в остальных реализациях существуют разной степени допиленности привязки ко всяким Gtk. В JazzScheme (которая основана на Gambit) есть какая-то своя реализация гуя. При этом они утверждают, что «JazzScheme has been used for more than 10 years to develop commercial software». Мне больше всего нравится Gambit и основанные на нем JazzScheme и Termite.

buddhist ★★★★★
()
Ответ на: комментарий от dave

Truly advanced, and dangerously powerful, features such as implicit conversions and higher-kinded types will in the future be enabled only under a special compiler flag.

Хм. Если он сказал бы «flags» вместо «flag», я бы сделал вывод, что Скала может пойти в правильную сторону.

Miguel ★★★★★
()
Ответ на: комментарий от buddhist

Спасибо за ответ!

Для JVM мне больше подходит Scala. Что касается Gtk, то SWT перекрывает его. В общем, похоже, придется жевать кактус из Scala и SWT. Жаль, что в программировании осталось так мало вещей, которые могут приятно удивить.

dave ★★★★★
()
Ответ на: комментарий от dave

Это как расширения для GHC?

Вроде того. Есть полезные (GeneralizedNewtypeDeriving, например), есть необходимые (RankNTypes), а есть и просто всё запутывающие (OverloadedInstances).

Miguel ★★★★★
()
Ответ на: комментарий от anonymous

Вы читали результаты ратификации r6rs и обоснования людей, проголосовавших против? Большинство из них являются ключевыми фигурами в сообществе: Джаффер, Перлмуттер, Сискинд, Холм, Клингер, Риз, Фили — это навскидку. Основная причина: ломают совместимость, суют кучу фич напрямую в ядро (что-то напоминает, да) ценой простоты и ортогональности, не следуя, собственно говоря Scheme-way.

Так вы, видимо, не в курсе предложения этих людей (в особенности Уильяма Клингера) по созданию отдельного стандарта ERR5RS. Почему среди всех реализаций r6rs не любят именно Racket? Ответ прост: его создатели — основные авторы r6rs да и концепция его не Ъ :) Впрочем, это только неосиляторы в ответ на просьбу посоветовать Scheme советуют Racket. Его создатели уже давно говорят, что Racket != Scheme.

buddhist ★★★★★
()
Ответ на: комментарий от dave

По поводу Scala я ничего не могу сказать, использовал ее один раз, давно, «когда она еще не была мейнстримом» :)

Жаль, что в программировании осталось так мало вещей, которые могут приятно удивить.

Да, это печально. Но меня, как любителя APL, недавно приятно удивил Nial чистотой, обоснованностью и мощными средствами (для массивно-ориентированного языка, конечно). Однако, он почти умер.

buddhist ★★★★★
()
Ответ на: комментарий от buddhist

Основная причина: ломают совместимость

Понятие совместимости для scheme никогда и не имело смысла, т.к. любая программа сложнее факториала неминуемо получалась заточена под конкретную реализацию. Собственно, r6rs и нужен был чтобы хоть как-то решить эту проблему.

суют кучу фич напрямую в ядро

Но это неправда.

ценой простоты и ортогональности

И это неправда.

не следуя, собственно говоря Scheme-way.

И это тоже неправда.

Так вы, видимо, не в курсе предложения этих людей (в особенности Уильяма Клингера) по созданию отдельного стандарта ERR5RS.

Который в итоге будет тем же r6rs. только в профиль :)

Впрочем, это только неосиляторы в ответ на просьбу посоветовать Scheme советуют Racket.

Обычно так советуют потому, что подмножество racket совместимо хоть с r5rs хоть c r6rs чуть менее чем полностью (а #lang соответствующие в принципе вообще совместимы полностью), зато когда надоест писать факториалы (что всегда рано или поздно происходит) - под рукой сразу есть куча батареек и макросы, сделанные правильно. Другими словами, на racket никто не мешает писать как на схеме, пока не захочется чего по-интереснее.

Его создатели уже давно говорят, что Racket != Scheme.

Да с этим никто и не спорит, Racket все же позиционируется не как ЯП для обучения, а как ЯП общего назначения.

anonymous
()
Ответ на: комментарий от buddhist

Почему среди всех реализаций r6rs не любят именно Racket?

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

anonymous
()
Ответ на: комментарий от anonymous

Нам известно, что терм может иметь сколь угодно много типов

Вот возьмём си (С++ брать не будем), какие другие типы кроме foo могут быть у `x' вот тут:

typedef struct {
  ...
} foo;

    foo x;

? Возьмём хаскель - какой (не-полиморфный) тип может быть у True кроме Bool? Могут быть разные полиморфные типы - например такой ((cls a, a ~ Bool) => a) и любой ему альфа- и бета- эквивалентный (в хаскеле есть редукция на классах), или такой (forall a. F Bool a) (type family F a b; type instance F Bool x = Bool) т.е. альфа- и бета- эквивалентные Bool (есть редукция на типах). Но не-полиморфный тип один. Даже в случае подтипов будет единственный минимальный тип.

И применять ее нельзя. Надо ее менять.

Вот в статически-типизированных языках без динамики и/или подтипов (или с динамикой и/или подтипами моделируемыми статическими конструкциями с полиморфизмом) как раз вполне естественно считать, что термы имеют один тип (один не-полиморфный / минимальный тип, если нет полиморфизма - вовсе один).

В динамическом лиспе тоже естественно иметь единственный минимальный тип (то что показывает type-of).

Но вернёмся к классам типов. Для типа Int какой будет минимальный тип (класс)? Никакого. Для двух классов cls1 Int и cls2 Int, может не быть отношения cls1 < cls2 или cls1 > cls2. Решётка как-то не просматривается, но даже если ты вводишь своё особое понятие типизации типов в классы, потом ты начинаешь говорить про «типизированную лямбду на типах» - вот тут уже хочется ссылок.

не существует _ни одного_ не маргинального ЯП без подтипирования.

Си? (Там есть только перегруженные числовые литералы и операторы, и приведение типов в числовых / указательных выражениях).

Я могу возразить - вся эта «нормальная» система типов в данном случае сводится к терминологической обертке над этой машинерией с образованием подтипов.

Но зачем (мы говорим о статически-типизированных языках) объяснять простое с помощью сложного, вместо того чтобы строить сложное на основе простого?

quasimoto ★★★★
() автор топика
Ответ на: комментарий от quasimoto

Вот возьмём си (С++ брать не будем)

Почему же не будем? Давай возьмем. Хотя ладно, давай си. Какой тип у терма «0»? Целое? Какое из них? Или указатель? Или bool? :)

Даже в случае подтипов будет единственный минимальный тип.

А при чем тут минимальный тип? Опять разговор уводишь куда-то в сторону.

Вот в статически-типизированных языках без динамики и/или подтипов

У тебя логика страдает. Сперва ты говоришь «давайте ограничимся ЯП без подтипов», потом говоришь «в ЯП без подтипов у термов один тип», потом говоришь «значит можно моделировать термы стрелками, у которй единственные dom/cod» - и пока все ок, но потом ВНЕЗАПНО у тебя откуда-то берется следствие, что вообще у терма всегда один тип, неважно где. Чуешь дыру в рассуждениях? У тебя каждый тип в хаскеле _по факту_ принадлежит (в общем случае) к нескольким тайпклассам. Так что имеем отношение подтипирования. Значит стрелка неприменима (не к системе типов хаскеля, а к ее надстройке на уровне типов).

В динамическом лиспе тоже естественно иметь единственный минимальный тип (то что показывает type-of).

Что еще за «естественно»? Естественно для кого? Естественно для каких задач? Я оперирую формально строгими математическими объектами, понятиями, рассуждениями, в этом контексте твои «естественно» смысла не имеют, потому что субъективны, потому что неформализуемы. Терм имеет несколько типов - математический факт. Хоть из штанов выпрыгни.

Для типа Int какой будет минимальный тип (класс)? Никакого.

А зачем минимальный? вопрос стоит - какие классы определены. Ну такие, которые в данном программе ты определил. Что здесь неясного?

Для двух классов cls1 Int и cls2 Int, может не быть отношения cls1 < cls2 или cls1 > cls2. Решётка как-то не просматривается

А оно и не должно быть, решетка - это ЧУП.

но даже если ты вводишь своё особое понятие типизации типов в классы

Какое еще свое? Совершенно обычное.

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

Ссылок на что? Я уже объяснил выше дважды, что подразумевается под этими словами.

Си?

union?

Но зачем (мы говорим о статически-типизированных языках) объяснять простое с помощью сложного, вместо того чтобы строить сложное на основе простого?

Вот именно - зачем? Я и предлагаю - давай сложное на основе простого строить. То есть: «вся эта „нормальная“ система типов в данном случае сводится к терминологической обертке над этой машинерией с образованием подтипов».

anonymous
()
Ответ на: комментарий от quasimoto

А Clojure не подходит по каким причинам?

Если кратко, то слишком функциональная.

Я глубоко не изучал этот язык. Но мне показалось, что там тяжеловато будет с объектами. Я привык к ним, хотя везде, где можно, использую иммутабельность и функции высшего порядка. Но некоторые вещи все же требуют объектов, или, по крайней мере, легко и естественно ложатся на объектно-ориентированную парадигму. Я за гибридный стиль.

В Scala с объектами все здорово. Там даже функции являются объектами :)

dave ★★★★★
()
Ответ на: комментарий от anonymous

Какой тип у терма «0»?

А в си появился вывод типов? Но вообще в выражениях приведение к int.

но потом ВНЕЗАПНО у тебя откуда-то берется следствие, что вообще у терма всегда один тип, неважно где. Чуешь дыру в рассуждениях?

Нет, я про «неважно где» не говорил. Я вообще весь тред топчусь мыслями в области MLTT / её сужения.

У тебя каждый тип в хаскеле _по факту_ принадлежит (в общем случае) к нескольким тайпклассам.

Типы классам принадлежат? Или ограничения (constraints) классов принадлежат типам?

Так что имеем отношение подтипирования.

А, ты говорил, что в хаскеле нет подтипов (в другом треде)? С -XConstraintKinds можно считать, что есть?

Что еще за «естественно»?

(type-of 0) => BIT естественно.

Я оперирую формально строгими математическими объектами

Терм имеет несколько типов - математический факт.

Нет математических фактов вообще, есть факты математических моделей. В одной модели у тебя будет много типов у терма, в другой - только один.

А зачем минимальный?

Затем, что в тех примерах которые я привёл _есть_ минимальный тип. Тут - нет. Это уже вызывает подозрения.

А оно и не должно быть, решетка - это ЧУП.

Тогда ладно.

Ссылок на что? Я уже объяснил выше дважды, что подразумевается под этими словами.

Ну ты оперируешь строгими математическими объектами и даешь некую формальную модель классов типов, если ты не вещаешь напрямую из области чистых идей, то должны быть ссылки на формально строгие описания таких моделей. Интересно же - сам факт существования формальной модели классов типов.

union?

Ну тогда Maybe это тоже подтипы (тот же union)?

То есть: «вся эта „нормальная“ система типов в данном случае сводится к терминологической обертке над этой машинерией с образованием подтипов».

Передёргиваешь. В ML-ях просто это именно эта «нормальная» система типов - simply typed LC + polymorphism + и т.д. вплоть до _надстроек_ для подтипов.

quasimoto ★★★★
() автор топика
Ответ на: комментарий от dave

Но некоторые вещи все же требуют объектов, или, по крайней мере, легко и естественно ложатся на объектно-ориентированную парадигму.

ООП в духе CLOS, или с объединением данных и методов в класс? Если второе - какие есть вещи которые более естественно программировать в таком ООП?

quasimoto ★★★★
() автор топика
Ответ на: комментарий от quasimoto

ООП в духе CLOS, или с объединением данных и методов в класс?

Пробовал себя там и там. Особо большой разницы пока не заметил. Разве что, в CLOS надо быть аккуратнее в выборе имен.

Если второе - какие есть вещи которые более естественно программировать в таком ООП?

Например, представление диаграммы в виде расширенного логического графа.

dave ★★★★★
()
Ответ на: комментарий от dave

Может быть, не так понял второй вопрос. Мой посыл относится к тому, что, вообще, удобно делать с ООП. Я с той же легкостью это запрограммировал в CLOS.

dave ★★★★★
()
Ответ на: комментарий от dave

Например, представление диаграммы в виде расширенного логического графа.

Имеется ввиду необходимость мутабельности (оверхед State Transformera), или необходимость иметь в классе вместе с графом (матрица смежности, например) дополнительные private параметры (тоже мутабельные) чтобы не передавать их аргументами?

quasimoto ★★★★
() автор топика
Ответ на: комментарий от dave

Мой посыл относится к тому, что, вообще, удобно делать с ООП. Я с той же легкостью это запрограммировал в CLOS.

Тогда что такое ООП? State + generics + inheritable intefaces + namespaces (private / public) + something?

quasimoto ★★★★
() автор топика
Ответ на: комментарий от quasimoto

Имеется ввиду необходимость мутабельности (оверхед State Transformera), или необходимость иметь в классе вместе с графом (матрица смежности, например) дополнительные private параметры (тоже мутабельные) чтобы не передавать их аргументами?

Просто ООП - наиболее естественное и простое выражение моей идеи.

dave ★★★★★
()
Ответ на: комментарий от quasimoto

Тогда что такое ООП? State + generics + inheritable intefaces + namespaces (private / public) + something?

Не-а, уволь меня от философических тем :)

dave ★★★★★
()
Ответ на: комментарий от dave

правка: «Просто через ООП получается...» и далее по тексту

dave ★★★★★
()
Ответ на: комментарий от dave

Не-а, уволь меня от философических тем :)

Просто поделись своим вИдением - что такое «ООП»? Если не трудно, конечно.

Просто ООП - наиболее естественное и простое выражение моей идеи.

Т.е. что это за языковые средства? Они общие для CLOS и Java? За счёт чего достигается выразительность?

quasimoto ★★★★
() автор топика
Ответ на: комментарий от quasimoto

Т.е. что это за языковые средства? Они общие для CLOS и Java? За счёт чего достигается выразительность?

Честно говоря, не задавался такими теоретическими вопросами. Я больше программист-практик, который когда-то сумел выучиться на математика. Теория программирования меня интересует мало. Для теории я могу попытаться заново прочитать учебник «Вероятность» Ширяева. Сейчас это двухтомник. Два года назад купил специально для этого, но все руки не доходят :)

dave ★★★★★
()
Ответ на: комментарий от quasimoto

А в си появился вывод типов?

А при чем тут вывод типов?

Нет, я про «неважно где» не говорил. Я вообще весь тред топчусь мыслями в области MLTT / её сужения.

Но речь ведь не о MLTT и не о ее сужениях, а о конкретной системе, которая задается в хаскеле типами/тайпклассами.

Типы классам принадлежат?

Типы классам, очевидно.

А, ты говорил, что в хаскеле нет подтипов (в другом треде)? С -XConstraintKinds можно считать, что есть?

В системе типов хаскеля - нет. В системе типов, которая получается из типов/функций с тайпклассами и применением полиморфного аргумента в качестве аппликации - есть. И констрейнты тут не при делах вовсе.

(type-of 0) => BIT естественно.

Не вижу ничего естественного.

Нет математических фактов вообще, есть факты математических моделей. В одной модели у тебя будет много типов у терма, в другой - только один.

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

Затем, что в тех примерах которые я привёл _есть_ минимальный тип. Тут - нет. Это уже вызывает подозрения.

У нас есть жопа в качестве минимального типа.

Ну ты оперируешь строгими математическими объектами и даешь некую формальную модель классов типов, если ты не вещаешь напрямую из области чистых идей, то должны быть ссылки на формально строгие описания таких моделей.

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

Ну тогда Maybe это тоже подтипы (тот же union)?

В сях неразмеченный union - это подтипы. Размеченные объединения - соответственно, не подтипы. Ну очевидно же.

Передёргиваешь.

Нет, не передергиваю, просто пытаюсь какбе намекнуть, что твое утверждение - это вкусовщина. Никаких объективных оснований утверждать, что один из подходов проще/сложнее - нет.

anonymous
()
Ответ на: комментарий от anonymous

А при чем тут вывод типов?

Ты же не пишешь var foo = 0; и дальше ждёшь вывода типов (как в go), ты пишешь, например, char ch = 0; или int n = 0; А в выражениях целые приводятся к int.

Типы классам, очевидно.

А в википедии написано, что constraints типам.

Не вижу ничего естественного.

Между тем, в CL type-of говорит минимальный тип, typep проверяет принадлежность значения типу (любому), а subtypep проверяет отношение подтипирования.

У нас есть жопа в качестве минимального типа.

Жопа это не класс. И да, жопы в виде типа в хаскеле нет.

В сях неразмеченный union - это подтипы.

Какими свойствами подтипов они обладают? LSP? Можно пример в коде?

quasimoto ★★★★
() автор топика
Ответ на: комментарий от anonymous

Я имею в виду не любят среди тех, о ком я говорил.

buddhist ★★★★★
()
Ответ на: комментарий от anonymous

Понятие совместимости для scheme никогда и не имело смысла

Я имел в виду совместимость со стандартами.

И это неправда.

Это слова нескольких из тех, кто проголосовал против, не мои (хотя я разделяю их мнение).

buddhist ★★★★★
()
Ответ на: комментарий от quasimoto

В сях неразмеченный union - это подтипы.

Какими свойствами подтипов они обладают? LSP? Можно пример в коде?

typedef union { foo x; ... } bar; foo <: bar.

Действительно, LSP тоже соблюдается.

quasimoto ★★★★
() автор топика
Ответ на: комментарий от anonymous

Странно, что у квазимото есть вообще желание на твои психоделические высеры что-либо отвечать. Ты чем упарываешься?

anonymous
()
Ответ на: комментарий от anonymous

если вы сказали, что нечто Тьюринг-(не)полно, то вы ничего не сказали.

После этого следовало бы разом закончить разговор и заигнорить пациента.

anonymous
()
Ответ на: комментарий от dave

Мне в Scheme не хватает CLOS

М.б. Swindle? Хоть он и идет в комплекте к Racket, вроде не Racket-специфичен =/

korvin_ ★★★★★
()
Ответ на: комментарий от dave

Если кратко, то слишком функциональная.

Clojure слишком функциональная по сравнению со Scala? Да ты шутишь.

korvin_ ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.