该函数接受一个char数组并返回一个串联的字符串。哈斯克尔

时间:2019-05-27 01:22:41

标签: haskell functional-programming

U ...与haskell斗争。尝试实施Conway的GOL并创建一个随机游戏板。这是我的位置。

我有一个随机化数组中每个方块的功能,以及一个使用随机化功能代表游戏板来创建字符阵列的功能。

我现在尝试创建一个函数:showBoard,该函数遍历数组并将每个char连接到一个字符串,该字符串可以在我的main中打印出来。

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

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


showBoard :: IO (Array Int Char) -> Int -> String -> String
showBoard arr i str = do
    if i > 0
       then showBoard arr (i-1) (str ++ (arr ! i))
       else return str

main :: IO ()
main = 
let board = showBoard boardArray 100 ""
    in
        do
            putStr board

我花了一个小时来尝试解决这个问题,并不断遇到类型问题。我什至无法得到此板来打印x.x,请帮忙。

1 个答案:

答案 0 :(得分:4)

一些问题:

  1. 不可能编写一个接受IO内容并使用它返回IO中不包含的内容的函数。更改showBoard以使用没有Array Int Char包装器的IO,然后从其中删除doreturn
  2. 由于您的数组基于零,因此将arr ! i更改为arr ! (i - 1)
  3. arr包含Char,而不包含String,因此在其索引周围使用[]代替()使其成为{{ 1}}。
  4. 由于我们使String的值不包含showBoard,因此请在IO中使用<-来获取所需的内部值。

这是所有这些更改的结果:

main

顺便说一句,import System.Random import Control.Monad import Data.Array import Data.List 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 showBoard :: Array Int Char -> Int -> String -> String showBoard arr i str = if i > 0 then showBoard arr (i-1) (str ++ [arr ! (i - 1)]) else str main :: IO () main = do randomArray <- boardArray let board = showBoard randomArray 100 "" putStr board 的实现方式虽然有效,但效率特别低。您应避免递归地执行类似showBoard的操作,因为它的平方速度很慢。同样,看起来您的函数会从结尾开始打印并向下打印到0,而不是从0开始一直打印到结尾。这是它的新版本,可同时修复这两个问题:

x ++ [y]

在可能的情况下使用showBoard :: Array Int Char -> Int -> String -> String showBoard arr i str = if i > 0 then showBoard arr (i-1) ((arr ! (i - 1)) : str) else str 比总是使用:更有效。

您甚至可以完全不使用++,而使用elems(来自showBoard)来简化操作:

Data.Array