Purescript中UnsafePartial为何可作用于非Partial函数?
关于PureScript中Partial约束与自定义受限函数的问题
为什么unsafePartial能调用无Partial约束的函数
PureScript的约束系统里,无约束的表达式可以兼容带任意额外约束的上下文。unsafePartial的类型是forall a. (Partial => a) -> a,它要求参数是一个“在Partial约束下能产生a的表达式”。而goodFn 1的类型是Effect Int,这个表达式不依赖任何约束——也就是说,不管有没有Partial约束,它都能正常生成Effect Int,所以它自然满足Partial => Effect Int的要求(相当于约束被“忽略”了,因为表达式不需要用到它)。这是编译器的正常行为,因为约束是对表达式的能力增强,而非限制:如果一个表达式不需要约束就能工作,那给它加上约束当然也能工作。
如何实现必须通过runner才能调用的自定义函数
要让函数必须通过runner调用,关键是让函数的类型必须依赖自定义的约束,而不是可选的。步骤如下:
- 定义一个自定义的空约束类型(和Partial类似):
class MyPartial
- 让目标函数的类型明确依赖这个约束,比如:
myRestrictedFn :: MyPartial => Int -> Effect Int myRestrictedFn n = pure (n + 1)
- 定义对应的runner函数,用来解除这个约束:
unsafeRunMyPartial :: forall a. (MyPartial => a) -> a unsafeRunMyPartial f = f -- 这里可以根据需要添加安全检查或日志逻辑
此时,直接调用myRestrictedFn 1会触发编译器错误,因为缺少MyPartial约束;必须通过unsafeRunMyPartial $ myRestrictedFn 1才能正常调用。
原理是:myRestrictedFn的类型明确要求必须存在MyPartial约束才能调用,而普通上下文没有这个约束,所以无法直接调用。只有通过runner函数(它内部提供了该约束的实现,或者直接忽略约束),才能解除这个限制。
内容的提问来源于stack exchange,提问作者Saravanan
相关产品推荐
相关产品推荐

