创建 haskell 个 IO 包装器
Create haskell IO wrapper
在 GHC 手册关于 FFI 的部分中,声明程序员可以使用 newtype
在 IO monad 周围创建一个包装器 monad,并在调用外部代码时使用它代替 IO monad。 (GHC manual)
到目前为止,我有:
newtype PGm a = PGm (IO a)
instance Monad PGm where
(>>=) a b = ...
(>>) a b = ...
return a = PGm (return a) --I think
fail a = PGm (fail a) --I think
我不知道如何实施 (>>=)
和 (>>)
。
您只需打开并重新包装每个操作。困难的部分是弄清楚展开和重新包装的位置:
newtype PGm a = PGm (IO a)
instance Monad PGm where
(>>=) (PGm a) b = PGm (a >>= (unPGm . b))
where
unPGm (PGm x) = x
(>>) (PGm a) (PGm b) = a >> b
return a = PGm (return a)
fail a = PGm (fail a)
然而,这还不够,因为 Haskell 需要 Functor
和 Applicative
的实例才能定义 Monad
实例。一个更简单的解决方案是将 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
放在文件的顶部(或在 GHCi 中启用 :set -XGeneralizedNewtypeDeriving
),这样你就可以这样做;
newtype PGm a = PGm (IO a) deriving (Functor, Applicative, Monad)
想法是,如果您启用此扩展,GHC 将足够智能,可以自动从 'base' 实例派生新类型实例。
在 GHC 手册关于 FFI 的部分中,声明程序员可以使用 newtype
在 IO monad 周围创建一个包装器 monad,并在调用外部代码时使用它代替 IO monad。 (GHC manual)
到目前为止,我有:
newtype PGm a = PGm (IO a)
instance Monad PGm where
(>>=) a b = ...
(>>) a b = ...
return a = PGm (return a) --I think
fail a = PGm (fail a) --I think
我不知道如何实施 (>>=)
和 (>>)
。
您只需打开并重新包装每个操作。困难的部分是弄清楚展开和重新包装的位置:
newtype PGm a = PGm (IO a)
instance Monad PGm where
(>>=) (PGm a) b = PGm (a >>= (unPGm . b))
where
unPGm (PGm x) = x
(>>) (PGm a) (PGm b) = a >> b
return a = PGm (return a)
fail a = PGm (fail a)
然而,这还不够,因为 Haskell 需要 Functor
和 Applicative
的实例才能定义 Monad
实例。一个更简单的解决方案是将 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
放在文件的顶部(或在 GHCi 中启用 :set -XGeneralizedNewtypeDeriving
),这样你就可以这样做;
newtype PGm a = PGm (IO a) deriving (Functor, Applicative, Monad)
想法是,如果您启用此扩展,GHC 将足够智能,可以自动从 'base' 实例派生新类型实例。