为Haskell数据类型添加可能性(使用记录语法)

Mit*_*ops 5 haskell maybe

看看这个问题的答案:

/sf/answers/2391497601/

我看到它定义了一个用于解析JSON对象的数据类型.

data Address = Address
    { house  :: Integer
    , street :: String
    , city   :: String
    , state  :: Maybe String
    , zip    :: String -- here I change the original, zip codes are strings, they have leading zeros.
    } deriving (Show, Eq)

$(deriveJSON defaultOptions ''Address)
Run Code Online (Sandbox Code Playgroud)

这很有用,但我想知道:如何更改Address数据类型以使所有json字段都可以为空?具体来说,我在状态字段之前看到了一个Maybe,但我想象的是一个更大的数据结构,将所有字段修改为Maybe字段会很繁琐.例如,虽然我/可以/重写上面的内容如下:

data Address = Address
    { house  :: Maybe Integer
    , street :: Maybe String
    , city   :: Maybe String
    , state  :: Maybe String
    , zip    :: Maybe String
    } deriving (Show, Eq)
Run Code Online (Sandbox Code Playgroud)

我可以将什么函数应用于地址数据类型/代码/以实现相同的结果而无需重写所有代码并手动插入Maybes?

Eli*_*ndt 5

正如评论中所讨论的那样,使用仿函数函数可以对原始数据类型进行非常小的更改.

如果你开始

data Address = Address
    { house  :: Integer
    , street :: String
    , city   :: String
    , state  :: Maybe String
    , zip    :: String
    } deriving (Show, Eq)
Run Code Online (Sandbox Code Playgroud)

那相当于

import Data.Functor.Identity

data AddressF f = Address
  { house  :: f Integer 
  , street :: f String
  , city   :: f String
  , state  :: Maybe String
  , zip    :: f String 
  } deriving (Show, Eq)

type Address = AddressF Identity
Run Code Online (Sandbox Code Playgroud)

然后你可以通过写作获得第二个

type Address' = AddressF Maybe
Run Code Online (Sandbox Code Playgroud)

要回到原始定义,您可以编写

toOriginal (AddressF (Identity house) (Identity street) (Identity city) mbState (Identity zip)) = Address house street city mbState zip
Run Code Online (Sandbox Code Playgroud)