处理Haskell中的事件

ako*_*sch 14 haskell event-handling typeclass ghc

我想在Haskell中实现以下场景.我有一组可以这样定义的'事件':

data MyEvent = Event1
             | Event2
             | Event3
Run Code Online (Sandbox Code Playgroud)

我想为以下方式使用这些事件定义处理程序:

eventLoop :: Handler h => h -> IO ()
eventLoop currentHandler = do
    event <- getNextEvent
    nextHandler <- currentHandler event
    eventLoop nextHandler
Run Code Online (Sandbox Code Playgroud)

基本上我希望处理程序能够返回自己或其他处理程序来处理未来的事件.这是我不确定的处理程序类型.

我的第一个想法是将处理程序定义为简单的函数,但它们的类型会变得无限长:

myHandler :: Event -> IO (Event -> IO (Event -> ... ))
Run Code Online (Sandbox Code Playgroud)

我怀疑这可以通过类型类来解决,其中每个处理程序都需要实现一个函数来处理事件(这反过来又返回同一个类的另一个类型),但递归定义仍然适用.更精通类型系统的人能指出我正确的方向吗?我也欢迎任何不同的看法.

谢谢!

C. *_*ann 17

好吧,"无限"类型通常相当于展开的递归类型.因此,您可以做的一件事是使用以下方法显式递归newtype:

newtype Handler = Handler { runHandler :: Event -> IO Handler }
Run Code Online (Sandbox Code Playgroud)

这也可能是最简单的解决方案,因为它避免了为了获得不同的行为而需要处理类型类和不同的实例 - 每个处理程序都可以选择它返回的内容,因为它们具有统一的接口.

请注意,在许多情况下,定义类型类来解决此类问题是完全多余的.如果您正在处理多态类型Handler h => h,那么您可以使用该类型使用类型类的函数.如果在该类型类上定义的函数很简单,那么通过概念上"预先应用"它们可以节省很多麻烦.