简体   繁体   English

如何获取记录字段? 哈斯克尔

[英]How to get a record field? Haskell

I have a record of Person我有一个记录

data Person = Person
 {name :: Name
 ,lastname :: LastName
 ,personId :: Int
 ,parentList :: [Int]
 ,childList :: [Int]
 ,siblingList ::[Int]
 }
 deriving (Show,Typeable,Data,Eq) 

and get function获得功能

getPersonId::Person -> Int
getPersonId = personId --here why/how can I achieve to get personId field of Person record since I don't have any Person p

They work correctly and I get what I want but I struggle to understand these functions:它们工作正常,我得到了我想要的,但我很难理解这些功能:

idGetters :: [Person->[Int]]
idGetters = [parentList]

ids :: Person -> [[Int]]
ids p = (fmap ($ p)) idGetters

I am studying for functors and applicative at the moment but I should be able to understand idGetters function(or whatever it is because by definition it is list of functions not a function itself)* with the help of what I know so far.我目前正在研究函子应用程序,但我应该能够理解 idGetters 函数(或任何它,因为根据定义它是函数列表而不是函数本身)* 在我目前所知道的帮助下。 What I couldn't understand is :我无法理解的是:

  1. I feel like I need to give a parameter to idGetters type but it doesn't need.我觉得我需要为 idGetters 类型提供一个参数,但它不需要。 Why?为什么? How should I call this?我该怎么称呼这个?
  2. ids p = (fmap ($ p)) idGetters in this line how come can idGetters return p's parentList which is [Int]? ids p = (fmap ($ p)) idGetters在这一行中,idGetters 怎么会返回p 的parentList,即 [Int]?

I feel like I need to give a parameter to idGetters type but it doesn't need.我觉得我需要为 idGetters 类型提供一个参数,但它不需要。 Why?为什么? How should I call this?我该怎么称呼这个?

You can't call it, because it's not a function.你不能调用它,因为它不是一个函数。 Its type is [Person->[Int]] which is not a function but a list of functions.它的类型是[Person->[Int]] ,它不是一个函数,而是一个函数列表

In this case, because of its definition, it's in fact a list containing only one function - but you only know that from the implementation, not the type.在这种情况下,由于它的定义,它实际上是一个仅包含一个函数的列表 - 但您只能从实现中知道这一点,而不是类型。 If that's really the intended implementation then it would probably make more sense to just return that function not wrapped in a list, in which case the type would indeed be a function type Person->[Int] .如果这确实是预期的实现,那么只返回未包含在列表中的函数可能更有意义,在这种情况下,类型确实是函数类型Person->[Int] However, based on the other fields in your record I assume the definition will at some point be extended to include the 3 relevant getter functions: [parentList, childList, siblingList] , and in this case you will of course need a list type.但是,根据您记录中的其他字段,我假设该定义将在某些时候扩展为包括 3 个相关的 getter 函数: [parentList, childList, siblingList] ,在这种情况下,您当然需要一个列表类型。

ids p = (fmap ($ p)) idGetters in this line how come can idGetters return p's parentList which is [Int]? ids p = (fmap ($ p)) idGetters在这一行中,idGetters 怎么会返回 p 的 parentList,即 [Int]?

I'm not quite sure I understand exactly what you're asking, but I accept that the definition can look a little confusing, so I'll try to explain it.我不太确定我完全理解你的要求,但我接受这个定义可能看起来有点混乱,所以我会试着解释一下。

Firstly, the type of ids is given as Person -> [[Int]] , so it's a function that takes a Person and returns a list of lists of Int s.首先, ids的类型以Person -> [[Int]]的形式给出,因此它是一个接受Person并返回Int列表列表的函数。 From this we can tell that the p in the definition above - ids p = ... - must be a Person .由此我们可以看出,上面定义中的p - ids p = ... - 必须是Person

The result of that function call is the result of fmap -ing a function over idGetters .该函数调用的结果是fmapidGetters上执行函数的结果。 We'll worry about exactly what that function is shortly, but for now, just notice that idGetters , as discussed above, is a list of functions each of which is of type Person -> [[Int]] .我们很快就会担心这个函数到底是什么,但现在,请注意idGetters ,如上所述,是一个函数列表,每个函数的类型都是Person -> [[Int]] So the function we fmap over that must take as its argument a function , and this function argument will take a Person as an argument and return a list of lists of Int s.因此,我们对其进行fmap的函数必须将function作为其参数,并且此函数参数将Person作为参数并返回Int列表的列表。

That function, in the definition we are given, is ($ p) , which is a section of the $ operator .在我们给出的定义中,该函数是($ p) ,它是$ 运算符一部分 That operator takes a function and a value and simply applies the function to the value, so when it's sectioned as ($ p) , it's the function that takes another function and applies it to p .该运算符接受一个函数和一个值,并将该函数应用于该值,因此当它被分割为($ p)时,它是一个接受另一个函数并将其应用于p的函数。

(It may be clearer to write this out as follows: (这样写出来可能更清楚:

($ p) = \f -> ($ p) f
      = \f -> f $ p
      = \f -> f p

) )

This hopefully now all fits together nicely.希望现在这一切都很好地结合在一起。 In the context of a function from the list idGetters - which we know must be of type Person -> [Int] - ($ p) must take a Person and apply that function to it, resulting in a list of Int s.idGetters列表中的函数的上下文中 - 我们知道它必须是Person -> [Int]类型 - ($ p)必须接受一个Person并将该函数应用于它,从而产生一个Int列表。 So we we fmap that function over idGetters , we get a list of lists of Int s, which is what we know ids must return (from its type signature).因此,我们将该函数idGetters fmap我们得到一个Int列表的列表,这是我们知道ids必须返回的(从它的类型签名中)。

With the very simply definition of idGetters you have, consisting of the single function parentList , all this will do is, given a Person , output its parentList (which is of type [Int] ) but wrapped inside another list (to have overall type [[Int]] ).有了非常简单的idGetters定义,由单个函数parentList组成,所有这一切都是,给定一个Person ,输出它的parentList (类型为[Int] )但包装在另一个列表中(具有整体类型[[Int]] )。 If, as I suggested earlier, idGetters was a list of the 3 relevant functions: [parentList, childList, siblingList] , then ids when applied to a Person would return a list of 3 sublists, which are respectively the parentList , childList and siblingList of that particular person.如果,正如我之前建议的那样, idGetters是 3 个相关函数的列表: [parentList, childList, siblingList] ,那么ids在应用于Person时将返回一个包含 3 个子列表的列表,它们分别是parentListchildListsiblingList那个特定的人。 So it's actually a fairly straightforward function, just packaging up some of the information from a Person 's definition in some perhaps-relevant way.所以它实际上是一个相当简单的函数,只是以某种可能相关的方式将来自Person定义的一些信息打包。

I hope this clears up your questions - if not, please let me know in the comments.我希望这可以解决您的问题 - 如果没有,请在评论中告诉我。

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

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