Про структуру классов.

Sep 21, 2013 14:06

В Хаскеле есть операции && и || для логических значений. Их тип фиксирован, это (&&), (||) :: Bool -> Bool -> Bool.

В результате те, кому мало Prelude, делают свои классы для своих операций, где те же самые операции уже перегружены по носителю: (&&), (||) :: Constraint f => f Bool -> f Bool -> f BoolИ эти же операции перекрываются с операциями из ( Read more... )

дизайн программного обеспечения, Хаскель

Leave a comment

Comments 7

thedeemon September 21 2013, 10:57:55 UTC
>И эти же операции перекрываются с операциями из Data.Bits:(.&.), (.|.)

Вовсе нет. В Data.Bits операции, работающие с короткими векторами битов, упомянутым там самое место. С логическими (&&) и (||) они не пересекаются, ни по смыслу, ни по типам, ни по семантике (что там у (.|.) с ленивостью, например?).

Reply

thesz September 21 2013, 11:23:43 UTC
Ленивость .|. в ее тип не входит. Она зависит от реализации.

По типам пересекаются. Bool -> Bool -> Bool частный случай a -> a -> a.

Смысл тоже один. || - это побитовое ИЛИ для однобитных значений. То есть, это .|. для значений типа Bool.

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

Reply

kodt_rsdn September 21 2013, 15:50:14 UTC
А если рассматривать Bool как одноэлементный битовый вектор, что мешает определить для него сдвиг?
Ну, будет True `shift` 0 = True, а всё остальное False...

Reply

thesz September 21 2013, 17:11:21 UTC
Я об этом думал. Но смысла мало, мне кажется.

Те же связки &&, || и xor вполне подходят, допустим, для логических значений с null (sql). Где там сдвиг?

Лучше разбить на два класса.

Reply


kodt_rsdn September 21 2013, 16:04:26 UTC
Набор битов можно трактовать как битсет (изоморфный конечному множеству), а можно - как битовый вектор.
С векторами, понятное дело, можно творить гораздо больше фокусов. Сдвиг, переворот, скалярное произведение - всё то, что для множеств бессмысленно.
Хотя, сдвиг - это инкремент всех элементов множества, а переворот - это вычитание... если элементы множества - отрезок целых чисел.

Тогда получится не Data.Bits (который Num a => Bits a, что как бы намекает, что это, всё-таки, относится к числам, а не к чему попало), а какие-нибудь
Abstract.BooleanAlgebra и Abstract.BooleanVectorSpace

Reply


ex_juan_gan September 21 2013, 20:07:00 UTC
А ещё было бы любопытно смотреть на это всё как на многозначную булеву логику и сообразить, шо за сдвиги? Это комбинация проекций какая-то.

Reply

thesz September 24 2013, 15:01:33 UTC
Кстати, напоминает финальные алгебры.

fix (`shiftLogical` 1) x = 0.

В любом направлении.

Reply


Leave a comment

Up