Haskell方法有两个where子句

时间:2014-01-14 20:37:51

标签: haskell syntax-error

我想编写一个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子句中声明?

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

你的缩进是错误的。 changeNew需要与changeOld对齐,而不是与where对齐。