2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




Начать новую тему Ответить на тему На страницу 1, 2  След.
 
 Сравнение конструкторов в F#
Сообщение07.06.2015, 15:20 


26/08/12
45
Допустим имеется тип Type. A, A1, B, B1, B2, B, C - некие типы.
Код:
type Type = | Cons1 A A1 | Cons2 B B1 B2 | Cons3 C

И имеется функция, которая принимает два объекта типа Type.
Функция должна выдавать true, если конструкторы объектов одинаковые, false в противном случае.

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

 Профиль  
                  
 
 Re: Сравнение конструкторов в F#
Сообщение07.06.2015, 16:13 
Заслуженный участник
Аватара пользователя


06/10/08
6422
zm_sansan в сообщении #1024397 писал(а):
Я не смог найти в F# функцию для извлечения конструктора и сравнения его с другим.
https://msdn.microsoft.com/en-us/library/ee353849.aspx . Но если не хотите заморачиваться с Reflection, то потребуется столько же паттернов, сколько конструкторов:
Код:
match (x, y) with
| (Cons1 _ _, Cons1 _ _) -> true
| (Cons2 _ _ _, Cons2 _ _ _) -> true
| (Cons3 _, Cons3 _) -> true
| _ -> false

 Профиль  
                  
 
 Re: Сравнение конструкторов в F#
Сообщение07.06.2015, 16:37 


06/06/15

12
Xaositect в сообщении #1024439 писал(а):
потребуется столько же паттернов, сколько конструкторов:

Вот она, слабость статики в действии. Пустяковая задача для Ъ-динамичного ЯП превращается в ад и погибель.
Код:

f := method(o1, o2, (o1 type == o2 type))


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

 Профиль  
                  
 
 Re: Сравнение конструкторов в F#
Сообщение07.06.2015, 16:49 
Заслуженный участник


27/04/09
28128
А есть в F# record syntax в шаблонах? Если да, тогда лучше в прямом матчинге, если всё закончится им, использовать его, потому что он позволяет не указывать число аргументов конструктора. В хаскеле это выглядело бы так:
Используется синтаксис Haskell
f C1{} C1{} = ...
f C1{} C2{} = ...
...
Хотя там как раз тоже есть способ такого не делать.

pborets в сообщении #1024453 писал(а):
Вот она, слабость статики в действии.
Это ерунда. Статически типизированный язык может иметь нормальное отражение (см., например, Ceylon, а хаскель я уже упомянул).

 Профиль  
                  
 
 Re: Сравнение конструкторов в F#
Сообщение07.06.2015, 17:17 


06/06/15

12
arseniiv в сообщении #1024456 писал(а):
может иметь нормальное отражение

Насколько я понимаю, жависты, и прочие хаскелисты, под термином "отражение" понимают нечто свое, особенное (какой то набор уродливых костылей внутри языка). Вообще-то, reflection -- это когда весь(!) исходный код доступен для чтения и модификации в рантайме. Например
Код:

sum := method(x, y, x + y)

sum(1, 2) #>>>> 3

getSlot("sum") message next setName("-")

sum(1, 2) #>>>> -1



И, вообще говоря, в данном случае не рефлексия рулит, а динамическая диспетчеризация.

 Профиль  
                  
 
 Re: Сравнение конструкторов в F#
Сообщение07.06.2015, 17:22 
Заслуженный участник


27/04/09
28128
pborets в сообщении #1024474 писал(а):
какой то набор уродливых костылей
Оценочными суждениями разговор не вымостить.

pborets в сообщении #1024474 писал(а):
Вообще-то, reflection -- это когда весь(!) исходный код доступен для чтения и модификации в рантайме.
Модификации? Это не обязательно.

pborets в сообщении #1024474 писал(а):
И, вообще говоря, в данном случае не рефлексия рулит, а динамическая диспетчеризация.
Ну вот и не путайте их и не примешивайте не относящееся к теме. :roll:

 Профиль  
                  
 
 Re: Сравнение конструкторов в F#
Сообщение07.06.2015, 17:27 


06/06/15

12
arseniiv в сообщении #1024477 писал(а):
Это не обязательно

Не обязательно -- это для интроспекции. И, опять же, весь код, абсолютно весь. А строку из слота прочитать -- это не значит прочитать весь исходник, поэтому я и говорю, что у них своя, "особая" терминология.

 Профиль  
                  
 
 Re: Сравнение конструкторов в F#
Сообщение07.06.2015, 17:39 
Заслуженный участник


16/02/13
4214
Владивосток
pborets в сообщении #1024453 писал(а):
слабость статики
Статика сильна не динамикой :wink: Сила статики — в раннем обнаружении ошибок. А уж самомодифицируемость программы превращает отладку в увлекательнейшее приключение с туманными перспективами...

 Профиль  
                  
 
 Re: Сравнение конструкторов в F#
Сообщение07.06.2015, 17:46 
Заслуженный участник


27/04/09
28128
Вообще интересно, pborets, а вы писали хоть строчку кода на хаскеле, использующую SYB? А то, может статься, всё держится на слухах и желании ещё раз поругать ненавистную область.

Достаточно просто поглядеть начало второй статьи про SYB, чтобы разобраться, как применить это к данному случаю.
Используется синтаксис Haskell
import Data.Data
sameConstructor :: (Data a, Data b) => a -> b -> Bool
sameConstructor a b = toConstr a == toConstr b
И это работает именно в том виде, в котором написано! Инстансы же Data для интересующего типа компилятор напишет сам, если ему намекнуть с помощью deriving.

(Оффтоп)

pborets в сообщении #1024482 писал(а):
Не обязательно -- это для интроспекции.
Посмотрел определение. Что ж, тогда стоит признать, что куча людей в описании своих языков использует слово отражение неправильно вместо интроспекции. Или даже мне не повезло видеть слишком узкие определения, когда в реальности отношение другое.

pborets в сообщении #1024482 писал(а):
И, опять же, весь код, абсолютно весь.
А зачем?

 Профиль  
                  
 
 Re: Сравнение конструкторов в F#
Сообщение07.06.2015, 17:50 


06/06/15

12
arseniiv в сообщении #1024497 писал(а):
А зачем?

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

 Профиль  
                  
 
 Re: Сравнение конструкторов в F#
Сообщение07.06.2015, 17:52 
Заслуженный участник


27/04/09
28128
Хотелось бы представлять, как это должно делаться и почему аналогичного нельзя проделать без полной информации о коде. Но лучше в другой теме.

 Профиль  
                  
 
 Re: Сравнение конструкторов в F#
Сообщение07.06.2015, 18:09 


06/06/15

12
arseniiv в сообщении #1024497 писал(а):
всё держится на слухах и желании ещё раз поругать ненавистную область.

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

 Профиль  
                  
 
 Re: Сравнение конструкторов в F#
Сообщение07.06.2015, 18:46 


26/08/12
45
Xaositect в сообщении #1024439 писал(а):
zm_sansan в сообщении #1024397 писал(а):
Я не смог найти в F# функцию для извлечения конструктора и сравнения его с другим.
https://msdn.microsoft.com/en-us/library/ee353849.aspx . Но если не хотите заморачиваться с Reflection, то потребуется столько же паттернов, сколько конструкторов:
Код:
match (x, y) with
| (Cons1 _ _, Cons1 _ _) -> true
| (Cons2 _ _ _, Cons2 _ _ _) -> true
| (Cons3 _, Cons3 _) -> true
| _ -> false


Как узнать тип объекта понятно, а как узнать конструктор объекта никак не могу найти

 Профиль  
                  
 
 Re: Сравнение конструкторов в F#
Сообщение07.06.2015, 18:52 
Заслуженный участник


27/04/09
28128

(Оффтоп)

pborets в сообщении #1024510 писал(а):
Слухи как раз, напротив, восхваляют ФП, идет агрессивный пиар
Где идёт? Вам, может, и очевидны границы, но поделитесь с остальными.

pborets в сообщении #1024510 писал(а):
особенно резкие
От полезного отзыва нужна не резкость, а аргументация. Так что отсутствие резких (да ещё и по-вашему) отзывов о чём-либо — вовсе не однозначно плохо.

pborets в сообщении #1024510 писал(а):
Я, да, не люблю статику.
А я не люблю динамику. Прекрасный разговор, да?

pborets в сообщении #1024510 писал(а):
И Ваш пример особо не впечатляет.
Мой пример, по крайней мере, ближе к теме (всё-таки она про конструкторы и F#), чем принесённый вами оффтоп о статическом vs. динамическом.

pborets в сообщении #1024510 писал(а):
на каждый случай -- отдельное, неконсистентное, нерасширяемое решение
В том-то и дело, что решение расширяемое. Функция работает для любых типов, которые имеют конструкторы. Плюс, SYB входит в пакет base, его не надо откуда-то тащить.

pborets в сообщении #1024510 писал(а):
И каждая подпорка тащит еще с собой кучу зависимостей. В итоге все компилируется часами, а потом тормозит и падает.
Во-первых, снова оценочные суждения о неопределённой совокупности вещей. Во-вторых, странно говорить о компиляции, когда в динамически типизированных языках её, как правило, вообще нет, и сравнение некорректно.

-- Вс июн 07, 2015 20:58:35 --

zm_sansan в сообщении #1024521 писал(а):
Как узнать тип объекта понятно, а как узнать конструктор объекта никак не могу найти
Ссылка Xaositect ведёт как раз на функцию, возвращающую информацию о конструкторе вместе со всеми его полями. UnionCaseInfo * obj [] — это именно оно. Отсюда надо просто взять первую компоненту с помощью fst или того же матчинга.

 Профиль  
                  
 
 Re: Сравнение конструкторов в F#
Сообщение07.06.2015, 19:18 


06/06/15

12
arseniiv в сообщении #1024523 писал(а):
В том-то и дело, что решение расширяемое

Допустим, я хочу написать функцию, которая возвращает true не только когда аргументы -- инстансы (прямые потомки) какого-то одного класса, а наследуют от какого то одного класса, но не напрямую, а через цепочку суперклассов. Можно такое расширение над этим Вашим решением написать?

(Оффтоп)

arseniiv в сообщении #1024523 писал(а):
странно говорить о компиляции, когда в динамически типизированных языках её, как правило, вообще нет, и сравнение некорректно.

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

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 18 ]  На страницу 1, 2  След.

Модераторы: Karan, Toucan, PAV, maxal, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group