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

nor*_*ane 3 haskell functional-programming

我写了以下内容:

data Expression = Expression { lhs :: Int, rhs :: Expression } | Int
Run Code Online (Sandbox Code Playgroud)

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

com*_*orm 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 }
Run Code Online (Sandbox Code Playgroud)

实际上,如果它是唯一的数据构造函数,则看到与其类型具有相同名称的数据构造函数是相当常见的:

data Foo = Foo { unwrapFoo :: Int }
Run Code Online (Sandbox Code Playgroud)