【问题标题】:Are comonads a good fit for modeling the Wumpus world?Comonads 是否适合为 Wumpus 世界建模?
【发布时间】:2014-06-06 03:20:46
【问题描述】:

我正在尝试找到一些comonad 的实际应用,我想我会尝试看看我是否可以将经典的Wumpus 世界表示为comonad。

我想使用此代码让 Wumpus 在世界中左右移动并清理脏瓷砖并避开坑。似乎唯一有用的comonad函数是extract(获取当前图块),而移动和清理图块将无法使用扩展或复制。

我不确定comonads 是否合适,但我看过一个演讲(Dominic Orchard: A Notation for Comonads),其中comonads 用于对二维矩阵中的光标进行建模。

如果comonad 是代表Wumpus 世界的好方法,您能否说明我的代码哪里出错了?如果错了,您能否建议一个简单的共单子应用程序?

module Wumpus where

-- Incomplete model of a world inhabited by a Wumpus who likes a nice
-- tidy world but does not like falling in pits.

import Control.Comonad

-- The Wumpus world is made up of tiles that can be in one of three
-- states.
data Tile = Clean | Dirty | Pit
  deriving (Show, Eq)

-- The Wumpus world is a one dimensional array partitioned into three
-- values: the tiles to the left of the Wumpus, the tile occupied by
-- the Wumpus, and the tiles to the right of the Wumpus.
data World a = World [a] a [a]
  deriving (Show, Eq)

-- Applies a function to every tile in the world
instance Functor World where
  fmap f (World as b cs) = World (fmap f as) (f b) (fmap f cs)

-- The Wumpus world is a Comonad
instance Comonad World where
  -- get the part of the world the Wumpus currently occupies
  extract (World _ b _) = b
  -- not sure what this means in the Wumpus world.  This type checks
  -- but does not make sense to me.
  extend f w@(World as b cs) = World (map world as) (f w) (map world cs)
      where world v = f (World [] v [])

-- returns a world in which the Wumpus has either 1) moved one tile to
-- the left or 2) stayed in the same place if the Wumpus could not move
-- to the left.
moveLeft :: World a -> World a
moveLeft w@(World [] _ _) = w
moveLeft (World as b cs) = World (init as) (last as) (b:cs)

-- returns a world in which the Wumpus has either 1) moved one tile to
-- the right or 2) stayed in the same place if the Wumpus could not move
-- to the right.
moveRight :: World a -> World a
moveRight w@(World _ _ []) = w
moveRight (World as b cs) = World (as ++ [b]) (head cs) (tail cs)

initWorld = World [Dirty, Clean, Dirty] Dirty [Clean, Dirty, Pit]

-- cleans the current tile
cleanTile :: Tile -> Tile
cleanTile Dirty = Clean
cleanTile t = t

谢谢!

【问题讨论】:

  • 我对 Wumbus 一无所知,所以也许我疯了,但这看起来像一个拉链,所以你说得对,它是一个共生体。 duplicate 生成了无数个 wumpus 世界,我们已经移动到了每一个可能的方格
  • 谢谢 jozefg。 Wumpus 是 Peter Norvig(等人)的著作《人工智能:一种现代方法》中提到的一种生物。 Wumpus 探索了一个寻求奖励(例如宝藏)和避免危险(例如坑)的世界。鉴于您对重复的解释,我不确定我目前是否需要重复。我想如果我开始尝试找到世界的最佳遍历,枚举所有遍历可能会非常方便。如果 extend 对我的 Wumpus 不是很有帮助,我可能会按照你的建议使用拉链,或者继续尝试找到一个简单的 comonads 应用程序。再次感谢!
  • 啊,我明白了 :) 而且我认为你的comonad 实例是错误的.. duplicate 在这里更容易定义 duplicate w = World (repeat moveLeft w) w (repeate moveRight w)。您的实例不应该丢弃左右正方形上的所有东西以进行扩展
  • 我对重复的使用有点困惑。迭代是否有机会更好地工作?下面是两个函数的类型:repeat :: a -> [a], iterate :: (a -> a) -> a -> [a]
  • 哦,我的错,我的意思是迭代:)

标签: haskell comonad wumpus-world


【解决方案1】:

我会将我的一串 cmets 移到一个更连贯的答案..

你所拥有的实际上是一个“拉链”,特别是一个列表的拉链

data ListZip a = ListZip {lefts   :: [a]
                         ,focus   ::  a
                         ,rights  :: [a]}

我们可以将非空列表转换为ListZip

toZip :: [a] -> Maybe (ListZip a)
toZip (x:xs) = Just $ ListZip [] x xs
toZip  _     = Nothing

像所有拉链一样,ListZip 有一个重点,我们可以在这个重点领域开展工作

modifyFocus :: (a -> a) -> ListZip a -> ListZip a
modifyFocus f z = z{focus = f $ focus z}

我们可以将焦点转移到你所说的 moveLeftmoveRight

moveLeft, moveRight :: ListZip a -> ListZip a

moveLeft  (ListZip (x:xs) y ys) = ListZip xs x (y : ys)
moveRight (ListZip xs x (y:ys)) = ListZip (x : xs) y ys

现在就像所有的拉链一样,ListZip 是一个comonad!

extract提取焦点,或者当前占据的方格

instance Comonad ListZip where
  extract = focus

extend返回一个新世界,我们根据“规则”修改了每个焦点方块。

  extend f w = ListZip (moving moveLeft) (f w) (moving moveRight)
    where moving i = map f $ iterate i w

在这种情况下,规则是一个函数

ZipList a -> a

如果这让您隐约想起了元胞自动机,那就对了!这与 Conway 的 Game of Life 等游戏的运作方式非常相似:简单的上下文相关规则。

我们还定义了duplicate,它将返回ListZipListzip,其中焦点已在每个ListZip 上朝任何可能的方向移动。

现在我不知道这在 Wumpus 的上下文中到底有什么用处,您可以对板上的每个方格进行任何统一的转换吗?您能否从能够将 Wumpus 世界具体化为所有可能的 Wumpus 世界的 Wumpus 世界中受益?

这就是comonads在这种情况下给你的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-03-19
    • 2020-10-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-06
    • 2017-03-31
    • 1970-01-01
    相关资源
    最近更新 更多