gpt4 book ai didi

Haskell sequencelistIO [a -> IO a] -> a -> IO a

转载 作者:行者123 更新时间:2023-12-03 21:33:38 25 4
gpt4 key购买 nike

我有以下问题:我的任务是编写一个函数,获取 IO 交互列表和初始值。第一个操作将初始值作为参数,函数应将其结果(IO a)作为参数传递给下一个交互。

后者需要类型 a 的数据,而不是 IO a。我不知道如何克服这个障碍。

这是我所拥有的:

seqList :: [a -> IO a] -> a -> IO a
seqList [] n = return n
seqList (inter:inters) n = do
val <- inter n
return $ seqList inters val

问题在于 val 的类型为 (IO a),但下一个 IO 需要 a。我尝试过类似的事情

tmp <- unsafePerformIO val

验证后<- ...

但这没有帮助,而且风格非常糟糕。我该如何解决这个问题?

我想要提示,没有解决方案,

提前致谢。

编辑

我按以下方式编辑它:

seqList :: [a -> IO a] -> a -> IO a
seqList [] n = return n
seqList (inter:inters) n = do
val <- inter n
seqList inters val

因为 seqList inters val 已经是正确的类型。

这应该没问题还是我弄错了?它实际上适用于我的示例。

看起来我对整个 do-notation-monads-io-stuff 仍然很陌生。

非常感谢您的提示。

最佳答案

编辑后的版本正确。


不过,有一种有趣的方式来看待这个问题。人们可以如下分析类型

type Thing a = a -> IO a

seqList :: [Thing a] -> Thing a

换句话说,seqList是一种组合Thing的机制。如果我们稍微重写您的工作代码,我们可以强调这一点。

seqList :: [Thing a] -> Thing a
seqList [] n = neutralThing n
seqList (thingHere : restOfThings) n = do
let remainingThing = seqList restOfThings
val <- thingHere
remainingThing val

neutralThing :: Thing a
neutralThing a = return a

特别是,我隔离了三个部分

  • 输入列表为空时返回的中性事物
  • 从列表尾部计算“剩余内容”的递归位
  • “组合”事物的实际 do 表示法位。

我们可以走得更远

seqList :: [Thing a] -> Thing a
seqList [] = neutralThing
seqList (thingHere : restOfThings) =
combineThings thingHere (seqList restOfThings)

neutralThing :: Thing a
neutralThing a = return a

combineThings :: Thing a -> Thing a -> Thing a
combineThings thing1 thing2 n = do
n' <- thing1 n
n'' <- thing2 n'
return n''

现在我们可以识别一个通用模式:seqList 只是列表的折叠。

seqList :: [Thing a] -> Thing a
seqList = foldr combineThings neutralThing

如果我们认识到折叠经常暴露 Monoids我们还可以检测 Thing a 对于任何 a

的选择如何是一个幺半群
memptyThing :: Thing a
memptyThing = neutralThing

mappendThing :: Thing a -> Thing a -> Thing a
mappendThing = combineThings

最后,如果我们真的很聪明,我们可以注意到 Thing 从稍微更通用的 Category 结构中继承了幺半群性。 - 特别是,称为 Kleisli IO category 的东西。如果我们使用 Kleisli 类型本身,将会有大量的包装和展开,但我们可以检查 return(>=> 的类型) 来自 Control.Monad

return :: Monad m => a -> m a
(>=>) :: Monad m => (a -> m b) -> (b -> m c) -> (a -> m c)

稍加注意,我们就可以看到这些类型与 memptyThingmappendThing 兼容。因此,您的问题的最终解决方案如下

seqList :: [Thing a] -> Thing a
seqList = foldr (>=>) return

如果我们愿意的话,我们终于可以注意到它有一个更通用的类型

seqList :: Monad m => [a -> m a] -> (a -> m a)
seqList = foldr (>=>) return

关于Haskell sequencelistIO [a -> IO a] -> a -> IO a,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30493159/

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