Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell:按类型筛选异构列表_Haskell_Filter - Fatal编程技术网

Haskell:按类型筛选异构列表

Haskell:按类型筛选异构列表,haskell,filter,Haskell,Filter,我们可以使用配对序列在Haskell中创建异构列表: type a *: b = (a, b) a *: b = (a, b) infixr 5 *: hlist :: Int *: String *: Maybe Float *: () hlist = 1 *: "hello" *: Just 3 *: () -- (1, ("hello", (Just 3, ()))) 有没有一种方法可以对这些列表进行类型级过滤?也就是说,定义一些多态函数hfilter,以便针对不同类型的a、b和c:

我们可以使用配对序列在Haskell中创建异构列表:

type a *: b = (a, b)
a *: b = (a, b)
infixr 5 *:

hlist :: Int *: String *: Maybe Float *: ()
hlist = 1 *: "hello" *: Just 3 *: () -- (1, ("hello", (Just 3, ())))
有没有一种方法可以对这些列表进行类型级过滤?也就是说,定义一些多态函数
hfilter
,以便针对不同类型的
a
b
c

hfilter :: a *: b *: c *: a *: b *: a *: () ->  a *: a *: a *: ()
hfilter :: a *: b *: c *: a *: b *: a *: () ->  b *: b *: ()
hfilter :: a *: b *: c *: a *: b *: a *: () ->  c *: ()
hfilter :: a *: b *: c *: a *: b *: a *: () ->  ()

通过一些类型扩展是可能的(顺便说一句,在发布问题时请检查您的示例代码是否编译。我不得不做了很多更正)

现在,通过显式定义所需列表的类型,我们可以按类型筛选项目

*Main> hfilter hlist :: [Int]
[1,2]
*Main> hfilter hlist :: [String]
["hello"]
*Main> hfilter hlist :: [Maybe Float]
[Just 3.0]
*Main> hfilter hlist :: [Maybe Int]
[]
它的工作原理是定义一个多参数类型类
TypeFilter
,该类接受异构列表的类型和我们要筛选的类型。然后,我们为空列表/单元
()
和类型匹配的列表(
TypeFilter(t:*rest)t
)定义实例,最后为头部类型不同于我们想要检索的类型的列表定义实例(
TypeFilter(a:*rest)t)


请注意,在上一个实例中,目前没有任何方法表明
a
t
必须是不同的类型,但当它们相同时,实例
TypeFilter(t:*rest)t
将被计算为更具体的类型,并选择它而不是
TypeFilter(a:*rest)t
one.

尽管有一些方法可以满足您的要求,但很有可能您没有在这里使用Haskell strength。你能详细说明你的需要吗?通常,您可以枚举代数数据类型中需要的所有变量。然后,您的列表将是同质的,允许您对元素进行模式匹配以对其进行操作。

对于编译问题,我很抱歉,我是从手机上发布的。好的,我可以从这里获得到
hfilter::a->h->h'
,并且使用异质列表进行输出。因此,
hfilter(undefined::Int)hlist::()
()
hfilter(undefined::Int)hlist::Int:*(
1:*()
hfilter(undefined::Int)hlist::Int:*Int:*(
1:*2()
.arg,但这需要
重叠实例才能实际使用。使用ADT,你可能会得到一个类似于spirit to的解决方案,它通过一个特定的构造函数来过滤列表。我正在haskell中编写一个基于堆栈的DSL(有点类似的因素)——在这种情况下,异构列表就是堆栈。啊,我想我明白了,也许是Sami基于SNOC对的多态堆栈的精神?
*Main> hfilter hlist :: [Int]
[1,2]
*Main> hfilter hlist :: [String]
["hello"]
*Main> hfilter hlist :: [Maybe Float]
[Just 3.0]
*Main> hfilter hlist :: [Maybe Int]
[]