1

Inspired by this two comments on reddit I set out to create a 'lensified entity system'. The basic idea is to have Lens' Entity Value lenses, but although there is Action to create Getters with side effects there is no Setter or a combined LensM' -thing.

I could probably use something like Lens' (Entity, State) Value but I would be interested in how (and if) this could be done in a better way.


Ok ... here is what I got:

{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
import qualified Data.Map    as M
import Control.Monad.State
import Control.Lens

newtype Entity = Entity { unEntity :: Int }
  deriving (Show, Eq, Ord, Enum)

type Address = String
type Name    = String

data EntitySystem = EntitySystem {
  _nextEntity :: Entity,

  _addresses  :: M.Map Entity Address,
  _names      :: M.Map Entity Name
} deriving (Show, Eq, Ord)

makeLenses ''EntitySystem

newEntry :: Name -> Address -> State EntitySystem Entity
newEntry name addr = do
  ne <- nextEntity <<%= succ

  addresses.at ne ?= addr
  names.at ne ?= name

  return ne 

entityAddress e = addresses . at e
entityName e = names . at e

Basically I can use entityAddress entity (which should be of type Entity -> Lens' EntitySystem Address but ghc is complaining). But this doesn't feel 'lensy'. What I am hoping for is something like entityAddress :: Lens' Entity Address where all the stateful handling of the entity system is hidden from the user.

fho
  • 6,787
  • 26
  • 71
  • It would be great if you could state your specific problem and include the code you have produced in your attempts to solve it. As it stands, it's unclear what your question is. – kqr Oct 31 '13 at 06:44

0 Answers0