如何确定Haskell中常量表达式的类型?

时间:2009-06-09 08:10:49

标签: haskell types functional-programming

我正在尝试修改我的函数编程考试,并且对过去论文的第一个问题感到困惑,是的,我们不允许使用解决方案表,这是过去论文中第一个问题的示例。

  

对于以下每个表达式,在Haskell中给出它的类型(对于有许多类型的表达式,只需给出一种类型)。

(True, "hello", 42)
[42, 4, 2]
length [True]
filter even

我个人认为,对于一个和两个的答案将是一个bool,String和int元组以及一个int的列表,这是正确的假设吗?第二,你如何回答3和4,我确定长度True只输出一个具有该长度的所有元素的列表,并且该过滤器甚至只是将一个int列表更改为所有偶数的列表,尽管如何我可以把它作为答案吗?

3 个答案:

答案 0 :(得分:6)

如果您想使用ghci使变量类型脱机,则必须输入
   :t 表达

如果你想在ghci中创建变量,你必须使用let而不使用'in'(如monad的表示法,我不知道你是否已经看过它们):
   let var = expr

如果你自己检查一下,你应该能够更容易地为你的考试记住它。 (祝你好运;))

答案 1 :(得分:1)

length [True]将为Int,它将返回1.您可以使用ghci或lambdabot进行检查。

过滤即使是(Integral a) => [a] -> [a] 例如,[Int] -> [Int]

我觉得这有点无意义,因为lambdabot可以告诉你所有这些事情。

答案 2 :(得分:1)

准确地说,[42,4,2]的类型将是

Num a => [a]

这是因为Haskell中的整数文字被视为在其前面有一个隐含的“fromIntegral”,所以实际表达式是[fromIntegral 42,fromIntegral 4,fromIntegral 2]。

“fromIntegral”是Num类的一部分,其类型为

fromIntegral :: (Integral a, Num b) => a -> b

这表示它将某个Integral类型的实例(即Int或Integer)转换为任意其他数字类型(Int,Float,Double,Complex ...)。这就是为什么你可以说“43.2 + 1”而不会出现类型错误的原因。

“length [True]”将具有Int类型,因为“length”具有类型“[a] - > Int”,并且提供了参数(Bool列表)。

“过滤均匀”有点复杂。从“过滤器”类型开始:

filter :: (a -> Bool) -> [a] -> [a]

第一个参数(括号中的位)本身就是一个获取列表项并返回Bool的函数。请记住“ - >” Haskell类型中的运算符是右关联的,因此如果您放入隐含的括号,您会看到类型为:

filter :: (a -> Bool) -> ([a] -> [a])

换句话说,如果你给它第一个参数,你会得到一个期望第二个参数的新函数。在这种情况下,第一个参数是:

even :: (Integral a) => a -> Bool

这引入了轻微的皱纹:“even”要求其参数为Integral类型(即Int或Integer,如上所述),因此必须将此约束传播到结果。如果不是那么你可以这样写:

filter even "foo"

因此答案是:

filter even :: (Integral a) => [a] -> [a]

你可以看到积分约束来自“偶数”类型,而其余类型来自“过滤器”。

相关问题