简体   繁体   English

将数据构造函数映射到类型

[英]Mapping data constructors to types

I'm creating an application that allows an admin to build a form, which a user can fill out. 我正在创建一个允许管理员构建表单的应用程序,用户可以填写该表单。 Questions can be of different types. 问题可以是不同类型的。 Each kind of question corresponds to a type of response data. 每种问题都对应于一种响应数据。

Is it possible to encode this at the type level? 是否可以在类型级别对此进行编码? How would you organize this? 你会如何组织这个?

data QuestionType = EmailText | PlainText | Numeric

-- this doesn't have any response information, it's the metadata
-- about the question itself.
data Question = { id :: ID, label :: Text, questionType :: QuestionType }

data Answer = { questionID :: ID, response :: Response }

-- I would like to map those question types to different response types
data Response = ???
-- EmailText => Text
-- PlainText => Text
-- Numeric   => Int

I've thought about Type Families, which would work perfectly except that I want to map from different data constructors to different types, and type families would require separate types for each one. 我已经考虑过Type Families,除了我想要从不同的数据构造函数映射到不同的类型之外,它可以完美地工作,而类型族要为每个类型需要单独的类型。

This would be a good fit for a single ADT, with the response information included in each constructor, but I need to be able to deal with question types independently from responses. 这将非常适合单个ADT,响应信息包含在每个构造函数中,但我需要能够独立于响应处理问题类型。

How should I approach this? 我该怎么做呢?

I've not completely understood what you exactly want, but maybe this can be a starting point: 我还没有完全理解你到底想要什么,但也许这可以作为一个起点:

{-# LANGUAGE DataKinds, GADTs #-}

data Response (qt :: QuestionType) where
  RPlainText :: Text -> Response PlainText
  REmailText :: Text -> Response EmailText
  RNumeric :: Int -> Response Numeric

data Answer qt = Answer {questionID :: ID, response :: Response qt}

If you do not want the qt argument in Answer qt , you probably need existential types to hide that, but at that point you'll probably want to link it with the questions somehow. 如果你不想在Answer qt使用qt参数,你可能需要存在类型来隐藏它,但在那时你可能想要以某种方式将它与问题联系起来。

Having types depend on values is exactly what dependent types are for. 依赖于值的类型正是依赖类型的用途。 Unfortunately, Haskell doesn't have dependent types. 不幸的是,Haskell没有依赖类型。 However, you can use a sum type to capture the possible response types: 但是,您可以使用sum类型捕获可能的响应类型:

data Response = ResponseText Text | ResponseInt Int

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

相关问题 为什么没有数据构造函数的类型有效? - Why are types with no data constructors valid? Haskells数据类型和带有函数的构造函数? - Haskells data types and constructors with functions? 类型构造函数和存在类型 - Types constructors and existential types 使用带有多个构造函数的代数数据类型的记录语法 - Using record syntax with algebraic data types with multiple constructors 将类型与数据构造函数关联的ADT编码有什么问题? (如Scala。) - What are the problems with an ADT encoding that associates types with data constructors? (Such as Scala.) 具有多个数据构造器的单一类型与多种类型 - Single Type With Several Data Constructors vs. Several Types 使用通用解码解析所有nullary构造函数的数据类型 - Parsing data types with all nullary constructors using generic decode 类型枚举和构造函数 - Types Enums and Constructors 仅具有零元或一元构造函数的 Haskell 数据类型是否被视为代数数据类型? - Are Haskell data types with only nullary or unary constructors considered as Algebraic Data Types? 了解 haskells 数据类型和构造函数(特别是在数据类型中使用另一种数据类型的地方) - Understanding haskells data types and constructors (specifically where you use another data type in a data type)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM