延迟评估中的原始函数类型
Type of primitive functions in lazy evaluation
我想知道像 Haskell 这样的惰性函数式编程语言中原始函数的确切类型是什么。
假设 thunk 被评估为弱头部范式的对象。那么,在像C这样的严格语言中,原始函数的类型应该是什么?
我的猜测是:
primitive1 : (thunk, thunk, ...) -> thunk
primitive2 : (thunk, thunk, ...) -> object
我认为原始函数应该作为参数传递 thunk,因为它们可能不需要其中的一些。但是,我不知道他们是否应该 return thunk 或 evaluated 对象,而后者必须用下面的一些函数包装以使其惰性。
lazy : ((thunk, thunk, ...) -> object) -> ((thunk, thunk, ...) -> thunk)
在 GHC 中,Haskell 原始函数(有时称为 PrimOp)是
使用混合指针(指向 "heap objects")调用并取消装箱
类型(包括 C 风格的整数、双精度数等)。 Haskell 类型系统
确保 PrimOps 始终获得对象的数量、顺序和类型
他们期望的指针和未装箱的值。这一点很重要
但是要注意,在原语期望指向特定类型堆对象的指针的地方,比如 String
,
它期待一个指向堆对象的指针,该对象可能 是一个列表
构造函数(因为 Haskell String
是一个字符列表) 或 thunk
可以评估为列表构造函数。
因此,Haskell PrimOp 的 "strict" 类型无法区分
在 thunk 和非 thunk 之间。如果有一个原始函数
获取列表的长度,例如(没有),它可能具有类型,使用您的符号, of:
primitiveLength : (list_object) -> unboxed_int
其中 list_object
将是指向 或者 列表的指针
constructor 或 可以生成列表构造函数的thunk。
这确实是唯一明智的做法。 PrimOp 无法控制它的参数是仍然是一个 thunk 还是已经部分(或完全!)评估了一些先前的计算,因此它必须准备好接受任何一个。
类似地,如果 Haskell PrimOp returns 是堆对象,该对象在技术上可以是 thunk 或非 thunk,并且选择对原语的 "strict" 类型签名没有影响。
实际上,PrimOp return thunk 不是很有用。在惰性语言中,调用原语的事实意味着需要它的 return 值。如果它 return 是 thunk,则需要立即评估该 thunk,那么为什么 return 是 thunk?
(编辑添加:)顺便说一句,上面的 PrimOps 没有什么特别的:用户定义的 Haskell 函数也被混合使用指针和未装箱类型调用(而且它们从不 return 砰的一声)。
我想知道像 Haskell 这样的惰性函数式编程语言中原始函数的确切类型是什么。
假设 thunk 被评估为弱头部范式的对象。那么,在像C这样的严格语言中,原始函数的类型应该是什么?
我的猜测是:
primitive1 : (thunk, thunk, ...) -> thunk
primitive2 : (thunk, thunk, ...) -> object
我认为原始函数应该作为参数传递 thunk,因为它们可能不需要其中的一些。但是,我不知道他们是否应该 return thunk 或 evaluated 对象,而后者必须用下面的一些函数包装以使其惰性。
lazy : ((thunk, thunk, ...) -> object) -> ((thunk, thunk, ...) -> thunk)
在 GHC 中,Haskell 原始函数(有时称为 PrimOp)是
使用混合指针(指向 "heap objects")调用并取消装箱
类型(包括 C 风格的整数、双精度数等)。 Haskell 类型系统
确保 PrimOps 始终获得对象的数量、顺序和类型
他们期望的指针和未装箱的值。这一点很重要
但是要注意,在原语期望指向特定类型堆对象的指针的地方,比如 String
,
它期待一个指向堆对象的指针,该对象可能 是一个列表
构造函数(因为 Haskell String
是一个字符列表) 或 thunk
可以评估为列表构造函数。
因此,Haskell PrimOp 的 "strict" 类型无法区分 在 thunk 和非 thunk 之间。如果有一个原始函数 获取列表的长度,例如(没有),它可能具有类型,使用您的符号, of:
primitiveLength : (list_object) -> unboxed_int
其中 list_object
将是指向 或者 列表的指针
constructor 或 可以生成列表构造函数的thunk。
这确实是唯一明智的做法。 PrimOp 无法控制它的参数是仍然是一个 thunk 还是已经部分(或完全!)评估了一些先前的计算,因此它必须准备好接受任何一个。
类似地,如果 Haskell PrimOp returns 是堆对象,该对象在技术上可以是 thunk 或非 thunk,并且选择对原语的 "strict" 类型签名没有影响。
实际上,PrimOp return thunk 不是很有用。在惰性语言中,调用原语的事实意味着需要它的 return 值。如果它 return 是 thunk,则需要立即评估该 thunk,那么为什么 return 是 thunk?
(编辑添加:)顺便说一句,上面的 PrimOps 没有什么特别的:用户定义的 Haskell 函数也被混合使用指针和未装箱类型调用(而且它们从不 return 砰的一声)。