gpt4 book ai didi

haskell - 关于返回函数和 Monad 的困惑

转载 作者:行者123 更新时间:2023-12-01 07:13:33 25 4
gpt4 key购买 nike

抱歉,我是 Haskell 的新手。这个问题可能很简单...

来自 Hoogle,return签名是 return :: Monad m => a -> m ahead签名是 head :: [a] -> a
在我这样做之前 head $ return [1,2,3] ,我以为ghci会抛出错误,因为m [a]不一样[a] .但令我惊讶的是,它返回 [1,2,3] .和 tail $ return [1,2,3]返回 [] .为什么?

还有一个问题:

我写了一个函数来生成随机数:

drawFloat :: Float -> Float -> IO Float
drawFloat x y = getStdRandom (randomR (x,y))
randList = mapM (const $ drawFloat 2 10) [1..10] -- generate a list of random numbers

当我想获得列表的头部时,我首先尝试了 head randList (失败)但是 head <$> randList工作。什么是 <$> ?有人可以解释一下吗?谢谢!

最佳答案

I thought that ghci would throw errors because m [a] is not the same as [a].



也许不是,但 m [a][b]可以统一!例如,我们可以设置 m ~ []b ~ [a]以便 m [a] ~ [] [a] ~ [[a]][b] ~ [[a]] .然后我们只需要检查 []Monad ,它是。这就是正在发生的事情:
> return [1,2,3] :: [[Int]]
[[1,2,3]]

那么应该清楚为什么 head返回 [1,2,3]tail返回 [] .

randList = mapM (const $ drawFloat 2 10) [1..n]


作为评论,还没有回答你的问题:这更好拼写 replicateM n (drawFloat 2 10) .

head randList (failed) but head <$> randList worked. What is <$>?



这里的问题是 head还在期待一个列表。之前,当您使用 return 时, monad 还没有被选择,所以它可以被选择为 [] ;但在这里,很明显你使用的 monad 是 IO .所以 head不能进步。解决办法是教 head如何处理 IO .方法很多, <$>是其中之一;它有这种类型:
> :t (<$>)
(<$>) :: Functor f => (a -> b) -> f a -> f b

读这个的方法是:给定一个纯函数,教它如何处理 IO (或任何其他符合 Functor 条件的效果)。例如,它也有这种类型:
(<$>) :: ([a] -> a) -> IO [a] -> IO a

还有其他几种老师。两个常用的是 <*>=<< :
Prelude Control.Applicative> :t (<*>)
(<*>) :: Applicative f => f (a -> b) -> f a -> f b
Prelude Control.Applicative> :t (=<<)
(=<<) :: Monad m => (a -> m b) -> m a -> m b

将第一个读作:给定一个产生纯函数的有效计算,产生一个可以处理效果的函数。第二个应该读作:给定一个在产生输出之前有一些效果的函数,生成一个可以处理效果的函数。

此时,如果这些解释没有帮助,您应该求助于众多 excellent monad tutorials 之一。可在网络上的其他地方获得。我个人最喜欢的是 You Could Have Invented Monads!All About Monads .

关于haskell - 关于返回函数和 Monad 的困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26707312/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com