在箭头内调用IO Monad

时间:2011-08-30 21:49:14

标签: opengl haskell monads arrows hxt

也许我会以错误的方式解决这个问题,但我正在使用HXT来读取我想在HOpenGL中的数组中使用的一些顶点数据。顶点数组需要是一个通过调用newArray创建的Ptr。不幸的是newArray返回IO Ptr,所以我不确定如何在Arrow中使用它。我想我需要类似于IO的类型声明 - >箭头a?

1 个答案:

答案 0 :(得分:5)

类型IO a -> Arrow a没有意义; Arrow是类型类,而不是特定类型,与MonadNum非常相似。具体来说,Arrow的一个实例是一个类型构造函数,它采用两个参数来描述可以像函数一样组合的东西,端到端匹配类型。因此,将IO a转换为箭头可能会被称为概念类型错误。

我不确定您要做什么,但如果您确实希望将IO操作用作Arrow的一部分,则需要Arrow个实例包括那个。最简单的形式是观察任何a -> m b实例的Monad类型的函数可以用显而易见的方式组成。 hxt包似乎提供了更复杂的类型:

newtype IOSLA s a b = IOSLA { runIOSLA :: s -> a -> IO (s, [b]) }

这是IOState[] monad的混合,附加到上面的函数中,以便您可以通过所有三个Monad组合它们在每一步。我还没有真正使用hxt,但如果这些是您正在使用的Arrow,那么将任意IO函数作为一个函数提升非常简单 - 只需传递状态值s不变,并将函数的输出转换为单例列表。可能已经有一个功能为你做这个,但我没有看到一个简短的一眼。

基本上,你需要这样的东西:

liftArrIO :: (a -> IO b) -> IOSLA s a b
liftArrIO f = IOSLA $ \s x -> fmap (\y -> (s, [y])) (f x)