【问题标题】:Mapping function to list/array in haskell?将函数映射到haskell中的列表/数组?
【发布时间】:2019-10-12 13:36:26
【问题描述】:

我正在尝试启动一个随机数组来开始游戏。为此,我创建了一个函数 randomBoard,它返回 '*' 或 ' ' 来表示游戏板上的空间。

我希望能够使用此函数创建游戏板数组。我还不能成功地实例化一个数组。我希望有一种方法可以声明一个大小为 100 的数组并使用我的随机函数来设置每个元素。

这显然行不通,甚至无法编译。我确信它有一些问题,因为我不确定如何在 haskell 中使用 IO 并产生这个结果。非常感谢任何指导...

【问题讨论】:

  • 我将 Game of Life 作为我在 Haskell 中的第一个项目之一。我建议你忘记Data.Array,只使用嵌套的[[Bool]] 作为游戏板。 Data.Array 效率更高,但嵌套列表更容易使用,尤其是对于初学者。此外,使用Bool 作为状态类型比使用Char 更容易,因为Bool 自然映射到单元状态的开/关性质。

标签: arrays list haskell functional-programming


【解决方案1】:

这应该适合你:

import Control.Monad
import System.Random
import Data.Array
import Data.List

randomBoard :: IO Char
randomBoard =
   do
   f1 <- randomIO :: IO Int
   if(f1 `mod` 2) == 0
     then return  '*'
     else return  ' '

boardArray :: IO (Array Int Char)
boardArray = listArray (0, 99) <$> replicateM 100 randomBoard

这是我所做的更改:

  1. 为了清楚起见,我添加了类型签名randomBoard :: IO Char。 (没有它,代码仍然可以工作,因为如果你不提供它,Haskell 会正确推断出这种类型。)
  2. 我将boardArray 的类型更改为使用IO。任何使用 IO 的东西,无论多么间接,都需要在 IO 本身中。
  3. 我将 listArray (0, 100) 更改为 listArray (0, 99),因为前者实际上是 101 个元素。
  4. map randomBoard $ 100 (0,100) 根本不对。要获得几个相同事物的列表,您通常会使用 replicate,但由于您在这里关心的是 IO monad,因此您使用 replicateM 代替。 replicateM 100 randomBoard 给出一个IO [Char],其中包含'*'' ' 的100 个随机元素。
  5. 我添加了一个Control.Monad的导入,这是使用replicateM所需要的。
  6. 我在boardArray 中使用&lt;$&gt;。由于您想用[Char] 调用listArray 并获得Array Int Char,但replicateM 100 randomBoardIO [Char],您不能直接应用参数。使用&lt;$&gt;(也称为fmap)将其应用到IO 的“内部”,从而返回IO (Array Int Char)

【讨论】:

  • 这很棒而且很有意义。太感谢了。跟进问题,将 boardArray 打印到屏幕的最佳方法是什么?以前我使用的是 putStr。
  • @Anon。对于调试,您可以只使用print 并获得类似于array (0,99) [(0,' '),(1,' '),(2,'*'),...,(98,'*'),(99,'*')] 的内容。如果你想要更漂亮的东西,那么带有putStr 的自定义函数可能是你最好的选择。
  • @Anon。 最佳 方法可能是定义您自己的自定义函数showBoard :: Array Int Char -&gt; String,它应该遍历数组并将其转换为String;这也允许您很好地格式化它。然后你可以用putStrLN打印出来。
猜你喜欢
  • 2012-09-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-31
  • 2020-05-16
相关资源
最近更新 更多