我们可以在函数式语言中创建一个带有void(即没有返回值)的函数吗?像Haskell或Scheme
答案 0 :(得分:7)
在Haskell中,您可以编写一系列返回()
( unit )的函数,这相当于C语言中的void
:
foo :: a -> ()
foo _ = ()
bar :: a -> b -> ()
bar _ _ = ()
但是,您会注意到我的实现忽略了他们的输入,只需返回()
,因此他们不会 任何东西。
您可以这样称呼它们:
Prelude> foo 42
()
Prelude> bar 42 "foo"
()
但这仍然无法完成任何事情。
另一方面,您可以编写返回IO ()
的函数,如下所示:
main :: IO ()
main = putStrLn "Hello, world!"
但现在这是不纯的。虽然这会产生副作用,但您可以争论它是否具有功能性。至少,在Haskell中,你不能从纯代码中调用不纯的代码(这是设计的),所以它没有编写。
答案 1 :(得分:4)
这种功能的目的是什么?如果你想到一个数学函数(函数式编程的基础),那么这个函数的密码域是什么?
所以简短的回答是没有在haskell(我不知道足够的方案来给出一个明智的答案)。
haskell中java中最接近void的是IO ()
答案 2 :(得分:2)
在Racket中你可以:
Welcome to DrRacket, version 6.11 [3m].
Language: racket, with debugging; memory limit: 128 MB.
> (define (f) (displayln "hello") (void))
> (f)
hello
> (void? (f))
hello
#t
答案 3 :(得分:2)
首先,您需要记住编程语言倾向于使用" function"在某种意义上,它与数学意义不同。编程语言函数只是一个命名子例程,可能会也可能不会产生可以分配或传递的值。
帕斯卡尔在某种程度上区分了真实的"功能和没有返回值的功能;关键字procedure
创建一个不返回任何内容的子例程,关键字function
必须返回某种类型的值。
C是一个模糊这种区别的例子;一个函数可以有一个void
类型的返回值,它实际上是具有一个值的类型(尽管该值实际上并未在代码中表示;您必须假装它存在)。具有此返回类型的每个函数始终返回相同的值。 Python使它更明确;没有return
语句的函数或没有值的return
语句实际上返回单例值None
。
Haskell有一个类似的类型()
,它由一个具有相同名称的值居住。您当然可以定义一个函数族,每个类型一个函数foo :: a -> ()
忽略其参数并返回()
。它没有任何实用价值(作为一种纯语言,函数除了返回其声明的返回类型的值外,不能执行任何操作),但确实存在。 foo _ = ()
。
顺便提一下,类型a -> ()
的函数将()
建立为(伪)类别 Hask 中的终端对象,这对于将 Hask 建立为笛卡尔封闭类别,使其适合于定义Haskell的语义。
但是,Haskell 的类型包含 no 值,适当地称为Void
:
data Void
由于Void
是有效类型,您可以想象一个包含从Void
到任何其他类型的函数的类型:
absurd :: Void -> a
但是,由于没有Void
类型的值,您无法调用这样的功能。类型Void -> a
的唯一函数可以定义为
absurd x = case x of {} -- There's nothing x *can* match
这并不是说absurd
完全没用,只是没有实际用处。就像a -> ()
类型的函数将()
定义为 Hask 中的终端对象一样,absurd
将Void
定义为 initial Hask 中的对象。
(这个答案的后半部分是Bartosz Milewski的一系列精彩帖子Category Theory for Programmers中的一个(不好的)信息概要。)
答案 4 :(得分:0)
在Haskell中, 这个函数 就是返回一个值。
如果一个函数没有返回任何内容,那么它实际上是什么做?
你可能正在考虑类似于打印“功能”的东西,它可以输出一些内容并且不返回任何内容。但这不是一个数学函数,那是一个动作。 Haskell以完全不同的方式对它们进行建模(即monad)。如果你想知道那是什么,那么Stack Overflow上有关于它的数十亿次讨论,并且遍布互联网。