我使用函数xmlWidget
将comboBox
转换为castTocomboBox
创建了一个组合框,现在我想获取活动项的文本或索引。问题是,如果我使用comboBoxGetActive
函数,它会返回IO Int
结果,我需要知道如何获取Int
值。我试着读一下monads,所以我能理解在这种情况下我们能做些什么,但我似乎并不理解。我很感激能得到的所有帮助。我应该提一下,我使用Glade
和gtk2hs
。
答案 0 :(得分:27)
作为一般规则,你写这样的东西:
do
x <- somethingThatReturnsIO
somethingElseThatReturnsIO $ pureFunction x
除了在IO Monad中执行其他操作外,无法从“IO Int”中获取“Int”。
以monad术语表示,上述代码可以进入
somethingThatReturnsIO >>= (\x -> somethingElseThatReturnsIO $ pureFunction x)
“&gt;&gt; =”运算符(发音为“bind”)具有将“IO Int”转换为“Int”的魔力,但它拒绝将Int直接赋予您。它只会将该值作为参数传递给另一个函数,并且该函数必须在“IO”中返回另一个值。冥想IO monad的绑定类型几分钟,你可能会受到启发:
>>= :: IO a -> (a -> IO b) -> IO b
第一个参数是“comboBoxGetActive”返回的初始“IO Int”值。第二个是一个函数,它获取Int值并将其转换为其他IO值。因此,您可以处理Int,但这样做的结果永远不会从IO monad中逃脱。
(当然有臭名昭着的“unsafePerformIO”,但在您的知识水平上,您可能会确定如果您使用它,那么您做错了。)
(实际上,desugaring相当复杂,允许失败的模式匹配。但你可以假装我写的是真的)
答案 1 :(得分:11)
嗯,有unsafePerformIO:http://haskell.org/ghc/docs/6.12.1/html/libraries/base-4.2.0.0/System-IO-Unsafe.html#v:unsafePerformIO
(如果您想知道如何找到此方法:转到http://www.haskell.org/hoogle并搜索您需要的签名,此处IO a -> a
)
那就是说,你可能听说过“IO在IO中会发生什么”。并且非常有充分的理由(只需阅读unsafePerformIO的文档)。所以你很可能遇到设计问题,但为了从经验丰富的Haskellers那里获得帮助(我当然不是),你需要更详细地描述你的问题。
答案 2 :(得分:3)
要了解这些类型的步骤,请先查看“可能”和“列表”:
data Maybe a = Nothing | Just a
data [a] = [] | a : [a]
(可能)与( a )的类型不同,如(可能的Int )与( Int <)不同/强>)。 类型的示例值( Maybe Int )是 只是5 和没什么。
( a )列表可以写为( [] a )和( [a] )。 ( [Int] )的示例值为 [1,7,42] 和 [] 。
现在,( IO a )与( a )不同:它是一个输入/输出计算,用于计算类型的值(的一强>)。换句话说:它是一个脚本或程序,必须执行它才能生成类型值( a )。 ( IO String )的示例是 getLine ,它从标准输入读取一行文本。
现在,comboBoxGetActive的类型是:
comboBoxGetActive :: ComboBoxClass self => self -> IO Int
这意味着,comboBoxGetActive是一个函数( - &gt; ),它映射自任何具有类型类ComboBoxClass实例的类型(基本类型类与java-interfaces类似) )到( IO Int )。每次使用此类型的相同输入值( self )(无论该类型是什么)评估此函数( - &gt; )时,它会产生相同的值:它始终是类型的值( IO Int ),这意味着它始终是相同的脚本。但是当您在不同时间执行相同的脚本时,它可能会生成不同的类型值( Int )。
程序的主要功能是类型( IO()),这意味着编译器和运行时系统会将您使用此函数式语言编程的方程式计算为main的值,这将在你启动程序后立即执行。