【发布时间】:2021-06-26 14:58:07
【问题描述】:
我遵循了有关创建基本 Gi-Gtk 应用程序的教程。 现在我想通过将图像的源设置为我从常量字符串列表中随机选择的字符串来响应按钮按下:
{-# LANGUAGE OverloadedLabels #-}
{-# LANGUAGE OverloadedStrings #-}
module Main where
import Data.GI.Base
import System.Random
import qualified GI.Gtk as Gtk
import Control.Monad.Random
akkorde = ["C11.png","C13.png","C69.png","C6.png","C7#11.png","C7#9.png","C7b13.png","C7b9.png","C7.png","C9.png","Cadd9.png","Cj7.png"]
selectAcc:: (MonadRandom m) => m [Char]
selectAcc = do
let n = length akkorde
i <- getRandomR (0, n-1)
return (akkorde !! i)
main :: IO ()
main = do
name <- selectAcc
Gtk.init Nothing
win <- Gtk.windowNew Gtk.WindowTypeToplevel
Gtk.windowSetTitle win "accordtrainer"
Gtk.onWidgetDestroy win Gtk.mainQuit
#resize win 640 480
img <- Gtk.imageNewFromFile ("../" ++ name)
box <- new Gtk.Box [#orientation := Gtk.OrientationVertical ]
#add box img
#add win box
msg <- new Gtk.Label[#label := ( "")]
#packStart box msg True False 10
btn <- new Gtk.Button [#label := "Click me!"]
#packStart box btn False False 10
on btn #clicked ( Gtk.imageSetFromFile img (do { name <- selectAcc; return ("../" ++ name) }))
Gtk.widgetShowAll win
Gtk.main
问题出现在生产线上
on btn #clicked ( Gtk.imageSetFromFile img (do { name <- selectAcc; return ("../" ++ name) }))
我认为 Gtk.imageSetFromFile 需要一个 Maybe[Char] 但目前它只得到 [Char] ghc 说:
app/Main.hs:38:62: error:
• No instance for (MonadRandom Maybe)
arising from a use of ‘selectAcc’
Just 构造函数应该给我一个可能的类型
on btn #clicked ( Gtk.imageSetFromFile img (Just(do { name <- selectAcc; return ("../" ++ name) })))
然后我得到一个类型不匹配
• Couldn't match type ‘[Char]’ with ‘Char’
Expected type: Maybe [Char]
Actual type: Maybe [[Char]]
错误/“修复”链继续
我认为我做的事情根本上是错误的,但我不知道如何以“正确”的方式执行此操作,如果您知道我应该如何编写此行或获取随机选择的字符串的更好方法,请回复
【问题讨论】:
-
Haskell 可能是一门难学的语言,而 monad 无疑是一个微妙的概念——我们都在学习,没有必要难过。
标签: haskell random callback gtk monads