看看这个问题的答案:
我看到它定义了一个用于解析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?
正如评论中所讨论的那样,使用仿函数函数可以对原始数据类型进行非常小的更改.
如果你开始
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)