mhwombat
mhwombat

Reputation: 8136

Type families and type constructors

I'm working on replacing multi-parameter type classes in some of my libraries with type synonyms. Everything was going great until I needed to work with a type constructor. The last two lines of this code won't compile.

{-# LANGUAGE TypeFamilies, FlexibleContexts #-}

import qualified Data.Map as M

-- | A regular arrangement of tiles.
class Eq (Index g) => Grid g where
  type Index g
  -- | Returns the indices of all tiles in a grid.
  indices :: g -> [Index g]
  -- plus other functions


-- | A map from tile positions in a grid to values. 
data LGridMap g v = LGridMap { toGrid :: g, toMap :: M.Map (Index g) v }

instance Grid g => Grid (LGridMap g v) where
  type Index (LGridMap g v) = Index g
  indices = indices . toGrid


class GridMap gm where
  type BaseGrid gm
  type Value gm

instance GridMap (LGridMap g v) where
  BaseGrid gm = g -- line 26
  Value = v       -- line 27

The compilation error I get is:

../Amy.hs:26:3:
    Pattern bindings (except simple variables) not allowed in instance declarations
      BaseGrid gm = g

../Amy.hs:27:3:
    Pattern bindings (except simple variables) not allowed in instance declarations
      Value = v
Failed, modules loaded: none.

Is there a better way to define LGridMap? Is there a way to specify that LGridMap is an instance of GridMap?

Upvotes: 2

Views: 754

Answers (1)

dave4420
dave4420

Reputation: 47062

Should it not be this?

instance GridMap (LGridMap g v) where
  type BaseGrid (LGridMap g v) = g
  type Value (LGridMap g v) = v

Upvotes: 5

Related Questions