【问题标题】:How do I determine the type of constant expressions in Haskell?如何确定 Haskell 中常量表达式的类型?
【发布时间】:2014-06-06 06:05:39
【问题描述】:

我正在尝试修改我的函数式编程考试,但在过去试卷的第一个问题上遇到了困难,是的,我们不允许使用解决方案表,这是过去试卷第一个问题的示例。

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

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

我个人认为,1 和 2 的答案分别是 bool、String 和 int 的元组以及 int 的列表,这是正确的假设吗?其次,您将如何回答 3 和 4,我确定 length True 只是输出具有该长度的所有元素的列表,并且该过滤器甚至只是将整数列表更改为所有偶数的列表,尽管如何我可以将此作为答案吗?

【问题讨论】:

    标签: haskell types functional-programming


    【解决方案1】:

    如果您想使用 ghci 离线获取变量类型,您必须输入
    :t表达式

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

    如果您自己检查所有内容,您应该能够在考试中更轻松地记住它。 (祝你好运;))

    【讨论】:

    • 让不是“像在 monads 中一样”;常规函数可以使用 let,例如 f x = let y = x * x in x + y
    【解决方案2】:

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

    过滤器甚至会是(Integral a) => [a] -> [a] 例如[Int] -> [Int]

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

    【讨论】:

    • GHCi 也可以告诉你所有这些事情。
    【解决方案3】:

    准确地说,[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
    

    这引入了一个小问题:“偶数”要求它的参数是一个 Integral 类型(即 Int 或 Integer,如上所述),所以这个约束必须传播到结果。如果不是,那么你可以这样写:

    filter even "foo"
    

    因此答案是:

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

    可以看到 Integral 约束来自“even”类型,而其余类型来自“filter”。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-05-03
      • 2013-09-12
      • 1970-01-01
      • 1970-01-01
      • 2023-03-22
      • 1970-01-01
      • 2012-03-18
      • 1970-01-01
      相关资源
      最近更新 更多