haskell - 让 Haskell 区分类型同义词

标签 haskell types type-alias type-synonyms

我喜欢 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在错误的地方。我想加强类型同义词之间的区别,使它们仍然共享底层表示,但在函数应用中不被接受。这可能吗?

最佳答案

您可以制作 Vector phantom type如下:

data Vector t a = Vec a a

data Pos
data Vel

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

现在,您可以定义 Position 的实例和 Velocity就像你通常会做的那样:

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

您还可以使用 DataKinds 使事情更精确。和 KindSignatures :

{-# 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

希望有帮助。

关于haskell - 让 Haskell 区分类型同义词,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49117602/

相关文章:

mysql - MySQL : BigInt(20) vs Int(20) 中的类型

c++ - 如何为类中的模板定义类型别名

c++ - 为什么类型别名决定输出是左值还是右值?

haskell - 努力在servant中连接一对类型类约束单子(monad)

haskell - 二元组的特殊地位是什么?

rest - postWith 是否切换了我的请求的 Content-Type?

list - 为什么任意大小的元组有用? (模板 Haskell)

types - 是否可以为命名类型/结构定义相等性?

c++ - 为什么这些 lambda 被认为是不同的类型?

scala - 如何使用类型别名来定义类型构造函数