【发布时间】:2018-08-11 08:06:55
【问题描述】:
我正在学习 Haskell,遇到了这个问题。 不使用存在类型,我们如何将下面的 OOP 伪代码翻译成 Haskell?不是在 Haskell 中模拟 OOP 概念的方法,而是正确的 Haskell 方法。
class MetricQuery { ... }
abstract class Metric[T] {
def computeValue(q: MetricQuery): T
}
class LinkClicksMetric extends Metric[Int] { ... }
class ButtonClicksMetric extends Metric[Int] { ... }
class PostCommentsMetric extends Metric[Int] { ... }
...
query: MetricQuery = ...
metrics: List[Metric[Int]] = ...
results: List[Int] = metrics.map(\x -> x.computeValue(query))
我的一个想法是,我们不使用类型类,而是简单地将 computeValue 函数设为 Haskell 数据类型的字段:
data MetricQuery = ...
data Metric a = Metric {
computeValue :: MetricQuery -> a
}
linkClicksMetric :: Metric Int
linkClicksMetric = Metric { computeValue = \q -> ... }
buttonClicksMetric :: Metric Int
buttonClicksMetric = Metric { computeValue = \q -> ... }
results =
let query = ...
metrics = ...
in fmap (\x -> computeValue x query) metrics
我认为这可行,只是不确定这是否是“正确”的 Haskell 方式。
另外,我不知道如何使用特定指标存储其他数据(即 OO 术语中的成员变量)。我尝试使用状态类型参数化度量类型构造函数,但这会导致不同的特定度量类型(例如Metric Int State1 与Metric Int State1)。一个想法是创建 data MetricState = ... | ... | ... 并将 state :: MetricState 设置为 Metric 的字段,这样每个特定指标都可以定义自己的状态类型。
【问题讨论】:
-
在 Java 中什么是具有单一方法的对象,在 Haskell 中只是一个函数。
-
@n.m.它可能携带的状态如何?具有多个方法的对象呢?
-
Haskell 有部分功能应用,例如
f = (+) 5定义了一个函数f,其中一个参数带有一个内部状态(单个值 5)。当应用于参数时,比如f x,它返回5 + x。 ((+)是 两个 参数的函数)。 -
至于几种方法,表示这样一个对象最简单的方法就是函数的记录。
标签: haskell functional-programming