这只是对丹尼尔的补充思考。看起来你的
Grids
只有
Colors
,对于一个小的“网格”可能不会有太大影响,但相对容易为
Color
创建一个
Unbox
实例。然后,网格将包含一个未装箱的数组。在
Grid.hs
中,您将导入
Data.Vector.Unboxed
而不是
Data.Vector
。这通常出于许多原因要好得多,但是需要在许多定义上放置
Unbox a =>
约束。如果您想制作或“映射”到除
Color
之外的其他类型的网格,则可能会产生后果,除非它具有
Unbox
实例。
下面我只添加了来自
vector-th-unbox
的TH咒语(我最近才了解到该软件包,并借此机会再次测试它)和两个必需的定义。手写它并按照
Data.Vector.Unboxed.Base
中的Bool实例也不难。
{-#LANGUAGE TemplateHaskell, TypeFamilies, MultiParamTypeClasses#-}
module Color where
import Display
import Data.Vector.Unboxed.Deriving
import qualified Data.Vector.Unboxed as V
import qualified Data.Vector.Generic as G
import qualified Data.Vector.Generic.Mutable as M
import Data.Word (Word8)
data Color = Yellow | Red | Green | Blue | Empty
deriving (Show, Eq, Ord, Enum, Bounded)
fromColor :: Color -> Word8
{-# INLINE fromColor #-}
fromColor = fromIntegral . fromEnum
toColor :: Word8 -> Color
{-# INLINE toColor #-}
toColor x | x < 5 = toEnum (fromIntegral x)
toColor _ = Empty
derivingUnbox "Color"
[t| Color -> Word8 |]
[| fromColor |]
[| toColor |]
colorCycle :: Int -> V.Vector Color
colorCycle n = V.unfoldr colorop 0 where
colorop m | m < n = Just (toColor (fromIntegral (m `mod` 5)),m+1)
colorop _ = Nothing
colorBlack = "\ESC[0;30m"
colorRed = "\ESC[0;31m"
colorGreen = "\ESC[0;32m"
colorYellow = "\ESC[0;33m"
colorBlue = "\ESC[0;34m"
instance Display Color where
display Red = colorRed ++ "R" ++ colorBlack
display Green = colorGreen ++ "G" ++ colorBlack
display Yellow = colorYellow ++ "Y" ++ colorBlack
display Blue = colorBlue ++ "B" ++ colorBlack
display Empty = "."
编辑:在版本0.1
之前的vector-th-unbox
中使用了以下模板:
derivingUnbox "Color"
[d| instance Unbox' (Color) Word8 |]
[| fromColor |]
[| toColor |]