为可能具有多态参数的函数键入签名 [英] Type signature for function with possibly polymorphic arguments
问题描述
我可以吗?如果是的话,我该如何写一个函数的类型签名:
gfxy =(fx ,fy)
给出:
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
这样:
pre $ g f1 x1 c1 ==([42],['c '))::([Int],[Char])
g f2 x1 x2 ==(126,15)::(Int,Int)
不,你不能。基本问题是Haskell的语法让你认为 f1
的和 f2
的类型更类似比他们真实。一旦翻译成GHC核心,它们看起来更加不同:
f1 :: forall a。 a - > [a]
f2 :: Int - > Int
不仅如此,相应的字词看起来相当不同:
f1 =Λa - >> λ(x :: a) - > [x]
f2 =λ(x :: Int) - > 3 * x
正如您所见, f1
和 f2
实际上有不同数量的参数,其中 f1
类型和值,而 f2
只需要一个值。
在更常见的情况下,当将 f2
放入期望函数类型的上下文中时,比如 Int - > [Int]
,GHC会将 f2
应用于您所需的类型(即实例化 f2
具体类型),一切都会好的。例如,如果您有
g ::(Int - > [Int]) - > Bool
,您可以将 g
应用于 f
,GHC实际上将它编译为
g(f @Int)
但是在这里你需要多态性来判断这个实例是否发生,哪个GHC不支持(我认为这对核心语言来说是一个相当激进和破坏性的变化)。
由于类实例,类型族模式和类型族结果不能量化,所以我很漂亮相信没有办法得到你想要的东西。
Can I, and if so, how do I, write the type signature for a function:
g f x y = (f x, f y)
Such that given:
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
Such that:
g f1 x1 c1 == ([42], ['c']) :: ([Int], [Char])
g f2 x1 x2 == (126, 15) :: (Int, Int)
No, you can't. The basic problem is that Haskell's syntax has fooled you into thinking that f1
's and f2
's types are more similar than they really are. Once translated into GHC Core, they look rather more different:
f1 :: forall a . a -> [a]
f2 :: Int -> Int
Not only this, but the corresponding terms look rather different:
f1 = Λa -> λ(x :: a) -> [x]
f2 = λ(x :: Int) -> 3 * x
As you can see, f1
and f2
actually have different numbers of arguments, where f1
takes a type and a value, and f2
takes just a value.
In more usual circumstances, when you plop f2
into a context expecting a function of type, say, Int -> [Int]
, GHC will apply f2
to the necessary type for you (i.e., instantiate f2
to a specific type), and all will be well. For example, if you have
g :: (Int -> [Int]) -> Bool
and you apply g
to f
, GHC will actually compile that to
g (f @Int)
But here you want polymorphism over whether that instantiation happens or not, which GHC doesn't support (I think it would be a rather radical and destructive change to the core language).
Since class instances, type family patterns, and type family results cannot be quantified, I'm pretty confident there is no way whatsoever to get what you want.
这篇关于为可能具有多态参数的函数键入签名的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!