gpt4 book ai didi

haskell - 用 `<=<` 组合单子(monad)函数

转载 作者:行者123 更新时间:2023-12-03 21:43:49 25 4
gpt4 key购买 nike

我正在尝试理解 <=<功能:

ghci> :t (<=<)
(<=<) :: Monad m => (b -> m c) -> (a -> m b) -> a -> m c

据我了解,我给了它 2 个函数和一个 a ,然后我会得到一个 m c .

那么,为什么这个例子不能编译?

import Control.Monad

f :: a -> Maybe a
f = \x -> Just x

g :: a -> [a]
g = \x -> [x]

foo :: Monad m => a -> m c
foo x = f <=< g x

对于 foo 3 , 我希望 Just 3结果。

但是我得到这个错误:

File.hs:10:15:
Couldn't match expected type `a0 -> Maybe c0'
with actual type `[a]'
In the return type of a call of `g'
Probable cause: `g' is applied to too many arguments
In the second argument of `(<=<)', namely `g x'
In the expression: f <=< g x Failed, modules loaded: none.

最佳答案

这里有两个错误。

首先,(<=<)仅当它们共享相同的 monad 时才组合 monadic 函数。换句话说,你可以用它来组成两个 Maybe功能:

(<=<) :: (b -> Maybe c) -> (a -> Maybe b) -> (a -> Maybe c)

...或两个列表函数:

(<=<) :: (b -> [c]) -> (a -> [b]) -> (a -> [c])

...但是你不能组成一个列表函数并且可能以这种方式运行。这样做的原因是当你有这样的类型签名时:

(<=<) :: Monad m => (b -> m c) -> (a -> m b) -> (a -> m c)

...编译器将确保所有 m s 必须匹配。

第二个错误是你忘了给你的作文加上括号。您可能想要的是:

(f <=< g) x

...如果您省略括号,编译器会这样解释它:

f <=< (g x)

修复函数的一种简单方法是定义一个辅助函数,将 Maybe 转换为s 到列表:

maybeToList :: Maybe a -> [a]
maybeToList Nothing = []
maybeToList (Just a) = [a]

这个函数实际上有以下两个很好的属性:

maybeToList . return = return

maybeToList . (f <=< g) = (maybeToList . f) <=< (maybeToList . g)

...如果你对待(maybeToList .),这是仿函数法则类似于 fmap并对待(<=<)类似于 (.)return类似于 id .

那么解就变成了:

(maybeToList . f <=< g) x

关于haskell - 用 `<=<` 组合单子(monad)函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25560448/

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