我喜欢 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 代码,尽管
v
和 p
在错误的地方。我想加强类型同义词之间的区别,使它们仍然共享底层表示,但在函数应用中不被接受。这可能吗?
最佳答案
您可以制作 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/