【问题标题】:Why does my Haskell function return a type instead of a value?为什么我的 Haskell 函数返回的是类型而不是值?
【发布时间】:2021-01-06 21:09:45
【问题描述】:

我很难理解 Haskell 中的类型创建。我试图理解为什么下面的 Haskell 函数返回一个类型而不是一个值:

data Exp = Enum Int

data Val = Vnum Int

eval :: Exp -> Val
eval (Enum x) = Vnum x

x :: Exp
x = Enum 2

当我运行“eval x”时,解释器并没有像我期望的那样返回 2,而是返回“eval x :: Val”。 Enum 和 Vnum 只是标签,所以 eval 函数基本上接受一个“表达式”作为参数,实际上只是一个整数,并返回一个“值”,也就是一个整数。

就像,当然 eval x 返回一个 Val,但为什么函数实际上并没有计算值并返回它呢?我的印象是答案就在我的脸上,但与此同时,我一定遗漏了一些基本概念,这使我无法注意到可能很明显的事情。

提前感谢您的帮助!

【问题讨论】:

  • 你能显示你如何在解释器中输入的日志吗?因为这似乎是问题所在。
  • 你是不是想写eval :: Exp -> Int; eval (Enum x) = x? Exp 和 Val 本质上是相同的类型,只是使用不同的名称来包装 Int 值。 (它们是我们所说的同构类型;您可以将一个值转换为另一个值而不会丢失任何信息。)
  • @chepner 我希望有两种不同的类型。这看起来像是评估者的前奏。被评估的语言无疑会区分表达式和值(2 + 2 是一个有效的表达式,但不是一个有效的值)。所以我们需要两种类型来区分,即使在早期没有区别。

标签: haskell types functional-programming


【解决方案1】:

为什么我的 Haskell 函数返回一个类型

它没有。你的函数工作得很好,eval x 确实给出了一个Val 类型的值。

但是请注意,解释器无法显示此值 - 就它而言,这是一个完全不透明的类型。至少 GHCi 很清楚地说明了这一点:

<interactive>:3:1: error:
    • No instance for (Show Val) arising from a use of ‘print’
    • In a stmt of an interactive GHCi command: print it

只有当你说你真的只对类型感兴趣时,通过使用:t 或:type 指令,它才会显示:

> :t eval (Enum 2)
eval (Enum 2) :: Val

启用打印值的最简单方法是派生Show 实例:

data Val = Vnum Int   -- incidentally, this should probably be `newtype`,
 deriving (Show)      -- rather than `data`
> eval (Enum 2)
Vnum 2

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-06-07
    • 1970-01-01
    • 1970-01-01
    • 2016-11-08
    • 2014-04-09
    • 2021-11-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多