haskell - 接受一个字符数组并返回一个连接字符串的函数。 haskell

标签 haskell functional-programming

呃...与 haskell 斗争。尝试实现 Conway 的 GOL 并创建随机游戏板。这就是我所在的位置。

我有一个函数可以随机化数组中的每个方 block ,还有一个函数可以使用随机化函数创建一个字符数组来表示我的游戏板。

我现在正在尝试创建一个函数:showBoard,它遍历数组并将每个字符连接成一个字符串,我可以在我的 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

我花了一个小时试图调整它并不断遇到类型问题。我什至无法让这 block 板打印 x.x 请帮忙。

最佳答案

几个问题:

  1. 不可能编写接受 IO 的函数的东西并用它来返回不在 IO 中的东西.更改 showBoard采取Array Int Char没有 IO包装器,并删除 doreturn
  2. 因为你的数组是从零开始的,改变arr ! iarr ! (i - 1) .
  3. arr包含 Char s,不是 String s,所以使用 []而不是 ()围绕它的索引使其成为 String .
  4. 自从我们制作了showBoard取一个没有 IO 的值, 使用 <-main获得我们需要的内在值(value)。

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

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已实现,尽管有效,但效率特别低。你应该避免做看起来像 x ++ [y] 的事情递归地,因为它的速度是二次方的。此外,看起来您的函数打印的元素从末尾开始一直向下到 0,而不是从 0 开始一直到最后。这是它的一个新版本,它同时修复了这两个问题:

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

使用 :在可能的情况下比总是使用 ++ 更有效.

您可以通过不使用 showBoard 来进一步简化完全没有,并使用 elems (来自 Data.Array )改为:

main :: IO ()
main = do
    randomArray <- boardArray
    let board = elems randomArray
    putStr board

关于haskell - 接受一个字符数组并返回一个连接字符串的函数。 haskell ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56318633/

相关文章:

haskell - 在 Haskell 中生成二维网格

haskell - 突然yesod tls异常,DecodeError

haskell - 这个惰性评估示例背后的魔力是什么?

macos - 我需要一种无需在 Mac 上安装即可运行 Haskell 代码的方法

Haskell 复杂函数组合

functional-programming - StandardML 中的 y 组合器

scala - 重构一个小型 Scala 函数

haskell - 定义类型类时类型变量不在范围内

java - 编写增量整数供应商

ruby - 如何使用 ruby​​ 中的函数式编程范例重写在动态编程中查找最大连续子数组?