4

So I found out that fmap, a Functor function can be expressed in terms of Monadic operator >>= and return function like this:

fmap' :: (Monad m) => (a -> b) -> m a -> m b
fmap' g x = x >>= (\y ->
                return (g y))

So my first question is how can we implement return function based on fmap?

Also if we can implement return function based on fmap, can we reduce Haskell expressions in do blocks? Would that produce more elegant code?

For instance:

Just x -> do 
    y <- f x
    return (a:y)
4

2 回答 2

3

我们一般不能return按照fmap. Monad只是比 更强大Functor

然而,作为一个练习,我们可以尝试问这个问题:如果有的话,第二个操作可以使return轮流实现成为可能fmap吗?我们可以通过查看类型来解决这个问题。(我们将使用purefromApplicative类而不是 -return它们基本上是相同的操作。)

fmap :: Functor f => (a -> b) -> f a -> f b
pure :: Applicative f => a -> f a

好吧,一种可能的方式是,如果我们有以下功能:

-- This is like the standard `const` function, but restricted to the `()` type:
const' :: a -> () -> a
const' a = \() -> a

然后我们可以这样写,也就是“几乎” pure/ return

almostThere :: Functor f => a -> f () -> f a
almostThere a = fmap (const' a)

然后,如果我们有以下类,我们可以用pure它来写:

class Functor f => Pointed f where
    unit :: f ()

pure :: Pointed f => a -> f a
pure a = almostThere a unit

长话短说,这归结为return,所有功能都允许您从头开始制作,而pure仅允许您在已有另一个的情况下制作。除非您可以访问具有“能力”从头开始制作的第三个操作,否则您无法使用它来实现。我展示的操作可能是最简单的具有这种“力量”的操作。unitffmapffmapreturnpurefunit

于 2013-11-06T08:08:51.567 回答
2

不可能的仿函数的最简单示例return(,) a

instance Functor ((,) a) where
  fmap f (a, x) = (a, f x)

但是要使其成为 monad,要实现return,您需要a凭空生成一个值(对于任何类型!)。这样做的唯一方法是return x = (undefined, x),这几乎不是解决方案......

于 2013-11-06T01:07:01.737 回答