我想在Haskell中实现Ravi Sethi的小被子语言。塞西的小被子的概述可以在这里看到:http://poj.org/problem?id=3201Ravi Sethi在Haskell的小被子语言
下面是我迄今为止功能:
import Data.List.Split
rotate :: Int -> [a] -> [a]
rotate n xs = iterate rot xs !! n
where
rot xs = last xs : init xs
turn :: [a] -> [a]
turn x = rotate 2 x
grid :: Int -> [String] -> String
grid n = unlines . map concat . chunksOf n
printAtom :: [String] -> IO()
printAtom x = putStrLn $ grid 2 x
我实现rotate
我turn
功能使用,因为它只是旋转的名单n
时间在左边。
下面是一个例子原子:
let a0 = ["#", "@", "#", "#"]
为了说明原子被如何看待,我将使用printAtom功能:
printAtom a0
#@
##
当我打电话turn
上原子a0
,并打印所得到的原子,我结束以下(turn
应代表90度顺时针转到整个原子):
##
#@
这是第一轮的预期输出。这将对应于面向原子a1
。上原子a1
一转应产生:
@#
##
然而,鉴于turn
功能的制约,它简单地返回原子回a0
状态。为了解决这个问题,我想实现一个功能,newTurn
,使用基于使用chunksOf 2 atom
测试卫士,如下所示:
newTurn :: [a] -> [a]
newTurn x
| chunksOf 2 x == [["#", "@"], ["#", "#"]] = rotate 2 x
| chunksOf 2 x == [["#", "#"], ["#", "@"]] = rotate 1 x
| chunksOf 2 x == [["@", "#"], ["#", "#"]] = rotate 2 x
| chunksOf 2 x == [["#", "#"], ["@", "#"]] = rotate 1 x
我几乎可以肯定,我不理解如何使用警卫,和我绝对知道我不太明白放在函数定义上的类型约束。当我尝试导入newTurn
功能分为ghci中,我得到这个错误:
functions.hs:19:29:
Couldn't match type `a' with `[Char]'
`a' is a rigid type variable bound by
the type signature for newTurn :: [a] -> [a] at functions.hs:18:1
In the expression: "#"
In the expression: ["#", "@"]
In the second argument of `(==)', namely `[["#", "@"], ["#", "#"]]'
我的问题的那冗长的解释之后,基本上就是我需要知道的是我可以改变我的turn
功能代表一个原子顺时针转90度的实际值? (注:这是第一个项目,我已经试过在Haskell来解决,所以我相信我的代码是相当混乱。)
我在定义转为函数时遇到问题。如果我说'let turn = map reverse。转置'并运行':t turn',它给了我'turn :: [[a]] - > [[a]]'。当我使用它作为函数定义文件中的'turn'的类型签名时,出现以下错误:'无法与实际类型a0 - > c0'匹配预期类型[[a]] – mrg1023 2013-05-05 23:58:39
我无法诊断完全没有看到代码,但是这个消息看起来好像你正在传递一个函数来转向。像“转弯”或任何东西。你能否在某个地方发布确切的问题部分? – 2013-05-06 00:03:00
接受你的建议,'turn = map reverse。转置“,它在解释器中传递列表列表时工作。以下是我如何将它定义为一个函数:'turn :: [[a]] - > [[a]] turn xs = map reverse xs。转置xs'。这给了我以前的评论中显示的类型错误。 – mrg1023 2013-05-06 00:14:02