gpt4 book ai didi

haskell - 也许是一堆变压器里面的单子(monad)

转载 作者:行者123 更新时间:2023-12-03 14:53:24 25 4
gpt4 key购买 nike

我有以下代码:

import Control.Monad
import Control.Monad.Trans
import Control.Monad.Trans.State

type T = StateT Int IO Int

someMaybe = Just 3

f :: T
f = do
x <- get
val <- lift $ do
val <- someMaybe
-- more code in Maybe monad
-- return 4
return 3

当我使用 doMaybe 中工作的符号单子(monad)失败了。从错误来看,它看起来像是 do 的类型签名不匹配。但是我不知道如何解决它。我尝试了一些 lift组合,但它们都不起作用,我不想再猜测了。

最佳答案

问题是 Maybe不是变压器堆栈的一部分。如果你的变压器只知道 StateT IntIO ,它不知道如何抬起Maybe .

您可以通过更改类型来解决此问题 T类似于:

type T = StateT Int (MaybeT IO) Int

(您需要导入 Control.Monad.Trans.Maybe 。)

你还需要改变你的内在 doMaybeT 合作而不是 Maybe .这意味着包装原始 Maybe a MaybeT . return 的值:
f :: T
f = do
x <- get
val <- lift $ do
val <- MaybeT $ return someMaybe
-- more code in Maybe monad
return 4
return 3

这有点尴尬,所以你可能想写一个像 liftMaybe 这样的函数。 :
liftMaybe = MaybeT . return

如果您使用 lift吊装 IO a代码的其他部分中的值,现在这将中断,因为您的转换器堆栈中现在有三个级别。您将收到如下所示的错误:
Couldn't match expected type `MaybeT IO t0'
with actual type `IO String'

要解决此问题,您应该使用 liftIO为您所有的原始 IO a值(value)观。这使用了一个类型类来生活 IO通过任意数量的变压器层进行操作。

回应您的评论:如果您只有一点代码取决于 Maybe ,将 do 的结果放入会更容易符号转换为变量并与之匹配:
let maybeVal = do val <- someMaybe
-- more Maybe code
return 4
case maybeVal of
Just res -> ...
Nothing -> ...

这意味着 Maybe代码将无法执行 IO。你也可以很自然地使用像 fromMaybe 这样的函数。而不是 case .

关于haskell - 也许是一堆变压器里面的单子(monad),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16064143/

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