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

时间:2015-10-23 18:18:10

标签: haskell types algebraic-data-types

我正在创建一个允许管理员构建表单的应用程序,用户可以填写该表单。问题可以是不同类型的。每种问题都对应于一种响应数据。

是否可以在类型级别对此进行编码?你会如何组织这个?

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

我已经考虑过Type Families,除了我想要从不同的数据构造函数映射到不同的类型之外,它可以完美地工作,而类型族要为每个类型需要单独的类型。

这对于单个ADT非常适合,每个构造函数中都包含响应信息,但我需要能够独立于响应来处理问题类型。

我该如何处理?

2 个答案:

答案 0 :(得分:8)

我还没有完全明白你到底想要什么,但也许这可能是一个起点:

{-# 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}

如果您不想qt中的Answer qt参数,您可能需要存在类型来隐藏它,但此时您可能希望以某种方式将其与问题相关联。

答案 1 :(得分:1)

依赖于值的类型正是依赖类型的用途。不幸的是,Haskell没有依赖类型。但是,您可以使用sum类型捕获可能的响应类型:

data Response = ResponseText Text | ResponseInt Int