После минимального примера наблюдения (такого рода изумленного меня):частичная деконструкция в сопоставлении с образцом (F #)
type Vector = V of float*float
// complete unfolding of type is OK
let projX (V (a,_)) = a
// also works
let projX' x =
match x with
| V (a, _) -> a
// BUT:
// partial unfolding is not Ok
let projX'' (V x) = fst x
// consequently also doesn't work
let projX''' x =
match x with
| V y -> fst y
Что является причиной того, что делает невозможным для сопоставления частично деконструированного типа?
Некоторых частичных деконструкциев кажется нормально:
// Works
let f (x,y) = fst y
EDIT: Хорошо, теперь я понимаю, «техническую» причина поведения, описанное (Спасибо за ваши ответы & комментариев). Тем не менее, я считаю, что язык мудрый, это поведение кажется немного «неестественным» по сравнению с остальной частью языка:
«Алгебраически», мне кажется странным различать тип «t» от типа »(t)». Скобки (в этом контексте) используются для обеспечения приоритета, например, в "(t * s) * r" vs "t * (s * r)". Также FSI ответы соответственно, отправлять ли я
type Vector = (int * int)
или
type Vector = int * int
к FSI, ответ всегда
типа Vector = Int * INT
Учитывая те наблюдения, заключают, что «int * int» и «(int * int)» означают точно такие же типы и t что все вхождения одного в любой фрагмент кода могут быть заменены другим (см. прозрачность) ... что, как мы видели, неверно.
Далее представляется важным, что для объяснения поведения мы должны были прибегать к разговорам о том, «как выглядит какой-то код после компиляции», а не о семантических свойствах языка, который указывает, что есть некоторые « напряженности "между семантикой языка и тем, что делает компилятор.
Попробуйте с помощью 'type Vector = V of (float * float)' вместо этого, чтобы компилятор использовал фактический кортеж для содержимого. – kvb
он работает! ... но как это могло измениться ... Я имею в виду тип Vector = (V of float) * float даже недействителен? –
Вопрос в следующем: означает ли 'V of x * y' означает, что V содержит кортеж элементов типов x и y" или "V содержит два разных поля типа x и y"? Если вы не вставляете в конец кортеж, тогда компилятор принимает последнее, но если вы его скопируете в скобки, это означает первое. Это различие в основном имеет значение для взаимодействия с другими языками .NET, но, как вы обнаружили, это может также повлиять на то, как вы взаимодействуете со значениями такого типа внутри F # в некоторых случаях. – kvb