【问题标题】:Haskell - Implementing function which extracts values from an algebraic data typeHaskell - 实现从代数数据类型中提取值的函数
【发布时间】:2016-07-18 04:41:54
【问题描述】:

好吧,作为一个不到一周前刚从面向对象编程中走出来的人,Haskell 有点不知所措——这很可能已经得到解答,但我所有的研究都没有结果。请多多包涵。

假设我有两种代数数据类型:

data Person = Person {name :: String, houseNumber :: Integer, hasBorrowed :: Bool}
data Book   = Book   {borrower :: Person, title :: String}

现在,我知道您可以使用函数从单个代数数据类型中简单地提取值:

getHouseNumber :: Person -> Integer
getHouseNumber (Person _ houseNumber _) = houseNumber

getBorrower :: Book -> Person
getBorrower (Book borrower _) = borrower

我的问题是(我发誓当我得到答案时我会打自己的脑袋)我将如何编写一个函数来直接从书中提取 houseNumber(例如)?换句话说:

getHouseNumberFromBook :: Book -> Integer

提前致谢。

【问题讨论】:

    标签: haskell algebraic-data-types


    【解决方案1】:

    记录的字段实际上是从 ADT 中提取值的函数。所以你有borrower :: Book -> Person 和houseNumber :: Person -> Integer。因此您可以使用组合运算符. 来创建一个新函数houseNumber . borrower :: Book -> Integer。

    【讨论】:

      【解决方案2】:

      首先,这是多余的

      getHouseNumber :: Person -> Integer
      getHouseNumber (Person _ houseNumber _) = houseNumber
      

      因为houseNumber已经自动定义为类似的投影。我们通过在data 声明中使用记录符号来获得这一点。也就是说,Haskell 已经自动定义了

      houseNumber :: Person -> Integer
      houseNumber (Person _ hN _) = hN
      

      并且没有必要复制它。 borrower 和其他字段也是如此。

      关于实际问题,我们可以简单地组合访问器:

      getHouseNumberFromBook :: Book -> Integer
      getHouseNumberFromBook b = houseNumber (borrower b)
      

      或者,更惯用的说法,

      getHouseNumberFromBook :: Book -> Integer
      getHouseNumberFromBook = houseNumber . borrower
      

      这很短,可以直接使用它的定义,而不必定义自定义函数。

      【讨论】:

      • 我明白了。非常感谢。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-24
      • 1970-01-01
      相关资源
      最近更新 更多