gpt4 book ai didi

haskell - 按类型指定函数参数

转载 作者:行者123 更新时间:2023-12-02 18:39:17 25 4
gpt4 key购买 nike

我确信这是非常明显的,但是请耐心等待,我对这个东西很陌生,而且它没有点击。因此,像许多其他人一样,我一直在努力了解 Monad。我已经对 >>= 和 return 运算符等感到满意了。但我觉得除非我自己去写一些东西,否则我不会真正理解它。

因此,我一直在尝试将列表的绑定(bind)>>=运算符实现为map和foldr的组合。例如,[5,6,7,8] >>= (\x -> [x*5, x*6, x*7])产量[25,30,35,30,36,42,35,42,49,40,48,56] 。这看起来很像 map 和折叠的组合。但如果我尝试类似 foldr (++) [] . map我收到明显的类型错误, map 没有类型 [a] -> [[a]]正如预期的那样。当然,如果我改用 map (\x -> [x*5, x*6, x*7]) 之类的东西作为组合运算符的正确参数,它一切正常。

但是每次都指定一个特定的函数会很麻烦;不知何故, >>= 运算符的行为更加通用。有没有办法通过参数的类型来指定参数?就像,我可以以某种方式告诉 map 仅采用 a -> [a] 类型的函数吗?在这个组合物中?我需要编写一个类型为 (a -> [a]) -> [a] -> [[a]] 的函数吗?从头开始,因为没有真正的方法将映射函数缩小到我想要的函数类型?

另外,请随时告诉我我的做法是错误的。我对这类东西还很陌生。如果是这样,请为我指出正确的方向。

最佳答案

如果你检查类似的类型

> :t \f -> foldr (++) [] . map f

在 GHCi 中,正如我上面所做的那样,您会注意到一些有趣的事情

\f -> foldr (++) [] . map f :: (a -> [b]) -> [a] -> [b]

或者,切入正题,事实证明输入函数f已经并且自然具有您要求的更受限制的类型为了。为什么会这样?

让我们检查一下 foldr (++) [],它更自然地称为 concat

concat :: [[a]] -> [a]
concat = foldr (++) []

我们看到它的输入必须是列表的列表。如果我们考虑一下这在使用 map

后期合成的背景下意味着什么
concat           ::        [[c]] -> [c]
. map f :: [a] -> [ b ] -- for (f :: a -> b)

我们可以看到,对于某些类型cb 必须与[c] 相同。换句话说,有关映射 f 结果的使用的信息,例如它通过concat的 channel 向后流动以专门化我们所知道的关于map的信息,甚至它的参数f

因此,统一上面的 b[c] 我们看到 map 必须具有稍微更严格的类型

map ::* (a -> [c]) -> [a] -> [[c]]

我在其中编写 (::*) 来表明这是 map 自然类型的特化,由 < em>统一与concat类型。

关于haskell - 按类型指定函数参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26248444/

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