【问题标题】:Getting Haskell to Distinguish Type Synonyms让 Haskell 区分类型同义词
【发布时间】:2023-03-18 20:43:01
【问题描述】:

我喜欢 Haskell 类型同义词的想法,因为它们允许区分共享底层表示的抽象数据类型。不幸的是,当我写一个像

这样的程序时
data Vector a = Vec a a

-- Some definitions here about (+) and (*) for Vector ...

type Position = Vector Float
type Velocity = Vector Float
type Time = Float

step :: Position -> Velocity -> Time -> Position
step p v dt = p + v*dt

p :: Position
p = Vec 0.0 0.0

v :: Velocity
v = Vec 1.0 1.0

p' = step v p 0.01

这是完全有效的 Haskell 代码,尽管 vp 出现在错误的位置。我想加强类型同义词之间的区别,以便它们仍然共享底层表示,但在功能应用程序中不被接受为彼此。这可能吗?

【问题讨论】:

  • 你应该使用 newtype 而不是 lf type
  • @Shersh 要回答问题,请使用“发布您的答案”按钮,评论用于请求澄清或建议对问题进行改进。
  • @Shersh 这不是借口。部分挑战是编写适当的个获得投票的cmets。
  • @amalloy,有时可以在几秒钟内写下评论(如 Shersh 的)并帮助 OP。但在那个时候,一个人可能无法写出正确的答案。如果将上述评论作为答案提出,则可能不会受到好评。
  • @dfeuer 是的,我知道这就是想法,但我不认为这是值得鼓励的事情。可以在七个字的评论中轻松回答的问题也很快就会得到真正的答案 - 在这种情况下,在评论“答案”之后仅两分钟就得到了彻底的答案。我宁愿我们得到一个真正的答案,并且存在这样的评论不鼓励发布答案,因为“OP 已经得到帮助”。

标签: haskell types type-alias type-synonyms


【解决方案1】:

您可以将Vector 设为phantom type,如下所示:

data Vector t a = Vec a a

data Pos
data Vel

type Position = Vector Pos Float
type Velocity = Vector Vel Float

现在,您可以像往常一样定义PositionVelocity 的实例:

p :: Position
p = Vec 0.0 0.0

v :: Velocity
v = Vec 1.0 1.0

但是,它不允许您互换使用它们:

type Time = Float

step :: Position -> Velocity -> Time -> Position
step p v dt = p + v*dt -- you might have to change this definition

p' = step v p 0.01 -- won't compile

您还可以使用DataKindsKindSignatures 使事情更精确:

{-# LANGUAGE DataKinds #-}
{-# LANGUAGE KindSignatures #-}

data VectorType = Pos | Vel

data Vector (t :: VectorType) a = Vec a a

type Position = Vector Pos Float
type Velocity = Vector Vel Float

希望对您有所帮助。

【讨论】:

  • 我认为现在说类型构造函数有一个或多个幻像参数比说它是幻像类型更常见。
  • 我相信我看到了类似的 C++ 解决方案。不幸的是没有我希望的那么优雅(特别是因为它不能应用于导入库中定义的数据类型),但仍然有用。
【解决方案2】:

newtype 可能是您想要的,或者至少是我们所拥有的最好的。与type 一样,它为现有类型定义了一个新名称,并且运行时表示将是相同的。不像type(但像data),它们在类型检查时被认为是不同的,并且有一个新的数据构造函数。

所以你可能有这样的代码:

newtype Position = Position (Vector Float)
p :: Position
p = Position (Vec 0 0)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-01
    • 1970-01-01
    • 2015-09-08
    • 2014-09-09
    相关资源
    最近更新 更多