Monads:确定是否可以进行任意转换

AJF*_*mar 9 monads haskell

相当的问题在这里大约与否涉及单子可能的类型一定转换.

例如,可以创建类型的函数f :: Monad m => [m a] -> m [a],但是不可能将类型的函数g :: Monad m => m [a] -> [m a]作为对前者的适当的反函数.(IE: f . g = id)

我想了解可以使用哪些规则来确定是否可以构造该类型的函数,以及如果这些类型违反这些规则,则无法构造这些类型的原因.

Mok*_*sha 5

我一直在考虑monad的方式是类型的值Monad m => m a是一些m执行和生成类型的程序a.该单子法律通过这些程序考虑成分"做的事情,然后做一个事物的两个"强化这个概念,并产生某种结果的组合.

  • 右单元获取程序并返回其值应该与运行原始程序相同.

    m >>= return = m
  • 左单元如果创建一个只返回一个值的简单程序,然后将该值传递给创建一个新程序的函数,那么生成的程序应该就像在函数上调用该函数一样.

    return x >>= f = f x
  • 关联性如果执行程序m,将其结果提供给f生成另一个程序的函数,然后将该结果提供给g也生成程序的第三个函数,那么这与创建一个基于提供程序返回程序的新函数相同的结果fg,和进给的结果m进去.

    (m >>= f) >>= g  =  m >>= (\x -> f x >>= g)

利用这种关于"创造价值的程序"的直觉可以得出一些结论,这些结论是关于你在例子中提供的函数的含义.

  1. Monad m => [m a] -> m [a]偏离对此功能应该做的直观定义很难:按顺序执行每个程序并收集结果.这会生成另一个生成结果列表的程序.
  2. Monad m => m [a] -> [m a]这并不是一个明确的直观定义,因为它是一个生成列表的程序.如果没有访问结果值,则无法创建列表,在这种情况下,这意味着执行程序.某些monad,有明确的方法从程序中提取值,并提供一些变体m a -> a,如Statemonad,可以像这样的某些函数的理智实现.它必须是特定于应用程序的.其他的monads,IO你无法逃脱.
  3. Monad m => (a -> m b) -> m (a -> b)这也没有一个明确的直观定义.这里有一个f生成类型程序的函数m b,但是你试图返回一个类型的函数m (a -> b).基于此a,f创建具有不同执行语义的完全不同的程序.m (a -> b)即使您可以a -> b在程序结果值中提供正确的映射,也不能在单个类型的程序中包含这些变体.

这种直觉并不完全包含monad背后的想法.例如,列表的monadic上下文实际上并不像程序.