我是Haskell的新手.我正在学习单子.
data Container a = Container a deriving Show
x = Container 1 :: Container Int
plusOne :: Container Int -> Container Int
plusOne (Container x) = Container (x+1)
Run Code Online (Sandbox Code Playgroud)
有没有办法解除plusOne
申请Container (IO Int)
?
或者我应该定义一个新功能,例如:
plusOne' :: Container (IO Int) -> Container (IO Int)
plusOne' (Container x) = Container (liftM (+1) x)
Run Code Online (Sandbox Code Playgroud)
谢谢大家:-)然后有什么方法可以避免重新定义plusOne吗?
因为我构建程序,首先我用非monadic类型的容器构建程序(正常值如:Container Int ..etc),并且我测试具有指定值的函数(容器10 ..).
然后我尝试将这些程序应用于随机或生成的值.这是我用其他语言编程的基本方法(比如Lisp,Python ..)
所以当我想尝试将这些函数应用于monadic-value容器时,我不想重新定义函数.
这种方法不适用于Haskell编程?我应该改变我的思维模式吗?或者我误解了Haskell?
看起来Container
应该是Functor的一个实例:
instance Functor Container where
fmap f (Container a) = Container (f a)
Run Code Online (Sandbox Code Playgroud)
然后
plusOne = fmap (+1)
Run Code Online (Sandbox Code Playgroud)
和
plusOne' = fmap $ liftM (+1)
Run Code Online (Sandbox Code Playgroud)
但是,现在我发现我可能误解了这个问题......
首先,看起来你实际上已经重新定义了Identity
monad.
当你在这里有包含其他仿函数的仿函数时,你不希望自己做所有的记账,以确保你有正确数量的fmap
s等等.这就是monad变形金刚进来的地方.
MTL库(它应该随Haskell平台一起提供)已经为您完成了所有艰苦的工作,您只需要做一些(好的,相当多)管道,使您自己的类型与所有现有的monad变换器一起工作.一旦你做完了,你Container
应该是一个好公民作为任何monad堆栈的成员.
当然,通常的警告适用:monad变形金刚强大且难以理解.有一半你认为你需要它们,你不是真的 - 所以要确保你使用正确的方法来解决你的问题.
归档时间: |
|
查看次数: |
225 次 |
最近记录: |