如何正确使用Terminfo的Capability类型。 monad变形金刚的答案是什么?

时间:2016-04-18 01:37:26

标签: haskell monad-transformers terminfo

我一直在努力使用System.Console.Terminfo简化小程序。我已经mappend多个Capability在一起,但每当我需要评估它们时,我必须使用getCapability,然后使用case来模式化 - 匹配生成的Maybe。模式始终相同

Just ... -> runTermOutput ...
Nothing -> return ()

所以我认为必须有更好的方法来做到这一点。在我看来,模式匹配正在用Maybe替换IO,所以我认为它可能是monad变换器的用途。查看Capability定义,

> :i Capability
newtype Capability a
  = System.Console.Terminfo.Base.Capability (Terminal
                                             -> IO (Maybe a))
...

它看起来类似于我在StackOverflow上找到的MaybeT示例,但事实上它是一个函数会让我失望。 (另外,在阅读一个例子后,我无法理解monad变形金刚。)

我是否在正确的轨道上?是否有一种不同的模式可以帮助我避免一遍又一遍地写这个case

这是getCapability类型:

> :i getCapability 
getCapability :: Terminal -> Capability a -> Maybe a
...

2 个答案:

答案 0 :(得分:1)

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_也是如此。

答案 1 :(得分:0)

根据我的理解,Terminfo Capability界面意味着monad变换器不是答案。

正如user2407038建议的那样,使用函数

可以避免使用case模式
\t -> maybe (return ()) (runTermOutput t) . (getCapability t)
  :: Terminal -> Capability TermOutput -> IO ()