Подтвердить что ты не робот

Может ли поле записи быть сопоставлено с некоторым значением и назначено параметру одновременно?

После относительно короткого текста в Haskell wiki о сопоставлении шаблонов записей, я не уверен, что поле записи может быть сопоставлено с некоторым значением и назначено параметру в то же время.

-- Sample record type
data Rec = Rec { uid :: Int, name :: String }

-- Function to update Rec fields
updateRec :: Rec -> Rec

-- basic matching with record data constructor
updateRec (Rec _ []) = Rec 0 "Nobody"

-- dtto with as-pattern at 2nd param
updateRec (Rec idn [email protected]"Alice") = Rec (idn+1) (ns ++ "+1")

-- basic matching by fields values
updateRec Rec {name = "Bob", uid = 42} = Rec (10^6) "SuperBob"

-- Q: how to match by name field and assign it value ?
updateRec Rec {name = "Bob", uid = idn} =
    Rec {uid = (idn+1), name = ("Bob" ++ "+1")}

-- Q: as-pattern works only on the whole record, not on a field
updateRec [email protected](Rec {name = "Bob", uid = idn}) =
    Rec {uid = (idn+1), name = (name rec ++ "+1")}

-- Q: pattern guards do work, but they are a bit clumsy
updateRec Rec {name = uname, uid = idn}
    | uname == "Bob" = Rec {uid = (idn+1), name = (uname ++ "+1")}
    | otherwise = ...

Итак, существует ли какой-то краткий способ сопоставления шаблонов по полю записи и назначать его значение одновременно?

Примечание. Я хотел бы избежать конкретных расширений GHC.

4b9b3361

Ответ 1

Имена полей - это сами шаблоны, поэтому вы можете использовать другой шаблон as-pattern:

updateRec Rec {name = [email protected]"Bob", uid = [email protected]} = ...

Существует не более сжатый способ сделать это, стандартный или с расширениями GHC. Конечно, для такого простого случая вы можете просто опустить привязки и использовать "Bob" и 42 непосредственно в теле функции.