我们如何在 Haskell 中实现模块化
How can we implement modularity in Haskell
在 OOP 中,我们可以使用 'interface' 来要求对象实现某些方法。我认为这可以在 FP Haskell 中实现,但我正在努力获得一个工作示例。
我的目标是创建一个具有一些标准化接口的工具包,以确保项目领域内的兼容性和标准化。
例如,假设我的一个接口定义了一个计算器,以及它必须实现的方法;我们可以要求每个计算器实现 + 和 -。可以有许多不同版本的计算器,它们可以根据需要定义函数。下面是一些类似于 Haskell 的代码尝试。
class Calculator c where
add :: (Float a) => a -> a -> a
sub :: (Float a) => a -> a -> a
instance Calculator DumbCalc where
add a b = 5
sub a b = 3
instance Calculator SmartCalc where
add a b = a + b
sub a b = a - b
通过以这种方式使用接口,我可以创建一个模块化程序,该程序利用没有硬编码行为的组件。在上面的示例中,我可以创建一个包含计算器的程序;以后我可以创建一个流程更高效的新计算器,并在不改变父程序逻辑的情况下实现它。
如何在 Haskell 中实现此设计模式?
如果只有操作而没有类型,就像您的示例一样,您更有可能将其视为数据类型。
data Calculator = Calculator {
add :: Float -> Float -> Float,
sub :: Float -> Float -> Float
}
构建计算器:
dumbCalc :: Calculator
dumbCalc = Calculator (\_ _ -> 5) (\_ _ -> 3)
smartCalc :: Calculator
smartCalc = Calculator (+) (-)
你甚至可以组合计算器,这是模块化的真正秘诀。
-- Uses both calculators and returns whichever result is smaller
leastCalc :: Calculator -> Calculator -> Calculator
leastCalc c1 c2 = Calculator (\x y -> min (add c1 x y) (add c2 x y))
(\x y -> min (sub c1 x y) (sub c2 x y))
而需要计算器的函数会将 Calculator
作为参数,您可以根据需要将其传递给它们。
如果除了函数之外还对类型进行抽象,那么像这样的数据类型模块化将无法正常工作。在那种情况下,正确的工具是 class 类型,因为这通常是类型 class 的要点,我将让您在网上的无数可用资源中阅读这些内容。
在 OOP 中,我们可以使用 'interface' 来要求对象实现某些方法。我认为这可以在 FP Haskell 中实现,但我正在努力获得一个工作示例。
我的目标是创建一个具有一些标准化接口的工具包,以确保项目领域内的兼容性和标准化。
例如,假设我的一个接口定义了一个计算器,以及它必须实现的方法;我们可以要求每个计算器实现 + 和 -。可以有许多不同版本的计算器,它们可以根据需要定义函数。下面是一些类似于 Haskell 的代码尝试。
class Calculator c where
add :: (Float a) => a -> a -> a
sub :: (Float a) => a -> a -> a
instance Calculator DumbCalc where
add a b = 5
sub a b = 3
instance Calculator SmartCalc where
add a b = a + b
sub a b = a - b
通过以这种方式使用接口,我可以创建一个模块化程序,该程序利用没有硬编码行为的组件。在上面的示例中,我可以创建一个包含计算器的程序;以后我可以创建一个流程更高效的新计算器,并在不改变父程序逻辑的情况下实现它。
如何在 Haskell 中实现此设计模式?
如果只有操作而没有类型,就像您的示例一样,您更有可能将其视为数据类型。
data Calculator = Calculator {
add :: Float -> Float -> Float,
sub :: Float -> Float -> Float
}
构建计算器:
dumbCalc :: Calculator
dumbCalc = Calculator (\_ _ -> 5) (\_ _ -> 3)
smartCalc :: Calculator
smartCalc = Calculator (+) (-)
你甚至可以组合计算器,这是模块化的真正秘诀。
-- Uses both calculators and returns whichever result is smaller
leastCalc :: Calculator -> Calculator -> Calculator
leastCalc c1 c2 = Calculator (\x y -> min (add c1 x y) (add c2 x y))
(\x y -> min (sub c1 x y) (sub c2 x y))
而需要计算器的函数会将 Calculator
作为参数,您可以根据需要将其传递给它们。
如果除了函数之外还对类型进行抽象,那么像这样的数据类型模块化将无法正常工作。在那种情况下,正确的工具是 class 类型,因为这通常是类型 class 的要点,我将让您在网上的无数可用资源中阅读这些内容。