gpt4 book ai didi

haskell - 表达式 `ap zip tail` 是如何工作的

转载 作者:行者123 更新时间:2023-12-04 01:51:41 24 4
gpt4 key购买 nike

我想知道如何写f x = zip x (tail x)在点免费。所以我使用了pointfree程序,结果是f = ap zip tail . ap作为 Control.Monad 的一个函数

我不明白无点定义是如何工作的。我希望我能从类型的角度来理解它。

import Control.Monad (ap)
let f = ap zip tail
let g = ap zip
:info ap zip tail f g
ap :: Monad m => m (a -> b) -> m a -> m b
-- Defined in `Control.Monad'
zip :: [a] -> [b] -> [(a, b)] -- Defined in `GHC.List'
tail :: [a] -> [a] -- Defined in `GHC.List'
f :: [b] -> [(b, b)] -- Defined at <interactive>:3:5
g :: ([a] -> [b]) -> [a] -> [(a, b)]
-- Defined at <interactive>:4:5

通过查看表达式 ap zip tail我认为 zip 是 ap 的第一个参数而tail是 ap的第二个参数.
Monad m => m (a -> b) -> m a -> m b
\--------/ \---/
zip tail

但这是不可能的,因为 zip 的类型和 tail完全不同于函数 ap需要。即使考虑到列表是一种单子(monad)。

最佳答案

所以 ap 的类型签名是 Monad m => m (a -> b) -> m a -> m b .你给了它ziptail作为参数,让我们看看它们的类型签名。

tail :: [a] -> [a] ~ (->) [a] [a] 开头(这里 ~ 是类型的相等运算符),如果我们将此类型与 ap 的第二个参数的类型进行比较,

 (->) [x]  [x] ~ m a
((->) [x]) [x] ~ m a

我们得到 a ~ [x]m ~ ((->) [x]) ~ ((->) a) .我们已经可以看到我们所在的 monad 是 (->) [x] ,而不是 [] .如果我们将我们能做的代入 ap 的类型签名中我们得到:
(((->) [x]) ([x] -> b)) -> (((->) [x]) [x]) -> (((->) [x]) b)

由于这不是很可读,它更通常可以写成
  ([x] -> ([x] -> b)) -> ([x] -> [x]) -> ([x] -> b)
~ ([x] -> [x] -> b ) -> ([x] -> [x]) -> ([x] -> b)
zip的类型是 [x] -> [y] -> [(x, y)] .我们已经可以看到这与 ap 的第一个参数一致。在哪里
[x]         ~    [x]   
[y] ~ [x]
[(x, y)] ~ b

在这里,我垂直列出了类型,以便您可以轻松查看哪些类型排列。很明显 x ~ x , y ~ x , 和 [(x, y)] ~ [(x, x)] ~ b , 所以我们可以完成替换 b ~ [(x, x)]进入 ap的类型签名并得到
([x] -> [x] -> [(x, x)]) -> ([x] -> [x]) -> ([x] -> [(x, x)])
-- zip tail ( ap zip tail )
-- ap zip tail u = zip u (tail u)

我希望这能为你解决问题。

编辑 : 如 danvari pointed out在评论中,monad (->) a有时被称为 reader monad。

关于haskell - 表达式 `ap zip tail` 是如何工作的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19181917/

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