Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Программирование [игнор отключен] [закрыт для гостей] / [haskell] ограничение системы типов хаскеля. / 25 сообщений из 39, страница 1 из 2
05.10.2011, 21:57
    #37470112
ZyK_BotaN
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
[haskell] ограничение системы типов хаскеля.
вот проблема:
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
05.10.2011, 21:59
    #37470115
ZyK_BotaN
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
[haskell] ограничение системы типов хаскеля.
вот что я нашел на данную тему в в журнале ПФП:

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


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

авторПроявлю смелость предположить, что вопрос сформулирован криво и (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
05.10.2011, 22:53
    #37470167
Зимаргл
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
[haskell] ограничение системы типов хаскеля.
ZyK_BotaN,

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

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

жигулевское
...
Рейтинг: 0 / 0
05.10.2011, 23:02
    #37470176
U-gene
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
[haskell] ограничение системы типов хаскеля.
нет в квадрате ширины и высоты
есть длина стороны.
писать для квадрата отдельно функции setWidth и setHeight - глупость изначально ;) . даже с точки зрения интерфейса.
...
Рейтинг: 0 / 0
05.10.2011, 23:09
    #37470180
ZyK_BotaN
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
[haskell] ограничение системы типов хаскеля.
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
05.10.2011, 23:09
    #37470181
ZyK_BotaN
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
[haskell] ограничение системы типов хаскеля.
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
05.10.2011, 23:11
    #37470182
U-gene
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
[haskell] ограничение системы типов хаскеля.
дак они как раз для того, что-бы можно было смотреть на квадрат, считая его прямоугольником. так-то.
а зачем? :)
...
Рейтинг: 0 / 0
05.10.2011, 23:11
    #37470183
ZyK_BotaN
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
[haskell] ограничение системы типов хаскеля.
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
05.10.2011, 23:12
    #37470185
ZyK_BotaN
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
[haskell] ограничение системы типов хаскеля.
U-geneдак они как раз для того, что-бы можно было смотреть на квадрат, считая его прямоугольником. так-то.
а зачем? :)

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

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

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

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

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

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

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

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

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

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

хочешь? - делай. при этом одно другому не мешает. он все так же будет оставаться прямоугольником.
...
Рейтинг: 0 / 0
05.10.2011, 23:32
    #37470197
ZyK_BotaN
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
[haskell] ограничение системы типов хаскеля.
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
05.10.2011, 23:46
    #37470201
ZyK_BotaN
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
[haskell] ограничение системы типов хаскеля.
вот полный код:

Код: 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
06.10.2011, 00:04
    #37470213
U-gene
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
[haskell] ограничение системы типов хаскеля.
ключевые слова - квадрат выглядит как прямоугольник
поэтому мы можем к нему применить алгоритм как к прямоугольнику
но не изменить стороны, как у прямоугольника

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

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

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

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

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

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


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

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

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

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

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

наверно

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


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

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

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

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

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


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


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

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

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

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

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


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