为什么此实现无效? [英] Why is this implementation invalid?

查看:103
本文介绍了为什么此实现无效?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我具有以下类型签名:

Let's say I have the following type signature:

someFunction :: (Eq a, Eq b) => a -> b

实施:

someFunction x = (2 :: Int)

(不要看得太深,这只是一个例子).

(Don't look in to it too far, it's just an example).

我对签名的理解是"someFunction接受作为Eq类型类的实例的参数,并返回作为Eq实例的值(可以是其他类型)类型类". IntEq的一个实例,那么GHC为什么会对这种实现感到不满?

My understanding of the signature is that "someFunction takes an argument that is an instance of the Eq typeclass, and returns a value (that can be of a different type) that is an instance of the Eq typeclass". Int is an instance of Eq, so why does GHC get upset about this implementation?

该错误使其很明显:

Couldn't match expected type ‘b’ with actual type ‘Int’
     ‘b’ is a rigid type variable bound by
       the type signature for:
         someFunction :: forall a b. (Eq a, Eq b) => a -> b

我想我不明白的是它必须永久"工作的要求.b.使用此功能的任何代码都应仅依赖于bEq的实例的事实,对吗?在我看来,实现确实与签名匹配.那我的实现又违反了此签名的期望吗?

I guess what I don't understand is the requirement that it work "forall" b. Any code using this function should only rely on the fact that b is an instance of Eq, right? In my head, the implementation does match the signature. What about my implementation is breaking the expectations of this signature?

推荐答案

不,您的类型签名实际上是

No, your type signature, which is actually

forall a b. (Eq a, Eq b) => a -> b

表示您的函数必须可以由调用站点确定的任何类型ab调用,只要两者都是Eq.

means that your function must be callable with any types a and b, as determined by the call site, as long as both are instances of Eq.

决定返回哪种类型的不是您的函数.确定结果的是函数的 use .

It is not your function that decides what type to return. It's your function's use that determines that.

所以你应该能够写

    let { i :: Int; i = 1;
          n :: Integer; y :: Double;
          n = foo i;   -- foo :: Int -> Integer
          y = foo i    -- foo :: Int -> Double
        }

并且您可以看到,该函数的唯一实现是 no 实现:

and as you can see, the only implementation for your function is no implementation:

foo _ = x where {x = x}

因为您无法产生所需的 any 类型的值.该类型可以是任何东西,而您对此一无所知.

because you have no way to produce a value of any type that's demanded of you. That type can be anything, and you have no way of knowing anything about it.

顺便说一句, other 类型类实际上可能允许您在此处定义某物,例如

By the way other typeclasses might actually allow you to define something here, like

foo :: (Enum a, Enum b, Bounded a, Bounded b) => a -> b 
foo a = snd . last $ zip [minBound .. a] (cycle [minBound ..])

我并不是说这是一个明智的定义,只是可能:

I'm not saying it's a sensible definition, just that it is possible:

> foo () :: Bool
False

> foo True :: Int
-9223372036854775807

> foo (0 :: Int) :: Bool
Interrupted.

对于来自较常用语言的程序员来说,普遍认为它是foo :: (Eq a) => a的意思,即我可以定义foo来返回我想要的任何类型,只要它在Eq中就可以了".没有. :)

It is probably a common misconception for programmers coming from the more usual languages to think that foo :: (Eq a) => a means "I get to define foo to return any type I want, as long as it is in Eq". It doesn't. :)

这篇关于为什么此实现无效?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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