记录字段是否可以与某个值匹配并同时分配给参数?

时间:2012-01-30 15:10:18

标签: haskell

在关于Haskell wiki的关于记录模式匹配的相对简短的文本之后,我不确定记录的字段是否可以与某个值匹配并同时分配给参数。

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

-- Function to update Rec's 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 ns@"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's 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 rec@(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扩展。

1 个答案:

答案 0 :(得分:31)

字段名称本身就是模式,因此您可以使用其他 as-pattern

updateRec Rec {name = uname@"Bob", uid = idn@42} = ...

没有更简洁的方法来执行此操作,标准或GHC扩展。当然,对于这样简单的情况,您可以简单地省略绑定并直接在函数体中使用"Bob"42