(=<<) 组合子的鸟名?
Bird name for the (=<<) combinator?
Haskell 鸟舍组合器将 (=<<) 列为:
(a -> r -> b) -> (r -> a) -> r -> b
有正式的鸟名吗?还是可以从已有的推导出来?
Is there an official bird-name for this?
我在 Data.Aviary.Birds 中找不到它,所以我想没有。如果有,它可能会在您链接的列表中被引用。
Or can it be derived via the pre-existing ones?
当然可以。最简单的可能是从签名相似的 starling
开始,然后用 flip
组合它,即
(=<<) = bluebird starling cardinal
也许会像这样:blackbird warbler bluebird
这就像
(...) = (.) . (.) -- blackbird
(.) -- bluebird
join -- warbler
-- and your function will be
f = join ... (.)
引用评论:
Btw do you have any advice on how to combine combinators to get a specific signature? I feel like I'm missing some trick (my current technique of staring at a list and doing mental gymnastics doesn't scale too well!)
让类型来指导您。您正在寻找:
-- This name is totally made-up.
mino :: (b -> a -> c) -> (a -> b) -> a -> c
虽然您不会在 the list 中找到它,但有些东西非常相似:
starling :: (a -> b -> c) -> (a -> b) -> a -> c
如果我们有办法以某种方式将 starling
扭曲成我们想要的...
mino :: (b -> a -> c) -> (a -> b) -> a -> c
mino = f starling
-- f :: ((a -> b -> c) -> (a -> b) -> a -> c) -> (b -> a -> c) -> (a -> b) -> a -> c
这个神秘的 f
有一个相当笨重的类型,所以让我们把它缩写一下:x ~ b -> a -> c
、y ~ a -> b -> c
和 z -> (a -> b) -> a -> c
,我们有
f :: (y -> z) -> x -> z
再看一下列表显示这符合 queer
的结果类型:
queer :: (a -> b) -> (b -> c) -> a -> c
进步!
mino :: (b -> a -> c) -> (a -> b) -> a -> c
mino = queer g starling
-- g :: x -> y
-- g :: (b -> a -> c) -> a -> b -> c
至于g
,有一个很好的候选人:
cardinal :: (a -> b -> c) -> b -> a -> c
就是这样:
mino :: (b -> a -> c) -> (a -> b) -> a -> c
mino = queer cardinal starling
queer
当然是cardinal bluebird
(即反向函数组合),又回到了.
GHC其实可以帮你做这种推导:
import Data.Aviary.Birds
mino :: (b -> a -> c) -> (a -> b) -> a -> c
mino = _f starling
GHCi> :l Mino.hs
[1 of 1] Compiling Main ( Mino.hs, interpreted )
Mino.hs:4:8: error:
* Found hole:
_f
:: ((a0 -> b0 -> c0) -> (a0 -> b0) -> a0 -> c0)
-> (b -> a -> c) -> (a -> b) -> a -> c
Where: `b0' is an ambiguous type variable
`a0' is an ambiguous type variable
`c0' is an ambiguous type variable
`b' is a rigid type variable bound by
the type signature for:
mino :: forall b a c. (b -> a -> c) -> (a -> b) -> a -> c
at Mino.hs:3:1-43
`a' is a rigid type variable bound by
the type signature for:
mino :: forall b a c. (b -> a -> c) -> (a -> b) -> a -> c
at Mino.hs:3:1-43
`c' is a rigid type variable bound by
the type signature for:
mino :: forall b a c. (b -> a -> c) -> (a -> b) -> a -> c
at Mino.hs:3:1-43
Or perhaps `_f' is mis-spelled, or not in scope
* In the expression: _f
In the expression: _f starling
In an equation for `mino': mino = _f starling
* Relevant bindings include
mino :: (b -> a -> c) -> (a -> b) -> a -> c (bound at Mino.hs:4:1)
|
4 | mino = _f starling
| ^^
Failed, no modules loaded.
不过,如果你想要一个干净的输出,你必须轻轻地问:
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE PartialTypeSignatures #-}
import Data.Aviary.Birds
mino :: forall b a c. (b -> a -> c) -> (a -> b) -> a -> c
mino =
let s :: (a -> b -> c) -> _
s = starling
in _f s
(starling
的类型注解会使定义 s
变得不必要;但是,这种风格会随着更复杂的表达式而变得非常丑陋。)
GHCi> :l Mino.hs
[1 of 1] Compiling Main ( Mino.hs, interpreted )
Mino.hs:10:8: error:
* Found hole:
_f
:: ((a -> b -> c) -> (a -> b) -> a -> c)
-> (b -> a -> c) -> (a -> b) -> a -> c
Where: `b' is a rigid type variable bound by
the type signature for:
mino :: forall b a c. (b -> a -> c) -> (a -> b) -> a -> c
at Mino.hs:6:1-57
`a' is a rigid type variable bound by
the type signature for:
mino :: forall b a c. (b -> a -> c) -> (a -> b) -> a -> c
at Mino.hs:6:1-57
`c' is a rigid type variable bound by
the type signature for:
mino :: forall b a c. (b -> a -> c) -> (a -> b) -> a -> c
at Mino.hs:6:1-57
Or perhaps `_f' is mis-spelled, or not in scope
* In the expression: _f
In the expression: _f s
In the expression:
let
s :: (a -> b -> c) -> _
s = starling
in _f s
* Relevant bindings include
s :: (a -> b -> c) -> (a -> b) -> a -> c (bound at Mino.hs:9:9)
mino :: (b -> a -> c) -> (a -> b) -> a -> c (bound at Mino.hs:7:1)
|
10 | in _f s
| ^^
Failed, no modules loaded.
上面描述的过程仍然涉及相当多的凝视列表,因为我们只使用无点威严的鸟类来计算它。但是,如果没有这些限制,我们可能会以不同的方式进行:
mino :: (b -> a -> c) -> (a -> b) -> a -> c
mino g f = _
洞的类型为 a -> c
,所以我们知道它是一个接受 a
:
的函数
mino :: (b -> a -> c) -> (a -> b) -> a -> c
mino g f = \x -> _
-- x :: a
这里唯一需要 a
的是 g
:
mino :: (b -> a -> c) -> (a -> b) -> a -> c
mino g f = \x -> g _ x
洞的类型现在是 b
,唯一给出 b
的是 f
:
mino :: (b -> a -> c) -> (a -> b) -> a -> c
mino g f = \x -> g (f x) x
这当然是通常定义的reader(=<<)
。如果我们翻转 g
,虽然...
mino :: (b -> a -> c) -> (a -> b) -> a -> c
mino g f = \x -> flip g x (f x)
... reader (<*>)
(即 S 组合子)变得可识别:
mino :: (b -> a -> c) -> (a -> b) -> a -> c
mino g f = \x -> (<*>) (flip g) f x
然后我们可以将它写成 pointfree...
mino :: (b -> a -> c) -> (a -> b) -> a -> c
mino = (<*>) . flip
...并翻译成鸟语:
mino :: (b -> a -> c) -> (a -> b) -> a -> c
mino = bluebird starling cardinal
Haskell 鸟舍组合器将 (=<<) 列为:
(a -> r -> b) -> (r -> a) -> r -> b
有正式的鸟名吗?还是可以从已有的推导出来?
Is there an official bird-name for this?
我在 Data.Aviary.Birds 中找不到它,所以我想没有。如果有,它可能会在您链接的列表中被引用。
Or can it be derived via the pre-existing ones?
当然可以。最简单的可能是从签名相似的 starling
开始,然后用 flip
组合它,即
(=<<) = bluebird starling cardinal
也许会像这样:blackbird warbler bluebird
这就像
(...) = (.) . (.) -- blackbird
(.) -- bluebird
join -- warbler
-- and your function will be
f = join ... (.)
引用评论:
Btw do you have any advice on how to combine combinators to get a specific signature? I feel like I'm missing some trick (my current technique of staring at a list and doing mental gymnastics doesn't scale too well!)
让类型来指导您。您正在寻找:
-- This name is totally made-up.
mino :: (b -> a -> c) -> (a -> b) -> a -> c
虽然您不会在 the list 中找到它,但有些东西非常相似:
starling :: (a -> b -> c) -> (a -> b) -> a -> c
如果我们有办法以某种方式将 starling
扭曲成我们想要的...
mino :: (b -> a -> c) -> (a -> b) -> a -> c
mino = f starling
-- f :: ((a -> b -> c) -> (a -> b) -> a -> c) -> (b -> a -> c) -> (a -> b) -> a -> c
这个神秘的 f
有一个相当笨重的类型,所以让我们把它缩写一下:x ~ b -> a -> c
、y ~ a -> b -> c
和 z -> (a -> b) -> a -> c
,我们有
f :: (y -> z) -> x -> z
再看一下列表显示这符合 queer
的结果类型:
queer :: (a -> b) -> (b -> c) -> a -> c
进步!
mino :: (b -> a -> c) -> (a -> b) -> a -> c
mino = queer g starling
-- g :: x -> y
-- g :: (b -> a -> c) -> a -> b -> c
至于g
,有一个很好的候选人:
cardinal :: (a -> b -> c) -> b -> a -> c
就是这样:
mino :: (b -> a -> c) -> (a -> b) -> a -> c
mino = queer cardinal starling
queer
当然是cardinal bluebird
(即反向函数组合),又回到了
GHC其实可以帮你做这种推导:
import Data.Aviary.Birds
mino :: (b -> a -> c) -> (a -> b) -> a -> c
mino = _f starling
GHCi> :l Mino.hs
[1 of 1] Compiling Main ( Mino.hs, interpreted )
Mino.hs:4:8: error:
* Found hole:
_f
:: ((a0 -> b0 -> c0) -> (a0 -> b0) -> a0 -> c0)
-> (b -> a -> c) -> (a -> b) -> a -> c
Where: `b0' is an ambiguous type variable
`a0' is an ambiguous type variable
`c0' is an ambiguous type variable
`b' is a rigid type variable bound by
the type signature for:
mino :: forall b a c. (b -> a -> c) -> (a -> b) -> a -> c
at Mino.hs:3:1-43
`a' is a rigid type variable bound by
the type signature for:
mino :: forall b a c. (b -> a -> c) -> (a -> b) -> a -> c
at Mino.hs:3:1-43
`c' is a rigid type variable bound by
the type signature for:
mino :: forall b a c. (b -> a -> c) -> (a -> b) -> a -> c
at Mino.hs:3:1-43
Or perhaps `_f' is mis-spelled, or not in scope
* In the expression: _f
In the expression: _f starling
In an equation for `mino': mino = _f starling
* Relevant bindings include
mino :: (b -> a -> c) -> (a -> b) -> a -> c (bound at Mino.hs:4:1)
|
4 | mino = _f starling
| ^^
Failed, no modules loaded.
不过,如果你想要一个干净的输出,你必须轻轻地问:
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE PartialTypeSignatures #-}
import Data.Aviary.Birds
mino :: forall b a c. (b -> a -> c) -> (a -> b) -> a -> c
mino =
let s :: (a -> b -> c) -> _
s = starling
in _f s
(starling
的类型注解会使定义 s
变得不必要;但是,这种风格会随着更复杂的表达式而变得非常丑陋。)
GHCi> :l Mino.hs
[1 of 1] Compiling Main ( Mino.hs, interpreted )
Mino.hs:10:8: error:
* Found hole:
_f
:: ((a -> b -> c) -> (a -> b) -> a -> c)
-> (b -> a -> c) -> (a -> b) -> a -> c
Where: `b' is a rigid type variable bound by
the type signature for:
mino :: forall b a c. (b -> a -> c) -> (a -> b) -> a -> c
at Mino.hs:6:1-57
`a' is a rigid type variable bound by
the type signature for:
mino :: forall b a c. (b -> a -> c) -> (a -> b) -> a -> c
at Mino.hs:6:1-57
`c' is a rigid type variable bound by
the type signature for:
mino :: forall b a c. (b -> a -> c) -> (a -> b) -> a -> c
at Mino.hs:6:1-57
Or perhaps `_f' is mis-spelled, or not in scope
* In the expression: _f
In the expression: _f s
In the expression:
let
s :: (a -> b -> c) -> _
s = starling
in _f s
* Relevant bindings include
s :: (a -> b -> c) -> (a -> b) -> a -> c (bound at Mino.hs:9:9)
mino :: (b -> a -> c) -> (a -> b) -> a -> c (bound at Mino.hs:7:1)
|
10 | in _f s
| ^^
Failed, no modules loaded.
上面描述的过程仍然涉及相当多的凝视列表,因为我们只使用无点威严的鸟类来计算它。但是,如果没有这些限制,我们可能会以不同的方式进行:
mino :: (b -> a -> c) -> (a -> b) -> a -> c
mino g f = _
洞的类型为 a -> c
,所以我们知道它是一个接受 a
:
mino :: (b -> a -> c) -> (a -> b) -> a -> c
mino g f = \x -> _
-- x :: a
这里唯一需要 a
的是 g
:
mino :: (b -> a -> c) -> (a -> b) -> a -> c
mino g f = \x -> g _ x
洞的类型现在是 b
,唯一给出 b
的是 f
:
mino :: (b -> a -> c) -> (a -> b) -> a -> c
mino g f = \x -> g (f x) x
这当然是通常定义的reader(=<<)
。如果我们翻转 g
,虽然...
mino :: (b -> a -> c) -> (a -> b) -> a -> c
mino g f = \x -> flip g x (f x)
... reader (<*>)
(即 S 组合子)变得可识别:
mino :: (b -> a -> c) -> (a -> b) -> a -> c
mino g f = \x -> (<*>) (flip g) f x
然后我们可以将它写成 pointfree...
mino :: (b -> a -> c) -> (a -> b) -> a -> c
mino = (<*>) . flip
...并翻译成鸟语:
mino :: (b -> a -> c) -> (a -> b) -> a -> c
mino = bluebird starling cardinal