haskell - 根据参数和请求的返回类型退回产品或记录的一部分的功能

标签 haskell generic-programming scrap-your-boilerplate

我正在寻找一个函数,给定必要的返回类型,该函数将完全基于传递给函数的类型结构来返回与该类型匹配的产品参数部分。

例如:

data MyProduct = MyProduct String Int Bool

prod = MyProduct "yes" 0 False

func prod :: Boolean -- would return False
func prod :: String  -- would return "yes"
func prod :: Double  -- compiler error


同样,对于相同的功能func,但产品不同:

data AnotherProduct = AP (Maybe Int) Char

ap = AP Nothing 'C'

func ap :: Maybe Int -- would return Nothing


是否存在这样的功能?我觉得应该可以,也许使用Generic。我知道这在其他语言中也是可行的,例如带有Shapeless库的Scala,但是我无法确定在Haskell中如何最好地实现这一点。

最佳答案

以下是获取所有兼容字段的列表的方法:

import Data.Data
import Data.Typeable
import Data.Maybe (maybeToList)

fields :: (Data a, Typeable b) => a -> [b]
fields = gmapQr (++) [] (maybeToList . cast)


您使用的产品类型应派生Data。这可以通过{-# LANGUAGE DeriveDataTypeable #-}自动完成

data MyProduct = MyProduct String Int Bool
    deriving (Typeable, Data)


请参阅gmapQrcast的文档。

唯一需要注意的是,当您请求一个不存在的字段时,我想不出一种产生编译时错误的方法。我们需要某种Data.Data的编译时版本。我不知道有任何这样的事情,尽管我怀疑这是可能的(尽管这可能会更痛苦-– deriving Data为我们做很多繁重的工作!)。

关于haskell - 根据参数和请求的返回类型退回产品或记录的一部分的功能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51736130/

相关文章:

Haskell-(类型声明)什么是 "a"?

c++ - 模板函数作为模板参数

vb.net - 如何使 VB.NET 函数的参数作为泛型类型?

haskell - 使用 SYB 和 ad-hoc 多态性在 Haskell 中进行泛型编程

Haskell 问题 : constraining data types to use show

Haskell 无法将预期类型 [char] 与实际类型 IO 匹配

haskell - 这个幺半群定律叫什么名字?

c++ - 在泛型编程中使用 placement new

f# - 在 f# 中废弃你的样板