[英]Check and find type in Haskell
The question is: 问题是:
Give a type declaration of
(f True) (f 1)
such that it is well-typed or explain why it cannot exist. 给出(f True) (f 1)
的类型声明,使其类型正确,或说明为什么它不存在。
Kindly please help me as I am unable to understand how to define type declaration. 请帮助我,因为我无法理解如何定义类型声明。 Thank you. 谢谢。
Here is how I would infer the type of f
from your expression. 这是我从您的表达式中推断f
的类型的方法。 Note that I'm not presenting how GHC works but how my "brain type checker" works. 请注意,我不是在介绍GHC的工作原理,而是我的“大脑类型检查器”的工作原理。
f True
is applied to a value, which means that the f
on the left has type f True :: a -> b
, so f :: Bool -> a -> b
. f True
应用于值,这意味着左侧的f
具有f True :: a -> b
f :: Bool -> a -> b
f True :: a -> b
,因此f :: Bool -> a -> b
。
On the right, we have f 1
, which means that on the right f :: (Num a) => a -> b
, this is when my internal type checker starts to complain, because from the application of f
on the left, I see that f
can be applied to Bool
, and on the right that it can be applied to a number, but Bool
is not an instance of the Num
class. 在右边,我们有f 1
,这意味着在右边f :: (Num a) => a -> b
,这是我的内部类型检查器开始抱怨的时候,因为在左边使用f
时,我看到f
可以应用于Bool
,而右边可以将其应用于数字,但是Bool
不是Num
类的实例。
However this still type checks if there is no constraint on the first argument, so we have f :: a -> b
and… we can't really say anything else I think. 但是,此类型仍会检查第一个参数是否没有约束,因此我们有f :: a -> b
和...我们真的不能说其他话。 (Because b
can be any type, it is perfectly possible that b
is actually a c -> d
, so we can obtain a new function from applying f
partially.) (由于b
可以是任何类型,因此b
实际上很可能是c -> d
,因此我们可以通过部分应用f
获得新函数。)
Note though that even if this type checks (you can check it in GHCi), it is very unlikely that f
as a meaningful definition, in fact the only function it can represent that is not undefined
is const
I think (but correct if I'm wrong). 请注意,尽管即使此类型检查(可以在GHCi中检查它),也不太可能将f
作为有意义的定义,实际上,它可以表示的唯一undefined
const
是const
我认为是正确的,但如果我错了)。 You can say that because there is no constraint on the type of the first argument which is rather strange… 您可以说,因为第一个参数的类型没有任何限制,这很奇怪……
According to your comment f :: a -> b -> Bool
(I was trying to have the most general type possible from the information given by the expression you typed, this is my result is a bit more general.) 根据您的评论f :: a -> b -> Bool
(我试图从您键入的表达式给出的信息中获得最通用的类型,这是我的结果更加通用。)
There is only one way to define such a function without using undefined
, it has to be a function that discards both its argument and give a constant. 只有一种方法可以不使用undefined
来定义这样的函数,它必须是一个既放弃参数又给出常量的函数。 Because there is no way f
can be defined for any type immaginable. 因为无法为任何无法想象的类型定义f
。 So the definition of f
is something like: 所以f
的定义是这样的:
f _ _ = True
When you apply f True
to f 1
, you apply f True :: b -> Bool
to a function f 1 :: b -> Bool
, this is well typed because b
is a type variable, it can be anything, in particular it is perfectly fine for b
to be a c -> Bool
, and in that case, the type of f True
is in fact f True :: (c -> Bool) -> Bool
. 将f True
应用于f 1
,将f True :: b -> Bool
应用于函数f 1 :: b -> Bool
,由于b
是类型变量,因此可以很好地键入它,可以是任何东西,尤其是它b
最好是c -> Bool
,在这种情况下, f True
的类型实际上是f True :: (c -> Bool) -> Bool
。 Is it clearer? 比较清楚吗?
If you have the body of f, you can type ":tf" in GHCI (the haskell interpreter) to get its type. 如果您具有f的主体,则可以在GHCI(haskell解释器)中键入“:tf”以获取其类型。
If all you know about f is that (f True) (f 1) compiles, then f could be any constant function of 2 variables, like \\xy -> 2 :: a -> b -> Int
, or \\xy = "foo" :: a -> b -> String
or even \\xy -> readFile "any.txt" :: a -> b -> IO (String)
. 如果您对f的所有了解是(f True)(f 1)进行编译,则f可以是2个变量的任何常数函数,例如\\xy -> 2 :: a -> b -> Int
或\\xy = "foo" :: a -> b -> String
\\xy -> readFile "any.txt" :: a -> b -> IO (String)
\\xy = "foo" :: a -> b -> String
甚至\\xy -> readFile "any.txt" :: a -> b -> IO (String)
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.