Haskell / XMonad:表达式的自然类型是什么?在一系列操作之后必须完成某些事情? [英] Haskell/XMonad: What is the natural type for expressing that something must be done after a sequence of actions?

查看:120
本文介绍了Haskell / XMonad:表达式的自然类型是什么?在一系列操作之后必须完成某些事情?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一系列 X()动作,在这些动作中可能会抓住某些按钮(并且之后不会释放)。为了防止按钮被抓住,我因此必须在最后取消所有按钮,例如:

  action1> ;> action2>> action3>> ungrabAllButtons 

我希望将此需求编码为一个类型,以便 action1 action2 action3 只有在按钮之后未被取消时才能使用。也就是说,即使 action1 action2 ,确实是 X()操作,我希望它们不能用于此类,除非它们被包装在如下内容中(借用关键字借用Python的):

  withGrabbedButtons :: ??? - > X()
withGrabbedButtons action =
action>> ungrabAllButtons


- 正确; complete_action不会让鼠标抓住
complete_action :: X()
complete_action = withGrabbedButtons(action1>> action2>> action3)

- 类型错误!
erroneous_single_action :: X()
erroneous_single_action = action1

- 类型错误!
erroneous_action :: X()
erroneous_action = action1>> action2>> action3

这样人们不会意外地使用 action1 action2 action3 作为 X()行动,同时忘记随后取消按钮。

Haskell的类型系统有可能吗?事先感谢。

解决方案

您需要做的是为 X 使用 GeneralizedNewtypeDiving 来获得一个免费的 Monad 实例:

  { - #LANGUAGE GeneralizedNewtypeDivingiving# - } 

newtype XNeedsCleanup a = FromX {toX :: X a}
派生(Functor,Applicative,Monad )

因为 XNeedsCleanup 是monad,所以可以将多个 XNeedsCleanup 绑定在一起,如 action1>>所示。 action2>> action3 例子;这将在 FromX 包装器中将所有包装的 X 动作绑定在一起。但是,您将无法将产生的操作与 X 操作绑定;这就是 withGrabbedButtons 的来源:

  withGrabbedButtons :: XNeedsCleanup() - > X()
withGrabbedButtons action = toX action>> ungrabAllButtons

如果您不导出 toX unwrapper,您的客户无法通过 withGrabbedButtons 使用 XNeedsCleanup 值。但是如果他们有能力使用任意 X 动作,那么他们可以导入任何你用来定义你的各种动作的东西,并且可以将它们重新实现为原始 X 操作。所以只是为了明确:这不是安全导向的安全,只是防止人们意外地忘记清理。


I have a sequence of X() actions during which certain buttons might be grabbed (and not released afterwards). In order to prevent buttons from ending up grabbed, I therefore have to ungrab every button at the end, for example:

action1 >> action2 >> action3 >> ungrabAllButtons

I wish to encode this requirement as a type, so that action1, action2, action3 can only be used if the buttons are ungrabbed afterwards. That is, even though action1, action2, are really X() actions, I would like them not to be usable as such unless they are wrapped in something like the following (borrowing Python's with keyword):

withGrabbedButtons :: ??? -> X()
withGrabbedButtons action =
  action >> ungrabAllButtons  


-- correct ; complete_action does not leave the mouse grabbed
complete_action :: X()
complete_action = withGrabbedButtons (action1 >> action2 >> action3)

-- type error!
erroneous_single_action :: X()
erroneous_single_action = action1

-- type error!
erroneous_action :: X()
erroneous_action = action1 >> action2 >> action3

This is so that people do not accidentally use action1, action2, action3 as X() actions, while forgetting to ungrab the buttons afterwards.

Is this possible with Haskell's type system? Thanks beforehand.

解决方案

What you will want to do is make a newtype wrapper for X, using GeneralizedNewtypeDeriving to get a free Monad instance:

{-# LANGUAGE GeneralizedNewtypeDeriving #-}

newtype XNeedsCleanup a = FromX { toX :: X a }
  deriving (Functor, Applicative, Monad)

Because XNeedsCleanup is a monad, you can bind multiple XNeedsCleanup together, as in your action1 >> action2 >> action3 example; this will bind all of their wrapped X actions together inside the FromX wrapper. But you won't be able to bind the resulting action with an X action; that's where your withGrabbedButtons comes in:

withGrabbedButtons :: XNeedsCleanup () -> X ()
withGrabbedButtons action = toX action >> ungrabAllButtons

If you don't export the toX unwrapper, your clients won't be able to use an XNeedsCleanup value without going through withGrabbedButtons. But if they have the ability to use arbitrary X actions, then presumably they can import whatever you use to define your various actions and could reimplement them as "raw" X actions. So just to be explicit: this isn't security-oriented safety, just preventing people from accidentally forgetting the cleanup.

这篇关于Haskell / XMonad:表达式的自然类型是什么?在一系列操作之后必须完成某些事情?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆