OOHaskell ExampleProblem中的范围错误

时间:2012-02-02 11:11:57

标签: haskell

我尝试使用OOHaskell实现矩形问题。

{-# LANGUAGE EmptyDataDecls, DeriveDataTypeable, TemplateHaskell #-}
{-# OPTIONS_GHC -fcontext-stack=100 #-}

module Rectangle where

import OOHaskell

$(label "getLength")
$(label "getWidth")
$(label "incr")
$(label "lengthenBy")
$(label "setLength")
$(label "setWidth")

rectangle length width self
          = do
             lengthRef <- newIORef value
              widthRef <- newIORef width
              return $
              getLength   .=. readIORef lengthRef
          .*. getWidth    .=. readIORef widthRef
          .*. setLength   .=. writeIORef lengthRef
          .*. setWidth    .=. writeIORef widthRef
          .*. lengthenBy  .=. (\dv ->
                 do
                   value <- self # getValue
                   (self # setValue) (value + dv))
          .*. incr        .=. (self # (lengthenBy 1))
          .*. emptyRecord

但是我得到了范围错误。错误消息是

 Rectangle.hs:21:38: Not in scope: `widthRef'
 Rectangle.hs:22:39: Not in scope: `lengthRef'
 Rectangle.hs:23:39: Not in scope: `widthRef'

如何解决错误?

谢谢丹尼尔做到了。但现在我得到的错误是:

The function `lengthenBy' is applied to one argument,
but its type `Proxy LengthenBy' has none
In the second argument of `(#)', namely `(lengthenBy 1)'
In the second argument of `(.=.)', namely `(self # (lengthenBy 1))'
In the first argument of `(.*.)', namely
  `incr .=. (self # (lengthenBy 1))'

1 个答案:

答案 0 :(得分:3)

修复缩进:

      = do
         lengthRef <- newIORef value
          widthRef <- newIORef width

lengthRef的'l'和widthRef的'w'必须位于同一列中。

按原样,它被解析为

= do lengthRef <- newIORef value widthRef <- newIORef ...

但是,我认为应该产生一个解析错误,而不是达到'不在范围'阶段。所以我想这不是你的实际代码,而是一个粘贴故障。

然后:

          return $
          getLength   .=. readIORef lengthRef
      .*. getWidth    .=. readIORef widthRef
      .*. setLength   .=. writeIORef lengthRef
      .*. setWidth    .=. writeIORef widthRef
      .*. lengthenBy  .=. (\dv ->
             do
               value <- self # getValue
               (self # setValue) (value + dv))
      .*. incr        .=. (self # (lengthenBy 1))
      .*. emptyRecord

打破它,.*.缩进小于do-block缩进,因此它被解析为

(do ...
    getLength .=. readIORef lengthRef) .*. getWidth .=. ...

将你想要进入的内容缩进return比封闭的do-block更远。