Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/xpath/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 科摩纳德很适合为Wumpus世界建模吗?_Haskell_Comonad_Wumpus World - Fatal编程技术网

Haskell 科摩纳德很适合为Wumpus世界建模吗?

Haskell 科摩纳德很适合为Wumpus世界建模吗?,haskell,comonad,wumpus-world,Haskell,Comonad,Wumpus World,我试图找到一个科摩纳德的一些实际应用,我想我会尝试看看我是否可以把经典的乌姆普斯世界表示成一个科摩纳德 我想用这个代码让Wumpus在世界上左右移动,清理脏瓷砖,避免坑。看起来唯一有用的comonad函数是extract(获取当前的tile),移动和清理tile将无法使用extend或replicate 我不确定comonads是否合适,但我看过一篇演讲(),其中comonads被用来在二维矩阵中为光标建模 如果comonad是表示Wumpus世界的一种很好的方式,您能说明我的代码哪里错了吗?如

我试图找到一个科摩纳德的一些实际应用,我想我会尝试看看我是否可以把经典的乌姆普斯世界表示成一个科摩纳德

我想用这个代码让Wumpus在世界上左右移动,清理脏瓷砖,避免坑。看起来唯一有用的comonad函数是extract(获取当前的tile),移动和清理tile将无法使用extend或replicate

我不确定comonads是否合适,但我看过一篇演讲(),其中comonads被用来在二维矩阵中为光标建模

如果comonad是表示Wumpus世界的一种很好的方式,您能说明我的代码哪里错了吗?如果它是错误的,你能建议一个简单的应用comonads吗

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

谢谢

我将把我的一系列评论转移到一个更连贯的答案上

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

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}
我们可以把焦点转移到你所说的
moveLeft
moveRight

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
返回一个新的世界,我们根据“规则”修改了每个聚焦方块

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

ZipList a -> a
如果这让你隐约想起了细胞自动机,你是对的!这与康威的《生活游戏》中的游戏非常相似:简单的上下文相关规则

我们还定义了
duplicate
,它将返回
Listzip
Listzip
,其中每个
Listzip
上的焦点都朝着可能的方向移动

现在我不知道这在Wumpus的上下文中到底有什么用处,你能对你的棋盘上的每个方块做任何统一的变换吗?你能将一个乌姆普斯世界具体化为一个包含所有可能的乌姆普斯世界的乌姆普斯世界吗


在这种情况下,这就是科摩纳德给你的。

我对Wumbus一无所知,所以也许我疯了,但这看起来像拉链,所以你是对的,这是科摩纳德
duplicate
生成了无限多的wumpus世界,在那里我们移动到了每一个可能的地方。Wumpus是彼得·诺维格(Peter Norvig)的书《人工智能:现代方法》中提到的一种生物。Wumpus探索一个寻求奖励(如宝藏)和避免危险(如坑)的世界。鉴于你对副本的解释,我现在不确定我是否需要副本。我想如果我开始尝试寻找世界的最佳遍历,枚举所有遍历可能会非常有用。如果extend对我的Wumpus不是很有帮助,我可以按照你的建议使用拉链,或者继续尝试找到一个简单的comonads应用程序。再次感谢!啊,我明白了:)我认为你的comonad实例是错误的
duplicate
在这里更容易定义
duplicate w=World(repeat moveLeft w)w(repeat moveRight w)
。你的实例不应该因为扩展而丢弃左右方格上的所有内容,我对重复的使用有点困惑。迭代是否有可能工作得更好?这是两个函数的类型:repeat::a->[a],iterate::(a->a)->a->[a]噢,天哪,我错了,我是说iterate:)
ZipList a -> a