Haskell 函数根据 monad 类型的不同而不同

Haskell function which acts differently depending on the monad type

我正在尝试实现一个通常将列表的第一个元素放在 monad 中的函数,但是如果 monad 是一个列表,它 return 就是整个列表:

putInMonad :: MonadPlus m => [a] -> m a
putInMonad (s:sx) = return s
putInMonad _ = mzero
putInMonad [1,2,3] :: Maybe Int

应该returnJust 1

putInMonad [1,2,3] :: [] Int

应该return[1,2,3].

有什么想法吗?

一般情况下,你不能这样做,因为函数无法知道调用函数时将使用哪个Foo实例,这意味着它没有决定return return sreturn (s:sx).

在这种特殊情况下,当 FooMonadPlus 时,有一个解决方法(参见 )。

在您的特定 use-case 中,您可以利用 msum:

putInMonad :: MonadPlus m => [a] -> m a
putInMonad x = msum $ map return x

那么两个例子都可以工作:

% putInMonad [1,2,3,4] :: Maybe Int
Just 1
% putInMonad [1,2,3,4] :: [Int]
[1,2,3,4]

但是请注意 Maybe 不完全是 MonadPlus,因为 mplus 没有关联。