我一直在努力使用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
...
答案 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 ()