【问题标题】:How to access newtype named tuples fields in haskell如何访问haskell中的新类型命名元组字段
【发布时间】:2017-09-05 16:21:23
【问题描述】:

我声明了以下新类型:

newtype Code = Code String deriving (Show)
newtype Name = Name String deriving (Show)
newtype Account = Account (Code, Name) deriving (Show)

所以:

*Main Lib> :t Code
Code :: String -> Code
*Main Lib> :t Name
Name :: String -> Name
*Main Lib> :t Account
Account :: (Code, Name) -> Account

然后我创建了一些实例:

cn = Code "1.1.1"
nn = Name "Land And Buildings"
an = Account (cn, nn)

*Main Lib> an
Account (Code "1.1.1",Name "Land And Buildings")

现在我需要访问变量an 中的Code 字段,例如an.Code 我该怎么做?

使用Data 比使用newtype 更好吗?如果 Haskell 让我创建一个名为 tuple 的新类型,那么我想应该有一种简单的方法来访问里面的元素。

【问题讨论】:

  • data Account = Account { accCode :: Code, accName :: Name } 然后accCode an (注意:“命名元组”是一条记录。)

标签: haskell tuples named newtype


【解决方案1】:

使用data 比使用newtype 更好吗?

嗯,是的...newtype 的全部意义在于给 single 类型一个新名称。它不应该用于构建复合类型。所以,就像 user2407038 建议的那样,做吧

data Account = Account
    { accCode :: Code
    , accName :: Name
    } deriving (Show)

然后你可以简单地使用

*Main Lib> let an = Account (Code "1.1.1") (Name "Land And Buildings")
*Main Lib> accCode an
Code "1.1.1"

也就是说,访问埋在新类型中的元组中的字段也不难,只要你给新类型一个解包器:

newtype Account = Account {getAccount :: (Code, Name)}
   deriving (Show)

然后

*Main Lib> let an = Account (Code "1.1.1", Name "Land And Buildings")
*Main Lib> fst $ getAccount an
Code "1.1.1"

如果你想花哨,还可以使用“20.2世纪记录存取器”,lenses

{-# LANGUAGE TemplateHaskell, FunctionalDependencies #-}
import Lens.Micro
import Lens.Micro.TH

data Account = Account
    { accountCode :: Code
    , accountName :: Name
    } deriving (Show)
makeFields ''Account

然后

*Main Lib> let an = Account (Code "1.1.1") (Name "Land And Buildings")
*Main Lib> an^.code
Code "1.1.1"

【讨论】:

    【解决方案2】:

    您可以使用模式匹配。例如

    case an of
      Account (Code c, Name n) -> "Code " ++ c ++ ", Name " ++ n
    

    或者,在函数定义中你可以直接写

    foo :: Account -> String
    foo  (Account (Code c, Name n)) = "Code " ++ c ++ ", Name " ++ n
    

    使用data 通常会更好。

    data Account = Account Code Name
    -- ...
    case an of
      Account (Code c) (Name n) -> "Code " ++ c ++ ", Name " ++ n
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-11-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-16
      • 2012-06-09
      • 1970-01-01
      相关资源
      最近更新 更多