受reddit 上这 两条评论的启发,我着手创建一个“强化实体系统”。基本的想法是有Lens' Entity Value
镜头,但是虽然有Action
创造Getter
有副作用的s,但没有Setter
或组合的LensM'
东西。
我可能会使用类似的东西,Lens' (Entity, State) Value
但我会对如何(以及是否)可以以更好的方式完成感兴趣。
好的......这是我得到的:
{-# 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
基本上我可以使用entityAddress entity
(应该是类型Entity -> Lens' EntitySystem Address
,但 ghc 抱怨)。但这并不让人感到“不敏感”。我希望的是entityAddress :: Lens' Entity Address
,实体系统的所有状态处理都对用户隐藏。