1

reddit に関するこの 2 つのコメントに触発されて、「レンズ化されたエンティティ システム」の作成に着手しました。基本的な考え方はLens' Entity Valueレンズを持つことですが、副作用のある sActionを作成することはありますが、何もないか、組み合わせることはありません。GetterSetterLensM'

おそらく次のようなものを使用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のは、エンティティ システムのすべてのステートフルな処理がユーザーから隠されているようなものです。

4

0 に答える 0