【问题标题】:Does this monadic Haskell function already exist (or is a simple combination of known functions)?这个单子 Haskell 函数是否已经存在(或者是已知函数的简单组合)?
【发布时间】:2013-08-24 10:20:27
【问题描述】:

我是 Haskell 的初学者,但在数学方面有丰富的背景,尤其是代数,所以像“单子是内函子类别中的幺半群”这样的陈述对我来说不是问题。

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

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]

整合到一个大功能中。我在数独求解器中使用它。如果您认为可能有更相关的上下文,请告诉我。

【问题讨论】:

  • a -> m a 形式的函数,其中m 是一个单子,称为Kleisli arrows,它们是Category 的一个实例,允许您使用(.) 组合它们。跨度>

标签: haskell monads


【解决方案1】:

也叫flip (foldl (>>=))

一般来说,如果您正在寻找像[a] -> b 这样的函数,那么您正在寻找折叠。要在 monad 中组合对象,您可能首先使用 (>>=)flip 之所以存在,是因为 foldl 采用与您想要的相反顺序的参数。

【讨论】:

  • 现在看起来很明显!谢谢。
【解决方案2】:

当我们发现自己试图组合两个或多个“事物”以得到另一个相同类型的“事物”时,通常附近潜伏着一个幺半群。

对于纯函数,有 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]    

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-04-20
    • 1970-01-01
    • 2011-11-23
    • 2020-01-23
    • 1970-01-01
    • 2011-12-24
    • 2013-05-25
    相关资源
    最近更新 更多