记录的字段可以与某个值匹配并同时分配给一个参数? [英] Can record's field be matched with some value and assigned to a parameter at the same time?

查看:120
本文介绍了记录的字段可以与某个值匹配并同时分配给一个参数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

   - 样本记录类型
数据Rec = Rec {uid :: Int,name :: String}

- 函数更新Rec的字段
updateRec :: Rec - > Rec

- 与记录数据构造函数进行基本匹配
updateRec(Rec _ [])= Rec 0Nobody

- dtto with as-pattern at第二个参数
updateRec(Rec idn ns @Alice)= Rec(idn + 1)(ns +++1)

- 通过字段值进行基本匹配
updateRec Rec {name =Bob,uid = 42} = Rec(10 ^ 6)SuperBob

- 问:如何通过名称字段匹配并赋值?
updateRec Rec {name =Bob,uid = idn} =
Rec {uid =(idn + 1),name =(Bob+++1)}

- Q:as-pattern只适用于整个记录,不适用于字段
updateRec rec @(Rec {name =Bob,uid = idn})=
Rec { uid =(idn + 1),name =(name rec +++1)}

- Q:模式守卫可以工作,但它们有点笨拙
updateRec Rec {name = uname,uid = idn}
| uname ==Bob= Rec {uid =(idn + 1),name =(uname +++1)}
|否则= ...

那么是否有一些简洁的方式来按照记录的字段进行模式匹配并赋值



注意:我想避免具体的GHC扩展。

解决方案



<$> p $ p $ updateRec Rec {name = uname @Bob,uid = idn @ 42} = ...

没有更简洁的方式来做到这一点,标准或GHC扩展。当然,对于这样简单的情况,您可以简单地省略绑定并使用Bob 42 直接在函数体中。


After a relatively brief text on Haskell wiki about pattern matching of records, I'm not sure if record's field can be matched with some value and assigned to a parameter at the same time.

-- 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 = ...

So is there some concise way to pattern match by record's field and assign its value at the same time?

Note: I would like to avoid specific GHC's extensions.

解决方案

The field names are patterns themselves, so you can use another as-pattern:

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

There isn't any more concise way to do this, standard or with GHC extensions. Of course, for a case as simple as this, you could simply omit the bindings and use "Bob" and 42 directly in the function body.

这篇关于记录的字段可以与某个值匹配并同时分配给一个参数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆