如何访问 haskell 中的新类型命名元组字段
How to access newtype named tuples fields in haskell
我声明以下新类型:
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 让我创建一个名为元组的新类型,那么我想应该有一种简单的方法来访问其中的元素。
Is it better to use data
instead of a newtype
?
嗯,是的...newtype
的全部意义在于给单个 类型一个新名称。它不应该用于构建复合类型。所以,按照 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"
您可以使用模式匹配。例如
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
我声明以下新类型:
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 让我创建一个名为元组的新类型,那么我想应该有一种简单的方法来访问其中的元素。
Is it better to use
data
instead of anewtype
?
嗯,是的...newtype
的全部意义在于给单个 类型一个新名称。它不应该用于构建复合类型。所以,按照 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"
您可以使用模式匹配。例如
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