[英]Indentation with Let Statements
恐怕我無法充分理解這一點以及let
塊。
如下代碼:
splitWith tf xs
|(null xs) = [[]]
|((length xs) == 1) = [xs]
|otherwise = let tpl = (break tf xs)
x = (fst tpl)
xrst = (snd tpl)
in [[x] ,(splitWith tf (tail xrst))]
創建此語法錯誤:
[1 of 1]編譯Main(ch04_exercise.hs,已解釋)
ch04_exercise.hs:31:26:輸入'x'解析錯誤
這是在我取消Sublime Text 2中的選項卡並放入空格以排列變量之后發生的。 在我這樣做之前,我在x
之后的=符號處遇到了語法錯誤。
知道我在做什么錯嗎?
in
必須與let
或位於同一行:
| otherwise = let (x, xrst) = break tf xs
in [[x], splitWith tf (tail xrst)]
這就是為什么我通常更喜歡將let
放在自己的行上:
| otherwise =
let (x, xrst) = break tf xs
in [[x], splitWith tf (tail xrst)]
您也有不必要的括號,並且可以從某些模式匹配中受益(如上所述)。
編譯器抱怨x = (fst tpl)
因為其左邊緣未與tpl =
。
您僅刪除了某些選項卡。 我將tab放在<------>
並將空格放在.
:
splitWith tf xs
<------><------>|(null xs) = [[]]
<------><------>|((length xs) == 1) = [xs]
<------><------>|otherwise = let tpl = (break tf xs)
.........................x = (fst tpl)
.........................xrst = (snd tpl)
<------><------>.....in [[x] ,(splitWith tf (tail xrst))]
編譯器使用制表符為8的倍數。您認為tpl =
位置與編譯器認為的位置之間為8的差值表明您的編輯器的制表符為4的倍數,如下所示:
splitWith tf xs
<--><-->|(null xs) = [[]]
<--><-->|((length xs) == 1) = [xs]
<--><-->|otherwise = let tpl = (break tf xs)
.........................x = (fst tpl)
.........................xrst = (snd tpl)
<--><-->.....in [[x] ,(splitWith tf (tail xrst))]
這看起來不錯且正確,但不是編譯器所看到的!
如果只使用沒有任何制表符的空格,則不會出現此問題,因為您的編輯器必須以編譯器思考的方式來顯示它。
我的編輯器允許我指定當我按下Tab鍵時,它應該插入一個選項卡將顯示為的空格數,因此我使用它,對於Tabstop為4來說是安全的。如果您的編輯器可以做到這一點,請使用該選項。 (如果沒有,請考慮在編程時使用更聰明的編輯器。)
我的編輯器還具有自動縮進和縮進功能,下一行復制前一行的空格縮進-這樣可以避免此問題。 如果您的編輯器支持,請啟用此功能,因為它可以節省您的工作量,並且您不太可能遇到解析錯誤。 (然后,當我按退格鍵時,我的編輯器將刪除回到先前的縮進級別,這很好。)
幾乎所有編輯者都可以更改標簽的顯示方式。 如果無法使用制表符使用空格,則應將制表符更改為8,因為它與ghc相匹配,並且出現此錯誤的可能性要小得多,但是最好還是使用空格。
這段代碼已編譯(盡管類型錯誤)
我認為從這里學到的一般教訓是,如果在下一行開始let
分配,則更容易排列它們。
splitWith tf xs
|(null xs) = [[]]
|((length xs) == 1) = [xs]
|otherwise = let
tpl = (break tf xs)
x = (fst tpl)
xrst = (snd tpl)
in [[x] ,(splitWith tf (tail xrst))]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.