如何正确使用 Terminfo 的 Capability 类型。 monad 转换器是答案吗?
How to use Terminfo's Capability type correctly. Are monad transformers the answer?
我一直在努力使用 System.Console.Terminfo
来简化一个小程序。我已经 mappend
将多个 Capability
放在一起,但是每当我需要评估它们时,我都必须使用 getCapability
然后使用 case
进行模式化-匹配结果 Maybe
。图案总是一样
Just ... -> runTermOutput ...
Nothing -> return ()
所以我认为一定有更好的方法来做到这一点。在我看来,模式匹配正在用 IO
替换 Maybe
,所以我认为这可能是 monad 转换器的用途。查看 Capability
定义,
> :i Capability
newtype Capability a
= System.Console.Terminfo.Base.Capability (Terminal
-> IO (Maybe a))
...
它看起来确实与我在 Whosebug 上找到的 MaybeT
示例相似,但它是一个函数这一事实让我很反感。 (另外,我不能声称只读了一个例子就理解了 monad 转换器。)
我走在正确的轨道上吗?有没有不同的模式可以帮助我避免一遍又一遍地写这个 case
?
这里是 getCapability
类型:
> :i getCapability
getCapability :: Terminal -> Capability a -> Maybe a
...
mapM :: (Monad m, Traversable t) => (a -> m b) -> t a -> m (t b)
不仅专注于
mapM :: (a -> IO b) -> [a] -> IO [b]
,还要
mapM :: (a -> IO b) -> Maybe a -> IO (Maybe b)
。 mapM_
、for
、for_
、traverse
、traverse_
、
也是如此
据我了解,Terminfo Capability
接口意味着 monad 转换器不是答案。
正如 user2407038 所建议的,case
模式可以通过函数避免,
\t -> maybe (return ()) (runTermOutput t) . (getCapability t)
:: Terminal -> Capability TermOutput -> IO ()
我一直在努力使用 System.Console.Terminfo
来简化一个小程序。我已经 mappend
将多个 Capability
放在一起,但是每当我需要评估它们时,我都必须使用 getCapability
然后使用 case
进行模式化-匹配结果 Maybe
。图案总是一样
Just ... -> runTermOutput ...
Nothing -> return ()
所以我认为一定有更好的方法来做到这一点。在我看来,模式匹配正在用 IO
替换 Maybe
,所以我认为这可能是 monad 转换器的用途。查看 Capability
定义,
> :i Capability
newtype Capability a
= System.Console.Terminfo.Base.Capability (Terminal
-> IO (Maybe a))
...
它看起来确实与我在 Whosebug 上找到的 MaybeT
示例相似,但它是一个函数这一事实让我很反感。 (另外,我不能声称只读了一个例子就理解了 monad 转换器。)
我走在正确的轨道上吗?有没有不同的模式可以帮助我避免一遍又一遍地写这个 case
?
这里是 getCapability
类型:
> :i getCapability
getCapability :: Terminal -> Capability a -> Maybe a
...
mapM :: (Monad m, Traversable t) => (a -> m b) -> t a -> m (t b)
不仅专注于
mapM :: (a -> IO b) -> [a] -> IO [b]
,还要
mapM :: (a -> IO b) -> Maybe a -> IO (Maybe b)
。 mapM_
、for
、for_
、traverse
、traverse_
、
据我了解,Terminfo Capability
接口意味着 monad 转换器不是答案。
正如 user2407038 所建议的,case
模式可以通过函数避免,
\t -> maybe (return ()) (runTermOutput t) . (getCapability t)
:: Terminal -> Capability TermOutput -> IO ()