List 什么是哈斯克尔中映射函数的Lambda演算等价物?
map函数返回通过将函数(第一个参数)应用于作为第二个参数传递的列表中的所有项而构造的列表List 什么是哈斯克尔中映射函数的Lambda演算等价物?,list,haskell,lambda-calculus,map-function,List,Haskell,Lambda Calculus,Map Function,map函数返回通过将函数(第一个参数)应用于作为第二个参数传递的列表中的所有项而构造的列表 我想弄清楚,如果用Lambda演算符号来表示,这会是什么样子。有人能举个例子吗?因为这是标记为haskell的haskell我会用haskell来写答案,但是要像lambda演算一样在函数上构建一切。这通常会导致为延续传递样式携带额外的类型参数r 列表通常可以编码为解构匹配器:(这是Scott编码,正如注释告诉我的那样) 现在我们要给它一个函子实例。与其他问题一样,您可以让编译器指导您: instance
我想弄清楚,如果用Lambda演算符号来表示,这会是什么样子。有人能举个例子吗?因为这是标记为haskell的
haskell
我会用haskell来写答案,但是要像lambda演算一样在函数上构建一切。这通常会导致为延续传递样式携带额外的类型参数r
列表通常可以编码为解构匹配器:(这是Scott编码,正如注释告诉我的那样)
现在我们要给它一个函子
实例。与其他问题一样,您可以让编译器指导您:
instance Functor (List r) where
fmap f (List l) = List _
这将提示
LambdaList.hs:8:26: error:
• Found hole: _ :: r -> (b -> List r b -> r) -> r
Where: ‘b’ is a rigid type variable bound by
the type signature for:
fmap :: forall a b. (a -> b) -> List r a -> List r b
at LambdaList.hs:8:3-6
‘r’ is a rigid type variable bound by
the instance declaration
at LambdaList.hs:7:10-25
• In the first argument of ‘List’, namely ‘_’
In the expression: List _
In an equation for ‘fmap’: fmap f (List l) = List _
• Relevant bindings include
l :: r -> (a -> List r a -> r) -> r (bound at LambdaList.hs:8:16)
f :: a -> b (bound at LambdaList.hs:8:8)
fmap :: (a -> b) -> List r a -> List r b
(bound at LambdaList.hs:8:3)
Valid hole fits include
const :: forall a b. a -> b -> a
with const @r @(b -> List r b -> r)
(imported from ‘Prelude’ at LambdaList.hs:1:1
(and originally defined in ‘GHC.Base’))
return :: forall (m :: * -> *) a. Monad m => a -> m a
with return @((->) (b -> List r b -> r)) @r
(imported from ‘Prelude’ at LambdaList.hs:1:1
(and originally defined in ‘GHC.Base’))
pure :: forall (f :: * -> *) a. Applicative f => a -> f a
with pure @((->) (b -> List r b -> r)) @r
(imported from ‘Prelude’ at LambdaList.hs:1:1
(and originally defined in ‘GHC.Base’))
|
8 | fmap f (List l) = List _
| ^
所以我们应该定义一个函数;那么从lambda绑定一些参数开始可能是个好主意:
instance Functor (List r) where
fmap f (List l) = List $ \nilCs consCs -> _
instance Functor (List r) where
fmap f (List l) = List
$ \nilCs consCs -> l nilCs $ \lHead lTail -> _
instance Functor (List r) where
fmap f (List l) = List
$ \nilCs consCs -> l nilCs $ \lHead lTail -> consCs _ _
CPS结果仍然应该来自原始列表,因此我们需要在此时使用它–args仍然待定,但nil情况不会改变,因此我们也可以立即传递它:
instance Functor (List r) where
fmap f (List l) = List $ \nilCs consCs -> l nilCs _
这也是函数时间,即绑定一些参数:
instance Functor (List r) where
fmap f (List l) = List $ \nilCs consCs -> _
instance Functor (List r) where
fmap f (List l) = List
$ \nilCs consCs -> l nilCs $ \lHead lTail -> _
instance Functor (List r) where
fmap f (List l) = List
$ \nilCs consCs -> l nilCs $ \lHead lTail -> consCs _ _
在这一点上,我们有很多可以使用的范围,但一个很好的经验法则是,我们可能至少应该使用所有的范围一次,所以让我们引入consCs
,其中有两个待定参数:
instance Functor (List r) where
fmap f (List l) = List $ \nilCs consCs -> _
instance Functor (List r) where
fmap f (List l) = List
$ \nilCs consCs -> l nilCs $ \lHead lTail -> _
instance Functor (List r) where
fmap f (List l) = List
$ \nilCs consCs -> l nilCs $ \lHead lTail -> consCs _ _
好的,只有一种方法可以获得b
值:使用f
,它需要一个a
作为参数,我们正好有一个参数,即lHead
:
instance Functor (List r) where
fmap f (List l) = List
$ \nilCs consCs -> l nilCs
$ \lHead lTail -> consCs (f lHead) _
这里有一点问题:没有列表rb
在任何绑定的范围或结果中。然而,产生列表rb
的是我们在这里定义的函数:fmap f
。在标准的lambda演算中,实际上不能递归调用定义(需要使用不动点组合器来模拟它),但我在这里忽略这一点。这是一个有效的Haskell解决方案:
instance Functor (List r) where
fmap f (List l) = List
$ \nilCs consCs -> l nilCs
$ \lHead lTail -> consCs (f lHead) (fmap f lTail)
或者以lambda风格编写(删除列表
newtype构造函数)
map=\f lνζ⟼ lν(\h t⟼ ζ(f h)(map f t))有许多在线编写的lambda演算都涵盖了这一点。这是我发现的一个例子。我看不出有任何理由重新讨论堆栈溢出的问题。它不应该是
(a->r->r)
而不是(a->List a->r)
?对于后一种类型,toList[1]
看起来像什么?(使用前者很简单,List$\r c->c 1 r
)这里的类型是列表的Scott编码,使用(a->r->r)
的类型是church编码。它们是同构的,但有一些类型理论上的差异我没有资格解释:)@WillNesstoList[1]≡ 列出$\\uC->c1。List$\r\u->r
@leftaroundabout谢谢,我也得到了这个表达式,但我认为它不可能正确,因为它忽略了提供给它的第一个r
参数。。。(我想应该是$
来代替
),那么c
参数会是什么呢deconstructList(toList[1])未定义的c,其中c a t=??
我确实没有线索。我以为c1t
会以某种方式用外部r
运行t
,但它不能;在展开列表$\r c->r
后,没有r
可应用它。(?)那么我们如何从它的列表
等价物中重新创建[1]
(或任何其他列表)?我找不到做这件事的方法。@oisdk谢谢你提供的信息。你知道我上述评论的答案吗(如何从斯科特编码list
等效列表中获取原始列表)?(无可否认,我还没有看完那篇WP文章……)
map = \f l ν ζ ⟼ l ν (\h t ⟼ ζ (f h) (map f t))