【问题标题】:Ad-hoc Polymorphism vs. Data Constructors in HaskellHaskell 中的临时多态性与数据构造函数
【发布时间】:2023-01-29 07:15:07
【问题描述】:

为一个类型定义不同的数据构造函数,然后使用模式匹配定义函数,这与其他语言中的临时多态性非常相似:

data Shape = Circle Float | Rectangle Float Float
area :: Shape -> Float
area (Circle r) = pi * r^2
area (Rectangle a b) = a*b

使用你可以做的类型类

class Shape s where
    area :: s -> Float

data Circle = Circle Float
instance Shape Circle where
    area (Circle r) = pi * r^2

data Rectangle = Rectangle Float Float
instance Shape Rectangle where
    area (Rectangle a b) = a*b

我看到的第二个优点之一是它可以在不触及现有声明的情况下进行扩展,特别是它可能是您唯一的选择。是否有其他理由更喜欢其中之一?

【问题讨论】:

  • 可能相关:the expression problem。第一个在构造函数上是封闭的(你以后不能添加新的案例)但在它允许的操作上是开放的(你可以在以后轻松地在形状上定义一个新函数)。第二个是对案例开放,但对操作关闭。
  • 第一个的明显优势是,如果你学会比第二个更喜欢它,你会发现自己写出更好的 Haskell 程序。我只是在开玩笑。
  • 谢谢@K.A.Buhr。你是说第一个通常有你的偏好吗?

标签: haskell polymorphism adt typeclass


【解决方案1】:

要使第二种方法起作用,您必须在编译时知道类型 s,而使用第一种方法可以匹配运行时值

data Shape = Circle Float | Rectangle Float Float
area :: Shape -> Float
area (Circle r) = pi * r^2
area (Rectangle a b) = a*b

fromString :: String -> [Float] -> Shape
fromString "circle" (r:_) = Circle r
fromString "rectangle" (a:b:_) = Rectangle a b

areaFromString :: String -> [Float] -> Float
areaFromString s params = area $ fromString s params

Difference between Type Class and Algebraic data types

Scala: difference between a typeclass and an ADT?

Type classes vs algebraic data types?

【讨论】:

    猜你喜欢
    • 2013-08-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-30
    • 1970-01-01
    相关资源
    最近更新 更多