dev*_*ium 3 haskell functional-programming
我正在尝试为我的Point3D类型定义Show :
type Point3D = (Integer, Integer, Integer)
instance Show Point3D where
show (x,y,z) = "<" ++ (show x) ++ "," ++ (show y) ++ "," ++ (show z) ++ ">"
Run Code Online (Sandbox Code Playgroud)
但我必须在sintax中遗漏一些东西,因为我总是收到一个错误:
Run Code Online (Sandbox Code Playgroud)Illegal instance declaration for `Show Point3D' (All instance types must be of the form (T t1 ... tn) where T is not a synonym. Use -XTypeSynonymInstances if you want to disable this.) In the instance declaration for `Show Point3D'
我究竟做错了什么?
type Point3D = (Integer, Integer, Integer)
此代码定义了一个名称:Point3D,它只是一个缩写(Integer,Integer,Integer).在每个上下文中,这两个类型表达式是等价的 而对于后者,已经Prelude定义了一个展示实例.
如果您确实需要3d点的不同字符串表示,则可以使用以下替代方法:
formatPoint :: Point3D -> Stringnewtype Point3D = P (Integer,Integer,Integer)我会推迟启用语言扩展,直到你掌握了Haskell的核心,因为它们有可能是危险或混乱.
newtype解决方案仅在运行时更改值的语法而不更改其内存表示.
作为其他提议的替代方案,您可以将Point3D定义为记录:
data Point3D = Point3D { x :: Int, y :: Int, z :: Int }
instance Show Point3D where
show (Point3D x y z) = concat ["<", show x, ",", show y, ",", show z, ">"]
Run Code Online (Sandbox Code Playgroud)
或者你把tripel放在一个新类型中:
data Point3D = Point3D (Int, Int, Int)
instance Show Point3D where
show (Point3D (x,y,z)) = concat ["<",(show x),",",show y,",",show z,">"]
Run Code Online (Sandbox Code Playgroud)
有关这些版本的优缺点,请参见http://learnyouahaskell.com/making-our-own-types-and-typeclasses.
[编辑]
我了解到最好将最后一个版本写为
newtype Point3D = Point3D (Int, Int, Int)
instance Show Point3D where
show (Point3D (x,y,z)) = concat ["<",(show x),",",show y,",",show z,">"]
Run Code Online (Sandbox Code Playgroud)
该newtype关键字是为正是这种情况作出.优点data是编译器不需要"包装"底层类型,但可以将其保持为内部表示,这既快又"懒惰".
| 归档时间: |
|
| 查看次数: |
2527 次 |
| 最近记录: |