我考虑过制作一个Direction数据类型,并且我想让每个元素与3d Vector相关联,指示方向的x,y和z值。例如,Up的值为0 1 0.这样做的好方法是什么?
data Direction = None | Up | Right | Down | Left | Above | Below deriving (Enum)
以下是最好的方式吗?:
direction :: Direction -> Point3
direction Up = Point3 0 1 0
direction GameEngine.Right = Point3 1 0 0
direction Down = Point3 0 (-1) 0
direction GameEngine.Left = Point3 (-1) 0 0
direction Above = Point3 0 0 1
direction Below = Point3 0 0 (-1)
direction None = Point3 0 0 0
答案 0 :(得分:1)
根据n.m.的建议,您可以使用数组。
{-# LANGUAGE NoImplicitPrelude #-}
import Data.Array
import Prelude hiding (Left, Right, abs)
data Direction = None | Above | Below | Up | Down | Right | Left deriving (Enum, Ord, Eq, Ix)
-- helper function for finding absolute value of Point3
abs (Point3 x y z) = sqrt $ fromIntegral $ x^2 + y^2 + z^2
-- written long way using do-notation
dir :: Array Direction Point3
dir = listArray (None, Left) states
where
moves = [0, 1, -1]
states :: [Point3]
states = do
x <- moves
y <- moves
z <- moves
let point = Point3 x y z
guard $ abs point <= 1
return point
-- written short way using list-comprehension
dir :: Array Direction Point3
dir = listArray (None,Left) [p |
x <- m, y <- m, z <- m,
let p = Point3 x y z,
abs p <= 1
] where m = [0, 1, -1]
按Direction
索引到数组将为您提供Point3
。
>>> dir ! Above
Point3 0 0 1
这将比一个函数具有轻微的性能优势,因为你将拥有预先构造的Point3
的永久缓存,因此不会导致任何分配。
另一个好处是代码非常整洁!
缺点是它需要Direction为Ord,Eq和Ix。