如何在haskell中访问名为tuples字段的newtype

nes*_*iax 4 haskell tuples named newtype

我声明了以下新类型:

newtype Code = Code String deriving (Show)
newtype Name = Name String deriving (Show)
newtype Account = Account (Code, Name) deriving (Show)
Run Code Online (Sandbox Code Playgroud)

所以:

*Main Lib> :t Code
Code :: String -> Code
*Main Lib> :t Name
Name :: String -> Name
*Main Lib> :t Account
Account :: (Code, Name) -> Account
Run Code Online (Sandbox Code Playgroud)

然后我创建了一些实例:

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")
Run Code Online (Sandbox Code Playgroud)

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

是否更好地使用Data而不是newtype?如果Haskell允许我创建一个名为tuple的新类型,那么我想应该有一种简单的方法来访问里面的元素.

lef*_*out 8

是否更好地使用data而不是newtype

嗯,是的...重点newtype是给一个单一的新名称.它不应该用于构建复合类型.所以,像user2407038建议的那样,制作它

data Account = Account
    { accCode :: Code
    , accName :: Name
    } deriving (Show)
Run Code Online (Sandbox Code Playgroud)

然后你可以简单地使用

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

也就是说,如果你给newtype一个unwrapper,那么访问一个埋在newtype中的元组中的字段也不难:

newtype Account = Account {getAccount :: (Code, Name)}
   deriving (Show)
Run Code Online (Sandbox Code Playgroud)

然后

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

如果你想要花哨,你也可以使用"20.2世纪记录存取器",镜头:

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

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

然后

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