有没有办法自动交换单子?

Phr*_*hro 5 monads haskell lift

我编写了一个程序来Maybe从一对中取出一个:

deMaybe :: (a, Maybe b) -> Maybe (a, b)
deMaybe (_, Nothing) = Nothing
deMaybe (x,Just y) = Just (x, y)
Run Code Online (Sandbox Code Playgroud)

我知道这Maybe是一个单子并且(,) a是一个函子(以及其他类型类)。我想知道是否缺少更高级别的功能,例如:

commute :: (Functor f, Monad m) => f (m a) -> m (f a)
Run Code Online (Sandbox Code Playgroud)

我的问题是:我可以deMaybe使用更通用的类型签名(例如假设的类型签名)来编写commute,承认我正在尝试将一个函子传递到另一个函子吗?fmap可以使用、>>=、 、 &c等函数来完成此操作吗pure

Wil*_*sem 7

您可以使用sequence :: (Traversable t, Monad m) => t (m a) -> m (t a),但这需要一个Traversable. 对于t ~ (b, )m ~ Maybe,其工作原理如下:

Prelude> sequence (2, Just 3)
Just (2,3)
Prelude> sequence (2, Nothing)
Nothing
Run Code Online (Sandbox Code Playgroud)

ATraversable是数据结构的类型类,可以转换为具有相同形状的项目。我们需要它来构造一个二元组(或列表,或类似的东西)。

或者我们可以使用@chepner 所说的sequenceA :: (Traversable t, Applicative f) => t (f a) -> f (t a),这更通用,因为所有s 也是s:MonadApplicative

Prelude> sequenceA (2, Just 3)
Just (2,3)
Prelude> sequenceA (2, Nothing)
Nothing
Run Code Online (Sandbox Code Playgroud)

  • 还有 `sequenceA`,因为我们只需要 `Maybe` 是一个应用函子,而不一定是一个 monad。 (4认同)