您可以将记录语法与Haskell数据类型中的枚举混合使用吗?

时间:2017-08-17 00:01:44

标签: haskell functional-programming

我写了以下内容:

cmd + /

问题是,如果我尝试使用int构造一个Expression,我会得到一个部分应用的函数。解决这个问题的最佳方法是什么?

2 个答案:

答案 0 :(得分:7)

事先要了解的事情:

  • Haskell data声明中的每个数据构造函数都有自己的名称
  • 数据构造函数位于与类型名称
  • 完全独立的命名空间中

正如评论所述,您正在定义名为Expression的类型和名为Expression的数据构造函数。因为Haskell为类型和数据构造函数提供了单独的命名空间,所以编译器就可以了。

此外,您正在创建名为Int的第二个数据构造函数(同样不会与名为Int的现有类型冲突)。这可能不是你想要的,而且很难引导!

当您尝试构造诸如myExpr = Expression x y之类的值时,您使用的是第一个数据构造函数,而不是类型名称或第二个数据构造函数。 Expression数据构造函数需要两个参数:首先是Int,然后是Expression。这就是为什么,如果你只是提供第一个参数,你将得到一个部分应用的函数。

您的示例的更正,更惯用的版本可能是:

data Expression = Assignment { lhs :: Int, rhs :: Expression }
                | Literal { value :: Int }

如果它是 only 数据构造函数,那么看到一个与其类型同名的数据构造函数实际上是很常见的:

data Foo = Foo { unwrapFoo :: Int }

答案 1 :(得分:4)

为了完整起见,你问题的答案是肯定的。另一个答案为您当前的代码提供了很好的解释,但对您的问题的简短回答是

data Expression = Assignment { lhs :: Int, rhs :: Expression }
                | Literal Int

是完全有效的类型声明。话虽如此,它并不是非常惯用,所以如果你要使用记录语法,你应该将它用于给定类型的每个数据构造函数。