我有以下代码,但我觉得它太丑陋而且势在必行.有人会说它更具功能吗?(我和MaybeT混淆但是无法使它工作)也欢迎应用答案.
getString :: IO String
pred :: String -> Bool
f :: String -> String
result :: IO (Maybe String)
result = do
s <- getString
if pred s
then return $ Just $ f s
else return Nothing
Run Code Online (Sandbox Code Playgroud)
编辑:一个后续问题:如果pred和f都返回IO内的结果会怎么样(我应该把它分成一个单独的问题吗?)
getString :: IO String
pred :: String -> IO Bool
f :: String -> IO String
result :: IO (Maybe String)
result = do
s <- getString
b <- pred s
if b
then Just <$> f s
else return Nothing
Run Code Online (Sandbox Code Playgroud)
ham*_*mar 26
我首先从IO
monad中取出逻辑.然后可以将您的函数写为
result :: IO (Maybe String)
result = foo <$> getString
foo :: String -> Maybe String
foo s | pred s = Just (f s)
| otherwise = Nothing
Run Code Online (Sandbox Code Playgroud)
您可以foo
使用一些奇特的组合器以不同的方式编写,但我不认为这是必要的.最重要的是让你的逻辑IO
变得更容易测试.
Dan*_*ner 10
这是一个很好的小组合:
ensure :: MonadPlus m => (a -> Bool) -> (a -> m a)
ensure p x = guard (p x) >> return x
Run Code Online (Sandbox Code Playgroud)
现在我们可以编写一个纯函数来检查你的谓词并f
在适当的时候应用:
process :: String -> Maybe String
process = fmap f . ensure pred
Run Code Online (Sandbox Code Playgroud)
将此提升为一个IO
动作只是另一个fmap
:
result = fmap process getString
Run Code Online (Sandbox Code Playgroud)
就个人而言,我可能会内联process
,并以这种方式写:
result = fmap (fmap f . ensure pred) getString
Run Code Online (Sandbox Code Playgroud)
...这是对正在发生的事情的一个相对清晰的描述.
代码的明显转换是对return
操作进行分析:
result = do
s <- getString
return $ if pred s
then Just (f s)
else Nothing
Run Code Online (Sandbox Code Playgroud)
这使得模式更加明显:
result = liftM g getString
g s | pred s = Just (f s)
| otherwise = Nothing
Run Code Online (Sandbox Code Playgroud)
通过f
从外部申请,我们可以使下一个模式显而易见:
g s = liftM f $ if pred s then Just s else Nothing
Run Code Online (Sandbox Code Playgroud)
这让我们重新阻止了这个if
块:
g = liftM f . mfilter pred . return
Run Code Online (Sandbox Code Playgroud)
总结一下:
result = liftM (liftM f . mfilter pred . return) getString
Run Code Online (Sandbox Code Playgroud)
import Control.Monad
result = getString >>= (return . fmap f . (mfilter pred . Just) )
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
6796 次 |
最近记录: |