我想在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