gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-02 17:07:37 25 4
gpt4 key购买 nike

为了用一个简单的例子来说明这一点,假设我已经实现了过滤器:

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 版本不会完全重复核心逻辑?

最佳答案

How do it make it work with filter without writing a separate implementation

这是不可能的,而且这种事情不可能的事实是设计使然 - Haskell 对它的类型设置了严格的限制,你必须遵守它们。你不能随意地将 IO 撒得到处都是。

Now the question is, can I structure my code so that the pure and IO versions don't completely duplicate the core logic?

您会对 filterM 感兴趣。然后,您可以使用 IO monad 获得 filterIO 的功能,并使用 Identity 获得纯功能。单子(monad)。当然,对于纯粹的情况,您现在必须支付包装/解开(或强制)Identity包装器的额外费用。 (旁注:由于 Identity 是一种 newtype,这只是代码可读性成本,而不是运行时成本。)

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

这是一个单子(monad)示例(请注意,仅包含 RedBlueBlue 的行是用户在提示符下输入的) :

 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]

关于haskell - 如何在IO代码中与纯算法交互,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41812122/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com