如何在 Haskell 中访问没有记录语法的自定义数据类型的字段?

Posted

技术标签:

【中文标题】如何在 Haskell 中访问没有记录语法的自定义数据类型的字段?【英文标题】:How to Access Fields of Custom Data Types without Record Syntax in Haskell? 【发布时间】:2021-09-08 20:39:34 【问题描述】:

我想了解如何在不使用记录语法的情况下访问自定义数据类型的字段。在 LYAH 中建议这样做:

-- Example
data Person = Subject String String Int Float String String deriving (Show)  

guy = Subject "Buddy" "Finklestein" 43 184.2 "526-2928" "Chocolate"  

firstName :: Person -> String  
firstName (Subject firstname _ _ _ _ _) = firstname  

我尝试通过获取 BST 节点的值来应用这种访问数据的方式:

data Tree a = EmptyTree | Node a (Tree a) (Tree a) deriving (Show, Read, Eq)  

singleton :: a -> Tree a  
singleton x = Node x EmptyTree EmptyTree  
  
treeInsert :: (Ord a) => a -> Tree a -> Tree a  
treeInsert x EmptyTree = singleton x  
treeInsert x (Node a left right)   
    | x == a = Node x left right  
    | x < a  = Node a (treeInsert x left) right  
    | x > a  = Node a left (treeInsert x right) 

getValue :: Tree -> a
getValue (Node a _ _) = a

但我收到以下错误:

有人可以解释如何在不使用记录语法的情况下正确访问该字段错误消息的含义是什么?请注意,我是 Haskell 的初学者。我的目的是了解为什么这种特殊情况会引发错误以及如何正确地做到这一点。我不是要这指向更方便的访问字段的方法(如记录语法)。如果之前有人问过类似的问题:对不起!我真的试着在这里找到答案,但不能。任何帮助表示赞赏!

【问题讨论】:

您应该复制粘贴错误的文本 我知道的其中之一。 【参考方案1】:

您忘记在函数的类型签名中将类型参数添加到Tree

getValue :: Tree -> a

应该是

getValue :: Tree a -> a

期待 `Tree' 的另一个参数

表示类型签名中的Tree 需要一个类型参数,但没有提供一个

需要一个类型,但是 Tree 有一个类型 `* -> *'

Tree a 是一个类型,但 Tree 不是 (?) 因为它需要一个类型参数。

kind 就像一个类型的类型签名。 kind* 表示类型构造函数不需要任何类型的参数。

data Tree = EmptyTree | Tree Int Tree Tree

有一种*

这就像无参数函数的类型签名(我认为从技术上讲,这并不真正称为函数)

f :: Tree Int
f = Node 0 EmptyTree EmptyTree

* -&gt; * 中的kind 表示类型构造函数需要一个参数。

您的Tree 类型有一种* -&gt; *,因为它接受一个类型参数,即= 左侧的a

* -&gt; * 有点像一个接受一个参数的函数:

f :: Int -> Tree Int
f x = Node x EmptyTree EmptyTree

【讨论】:

@MoritzWolff 我添加了对错误的尝试解释:) 感谢您为这样的愚蠢错误提供如此彻底的答案。接受。

以上是关于如何在 Haskell 中访问没有记录语法的自定义数据类型的字段?的主要内容,如果未能解决你的问题,请参考以下文章

Atom 没有突出 Haskell 语法?

如何在 GraphQL 中访问 ACF 关系字段中的自定义字段?

在 haskell -> TRIE 中使用自定义递归数据类型

如何在我们的自定义指令中以角度解码现有的结构指令字符串语法

如何在 PHP 博客上突出显示 Haskell 语法

如何在 Haskell 中嵌套 let 语句?