首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在纯函数式语言中,is data (字符串、整数、浮点数..)也只是函数吗?

问在纯函数式语言中,is data (字符串、整数、浮点数..)也只是函数吗?
EN

Stack Overflow用户
提问于 2012-11-28 06:53:31
回答 4查看 782关注 0票数 12

我考虑的是像Ruby这样的纯面向对象语言,在这些语言中,包括数字、整数、浮点数和字符串在内的所有内容都是对象。这对纯函数式语言也是一样的吗?例如,在Haskell中,数字和字符串也是函数吗?

我知道Haskell是基于lambda演算的,它将一切都表示为函数,包括数据和操作。在我看来,“纯函数式语言”将把所有东西都建模为一个函数,并且符合函数的定义,即函数总是以相同的输入返回相同的输出,并且没有状态,这似乎是符合逻辑的。

EN

回答 4

Stack Overflow用户

发布于 2012-11-28 06:58:59

从理论上考虑这个问题是可以的,但是...

就像Ruby语言中并不是所有的东西都是对象(例如,参数列表,are not objects),在Haskell中也不是所有的东西都是函数。

有关更多参考信息,请查看此整洁的帖子:http://conal.net/blog/posts/everything-is-a-function-in-haskell

票数 15
EN

Stack Overflow用户

发布于 2012-11-28 07:13:30

@wrhall给出了一个很好的答案。然而,您在某种程度上是正确的,在纯lambda演算中,一切都是一致的,并且语言是Turing-complete (能够表达Haskell等的任何纯计算)。

这给了你一些非常奇怪的东西,因为你对任何东西唯一能做的就是将它应用于其他东西。你什么时候能观察到什么东西?你有一些值f,并且想知道一些关于它的信息,你唯一的选择是应用一些值x来获得f x,这是另一个函数,唯一的选择是将它应用于另一个值y,获得f x y,依此类推。

我经常将纯lambda演算解释为谈论对不是函数的事物的转换,但只能表达函数本身。也就是说,我可以创建一个函数(使用一些Haskelly语法糖来实现递归& let):

代码语言:javascript
复制
purePlus = \zero succ natCase -> 
   let plus = \m n -> natCase m n (\m' -> plus m' n)
   in plus (succ (succ zero)) (succ (succ zero))

在这里,我表达了计算2+2,而不需要知道存在非函数之类的东西。我只是简单地将我需要的东西作为我定义的函数的参数,这些参数的值可以是教堂编码,也可以是“真实”数字(不管是什么意思) --我的定义并不关心。

你也可以对Haskell有同样的想法。没有特别的理由认为存在不是函数的东西,也没有特别的理由认为一切都是函数。但是Haskell的类型系统至少阻止了您将参数应用于数字(现在考虑fromInteger的任何人都需要保持沉默!:-)。在上面的解释中,这是因为数字不一定被建模为函数,所以您不一定要对它们应用参数。

如果到目前为止还不清楚,这个完整的答案有点技术/哲学上的离题,对你的问题的简单回答是“不,在函数式语言中并不是所有的东西都是函数”。函数是可以应用参数的东西,仅此而已。

票数 14
EN

Stack Overflow用户

发布于 2012-11-28 09:24:15

在这个问题上有一个非常不同的角度: Haskell中的所有类型的数据都可以表示为函数,使用一种称为的技术。这是控制反转的一种形式:不是将数据传递给使用它的函数,而是将数据隐藏在一组闭包中,并在描述如何处理这些数据的回调中传递来使用它。

例如,任何使用列表的程序都可以转换为使用函数而不是列表的程序:

代码语言:javascript
复制
-- | A list corresponds to a function of this type:
type ChurchList a r = (a -> r -> r)  --^ how to handle a cons cell
                   -> r              --^ how to handle the empty list
                   -> r              --^ result of processing the list

listToCPS :: [a] -> ChurchList a r
listToCPS xs = \f z -> foldr f z xs

该函数以一个具体的列表为起点,但这并不是必需的。您可以仅使用纯函数构建ChurchList函数:

代码语言:javascript
复制
-- | The empty 'ChurchList'.
nil :: ChurchList a r
nil = \f z -> z

-- | Add an element at the front of a 'ChurchList'.
cons :: a -> ChurchList a r -> ChurchList a r
cons x xs = \f z -> f z (xs f z)

foldChurchList :: (a -> r -> r) -> r -> ChurchList a r -> r
foldChurchList f z xs = xs f z

mapChurchList :: (a -> b) -> ChurchList a r -> ChurchList b r
mapChurchList f = foldChurchList step nil
    where step x = cons (f x)

filterChurchList :: (a -> Bool) -> ChurchList a r -> ChurchList a r
filterChurchList pred = foldChurchList step nil
    where step x xs = if pred x then cons x xs else xs

最后一个函数使用Bool,当然我们也可以用函数替换Bool:

代码语言:javascript
复制
-- | A Bool can be represented as a function that chooses between two 
-- given alternatives.
type ChurchBool r = r -> r -> r

true, false :: ChurchBool r
true a _ = a
false _ b = b

filterChurchList' :: (a -> ChurchBool r) -> ChurchList a r -> ChurchList a r
filterChurchList' pred = foldChurchList step nil
    where step x xs = pred x (cons x xs) xs

这种类型的转换基本上可以用于任何类型,因此从理论上讲,您可以去掉Haskell中的所有“值”类型,只保留()类型、(->)和IO类型构造函数、IO的return和>>=以及一组合适的IO原语。这显然是不切实际的--而且它的性能会更差(试着写tailChurchList :: ChurchList a r -> ChurchList a r试试)。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13594683

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档