[英]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.