简体   繁体   English

Haskell获取数据构造器的类型

[英]Haskell get types of Data Constructor

I was wondering if given a constructor, such as: 我想知道是否给出了一个构造函数,例如:

data UserType = User
  { username :: String
  , password :: String
  } -- deriving whatever necessary

What the easiest way is for me to get something on the lines of [("username", String), ("password", String)] , short of just manually writing it. 对我来说,最简单的方法是在[("username", String), ("password", String)] ,而不仅仅是手动编写。 Now for this specific example it is fine to just write it but for a complex database model with lots of different fields it would be pretty annoying. 现在对于此特定示例,只需编写它就可以了,但是对于具有许多不同字段的复杂数据库模型而言,这将非常烦人。

So far I have looked through Typeable and Data but so far the closest thing I have found is: 到目前为止,我已经研究了TypeableData但到目前为止,发现的最接近的是:

user = User "admin" "pass"
constrFields (toConstr user)

But that doesn't tell me the types, it just returns ["username", "password"] and it also requires that I create an instance of User. 但这并不能告诉我类型,它只返回["username", "password"] ,还要求我创建User的实例。

I just knocked out a function using Data.Typeable that lets you turn a constructor into a list of the TypeRep s of its arguments. 我刚刚使用Data.Typeable了一个函数,该函数使您可以将构造函数转换为其参数的TypeRep列表。 In conjunction with the constrFields you found you can zip them together to get your desired result: 结合您发现的constrFields ,可以将它们压缩在一起以获得所需的结果:

{-# LANGUAGE DeriveDataTypeable #-}

module Foo where
import Data.Typeable
import Data.Typeable.Internal(funTc)

getConsArguments c = go (typeOf c)
   where go x = let (con, rest) = splitTyConApp x    
                in if con == funTc         
                   then case rest of (c:cs:[]) -> c : go cs
                                     _ -> error "arrows always take two arguments"
                   else []                      

given data Foo = Foo {a :: String, b :: Int} deriving Typeable , we get 给定data Foo = Foo {a :: String, b :: Int} deriving Typeable ,我们得到

*> getConsArguments Foo
[[Char],Int]

As one would hope. 就像人们希望的那样。


On how to get the field names without using a populated data type value itself, here is a solution: 关于如何在不使用填充的数据类型值本身的情况下获取字段名称的方法,这是一种解决方案:

constrFields . head . dataTypeConstrs $ dataTypeOf (undefined :: Foo)

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

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