我最近在使用threepenny-gui时遇到了一个错误
,它通过将符号中的模式匹配的代码更改为<-与let符号的模式匹配来解决.
在这两种模式匹配形式之间进行转换时,我是否应该期望改变行为?
具体如下代码:
在IO monad中:
Just events <- Map.lookup elid <$> readMVar sElementEvents
Run Code Online (Sandbox Code Playgroud)
改为:
mevents <- Map.lookup elid <$> readMVar sElementEvents
let Just events = mevents
Run Code Online (Sandbox Code Playgroud)
这是一个提交的链接,为我解决了问题:https: //github.com/Davorak/threepenny-gui/commit/fbf6cbe25875fafdc64f7a111ddebf485b45143b
其他平台细节:os:10.8.5 ghc:7.6.3
编辑:添加了这个发生在IO monad的事实
我在Haskell中使用一个名为Threepenny-GUI的图形库.在这个库中,main函数返回一个UImonad对象.这让我很头疼,因为当我尝试将IO值解压缩到局部变量时,我收到错误抱怨不同的monad类型.
这是我的问题的一个例子.这是标准主函数的略微修改版本,由Threepenny-GUI的代码示例给出:
main :: IO ()
main = startGUI defaultConfig setup
setup :: Window -> UI ()
setup w = do
labelsAndValues <- shuffle [1..10]
shuffle :: [Int] -> IO [Int]
shuffle [] = return []
shuffle xs = do randomPosition <- getStdRandom (randomR (0, length xs - 1))
let (left, (a:right)) = splitAt randomPosition xs
fmap (a:) (shuffle (left ++ right))
Run Code Online (Sandbox Code Playgroud)
请注意第五行:
labelsAndValues <- shuffle [1..10]
Run Code Online (Sandbox Code Playgroud)
返回以下错误:
Couldn't match type ‘IO’ with ‘UI’ …Run Code Online (Sandbox Code Playgroud) 首先是一个免责声明,我可能完全误解了三便器的工作方式,因为我对Haskell的知识不那么先进,所以我的断言就是一粒盐.:-)
在我看来,一些组合器不是纯粹的,例如
stepper :: MonadIO m => a -> Event a -> m (Behavior a)
Run Code Online (Sandbox Code Playgroud)
步进器是否必然在某种类型的IO monad上运行(因此它不是纯粹的),或者我在这里误解了什么?第二个问题,如果那些组合器确实不合适,那为什么呢?对我来说,这使得构建事件图的代码比反应性香蕉更好,因为必须使用IO monad而不是纯粹的普通函数.代码似乎变得比在反应性香蕉中变得更复杂.
更可怕的是,valueChange似乎是纯粹的类型
valueChange :: Element -> Event String
Run Code Online (Sandbox Code Playgroud)
但它实际上是在内部使用unsafeMapIO,它实际上是在做隐藏的IO吗?同样,我可能会误解某些东西,但这不是Haskell中最严重的罪吗?这也令人困惑,我无法从类型中看出回叫注册是如何发生的......这在我之前从未发生在Haskell中......是否这样做是为了让用户不得不处理Frameworks monad?
我真希望我没有走进死胡同。我有一个行为,它给出当前选择的颜色和当前鼠标坐标,然后在单击鼠标时执行任务。该任务涉及查看列表,然后更新该列表中的值,以便稍后检索。我可以“存储”所选颜色这一事实让我希望可以以类似的方式存储列表。我正处于死胡同,不知道如何解决这个问题。非常感谢一些帮助。
\n-- There is a Blue button and a Red button on our UI. Whichever\n-- button was clicked last is our current color selection.\ncolorRedSelected = const ColorRed <$ UI.click redButton\ncolorBlueSelected = const ColorBlue <$ UI.click blueButton\n\n-- we combine both the above Events to create a new one that tells us the current selected color\ncolorSelected = unionWith const colorRedSelected colorBlueSelected\n\n-- accumulate values for our Behaviour, starting with ColorRed selected by default\ncolorMode \xc2\xa0 \xc2\xa0 \xc2\xa0 <- accumB ColorRed modeEvent\n\n-- create a …Run Code Online (Sandbox Code Playgroud) 简单来说,我正在寻找一种显示方式Behaviour (UI Element).
我的实际用例是显示一个可以过滤的表.所以我有一个函数tableElement :: String -> UI Element(String参数是过滤条件)和一个输入字段filterElement :: Element,它代表过滤器.对我来说,最自然的方式就是这样:
bFilter <- stepper "" (valueChange filterElement)
displaySomehow (fmap tableElement bFilter)
Run Code Online (Sandbox Code Playgroud)
这也是在Elm中完成的方式.
到目前为止sink children,我发现的最接近的是使用,但这只适用于[Element]而不适用[UI Element].另外,我必须使用虚拟元素作为父元素或与其余子元素混在一起.
用threepenny-gui实现类似这样的东西最好的方法是什么?
我想达到的目标:
每次用户单击画布时,从该单击中获取鼠标坐标以构造 aPoint x y并将此状态存储在 a 中[Point],以便在稍后用户单击按钮时我可以将其[Point]用作某些功能的输入。
我所做的:
我已经定义了一个Point数据类型,有一个像这样的单值构造函数:
data Point = Point {
x :: Int,
y :: Int
} deriving (Show, Eq)
Run Code Online (Sandbox Code Playgroud)
我已经设置了一个三便士UI(monad?)来定义用户界面,一个简单的400 x 400 canvas和一个button:
import qualified Graphics.UI.Threepenny as UI
import Graphics.UI.Threepenny.Core
import Control.Monad
canvasSize = 400
setup :: Window -> UI ()
setup window = do
return window # set title "Haskell GUI"
canvas <- UI.canvas
# set UI.height canvasSize
# set …Run Code Online (Sandbox Code Playgroud) 我得到了一个与该库一起使用的蛇版本threepenny-gui,但我不喜欢这样的事实:我显式调用newEvent并addStateUpdate手动而不是完全基于事件定义行为,例如:
(updates, addUpdate) <- liftIO newEvent
managerB <- accumB initialManager updates
on UI.tick timer $ \_ -> addUpdate $ \manager -> manager'
Run Code Online (Sandbox Code Playgroud)
相比:
managerB <- accumB initialManager $
UI.tick timer $> \manager -> manager'
Run Code Online (Sandbox Code Playgroud)
IIUC 第二个是更惯用的 FRP,因为它定义了实际事件的行为,而不是创建代理事件来代理更新。但是当我进行此更改时,它会导致以下两个问题之一:
managerB首先定义(使用 RecursiveDo 访问timer,其定义如下),则根本不会渲染任何内容managerB到末尾(使用 RecursiveDo 从 DOM 元素访问managerB),第一次按下箭头键时的初始移动会滞后,并且帧会以不稳定的方式呈现。难道我做错了什么?我应该用什么惯用的方式来构建这些事件/行为?
代码差异在这里:https ://github.com/brandonchinn178/snake/compare/inline-event-handlers
亲爱的Haskell社区我已经写了我的第一个gui应用程序,并决定使用threepenny-gui这样做.
任务是搜索给定文件夹中的文件以查找匹配项,并提供打开这些文件的链接.另外我做了很好的解析和渲染功能,因为文件(大多数)都有一个特殊的格式.
但是现在我偶然发现了一个问题 - href="file://localhost/home/user/folder/file.pdf"出于安全原因,大多数浏览器禁止通过打开本地文件的链接,这是我理解并发现完全合理的.
href="./file.pdf"当程序和文件在同一个文件夹中时,我试图使用,这似乎也不起作用.
整个应用程序的代码可以在github/epsilonhalbe上找到,我在一个文件夹中运行它并通过浏览器访问它localhost:100000
我有一个关于 Threepenny-Gui 与 StateT 交互的问题。考虑这个玩具程序,每次单击按钮时,都会在列表中添加一个“Hi”项:
import Control.Monad
import Control.Monad.State
import qualified Graphics.UI.Threepenny as UI
import Graphics.UI.Threepenny.Core hiding (get)
main :: IO ()
main = startGUI defaultConfig setup
setup :: Window -> UI ()
setup w = void $ do
return w # set title "Ciao"
buttonAndList <- mkButtonAndList
getBody w #+ map element buttonAndList
mkButtonAndList :: UI [Element]
mkButtonAndList = do
myButton <- UI.button # set text "Click me!"
myList <- UI.ul
on UI.click myButton $ \_ -> element myList …Run Code Online (Sandbox Code Playgroud) 这是一个后续的问题这个.我在Haskell中使用一个名为Threepenny-GUI的图形库.在这个库中,main函数返回一个UImonad对象.我正在尝试执行一个简单的打印命令但没有成功.什么是正确的解决方案来启用打印以进行调试.
码:
main :: IO ()
main = startGUI defaultConfig setup
setup :: Window -> UI ()
setup w = do
print "debug message 1 "
Run Code Online (Sandbox Code Playgroud)
错误:
Couldn't match type ‘IO’ with ‘UI’
Expected type: UI ()
Actual type: IO ()
In a stmt of a 'do' block: print "labels and values "
Run Code Online (Sandbox Code Playgroud) 我想使用Threepenny-gui开发一个新的 Haskell 项目。
\n我做的第一件事是通过创建一个堆栈项目$ stack new threepennydemo。从这里,这里,我做了以下事情:
#\xc2\xa0extra-deps: []\nRun Code Online (Sandbox Code Playgroud)\n到
\nextra-deps:\n - threepenny-gui-0.9.0.0\nRun Code Online (Sandbox Code Playgroud)\nlibrary\n exposed-modules:\n Lib\n other-modules:\n Paths_threepennydemo\n hs-source-dirs:\n src\n build-depends:\n base >=4.7 && <5\n default-language: Haskell2010\n\nexecutable threepennydemo-exe\n main-is: Main.hs\n other-modules:\n Paths_threepennydemo\n hs-source-dirs:\n app\n ghc-options: -threaded -rtsopts -with-rtsopts=-N\n build-depends:\n base >=4.7 && <5\n , threepennydemo\n default-language: Haskell2010\n\ntest-suite threepennydemo-test\n type: exitcode-stdio-1.0\n main-is: Spec.hs\n other-modules:\n Paths_threepennydemo\n hs-source-dirs:\n test\n ghc-options: …Run Code Online (Sandbox Code Playgroud) 我想试试hasckell的threepenny-gui包.所以我跑了
cabal install threepenny-gui
Run Code Online (Sandbox Code Playgroud)
......没有任何问题
所以我尝试了以下示例:
module Main where
import qualified Graphics.UI.Threepenny as UI
import Graphics.UI.Threepenny.Core
main :: IO ()
main = do
startGUI defaultConfig setup
setup :: Window -> IO ()
setup window = do
return window # set UI.title "Hello World!"
button <- UI.button # set UI.text "Click me!"
getBody window #+ [element button]
on UI.click button $ const $ do
element button # set UI.text "I have been clicked!"
Run Code Online (Sandbox Code Playgroud)
但是我得到了关于类型的错误:
threePennyHelloWorld.hs:8:28:
Couldn't match type `IO ()' with …Run Code Online (Sandbox Code Playgroud) haskell ×12
threepenny-gui ×12
frp ×4
monads ×2
cabal ×1
do-notation ×1
html ×1
localhost ×1
state-monad ×1