2014 dxdy logo

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

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




На страницу 1, 2  След.
 
 Сравнение конструкторов в F#
Сообщение07.06.2015, 15:20 
Допустим имеется тип 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 
Аватара пользователя
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 
Xaositect в сообщении #1024439 писал(а):
потребуется столько же паттернов, сколько конструкторов:

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

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


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

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

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

 
 
 
 Re: Сравнение конструкторов в F#
Сообщение07.06.2015, 17:17 
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 
pborets в сообщении #1024474 писал(а):
какой то набор уродливых костылей
Оценочными суждениями разговор не вымостить.

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

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

 
 
 
 Re: Сравнение конструкторов в F#
Сообщение07.06.2015, 17:27 
arseniiv в сообщении #1024477 писал(а):
Это не обязательно

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

 
 
 
 Re: Сравнение конструкторов в F#
Сообщение07.06.2015, 17:39 
pborets в сообщении #1024453 писал(а):
слабость статики
Статика сильна не динамикой :wink: Сила статики — в раннем обнаружении ошибок. А уж самомодифицируемость программы превращает отладку в увлекательнейшее приключение с туманными перспективами...

 
 
 
 Re: Сравнение конструкторов в F#
Сообщение07.06.2015, 17:46 
Вообще интересно, 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 
arseniiv в сообщении #1024497 писал(а):
А зачем?

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

 
 
 
 Re: Сравнение конструкторов в F#
Сообщение07.06.2015, 17:52 
Хотелось бы представлять, как это должно делаться и почему аналогичного нельзя проделать без полной информации о коде. Но лучше в другой теме.

 
 
 
 Re: Сравнение конструкторов в F#
Сообщение07.06.2015, 18:09 
arseniiv в сообщении #1024497 писал(а):
всё держится на слухах и желании ещё раз поругать ненавистную область.

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

 
 
 
 Re: Сравнение конструкторов в F#
Сообщение07.06.2015, 18:46 
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 

(Оффтоп)

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 
arseniiv в сообщении #1024523 писал(а):
В том-то и дело, что решение расширяемое

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

(Оффтоп)

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

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

 
 
 [ Сообщений: 18 ]  На страницу 1, 2  След.


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group