Mik*_*cki 13 haskell types higher-order-functions
假设我有更高阶的功能f :: (a -> b) -> (a -> b).但f只有在输入函数是满射的情况下才能正常运行.反正有没有迫使这种情况发生在Haskell?例如,我真的希望f类型签名是这样的:
f :: (Surjective (a -> b)) => (a -> b) -> (a -> b)
Run Code Online (Sandbox Code Playgroud)
但这不起作用,因为我不希望a -> b声明该类型的所有函数都是满射的,只是其中的一部分.例如,可以f将满射函数转换为非满射函数.
我们可以将函数包装在一个特殊的数据类型中data Surjective f = Surjective f,然后定义
f :: Surjective (a -> b) -> (a -> b)
Run Code Online (Sandbox Code Playgroud)
但这会使很难为函数分配多个属性.
在练习中有没有方便的方法呢?这在理论上是否可行?
module Surjectivity where
open import Data.Product using ( ?; ,_ )
open import Relation.Binary.PropositionalEquality using ( _?_; refl )
Surjective : ? {a b} {A : Set a} {B : Set b} ? (A ? B) ? Set _
Surjective {A = A} {B = B} f = ? (y : B) ? ? ? (x : A) ? f x ? y
Run Code Online (Sandbox Code Playgroud)
例如,id是outjective(一个简单的证明):
open import Function using ( id )
id-is-surjective : ? {a} {A : Set a} ? Surjective {A = A} id
id-is-surjective _ = , refl
Run Code Online (Sandbox Code Playgroud)
采用另一种仅适用于射影函数的身份函数:
id-for-surjective's : ? {a b} {A : Set a} {B : Set b} ? (F : A ? B) ? {proof : Surjective F} ? A ? B
id-for-surjective's f = f
Run Code Online (Sandbox Code Playgroud)
我们可以通过id到id-for-surjective's其满射的证明作证:
id? : ? {a} {A : Set a} ? A ? A
id? = id-for-surjective's id {proof = id-is-surjective}
Run Code Online (Sandbox Code Playgroud)
这id?与以下功能相同id:
id?id? : ? {a} {A : Set a} ? id {A = A} ? id?
id?id? = refl
Run Code Online (Sandbox Code Playgroud)
试图传递非射影函数id-for-surjective's是不可能的:
open import Data.Nat using ( ? )
f : ? ? ?
f x = 1
f? : ? ? ?
f? = id-for-surjective's f {proof = {!!}} -- (y : ?) ? ? (? x ? f x ? y) (unprovable)
Run Code Online (Sandbox Code Playgroud)
与之相似,许多其他特性可以以这样的方式来表达,阿格达的标准库已经具备必要的定义(例如Function.Surjection,Function.Injection,Function.Bijection等模块).