gpt4 book ai didi

haskell - 管理约束爆炸 (Haskell)

转载 作者:行者123 更新时间:2023-12-02 10:33:52 25 4
gpt4 key购买 nike

我正在编写一个函数,我希望它能够在向量上通用。换句话说,我有这样的东西:

import qualified Data.Vector.Generic as G
foo :: (G.Vector v a, G.Vector v b, G.Vector v c, G.Vector v d)
=> v a -> v b -> v c -> v d

这样用户就可以选择使用UnboxedStorable向量等。

但是如果我需要将中间值放入 v 中,我会得到向量约束的组合爆炸,例如:

foo :: (G.Vector v a, G.Vector v b, G.Vector v c, G.Vector v d,
G.Vector v (a, b), G.Vector v (a, c), G.Vector v (c, b))
=> v a -> v b -> v c -> v d

如何管理这种冗长的内容?有没有办法可以拥有

1) GHC 隐式生成约束

2)以某种方式将约束重构为公共(public)类

最佳答案

类型族可能会很方便:

{-# LANGUAGE TypeFamilies, KindSignatures, DataKinds, TypeOperators, ConstraintKinds #-}

import qualified Data.Vector.Generic as G
import GHC.Prim

type family Vectors v (a :: [*]) :: Constraint where
Vectors v '[] = ()
Vectors v (a ': as) = (G.Vector v a, Vectors v as)

这将创建一个类型级别函数,该函数采用类型列表,并为具有这些类型的通用 Vector 进行适当的约束。您可以像这样使用它:

foo :: (Vectors v [a, b, c, d, (a, b), (a, c), (c, b)]) => v a -> v b -> v c -> v d

这不太理想,但它确实在一定程度上减少了代码。

处理元组约束的急剧增加

您可以通过一些更多类型级别的技巧更好地处理由于对类型而导致的约束爆炸:

type family Combinations v (a :: [*]) :: Constraint where
Combinations v '[] = ()
Combinations v (a ': as) = (G.Vector v a, CombComponent v a as, Combinations v as)

type family CombComponent v (a :: *) (bs :: [*]) :: Constraint where
CombComponent v a '[] = ()
CombComponent v a (b ': bs) = (G.Vector v (a, b), G.Vector v (b, a), CombComponent v a bs)

这有点复杂,但现在我们可以像这样编写第二个 foo 签名:

foo :: (Combinations v [a, b, c, d]) => v a -> v b -> v c -> v d

这也可以进一步推广以允许签名,例如:

foo :: (Combinations (G.Vector v) [a, b, c, d]) => v a -> v b -> v c -> v d

关于haskell - 管理约束爆炸 (Haskell),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28142914/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com