2014-01-14 44 views
2

我想寫它有兩個where子句Haskell的功能,但我從編譯器收到此錯誤:哈斯克爾方法有兩個where子句

語法錯誤輸入(意外符號「changeNew」)

changeItem oPos nPos (x:xs) 
         | oPos < nPos = changeOld 
         | oPos > nPos = changeNew 
         | otherwise = x : changeItem (oPos-1) (nPos-1) xs 
         where changeOld 
          | oPos == 0 = (xs !! nPos) : changeItem x (nPos-1) xs 
          | nPos == 0 = oPos : xs 
          | otherwise = x : changeItem (oPos-1) (nPos-1) xs 
         changeNew 
          | oPos == 0 = nPos : xs 
          | nPos == 0 = (xs !! oPos) : changeItem (oPos-1) x xs 
          | otherwise = x : changeItem (oPos-1) (nPos-1) xs 

什麼是錯的代碼?爲什麼我不能在where子句中聲明兩個?

+0

嘗試將您的選項卡轉換爲代碼中的空格(如果它是一個體面的編輯器,您的編輯器應該支持此操作)。 Haskell中的選項卡經常會導致類似的問題。你必須把'changeNew'換成'changeOld',這對空間來說更容易。 – bheklilr

+1

其他人給你答案。我想我會給你一個建議:到目前爲止,不要縮回guardItem的警衛。代碼正在脫離世界的邊緣。 – dfeuer

回答

10

的名字在where條款需要在左側排隊被定義,這樣

changeItem oPos nPos (x:xs) 
         | oPos < nPos = changeOld 
         | oPos > nPos = changeNew 
         | otherwise = x : changeItem (oPos-1) (nPos-1) xs 
         where 
          changeOld 
          | oPos == 0 = (xs !! nPos) : changeItem x (nPos-1) xs 
          | nPos == 0 = oPos : xs 
          | otherwise = x : changeItem (oPos-1) (nPos-1) xs 
          changeNew 
          | oPos == 0 = nPos : xs 
          | nPos == 0 = (xs !! oPos) : changeItem (oPos-1) x xs 
          | otherwise = x : changeItem (oPos-1) (nPos-1) xs 

雖然更「正常」的Haskell風格,將一切向左移動,以防止你的代碼進入右下角。

changeItem oPos nPos (x:xs) 
    | oPos < nPos = changeOld 
    | oPos > nPos = changeNew 
    | otherwise = x : changeItem (oPos-1) (nPos-1) xs 
where 
    changeOld 
    | oPos == 0 = (xs !! nPos) : changeItem x (nPos-1) xs 
    | nPos == 0 = oPos : xs 
    | otherwise = x : changeItem (oPos-1) (nPos-1) xs 
    changeNew 
    | oPos == 0 = nPos : xs 
    | nPos == 0 = (xs !! oPos) : changeItem (oPos-1) x xs 
    | otherwise = x : changeItem (oPos-1) (nPos-1) xs 
0

您的縮進是錯誤的。 changeNew需要與changeOld對齊,而不是與where對齊。