Haskell:做块,最后一个语句必须是表达式

时间:2015-01-05 15:42:40

标签: haskell expression

我想知道右键或左键单击按钮时的区别。我写了以下代码:

import Graphics.UI.Gtk
import Control.Monad.IO.Class 

--main::IO()
main = do
    initGUI

window <- windowNew

    button <- buttonNewWithLabel "button"

    on button buttonPressEvent (tryEvent (do button <- eventButton

                                             liftIO (extrafunctie button)
                                             ))                                         
    containerAdd window button

    onDestroy window mainQuit

    widgetShowAll window

    mainGUI

extrafunctie b = if (RightButton == b) 
                 then putStrLn "True"
                 else putStrLn "False"

我收到以下错误:

jolien@jolien-VirtualBox:~/Documenten/haskell$ ghc --make test.hs -o test
[1 of 1] Compiling Main             ( test.hs, test.o )

test.hs:9:50:
    The last statement in a 'do' block must be an expression
      button <- eventButton liftIO (extrafunctie button)

我看了我的缩进,这是正确的。有人知道解决方案吗?

3 个答案:

答案 0 :(得分:1)

你的缩进很糟糕,这就是问题所在。你需要替换它:

on button buttonPressEvent (tryEvent (do button <- eventButton

                                         liftIO (extrafunctie button)
                                         ))  

使用:

on button buttonPressEvent $
    tryEvent $ do 
        button <- eventButton
        liftIO (extrafunctie button)

您也可以将extrafunctie功能替换为:

extrafunctie b = print (RightButton == b)

答案 1 :(得分:0)

以下是编译器如何看待您的代码,其中tabstops为8个字符间隔。 我会将标签显示为-------|,空格显示为.

>....import Graphics.UI.Gtk
>....import Control.Monad.IO.Class 
>
>....--main::IO()
>....main = do
>....-|initGUI

>...--|window <- windowNew

>....-|button <- buttonNewWithLabel "button"

>....-|on button buttonPressEvent (tryEvent (do button <- eventButton

>....-|------|------|------|------|------|------|------|------|------|..----|.liftIO (extrafunctie button)
>....-|------|------|------|------|------|------|------|------|------|.....))                                           
>....-|containerAdd window button

>....-|onDestroy window mainQuit

>....-|widgetShowAll window

>....-|mainGUI
>
>....extrafunctie b = if (RightButton == b) 
>....-|------|------|------|.then putStrLn "True"
>....-|------|------|------|.else putStrLn "False"

正如您所看到的,编译器会在右侧进一步看到liftIO (extrafunctie位。 如果您使用空格来布置您的工作,则不会发生这种情况:

>    import Graphics.UI.Gtk
>    import Control.Monad.IO.Class 
>
>    --main::IO()
>    main = do
>      initGUI
>      window <- windowNew
>      button <- buttonNewWithLabel "button"
>      on button buttonPressEvent (tryEvent (do button <- eventButton
>                                               liftIO (extrafunctie button)
>                                               ))                                             
>      containerAdd window button
>      onDestroy window mainQuit
>      widgetShowAll window
>      mainGUI
>
>    extrafunctie b = if (RightButton == b) 
>                  then putStrLn "True"
>                  else putStrLn "False"

如果你坚持空间,这是最简单的。更改编辑器的设置。

如果你只使用没有任何标签的空格,你就不会遇到这个问题,因为你的编辑必须按照编译器对它的看法来展示它。

我的编辑器让我指定当我按Tab键时,它应该插入一个选项卡显示的空格数,所以我使用它,这对于一个4的tabstop是安全的。如果你的编辑器可以这样做,请使用那个选择。 (如果没有,请考虑在编程时获得一个更聪明的编辑器。)

我的编辑器也有自动缩进和outdent,其中下一行复制前一行的空白缩进 - 这避免了问题。如果您的编辑器支持它,请启用它,因为它可以节省您的工作量,并且您不太可能得到解析错误。 (当我按下退格键时,我的编辑器会删除回到上一级别的缩进,这很不错。)

几乎所有编辑都可以更改显示标签的方式。如果你不能让它为标签使用空格,你应该将tabstop改为8,因为它匹配ghc,你不太可能得到这个错误,但你最好还是使用空格。 / p>

答案 2 :(得分:-1)

以下是怎样的?

import Graphics.UI.Gtk
import Control.Monad.IO.Class 

--main::IO()
main = do
  initGUI
  window <- windowNew
  button <- buttonNewWithLabel "button"
  on button buttonPressEvent (tryEvent (do button <- eventButton
                                         liftIO (extrafunctie button)
                                         ))                                      
  containerAdd window button
  onDestroy window mainQuit
  widgetShowAll window
  mainGUI

extrafunctie b = if (RightButton == b) 
           then putStrLn "True"
           else putStrLn "False"