简体   繁体   English

如何解除应用monadic值容器的功能?

[英]How to lift function to apply monadic value container?

I'm newbie of Haskell. 我是Haskell的新手。 And I'm learning about monads. 我正在学习单子。

data Container a = Container a deriving Show

x = Container 1 :: Container Int

plusOne :: Container Int -> Container Int
plusOne (Container x) = Container (x+1)

Is there any way to lift plusOne to apply to Container (IO Int) ? 有没有办法解除plusOne申请Container (IO Int)

Or should I define a new function, such as: 或者我应该定义一个新功能,例如:

plusOne' :: Container (IO Int) -> Container (IO Int)  
plusOne' (Container x) = Container (liftM (+1) x)

Thanks all :-) And then Is there any way to avoid redefine plusOne ? 谢谢大家:-)然后有什么方法可以避免重新定义plusOne吗?

Because whan I build program, first I build program with non-monadic-type container(normal value such as: Container Int ..etc), And I test function with specified value (Container 10..). 因为我构建程序,首先我用非monadic类型的容器构建程序(正常值如:Container Int ..etc),并且我测试具有指定值的函数(容器10 ..)。

And after that I try to apply these program to random or generated value. 然后我尝试将这些程序应用于随机或生成的值。 This is my basic approach for programming in other language (such as Lisp, Python..) 这是我用其他语言编程的基本方法(比如Lisp,Python ..)

So I don't want to redefine function when I want to try to apply these function to monadic-value container. 所以当我想尝试将这些函数应用于monadic-value容器时,我不想重新定义函数。

this approach doesn't work on Haskell programming? 这种方法不适用于Haskell编程? Should I change my mind-model? 我应该改变我的思维模式吗? Or I misunderstanding about Haskell? 或者我误解了Haskell?

Looks like Container should be an instance of Functor : 看起来像Container应该是Functor的一个实例:

instance Functor Container where
    fmap f (Container a) = Container (f a)

Then 然后

plusOne = fmap (+1)

and

plusOne' = fmap $ liftM (+1)

However, now it occurs to me that I might have misunderstood the question... 但是,现在我发现我可能误解了这个问题......

First things first, it looks like you've actually redefined the Identity monad . 首先,看起来你实际上已经重新定义Identity monad

When you have functors containing other functors as you do here, you don't want to have to do all the bookkeeping yourself to make sure you've got the right number of fmap s and so on. 当你在这里有包含其他fmap函数时,你不希望自己做所有的记账,以确保你有正确数量的fmap等等。 That's where monad transformers come in. 这就是monad变形金刚进来的地方。

The MTL library (which should come with the Haskell Platform) has done all the hard work for you, you just need to do a bit (OK, quite a lot) of plumbing to make your own type work with all the existing monad transformers. MTL库 (它应该随Haskell平台一起提供)已经为您完成了所有艰苦的工作,您只需要做一些(好的,相当多)管道,使您自己的类型与所有现有的monad变换器一起工作。 Once you've done that, your Container should be a good citizen as a member of any monad stack. 一旦你完成了,你的Container应该是一个好公民作为任何monad堆栈的成员。

Of course, the usual caveats apply: monad transformers are powerful and hard to understand. 当然,通常的警告适用:monad变形金刚强大且难以理解。 Half the times you think you need them, you don't really - so make sure you're using the right approach to solve your problem first. 有一半你认为你需要它们,你不是真的 - 所以要确保你使用正确的方法来解决你的问题。

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

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