我正在学习Haskell,而且我必须打印一个Snakes and Ladders游戏。开始时,我正在尝试打印电路板,这就是我所做的。
import Data.List
aRow :: Int -> String
aRow n = "+" ++ take (4*n) (intercalate "" (repeat "---+")) ++ "\n|" ++ take (4*n) (intercalate "" (repeat " |")) ++ "\n"
board :: Int -> Int -> IO()
board 1 y = putStrLn (aRow y)
我想要另一个董事会实例,它需要参数x和y
board x y = putStrLn (aRow y)
board (x-1) y
我知道我不能只调用这样的多个语句,但是任何人都可以提供一些有关我如何能够接受这一点的见解吗?我想用参数'y'调用aRow并执行'x'次。
感谢。
另外:当我拨打电话板1时,我将其作为输出:
板1 5
+ - + - + - + - + - +
| | | | | |
答案 0 :(得分:7)
我认为最干净的方法是创建电路板而不进行任何IO
,然后最后只使用IO
将其打印出来。
您可以使用concat
和replicate
来实现此目标:
board :: Int -> Int -> String
board x y = concat (replicate y (aRow x))
你可能在底部错过了一条线,但我会让你弄清楚这一点!
顺便说一下,take (4*n) (intercalate "" (repeat "---+"))
与concat (replicate n "---+")
相同,因此您可以将aRow
写为:
aRow :: Int -> String
aRow n = '+' : concat (replicate n "---+")
++ "\n|" ++ concat (replicate n " |")
++ "\n"
修改:我会使用unlines :: [String] -> String
在多行上连接多个String
:
aRow :: Int -> String
aRow n = unlines
[ '+' : concat (replicate n "---+")
, '|' : concat (replicate n " |")
]
答案 1 :(得分:2)
因此,您希望执行IO ()
,然后执行另一个IO ()
操作。他们一起也应该是IO ()
。因此,您正在寻找具有签名IO () -> IO () -> IO ()
的组合子。你可以ask Hoogle about this ...亲爱的,这会产生很多无关紧要的结果。但也the right one, namely
(>>) :: Monad m => m a -> m b -> m b
您的IO () -> IO () -> IO ()
是此签名的特例,通过设置m ~ IO
和a ~ b ~ ()
获得。所以,你可以写
board x y = putStrLn (aRow y)
>> board (x-1) y
因为这些 monadic排序运算符经常在Haskell中使用,所以它具有特殊的语法 - 糖语法,即
board x y = do
putStrLn (aRow y)
board (x-1) y
好的,这样可行,但它并不是真正的惯用语。带有“计数器变量”x
的手动递归“循环”很笨拙,而且容易出错(你需要获得正确的初始,终止和步进条件)。实际上,您所做的就是连续执行x
次行动。所以你真的对Int -> IO () -> IO ()
感兴趣。再次ask Hoogle;这次the right result提前了一点......
replicateM_ :: Applicative m => Int -> m a -> m ()
所以
board :: Int -> Int -> IO ()
board x y = replicateM_ x $ putStrLn (aRow y)
更好的是,正如Boomerang所言,完全是为了避免IO循环。
答案 2 :(得分:2)
你只需要对两个monadic函数进行排序:
board x y = putStrLn (aRow y) >> board (x - 1) y
或使用do
表示法
board x y = do
putStrLn (aRow y)
board (x - 1) y
请注意x == 0
是一个更自然的基础案例:
board 0 y = return ()
board x y = do
putStrLn (aRow y)
board (x - 1) (aRow y)
尽管如此,请参阅Boomerang的答案,了解更为惯用的写作方式。