这是一项家庭作业,我真的在最后一点苦苦挣扎。我们正在Haskell写“战舰”,除了一些关于功能语言的一般讲座之外,我们没有太多可继续的事情。没有教科书等。我已经被提到了几次LYAH,那里有很好的东西,但它似乎没有针对这个特定问题的建议。
对于上下文,我会将我的整个Battleship代码放上,这样你就可以看到我后来引用的定义。
--A
data Row = A | B | C | D | E | F | G | H | I | J deriving (Enum, Ord, Show, Bounded, Eq, Read)
data Column = One | Two | Three | Four | Five | Six | Seven | Eight | Nine | Ten deriving (Enum, Ord, Show, Bounded, Eq, Read)
--B
data Address = Address Row Column deriving (Show, Read, Eq)
--C
data Cell = Cell Address Bool deriving (Show, Read, Eq)
--D
data Ship = Ship [Cell] deriving (Show, Eq)
--E
data Ships = Ships [Ship] deriving (Show, Eq)
--F
toAddress r c = Address (toEnum r) (toEnum c)
--G
toRowColumn (Address aRow aColumn) = (fromEnum aRow, fromEnum aColumn)
--H
allAddressesA = [ Address row column | row <- [A .. J], column <- [One .. Ten]]
--I
allAddressesB = [toAddress row column | row <- [0 .. 9], column <- [0 .. 9]]
--J
targetShip (Ship ship) (Address row column)
| Address == map (\list -> (head Address Bool)) s
--K
targetShips [(Ships)] toAddress //TODO
--L
isSunk Ship ship
|ship [] = true
|otherwise foldl
--M
areSunk [(Ships)] //TODO
现在我也会发布具体的作业说明,以便在我需要帮助时没有任何沟通错误:
(j)编写接受Ship和目标的函数targetShip 地址作为其两个参数。如果船上有一个带目标的单元格 地址,该单元格被标记为沉没。这艘船的更新版本是 回。如果船舶为空,则返回空船。 (1张地图, 116个字符)
(k)编写接受列表的函数targetShips 船舶和目标地址作为其两个参数。它试图 将每艘船沉入船舶清单。它返回更新船只的清单。 如果没有船只,则返回空列表。 (1幅地图,86 人物)
(l)编写一个接受Ship作为其的函数isSunk 参数。如果船是空船,则返回true。除此以外, 如果所有单元格都标记为沉没,则返回true。 (1折,78个字符)
(m)写一个函数areSunk接受一个Ships列表作为它 参数。如果没有船只,则返回true。否则,返回 如果所有船舶都标记为沉没,则为true。 (1折,78个字符)
所以我在这里特别努力的是这些最后的4.解决方案(A - I)我已经测试过,它们的工作正常。
对于初学者,我们需要知道如何引用单元格值...分别为Address和Bool。
我们不能写更多功能。
我会假设你需要更多关于特定问题的解释,所以我会密切关注。任何有关最后四个问题从哪里开始的提示将不胜感激。提前谢谢你...我现在将回到我的文本编辑器,并试图解决这个问题。
答案 0 :(得分:3)
(j)编写一个函数targetShip,它接受Ship和目标地址作为其两个参数。如果船上有一个具有目标地址的单元格,则该单元格被标记为沉没。返回船的更新版本。如果船舶为空,则返回空船。 (1张地图,116个字符)
功能targetShip
,
参数Ship and a target address as its two parameters
产生Ship is returned
这些信息足以记下您的函数的类型注释。
targetShip :: Ship -> Address -> Ship
targetShip (Ship ship) (Address row column)
If the ship is empty, the empty Ship is returned
并且船只是列表或列表是空列表[]或带有尾部的头部,然后
targetShip :: Ship -> Address -> Ship
targetShip (Ship []) (Address row column) = Ship []
targetShip (Ship (x:xs)) (Address row column) =
现在是困难的部分
If the ship has a cell with the target address, that cell is marked sunk
船是一个单元格列表,然后我需要为每个单元格(定义船只)检查当前单元格的地址是否与函数参数提供的地址相同。
好的,让我们的模式匹配出现的头x
。
targetShip :: Ship -> Address -> Ship
targetShip (Ship []) (Address row column) = Ship []
targetShip (Ship (x:xs)) (Address row column) =
if x ...
OMG,我做不到,因为没有帮助功能,我需要更多信息。我需要将x的结构出现在我的模式匹配中,就像这样,
targetShip (Ship ((Cell address bool):xs)) (Address row column) =
再一次,OMG,我不能做更多,好的重做同样的事情,在我的模式匹配中更具表现力。
targetShip (Ship ((Cell (Address shipRow shipColumn) bool):xs)) (Address row column) =
现在可以,我可以做到 我会让你完成它。
祝你好运答案 1 :(得分:1)
J:你必须退回一艘船,船上有一个取决于地址的新清单。
targetShip (Ship oldCells) address = Ship newCells
where newCells = ...
f cell =
你如何找出新细胞?该任务建议使用地图。因此,您可以将函数f
映射到oldCells
。 f
应该做什么?如果它获得的地址与targetShip的参数具有相同的地址,则它应返回具有相同地址但具有凹陷状态的新单元格。否则它应该只返回作为参数给出的单元格。
K:一旦你获得目标工作,应该很容易。按照建议使用map
。
foldr
和foldl
,它们都通过采用带有两个参数的函数,累加器和当前元素,并将列表一次折叠到累加器中,使用给定的累加器。让我向您展示一些实际的折叠示例。
foldl (\acc x -> acc + x) 0 [1,2,3] -> 6 -- starting accumulator of 0
foldl (+) 0 [1,2,3] -> 6 -- same thing as above
foldl (&&) True [True, True, True] -> True -- folding booleans
foldl (&&) True [True, False, True] -> False -- more boolean folding
foldl (&&) True [] -> True -- folding an empty list yields the initial accumulator
foldl (\acc x -> acc && (x > 5)) True [6,7,8] -> True -- complex folding function.
使用最后一个函数,我希望你能看到,如何解决问题L和J.否则看看匿名函数中的模式匹配,并查看LYAH中的folding。