powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Программирование [игнор отключен] [закрыт для гостей] / [haskell] ограничение системы типов хаскеля.
25 сообщений из 39, страница 1 из 2
[haskell] ограничение системы типов хаскеля.
    #37470112
Фотография ZyK_BotaN
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
вот проблема:
ZyK_BotaNZyK_BotaNче-то мне система типов хаскеля дала по рукам, и не позволила мне реализовать проблему квадрата_прямоугольника так, как я это делал на с++

кстати, вспомнил почему. недавно же читал про ограничения системы типов хаскеля, на примере Функтора.
то что в хаскеле называется Функтором, на самом деле является ЭндоФунктором, а настоящий Функтор, так просто не реализуешь, так как хаскель типизируется по хиндли-милнеру(что обеспечивает автоматический вывод типов)

что-бы понять суть, покажу, то как я хотел реализовать, и почему не получилось.
хотел сделать так(не нарушая принцип лисков):
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
class Rectangle r where 
    setWidth ::  r a -> a -> r a
    setHeight :: r a -> a -> r a
    getWidth :: r a -> a
    getHeight :: r a -> a
    
class (Rectangle s) => Square s where
    setSide :: s a -> a -> s a
    getSide :: s a -> a

data Sqr a = Square a
             deriving Show
data Rct a = Rectangle a a
             deriving Show
             
instance Square Sqr where
    setSide    _ s         = Square s
    getSide   (Square s)   = s

instance Rectangle Sqr where
    setWidth  (Square s) w = Rectangle w s
    setHeight (Square s) h = Rectangle s h
    getWidth  (Square s)   = s
    getHeight (Square s)   = s
    
    
instance Rectangle Rct where
    setWidth  (Rectangle _ h) w = Rectangle w h
    setHeight (Rectangle w _) h = Rectangle w h
    getWidth  (Rectangle w _)   = w
    getHeight (Rectangle _ h)   = h
    
но это:

Код: plaintext
1.
2.
    setWidth  (Square s) w = Rectangle w s
    setHeight (Square s) h = Rectangle s h
, хаскель не позволяет, так как в сигнатуре(r a -> a -> r a), переменные типа r совпадают, и не может быть на входе квадрат, а на выходе - прямоугольник.
вот если бы хаскель позволял сделать такую сигнатуру - (r1 a -> a -> r2 a) - где r1 и r2 - типы класса Rectangle, то все бы выше. но из-за возможности вывода типов, данные возможности у хаскеля убрали(но я попробую как-то эту проблему решить)

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

λf.(λx.f (x x)) (λx.f (x x))

пуду по ходу решения проблемы, оставлять здесь комментарии.
...
Рейтинг: 0 / 0
[haskell] ограничение системы типов хаскеля.
    #37470115
Фотография ZyK_BotaN
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
вот что я нашел на данную тему в в журнале ПФП:

авторПолиморфизм ранга * (rank * polymorphism) — вместо символа подстановки * могут использоваться значения «1», «k» и «N». В полиморфизме первого ранга (этот тип полиморфизма ещё называют «предварённым полиморфизмом» или «let-полиморфизмом») типовые переменные могут получать конкретные значения мономорфных типов. Полиморфизм ранга k предполагает, что в формулах, описывающих λ-термы, квантор всеобщности (∀) может стоять не более чем перед k стрелками. Данный класс полиморфизма выделен потому, что при k = 2 проблема вывода типов разрешима, в то время как при k > 2 эта проблема неразрешима. Наконец, полиморфизм высшего ранга (или полиморфизм ранга N) определяется тем, что кванторы всеобщности могут стоять перед произвольным количеством стрелок.


в системе по хиндли-милнеру используется let полиморфизм. т.е. первого ранга. я думаю нужно сюда копать.
как сделать полиморфизм 2-го ранга. возможно есть расширения для компилятора, которіе позволяют єто сделать.
...
Рейтинг: 0 / 0
[haskell] ограничение системы типов хаскеля.
    #37470141
Фотография ZyK_BotaN
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
вот что мне рассказал анонимус с лора:

авторПроявлю смелость предположить, что вопрос сформулирован криво и (f :: a1 -> b -> a2) требуется по a2 экзистенциальным, а не полиморфным.

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

Раз.

class C a1 a2 | a1 -> a2 where
f :: a1 -> b -> a2

data T1 = T1

data T2 = T2

instance C T1 T1 where
f T1 b = T1

instance C T2 T1 where
f T2 b = T1

Два.

class C a1 where
type F a1
f :: a1 -> b -> F a1

data T1 = T1

data T2 = T2

instance C T1 where
type F T1 = T1
f T1 b = T1

instance C T2 where
type F T2 = T1
f T2 b = T1

anonymous (05.10.2011 22:18:18)
...
Рейтинг: 0 / 0
[haskell] ограничение системы типов хаскеля.
    #37470167
Зимаргл
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ZyK_BotaN,

Какие _вещества_ употребляем на нось глядя?
...
Рейтинг: 0 / 0
[haskell] ограничение системы типов хаскеля.
    #37470169
Фотография ZyK_BotaN
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ЗимарглZyK_BotaN,

Какие _вещества_ употребляем на нось глядя?

жигулевское
...
Рейтинг: 0 / 0
[haskell] ограничение системы типов хаскеля.
    #37470176
Фотография U-gene
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
нет в квадрате ширины и высоты
есть длина стороны.
писать для квадрата отдельно функции setWidth и setHeight - глупость изначально ;) . даже с точки зрения интерфейса.
...
Рейтинг: 0 / 0
[haskell] ограничение системы типов хаскеля.
    #37470180
Фотография ZyK_BotaN
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
U-geneнет в квадрате ширины и высоты
есть длина стороны.
писать для квадрата отдельно функции setWidth и setHeight - глупость изначально ;) . даже с точки зрения интерфейса.

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

з.ы. благодяря анонимусу с лора, запилил работающую версию:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
class Rectangle r where 
    type R r :: * -> *
    setWidth :: r a -> a -> R r a
    setHeight :: r a -> a -> R r a
    getWidth :: r a -> a
    getHeight :: r a -> a
    
class (Rectangle s) => Square s where
    setSide :: s a -> a -> s a
    getSide :: s a -> a

data Sqr a = Square a
             deriving Show
data Rct a = Rectangle a a
             deriving Show
             
instance Square Sqr where
    setSide    _ s         = Square s
    getSide   (Square s)   = s

instance Rectangle Sqr where
    type R Sqr = Rct
    setWidth  (Square s) w = Rectangle w s
    setHeight (Square s) h = Rectangle s h
    getWidth  (Square s)   = s
    getHeight (Square s)   = s
    
    
instance Rectangle Rct where
    type R Rct = Rct
    setWidth  (Rectangle _ h) w = Rectangle w h
    setHeight (Rectangle w _) h = Rectangle w h
    getWidth  (Rectangle w _)   = w
    getHeight (Rectangle _ h)   = h    

правда, что-бы она заработала, нужно использовать ghc-расширение - "-XTypeFamilies"
стандарт 98-го года, не позволяет так делать
...
Рейтинг: 0 / 0
[haskell] ограничение системы типов хаскеля.
    #37470181
Фотография ZyK_BotaN
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
U-geneнет в квадрате ширины и высоты
есть длина стороны.
писать для квадрата отдельно функции setWidth и setHeight - глупость изначально ;) . даже с точки зрения интерфейса.

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

з.ы. благодяря анонимусу с лора, запилил работающую версию:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
class Rectangle r where 
    type R r :: * -> *
    setWidth :: r a -> a -> R r a
    setHeight :: r a -> a -> R r a
    getWidth :: r a -> a
    getHeight :: r a -> a
    
class (Rectangle s) => Square s where
    setSide :: s a -> a -> s a
    getSide :: s a -> a

data Sqr a = Square a
             deriving Show
data Rct a = Rectangle a a
             deriving Show
             
instance Square Sqr where
    setSide    _ s         = Square s
    getSide   (Square s)   = s

instance Rectangle Sqr where
    type R Sqr = Rct
    setWidth  (Square s) w = Rectangle w s
    setHeight (Square s) h = Rectangle s h
    getWidth  (Square s)   = s
    getHeight (Square s)   = s
    
    
instance Rectangle Rct where
    type R Rct = Rct
    setWidth  (Rectangle _ h) w = Rectangle w h
    setHeight (Rectangle w _) h = Rectangle w h
    getWidth  (Rectangle w _)   = w
    getHeight (Rectangle _ h)   = h    

правда, что-бы она заработала, нужно использовать ghc-расширение - "-XTypeFamilies"
стандарт 98-го года, не позволяет так делать
...
Рейтинг: 0 / 0
[haskell] ограничение системы типов хаскеля.
    #37470182
Фотография U-gene
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
дак они как раз для того, что-бы можно было смотреть на квадрат, считая его прямоугольником. так-то.
а зачем? :)
...
Рейтинг: 0 / 0
[haskell] ограничение системы типов хаскеля.
    #37470183
Фотография ZyK_BotaN
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
U-geneнет в квадрате ширины и высоты
есть длина стороны.
писать для квадрата отдельно функции setWidth и setHeight - глупость изначально ;) . даже с точки зрения интерфейса.

заметь. вот интерфейс квадрата:

Код: plaintext
1.
2.
3.
class (Rectangle s) => Square s where
    setSide :: s a -> a -> s a
    getSide :: s a -> a

здесь нет ширины и высоты.
но так как квадрат является прямоугольником, то мы говорим, что тип s можно сделать инстасом калсса Квадрат, только если тип s - является инстансом класса прямоугольник
...
Рейтинг: 0 / 0
[haskell] ограничение системы типов хаскеля.
    #37470185
Фотография ZyK_BotaN
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
U-geneдак они как раз для того, что-бы можно было смотреть на квадрат, считая его прямоугольником. так-то.
а зачем? :)

есть у меня алгоритм для прямоугольника.

есть квадрат.

хочу применить данный алгоритм для моего объекта. квадрат ведь является прямоугольником, да?
...
Рейтинг: 0 / 0
[haskell] ограничение системы типов хаскеля.
    #37470187
Фотография U-gene
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ну ладно есть такие свойсвта прямоугольника как высота и длина. это его унутрениие свойства

а почему мартин пытается вычислить площадь снаружи ?

нужна ему площадь - пусть описывает это свойтсво внутри объекта. а из-за двойных стандартов все проблемы и есть :)
...
Рейтинг: 0 / 0
[haskell] ограничение системы типов хаскеля.
    #37470189
Фотография U-gene
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
нет
я точно также могу определить его как равносторонний равноугольный многоугольник с четырьмя сторонами.
тогда наследовать я его буду от другого базового класса.
...
Рейтинг: 0 / 0
[haskell] ограничение системы типов хаскеля.
    #37470192
Фотография ZyK_BotaN
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
U-geneну ладно есть такие свойсвта прямоугольника как высота и длина. это его унутрениие свойства

а почему мартин пытается вычислить площадь снаружи ?

нужна ему площадь - пусть описывает это свойтсво внутри объекта. а из-за двойных стандартов все проблемы и есть :)

ну в данном случае проблемы с площадью нет. можно смело снаружи считать.
так как у квадрата есть и ширина и высота:

Код: plaintext
1.
square rect = (getWidth rect) * (getHeight rect)
...
Рейтинг: 0 / 0
[haskell] ограничение системы типов хаскеля.
    #37470193
Фотография ZyK_BotaN
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
U-geneнет
я точно также могу определить его как равносторонний равноугольный многоугольник с четырьмя сторонами.
тогда наследовать я его буду от другого базового класса.

внезапно. кто тебе мешает сделать квадрат еще и раносторониим и равно угольным многоугольником?

хочешь? - делай. при этом одно другому не мешает. он все так же будет оставаться прямоугольником.
...
Рейтинг: 0 / 0
[haskell] ограничение системы типов хаскеля.
    #37470197
Фотография ZyK_BotaN
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ZyK_BotaNU-geneнет
я точно также могу определить его как равносторонний равноугольный многоугольник с четырьмя сторонами.
тогда наследовать я его буду от другого базового класса.

внезапно. кто тебе мешает сделать квадрат еще и раносторониим и равно угольным многоугольником?

хочешь? - делай. при этом одно другому не мешает. он все так же будет оставаться прямоугольником.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
class Rectangle r where 
    type R r :: * -> *
    setWidth :: r a -> a -> R r a
    setHeight :: r a -> a -> R r a
    getWidth :: r a -> a
    getHeight :: r a -> a

class EqualAngle e where
    getNumberOfAngles :: e a -> Int
    
class (Rectangle s, EqualAngle s) => Square s where
    setSide :: s a -> a -> s a
    getSide :: s a -> a

data Sqr a = Square a
             deriving Show
data Rct a = Rectangle a a
             deriving Show
             
instance Square Sqr where
    setSide    _ s         = Square s
    getSide   (Square s)   = s

instance Rectangle Sqr where
    type R Sqr = Rct
    setWidth  (Square s) w = Rectangle w s
    setHeight (Square s) h = Rectangle s h
    getWidth  (Square s)   = s
    getHeight (Square s)   = s

instance EqualAngle Sqr where
    getNumberOfAngles _ =  4 

пример пойдет?
...
Рейтинг: 0 / 0
[haskell] ограничение системы типов хаскеля.
    #37470201
Фотография ZyK_BotaN
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
вот полный код:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
class Rectangle r where 
    type R r :: * -> *
    setWidth :: r a -> a -> R r a
    setHeight :: r a -> a -> R r a
    getWidth :: r a -> a
    getHeight :: r a -> a

class EqualAngle e where
    getNumberOfAngles :: e a -> Int
    
class (Rectangle s, EqualAngle s) => Square s where
    setSide :: s a -> a -> s a
    getSide :: s a -> a

data Sqr a = Square a
             deriving Show
data Rct a = Rectangle a a
             deriving Show
             
instance Square Sqr where
    setSide    _ s         = Square s
    getSide   (Square s)   = s

instance Rectangle Sqr where
    type R Sqr = Rct
    setWidth  (Square s) w = Rectangle w s
    setHeight (Square s) h = Rectangle s h
    getWidth  (Square s)   = s
    getHeight (Square s)   = s

instance EqualAngle Sqr where
    getNumberOfAngles _ =  4 
    
    
instance Rectangle Rct where
    type R Rct = Rct
    setWidth  (Rectangle _ h) w = Rectangle w h
    setHeight (Rectangle w _) h = Rectangle w h
    getWidth  (Rectangle w _)   = w
    getHeight (Rectangle _ h)   = h

square rect = (getWidth rect) * (getHeight rect)
...
Рейтинг: 0 / 0
[haskell] ограничение системы типов хаскеля.
    #37470213
Фотография U-gene
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ключевые слова - квадрат выглядит как прямоугольник
поэтому мы можем к нему применить алгоритм как к прямоугольнику
но не изменить стороны, как у прямоугольника

если бы было два типа наследования
1) IS наследование, когда наследуется все
и
2) LOOKS_LIKE наследование когда наследуются только get часть спецификации

а затем писать что-то типа

void LSPV( readonly Rectangle& r){
r.SetWidth(5); // ошибка компилятора, потому что это set-метод

assert(r.GetWidth() * r.GetHeight()) == 20);
}

то это бы в некоторой степени решило проблему.

наверно
...
Рейтинг: 0 / 0
[haskell] ограничение системы типов хаскеля.
    #37470214
Фотография ZyK_BotaN
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
U-geneключевые слова - квадрат выглядит как прямоугольник
поэтому мы можем к нему применить алгоритм как к прямоугольнику
но не изменить стороны, как у прямоугольника


бинго.
функция setWidth - возвращает прямоугольник
если хочешь изменить сторону квадрата, нужно юзать setSide

но при этом, квадрат наследуется от прямоугольника, поэтому ф-ю setWidth можно применить к квадрату(ну и получить прямоугольник).

что и видно из моего кода
...
Рейтинг: 0 / 0
[haskell] ограничение системы типов хаскеля.
    #37470216
Фотография ZyK_BotaN
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
U-genevoid LSPV( readonly Rectangle& r){
r.SetWidth(5); // ошибка компилятора, потому что это set-метод

assert(r.GetWidth() * r.GetHeight()) == 20);
}

то это бы в некоторой степени решило проблему.

наверно

нет. проблему решают иммутабешьные типы.
когда setWidth, не объект изменяет, а возвращает новый измененный объект.
...
Рейтинг: 0 / 0
[haskell] ограничение системы типов хаскеля.
    #37470220
Фотография ZyK_BotaN
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
U-geneключевые слова - квадрат выглядит как прямоугольник


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

т.е. множество квадратов входит в множество прямоугольников.
...
Рейтинг: 0 / 0
[haskell] ограничение системы типов хаскеля.
    #37470361
Фотография U-gene
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
когда setWidth, не объект изменяет, а возвращает новый измененный объект
это не понял.
ну вернет оно измененный объект
что - площадь правильно посчитается?

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

умартина пример логической ошибки, когда код вроде бы правильный, а результат кривой

существуют внутренние зависимости, когда изменение некоторого компонента объекта влечет изменение другого компонента.
мне кажется, что любое изменение такой зависимости в процессе наследования потенциально ведет к ошибке, как у мартина
любое!
если мы позволим себе LOOKS_LIKE наследование (только get-интерфейс) и затем будем пресекать для таких объектов использование чужих set-интерфейсов, то проблема будет ловиться на этапе компиляции.
...
Рейтинг: 0 / 0
[haskell] ограничение системы типов хаскеля.
    #37470491
Фотография ZyK_BotaN
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
U-geneкогда setWidth, не объект изменяет, а возвращает новый измененный объект
это не понял.
ну вернет оно измененный объект
что - площадь правильно посчитается?


да
...
Рейтинг: 0 / 0
[haskell] ограничение системы типов хаскеля.
    #37470498
Фотография ZyK_BotaN
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
U-geneа по set интерфейсу оно входит в множество центрально-симметричных многоугольников.


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

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

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

вот с площадью все ок.
...
Рейтинг: 0 / 0
[haskell] ограничение системы типов хаскеля.
    #37470502
Фотография ZyK_BotaN
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
U-geneесли мы позволим себе LOOKS_LIKE наследование (только get-интерфейс) и затем будем пресекать для таких объектов использование чужих set-интерфейсов, то проблема будет ловиться на этапе компиляции.

почему же только гет? и сет нужно наследовать.
...
Рейтинг: 0 / 0
25 сообщений из 39, страница 1 из 2
Форумы / Программирование [игнор отключен] [закрыт для гостей] / [haskell] ограничение системы типов хаскеля.
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]