I would like to have points in two or three dimensions, so that two-dimensional points and three-dimensional points can share the code, but the compiler can tell them apart. Here is the first attempt.
{-# LANGUAGE DataKinds, GADTs, KindSignatures #-}
data Dimension = D2 | D3
data Point :: Dimension -> * where
Point :: Dimension -> [Int] -> Point d
origin = Point D2 [0, 0]
It still works. Here is a simplified version:
data Point' :: Int -> * where
Point' :: Int -> [Int] -> Point' d
origin' = Point' 2 [0, 0]
It will not compile: ‘Int’ of kind ‘*’ is not promotable
. The data type promotion documentation for GHC 7.10.3 lists various reasons why a type may not be promoted (for example, if it already includes advanced types), but I don’t understand why they exclude Int.
(1) Why does this error occur?
And as a bonus
(2) Is there a reasonable solution or alternative approach? A search shows, for example, fixed-length Vector types in Haskell , but that seems complicated.