我一直在考虑monad的方式是类型的值Monad m => m a是一些m执行和生成类型的程序a.该单子法律通过这些程序考虑成分"做的事情,然后做一个事物的两个"强化这个概念,并产生某种结果的组合.
右单元获取程序并返回其值应该与运行原始程序相同.
m >>= return = m
左单元如果创建一个只返回一个值的简单程序,然后将该值传递给创建一个新程序的函数,那么生成的程序应该就像在函数上调用该函数一样.
return x >>= f = f x
关联性如果执行程序m,将其结果提供给f生成另一个程序的函数,然后将该结果提供给g也生成程序的第三个函数,那么这与创建一个基于提供程序返回程序的新函数相同的结果f为g,和进给的结果m进去.
(m >>= f) >>= g = m >>= (\x -> f x >>= g)
利用这种关于"创造价值的程序"的直觉可以得出一些结论,这些结论是关于你在例子中提供的函数的含义.
Monad m => [m a] -> m [a]偏离对此功能应该做的直观定义很难:按顺序执行每个程序并收集结果.这会生成另一个生成结果列表的程序.Monad m => m [a] -> [m a]这并不是一个明确的直观定义,因为它是一个生成列表的程序.如果没有访问结果值,则无法创建列表,在这种情况下,这意味着执行程序.某些monad,有明确的方法从程序中提取值,并提供一些变体m a -> a,如Statemonad,可以像这样的某些函数的理智实现.它必须是特定于应用程序的.其他的monads,IO你无法逃脱.Monad m => (a -> m b) -> m (a -> b)这也没有一个明确的直观定义.这里有一个f生成类型程序的函数m b,但是你试图返回一个类型的函数m (a -> b).基于此a,f创建具有不同执行语义的完全不同的程序.m (a -> b)即使您可以a -> b在程序结果值中提供正确的映射,也不能在单个类型的程序中包含这些变体.这种直觉并不完全包含monad背后的想法.例如,列表的monadic上下文实际上并不像程序.
| 归档时间: |
|
| 查看次数: |
210 次 |
| 最近记录: |