为可能具有多态参数的函数键入签名 [英] Type signature for function with possibly polymorphic arguments

查看:110
本文介绍了为可能具有多态参数的函数键入签名的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我可以吗?如果是的话,我该如何写一个函数的类型签名:

  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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆