将函数应用于类型级别的记录中的所有字段

时间:2016-10-21 07:44:25

标签: haskell types

有没有办法在类型系统中轻松完成以下操作?

xcopy "$(ProjectDir)NewFolder" "$(TargetDir)NewFolder" /E /Y

它基本上是某种容器(仿函数?),它应用于类型级别记录的每个字段。

这个想法是否可以用可扩展的记录库更好地表示?

编辑用例是我们将从UI图层获取data Product = Product { id :: ProductId , name :: Text , sku :: SKU, quantity :: Int , description :: Maybe Text } data Omittable a = Omit | Present a type ProductWithOmittableFields = Omittable Product -- ProductWithOmittableFields is now equivalent to:\ -- -- data ProductWithOmittableFields = ProductWithOmmitableFields { -- id :: Omittable ProductId -- ,name :: Omittable Text -- ,sku : : Omittable SKU -- ,quantity :: Omittable Int -- ,desciption :: Omittable (Maybe Text) -- } ,表示用户已更改的字段集;我们将从数据库中获取ProductWithOmittableFields,我们将合并它们以获取新值Product

1 个答案:

答案 0 :(得分:5)

一种可能的方式:

import Control.Functor.Identity

data Product k = Product {
    id :: k ProductId
  , name :: k Text
  , sku :: k SKU
  , quantity :: k Int
  , description :: k (Maybe Text)
  }

data Omittable a = Omit | Present a
type ProductWithOmittableFields = Product Omittable
type ProductWithRegularFields = Product Identity

示例:

testOmit :: ProductWithOmittableFields
testOmit = Product
     { id = Present someProductId
     , name = Omit
     ... }

testReg :: ProductWithRegularFields
testReg = Product
     { id = Identity someProductId
     , name = Identity someText
     ... }

这种方法只会在常规情况下用Identity包裹每个字段时带来轻微的不便。