gpt4 book ai didi

Qt : button click => a message should appear in a haskell program

转载 作者:行者123 更新时间:2023-12-04 18:30:09 26 4
gpt4 key购买 nike

我尝试在 ubuntu 上使用 sublime text 3 创建一个在单击按钮时使用 haskell 和 Qt 显示文本的程序。
但显然在定义信号键时存在问题(该键将识别单击按钮时调用的信号)。
此外,很难找到有关 HsQML 的文档,即连接 haskell 和 Qt 的绑定(bind)。

代码:

module Main where

import Graphics.QML
import Control.Concurrent
import Control.Exception
import Data.IORef
import Data.Text (Text)
import qualified Data.Text as T

main :: IO ()
main = do
state <- newIORef $ T.pack ""
skey <- newSignalKey
clazz <- newClass [
defPropertySigRO' "my_label" skey (\_ -> readIORef state),
defMethod' "sayHello" (\obj txt -> do
writeIORef state txt
fireSignal skey obj
return ())]
ctx <- newObject clazz ()
runEngineLoop defaultEngineConfig {
initialDocument = fileDocument "exemple2.qml",
contextObject = Just $ anyObjRef ctx}

错误信息:
Build FAILED

/home/lowley/Documents/haskell/Qt/exemple-2.hs: line 13, column 10:
No instance for (SignalSuffix (IO a0))
arising from a use of `newSignalKey'
The type variable `a0' is ambiguous
Possible fix: add a type signature that fixes these type variable(s)
Note: there is a potential instance available:
instance SignalSuffix (IO ()) -- Defined in `Graphics.QML.Objects'
Possible fix:
add an instance declaration for (SignalSuffix (IO a0))
In a stmt of a 'do' block: skey <- newSignalKey
In the expression:
do { state <- newIORef $ T.pack "";
skey <- newSignalKey;
clazz <- newClass
[defPropertySigRO' "my_label" skey (\ _ -> readIORef state),
defMethod' "sayHello" (\ obj txt -> ...)];
ctx <- newObject clazz ();
.... }
In an equation for `main':
main
= do { state <- newIORef $ T.pack "";
skey <- newSignalKey;
clazz <- newClass
[defPropertySigRO' "my_label" skey (\ _ -> ...), ....];
.... }

解决了!
但我想知道为什么这个程序可以编译而没有上述错误:
module Main where

import Graphics.QML
import Control.Concurrent
import Control.Exception
import Data.IORef
import qualified Data.Text as T

main :: IO ()
main = do
state <- newIORef $ T.pack ""
skey <- newSignalKey
clazz <- newClass [
defPropertySigRO' "result" skey (\_ ->
readIORef state),
defMethod' "factorial" (\obj txt -> do
let n = read $ T.unpack txt :: Integer
writeIORef state $ T.pack "Working..."
fireSignal skey obj
forkIO $ do
let out = T.take 1000 . T.pack . show $ product [1..n]
evaluate out
writeIORef state out
fireSignal skey obj
return ())]
ctx <- newObject clazz ()
runEngineLoop defaultEngineConfig {
initialDocument = fileDocument "factorial2.qml",
contextObject = Just $ anyObjRef ctx}

最佳答案

有错误告诉你 GHC 不知道 newSignalKey 创建的信号是什么类型应该有( newSignalKey :: SignalSuffix p => IO (SignalKey p) 。GHC 不知道 p 应该是什么,因为您没有指定它)。像这样添加显式类型签名:

skey <- newSignalKey :: IO (SignalKey (IO ()))

应该修复您看到的错误。

好的,那么现在为什么它在第二个示例中起作用?要理解这一点,我们必须看看 GHC 知道什么以及它可以确定 skey 的类型。 .

在第一个示例和第二个示例中, skey使用如下:
do
...
fireSignal skey obj
...

因为 fireSignal :: SignalKey p -> ObjRef () -> p (简化型, fireSignal的完整型更通用),GHC知道 p必须是 IO something ,因为它用于 IO something 的上下文中。需要采取行动(作为 IO 中的 do block 的一部分)。不知道是什么 something但是,因为 IO 的返回值从未使用过 action。所以剩下 skey :: SignalKey (IO something) , 并正确报告 something 的错误是模棱两可的(它不知道 something 应该是什么类型)。

然而,在第二个示例中,skey 也用于以下模式:
forkIO $ do
...
fireSignal skey obj

由于 forkIO预计 IO返回 () 类型值的操作, GHC 现在知道 fireSignal skey obj :: IO () (所以在这种情况下,它知道 something 必须是 () )。这意味着 p不再模棱两可了,一定是 IO () .

关于Qt : button click => a message should appear in a haskell program,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35847550/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com