我正在尝试修改我的函数编程考试,并且对过去论文的第一个问题感到困惑,是的,我们不允许使用解决方案表,这是过去论文中第一个问题的示例。
对于以下每个表达式,在Haskell中给出它的类型(对于有许多类型的表达式,只需给出一种类型)。
(True, "hello", 42) [42, 4, 2] length [True] filter even
我个人认为,对于一个和两个的答案将是一个bool,String和int元组以及一个int的列表,这是正确的假设吗?第二,你如何回答3和4,我确定长度True只输出一个具有该长度的所有元素的列表,并且该过滤器甚至只是将一个int列表更改为所有偶数的列表,尽管如何我可以把它作为答案吗?
答案 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]
你可以看到积分约束来自“偶数”类型,而其余类型来自“过滤器”。