繁体   English   中英

有人可以解释如何在haskell中使用电梯吗?

[英]Can some one explain how to use lift in haskell?

我试着通过例子来理解起重原理,发现了这个:

https://github.com/graninas/Functional-Design-and-Architecture/blob/1736abc16d3e4917fc466010dcc182746af2fd0e/First-Edition/BookSamples/CH03/MonadStack.hs

然后,如果我将它的lift (lift (putStrLn "bla-bla"))更改为putStrLn "bla-bla" ,编译器会抛出错误!

我这样做是基于我的理解: do块只是语法糖,每一行的结果都传递到下一行。 如果下一行不使用从上一行传递的 args,我认为 args 的类型不会导致类型冲突。

以波纹管为例,而x<- getLine可以通过编译

test:: IO ()
test = do
  x <- getLine              -- discarded and compiler don't care it type 
  let a = "bla-bla"   -- discarded and compiler don't care it type 
  putStrLn $ "You type are discarded: "

现在回到calculations函数:

type Data = Map.Map Int String
type StateIO = StateT Data IO
type MaybeStateIO a = MaybeT StateIO a

calculations :: MaybeStateIO ()
calculations = do
    lift (lift (putStrLn "bla-bla")) -- if I change this to `putStrLn "bla-bla"`, it failed compiling.
    lift (modify (Map.insert 3 "3"))
    lift (modify (Map.insert 1 "1"))
    mb <- lift (get >>= (return . Map.lookup 1))
    lift (lift (print mb))

main = runStateT (runMaybeT calculations) Map.empty

我不明白编译器需要提升putStrLn "bla-bla"

do块最后一行的返回值与函数的返回值匹配还不够吗?

在这个例子中,编译器如何根据函数的签名来决定do block的值类型?

谁能帮我解释一下电梯? 它是如何工作的,何时使用等。

calculations的值是一个MaybeStateIO值。 这就是你正在操作的 monad,所以这就是do块的每一行都必须产生的内容。 但是putStrLn "bla-bla"不会产生MaybeStateIO值; 它只是产生一个IO值。 第一个lift取那个IO值并返回一个StateIO值; 第二次lift采用StateIO值并返回MaybeStateIO值。

记住,

do
   a
   b

只是a >> b语法糖,并且(>>) :: Monad m => ma -> mb -> mb需要来自同一个 monad 的值作为参数。 只有单子的“返回值”( ab )会因行而异; monad m本身是固定的。

do块最后一行的返回值与函数的返回值匹配还不够吗?

不,因为这意味着您可以编写一个do块,例如,第一项将使用Monad[]实例,而下一项将使用例如MaybeIO ,但是x <- some_listputStrLn x的列表? do块中的所有行都应该是ma类型,其中mMonad的相同实例,并且每行a s 可以有不同的类型。 如果你写一个 do 块:

foo = do
    x <- exp1
    exp2

然后将其转换为exp 1 >>= \x -> exp 2 ,并且由于(>>=) :: Monad m => ma -> (a -> mb) -> mb在两个操作数共享相同的情况下运行monad m ,因此这意味着exp 1 :: maexp 2 :: mb因此需要使用相同的单子类型m

您需要执行两次提升,因为该行应该具有类型MaybeT (StateT Data IO) aputStrLn "bla-bla"具有IO a ,因此需要一次lift :: (MonadTrans t, Monad m) => ma -> tma将其提升到StateT Data IO a和另一个最终将其提升到MaybeT (StateT Data IO) a

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM