所以今天我正在玩Haskell,考虑给出类型的函数定义的自动生成。
例如,函数的定义
twoply :: (a -> b, a -> c) -> a -> (b, c)
鉴于类型(如果我排除使用undefined :: a
),对我来说是显而易见的。
然后我想出了以下内容:
¢ :: a -> (a ->b) -> b
¢ = flip ($)
其中有一个有趣的属性
(¢) ¢ ($) :: a -> (a -> b) -> b
这让我想到了我的问题。鉴于=::=
的关系“与...具有相同的类型”,语句x =::= x x ($)
是否唯一地定义了x
的类型?必须x =::= ¢
,或x
还有其他可能的类型吗?
我试图从x =::= x x ($)
向后工作以推断x :: a -> (a -> b) -> b
,但却陷入困境。
答案 0 :(得分:8)
x =::= x x ($)
也适用于x = const
,其类型为a -> b -> a
。因此它不能唯一地识别类型。
答案 1 :(得分:8)
我想补充一点,你应该看一下http://hackage.haskell.org/package/djinn。它可以采用许多类型签名并从中派生出实现。如果djinn理解的类型只有一种可能的实现,它将产生它。
答案 2 :(得分:1)
从上面的等式中,我们可以确定x的某些类型签名。 X不需要这种类型,但它需要至少统一这种类型。
$ :: forall a b. (a -> b) -> a -> b
x :: t1 -> ((a -> b) -> a -> b) -> t1
鉴于此,编写大量x的实现应该是直截了当的。