表达式“ap zip tail”是如何工作的 [英] How does the expression `ap zip tail` work
问题描述
我想知道如何在免费的地方写 f x = zip x(tail x)
。所以我使用了pointfree程序,结果是 f = ap zip tail
。 ap
是Control.Monad的一个函数
我不明白point free定义是如何工作的。我希望能够从类型的角度理解它。
b $ b let f = ap zip taillet g = ap zip
:info ap zip tail fg
ap :: Monad m => m(a - > b) - > m a - > m b
- 在`Control.Monad'中定义
zip :: [a] - > [b] - > [(a,b)] - 在`GHC.List'中定义
tail :: [a] - > [a] - 在`GHC.List'中定义
f :: [b] - > [(b,b)] - 定义于< interactive>:3:5
g ::([a] - > [b]) - > [a] - > [(a,b)]
- 定义于< interactive>:4:5
<通过查看表达式 ap zip tail
我会认为zip是 ap
的第一个参数,tail是第二个参数 ap
。
Monad m => m(a - > b) - > m a - > mb
\ -------- / \ --- /
zip tail
但是这是不可能的,因为 zip
和 tail
的类型完全不同于函数 ap
需要什么。即使考虑到这个列表是一个monad。
ap
是 Monad m => m(a - > b) - > m a - > m b
。你已经给它 zip
和 tail
作为参数,所以让我们看看它们的类型签名。 从 tail :: [a] - > [a]〜( - >)[a] [a]
(这里〜
是类型的相等运算符)键入 ap
,
( - >)[x] [x]〜ma
(( - >)[x])[x]〜ma
$ b $($ - $)$($ - $)$($ - $)$($ - $) ( - >)a)。我们已经可以看到我们所在的monad是( - >)[x]
,而不是 []
。如果我们用 ap
的类型签名替换我们可以得到的:
<$ c $ ((( - >)[x])([x]→> b)) - > ((( - >)[x])[x]) - > (( - >)[x])b)
由于这不太可读, ([x] - >([x] - > b)) - >([x] - > ([x]→> [x]) - > ([x]→b)
〜([x]→> [x]→> b)→> ([x]→> [x]) - > ([x] - > b)
是
[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)])
- 拉链尾(ap zip尾)
- ap zip尾u =拉链u(尾u)
我希望能为您解决问题。
编辑:正如 danvari ,monad I wondered how to write I do not understand how the point free definition works. I hope I can figure it out if I can comprehend it from the perspective of types. By looking at the expression But this is not possible, because the types of So the type signature of Starting with we get Since this is not very readable, it can more normally be written as The type of Here I've listed the types vertically so that you can easily see which types line up. So obviously I hope that clears things up for you. EDIT: As danvari pointed out in the comments, the monad 这篇关于表达式“ap zip tail”是如何工作的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!( - >)a
有时被称为读者monad。 f x = zip x (tail x)
in point free. So I used the pointfree program and the result was f = ap zip tail
. ap
being a function from Control.Monadimport 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
I would think that zip is the first parameter of ap
and tail is the second parameter of ap
.Monad m => m (a -> b) -> m a -> m b
\--------/ \---/
zip tail
zip
and tail
are completely different than what the function ap
requires. Even with taking into consideration that the list is a monad of sorts.ap
is Monad m => m (a -> b) -> m a -> m b
. You've given it zip
and tail
as arguments, so let's look at their type signatures. tail :: [a] -> [a] ~ (->) [a] [a]
(here ~
is the equality operator for types), if we compare this type against the type of the second argument for ap
, (->) [x] [x] ~ m a
((->) [x]) [x] ~ m a
a ~ [x]
and m ~ ((->) [x]) ~ ((->) a)
. Already we can see that the monad we're in is (->) [x]
, not []
. If we substitute what we can into the type signature of ap
we get:(((->) [x]) ([x] -> b)) -> (((->) [x]) [x]) -> (((->) [x]) b)
([x] -> ([x] -> b)) -> ([x] -> [x]) -> ([x] -> b)
~ ([x] -> [x] -> b ) -> ([x] -> [x]) -> ([x] -> b)
zip
is [x] -> [y] -> [(x, y)]
. We can already see that this lines up with the first argument to ap
where[x] ~ [x]
[y] ~ [x]
[(x, y)] ~ b
x ~ x
, y ~ x
, and [(x, y)] ~ [(x, x)] ~ b
, so we can finish substituting b ~ [(x, x)]
into ap
's type signature and get([x] -> [x] -> [(x, x)]) -> ([x] -> [x]) -> ([x] -> [(x, x)])
-- zip tail ( ap zip tail )
-- ap zip tail u = zip u (tail u)
(->) a
is sometimes called the reader monad.