【问题标题】:Haskell UI do clause, how to print?Haskell UI do 子句,如何打印?
【发布时间】:2015-09-08 09:57:22
【问题描述】:

这是this 的后续问题。我在 Haskell 中使用了一个名为 Threepenny-GUI 的图形库。在这个库中,主函数返回一个UI monad 对象。我正在尝试执行一个简单的打印命令,但没有成功。什么是启用打印以进行调试的正确解决方法。

代码:

main :: IO ()
main = startGUI defaultConfig setup

setup :: Window -> UI ()
setup w = do

print "debug message 1 "

错误:

Couldn't match type ‘IO’ with ‘UI’
Expected type: UI ()
  Actual type: IO ()
In a stmt of a 'do' block: print "labels and values "

【问题讨论】:

  • 您的do 块必须只包含一个monad(即UIIO,但不能同时包含两者)。如果你想在 Haskell 中调试,调试器可能会很有用。
  • 那我如何支持打印呢?
  • 您应该尝试在代码块中保留 Haskell 代码的格式。您问题中的代码存在解析错误,因为print 之前没有空格。有帮助的一件事是 StackOverflow 快捷键 Ctrl-k。如果您突出显示问题或答案中的文本块并按 Ctrl-k,它将每行缩进 4 个空格。据我所知,这个快捷方式并没有在任何地方正式记录,但它很方便。

标签: haskell monads threepenny-gui


【解决方案1】:

根据类型,这是liftIO 的一个很好的应用程序。 liftIO 有一个 MonadIO m => IO a -> m a 类型,所以可以这样使用:

liftIO (print "debug message 1")

该表达式的类型可以是UI (),因为UIMonadIO 的一个实例,而print "debug message 1" 的类型是IO ()

【讨论】:

  • 那么应用liftio的唯一原因是包装未使用的打印结果,这样它就不会对我大喊大叫了?
  • @vondip 否。未使用的输出是()。 IO 操作的类型为IO ()。在 Haskell 中,IO 操作是一等值,因此值 print "debug message 1" 是打印该消息的 IO 操作,而不是 ()
  • 再举一个例子,如果你想从stdin里面读入StringUI,你可以写:do ... ; someInput <- liftIO getLine ; ...(注意getLine的类型是IO String)。 liftIO 提升 IO 操作。
  • 顺便说一句:如果您想打印到控制台以响应按钮单击或其他一些 UI 事件,而不是在 GUI 初始化期间,您可以使用 onEventon .在这种情况下,liftIO 将出现在传递给onEvent/on(a -> UI void) 回调中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-18
  • 1970-01-01
  • 1970-01-01
  • 2021-04-29
  • 1970-01-01
相关资源
最近更新 更多