haskell - 在 HList 中查找元素

标签 haskell hlist

我正在尝试编写两个函数来从 HList 中提取值,但我似乎无法让 GHC 满意。

第一个函数将具有签名 extract::HList a -> [b],它从列表中提取 b 类型的所有元素。我只是通过要求 a 中的类型具有 Typeable 实例才成功编写它。

class OfType a b where
    oftype :: a -> [Maybe b]

instance OfType (HList '[]) b where
    oftype = const []

instance (Typeable t, Typeable b, OfType (HList ts) b) => OfType (HList (t ': ts)) b where
    oftype (x :- xs) = (cast x :: Maybe b) : oftype xs

extract :: OfType a b => a -> [b]
extract = catMaybes . oftype

这是次优的,因为实际上并不需要 Typeable 约束来编写任何 extract 实例。

我尝试在约束中使用类型相等和不等式,但这只会给我重叠的实例。

我尝试编写的第二个函数将具有签名 extract'::Contains h n => HList h -> n ,它提取 n 类型的第一个元素在列表中,并且上下文表明该列表实际上包含该类型的一个元素。

是否可以在没有 Typeable 约束的情况下编写extract

是否可以在没有 Typeable 约束的情况下编写 extract' ? 如何写Contains

最佳答案

由于您想在编译时检查类型相等性,因此我相信重叠实例是不可避免的(而且我不喜欢这些......)。

此外,我不能 100% 确定我的重叠编译指示正确无误。

{-# LANGUAGE DataKinds, TypeOperators, ScopedTypeVariables,
    MultiParamTypeClasses, FlexibleInstances, FlexibleContexts #-}
{-# OPTIONS -Wall #-}
module HListFilter where

import Data.HList.HList

class OfType a b where
    oftype :: a -> [b]

instance OfType (HList '[]) b where
    oftype = const []

instance {-# OVERLAPS #-} (OfType (HList ts) t) => OfType (HList (t ': ts)) t where
    oftype (HCons x xs) = x : oftype xs

instance {-# OVERLAPPABLE #-} (OfType (HList ts) b) => OfType (HList (t ': ts)) b where
    oftype (HCons _ xs) = oftype xs

test :: HList '[Int, Char, [Char], Char, Bool]
test = HCons (1::Int) (HCons 'a' (HCons "foo" (HCons 'b' (HCons True HNil))))

test_result :: [Char]
test_result = oftype test  -- "ab"

关于haskell - 在 HList 中查找元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35252562/

相关文章:

haskell - Haskell 中的类型化抽象语法和 DSL 设计

绑定(bind)到记录实例的内存函数的 Haskell 生命周期

haskell - 如何将 MonadLogger 添加到我的免费 monad 转换器堆栈中?

haskell - 类型族卡在使用函数依赖的等效类型可以简化的地方

types - Rust 中的类型级映射

node.js - 从 Node.JS 调用 Haskell

haskell - 显示 Haskell 程序的进度

scala - 将无形 HList 转换为元组

scala - HList的证据保全LUB约束

haskell - 如何在 Haskell 中连接幻像类型中的元组?