我是 Monads 的新手,正在尝试编写一个添加函数,但我不确定为什么这不起作用。使用 monad 时,是否需要以特定方式返回值?
monadd :: (Monad m, Num b) => m b -> m b -> m b
monadd mx my = mx >>= (\x -> my >>= (\y -> (x + y)))
Run Code Online (Sandbox Code Playgroud)
你想使用pure(更一般的形式return)
monadd :: Monad m => Num a => m a -> m a -> m a\nmonadd mx my = mx >>= (\\x -> my >>= (\\y -> pure (x + y)))\nRun Code Online (Sandbox Code Playgroud)\n的右侧(延续)>>=必须始终返回一元操作。但当你添加时,x + y :: a你就有了一个数字。你需要pure (x + y) :: m a把它变成一个单一的动作:
monadd :: Monad m => Num a => m a -> m a -> m a\nmonadd mx my = mx >>= (\\x -> my >>= (\\y -> pure (x + y)))\n ^^^ ^ ^^^ ^ ^^^^^^^^^^^^\n m a a m a a m a\nRun Code Online (Sandbox Code Playgroud)\n你可以等效地写成do- 表示法
monadd :: Monad m => Num a => m a -> m a -> m a\nmonadd mx my = do\n x <- mx\n y <- my\n pure (x + y)\nRun Code Online (Sandbox Code Playgroud)\n实际上。这不需要Monad.Applicative(n 元提升)就足够了:
monadd :: Applicative m => Num a => m a -> m a -> m a\nmonadd = liftA2 (+)\nRun Code Online (Sandbox Code Playgroud)\nFunctor提升一元函数以及Applicative提升常量和 n 元函数的提醒(其中liftA0 = pure和liftF1 = fmap):
liftA0 :: Applicative f => (a) -> (f a)\nliftF1 :: Functor f => (a -> b) -> (f a -> f b)\nliftA2 :: Applicative f => (a -> b -> c) -> (f a -> f b -> f c)\nliftA3 :: Applicative f => (a -> b -> c -> d) -> (f a -> f b -> f c -> f d)\nRun Code Online (Sandbox Code Playgroud)\n仅当计算之间Monad存在依赖性时才需要。请注意,在您的情况下,my计算并不依赖于结果mx。
如果m b取决于它的输出,m a它会变成a -> m b。然后Monad需要:
dependency :: Monad m => (a -> b -> c) -> m a -> (a -> m b) -> m c\ndependency (\xc2\xb7) as bs = do\n a <- as\n b <- bs a\n pure (a \xc2\xb7 b)\nRun Code Online (Sandbox Code Playgroud)\n
使用 monad 时,是否需要以特定方式返回值?
是的,您需要在单子上下文中换行x并返回,使用 ,因此:yreturn :: Monad m => a -> m a
monadd :: (Monad m, Num b) => m b -> m b -> m b
monadd mx my = mx >>= (\x -> my >>= return (x+y)))
Run Code Online (Sandbox Code Playgroud)
然而,由于 monadmx和的两个操作my彼此独立Applicative就足够了,您可以将其实现为:
monadd :: (Applicative f, Num b) => f b -> f b -> f b
monadd mx my = (+) <$> mx <*> my
Run Code Online (Sandbox Code Playgroud)
或通过liftA2 :: Applicative f => (a -> b -> c) -> f a -> f b -> f c:
monadd :: (Applicative f, Num b) => f b -> f b -> f b
monadd = liftA2 (+)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
141 次 |
| 最近记录: |