当前位置:  开发笔记 > 编程语言 > 正文

如何在IO代码中与纯算法交互

如何解决《如何在IO代码中与纯算法交互》经验,为你挑选了1个好方法。

为了用一个简单的例子说明这一点,请说我已经实现了filter:

filter :: (a -> Bool) -> [a] -> [a]

我有一个p与现实世界相互作用的谓词:

p :: a -> IO Bool

如何在filter不编写单独的实现的情况下使其工作:

filterIO :: (a -> IO Bool) -> [a] -> IO [a]

大概如果我可以p变成p':

p': IO (a -> Bool)

然后我就能做到

main :: IO ()
main = do 
  p'' <- p'
  print $ filter p'' [1..100]

但我一直无法找到转换.

编辑: 正如人们在评论中指出的那样,这样的转换没有意义,因为它会破坏IO Monad的封装.

现在的问题是,我可以构建我的代码,以便纯和IO版本不完全复制核心逻辑吗?



1> Alec..:

如何在不编写单独的实现的情况下使其与过滤器一起使用

这是不可能的,事实上这种事情是不可能的 - 设计--Haskell对其类型设置了严格的限制,你必须遵守它们.你不能IO无所畏惧地洒遍这个地方.

现在的问题是,我可以构建我的代码,以便纯和IO版本不完全复制核心逻辑吗?

你会感兴趣的filterM.然后,您可以filterIO使用IOmonad和使用monad的纯功能来获得两种功能Identity.当然,对于纯粹的情况,您现在必须支付包装/解包(或包装coerce)Identity包装的额外费用.(边注:由于Identitynewtype,这仅仅是一个代码的可读性成本,而不是一个运行一个)

 ghci> data Color = Red | Green | Blue deriving (Read, Show, Eq)

下面是一个monadic示例(注意,只含有该线Red,BlueBlue在提示被用户输入的):

 ghci> filterM (\x -> do y<-readLn; pure (x==y)) [Red,Green,Blue]
 Red
 Blue
 Blue
 [Red,Blue] :: IO [Color]

这是一个纯粹的例子:

 ghci> filterM (\x -> Identity (x /= Green)) [Red,Green,Blue]
 Identity [Red,Blue] :: Identity [Color]

推荐阅读
wurtjq
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有