-3

给出函数 fmap :: (a->b) -> IO a -> IO b 的定义

其效果是通过将函数应用于其结果来转换交互。您应该使用 do 构造来定义它。

我应该如何定义 fmap?我对此一无所知?

有人可以帮我吗?

谢谢~!

4

3 回答 3

6

它看起来像家庭作业或其他东西,所以我会给你足够的提示,这样你就可以自己处理其余的细节。

fmap1 :: (a -> b) -> IO a -> IO b 
fmap1 f action = 

actionis 作为IO动作,f是来自ato的函数b,因此是 type a -> b

如果您熟悉>>=具有类型的 monadic bind(简化为IOmonad)

(>>=) :: IO a -> (a -> IO b) -> IO b

现在如果你看

action >>= f

这意味着执行IO返回输出(例如outtype a)并将输出传递给ftype 的操作a -> IO b,因此f out是 type IO b

如果您查看第二个调用return的具有类型的函数(再次简化为IOmonad)

return :: a -> IO a

它接受 type 的纯值a并给出 type 的IO动作IO a

现在让我们回顾一下fmap

fmap1 f action 

它执行IO动作,然后f在动作的输出上运行,然后将输出转换为另一个IO类型的动作IO b。所以

fmap1 f action = action >>= g 
    where
        g out = return (f out)

现在是do符号的语法糖。这只是以另一种方式编写绑定>>=

do符号中,您可以通过以下方式获得操作的输出

out <- action 

所以 bind 只是减少到

action >>= f = do 
    out <- action 
    f out 

我认为现在您将能够将 fmap 的定义转换为 do 构造。

于 2012-09-29T12:14:37.293 回答
2

你熟悉地图吗?

地图的类型是

地图 :: (a -> b) -> [a] -> [b]

如果你跑

地图 (*5) [1,2,3]

你得到

[5,10,15]

map 的重点是给它一个转换函数和一个源列表,并让它将转换应用于列表以获得结果列表。

map 是列表的 fmap。他们希望您为 IO 类型编写 fmap,这有帮助吗?

如果您想了解更多关于 fmap 的信息,请阅读http://learnyouahaskell.com/making-our-own-types-and-typeclasses#the-functor-typeclass

于 2012-09-29T11:08:36.473 回答
1

请注意,每个 monad 已经是一个仿函数。但是,如果你想重新实现fmap,你可以很容易地用一元函数来做到这一点。一个单子定律是这样的:

fmap f xs = xs >>= return . f

如果你对 do notation 的理解足够,你应该可以自己翻译。如果没有,请问。

于 2012-09-29T11:51:11.803 回答