简体   繁体   English

检查并查找Haskell中的类型

[英]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 constconst我认为是正确的,但如果我错了)。 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM