简体   繁体   English

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

[英]How to Access Fields of Custom Data Types without Record Syntax in Haskell?

I'd like to understand how to access fields of custom data types without using the record syntax.我想了解如何在不使用记录语法的情况下访问自定义数据类型的字段。 In LYAH it is proposed to do it like this:在 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  

I tried applying this way of accessing data by getting the value of a node of a BST:我尝试通过获取 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

But I got the following error:但我收到以下错误:

错误信息

Could someone explain how to access the field correctly without using the record syntax and what the error message means?有人可以解释如何在不使用记录语法的情况下正确访问该字段以及错误消息的含义吗? Please note that I'm a beginner in Haskell.请注意,我是 Haskell 的初学者。 My purpose is to understand why this particular case throws an error and how to do it it correctly.我的目的是了解为什么这种特殊情况会引发错误以及如何正确执行此操作。 I'm not asking this to be pointed to more convenient ways of accessing fields (like the record syntax).我不是要求将其指向更方便的访问字段的方法(如记录语法)。 If someone asked a similar question before: Sorry!如果之前有人问过类似的问题:对不起! I really tried finding an answer here but could not.我真的试图在这里找到答案,但找不到。 Any help is appreciated!任何帮助表示赞赏!

You forgot to add the type parameter to Tree in your function's type signature您忘记在函数的类型签名中将类型参数添加到Tree

getValue :: Tree -> a

should be应该

getValue :: Tree a -> a

Expecting one more argument to `Tree'期待“树”的另一个论据

means that Tree in the type signature is expecting a type argument, but wasn't provided one意味着类型签名中的Tree一个类型参数,但没有提供一个

Expected a type, but Tree has a kind `* -> *'需要一个类型,但 Tree 有一个 `* -> *'

Tree a is a type, but Tree isn't (?) because it is expecting a type argument. Tree a是一种类型,但Tree不是 (?) 因为它需要一个类型参数。

A kind is like a type signature for a type. kind就像类型的类型签名。 A kind of * means the type constructor does not expect any type of argument. kind *表示类型构造函数不期望任何类型的参数。

data Tree = EmptyTree | Tree Int Tree Tree

has a kind of *有一种*

It is like the type signature of a no-argument function (technically this is not really called a function, I think)它就像一个无参数函数的类型签名(从技术上讲,这并不是真正的函数,我认为)

f :: Tree Int
f = Node 0 EmptyTree EmptyTree

A kind of * -> * means the type constructor expects an argument. kind * -> *表示类型构造函数需要一个参数。

Your Tree type has a kind of * -> * , because it takes one type argument, the a on the left hand side of = .你的Tree类型有着怎样的* -> * ,因为它需要一个类型参数, a对左侧=

A kind of * -> * is sort of like a function that takes one argument:一种* -> *有点像一个接受一个参数的函数:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM