【问题标题】:haskell : calculated fields in custom data typeshaskell : 自定义数据类型中的计算字段
【发布时间】:2019-05-31 23:21:33
【问题描述】:

是否可以做一些相当于在数据类型中拥有一个字段,该字段是从该数据类型中的其他字段自动计算出来的。例如:

data Grid = Grid
  { x :: Int
  , y :: Int
  , c = (x * y) :: Int
  }

然后 myGrid = Grid 5 6

或者这必须或只能通过Class来完成?

data Grid = Grid
  { x :: Int
  , y :: Int
  }

class Calculated a where
  c :: a -> Int

instance Calculated Grid where
  c g = x g * y g

【问题讨论】:

    标签: haskell


    【解决方案1】:

    没有任何额外的要求,这只是一个函数。

    c :: Grid -> Int
    c g = x g * y g
    

    【讨论】:

    • 为了增强您的示例,请注意 x, y, c :: Grid -> Int 的构造,因为字段名称只是访问器函数。
    【解决方案2】:

    如果出于某种原因,您想预先计算 c 并将其存储在值中,请定义一个智能构造函数。

    data Grid = Grid {x :: Int, y :: Int, c :: Int}
    
    mkGrid :: Int -> Int -> Grid
    mkGrid x y = Grid x y (x * y)
    

    Haskell 中数据和函数的分离比 OO 语言更严格。 data 只定义了一个新类型,而不是对该类型的操作。记录语法只为某些类型x 提供Grid -> x 形式的投影;它不会让你定义更复杂的东西。

    【讨论】:

    • @matthias,还要注意因为 Haskell 是惰性的,所以这里的 x * y 在请求 c 之前不会计算,所以这样做没有时间成本。与将c 定义为裸函数不同,这会保存结果以供将来使用。
    • 除非您隐藏裸构造函数,否则有人可以更新其中一个字段:grid {y=16},但不会更新 c 的值。
    猜你喜欢
    • 1970-01-01
    • 2011-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多