Haskell 使用Void的实例

Haskell 使用Void的实例,haskell,types,type-systems,curry-howard,Haskell,Types,Type Systems,Curry Howard,编辑:通过Void,我指的是Haskell的Void类型,即不能有值但未定义的空类型 关于Swift Evolution是否将noreturn函数属性替换为实际的Void类型,目前正在进行讨论。为此,我们必须确保这将为平台带来真正的好处。仅使用Void作为返回类型是不够的 因此,我要求您提供非常实用的示例,其中使用Void可以增加代码的清晰度、简洁性和通用性。也许它将使用类(在Haskell意义上),也许是泛型,也许它将在ADT中合并Void 但是,请不要过分关注HKT,Monads,所有那些高

编辑:通过
Void
,我指的是Haskell的
Void
类型,即不能有值但
未定义的空类型

关于Swift Evolution是否将
noreturn
函数属性替换为实际的
Void
类型,目前正在进行讨论。为此,我们必须确保这将为平台带来真正的好处。仅使用
Void
作为返回类型是不够的

因此,我要求您提供非常实用的示例,其中使用
Void
可以增加代码的清晰度、简洁性和通用性。也许它将使用类(在Haskell意义上),也许是泛型,也许它将在ADT中合并
Void

但是,请不要过分关注HKT,Monads,所有那些高级的东西。标准库中的实用程序函数也是一个坏例子。一个完美的例子是街机游戏或类似游戏的一部分。

(将
Void
称为无值类型,这与只有一个值的类型(通常称为单位)不同。)

在Haskell流媒体库(如或)中,有一些数据类型表示“类型
a
的值的源,一旦耗尽,返回类型
r
”的值。类似于
Producer a m r
m
是一个基本单子,但在这里不相关。)

让生产者返回一个值(与运行时发出的值类型无关的类型)实际上非常有用。例如,您可以将“流式拆分器”定义为具有以下类型的函数:

streamingSplit :: Producer a m r -> Producer a m (Producer a m r)
此函数用于分割生产者,而不必在内存中累积分割前的所有元素

现在,如果我们想在类型级别上表达一个生产者从不停止生产东西,该怎么办?我们可以让它返回类型为
Void
的值,比如
Producer a m Void

另一个可能的用例。假设有一个高阶函数接受可能失败的回调。比如:

-- does something with the wrapped callback, maybe emit a log message or whatever
takesACallback :: (a -> IO (Either e r)) -> a -> IO (Either e r)
如果我们想为永不失败的函数定义一个版本的
takesACallback
,该怎么办?进出
都是一件麻烦事,在获取值时会导致虚假的模式匹配

使用
Void
我们可以首先将
a->IO r
转换为
a->IO(任意一个Void r)
,将其传递到
takesACallback
,然后使用函数删除任意一个上的“伪”错误分支

takesACallback':: (a -> IO r) -> a -> IO r
takesACallback' callback = fmap (either absurd id) 
                         . takesACallback (fmap Right . callback) 

这就是黑客攻击的一个例子。

你说的是一个只有一个值的单位类型(mod.undefined)还是一个真正的void类型(除了通常未定义的值之外没有其他值)?void没有居民,所以你怎么能返回void类型的东西。@pdexter很多语言都使用void作为单位类型(C、Java等)的特殊替代品嗯,我不认为这会得到任何合适的答案-我建议你访问haskell IRC或reddit频道,而不是看。也谢谢你,这真的很有帮助!不能向上投票,但已被接受。@Anton3生产者不停止的另一种说法是保留返回类型多态性(它可以是任何类型,因为它从未实际返回)。这只是因为多态(独立)返回类型同构于Void。