这个monadic Haskell函数是否已经存在(或者是已知函数的简单组合)?

时间:2013-08-21 21:05:12

标签: haskell monads

我是Haskell的初学者,但是在数学,特别是代数方面有很多背景,所以像“monad是endofunctors类别中的monoid”这样的陈述对我来说不是问题。

即便如此,我只是了解Haskell中monad的一部分,在学习过程中我发现自己编写了以下函数:

bindMap ::(Monad m) => [a -> m a] -> m a -> m a
bindMap (f:fs) s = bindMap fs (s >>= f)
bindMap _ s = s

这完全符合我的目的,但它似乎是一个显而易见的功能,我认为我应该能够找到它或用一些简单的组合器定义,或者(更有可能)我应该以不同的方式思考事物

我最初使用类型签名

编写它
[a -> [a]] -> [a] -> [a]

这可能会更多地表明我所追求的目标。我们的想法是加入一系列功能

a -> [a]
成为一个大功能。我在Sudoku求解器中使用它。如果您认为可能有更多相关背景,请告诉我。

2 个答案:

答案 0 :(得分:10)

它也被称为flip (foldl (>>=))

一般来说,如果您正在寻找像[a] -> b这样的功能,那么您正在寻找折叠。要在monad中撰写对象,您可能会首先找到(>>=)flip就在那里,因为foldl以与你想要的相反的顺序获取参数。

答案 1 :(得分:5)

当我们发现自己试图将两个或更多“事物”结合起来以获得相同类型的另一个“事物”时,通常会有一个幺半群潜伏在附近。

对于纯函数,有Endo幺半群。

奇怪的是,Kleisli箭似乎没有标准的模拟。它会是这样的:

import Data.Monoid
import Control.Monad

newtype EndoM m a = EndoM { appEndoM :: a -> m a }

instance Monad m => Monoid (EndoM m a) where
     mempty = EndoM return
     EndoM f `mappend` EndoM g = EndoM (f >=> g)

main :: IO ()
main = putStrLn . show . kleisli $ 5
    where
    kleisli = appEndoM . mconcat . map EndoM $ [return,Just,const Nothing]