【发布时间】:2023-03-03 00:32:01
【问题描述】:
我正在尝试在 Haskell 中实现 Ravi Sethi 的 Little Quilt 语言。 Sethi的小被子概览可以在这里看到:http://poj.org/problem?id=3201
以下是我目前拥有的功能:
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
#@
##
当我在原子 a0 上调用 turn 并打印结果原子时,我最终得到以下结果(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 中处理的第一个项目,所以我确信我的代码相当混乱。)
【问题讨论】: