我可以,如果可以,我该如何为函数编写类型签名:
g f x y = (f x, f y)
这样给出:
f1 :: a -> [a]
f1 x = [x]
x1 :: Int
x1 = 42
c1 :: Char
c1 = 'c'
f2 :: Int -> Int
f2 x = 3 * x
x2 :: Int
x2 = 5
这样:
g f1 x1 c1 == ([42], ['c']) :: ([Int], [Char])
g f2 x1 x2 == (126, 15) :: (Int, Int)
最佳答案
不,你不能。基本问题是 Haskell 的语法让你误以为 f1
的和 f2
的类型比实际情况更相似。一旦翻译成 GHC Core,它们看起来就大不相同了:
f1 :: forall a . a -> [a]
f2 :: Int -> Int
不仅如此,相应的术语看起来也大不相同:f1 = Λa -> λ(x :: a) -> [x]
f2 = λ(x :: Int) -> 3 * x
如您所见,f1
和 f2
实际上有不同数量的参数,其中 f1
接受一个类型和一个值,f2
只取一个值。在更常见的情况下,当你扑通
f1
进入期望类型函数的上下文,例如 Int -> [Int]
, GHC 将申请f1
为您所需的类型(即,将 f1
实例化为特定类型),一切都会好起来的。例如,如果您有g :: (Int -> [Int]) -> Bool
你申请g
至f1
, GHC 实际上会将其编译为g (f1 @Int)
但是在这里,您需要关于该实例化是否发生的多态性,这是 GHC 不支持的(我认为这将是对核心语言的一个相当激进和破坏性的改变)。由于类实例、类型族模式和类型族结果无法量化,我非常有信心没有办法得到你想要的。
关于haskell - 具有可能多态参数的函数的类型签名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38603014/