Что означает стрелка влево <- вне блока do? - PullRequest
11 голосов
/ 31 мая 2019

Я недавно сталкивался со следующим кодом, и он меня очень беспокоит

lowerSafeForeignCall dflags block
| (entry, middle, CmmForeignCall { .. }) <- blockSplit block
= do
 -- do block stuffs
 -- Block doesn't end in a safe foreign call:
| otherwise = return block

Этот фрагмент кода взят из https://phabricator.haskell.org/rGHCb0534f78a73f972e279eed4447a5687bd6a8308e

в файле compiler / cmm / CmmLayoutStack.hs

строка 983

Мне бы очень хотелось узнать, что это <- во второй строке.Я считаю, что <em>lowerSafeForeignCall является функцией, а | и ' в противном случае ' указывают, что эта функция использует охрану.Так что

(entry, middle, CmmForeignCall { .. }) <- blockSplit block

должно быть типа Bool.Но <- вне любого блока do.Я провел поиск в Интернете, но до сих пор не получил ни малейшего представления об этом использовании. </p>

Ответы [ 2 ]

12 голосов
/ 31 мая 2019

Это паттерн :

охранник pat <- infixexp (шаблон защиты)

[...]

A guard имеет одну из следующих форм:

  • шаблонные ограждения имеют форму p <- e, где p является шаблоном (см. Раздел 3.17 ) типа t и e является типом выражения t . Они успешно выполняются, если выражение e соответствует шаблону p , и вводят привязки шаблона в среду.

Там, где обычные средства защиты ограничены булевой проверкой, средства защиты образцов могут сопоставляться с произвольным образцом и определять локальные переменные. (В вашем случае entry, middle и содержимое CmmForeignCall будут непосредственно доступны в теле функции.)

Вы можете думать, что булевы охранники эквивалентны шаблонным охранникам с рисунком True:

| expr

работает как

| True <- expr
8 голосов
/ 31 мая 2019

Это паттерн охраны [Haskell-wiki] .Начиная с Haskell'10 охранник - это список квалификаторов.Спецификатор может быть условием (как в старых гвардейцах), и шаблон гвардейцев .

Таким образом, Haskell (лениво) оценит выражение на правой стороне стрелки <- ицель, чтобы соответствовать этому с образцом слева от стрелки.Если это удастся, то охранник (хорошо, что часть охранника) успешен.Если все части охраны успешны, то правило «срабатывает».

В этом конкретном случае единственная часть паттерна, которая может потерпеть неудачу, - это тот факт, что третий элемент 3-го кортежа - это не a CmmForeignCall конструктор данных.Кроме того, используя этот шаблон защиты, мы, конечно, можем использовать entry, middle в теле выражения.

...